School Commit Init

This commit is contained in:
2024-08-31 12:07:21 +03:00
commit 0b130ee18c
2801 changed files with 4720552 additions and 0 deletions
@@ -0,0 +1,41 @@
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
x64
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
*.sln
*.ui
*.qrc
.vs
@@ -0,0 +1,108 @@
#include "Admin_view.h"
#include "Service.h"
#include <qheaderview.h>
#include<QObject>
#include <QMessageBox>
#include <algorithm>
Admin_view::Admin_view(Service& subject, User& user, QWidget* parent) : _subject{subject} , _user{user}, QWidget{parent}
{
_subject.attach(this);
_combo = new QComboBox{};
_combo->addItems(QStringList{QString::fromStdString("All"), QString::fromStdString("Wood"), QString::fromStdString("Artifacts"), QString::fromStdString("Painting")});
_combo->setCurrentIndex(0);
_table = new QTableWidget{1, 3};
_table->setHorizontalHeaderLabels(QStringList{"Name", "Category", "Current price"});
_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
populate_table();
QVBoxLayout* layout = new QVBoxLayout{};
layout->addWidget(_combo);
layout->addWidget(_table);
_name = new QLineEdit{};
_category = new QLineEdit{};
_price = new QLineEdit{};
_validator = new QIntValidator();
_validator->setBottom(0);
_price->setValidator(_validator);
_add_button = new QPushButton{"Add"};
layout->addWidget(_name);
layout->addWidget(_category);
layout->addWidget(_price);
layout->addWidget(_add_button);
_table_item = new QTableWidget{1, 3};
_table_item->setHorizontalHeaderLabels(QStringList{"User Id", "Date", "Offer"});
_table_item->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
layout->addWidget(_table_item);
setLayout(layout);
this->setWindowTitle(QString::fromStdString(_user.name()));
QObject::connect(_add_button, &QPushButton::clicked, [&]() {
std::string name = _name->text().toStdString();
std::string category = _category->text().toStdString();
int price = _price->text().toInt();
if (name == "" || category == "" || price == 0)
{
QMessageBox::critical(this, "Error", "Invalid input");
return;
}
try
{
_subject.add(name, category, price);
}
catch (std::exception& e)
{
QMessageBox::critical(this, "Error", e.what());
}
});
QObject::connect(_combo, &QComboBox::currentTextChanged, this, &Admin_view::populate_table);
QObject::connect(_table, &QTableWidget::itemSelectionChanged, this, &Admin_view::populate_table_item);
}
void Admin_view::update()
{
populate_table();
}
void Admin_view::populate_table()
{
std::string _category = _combo->currentText().toStdString();
_table->setRowCount(0);
std::vector<Item> items = _subject.get_items();
std::sort(items.begin(), items.end(), [](const Item& a, const Item& b) {return a.price() < b.price(); });
for (auto item : items)
{
if(_category == "All" || _category == item.category())
{
int row = _table->rowCount();
_table->insertRow(row);
_table->setItem(row, 0, new QTableWidgetItem{QString::fromStdString(item.name())});
_table->setItem(row, 1, new QTableWidgetItem{QString::fromStdString(item.category())});
_table->setItem(row, 2, new QTableWidgetItem{QString::number(item.price())});
}
}
}
void Admin_view::populate_table_item(){
//QMessageBox::critical(this, "Error", "Invalid input");
QModelIndexList selection = _table->selectionModel()->selectedIndexes();
if (selection.isEmpty())
{
_table_item->setRowCount(0);
return;
}
int row = selection.at(0).row();
std::string name = _table->item(row, 0)->text().toStdString();
Item item = _subject.find_item(name);
_table_item->setRowCount(0);
auto offers = item.offers();
std::sort(offers.begin(), offers.end(), [](const auto& a, const auto& b) {return std::get<1>(a) > std::get<1>(b); });
for( auto offer : offers){
int row = _table_item->rowCount();
_table_item->insertRow(row);
_table_item->setItem(row, 0, new QTableWidgetItem{QString::number(std::get<0>(offer))});
_table_item->setItem(row, 1, new QTableWidgetItem{QString::fromStdString(std::get<1>(offer))});
_table_item->setItem(row, 2, new QTableWidgetItem{QString::number(std::get<2>(offer))});
}
}
@@ -0,0 +1,35 @@
#pragma once
#include <QWidget>
#include <QTableWidget>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QIntValidator>
#include <QComboBox>
#include "Subject.h"
#include "Service.h"
class Admin_view : public QWidget , virtual public Observer
{
private:
Service& _subject;
QComboBox* _combo;
QTableWidget* _table;
QLineEdit* _name;
QLineEdit* _category;
QLineEdit* _price;
QPushButton* _add_button;
QIntValidator* _validator;
QTableWidget* _table_item;
User& _user;
public:
Admin_view(Service& subject, User& user, QWidget* parent = nullptr);
void update() override;
void populate_table();
void populate_table_item();
};
@@ -0,0 +1,107 @@
#include "Collector_view.h"
#include "Service.h"
#include <qheaderview.h>
#include <algorithm>
#include <QModelIndex>
#include <tuple>
#include <QMessageBox>
Collector_view::Collector_view(Service& subject, User& user, QWidget* parent) : _subject{subject} , _user{user}, QWidget{parent}
{
_subject.attach(this);
_combo = new QComboBox{};
_combo->addItems(QStringList{QString::fromStdString("All"), QString::fromStdString("Wood"), QString::fromStdString("Artifacts"), QString::fromStdString("Painting")});
_combo->setCurrentIndex(0);
_table = new QTableWidget{1, 3};
_table->setHorizontalHeaderLabels(QStringList{"Name", "Category", "Current price"});
_table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
populate_table();
QVBoxLayout* layout = new QVBoxLayout{};
layout->addWidget(_combo);
layout->addWidget(_table);
_table_item = new QTableWidget{1, 3};
_table_item->setHorizontalHeaderLabels(QStringList{"User Id", "Date", "Offer"});
_table_item->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
layout->addWidget(_table_item);
_bid = new QLineEdit{};
QIntValidator* _validator = new QIntValidator();
_validator->setBottom(0);
_bid->setValidator(_validator);
layout->addWidget(_bid);
_bid_button = new QPushButton{"Bid"};
layout->addWidget(_bid_button);
setLayout(layout);
this->setWindowTitle(QString::fromStdString(_user.name()));
QObject::connect(_combo, &QComboBox::currentTextChanged, this, &Collector_view::populate_table);
QObject::connect(_table, &QTableWidget::cellClicked, this, &Collector_view::populate_table_item);
QObject::connect(_bid_button, &QPushButton::clicked, this, &Collector_view::bid_item);
}
void Collector_view::update()
{
populate_table_item();
populate_table();
}
void Collector_view::populate_table()
{
std::string _category = _combo->currentText().toStdString();
_table->setRowCount(0);
std::vector<Item> items = _subject.get_items();
std::sort(items.begin(), items.end(), [](const Item& a, const Item& b) {return a.price() < b.price(); });
for (auto item : items)
{
if(_category == "All" || _category == item.category())
{
int row = _table->rowCount();
_table->insertRow(row);
_table->setItem(row, 0, new QTableWidgetItem{QString::fromStdString(item.name())});
_table->setItem(row, 1, new QTableWidgetItem{QString::fromStdString(item.category())});
_table->setItem(row, 2, new QTableWidgetItem{QString::number(item.price())});
}
}
}
void Collector_view::populate_table_item(){
//QMessageBox::critical(this, "Error", "Invalid input");
QModelIndexList selection = _table->selectionModel()->selectedIndexes();
if (selection.isEmpty())
{
_table_item->setRowCount(0);
return;
}
int row = selection.at(0).row();
std::string name = _table->item(row, 0)->text().toStdString();
Item item = _subject.find_item(name);
_table_item->setRowCount(0);
auto offers = item.offers();
std::sort(offers.begin(), offers.end(), [](const auto& a, const auto& b) {return std::get<1>(a) > std::get<1>(b); });
for( auto offer : offers){
int row = _table_item->rowCount();
_table_item->insertRow(row);
_table_item->setItem(row, 0, new QTableWidgetItem{QString::number(std::get<0>(offer))});
_table_item->setItem(row, 1, new QTableWidgetItem{QString::fromStdString(std::get<1>(offer))});
_table_item->setItem(row, 2, new QTableWidgetItem{QString::number(std::get<2>(offer))});
}
}
void Collector_view::bid_item(){
QModelIndexList selection = _table->selectionModel()->selectedIndexes();
if (selection.isEmpty())
{
return;
}
int row = selection.at(0).row();
std::string name = _table->item(row, 0)->text().toStdString();
Item item = _subject.find_item(name);
int bid = _bid->text().toInt();
if(bid < item.price()){
QMessageBox::critical(this, "Error", "Invalid input");
return;
}
_subject.bid(name,bid , _user.id(), "2023.06.13");
_bid->setText("");
}
@@ -0,0 +1,31 @@
#pragma once
#include "QWidget"
#include "QTableWidget"
#include "QVBoxLayout"
#include "QLineEdit"
#include "QPushButton"
#include "QComboBox"
#include "Subject.h"
#include "Service.h"
class Collector_view : public QWidget , virtual public Observer
{
Q_OBJECT
private:
Service& _subject;
QTableWidget* _table;
QTableWidget* _table_item;
User _user;
QComboBox* _combo;
QLineEdit* _bid;
QPushButton* _bid_button;
public:
Collector_view(Service& subject, User& user, QWidget* parent = nullptr);
void update() override;
void populate_table();
void populate_table_item();
void bid_item();
};
+10
View File
@@ -0,0 +1,10 @@
#include "Exam.h"
Exam::Exam(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
Exam::~Exam()
{}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_Exam.h"
class Exam : public QMainWindow
{
Q_OBJECT
public:
Exam(QWidget *parent = nullptr);
~Exam();
private:
Ui::ExamClass ui;
};
@@ -0,0 +1,7 @@
#pragma once
class Observer
{
public:
virtual void update() = 0;
};
@@ -0,0 +1,15 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-24ddc0f5d75046c5622901739e7c5dd533143b0c8e959d652212380cedb1ea36.svg)](https://classroom.github.com/a/Qi9-k8ID)
# Practical examination
Solve the provided problem, using object oriented programming, C++ and Qt.
The application must use layered architecture in order for functionalities to be graded.
Do not forget to add the required tests and specifications.
Using existing code is forbidden, you must start your application from scratch.
For function documentation you may use:
- http://doc.qt.io/qt-6/
- https://en.cppreference.com/w/
- https://www.cplusplus.com/
@@ -0,0 +1,45 @@
#include "Service.h"
#include "item.h"
#include <algorithm>
Service::Service(Repository& repository) : _repository{repository} {
}
void Service::add(std::string name, std::string category, int current_price) {
Item item(name, category, current_price);
this->_repository.add_item(item);
this->notify();
}
void Service::bid(std::string name, int bid, int id, std::string date) {
Item& item = this->_repository.find_item(name);
std::tuple <int, std::string, int> bid_tuple(id, date, bid);
item.add_offer(bid_tuple);
item.price(bid);
this->notify();
}
std::vector<Item> Service::get_items() {
return this->_repository.items();
}
Item& Service::find_item(std::string name) {
return this->_repository.find_item(name);
}
void Service::attach(Observer* observer) {
this->_observers.push_back(observer);
}
void Service::detach(Observer* observer) {
this->_observers.erase(std::remove(this->_observers.begin(), this->_observers.end(), observer), this->_observers.end());
}
void Service::notify() {
for (auto observer : this->_observers) {
observer->update();
}
}
@@ -0,0 +1,21 @@
#pragma once
#include "repo.h"
#include "Subject.h"
class Service : public Subject{
private:
Repository& _repository;
public:
Service(Repository& repository);
void add(std::string name, std::string category, int current_price);
void bid(std::string name, int bid, int id, std::string date);
std::vector<Item> get_items();
Item& find_item(std::string name);
void attach(Observer* observer) override;
void detach(Observer* observer) override;
void notify() override;
};
@@ -0,0 +1,15 @@
#pragma once
#include "Observer.h"
#include <vector>
class Subject
{
protected:
std::vector<Observer*> _observers;
public:
virtual void attach(Observer* observer) = 0;
virtual void detach(Observer* observer) = 0;
virtual void notify() = 0;
};
+68
View File
@@ -0,0 +1,68 @@
#include "item.h"
Item::Item()
{
this->_name = "";
this->_category = "";
this->_price = 0;
}
Item::Item(std::string name, std::string category, int price)
{
this->_name = name;
this->_category = category;
this->_price = price;
}
Item::Item(std::string name, std::string category, int price, std::vector<std::tuple<int,std::string,int>> offers){
this->_name = name;
this->_category = category;
this->_price = price;
this->_offers = offers;
}
std::string Item::name()
{
return this->_name;
}
std::string Item::category()
{
return this->_category;
}
int Item::price() const
{
return this->_price;
}
std::vector<std::tuple<int,std::string,int>> Item::offers()
{
return this->_offers;
}
void Item::name(std::string name)
{
this->_name = name;
}
void Item::category(std::string category)
{
this->_category = category;
}
void Item::price(int price)
{
this->_price = price;
}
void Item::offers(std::vector<std::tuple<int,std::string,int>> offers)
{
this->_offers = offers;
}
void Item::add_offer(std::tuple<int,std::string,int> offer)
{
this->_offers.push_back(offer);
}
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include<string>
#include<vector>
#include<tuple>
class Item{
private:
std::string _name;
std::string _category;
int _price;
std::vector<std::tuple<int,std::string,int>> _offers;
public:
Item();
Item(std::string name, std::string category, int price);
Item(std::string name, std::string category, int price, std::vector<std::tuple<int,std::string,int>> offers);
std::string name();
std::string category();
int price() const;
std::vector<std::tuple<int,std::string,int>> offers();
void name(std::string name);
void category(std::string category);
void price(int price);
void offers(std::vector<std::tuple<int,std::string,int>> offers);
void add_offer(std::tuple<int,std::string,int> offer);
};
@@ -0,0 +1,2 @@
Compass|Artifacts|100|1,2023.10.09,50;3,2023.10.10,100;
Table|Wood|300|3,2023.10.10,50;1,2023.10.11,300;
@@ -0,0 +1,3 @@
Compass|Artifacts|100|1,2023.10.09,50;3,2023.10.10,100;
Table|Wood|100|3,2023.10.10,50;1,2023.10.11,30;0,2023.06.13,100;
DAd|Painting|3000|1,2023.06.13,1000;3,2023.06.13,2000;1,2023.06.13,3000;
+23
View File
@@ -0,0 +1,23 @@
#include "Exam.h"
#include <QtWidgets/QApplication>
#include "Service.h"
#include "Collector_view.h"
#include "Admin_view.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Repository repo{};
Service service{repo};
for(auto user: repo.users()){
if(user.type() == "collector"){
Collector_view* view = new Collector_view{service, user};
view->show();
}
else{
Admin_view* view = new Admin_view{service, user};
view->show();
}
}
return a.exec();
}
+111
View File
@@ -0,0 +1,111 @@
#include "repo.h"
#include <stdexcept>
#include <fstream>
Repository::Repository()
{
this->read_from_file();
}
Repository::~Repository()
{
this->write_to_file();
}
std::vector<User> Repository::users()
{
return this->_users;
}
std::vector<Item> Repository::items()
{
return this->_items;
}
void Repository::add_item(Item item)
{
for(auto it : this->_items){
if(it.name() == item.name()){
throw std::runtime_error("Item already exists");
}
}
this->_items.push_back(item);
}
Item& Repository::find_item(std::string name)
{
for(auto& it : this->_items){
if(it.name() == name){
return it;
}
}
throw std::runtime_error("Item not found");
}
void Repository::read_from_file()
{
std::ifstream f("items.txt");
std::string name, category;
int price;
std::string line;
std::string buf;
int user_id;
std::string date;
int offer_price;
while(std::getline(f,line) || line != ""){
buf=line.substr(0, line.find("|"));
name = buf;
line.erase(0, line.find("|")+1);
buf=line.substr(0, line.find("|"));
category = buf;
line.erase(0, line.find("|")+1);
buf=line.substr(0, line.find("|"));
price = std::stoi(buf);
line.erase(0, line.find("|")+1);
std::vector<std::tuple<int,std::string,int>> offers;
while(line != ""){
buf=line.substr(0, line.find(","));
user_id = std::stoi(buf);
line.erase(0, line.find(",")+1);
buf=line.substr(0, line.find(","));
date = buf;
line.erase(0, line.find(",")+1);
buf=line.substr(0, line.find(","));
offer_price = std::stoi(buf);
line.erase(0, line.find(";")+1);
offers.push_back(std::make_tuple(user_id, date, offer_price));
}
this->_items.push_back(Item(name, category, price, offers));
}
std::string type;
int id;
std::ifstream g("users.txt");
while(std::getline(g,line) || line != ""){
buf=line.substr(0, line.find("|"));
id = std::stoi(buf);
line.erase(0, line.find("|")+1);
buf=line.substr(0, line.find("|"));
name = buf;
line.erase(0, line.find("|")+1);
buf=line.substr(0, line.find("|"));
type = buf;
line.erase(0, line.find("|")+1);
this->_users.push_back(User(name, id, type));
}
f.close();
g.close();
}
void Repository::write_to_file()
{
std::ofstream f("items.txt");
for(auto it : this->_items){
f<<it.name()<<"|"<<it.category()<<"|"<<it.price()<<"|";
for(auto it2 : it.offers()){
f<<std::get<0>(it2)<<","<<std::get<1>(it2)<<","<<std::get<2>(it2)<<";";
}
f<<"\n";
}
f.close();
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "user.h"
#include "item.h"
class Repository{
private:
std::vector<User> _users;
std::vector<Item> _items;
public:
Repository();
~Repository();
std::vector<User> users();
std::vector<Item> items();
void add_item(Item item);
Item& find_item(std::string name);
void read_from_file();
void write_to_file();
};
+45
View File
@@ -0,0 +1,45 @@
#include "user.h"
User::User()
{
this->_name = "";
this->_id = 0;
this->_type = "";
}
User::User(std::string name, int id, std::string type)
{
this->_name = name;
this->_id = id;
this->_type = type;
}
std::string User::name()
{
return this->_name;
}
int User::id()
{
return this->_id;
}
std::string User::type()
{
return this->_type;
}
void User::name(std::string name)
{
this->_name = name;
}
void User::id(int id)
{
this->_id = id;
}
void User::type(std::string type)
{
this->_type = type;
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include<string>
class User
{
private:
std::string _name;
int _id;
std::string _type;
public:
User();
User(std::string name, int id, std::string type);
std::string name();
int id();
std::string type();
void name(std::string name);
void id(int id);
void type(std::string type);
};
@@ -0,0 +1,2 @@
1|John|collector
2|Dumi|administrator
@@ -0,0 +1,3 @@
1|John|collector
2|Dumi|administrator
3|Adi|collector