School Commit Init
This commit is contained in:
@@ -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();
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "Exam.h"
|
||||
|
||||
Exam::Exam(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
}
|
||||
|
||||
Exam::~Exam()
|
||||
{}
|
||||
@@ -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 @@
|
||||
[](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;
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "MockTest1.h"
|
||||
|
||||
MockTest1::MockTest1(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
}
|
||||
|
||||
MockTest1::~MockTest1()
|
||||
{}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include "ui_MockTest1.h"
|
||||
|
||||
class MockTest1 : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MockTest1(QWidget *parent = nullptr);
|
||||
~MockTest1();
|
||||
|
||||
private:
|
||||
Ui::MockTest1Class ui;
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
<RCC>
|
||||
<qresource prefix="MockTest1">
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.6.33723.286
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MockTest1", "MockTest1.vcxproj", "{6E00E0F0-D4AC-45C2-8D14-87AA4438D72C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6E00E0F0-D4AC-45C2-8D14-87AA4438D72C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6E00E0F0-D4AC-45C2-8D14-87AA4438D72C}.Debug|x64.Build.0 = Debug|x64
|
||||
{6E00E0F0-D4AC-45C2-8D14-87AA4438D72C}.Release|x64.ActiveCfg = Release|x64
|
||||
{6E00E0F0-D4AC-45C2-8D14-87AA4438D72C}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2475A094-A48B-45CD-8181-64DC4484D0E4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,28 @@
|
||||
<UI version="4.0" >
|
||||
<class>MockTest1Class</class>
|
||||
<widget class="QMainWindow" name="MockTest1Class" >
|
||||
<property name="objectName" >
|
||||
<string notr="true">MockTest1Class</string>
|
||||
</property>
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>MockTest1</string>
|
||||
</property> <widget class="QMenuBar" name="menuBar" />
|
||||
<widget class="QToolBar" name="mainToolBar" />
|
||||
<widget class="QWidget" name="centralWidget" />
|
||||
<widget class="QStatusBar" name="statusBar" />
|
||||
</widget>
|
||||
<layoutDefault spacing="6" margin="11" />
|
||||
<pixmapfunction></pixmapfunction>
|
||||
<resources>
|
||||
<include location="MockTest1.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</UI>
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{6E00E0F0-D4AC-45C2-8D14-87AA4438D72C}</ProjectGuid>
|
||||
<Keyword>QtVS_v304</Keyword>
|
||||
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0.22000.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0.22000.0</WindowsTargetPlatformVersion>
|
||||
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
|
||||
<Import Project="$(QtMsBuild)\qt_defaults.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
|
||||
<QtInstall>6.6.0_msvc2019_64</QtInstall>
|
||||
<QtModules>core;gui;widgets</QtModules>
|
||||
<QtBuildConfig>debug</QtBuildConfig>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
|
||||
<QtInstall>6.6.0_msvc2019_64</QtInstall>
|
||||
<QtModules>core;gui;widgets</QtModules>
|
||||
<QtBuildConfig>release</QtBuildConfig>
|
||||
</PropertyGroup>
|
||||
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
||||
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
|
||||
</Target>
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Label="Shared" />
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(QtMsBuild)\Qt.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(QtMsBuild)\Qt.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
|
||||
<ClCompile>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
|
||||
<ClCompile>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Participant.cpp" />
|
||||
<ClCompile Include="ParticipantModel.cpp" />
|
||||
<ClCompile Include="ParticipantRepo.cpp" />
|
||||
<ClCompile Include="ParticipantView.cpp" />
|
||||
<ClCompile Include="PresenterModel.cpp" />
|
||||
<ClCompile Include="PresenterView.cpp" />
|
||||
<ClCompile Include="Question.cpp" />
|
||||
<ClCompile Include="QuestionRepo.cpp" />
|
||||
<QtRcc Include="MockTest1.qrc" />
|
||||
<QtUic Include="MockTest1.ui" />
|
||||
<QtMoc Include="MockTest1.h" />
|
||||
<ClCompile Include="MockTest1.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Participant.h" />
|
||||
<QtMoc Include="ParticipantModel.h" />
|
||||
<ClInclude Include="ParticipantRepo.h" />
|
||||
<QtMoc Include="ParticipantView.h" />
|
||||
<QtMoc Include="PresenterModel.h" />
|
||||
<QtMoc Include="PresenterView.h" />
|
||||
<ClInclude Include="Question.h" />
|
||||
<ClInclude Include="QuestionRepo.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="participants.txt" />
|
||||
<Text Include="questions.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
||||
<Import Project="$(QtMsBuild)\qt.targets" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Form Files">
|
||||
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
|
||||
<Extensions>ui</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Translation Files">
|
||||
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
|
||||
<Extensions>ts</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtRcc Include="MockTest1.qrc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</QtRcc>
|
||||
<QtUic Include="MockTest1.ui">
|
||||
<Filter>Form Files</Filter>
|
||||
</QtUic>
|
||||
<QtMoc Include="MockTest1.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<ClCompile Include="MockTest1.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Question.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Participant.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QuestionRepo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ParticipantRepo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PresenterModel.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PresenterView.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ParticipantModel.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ParticipantView.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Question.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Participant.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="QuestionRepo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ParticipantRepo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="questions.txt" />
|
||||
<Text Include="participants.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="PresenterView.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="PresenterModel.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="ParticipantModel.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="ParticipantView.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<QtLastBackgroundBuild>2023-06-11T06:42:13.1294312Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<QtLastBackgroundBuild>2023-06-11T06:42:13.5051728Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "Participant.h"
|
||||
|
||||
Participant::Participant(std::string name)
|
||||
{
|
||||
this->_name = name;
|
||||
this->_score = 0;
|
||||
}
|
||||
|
||||
Participant::Participant()
|
||||
{
|
||||
this->_name = "";
|
||||
this->_score = -1;
|
||||
}
|
||||
|
||||
std::string Participant::name()
|
||||
{
|
||||
return this->_name;
|
||||
}
|
||||
|
||||
int Participant::score()
|
||||
{
|
||||
return this->_score;
|
||||
}
|
||||
|
||||
void Participant::name(std::string name)
|
||||
{
|
||||
this->_name = name;
|
||||
}
|
||||
|
||||
void Participant::score(int score)
|
||||
{
|
||||
this->_score = score;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
class Participant
|
||||
{
|
||||
private:
|
||||
std::string _name;
|
||||
int _score;
|
||||
public:
|
||||
Participant(std::string name);
|
||||
Participant();
|
||||
~Participant()=default;
|
||||
std::string name();
|
||||
int score();
|
||||
void name(std::string name);
|
||||
void score(int score);
|
||||
};
|
||||
@@ -0,0 +1,97 @@
|
||||
#include "ParticipantModel.h"
|
||||
#include <QRadioButton>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
|
||||
ParticipantModel::ParticipantModel(ParticipantRepo& repo, QuestionRepo& qrepo, QObject* parent) : repo{ repo }, qrepo{ qrepo }, QAbstractTableModel{ parent }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int ParticipantModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return this->qrepo.size();
|
||||
}
|
||||
|
||||
int ParticipantModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
QVariant ParticipantModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
int row = index.row();
|
||||
int column = index.column();
|
||||
Question q = this->qrepo.get_all()[row];
|
||||
if(role == Qt::DisplayRole)
|
||||
{
|
||||
switch(column)
|
||||
{
|
||||
case 0:
|
||||
return QString::number(q.id());
|
||||
case 1:
|
||||
return QString::fromStdString(q.text());
|
||||
case 2:
|
||||
return QString::number(q.score());
|
||||
case 3:
|
||||
return QString("Select");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(role == Qt::BackgroundRole)
|
||||
{
|
||||
if(this->answered.find(row) != this->answered.end())
|
||||
{
|
||||
return QColor{ Qt::green };
|
||||
}
|
||||
}
|
||||
return QVariant{};
|
||||
}
|
||||
|
||||
QVariant ParticipantModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if(role == Qt::DisplayRole)
|
||||
{
|
||||
if(orientation == Qt::Horizontal)
|
||||
{
|
||||
switch(section)
|
||||
{
|
||||
case 0:
|
||||
return QString{ "ID" };
|
||||
case 1:
|
||||
return QString{ "Text" };
|
||||
case 2:
|
||||
return QString{ "Score" };
|
||||
case 3:
|
||||
return QString{ "Selected" };
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return QString::number(section+1);
|
||||
}
|
||||
}
|
||||
return QVariant{};
|
||||
}
|
||||
|
||||
void ParticipantModel::answerQuestion(const int index, const std::string& answer)
|
||||
{
|
||||
|
||||
Question q = this->qrepo.get_all()[index];
|
||||
if(this->answered.find(index) != this->answered.end())
|
||||
{
|
||||
QMessageBox::critical(nullptr, "Error", "Question already answered!");
|
||||
return;
|
||||
}
|
||||
if(q.correct_answer() == answer)
|
||||
{
|
||||
QMessageBox::information(nullptr, "Correct", "Correct answer!");
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(nullptr, "Incorrect", "Incorrect answer!");
|
||||
}
|
||||
this->answered.insert(index);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "ParticipantRepo.h"
|
||||
#include "QuestionRepo.h"
|
||||
#include <qabstractitemmodel.h>
|
||||
#include <QVariant>
|
||||
#include <QModelIndex>
|
||||
#include <unordered_set>
|
||||
|
||||
class ParticipantModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
ParticipantRepo& repo;
|
||||
QuestionRepo& qrepo;
|
||||
std::unordered_set<int> answered;
|
||||
public:
|
||||
ParticipantModel(ParticipantRepo& repo, QuestionRepo& qrepo, QObject* parent = nullptr);
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
void answerQuestion(const int index, const std::string& answer);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "ParticipantRepo.h"
|
||||
#include <stdexcept>
|
||||
#include <fstream>
|
||||
|
||||
ParticipantRepo::ParticipantRepo(std::string file_name)
|
||||
{
|
||||
this->_file_name = file_name;
|
||||
this->read_from_file();
|
||||
}
|
||||
|
||||
std::vector<Participant> ParticipantRepo::get_all()
|
||||
{
|
||||
return this->_participants;
|
||||
}
|
||||
|
||||
int ParticipantRepo::size()
|
||||
{
|
||||
return this->_participants.size();
|
||||
}
|
||||
|
||||
void ParticipantRepo::read_from_file()
|
||||
{
|
||||
std::ifstream file(this->_file_name);
|
||||
if(!file.is_open())
|
||||
throw std::runtime_error("File could not be opened!");
|
||||
std::string line;
|
||||
while(std::getline(file, line) && !line.empty())
|
||||
{
|
||||
Participant p(line);
|
||||
this->_participants.push_back(p);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "Participant.h"
|
||||
#include <vector>
|
||||
|
||||
class ParticipantRepo
|
||||
{
|
||||
private:
|
||||
std::string _file_name;
|
||||
std::vector<Participant> _participants;
|
||||
void read_from_file();
|
||||
public :
|
||||
ParticipantRepo(std::string file_name);
|
||||
~ParticipantRepo()=default;
|
||||
std::vector<Participant> get_all();
|
||||
int size();
|
||||
void write_to_file();
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "ParticipantView.h"
|
||||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
||||
ParticipantView::ParticipantView(ParticipantModel* model, QWidget* parent) : QWidget{ parent }, model{ model }
|
||||
{
|
||||
this->initGUI();
|
||||
this->view->setModel(model);
|
||||
this->connectSignalsAndSlots();
|
||||
}
|
||||
|
||||
ParticipantView::~ParticipantView()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ParticipantView::initGUI()
|
||||
{
|
||||
this->view = new QTableView{};
|
||||
this->answerEdit = new QLineEdit{};
|
||||
this->addButton = new QPushButton{ "Add" };
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout{};
|
||||
layout->addWidget(this->view);
|
||||
layout->addWidget(this->answerEdit);
|
||||
layout->addWidget(this->addButton);
|
||||
|
||||
this->setLayout(layout);
|
||||
}
|
||||
|
||||
void ParticipantView::connectSignalsAndSlots()
|
||||
{
|
||||
QObject::connect(this->addButton, &QPushButton::clicked, this, [this]() {
|
||||
QModelIndexList selectedIndexes = this->view->selectionModel()->selectedIndexes();
|
||||
if (selectedIndexes.size() != 1 || selectedIndexes.at(0).column()!=3)
|
||||
{
|
||||
QMessageBox::critical(this, "Error", "Please select one question!");
|
||||
return;
|
||||
}
|
||||
int index = selectedIndexes.at(0).row();
|
||||
|
||||
std::string answer = this->answerEdit->text().toStdString();
|
||||
this->model->answerQuestion(index, answer);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "ParticipantModel.h"
|
||||
#include <QWidget>
|
||||
#include <QTableView>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
|
||||
class ParticipantView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
ParticipantModel* model;
|
||||
QTableView* view;
|
||||
QLineEdit* answerEdit;
|
||||
QPushButton* addButton;
|
||||
void initGUI();
|
||||
void connectSignalsAndSlots();
|
||||
public:
|
||||
ParticipantView(ParticipantModel* model, QWidget* parent = nullptr);
|
||||
~ParticipantView();
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "PresenterModel.h"
|
||||
|
||||
PresenterModel::PresenterModel(QuestionRepo& repo, QObject* parent) : repo{ repo }, QAbstractTableModel{ parent }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int PresenterModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return this->repo.size();
|
||||
}
|
||||
|
||||
int PresenterModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
QVariant PresenterModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
|
||||
std::vector<Question> questions = this->repo.get_all();
|
||||
Question q = questions[row];
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (col)
|
||||
{
|
||||
case 0:
|
||||
return QString::number(q.id());
|
||||
case 1:
|
||||
return QString::fromStdString(q.text());
|
||||
case 2:
|
||||
return QString::fromStdString(q.correct_answer());
|
||||
case 3:
|
||||
return QString::number(q.score());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PresenterModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case 0:
|
||||
return QString{ "ID" };
|
||||
case 1:
|
||||
return QString{ "Text" };
|
||||
case 2:
|
||||
return QString{ "Correct Answer" };
|
||||
case 3:
|
||||
return QString{ "Score" };
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(role == Qt::DisplayRole && orientation == Qt::Vertical)
|
||||
{
|
||||
return QString::number(section+1);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void PresenterModel::addQuestion(const Question& q)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), this->rowCount(), this->rowCount());
|
||||
this->repo.add(q);
|
||||
endInsertRows();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <qabstractitemmodel.h>
|
||||
#include "QuestionRepo.h"
|
||||
|
||||
class PresenterModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QuestionRepo& repo;
|
||||
|
||||
public:
|
||||
PresenterModel(QuestionRepo& repo, QObject* parent = nullptr);
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
void addQuestion(const Question& q);
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "PresenterView.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QFormLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QHeaderView>
|
||||
|
||||
PresenterView::PresenterView(PresenterModel* model, QWidget* parent) : QWidget{ parent }, model{ model }
|
||||
{
|
||||
this->initGUI();
|
||||
this->view->setModel(model);
|
||||
this->connectSignalsAndSlots();
|
||||
}
|
||||
|
||||
PresenterView::~PresenterView()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PresenterView::initGUI()
|
||||
{
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout{ this };
|
||||
this->setLayout(mainLayout);
|
||||
|
||||
this->view = new QTableView{};
|
||||
mainLayout->addWidget(this->view);
|
||||
|
||||
this->idEdit = new QLineEdit{};
|
||||
auto validator = new QIntValidator{};
|
||||
validator->setBottom(0);
|
||||
this->idEdit->setValidator(validator);
|
||||
this->textEdit = new QLineEdit{};
|
||||
this->answerEdit = new QLineEdit{};
|
||||
this->scoreEdit = new QLineEdit{};
|
||||
this->scoreEdit->setValidator(validator);
|
||||
this->addButton = new QPushButton{ "Add" };
|
||||
|
||||
QFormLayout* formLayout = new QFormLayout{};
|
||||
formLayout->addRow("Id", this->idEdit);
|
||||
formLayout->addRow("Text", this->textEdit);
|
||||
formLayout->addRow("Answer", this->answerEdit);
|
||||
formLayout->addRow("Score", this->scoreEdit);
|
||||
formLayout->addWidget(this->addButton);
|
||||
|
||||
mainLayout->addLayout(formLayout);
|
||||
this->view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
this->setMinimumWidth(1000);
|
||||
this->setWindowTitle("Presenter");
|
||||
}
|
||||
|
||||
void PresenterView::connectSignalsAndSlots()
|
||||
{
|
||||
QObject::connect(this->addButton, &QPushButton::clicked, this, [&](){
|
||||
if(this->idEdit->text().isEmpty() || this->textEdit->text().isEmpty() || this->answerEdit->text().isEmpty() || this->scoreEdit->text().isEmpty())
|
||||
{
|
||||
QMessageBox::critical(this, "Error", "All fields must be filled!");
|
||||
return;
|
||||
}
|
||||
int id = this->idEdit->text().toInt();
|
||||
std::string text = this->textEdit->text().toStdString();
|
||||
std::string answer = this->answerEdit->text().toStdString();
|
||||
int score = this->scoreEdit->text().toInt();
|
||||
Question q{ id, text, answer, score };
|
||||
try{
|
||||
this->model->addQuestion(q);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
QMessageBox::critical(this, "Error", e.what());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "PresenterModel.h"
|
||||
#include <QWidget>
|
||||
#include <QTableView>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
|
||||
class PresenterView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
PresenterModel* model;
|
||||
QTableView* view;
|
||||
QLineEdit* idEdit;
|
||||
QLineEdit* textEdit;
|
||||
QLineEdit* answerEdit;
|
||||
QLineEdit* scoreEdit;
|
||||
QPushButton* addButton;
|
||||
void initGUI();
|
||||
void connectSignalsAndSlots();
|
||||
public:
|
||||
PresenterView(PresenterModel* model, QWidget* parent = nullptr);
|
||||
~PresenterView();
|
||||
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "Question.h"
|
||||
|
||||
Question::Question(int id, std::string text, std::string correct_answer, int score)
|
||||
{
|
||||
this->_id = id;
|
||||
this->_text = text;
|
||||
this->_correct_answer = correct_answer;
|
||||
this->_score = score;
|
||||
}
|
||||
|
||||
Question::Question()
|
||||
{
|
||||
this->_id = -1;
|
||||
this->_text = "";
|
||||
this->_correct_answer = "";
|
||||
this->_score = -1;
|
||||
}
|
||||
|
||||
int Question::id()
|
||||
{
|
||||
return this->_id;
|
||||
}
|
||||
|
||||
std::string Question::text()
|
||||
{
|
||||
return this->_text;
|
||||
}
|
||||
|
||||
std::string Question::correct_answer()
|
||||
{
|
||||
return this->_correct_answer;
|
||||
}
|
||||
|
||||
int Question::score()
|
||||
{
|
||||
return this->_score;
|
||||
}
|
||||
|
||||
void Question::id(int id)
|
||||
{
|
||||
this->_id = id;
|
||||
}
|
||||
|
||||
void Question::text(std::string text)
|
||||
{
|
||||
this->_text = text;
|
||||
}
|
||||
|
||||
void Question::correct_answer(std::string correct_answer)
|
||||
{
|
||||
this->_correct_answer = correct_answer;
|
||||
}
|
||||
|
||||
void Question::score(int score)
|
||||
{
|
||||
this->_score = score;
|
||||
}
|
||||
|
||||
void operator>>(std::string& is, Question& q)
|
||||
{
|
||||
std::string buffer;
|
||||
buffer = is.substr(0, is.find(","));
|
||||
q.id(std::stoi(buffer));
|
||||
is.erase(0, is.find(",") + 1);
|
||||
buffer = is.substr(0, is.find(","));
|
||||
q.text(buffer);
|
||||
is.erase(0, is.find(",") + 1);
|
||||
buffer = is.substr(0, is.find(","));
|
||||
q.correct_answer(buffer);
|
||||
is.erase(0, is.find(",") + 1);
|
||||
buffer = is;
|
||||
q.score(std::stoi(buffer));
|
||||
}
|
||||
|
||||
std::ofstream& operator<<(std::ofstream& os, Question& q)
|
||||
{
|
||||
os << q.id() << "," << q.text() << "," << q.correct_answer() << "," << q.score() << "\n";
|
||||
return os;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
class Question
|
||||
{
|
||||
private:
|
||||
int _id;
|
||||
std::string _text;
|
||||
std::string _correct_answer;
|
||||
int _score;
|
||||
public:
|
||||
Question(int id, std::string text, std::string correct_answer, int score);
|
||||
Question();
|
||||
~Question()=default;
|
||||
int id();
|
||||
std::string text();
|
||||
std::string correct_answer();
|
||||
int score();
|
||||
void id(int id);
|
||||
void text(std::string text);
|
||||
void correct_answer(std::string correct_answer);
|
||||
void score(int score);
|
||||
friend void operator>>(std::string& is, Question& q);
|
||||
friend std::ofstream& operator<<(std::ofstream& os, Question& q);
|
||||
|
||||
};
|
||||
|
||||
void operator>>(std::string& is, Question& q);
|
||||
std::ofstream& operator<<(std::ofstream& os, Question& q);
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "QuestionRepo.h"
|
||||
#include <stdexcept>
|
||||
|
||||
QuestionRepo::QuestionRepo(std::string file_name)
|
||||
{
|
||||
this->_file_name = file_name;
|
||||
this->read_from_file();
|
||||
}
|
||||
|
||||
QuestionRepo::~QuestionRepo()
|
||||
{
|
||||
this->write_to_file();
|
||||
}
|
||||
|
||||
void QuestionRepo::add(Question q)
|
||||
{
|
||||
for(auto& question : this->_questions)
|
||||
if(question.id() == q.id())
|
||||
throw std::runtime_error("Question already exists!");
|
||||
this->_questions.push_back(q);
|
||||
}
|
||||
|
||||
std::vector<Question> QuestionRepo::get_all()
|
||||
{
|
||||
return this->_questions;
|
||||
}
|
||||
|
||||
int QuestionRepo::size()
|
||||
{
|
||||
return this->_questions.size();
|
||||
}
|
||||
|
||||
void QuestionRepo::read_from_file()
|
||||
{
|
||||
std::ifstream file(this->_file_name);
|
||||
if(!file.is_open())
|
||||
throw std::runtime_error("File could not be opened!");
|
||||
std::string line;
|
||||
while(std::getline(file, line) && !line.empty())
|
||||
{
|
||||
Question q;
|
||||
line >> q;
|
||||
this->_questions.push_back(q);
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
void QuestionRepo::write_to_file()
|
||||
{
|
||||
std::ofstream file(this->_file_name);
|
||||
if(!file.is_open())
|
||||
throw std::runtime_error("File could not be opened!");
|
||||
for(auto& question : this->_questions)
|
||||
file << question;
|
||||
file.close();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "vector"
|
||||
#include "Question.h"
|
||||
|
||||
class QuestionRepo
|
||||
{
|
||||
private:
|
||||
std::vector<Question> _questions;
|
||||
std::string _file_name;
|
||||
void read_from_file();
|
||||
void write_to_file();
|
||||
public:
|
||||
QuestionRepo(std::string file_name);
|
||||
~QuestionRepo();
|
||||
void add(Question q);
|
||||
std::vector<Question> get_all();
|
||||
int size();
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#include <QtWidgets/QApplication>
|
||||
#include "PresenterView.h"
|
||||
#include "ParticipantView.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
QuestionRepo repo{"questions.txt"};
|
||||
ParticipantRepo prepo{"participants.txt"};
|
||||
ParticipantModel* pmodel = new ParticipantModel{ prepo, repo };
|
||||
ParticipantView* pview = new ParticipantView{ pmodel };
|
||||
PresenterModel* model = new PresenterModel{ repo };
|
||||
PresenterView* view = new PresenterView{ model};
|
||||
pview->show();
|
||||
|
||||
view->show();
|
||||
return a.exec();
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Ioan
|
||||
@@ -0,0 +1,7 @@
|
||||
1,What is the capital of UK?,London,100
|
||||
2,What is the capital of France?,Paris,100
|
||||
3,What is the capital of Germany?,Berlin,100
|
||||
4,What river runs through London?,Thames,300
|
||||
5,What is the capital of Spain?,Madrid,100
|
||||
6,What is the capital of Italy?,Rome,100
|
||||
10,3,4,4
|
||||
@@ -0,0 +1,53 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
.vscode/
|
||||
@@ -0,0 +1,60 @@
|
||||
# Assignment 01
|
||||
|
||||
## Lab 1 activity
|
||||
|
||||
You should set up a C++ compiler and an IDE. Choose any IDE and compiler you prefer. Later on in the semester we will also work with the Qt framework. Microsoft Visual Studio 2022 can be integrated with Qt development tools.
|
||||
|
||||
If you choose Microsoft Visual Studio, the *Community* version is free.
|
||||
|
||||
Create a new C project and a simple “Hello, World!” C application.
|
||||
|
||||
**Assignment 1 consists of the following requirements and is due in week 2.**
|
||||
|
||||
## Requirements
|
||||
- Write a **C application** (not C++!) with a menu based console interface which solves one of the problems below.
|
||||
- Menu entries are expected for:
|
||||
- reading a vector of numbers from the console,
|
||||
- solving each of the 2 required functionalities,
|
||||
- exiting the program.
|
||||
- Each requirement must be resolved using at least one function. Functions communicate via input/output parameters and the return statement.
|
||||
- Provide specifications for all functions.
|
||||
|
||||
## Problem Statements
|
||||
1. **a.** Generate all the prime numbers smaller than a given natural number `n`.\
|
||||
**b.** Given a vector of numbers, find the longest increasing contiguous subsequence, such the sum of that any 2 consecutive elements is a prime number.
|
||||
|
||||
2. **a.** Generate the first `n` prime numbers (`n` is a given natural number).\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that any two consecutive elements are relatively prime.
|
||||
|
||||
3. **a.** Print the Pascal triangle of dimension `n` of all combinations `C(m,k)` of m objects taken by `k, k = 0, 1, ..., m`, for line `m, where m = 1, 2, ..., n`.\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence of prime numbers.
|
||||
|
||||
4. **a.** Compute the approximated value of square root of a positive real number. The precision is provided by the user.\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that the difference of any two consecutive elements is a prime number.
|
||||
|
||||
5. **a.** Print the exponent of a prime number `p` from the decomposition in prime factors of a given number `n` (n is a non-null natural number).\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that any two consecutive elements are relatively prime.
|
||||
|
||||
6. **a.** Read a sequence of natural numbers (sequence ended by `0`) and determine the number of `0` digits of the product of the read numbers.\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that the sum of any two consecutive elements is a prime number.
|
||||
|
||||
7. **a.** Read sequences of positive integer numbers (reading of each sequence ends by `0`, reading of all the sequences ends by `-1`) and determine the maximum element of each sequence and the maxim element of the global sequence.\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that all elements are in a given interval.
|
||||
|
||||
8. **a.** Determine the value `x^n`, where `x` is a real number and `n` is a natural number, by using multiplication and squared operations.\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that any two consecutive elements have contrary signs.
|
||||
|
||||
9. **a.** Decompose a given natural number in its prime factors.\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that any consecutive elements contain the same digits.
|
||||
|
||||
10. **a.** Decompose a given even natural number, greater than 2, as a sum of two prime numbers (Goldbach’s conjecture).\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that any consecutive elements have at least 2 distinct digits in common.
|
||||
|
||||
11. **a.** Determine the first `n` pairs of twin numbers, where n is a given natural and non-null number. Two prime numbers p and q are called twin if `q – p = 2`.\
|
||||
**b.** Given a vector of numbers, find the longest decreasing contiguous subsequence.
|
||||
|
||||
12. **a.** Determine all the numbers smaller than a given natural and non-null number `n` and that are relatively prime to n.\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence with the maximum sum.
|
||||
|
||||
13. **a.** Determine the first (and only) 8 natural numbers `(x1, x2, …, x8)` greater than 2 with the following property: all the natural numbers smaller than `xi` and that are relatively prime with `xi` (except for the number 1) are prime, `i =1,2, …, n`.\
|
||||
**b.** Given a vector of numbers, find the longest contiguous subsequence such that any consecutive elements contain the same digits.
|
||||
@@ -0,0 +1,217 @@
|
||||
// Problem 8
|
||||
//a. Determine the value x^n, where x is a real number and n is a natural number, by using multiplication and squared operations.
|
||||
//b. Given a vector of numbers, find the longest contiguous subsequence such that any two consecutive elements have contrary signs.
|
||||
|
||||
//Problem 2 for A23
|
||||
|
||||
#include<stdio.h>
|
||||
#include<stdbool.h>
|
||||
#include<stdlib.h>
|
||||
|
||||
int read_vector(int **v);
|
||||
void print_vector(int *v,int size);
|
||||
void print_vector_with_interval(int *v,int start,int end);
|
||||
void ui();
|
||||
float power(float x, int n);
|
||||
int* longest_contiguous_subsequence(int* v,int size_of_v);
|
||||
|
||||
int read_vector(int **v){
|
||||
/*
|
||||
:Params:
|
||||
v: pointer to the pointer of the vector
|
||||
:Returns:
|
||||
size: size of the vector
|
||||
:Description:
|
||||
Reads a vector from the user and returns the size of the vector and the vector itself
|
||||
*/
|
||||
int size;
|
||||
printf("What is the size of the vector?\n");
|
||||
scanf("%d",&size);
|
||||
if (size<=0){
|
||||
return 0;
|
||||
}
|
||||
free(*v);
|
||||
int *p = (int*)malloc(sizeof(int)*size);
|
||||
for(int i=0;i<=size-1;i++){
|
||||
scanf("%d",p+i);
|
||||
}
|
||||
*v=p;
|
||||
return size;
|
||||
}
|
||||
|
||||
void print_vector(int *v,int size){
|
||||
/*
|
||||
:Params:
|
||||
v: pointer to the vector
|
||||
size: size of the vector
|
||||
:Returns:
|
||||
None
|
||||
:Description:
|
||||
Prints the vector
|
||||
*/
|
||||
for(int i=0;i<=size-1;i++){
|
||||
printf("%d ",*(v+i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void print_vector_with_interval(int *v,int start,int end){
|
||||
/*
|
||||
:Params:
|
||||
v: pointer to the vector
|
||||
start: start index
|
||||
end: end index
|
||||
:Returns:
|
||||
None
|
||||
:Description:
|
||||
Prints the vector from start to end
|
||||
*/
|
||||
for(int i=start;i<=end;i++){
|
||||
printf("%d ",*(v+i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void ui(){
|
||||
/*
|
||||
:Params:
|
||||
None
|
||||
:Returns:
|
||||
None
|
||||
:Description:
|
||||
User interface
|
||||
*/
|
||||
int *v=NULL;
|
||||
int size=0;
|
||||
while(true){
|
||||
printf("\
|
||||
1.Read a vector\n\
|
||||
2.Determine the value x^n, where x is a real number and n is a natural number, by using multiplication and squared operations.\n\
|
||||
3.Given a vector of numbers, find the longest contiguous subsequence such that any two consecutive elements have contrary signs.\n\
|
||||
0.Exit\n\
|
||||
\n\
|
||||
");
|
||||
int option=-1;
|
||||
scanf("%d",&option);
|
||||
switch (option)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
int new_size=read_vector(&v);
|
||||
if (new_size==0){
|
||||
printf("Invalid size\n");
|
||||
break;
|
||||
}
|
||||
size=new_size;
|
||||
print_vector(v,size);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
float x;
|
||||
int n;
|
||||
printf("What is the value of x?\n");
|
||||
scanf("%f",&x);
|
||||
printf("What is the value of n?\n");
|
||||
scanf("%d",&n);
|
||||
float result=power(x,n);
|
||||
if (result==0){
|
||||
printf("Invalid power\n");
|
||||
break;
|
||||
}
|
||||
printf("%f\n",result);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
int *p=longest_contiguous_subsequence(v,size);
|
||||
if (p==NULL){
|
||||
printf("Invalid vector\n");
|
||||
break;
|
||||
}
|
||||
print_vector_with_interval(v,*p,*(p+1));
|
||||
free(p);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
goto exit;
|
||||
|
||||
default:
|
||||
printf("Invalid option\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
free(v);
|
||||
}
|
||||
|
||||
float power(float x, int n){
|
||||
/*
|
||||
:Params:
|
||||
x: real number
|
||||
n: natural number
|
||||
:Returns:
|
||||
x^n
|
||||
:Description:
|
||||
Calculates x^n by using multiplication and squared operations
|
||||
*/
|
||||
if (n<0){
|
||||
return 0;
|
||||
}
|
||||
if (n==0){
|
||||
return 1;
|
||||
}
|
||||
if (n==1){
|
||||
return x;
|
||||
}
|
||||
if (n%2==0){
|
||||
return power(x*x,n/2);
|
||||
}
|
||||
return x*power(x*x,(n-1)/2);
|
||||
}
|
||||
|
||||
int* longest_contiguous_subsequence(int* v,int size_of_v){
|
||||
/*
|
||||
:Params:
|
||||
v: pointer to the vector
|
||||
:Returns:
|
||||
p: pointer to the longest contiguous subsequence
|
||||
|
||||
:Description:
|
||||
Finds the longest contiguous subsequence such that any two consecutive elements have contrary signs
|
||||
*/
|
||||
if (size_of_v==0){
|
||||
return NULL;
|
||||
}
|
||||
int start=0;
|
||||
int end=0;
|
||||
int max_size=0;
|
||||
int size=0;
|
||||
for(int i=0;i<size_of_v-1;i++){
|
||||
if ((*(v+i))*(*(v+i+1))<0){
|
||||
size++;
|
||||
}
|
||||
else{
|
||||
if (size>max_size){
|
||||
max_size=size;
|
||||
start=i-size;
|
||||
end=i;
|
||||
}
|
||||
size=0;
|
||||
}
|
||||
}
|
||||
if (size>max_size){
|
||||
start=size_of_v-1-size;
|
||||
end=size_of_v-1;
|
||||
}
|
||||
int *p = malloc(sizeof(int)*2);
|
||||
*(p)=start;
|
||||
*(p+1)=end;
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
int main(){
|
||||
ui();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
.vscode/
|
||||
@@ -0,0 +1,70 @@
|
||||
# Assignment 02-03
|
||||
|
||||
## Requirements
|
||||
- Each student will be given one of the problems below.
|
||||
- The solution must use the **C language**.
|
||||
- The problem should be solved over 2 iterations, due `Week 3` and `Week 4`:
|
||||
|
||||
### Week 3
|
||||
- Solve at least requirements **a** and **b**.
|
||||
- The vector used in the repository can be statically allocated.
|
||||
|
||||
### Week 4
|
||||
- Solve all problem requirements.
|
||||
- Define a vector structure with specific operations using a dynamically allocated array.
|
||||
- Use modular programming.
|
||||
- Source code must be specified and include tests for all non-UI functions
|
||||
- The program must not leak memory!
|
||||
- Use a layered architecture for your application (domain, repository, controller, UI). User interface, domain and data access elements will be stored in different modules. The user interface module will only contain the user interface part.
|
||||
- Have at least 10 entries available at application startup.
|
||||
- Handle user input errors gracefully (replace program crashes with nice error messages :blush:).
|
||||
|
||||
## Bonus possibilities
|
||||
1. Implement the following requirements using function pointers **[deadline: week 4, bonus: 0.1p]**:
|
||||
- For requirement **b**, add a different type of filtering (of your choice).
|
||||
- For requirement **c**, add descending sorting. The user should choose the type of sort and the program will show the list of entities accordingly.
|
||||
2. Provide 2 different implementations for the undo/redo functionality: one using a list of operations (this approach is a precursor of the [Command design pattern](https://en.wikipedia.org/wiki/Command_pattern)) and one where each state of the repository is recorded (this approach is not unlike the [Memento design pattern](https://en.wikipedia.org/wiki/Memento_pattern)). Implement your dynamic array generically, such that it can contain any type of elements (use void*). Use this structure for your repository, as well as to implement both undo/redo functionalities **[deadline: week 5, bonus: 0.1p]**.
|
||||
|
||||
## Problem Statements
|
||||
|
||||
### Pharmacy
|
||||
John is the administrator of the *“Smiles”* Pharmacy. He needs a software application to help him manage his pharmacy's medicine stocks. Each **Medicine** has the following attributes: `name`, `concentration`, `quantity` and `price`. John wants the application to help him in the following ways:\
|
||||
**(a)** Add, delete or update a medicine. A medicine is uniquely identified by its name and concentration. If a product that already exists is added, its quantity will be updated (the new quantity is added to the existing one).\
|
||||
**(b)** See all available medicines containing a given string (if the string is empty, all the available medicines will be considered), sorted ascending by medicine name.\
|
||||
**(c)** See only those medicines that are in short supply (quantity less than `X` items, where the value of `X` is user-provided).\
|
||||
**(d)** Provide multiple undo and redo functionality. Each step will undo/redo the previous operation performed by the user.
|
||||
|
||||
### Bakery
|
||||
Mary runs her family's bakery, *“Bread'n Bagel”*. Every day she struggles with keeping up to date with available stocks of raw materials and would like a program to help her manage the business more effectively. Each **Material** used in the bakery must have: a `name`, a `supplier`, a `quantity` and the `expiration date`. Mary wants a software application that helps her in the following ways:\
|
||||
**(a)** Add, delete and update a material. A raw material is uniquely identified by its name, supplier and expiration date. If a material that already exists is added, its quantity will be modified (the new quantity is added to the existing one).\
|
||||
**(b)** See all available materials past their expiration date, containing a given string (if the string is empty, all materials past their expiration date will be considered).\
|
||||
**(c)** Display all materials from a given supplier, which are in short supply (quantity less than a user-provided value), sorted ascending by their quantities.\
|
||||
**(d)** Provide multiple undo and redo functionality. Each step will undo/redo the previous operation performed by the user.
|
||||
|
||||
### Tourism Agency
|
||||
The employees of *“Happy Holidays”* need an application to manage the offers that the agency has. Each **Offer** has a `type` (one of `seaside, mountain or city break`), a `destination`, a `departure date` and a `price`. The employees need the application to help them in the following ways:\
|
||||
**(a)** Add, delete and update an offer. An offer is uniquely identified by its destination and departure dates.\
|
||||
**(b)** Display all tourism offers whose destinations contain a given string (if the string is empty, all destinations are considered), and show them sorted ascending by price.\
|
||||
**(c)** Display all offers of a given type, having their departure after a given date.\
|
||||
**(d)** Provide multiple undo and redo functionality. Each step will undo/redo the previous operation performed by the user.
|
||||
|
||||
### Real Estate Agency
|
||||
Evelyn owns a real estate agency. Being also the only employee, she needs an application to help her manage all the real estates of her clients. Each **Estate** has a type (one of `house, apartment or penthouse`), an `address`, a `surface` and a `price`. Evelyn needs the application to help her in the following ways:\
|
||||
**(a)** Add, delete or update an estate. An estate is uniquely identified by its address.\
|
||||
**(b)** Display all estates whose address contains a given string (if the string is empty, all estates will be considered), sorted ascending by their price.\
|
||||
**(c)** See all estates of a given type, having the surface greater than a user provided value.\
|
||||
**(d)** Provide multiple undo and redo functionality. Each step will undo/redo the previous operation performed by the user.
|
||||
|
||||
### Intelligent Refrigerator
|
||||
The company *“Home SmartApps”* have decided to design a new intelligent refrigerator. Besides the hardware, they need a software application to manage the refrigerator. Each **Product** that the fridge can store has a `name`, a `category` (one of `dairy, sweets, meat or fruit`), a `quantity` and an `expiration date`. The software application will provide the following functionalities:\
|
||||
**(a)** Add, delete or update a product. A product is uniquely identified by name and category. If a product that already exists is added, its quantity will be updated (the new quantity is added to the existing one).\
|
||||
**(b)** Display all products whose name contains a given string (if the string is empty, all products from the refrigerator are considered), and show them sorted ascending by the existing quantity.\
|
||||
**(c)** Display all products of a given category (if the category is empty, all types of food will be considered) whose expiration dates are close (expire in the following `X` days, where the value of `X` is user-provided).\
|
||||
**(d)** Provide multiple undo and redo functionality. Each step will undo/redo the previous operation performed by the user.
|
||||
|
||||
### World Population Monitoring
|
||||
The World Population Monitoring Organisation needs an application to help keep track of countries’ populations. Each **Country** has a unique `name`, the `continent` it belongs to (one of `Europe, America, Africa, Australia or Asia`), and a population (stored in millions). The employees of the organisation need the application to help them in the following ways:\
|
||||
**(a)** Add, delete or update a country. Updating must also consider the case of migration: a given number of people leave one country to migrate to another.\
|
||||
**(b)** Display all countries whose name contains a given string (if the string is empty, all the countries should be considered).\
|
||||
**(c)** Display all countries on a given continent (if the continent is empty, all countries will be considered), whose populations are greater than a given value, sorted ascending by population.\
|
||||
**(d)** Provide multiple undo and redo functionality. Each step will undo/redo the previous operation performed by the user.
|
||||
@@ -0,0 +1,364 @@
|
||||
#include "UI.h"
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
#include "../controller/controller.h"
|
||||
|
||||
UI _UI_Constructor(Controller *controller){
|
||||
UI ui;
|
||||
ui.controller=controller;
|
||||
return ui;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _UI_Destructor(UI* ui){
|
||||
_Controller_Destructor(ui->controller);
|
||||
}
|
||||
|
||||
|
||||
void _UI_start(UI* ui ){
|
||||
while(1){
|
||||
printf("\n");
|
||||
printf("1. Add a material\n");
|
||||
printf("2. Delete a material\n");
|
||||
printf("3. Update a material\n");
|
||||
printf("4. List all materials\n");
|
||||
printf("5. See all available materials past their expiration date\n");
|
||||
printf("6. See all materials with a given supplier which are in short supply\n");
|
||||
printf("7. Undo\n");
|
||||
printf("8. Redo\n");
|
||||
printf("9. Exit\n");
|
||||
printf("\n");
|
||||
printf("Enter command: ");
|
||||
char command = getchar();
|
||||
char buffer;
|
||||
if (command!='\n'&&(buffer=getchar())!='\n'&&buffer!=EOF){
|
||||
while(getchar()!='\n'&&buffer!=EOF);
|
||||
printf("Invalid Command\n");
|
||||
continue;
|
||||
}
|
||||
switch (command){
|
||||
case '1':
|
||||
{
|
||||
char* name = (char*)malloc(255);
|
||||
char* supplier=(char*)malloc(255);
|
||||
int quantity;
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
char* buffer = (char*)malloc(255);
|
||||
printf("Enter name: ");
|
||||
fgets(name,255,stdin);
|
||||
name[strlen(name)-1]='\0';
|
||||
if(strlen(name)==0){
|
||||
printf("Invalid name\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter supplier: ");
|
||||
fgets(supplier,255,stdin);
|
||||
supplier[strlen(supplier)-1]='\0';
|
||||
if(strlen(supplier)==0){
|
||||
printf("Invalid supplier\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter quantity: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
quantity = atoi(buffer);
|
||||
if (quantity==0){
|
||||
printf("Invalid quantity\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter day: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
day = atoi(buffer);
|
||||
if (day==0 || day>31){
|
||||
printf("Invalid day\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter month: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
month = atoi(buffer);
|
||||
if (month==0 || month>12){
|
||||
printf("Invalid month\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter year: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
year = atoi(buffer);
|
||||
if (year==0 || year<1900){
|
||||
printf("Invalid year\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
free(buffer);
|
||||
int response = _Controller_add(ui->controller,name,supplier,quantity,day,month,year);
|
||||
if(response==0){
|
||||
printf("Material added successfully\n");
|
||||
}
|
||||
else if(response==1){
|
||||
printf("Material not added\n");
|
||||
}
|
||||
else{
|
||||
printf("Material already exists. Updated quantity\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '2':
|
||||
{
|
||||
char* name = (char*)malloc(255);
|
||||
char* supplier=(char*)malloc(255);
|
||||
int quantity;
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
char* buffer = (char*)malloc(255);
|
||||
printf("Enter name: ");
|
||||
fgets(name,255,stdin);
|
||||
name[strlen(name)-1]='\0';
|
||||
if(strlen(name)==0){
|
||||
printf("Invalid name\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter supplier: ");
|
||||
fgets(supplier,255,stdin);
|
||||
supplier[strlen(supplier)-1]='\0';
|
||||
if(strlen(supplier)==0){
|
||||
printf("Invalid supplier\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter day: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
day = atoi(buffer);
|
||||
if (day==0 || day>31){
|
||||
printf("Invalid day\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter month: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
month = atoi(buffer);
|
||||
if (month==0 || month>12){
|
||||
printf("Invalid month\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter year: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
year = atoi(buffer);
|
||||
if (year==0 || year<1900){
|
||||
printf("Invalid year\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
free(buffer);
|
||||
int response = _Controller_delete(ui->controller,name,supplier,day,month,year);
|
||||
if(response==0){
|
||||
printf("Material deleted successfully\n");
|
||||
}
|
||||
else{
|
||||
printf("Material not deleted\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '3':
|
||||
{
|
||||
char* name = (char*)malloc(255);
|
||||
char* supplier=(char*)malloc(255);
|
||||
int quantity;
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
char* buffer = (char*)malloc(255);
|
||||
printf("Enter name: ");
|
||||
fgets(name,255,stdin);
|
||||
name[strlen(name)-1]='\0';
|
||||
if (strlen(name)==0){
|
||||
printf("Invalid name\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter supplier: ");
|
||||
fgets(supplier,255,stdin);
|
||||
supplier[strlen(supplier)-1]='\0';
|
||||
if (strlen(supplier)==0){
|
||||
printf("Invalid supplier\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter quantity: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
quantity = atoi(buffer);
|
||||
if (quantity==0){
|
||||
printf("Invalid quantity\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter day: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
day = atoi(buffer);
|
||||
if (day==0 || day>31){
|
||||
printf("Invalid day\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter month: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
month = atoi(buffer);
|
||||
if (month==0 || month>12){
|
||||
printf("Invalid month\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
printf("Enter year: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
year = atoi(buffer);
|
||||
if (year==0 || year<1900){
|
||||
printf("Invalid year\n");
|
||||
free(buffer);
|
||||
free(name);
|
||||
free(supplier);
|
||||
break;
|
||||
}
|
||||
free(buffer);
|
||||
int response = _Controller_update(ui->controller,name,supplier,quantity,day,month,year);
|
||||
if(response==0){
|
||||
printf("Material updated successfully\n");
|
||||
}
|
||||
else{
|
||||
printf("Material not updated\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '4':
|
||||
{
|
||||
for(int i=0;i<_Controller_getLenght(ui->controller);i++){
|
||||
char* s =_Material_stringify(_Controller_getItem(ui->controller,i));
|
||||
printf("%s",s);
|
||||
free(s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '5':
|
||||
{
|
||||
char string[255];
|
||||
printf("Enter string to compare: ");
|
||||
fgets(string,255,stdin);
|
||||
int lenght=0;
|
||||
Material** vector_material=_Controller_getExpiredMaterial(ui->controller,string,&lenght);
|
||||
for(int i=0;i<lenght;i++){
|
||||
char* s =_Material_stringify(vector_material[i]);
|
||||
printf("%s",s);
|
||||
free(s);
|
||||
}
|
||||
free(vector_material);
|
||||
break;
|
||||
}
|
||||
case '6':
|
||||
{
|
||||
int quantity;
|
||||
char* buffer = (char*)malloc(255);
|
||||
printf("Enter quantity: ");
|
||||
fgets(buffer,255,stdin);
|
||||
buffer[strlen(buffer)-1]='\0';
|
||||
quantity = atoi(buffer);
|
||||
if (quantity==0){
|
||||
printf("Invalid quantity\n");
|
||||
free(buffer);
|
||||
break;
|
||||
}
|
||||
free(buffer);
|
||||
Vector* vector = _Controller_getShortSupplyItems(ui->controller,quantity);
|
||||
for(int i=0;i<_Vector_getLength(vector);i++){
|
||||
char* s =_Material_stringify((Material*)_Vector_getItem(vector,i));
|
||||
printf("%s",s);
|
||||
free(s);
|
||||
}
|
||||
_Vector_Destructor(vector);
|
||||
break;
|
||||
}
|
||||
case '7':
|
||||
{
|
||||
int response = _Controller_undo(ui->controller);
|
||||
if(response==0){
|
||||
printf("Undo successful\n");
|
||||
}
|
||||
else{
|
||||
printf("Undo not successful\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '8':
|
||||
{
|
||||
int response = _Controller_redo(ui->controller);
|
||||
if(response==0){
|
||||
printf("Redo successful\n");
|
||||
}
|
||||
else{
|
||||
printf("Redo not successful\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '9':
|
||||
{
|
||||
_UI_Destructor(ui);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
{
|
||||
printf("Invalid Command\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "../controller/controller.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Controller *controller;
|
||||
} UI;
|
||||
|
||||
UI _UI_Constructor(Controller *controller);
|
||||
|
||||
void _UI_Destructor(UI* ui);
|
||||
|
||||
void _UI_start(UI* ui);
|
||||
@@ -0,0 +1,226 @@
|
||||
#include "controller.h"
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Controller* _Controller_Constructor(Repository* repository,UndoController* undo_controller){
|
||||
Controller* controller = (Controller*)malloc(sizeof(Controller));
|
||||
if (controller==NULL)
|
||||
return NULL;
|
||||
controller->repository=repository;
|
||||
controller->undo_controller=undo_controller;
|
||||
return controller;
|
||||
}
|
||||
|
||||
void _Controller_Destructor(Controller* controller){
|
||||
if (controller==NULL)
|
||||
return;
|
||||
_Repository_Destructor(controller->repository);
|
||||
_UndoController_Destructor(controller->undo_controller);
|
||||
controller->repository=NULL;
|
||||
free(controller);
|
||||
}
|
||||
|
||||
int _Controller_add(Controller* controller, char *name, char *supplier, int quantity, int day, int month, int year){
|
||||
if (controller==NULL)
|
||||
return 1;
|
||||
if (name==NULL)
|
||||
return 1;
|
||||
if (supplier==NULL)
|
||||
return 1;
|
||||
Material* material = _Material_Constructor(name,supplier,quantity,day,month,year);
|
||||
int response = _Repository_add(controller->repository,material);
|
||||
switch (response)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Vector* argsDo = _Vector_Constructor(2);
|
||||
_Vector_add(argsDo,controller->repository);
|
||||
_Vector_add(argsDo,material);
|
||||
FunctionCall* doFunction = _FunctionCall_Constructor(_Repository_add,argsDo);
|
||||
Vector* argsUndo = _Vector_Constructor(2);
|
||||
_Vector_add(argsUndo,controller->repository);
|
||||
char* copy_name=(char*)malloc(255);
|
||||
strcpy(copy_name,name);
|
||||
char* copy_supplier = (char*)malloc(255);
|
||||
strcpy(copy_supplier,supplier);
|
||||
Material* copy_material = _Material_Constructor(copy_name,copy_supplier,quantity,day,month,year);
|
||||
_Vector_add(argsUndo,copy_material);
|
||||
FunctionCall* undoFunction = _FunctionCall_Constructor(_Repository_delete,argsUndo);
|
||||
Operation* operation = _Operation_Constructor(doFunction,undoFunction);
|
||||
_UndoController_recordOperation(controller->undo_controller,operation);
|
||||
return 0;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
Vector* argsDo = _Vector_Constructor(2);
|
||||
_Vector_add(argsDo,controller->repository);
|
||||
_Vector_add(argsDo,material);
|
||||
FunctionCall* doFunction = _FunctionCall_Constructor(_Repository_add,argsDo);
|
||||
Vector* argsUndo = _Vector_Constructor(2);
|
||||
_Vector_add(argsUndo,controller->repository);
|
||||
char* copy_name=(char*)malloc(255);
|
||||
strcpy(copy_name,name);
|
||||
char* copy_supplier = (char*)malloc(255);
|
||||
strcpy(copy_supplier,supplier);
|
||||
Material* negativeMaterial = _Material_Constructor(copy_name,copy_supplier,-_Material_GetQuantity(material),_Material_GetDate(material).tm_mday,_Material_GetDate(material).tm_mon+1,_Material_GetDate(material).tm_year);
|
||||
_Vector_add(argsUndo,negativeMaterial);
|
||||
FunctionCall* undoFunction = _FunctionCall_Constructor(_Repository_add,argsUndo);
|
||||
Operation* operation = _Operation_Constructor(doFunction,undoFunction);
|
||||
_UndoController_recordOperation(controller->undo_controller,operation);
|
||||
return 2;
|
||||
}
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int _Controller_delete(Controller* controller, char *name, char *supplier, int day, int month, int year){
|
||||
if (controller==NULL)
|
||||
return 1;
|
||||
if (name==NULL)
|
||||
return 1;
|
||||
if (supplier==NULL)
|
||||
return 1;
|
||||
Material* material = _Material_Constructor(name,supplier,0,day,month,year);
|
||||
int response = _Repository_delete(controller->repository,material);
|
||||
switch (response)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Vector* argsDo = _Vector_Constructor(2);
|
||||
_Vector_add(argsDo,controller->repository);
|
||||
_Vector_add(argsDo,material);
|
||||
FunctionCall* doFunction = _FunctionCall_Constructor(_Repository_delete,argsDo);
|
||||
Vector* argsUndo = _Vector_Constructor(2);
|
||||
_Vector_add(argsUndo,controller->repository);
|
||||
char* copy_name=(char*)malloc(255);
|
||||
strcpy(copy_name,name);
|
||||
char* copy_supplier = (char*)malloc(255);
|
||||
strcpy(copy_supplier,supplier);
|
||||
Material* copy_material = _Material_Constructor(copy_name,copy_supplier,_Material_GetQuantity(material),day,month,year);
|
||||
_Vector_add(argsUndo,copy_material);
|
||||
FunctionCall* undoFunction = _FunctionCall_Constructor(_Repository_add,argsUndo);
|
||||
Operation* operation = _Operation_Constructor(doFunction,undoFunction);
|
||||
_UndoController_recordOperation(controller->undo_controller,operation);
|
||||
return 0;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int _Controller_update(Controller* controller,char *name, char *supplier, int quantity, int day, int month, int year){
|
||||
if (controller==NULL)
|
||||
return 1;
|
||||
if (name==NULL)
|
||||
return 1;
|
||||
if (supplier==NULL)
|
||||
return 1;
|
||||
Material* material = _Material_Constructor(name,supplier,quantity,day,month,year);
|
||||
int response = _Repository_update(controller->repository,material);
|
||||
switch (response)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
Vector* argsUndo = _Vector_Constructor(2);
|
||||
_Vector_add(argsUndo,controller->repository);
|
||||
_Vector_add(argsUndo,material);
|
||||
FunctionCall* undoFunction = _FunctionCall_Constructor(_Repository_update,argsUndo);
|
||||
Vector* argsDo = _Vector_Constructor(2);
|
||||
_Vector_add(argsDo,controller->repository);
|
||||
char* copy_name=(char*)malloc(255);
|
||||
strcpy(copy_name,name);
|
||||
char* copy_supplier = (char*)malloc(255);
|
||||
strcpy(copy_supplier,supplier);
|
||||
Material* new_material = _Material_Constructor(copy_name,copy_supplier,quantity,day,month,year);
|
||||
_Vector_add(argsDo,new_material);
|
||||
FunctionCall* doFunction = _FunctionCall_Constructor(_Repository_update,argsDo);
|
||||
Operation* operation = _Operation_Constructor(doFunction,undoFunction);
|
||||
_UndoController_recordOperation(controller->undo_controller,operation);
|
||||
return 0;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int _Controller_getLenght(Controller* controller){
|
||||
if (controller==NULL)
|
||||
return 0;
|
||||
return _Repository_getLenght(controller->repository);
|
||||
}
|
||||
|
||||
Material* _Controller_getItem(Controller* controller,int index){
|
||||
if (controller==NULL)
|
||||
return NULL;
|
||||
return _Repository_getItem(controller->repository,index);
|
||||
}
|
||||
|
||||
Material** _Controller_getExpiredMaterial(Controller* controller,char* string,int* lenght){
|
||||
int len=_Controller_getLenght(controller);
|
||||
Material** vector = (Material**)malloc(sizeof(Material)*len);
|
||||
time_t t = time(NULL);
|
||||
struct tm current_time = *localtime(&t);
|
||||
current_time.tm_year+=1900;
|
||||
string[strlen(string)-1]='\0';
|
||||
for(int i=0;i<len;i++){
|
||||
Material* material=_Controller_getItem(controller,i);
|
||||
if ((strstr(material->name,string)!=NULL||strlen(string)==0||string[0]=='\n')&&(material->expiration_date.tm_year<current_time.tm_year ||(material->expiration_date.tm_year==current_time.tm_year && material->expiration_date.tm_mon<current_time.tm_mon)||(material->expiration_date.tm_year==current_time.tm_year && material->expiration_date.tm_mon==current_time.tm_mon && material->expiration_date.tm_mday<current_time.tm_mday))){
|
||||
vector[*lenght]=material;
|
||||
(*lenght)++;
|
||||
}
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
Vector* _Controller_getShortSupplyItems(Controller* controller, int quantity){
|
||||
int len = _Controller_getLenght(controller);
|
||||
Vector* vector = _Vector_Constructor(5);
|
||||
for(int i=0;i<len;i++){
|
||||
Material* material=_Controller_getItem(controller,i);
|
||||
if(_Material_GetQuantity(material)<quantity)
|
||||
_Vector_add(vector,material);
|
||||
}
|
||||
for(int i=0;i<_Vector_getLength(vector)-1;i++){
|
||||
for(int j=i;j<_Vector_getLength(vector);j++){
|
||||
if(_Material_GetQuantity((Material*)_Vector_getItem(vector,i)) > _Material_GetQuantity((Material*)_Vector_getItem(vector,j))){
|
||||
TElem aux = vector->elems[i];
|
||||
vector->elems[i] = vector->elems[j];
|
||||
vector->elems[j] = aux;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
int _Controller_undo(Controller* controller){
|
||||
if (controller==NULL)
|
||||
return 1;
|
||||
return _UndoController_undo(controller->undo_controller);
|
||||
}
|
||||
|
||||
int _Controller_redo(Controller* controller){
|
||||
if (controller==NULL)
|
||||
return 1;
|
||||
return _UndoController_redo(controller->undo_controller);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
#include "../repository/repository.h"
|
||||
#include "../undo_module/undo_controller/undo_controller.h"
|
||||
|
||||
typedef struct{
|
||||
Repository* repository;
|
||||
UndoController* undo_controller;
|
||||
} Controller;
|
||||
|
||||
/*
|
||||
Constructor for the Controller
|
||||
Input: repository - Repository*
|
||||
Output: a pointer to the newly created controller
|
||||
*/
|
||||
Controller* _Controller_Constructor(Repository* repository,UndoController* undo_controller);
|
||||
|
||||
/*
|
||||
Destructor for the Controller
|
||||
Input: controller - Controller*
|
||||
Output: -
|
||||
*/
|
||||
void _Controller_Destructor(Controller* controller);
|
||||
|
||||
/*
|
||||
Adds an element to the repository
|
||||
Input: controller - Controller*
|
||||
name - char* - the name of the material
|
||||
supplier - char* - the supplier of the material
|
||||
quantity - int - the quantity of the material
|
||||
day - int - the day of the expiration date
|
||||
month - int - the month of the expiration date
|
||||
year - int - the year of the expiration date
|
||||
Output: 1 - if the element was added
|
||||
0 - if the element was not added
|
||||
2 - if the element was not added because it already exists
|
||||
*/
|
||||
int _Controller_add(Controller* controller, char *name, char *supplier, int quantity, int day, int month, int year);
|
||||
|
||||
/*
|
||||
Deletes an element from the repository
|
||||
Input: controller - Controller*
|
||||
name - char* - the name of the material
|
||||
supplier - char* - the supplier of the material
|
||||
day - int - the day of the expiration date
|
||||
month - int - the month of the expiration date
|
||||
year - int - the year of the expiration date
|
||||
Output: 1 - if the element was deleted
|
||||
0 - if the element was not deleted
|
||||
*/
|
||||
int _Controller_delete(Controller* controller, char *name, char *supplier, int day, int month, int year);
|
||||
|
||||
/*
|
||||
Updates an element from the repository
|
||||
Input: controller - Controller*
|
||||
name - char* - the name of the material
|
||||
supplier - char* - the supplier of the material
|
||||
quantity - int - the quantity of the material
|
||||
day - int - the day of the expiration date
|
||||
month - int - the month of the expiration date
|
||||
year - int - the year of the expiration date
|
||||
Output: 1 - if the element was updated
|
||||
0 - if the element was not updated
|
||||
*/
|
||||
int _Controller_update(Controller* controller,char *name, char *supplier, int quantity, int day, int month, int year);
|
||||
|
||||
/*
|
||||
Gets the lenght of the repository
|
||||
Input: controller - Controller*
|
||||
Output: int - the lenght of the repository
|
||||
*/
|
||||
int _Controller_getLenght(Controller* controller);
|
||||
|
||||
/*
|
||||
Gets an element from the repository
|
||||
Input: controller - Controller*
|
||||
index - int - the index of the element to be returned
|
||||
Output: Material* - the element at the given index
|
||||
NULL - if the index is invalid
|
||||
*/
|
||||
Material* _Controller_getItem(Controller* controller,int index);
|
||||
|
||||
/*
|
||||
Gets the expired material matching the given string
|
||||
Input: controller - Controller*
|
||||
string - char* - the string to be matched
|
||||
lenght - int* - the lenght of the retruned array
|
||||
Output: Material** - the array of expired material matching the given string
|
||||
*/
|
||||
Material** _Controller_getExpiredMaterial(Controller* controller,char* string,int* lenght);
|
||||
|
||||
/*
|
||||
Gets the material with quantity less than the given quantity
|
||||
Input: controller - Controller*
|
||||
quantity - int - the quantity to be matched
|
||||
Output: Vector* - the vector of material with the given quantity
|
||||
*/
|
||||
Vector* _Controller_getShortSupplyItems(Controller* controller, int quantity);
|
||||
|
||||
/*
|
||||
Undoes the last operation
|
||||
Input: controller - Controller*
|
||||
Output: 1 - if the operation was undone
|
||||
0 - if the operation was not undone
|
||||
*/
|
||||
int _Controller_undo(Controller* controller);
|
||||
|
||||
/*
|
||||
Redoes the last operation
|
||||
Input: controller - Controller*
|
||||
Output: 1 - if the operation was redone
|
||||
0 - if the operation was not redone
|
||||
*/
|
||||
int _Controller_redo(Controller* controller);
|
||||
@@ -0,0 +1,50 @@
|
||||
#include "domain.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Material* _Material_Constructor(char *name, char *supplier, int quantity, int day, int month, int year)
|
||||
{
|
||||
Material* m =(Material*)malloc(sizeof(Material));
|
||||
m->name=name;
|
||||
m->supplier=supplier;
|
||||
m->quantity = quantity;
|
||||
m->expiration_date.tm_mday = day;
|
||||
m->expiration_date.tm_mon = month-1;
|
||||
m->expiration_date.tm_year = year;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _Material_Destructor(Material *material){
|
||||
free(material->name);
|
||||
free(material->supplier);
|
||||
free(material);
|
||||
}
|
||||
|
||||
char* _Material_GetName(Material *material){
|
||||
return material->name;
|
||||
}
|
||||
|
||||
char* _Material_GetSupplier(Material *material){
|
||||
return material->supplier;
|
||||
}
|
||||
|
||||
int _Material_GetQuantity(Material *material){
|
||||
return material->quantity;
|
||||
}
|
||||
|
||||
struct tm _Material_GetDate(Material *material){
|
||||
return material->expiration_date;
|
||||
}
|
||||
|
||||
void _Material_SetQuantity(Material *material, int quantity){
|
||||
material->quantity = quantity;
|
||||
}
|
||||
|
||||
char* _Material_stringify(Material *material){
|
||||
char* string =(char*)malloc(sizeof(char)*255);
|
||||
sprintf(string,"Name: %s | Supplier: %s | Quantity: %d | Expiration Date: %02d/%02d/%d\n",material->name,material->supplier,material->quantity,material->expiration_date.tm_mday,material->expiration_date.tm_mon+1,material->expiration_date.tm_year);
|
||||
return string;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
#include<time.h>
|
||||
|
||||
typedef struct{
|
||||
char *name;
|
||||
char *supplier;
|
||||
int quantity;
|
||||
struct tm expiration_date;
|
||||
} Material;
|
||||
|
||||
/*
|
||||
Constructor for Material
|
||||
Input: name - char*
|
||||
supplier - char*
|
||||
quantity - int
|
||||
day - int
|
||||
month - int
|
||||
year - int
|
||||
Output: Material* - pointer to the newly created Material
|
||||
*/
|
||||
Material* _Material_Constructor(char *name, char *supplier, int quantity, int day, int month, int year);
|
||||
|
||||
/*
|
||||
Destructor for Material
|
||||
Input: material - Material*
|
||||
Output: -
|
||||
*/
|
||||
void _Material_Destructor(Material *material);
|
||||
|
||||
/*
|
||||
Getter for name
|
||||
Input: material - Material*
|
||||
Output: char* - name
|
||||
*/
|
||||
char* _Material_GetName(Material *material);
|
||||
|
||||
/*
|
||||
Getter for supplier
|
||||
Input: material - Material*
|
||||
Output: char* - supplier
|
||||
*/
|
||||
char* _Material_GetSupplier(Material *material);
|
||||
|
||||
/*
|
||||
Getter for quantity
|
||||
Input: material - Material*
|
||||
Output: int - quantity
|
||||
*/
|
||||
int _Material_GetQuantity(Material *material);
|
||||
|
||||
/*
|
||||
Getter for expiration date
|
||||
Input: material - Material*
|
||||
Output: struct tm - expiration date
|
||||
*/
|
||||
struct tm _Material_GetDate(Material *material);
|
||||
|
||||
/*
|
||||
Setter for name
|
||||
Input: material - Material*
|
||||
name - char*
|
||||
Output: -
|
||||
*/
|
||||
void _Material_SetQuantity(Material *material, int quantity);
|
||||
|
||||
/*
|
||||
Setter for supplier
|
||||
Input: material - Material*
|
||||
supplier - char*
|
||||
Output: -
|
||||
*/
|
||||
char* _Material_stringify(Material *material);
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include "domain/domain.h"
|
||||
#include "vector/vector.h"
|
||||
#include "UI/UI.h"
|
||||
#include "repository/repository.h"
|
||||
#include "controller/controller.h"
|
||||
#include "undo_module/undo_controller/undo_controller.h"
|
||||
#include "undo_module/function_call/functioncall.h"
|
||||
#include "undo_module/operation/operation.h"
|
||||
#include<string.h>
|
||||
#include "tests/tests.h"
|
||||
|
||||
|
||||
void add_materials(Controller* controller){
|
||||
char* name;
|
||||
char* supplier;
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Water");
|
||||
strcpy(supplier,"Bucovina");
|
||||
_Controller_add(controller,name,supplier,20,2,3,2025);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Water");
|
||||
strcpy(supplier,"Dorna");
|
||||
_Controller_add(controller,name,supplier,5,16,10,2026);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Flour");
|
||||
strcpy(supplier,"Boromir");
|
||||
_Controller_add(controller,name,supplier,25,16,10,2023);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Flour");
|
||||
strcpy(supplier,"Titan");
|
||||
_Controller_add(controller,name,supplier,25,4,1,2023);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Sugar");
|
||||
strcpy(supplier,"Margarita");
|
||||
_Controller_add(controller,name,supplier,25,7,11,2021);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Sugar");
|
||||
strcpy(supplier,"Diamant");
|
||||
_Controller_add(controller,name,supplier,125,23,10,2021);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Rum Extract");
|
||||
strcpy(supplier,"Diamant");
|
||||
_Controller_add(controller,name,supplier,65,23,10,2021);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Vanilla Extract");
|
||||
strcpy(supplier,"Diamant");
|
||||
_Controller_add(controller,name,supplier,45,23,10,2025);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Apples");
|
||||
strcpy(supplier,"Eco Fruits");
|
||||
_Controller_add(controller,name,supplier,95,4,9,2021);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Plums");
|
||||
strcpy(supplier,"Eco Fruits");
|
||||
_Controller_add(controller,name,supplier,15,22,11,2021);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
testAll();
|
||||
Repository* repository = _Repository_Constructor();
|
||||
UndoController* undo_controller = _UndoController_Constructor();
|
||||
Controller* controller = _Controller_Constructor(repository,undo_controller);
|
||||
UI ui = _UI_Constructor(controller);
|
||||
add_materials(controller);
|
||||
_UI_start(&ui);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "repository.h"
|
||||
#include "../vector/vector.h"
|
||||
#include <string.h>
|
||||
#include<time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Repository* _Repository_Constructor(){
|
||||
Repository* repository = (Repository*)malloc(sizeof(Repository));
|
||||
if (repository==NULL)
|
||||
return NULL;
|
||||
repository->elements=_Vector_Constructor(10);
|
||||
return repository;
|
||||
}
|
||||
|
||||
void _Repository_Destructor(Repository* repository){
|
||||
if (repository==NULL)
|
||||
return;
|
||||
_Vector_Destructor(repository->elements);
|
||||
repository->elements=NULL;
|
||||
free(repository);
|
||||
|
||||
}
|
||||
|
||||
int _Repository_add(Repository* repository, Material* material){
|
||||
if (repository==NULL)
|
||||
return 1;
|
||||
if (material==NULL)
|
||||
return 1;
|
||||
for(int i=0;i<_Vector_getLength(repository->elements);i++){
|
||||
Material* item =_Vector_getItem(repository->elements,i);
|
||||
if(strcmp(item->name,material->name)==0&&strcmp(item->name,material->name)==0&&item->expiration_date.tm_mday==material->expiration_date.tm_mday&&item->expiration_date.tm_mon==material->expiration_date.tm_mon&&item->expiration_date.tm_year==material->expiration_date.tm_year){
|
||||
_Material_SetQuantity(item,_Material_GetQuantity(item)+_Material_GetQuantity(material));
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
_Vector_add(repository->elements,material);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _Repository_delete(Repository* repository, Material* material){
|
||||
if (repository==NULL)
|
||||
return 1;
|
||||
if (material==NULL)
|
||||
return 1;
|
||||
for(int i=0;i<_Vector_getLength(repository->elements);i++){
|
||||
Material* item =_Vector_getItem(repository->elements,i);
|
||||
if(strcmp(item->name,material->name)==0&&strcmp(item->name,material->name)==0&&item->expiration_date.tm_mday==material->expiration_date.tm_mday&&item->expiration_date.tm_mon==material->expiration_date.tm_mon&&item->expiration_date.tm_year==material->expiration_date.tm_year){
|
||||
int quantity = _Material_GetQuantity(item);
|
||||
_Vector_delete(repository->elements,i);
|
||||
_Material_SetQuantity(material,quantity);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _Repository_update(Repository* repository, Material* material){
|
||||
if (repository==NULL)
|
||||
return 1;
|
||||
if (material==NULL)
|
||||
return 1;
|
||||
for(int i=0;i<_Vector_getLength(repository->elements);i++){
|
||||
Material* item =_Vector_getItem(repository->elements,i);
|
||||
if(strcmp(item->name,material->name)==0&&strcmp(item->name,material->name)==0&&item->expiration_date.tm_mday==material->expiration_date.tm_mday&&item->expiration_date.tm_mon==material->expiration_date.tm_mon&&item->expiration_date.tm_year==material->expiration_date.tm_year){
|
||||
int quantity = _Material_GetQuantity(item);
|
||||
_Material_SetQuantity(item,_Material_GetQuantity(material));
|
||||
_Material_SetQuantity(material,quantity);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _Repository_getLenght(Repository* repository){
|
||||
return _Vector_getLength(repository->elements);
|
||||
}
|
||||
|
||||
Material* _Repository_getItem(Repository* repository,int index){
|
||||
return (Material*)_Vector_getItem(repository->elements,index);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
#include "../vector/vector.h"
|
||||
#include "../domain/domain.h"
|
||||
|
||||
typedef struct {
|
||||
Vector* elements;
|
||||
} Repository;
|
||||
|
||||
/*
|
||||
Constructor for the Repository
|
||||
Input: -
|
||||
Output: a pointer to the newly created repository
|
||||
*/
|
||||
Repository* _Repository_Constructor();
|
||||
|
||||
/*
|
||||
Destructor for the Repository
|
||||
Input: repository - Repository*
|
||||
Output: -
|
||||
*/
|
||||
void _Repository_Destructor(Repository* repository);
|
||||
|
||||
/*
|
||||
Adds an element to the repository
|
||||
Input: repository - Repository*
|
||||
material - Material* - the element to be added
|
||||
Output: 1 - if the element was added
|
||||
0 - if the element was not added
|
||||
*/
|
||||
int _Repository_add(Repository* repository, Material* material);
|
||||
|
||||
/*
|
||||
Deletes an element from the repository
|
||||
Input: repository - Repository*
|
||||
material - Material* - the element to be deleted
|
||||
Output: 1 - if the element was deleted
|
||||
0 - if the element was not deleted
|
||||
*/
|
||||
int _Repository_delete(Repository* repository, Material* material);
|
||||
|
||||
/*
|
||||
Updates an element from the repository
|
||||
Input: repository - Repository*
|
||||
material - Material* - the element to be updated
|
||||
Output: 1 - if the element was updated
|
||||
0 - if the element was not updated
|
||||
*/
|
||||
int _Repository_update(Repository* repository, Material* material);
|
||||
|
||||
/*
|
||||
Gets the lenght of the repository
|
||||
Input: repository - Repository*
|
||||
Output: int - the lenght of the repository
|
||||
*/
|
||||
int _Repository_getLenght(Repository* repository);
|
||||
|
||||
/*
|
||||
Gets an element from the repository
|
||||
Input: repository - Repository*
|
||||
index - int - the index of the element to be returned
|
||||
Output: Material* - the element at the given index
|
||||
NULL - if the element was not found
|
||||
*/
|
||||
Material* _Repository_getItem(Repository* repository,int index);
|
||||
@@ -0,0 +1,134 @@
|
||||
#include "controller_tests.h"
|
||||
#include "../controller/controller.h"
|
||||
#include "../domain/domain.h"
|
||||
#include "../repository/repository.h"
|
||||
#include "../undo_module/undo_controller/undo_controller.h"
|
||||
#include "../undo_module/function_call/functioncall.h"
|
||||
#include "../undo_module/operation/operation.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void controller_tests(void){
|
||||
printf("Running controller tests\n");
|
||||
Repository* repository = _Repository_Constructor();
|
||||
UndoController* undo_controller = _UndoController_Constructor();
|
||||
Controller* controller = _Controller_Constructor(repository,undo_controller);
|
||||
char* name;
|
||||
char* supplier;
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Water");
|
||||
strcpy(supplier,"Bucovina");
|
||||
_Controller_add(controller,name,supplier,20,2,3,2025);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Water");
|
||||
strcpy(supplier,"Dorna");
|
||||
_Controller_add(controller,name,supplier,5,16,10,2026);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Flour");
|
||||
strcpy(supplier,"Boromir");
|
||||
_Controller_add(controller,name,supplier,25,16,10,2023);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Flour");
|
||||
strcpy(supplier,"Titan");
|
||||
_Controller_add(controller,name,supplier,25,4,1,2023);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Sugar");
|
||||
strcpy(supplier,"Margarita");
|
||||
_Controller_add(controller,name,supplier,25,7,11,2021);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Sugar");
|
||||
strcpy(supplier,"Diamant");
|
||||
_Controller_add(controller,name,supplier,125,23,10,2021);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Rum Extract");
|
||||
strcpy(supplier,"Diamant");
|
||||
_Controller_add(controller,name,supplier,65,23,10,2021);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Vanilla Extract");
|
||||
strcpy(supplier,"Diamant");
|
||||
_Controller_add(controller,name,supplier,45,23,10,2025);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Apples");
|
||||
strcpy(supplier,"Eco Fruits");
|
||||
_Controller_add(controller,name,supplier,95,4,9,2021);
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Plums");
|
||||
strcpy(supplier,"Eco Fruits");
|
||||
_Controller_add(controller,name,supplier,15,22,11,2021);
|
||||
|
||||
assert(_Controller_getLenght(controller) == 10);
|
||||
assert(strcmp(_Material_GetName(_Controller_getItem(controller,0)), "Water") == 0);
|
||||
assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,0)), "Bucovina") == 0);
|
||||
assert(_Material_GetQuantity(_Controller_getItem(controller,0)) == 20);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mday == 2);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mon == 2);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_year == 2025);
|
||||
|
||||
assert(strcmp(_Material_GetName(_Controller_getItem(controller,9)),"Plums" ) == 0);
|
||||
assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,9)),"Eco Fruits" ) == 0);
|
||||
assert(_Material_GetQuantity(_Controller_getItem(controller,9)) == 15);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_mday == 22);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_mon == 10);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_year == 2021);
|
||||
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Water");
|
||||
strcpy(supplier,"Bucovina");
|
||||
|
||||
_Controller_update(controller,name,supplier,30,2,3,2025);
|
||||
assert(_Controller_getLenght(controller) == 10);
|
||||
assert(strcmp(_Material_GetName(_Controller_getItem(controller,0)), "Water") == 0);
|
||||
assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,0)), "Bucovina") == 0);
|
||||
assert(_Material_GetQuantity(_Controller_getItem(controller,0)) == 30);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mday == 2);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mon == 2);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_year == 2025);
|
||||
|
||||
name = (char*)malloc(255);
|
||||
supplier = (char*)malloc(255);
|
||||
strcpy(name,"Water");
|
||||
strcpy(supplier,"Bucovina");
|
||||
_Controller_delete(controller,name,supplier,2,3,2025);
|
||||
assert(_Controller_getLenght(controller) == 9);
|
||||
assert(strcmp(_Material_GetName(_Controller_getItem(controller,0)), "Water") == 0);
|
||||
assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,0)), "Dorna") == 0);
|
||||
assert(_Material_GetQuantity(_Controller_getItem(controller,0)) == 5);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mday == 16);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mon == 9);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_year == 2026);
|
||||
|
||||
_Controller_undo(controller);
|
||||
assert(_Controller_getLenght(controller) == 10);
|
||||
assert(strcmp(_Material_GetName(_Controller_getItem(controller,9)), "Water") == 0);
|
||||
assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,9)), "Bucovina") == 0);
|
||||
assert(_Material_GetQuantity(_Controller_getItem(controller,9)) == 30);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_mday == 2);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_mon == 2);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,9)).tm_year == 2025);
|
||||
|
||||
_Controller_redo(controller);
|
||||
assert(_Controller_getLenght(controller) == 9);
|
||||
assert(strcmp(_Material_GetName(_Controller_getItem(controller,0)), "Water") == 0);
|
||||
assert(strcmp(_Material_GetSupplier(_Controller_getItem(controller,0)), "Dorna") == 0);
|
||||
assert(_Material_GetQuantity(_Controller_getItem(controller,0)) == 5);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mday == 16);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_mon == 9);
|
||||
assert(_Material_GetDate(_Controller_getItem(controller,0)).tm_year == 2026);
|
||||
|
||||
_Controller_Destructor(controller);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void controller_tests(void);
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "domain_tests.h"
|
||||
#include "../domain/domain.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void domain_tests(void){
|
||||
printf("Running domain tests\n");
|
||||
char *name = (char *)malloc(20);
|
||||
char *supplier = (char *)malloc(20);
|
||||
strcpy(name, "name");
|
||||
strcpy(supplier, "supplier");
|
||||
Material* material = _Material_Constructor(name,supplier,10,1,2,2005);
|
||||
assert(strcmp(_Material_GetName(material), "name") == 0);
|
||||
assert(strcmp(_Material_GetSupplier(material), "supplier") == 0);
|
||||
assert(_Material_GetQuantity(material) == 10);
|
||||
assert(_Material_GetDate(material).tm_mday == 1);
|
||||
assert(_Material_GetDate(material).tm_mon == 1);
|
||||
assert(_Material_GetDate(material).tm_year == 2005);
|
||||
_Material_Destructor(material);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
void domain_tests(void);
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "repo_tests.h"
|
||||
#include "../repository/repository.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void repo_tests(){
|
||||
printf("Running repository tests\n");
|
||||
Repository* repository = _Repository_Constructor();
|
||||
assert(_Repository_getLenght(repository) == 0);
|
||||
char *name = (char *)malloc(20);
|
||||
char *supplier = (char *)malloc(20);
|
||||
strcpy(name, "name");
|
||||
strcpy(supplier, "supplier");
|
||||
Material* material = _Material_Constructor(name,supplier,10,1,2,2005);
|
||||
_Repository_add(repository, material);
|
||||
assert(_Repository_getLenght(repository) == 1);
|
||||
assert(strcmp(_Material_GetName(_Repository_getItem(repository,0)), "name") == 0);
|
||||
assert(strcmp(_Material_GetSupplier(_Repository_getItem(repository,0)), "supplier") == 0);
|
||||
assert(_Material_GetQuantity(_Repository_getItem(repository,0)) == 10);
|
||||
assert(_Material_GetDate(_Repository_getItem(repository,0)).tm_mday == 1);
|
||||
assert(_Material_GetDate(_Repository_getItem(repository,0)).tm_mon == 1);
|
||||
assert(_Material_GetDate(_Repository_getItem(repository,0)).tm_year == 2005);
|
||||
_Repository_Destructor(repository);
|
||||
_Material_Destructor(material);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
void repo_tests();
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "domain_tests.h"
|
||||
#include "vector_tests.h"
|
||||
#include "repo_tests.h"
|
||||
#include "controller_tests.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void testAll(void){
|
||||
domain_tests();
|
||||
vector_tests();
|
||||
repo_tests();
|
||||
controller_tests();
|
||||
printf("All tests passed\n");
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
void testAll(void);
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "vector_tests.h"
|
||||
#include "../vector/vector.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
void vector_tests(void){
|
||||
printf("Running vector tests\n");
|
||||
Vector* vector = _Vector_Constructor(10);
|
||||
assert(_Vector_getLength(vector) == 0);
|
||||
assert(_Vector_getCapacity(vector) == 10);
|
||||
int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, i = 9, j = 10, k = 11;
|
||||
_Vector_add(vector, &a);
|
||||
_Vector_add(vector, &b);
|
||||
_Vector_add(vector, &c);
|
||||
assert(_Vector_getLength(vector) == 3);
|
||||
assert(_Vector_getCapacity(vector) == 10);
|
||||
_Vector_add(vector, &d);
|
||||
_Vector_add(vector, &e);
|
||||
_Vector_add(vector, &f);
|
||||
_Vector_add(vector, &g);
|
||||
_Vector_add(vector, &h);
|
||||
_Vector_add(vector, &i);
|
||||
_Vector_add(vector, &j);
|
||||
_Vector_add(vector, &k);
|
||||
assert(_Vector_getLength(vector) == 11);
|
||||
assert(_Vector_getCapacity(vector) == 20);
|
||||
assert(*((int*)_Vector_getItem(vector, 0)) == 1);
|
||||
assert(*((int*)_Vector_getItem(vector, 1)) == 2);
|
||||
_Vector_delete(vector, 0);
|
||||
assert(_Vector_getLength(vector) == 10);
|
||||
assert(*((int*)_Vector_getItem(vector, 0)) == 2);
|
||||
_Vector_Destructor(vector);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
void vector_tests(void);
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
#include<stdlib.h>
|
||||
#include "functioncall.h"
|
||||
#include "../../repository/repository.h"
|
||||
#include "../../domain/domain.h"
|
||||
#include "../../vector/vector.h"
|
||||
|
||||
FunctionCall* _FunctionCall_Constructor(int (*function)(Repository*, Material*), Vector* args){
|
||||
FunctionCall* functionCall = (FunctionCall*)malloc(sizeof(FunctionCall));
|
||||
functionCall->function = function;
|
||||
functionCall->args = args;
|
||||
return functionCall;
|
||||
}
|
||||
|
||||
void _FunctionCall_Destructor(FunctionCall* functionCall){
|
||||
_Material_Destructor((Material*)functionCall->args->elems[1]);
|
||||
_Vector_Destructor(functionCall->args);
|
||||
free(functionCall);
|
||||
}
|
||||
|
||||
void _FunctionCall_Execute(FunctionCall* functionCall){
|
||||
functionCall->function((Repository*)functionCall->args->elems[0], (Material*)functionCall->args->elems[1]);
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "../../repository/repository.h"
|
||||
#include "../../domain/domain.h"
|
||||
#include "../../vector/vector.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int (*function)(Repository*, Material*);
|
||||
Vector* args;
|
||||
} FunctionCall;
|
||||
|
||||
/*
|
||||
Constructor for the FunctionCall
|
||||
Input: function - int (*)(Repository*, Material*) - the function to be called
|
||||
args - Vector* - the arguments of the function
|
||||
Output: a pointer to the newly created FunctionCall
|
||||
*/
|
||||
FunctionCall* _FunctionCall_Constructor(int (*function)(Repository*, Material*), Vector* args);
|
||||
|
||||
/*
|
||||
Destructor for the FunctionCall
|
||||
Input: functionCall - FunctionCall*
|
||||
Output: -
|
||||
*/
|
||||
void _FunctionCall_Destructor(FunctionCall* functionCall);
|
||||
|
||||
/*
|
||||
Executes the function
|
||||
Input: functionCall - FunctionCall*
|
||||
Output: -
|
||||
*/
|
||||
void _FunctionCall_Execute(FunctionCall* functionCall);
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#include "operation.h"
|
||||
#include "../function_call/functioncall.h"
|
||||
#include<stdlib.h>
|
||||
|
||||
Operation* _Operation_Constructor(FunctionCall* functionDo, FunctionCall* functionUndo){
|
||||
Operation* operation = (Operation*)malloc(sizeof(Operation));
|
||||
operation->functionDo = functionDo;
|
||||
operation->functionUndo = functionUndo;
|
||||
return operation;
|
||||
}
|
||||
|
||||
void _Operation_Destructor(Operation* operation){
|
||||
_FunctionCall_Destructor(operation->functionDo);
|
||||
_FunctionCall_Destructor(operation->functionUndo);
|
||||
free(operation);
|
||||
}
|
||||
|
||||
void _Operation_Do(Operation* operation){
|
||||
_FunctionCall_Execute(operation->functionDo);
|
||||
}
|
||||
|
||||
void _Operation_Undo(Operation* operation){
|
||||
_FunctionCall_Execute(operation->functionUndo);
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "../function_call/functioncall.h"
|
||||
|
||||
typedef struct{
|
||||
FunctionCall* functionDo;
|
||||
FunctionCall* functionUndo;
|
||||
} Operation;
|
||||
|
||||
/*
|
||||
Constructor for the Operation
|
||||
Input: functionDo - FunctionCall* - the function to be called when the operation is done
|
||||
functionUndo - FunctionCall* - the function to be called when the operation is undone
|
||||
Output: a pointer to the newly created Operation
|
||||
*/
|
||||
Operation* _Operation_Constructor(FunctionCall* functionDo, FunctionCall* functionUndo);
|
||||
|
||||
/*
|
||||
Destructor for the Operation
|
||||
Input: operation - Operation*
|
||||
Output: -
|
||||
*/
|
||||
void _Operation_Destructor(Operation* operation);
|
||||
|
||||
/*
|
||||
Executes the Do function
|
||||
Input: operation - Operation*
|
||||
Output: -
|
||||
*/
|
||||
void _Operation_Do(Operation* operation);
|
||||
|
||||
/*
|
||||
Executes the Undo function
|
||||
Input: operation - Operation*
|
||||
Output: -
|
||||
*/
|
||||
void _Operation_Undo(Operation* operation);
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
#include<stdlib.h>
|
||||
#include "undo_controller.h"
|
||||
#include "../operation/operation.h"
|
||||
|
||||
|
||||
|
||||
UndoController* _UndoController_Constructor(){
|
||||
UndoController* undo_controller = (UndoController*)malloc(sizeof(UndoController));
|
||||
undo_controller->operations = _Vector_Constructor(10);
|
||||
undo_controller->index=-1;
|
||||
return undo_controller;
|
||||
}
|
||||
|
||||
void _UndoController_Destructor(UndoController* undo_controller){
|
||||
for(int i=0;i<_Vector_getLength(undo_controller->operations);i++)
|
||||
_Operation_Destructor((Operation*)(_Vector_getItem(undo_controller->operations,i)));
|
||||
_Vector_Destructor(undo_controller->operations);
|
||||
undo_controller->operations=NULL;
|
||||
free(undo_controller);
|
||||
}
|
||||
|
||||
void _UndoController_recordOperation(UndoController* undo_controller,Operation* operation){
|
||||
for(int i = _Vector_getLength(undo_controller->operations)-1;i>undo_controller->index;i--){
|
||||
_Operation_Destructor((Operation*)(_Vector_getItem(undo_controller->operations,i)));
|
||||
_Vector_delete(undo_controller->operations,i);
|
||||
}
|
||||
_Vector_add(undo_controller->operations,operation);
|
||||
undo_controller->index+=1;
|
||||
}
|
||||
|
||||
int _UndoController_undo(UndoController* undo_controller){
|
||||
if(undo_controller->index<0)
|
||||
return 1;
|
||||
_Operation_Undo((Operation*)(_Vector_getItem(undo_controller->operations,undo_controller->index)));
|
||||
undo_controller->index--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _UndoController_redo(UndoController* undo_controller){
|
||||
if(undo_controller->index + 1 >= _Vector_getLength(undo_controller->operations))
|
||||
return 1;
|
||||
undo_controller->index++;
|
||||
_Operation_Do((Operation*)(_Vector_getItem(undo_controller->operations,undo_controller->index)));
|
||||
return 0;
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../vector/vector.h"
|
||||
#include "../operation/operation.h"
|
||||
|
||||
typedef struct {
|
||||
Vector* operations;
|
||||
int index;
|
||||
} UndoController;
|
||||
|
||||
/*
|
||||
Constructor for the UndoController
|
||||
Input: -
|
||||
Output: a pointer to the newly created UndoController
|
||||
*/
|
||||
UndoController* _UndoController_Constructor();
|
||||
|
||||
/*
|
||||
Destructor for the UndoController
|
||||
Input: undo_controller - UndoController*
|
||||
Output: -
|
||||
*/
|
||||
void _UndoController_Destructor(UndoController* undo_controller);
|
||||
|
||||
/*
|
||||
Adds an operation to the UndoController
|
||||
Input: undo_controller - UndoController*
|
||||
operation - Operation* - the operation to be added
|
||||
Output: -
|
||||
*/
|
||||
void _UndoController_recordOperation(UndoController* undo_controller,Operation* operation);
|
||||
|
||||
/*
|
||||
Undoes the last operation
|
||||
Input: undo_controller - UndoController*
|
||||
Output: 1 - if the operation was undone
|
||||
0 - if the operation was not undone
|
||||
*/
|
||||
int _UndoController_undo(UndoController* undo_controller);
|
||||
|
||||
/*
|
||||
Redoes the last operation
|
||||
Input: undo_controller - UndoController*
|
||||
Output: 1 - if the operation was redone
|
||||
0 - if the operation was not redone
|
||||
*/
|
||||
int _UndoController_redo(UndoController* undo_controller);
|
||||
@@ -0,0 +1,84 @@
|
||||
#include <stdlib.h>
|
||||
#include "vector.h"
|
||||
|
||||
|
||||
Vector* _Vector_Constructor(int capacity){
|
||||
Vector* vector = (Vector*)malloc(sizeof(Vector));
|
||||
if (vector == NULL)
|
||||
return NULL;
|
||||
vector->capacity=capacity;
|
||||
vector->lenght=0;
|
||||
vector->elems=(TElem*)malloc(capacity*(sizeof(TElem)));
|
||||
if (vector->elems==NULL)
|
||||
return NULL;
|
||||
return vector;
|
||||
}
|
||||
|
||||
void _Vector_Destructor(Vector* vector){
|
||||
if (vector==NULL)
|
||||
return;
|
||||
free(vector->elems);
|
||||
vector->elems=NULL;
|
||||
free(vector);
|
||||
|
||||
}
|
||||
|
||||
int _Vector_add(Vector* vector, TElem t){
|
||||
if (vector == NULL)
|
||||
return 1;
|
||||
if (vector->elems==NULL)
|
||||
return 1;
|
||||
|
||||
if (vector->lenght==vector->capacity)
|
||||
_Vector_resize(vector);
|
||||
vector->elems[vector->lenght]=t;
|
||||
vector->lenght++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _Vector_delete(Vector* vector,int index){
|
||||
if (vector == NULL)
|
||||
return 1;
|
||||
if (vector->elems==NULL)
|
||||
return 1;
|
||||
if (vector->lenght<=index)
|
||||
return 1;
|
||||
|
||||
TElem return_value=vector->elems[index];
|
||||
for(int i=index;i<vector->lenght-1;i++)
|
||||
vector->elems[i]=vector->elems[i+1];
|
||||
vector->lenght--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _Vector_resize(Vector* vector){
|
||||
if (vector == NULL)
|
||||
return;
|
||||
vector->capacity*=2;
|
||||
TElem* aux = (TElem*)realloc(vector->elems,vector->capacity*sizeof(TElem));
|
||||
if (aux==NULL)
|
||||
return;
|
||||
vector->elems=aux;
|
||||
}
|
||||
|
||||
TElem _Vector_getItem(Vector* vector,int index){
|
||||
if (vector==NULL)
|
||||
return NULL;
|
||||
if (index<0 || index >= vector->lenght)
|
||||
return NULL;
|
||||
return vector->elems[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _Vector_getLength(Vector* vector){
|
||||
if (vector==NULL)
|
||||
return 0;
|
||||
return vector->lenght;
|
||||
}
|
||||
|
||||
int _Vector_getCapacity(Vector* vector){
|
||||
if (vector==NULL)
|
||||
return 0;
|
||||
return vector->capacity;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#include "../domain/domain.h"
|
||||
|
||||
typedef void* TElem;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TElem* elems;
|
||||
int lenght;
|
||||
int capacity;
|
||||
} Vector;
|
||||
|
||||
/*
|
||||
Constructor for the Vector
|
||||
Input: capacity - the initial capacity of the vector
|
||||
Output: a pointer to the newly created vector
|
||||
*/
|
||||
Vector* _Vector_Constructor(int capacity);
|
||||
|
||||
/*
|
||||
Destructor for the Vector
|
||||
Input: vector - Vector*
|
||||
Output: -
|
||||
*/
|
||||
void _Vector_Destructor(Vector* vector);
|
||||
|
||||
/*
|
||||
Adds an element to the vector
|
||||
Input: vector - Vector*
|
||||
t - TElem - the element to be added
|
||||
Output: 1 - if the element was added
|
||||
0 - if the element was not added
|
||||
*/
|
||||
int _Vector_add(Vector* vector, TElem t);
|
||||
|
||||
/*
|
||||
Deletes an element from the vector
|
||||
Input: vector - Vector*
|
||||
index - int - the index of the element to be deleted
|
||||
Output: 1 - if the element was deleted
|
||||
0 - if the element was not deleted
|
||||
*/
|
||||
int _Vector_delete(Vector* vector,int index);
|
||||
|
||||
/*
|
||||
Gets an element from the vector
|
||||
Input: vector - Vector*
|
||||
index - int - the index of the element to be returned
|
||||
Output: TElem - the element at the given index
|
||||
NULL - if the element was not found
|
||||
*/
|
||||
TElem _Vector_getItem(Vector* vector,int index);
|
||||
|
||||
/*
|
||||
Resizes the vector, doubling its capacity
|
||||
Input: vector - Vector*
|
||||
Output: -
|
||||
*/
|
||||
void _Vector_resize(Vector* vector);
|
||||
|
||||
/*
|
||||
Gets the length of the vector
|
||||
Input: vector - Vector*
|
||||
Output: int - the length of the vector
|
||||
*/
|
||||
int _Vector_getLength(Vector* vector);
|
||||
|
||||
/*
|
||||
Gets the capacity of the vector
|
||||
Input: vector - Vector*
|
||||
Output: int - the capacity of the vector
|
||||
*/
|
||||
int _Vector_getCapacity(Vector* vector);
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# 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
|
||||
|
||||
.vscode
|
||||
@@ -0,0 +1,69 @@
|
||||
# Assignment 04-05
|
||||
## Requirements
|
||||
- You will be given one of the problems below to solve.
|
||||
- The application must be implemented in C++ and use layered architecture.
|
||||
- Provide tests and specifications for non-trivial functions outside the UI. Test coverage must be at least 98% for all layers, except the UI.
|
||||
- Have at least 10 entities in your memory repository.
|
||||
- Validate the input data.
|
||||
- Handle the following situations:
|
||||
- If an entity that already exists is added, a message is shown and the entity is not stored. You must decide what makes an entity unique.
|
||||
- If the user tries to update/delete an entity that does not exist, a message will be shown and there will be no effect on the list of entities.
|
||||
|
||||
## Week 5
|
||||
- Solve the requirements related to the administrator mode.
|
||||
- Define the `DynamicVector` class which provides the specific operations: `add`, `remove`, `length`, etc. The array of elements must be dynamically allocated.
|
||||
|
||||
## Week 6
|
||||
- Solve all problem requirements.
|
||||
- `DynamicVector` must be a class template.
|
||||
|
||||
## Problem Statements
|
||||
|
||||
### Keep calm and adopt a pet
|
||||
The *“Keep calm and adopt a pet”* shelter needs a software application to help them find adoptive parents for the dogs they are taking care of. The application can be used in two modes: `administrator` and `user`. When the application is started, it will offer the option to select the mode.\
|
||||
**Administrator mode:** The application will have a database that holds all the dogs in the shelter at a given moment. The shelter employees must be able to update the database, meaning: add a new dog, delete a dog (when the dog is adopted) and update the information of a dog. Each **Dog** has a `breed`, a `name`, an `age` and a `photograph`. The photograph is memorised as a link towards an online resource (the photograph on the presentation site of the centre). The administrators will also have the option to see all the dogs in the shelter.\
|
||||
**User mode:** A user can access the application and choose one or more dogs to adopt. The application will allow the user to:
|
||||
- See the dogs in the database, one by one. When the user chooses this option, the data of the first dog (breed, name, age) is displayed, along with its photograph.
|
||||
- Choose to adopt the dog, in which case the dog is added to the user’s adoption list.
|
||||
- Choose not to adopt the dog and to continue to the next. In this case, the information corresponding to the next dog is shown and the user is again offered the possibility to adopt it. This can continue as long as the user wants, as when arriving to the end of the list, if the user chooses next, the application will again show the first dog.
|
||||
- See all the dogs of a given breed, having an age less than a given number. If no breed is provided, then all the dogs will be considered. The functionalities outlined above apply again in this case.
|
||||
- See the adoption list.
|
||||
|
||||
## Local Movie Database
|
||||
So many movies, so little time. To make sure you do not miss any good movies, you absolutely need a software application to help you manage your films and create watch lists. The application can be used in two modes: administrator and user. When the application is started, it will offer the option to choose the mode.\
|
||||
**Administrator mode:** The application will have a database which holds all the movies. You must be able to update the database, meaning: add a new movie, delete a movie and update the information of a movie. Each **Movie** has a `title`, a `genre`, a `year of release`, a `number of likes` and a `trailer`. The trailer is memorised as a link towards an online resource. The administrators will also have the option to see all the movies in the database.\
|
||||
**User mode:** A user can create a watch list with the movies that she wants to watch. The application will allow the user to:
|
||||
- See the movies in the database having a given genre (if the genre is empty, see all the movies), one by one. When the user chooses this option, the data of the first movie (title, genre, year of release, number of likes) is displayed and the trailer is played in the browser.
|
||||
- If the user likes the trailer, she can choose to add the movie to her watch list.
|
||||
- If the trailer is not satisfactory, the user can choose not to add the movie to the watch list and to continue to the next. In this case, the information corresponding to the next movie is shown and the user is again offered the possibility to add it to the watch list. This can continue as long as the user wants, as when arriving to the end of the list of movies with the given genre, if the user chooses next, the application will again show the first movie.
|
||||
- Delete a movie from the watch list, after the user watched the movie. When deleting a movie from the watch list, the user can also rate the movie (with a like), and in this case, the number of likes the movie has in the repository will be increased.
|
||||
- See the watch list.
|
||||
|
||||
## Proper Trench Coats
|
||||
Trench coats are cool. Everyone should own a trench coat. The *“Proper Trench Coats”* store sells fashionable, elegant trench coats and the store needs software to allow their customers to order online. The application can be used in two modes: administrator and user. When the application is started, it will offer the option to choose the mode.\
|
||||
**Administrator mode:** The application will have a database which holds available trench coats at a given moment. The store employees must be able to update the database, meaning: add a new trench coat, delete a trench coat (when it is sold out) and update the information of a trench coat. Each **Trench Coat** has a `size`, a `colour`, a `price`, a `quantity` and a `photograph`. The photograph is memorised as a link towards an online resource (the photograph on the presentation site of the store). The administrators will also have the option to see all the trench coats in the store.\
|
||||
**User mode:** A user can access the application and choose one or more trench coats to buy. The application will allow the user to:
|
||||
- See the trench coats in the database, having a given size, one by one. If the size is empty, then all the trench coats will be considered. When the user chooses this option, the data of the first trench coat (size, colour, price, quantity) is displayed, along with its photograph.
|
||||
- Choose to add the trench to the shopping basket. In this case, the price is added to the total sum the user has to pay. The total sum will be shown after each purchase.
|
||||
- Choose not to add the trench coat to the basket and to continue to the next. In this case, the information corresponding to the next trench coat is shown and the user is again offered the possibility to buy it. This can continue as long as the user wants, as when arriving to the end of the list, if the user chooses next, the application will again show the first trench coat.
|
||||
- See the shopping basket and the total price of the items.
|
||||
|
||||
## Master C++
|
||||
You are very passionate about programing (otherwise you wouldn't be reading this) and C++ is a language close to your heart. On your way to becoming a guru, you study a lot and watch many tutorials. To make sure you do not miss any good tutorials, you absolutely need a software application to help you manage your tutorials and create watch lists. The application can be used in two modes: administrator and user. When the application is started, it will offer the option to choose the mode.\
|
||||
**Administrator mode:** The application will have a database , which holds all the tutorials. You must be able to update the database, meaning: add a new tutorial, delete a tutorial and update the information of a tutorial. Each **Tutorial** has a `title`, a `presenter` (name of the presenter person), a `duration` (minutes and seconds), a number of `likes` and a `link` towards the online resource containing the tutorial. The administrators will also have the option to see all the tutorials in the database.\
|
||||
**User mode:** A user can create a watch list with the tutorials that he/she wants to watch. The application will allow the user to:
|
||||
- See the tutorials in the database having a given presenter (if the presenter name is empty, see all the tutorials), one by one. When the user chooses this option, the data of the first tutorial (title, presenter, duration, number of likes) is displayed and the tutorial is played in the browser.
|
||||
- If the user likes the tutorial, he/she can choose to add it to his/her tutorial watch list.
|
||||
- If the tutorial seems uninteresting, the user can choose not to add it to the watch list and continue to the next. In this case, the information corresponding to the next tutorial is shown and the user is again offered the possibility to add it to the watch list. This can continue as long as the user wants, as when arriving to the end of the list of tutorials with the given presenter, if the user chooses next, the application will again show the first tutorial.
|
||||
- Delete a tutorial from the watch list, after the user watched the tutorial. When deleting a tutorial from the watch list, the user can also rate the tutorial (with a like), and in this case, the number of likes for the tutorial will be increased.
|
||||
- See the watch list.
|
||||
|
||||
## Life After School
|
||||
Lectures, seminars and labs ... school in general must be taken seriously; BUT so must be your social life and leisure time. To manage the latter and be always informed about the interesting events happening in your city you will implement a software application. The application can be used in two modes: administrator and user. When the application is started, it will offer the option to choose the mode.\
|
||||
**Administrator mode:** The application will have a database which holds all the interesting events in your area. You must be able to update the database, meaning: add a new event, delete an event and update the information of an event. Each **Event** has a `title`, a `description`, a `date and time`, a `number of people` who are going and a `link` towards the online resource containing the event. The administrators will also have the option to see all the events in the database.\
|
||||
**User mode:** A user can create a list with the events that he/she is interested in. The application will allow the user to:
|
||||
- See the events in the database for a given month (if there is no month given, see all the events, ordered chronologically), one by one. When the user chooses this option, the data of the first event (title, description, date and time, number of people who are going) is displayed, and the event is opened in the browser (e.g. Facebook event).
|
||||
- If the user wants to participate in the event he/she can choose to add it to his/her events list. When this happens, the number of people who are going to the event increases (for the event in the repository).
|
||||
- If the event seems uninteresting, the user can choose not to add it to the list and continue to the next. In this case, the information corresponding to the next event is shown, and the user is again offered the possibility to add it to his/her list. This can continue as long as the user wants, as when arriving to the end of the list of events for the given month, if the user chooses next, the application will again show the first event.
|
||||
- Delete an event from the list. When the user deletes an event from his/her list, the number of people who are going to the event decreases.
|
||||
- See the list of events the user wants to attend.
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
#include "admin_controller.h"
|
||||
#include "../../exceptions/exceptions.h"
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
AdminController::AdminController(Repository* repo){
|
||||
this->_repo = repo;
|
||||
}
|
||||
AdminController::~AdminController(){
|
||||
delete this->_repo;
|
||||
}
|
||||
void AdminController::add(int size,const char* colour,int price,int quantity,const char* photograph){
|
||||
if(size<=0){
|
||||
throw AdminControllerException("Size must be greater than 0");
|
||||
}
|
||||
if(strlen(colour)==0){
|
||||
throw AdminControllerException("Colour must not be empty");
|
||||
}
|
||||
if(price<=0){
|
||||
throw AdminControllerException("Price must be greater than 0");
|
||||
}
|
||||
if(quantity<0){
|
||||
throw AdminControllerException("Quantity must be greater than or equal to 0");
|
||||
}
|
||||
if(strlen(photograph)==0){
|
||||
throw AdminControllerException("Photograph must not be empty");
|
||||
}
|
||||
Trench* trench = new Trench(size,colour,price,quantity,photograph);
|
||||
try{
|
||||
this->_repo->add(trench);
|
||||
}
|
||||
catch(RepoException& e){
|
||||
delete trench;
|
||||
throw AdminControllerException(e.what());
|
||||
}
|
||||
}
|
||||
void AdminController::remove(int size,const char* colour,const char* photograph){
|
||||
if(size<=0){
|
||||
throw AdminControllerException("Size must be greater than 0");
|
||||
}
|
||||
if(strlen(colour)==0){
|
||||
throw AdminControllerException("Colour must not be empty");
|
||||
}
|
||||
if(strlen(photograph)==0){
|
||||
throw AdminControllerException("Photograph must not be empty");
|
||||
}
|
||||
Trench* trench = new Trench(size,colour,0,0,photograph);
|
||||
try{
|
||||
this->_repo->remove(trench);
|
||||
}
|
||||
catch(RepoException& e){
|
||||
delete trench;
|
||||
throw AdminControllerException(e.what());
|
||||
}
|
||||
delete trench;
|
||||
}
|
||||
void AdminController::remove(int index){
|
||||
this->_repo->remove(index);
|
||||
}
|
||||
void AdminController::update(int size,const char* colour,int price,int quantity,const char* photograph){
|
||||
if(size<=0){
|
||||
throw AdminControllerException("Size must be greater than 0");
|
||||
}
|
||||
if(strlen(colour)==0){
|
||||
throw AdminControllerException("Colour must not be empty");
|
||||
}
|
||||
if(price!=-1 && price<=0){
|
||||
throw AdminControllerException("Price must be greater than 0");
|
||||
}
|
||||
if(quantity!=-1 && quantity<0){
|
||||
throw AdminControllerException("Quantity must be greater than or equal to 0");
|
||||
}
|
||||
if(strlen(photograph)==0){
|
||||
throw AdminControllerException("Photograph must not be empty");
|
||||
}
|
||||
Trench* trench = new Trench(size,colour,price,quantity,photograph);
|
||||
int index = this->_repo->get(trench);
|
||||
delete trench;
|
||||
if(index==-1){
|
||||
throw AdminControllerException("Trench does not exist");
|
||||
}
|
||||
this->_repo->update(index,price,quantity);
|
||||
|
||||
}
|
||||
int AdminController::get(int size,const char* colour,const char* photograph){
|
||||
if(size<=0){
|
||||
throw AdminControllerException("Size must be greater than 0");
|
||||
}
|
||||
if(strlen(colour)==0){
|
||||
throw AdminControllerException("Colour must not be empty");
|
||||
}
|
||||
if(strlen(photograph)==0){
|
||||
throw AdminControllerException("Photograph must not be empty");
|
||||
}
|
||||
Trench* trench = new Trench(size,colour,0,0,photograph);
|
||||
int index = this->_repo->get(trench);
|
||||
delete trench;
|
||||
return index;
|
||||
|
||||
}
|
||||
int AdminController::size(){
|
||||
return this->_repo->size();
|
||||
}
|
||||
Trench*& AdminController::operator[](int index){
|
||||
return (*this->_repo)[index];
|
||||
}
|
||||
Repository* AdminController::getAll(){
|
||||
return this->_repo;
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
#pragma once
|
||||
#include "../../repository/repository.h"
|
||||
|
||||
class AdminController {
|
||||
private:
|
||||
Repository* _repo;
|
||||
public:
|
||||
|
||||
/*
|
||||
* Constructor for the AdminController class
|
||||
* Input: repo - Repository object
|
||||
* Output: adminController object
|
||||
*/
|
||||
AdminController(Repository* repo);
|
||||
|
||||
/*
|
||||
* Destructor for the AdminController class
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
~AdminController();
|
||||
|
||||
/*
|
||||
* Adds a trench coat to the repository
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* price - integer
|
||||
* quantity - integer
|
||||
* photograph - string
|
||||
* Output: -
|
||||
* Throws: AdminControllerException if: size<=0
|
||||
* colour is empty
|
||||
* price<=0
|
||||
* quantity<0
|
||||
* photograph is empty
|
||||
* trench coat already exists
|
||||
*/
|
||||
void add(int size,const char* colour,int price,int quantity,const char* photograph);
|
||||
|
||||
/*
|
||||
* Removes a trench coat from the repository
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* photograph - string
|
||||
* Output: -
|
||||
* Throws: AdminControllerException if: size<=0
|
||||
* colour is empty
|
||||
* photograph is empty
|
||||
* trench coat does not exist
|
||||
*/
|
||||
void remove(int size,const char* colour,const char* photograph);
|
||||
|
||||
/*
|
||||
* Removes a trench coat from the repository
|
||||
* Input: index - integer
|
||||
* Output: -
|
||||
* Throws: RepoException if: index is out of bounds
|
||||
*/
|
||||
void remove(int index);
|
||||
|
||||
/*
|
||||
* Updates a trench coat from the repository. If the price or quantity is -1, it will not be updated
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* price - integer
|
||||
* quantity - integer
|
||||
* photograph - string
|
||||
* Output: -
|
||||
* Throws: AdminControllerException if: size<=0
|
||||
* colour is empty
|
||||
* price!=-1 and price<=0
|
||||
* quantity!=-1 and quantity<0
|
||||
* photograph is empty
|
||||
* trench coat does not exist
|
||||
*/
|
||||
void update(int size,const char* colour,int price,int quantity,const char* photograph);
|
||||
|
||||
/*
|
||||
* Returns the index of a trench coat in the repository. If it does not exist, it returns -1
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* photograph - string
|
||||
* Output: index - integer
|
||||
*/
|
||||
int get(int size,const char* colour,const char* photograph);
|
||||
|
||||
/*
|
||||
* Returns the number of trench coats in the repository
|
||||
* Input: -
|
||||
* Output: size - integer
|
||||
*/
|
||||
int size();
|
||||
|
||||
/*
|
||||
* Returns the trench coat at the given index
|
||||
* Input: index - integer
|
||||
* Output: trench coat - Trench object
|
||||
* Throws: RepoException if: index is out of bounds
|
||||
*/
|
||||
Trench*& operator[](int index);
|
||||
|
||||
/*
|
||||
* Returns an iterator for all the trench coats in the repository
|
||||
* Input: -
|
||||
* Output: iterator
|
||||
*/
|
||||
Repository* getAll();
|
||||
|
||||
};
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
#include "../../repository/repository.h"
|
||||
#include "../../domain/trench.h"
|
||||
#include "../../vector/vector.h"
|
||||
#include "user_controller.h"
|
||||
#include <stdio.h>
|
||||
|
||||
UserController::UserController(Repository* repo,Repository* shoppingRepository) {
|
||||
this->_repo = repo;
|
||||
this->_shoppingRepository = shoppingRepository;
|
||||
}
|
||||
|
||||
UserController::~UserController() {
|
||||
delete this->_shoppingRepository;
|
||||
}
|
||||
|
||||
void UserController::addProductToShoppingList(Trench* trench) {
|
||||
int index = this->_shoppingRepository->get(trench);
|
||||
int repo_index = this->_repo->get(trench);
|
||||
if(index==-1) {
|
||||
Trench* trenchCopy = new Trench(trench->size(),trench->colour(),trench->price(),1,trench->photograph());
|
||||
this->_shoppingRepository->add(trenchCopy);
|
||||
trench->quantity(trench->quantity()-1);
|
||||
(*this->_repo)[repo_index]->quantity((*this->_repo)[repo_index]->quantity()-1);
|
||||
return;
|
||||
}
|
||||
(*this->_shoppingRepository)[index]->quantity((*this->_shoppingRepository)[index]->quantity()+1);
|
||||
trench->quantity(trench->quantity()-1);
|
||||
(*this->_repo)[repo_index]->quantity((*this->_repo)[repo_index]->quantity()-1);
|
||||
|
||||
}
|
||||
|
||||
void UserController::emptyShoppingList() {
|
||||
for(Trench* i : *this->_shoppingRepository) {
|
||||
int index = this->_repo->get(i);
|
||||
(*this->_repo)[index]->quantity((*this->_repo)[index]->quantity()+i->quantity());
|
||||
}
|
||||
while(this->_shoppingRepository->size()){
|
||||
this->_shoppingRepository->remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
void UserController::buyShoppingList() {
|
||||
while(this->_shoppingRepository->size()){
|
||||
this->_shoppingRepository->remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
int UserController::shoppingListTotal() {
|
||||
int total = 0;
|
||||
for(Trench* i : *this->_shoppingRepository) {
|
||||
total+=i->quantity()*i->price();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
Vector<Trench*> UserController::getTrenchCarousel(int size) {
|
||||
Vector<Trench*> trenchCarousel;
|
||||
for(Trench* i : *this->_repo){
|
||||
if((size == -1||i->size()==size) && i->quantity()>0){
|
||||
Trench* copy = new Trench(*i);
|
||||
trenchCarousel.add(copy);
|
||||
}
|
||||
}
|
||||
return trenchCarousel;
|
||||
}
|
||||
|
||||
Vector<Trench*> UserController::getShoppingListTrench(){
|
||||
Vector<Trench*> trenchCarousel;
|
||||
for(Trench* i : *this->_shoppingRepository){
|
||||
Trench* copy = new Trench(*i);
|
||||
trenchCarousel.add(copy);
|
||||
}
|
||||
return trenchCarousel;
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#include "../../repository/repository.h"
|
||||
#include "../../domain/trench.h"
|
||||
#include "../../vector/vector.h"
|
||||
|
||||
class UserController {
|
||||
private:
|
||||
Repository* _repo;
|
||||
Repository* _shoppingRepository;
|
||||
public:
|
||||
|
||||
/*
|
||||
* Constructor for the UserController class
|
||||
* Input: repo - Repository object
|
||||
* Output: userController object
|
||||
*/
|
||||
UserController(Repository* repo,Repository* shoppingRepository);
|
||||
|
||||
/*
|
||||
* Destructor for the UserController class
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
~UserController();
|
||||
|
||||
/*
|
||||
* Adds a trench coat to the shopping list
|
||||
* Input: trench - Trench object
|
||||
* Output: -
|
||||
*/
|
||||
void addProductToShoppingList(Trench* trench);
|
||||
|
||||
/*
|
||||
* Empties the shopping list
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
void emptyShoppingList();
|
||||
|
||||
/*
|
||||
* Buys the shopping list
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
void buyShoppingList();
|
||||
|
||||
/*
|
||||
* Returns the total price of the shopping list
|
||||
* Input: -
|
||||
* Output: total - integer
|
||||
*/
|
||||
int shoppingListTotal();
|
||||
|
||||
|
||||
/*
|
||||
* Returns a vector of trench coats that are in the shopping list
|
||||
* Input: size - integer
|
||||
* Output: trenchCarousel - Vector<Trench*> object
|
||||
*/
|
||||
Vector<Trench*> getTrenchCarousel(int size);
|
||||
|
||||
Vector<Trench*> getShoppingListTrench();
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
#include "trench.h"
|
||||
#include <string.h>
|
||||
#include <exception>
|
||||
#include <stdio.h>
|
||||
using namespace std;
|
||||
|
||||
Trench::Trench(int size, const char *colour, int price, int quantity, const char *photograph){
|
||||
this->_size = size;
|
||||
this->_colour = new char[255];
|
||||
strcpy(this->_colour,colour);
|
||||
this->_price = price;
|
||||
this->_quantity = quantity;
|
||||
this->_photograph=new char[255];
|
||||
strcpy(this->_photograph,photograph);
|
||||
}
|
||||
|
||||
Trench::~Trench(){
|
||||
delete[] this->_colour;
|
||||
delete[] this->_photograph;
|
||||
}
|
||||
|
||||
Trench::Trench(const Trench &trench){
|
||||
_size = trench.size();
|
||||
_colour = new char[255];
|
||||
strcpy(_colour,trench.colour());
|
||||
_price = trench.price();
|
||||
_quantity = trench.quantity();
|
||||
_photograph = new char[255];
|
||||
strcpy(_photograph,trench.photograph());
|
||||
}
|
||||
|
||||
int Trench::size() const {
|
||||
return this->_size;
|
||||
}
|
||||
|
||||
void Trench::size(int newSize){
|
||||
this->_size = newSize;
|
||||
}
|
||||
|
||||
char* Trench::colour() const {
|
||||
return this->_colour;
|
||||
}
|
||||
|
||||
void Trench::colour(const char *newColour){
|
||||
strcpy(this->_colour,newColour);
|
||||
}
|
||||
|
||||
int Trench::price() const {
|
||||
return this->_price;
|
||||
}
|
||||
|
||||
void Trench::price(int newPrice){
|
||||
this->_price = newPrice;
|
||||
}
|
||||
|
||||
int Trench::quantity() const{
|
||||
return this->_quantity;
|
||||
}
|
||||
|
||||
void Trench::quantity(int newQuantity){
|
||||
this->_quantity = newQuantity;
|
||||
}
|
||||
|
||||
char* Trench::photograph() const {
|
||||
return this->_photograph;
|
||||
}
|
||||
|
||||
void Trench::photograph(const char *newPhotograph){
|
||||
strcpy(this->_photograph, newPhotograph);
|
||||
}
|
||||
|
||||
bool Trench::operator==(const Trench& t){
|
||||
if(this->_size==t.size() && strcmp(this->_colour,t.colour())==0 && strcmp(this->_photograph,t.photograph())==0){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* Trench::toString(){
|
||||
char* string = new char[256];
|
||||
sprintf(string,"Size: %d | Colour: %s | Price: %d | Quantity: %d | Photograph Link: %s \n",this->_size,this->_colour,this->_price,this->_quantity,this->_photograph);
|
||||
return string;
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
|
||||
class Trench {
|
||||
|
||||
private:
|
||||
|
||||
int _size;
|
||||
char* _colour;
|
||||
int _price;
|
||||
int _quantity;
|
||||
char* _photograph;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Constructor for the Trench class
|
||||
* Input: size - integer
|
||||
* colour - string
|
||||
* price - integer
|
||||
* quantity - integer
|
||||
* photograph - string
|
||||
* Output: trench object
|
||||
*/
|
||||
Trench(int size, const char *colour, int price, int quantity, const char *photograph);
|
||||
|
||||
|
||||
/*
|
||||
* Destructor for the Trench class
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
~Trench();
|
||||
|
||||
/*
|
||||
* Copy constructor for the Trench class
|
||||
* Input: trench - trench object
|
||||
* Output: trench object
|
||||
*/
|
||||
Trench(const Trench &trench);
|
||||
|
||||
/*
|
||||
* Getter for the size attribute
|
||||
* Input: -
|
||||
* Output: size - integer
|
||||
*/
|
||||
int size() const;
|
||||
|
||||
/*
|
||||
* Setter for the size attribute
|
||||
* Input: newSize - integer
|
||||
* Output: -
|
||||
*/
|
||||
void size(int newSize);
|
||||
|
||||
/*
|
||||
* Getter for the colour attribute
|
||||
* Input: -
|
||||
* Output: colour - string
|
||||
*/
|
||||
char* colour() const;
|
||||
|
||||
/*
|
||||
* Setter for the colour attribute
|
||||
* Input: newColour - string
|
||||
* Output: -
|
||||
*/
|
||||
void colour(const char *newColour);
|
||||
|
||||
/*
|
||||
* Getter for the price attribute
|
||||
* Input: -
|
||||
* Output: price - integer
|
||||
*/
|
||||
int price() const;
|
||||
|
||||
/*
|
||||
* Setter for the price attribute
|
||||
* Input: newPrice - integer
|
||||
* Output: -
|
||||
*/
|
||||
void price(int newPrice);
|
||||
|
||||
/*
|
||||
* Getter for the quantity attribute
|
||||
* Input: -
|
||||
* Output: quantity - integer
|
||||
*/
|
||||
int quantity() const;
|
||||
|
||||
/*
|
||||
* Setter for the quantity attribute
|
||||
* Input: newQuantity - integer
|
||||
* Output: -
|
||||
*/
|
||||
void quantity(int newQuantity);
|
||||
|
||||
/*
|
||||
* Getter for the photograph attribute
|
||||
* Input: -
|
||||
* Output: photograph - string
|
||||
*/
|
||||
char* photograph() const;
|
||||
|
||||
/*
|
||||
* Setter for the photograph attribute
|
||||
* Input: newPhotograph - string
|
||||
* Output: -
|
||||
*/
|
||||
void photograph(const char *newPhotograph);
|
||||
|
||||
/*
|
||||
* Overload of the == operator
|
||||
* Input: trench - trench object
|
||||
* Output: true - if the trench objects are the same
|
||||
* false - otherwise
|
||||
*/
|
||||
bool operator==(const Trench& t);
|
||||
|
||||
/*
|
||||
* Converts the trench object into a string
|
||||
* Input: -
|
||||
* Output: trench - char*
|
||||
*/
|
||||
char* toString();
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "exceptions.h"
|
||||
|
||||
VectorException::VectorException(const char* message){
|
||||
this->_message = message;
|
||||
}
|
||||
|
||||
const char* VectorException::what() const noexcept {
|
||||
return this->_message;
|
||||
}
|
||||
|
||||
RepoException::RepoException(const char* message){
|
||||
this->_message = message;
|
||||
}
|
||||
|
||||
const char* RepoException::what() const noexcept {
|
||||
return this->_message;
|
||||
}
|
||||
|
||||
AdminControllerException::AdminControllerException(const char* message){
|
||||
this->_message = message;
|
||||
}
|
||||
|
||||
const char* AdminControllerException::what() const noexcept {
|
||||
return this->_message;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <exception>
|
||||
|
||||
class VectorException : public std::exception {
|
||||
public:
|
||||
VectorException(const char* message);
|
||||
const char* what() const noexcept override;
|
||||
private:
|
||||
const char* _message;
|
||||
};
|
||||
|
||||
class RepoException : public std::exception {
|
||||
public:
|
||||
RepoException(const char* message);
|
||||
const char* what() const noexcept override;
|
||||
private:
|
||||
const char* _message;
|
||||
};
|
||||
|
||||
class AdminControllerException : public std::exception {
|
||||
public:
|
||||
AdminControllerException(const char* message);
|
||||
const char* what() const noexcept override;
|
||||
private:
|
||||
const char* _message;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "repository/repository.h"
|
||||
#include "controllers/admin_controller/admin_controller.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
void fillRepo(AdminController* controller){
|
||||
controller->add(38,"Bej",55,30,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71zZoa1e-xL._AC_UX466_.jpg");
|
||||
controller->add(40,"Bej",55,25,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71zZoa1e-xL._AC_UX466_.jpg");
|
||||
controller->add(36,"Black",60,5,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/41RBzLubByL._AC_UY550_.jpg");
|
||||
controller->add(40,"Black",60,50,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/41RBzLubByL._AC_UY550_.jpg");
|
||||
controller->add(38,"Army Green",60,40,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/61Qptn0CKQL._AC_UX342_.jpg");
|
||||
controller->add(42,"Army Green",60,40,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/61Qptn0CKQL._AC_UX342_.jpg");
|
||||
controller->add(40,"Black",100,3,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/71YLqJCurtL._AC_UY550_.jpg");
|
||||
controller->add(38,"Red",33,20,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/816lGcU-fWL._AC_UX425_.jpg");
|
||||
controller->add(40,"Red",33,33,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/816lGcU-fWL._AC_UX425_.jpg");
|
||||
controller->add(38,"Blue",51,15,"https://m.media-amazon.com/images/W/IMAGERENDERING_521856-T2/images/I/51zHT88C6zL._AC_UY550_.jpg");
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
|
||||
Repository* repo = new Repository();
|
||||
Repository* shoppingRepo = new Repository();
|
||||
AdminController* controller = new AdminController(repo);
|
||||
fillRepo(controller);
|
||||
UserController* userController = new UserController(repo,shoppingRepo);
|
||||
UI* ui = new UI(controller,userController);
|
||||
ui->run();
|
||||
delete ui;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#include "repository.h"
|
||||
#include "../exceptions/exceptions.h"
|
||||
|
||||
Repository::Repository(){
|
||||
this->_data = new Vector<Trench*>();
|
||||
}
|
||||
Repository::~Repository(){
|
||||
delete this->_data;
|
||||
}
|
||||
void Repository::add(Trench* trench){
|
||||
if(this->get(trench)!=-1)
|
||||
throw RepoException("Trench already exists");
|
||||
this->_data->add(trench);
|
||||
|
||||
}
|
||||
void Repository::remove(Trench* trench){
|
||||
int index = this->get(trench);
|
||||
if(index==-1)
|
||||
throw RepoException("Trench does not exists");
|
||||
this->_data->remove(index);
|
||||
}
|
||||
void Repository::remove(int index){
|
||||
if(index<0 || index > this->_data->size()-1)
|
||||
throw RepoException("Index out of bounds");
|
||||
this->_data->remove(index);
|
||||
}
|
||||
|
||||
int Repository::get(Trench* trench){
|
||||
for(int i=0;i<this->_data->size();i++){
|
||||
if(*trench == *(*this->_data)[i])
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
//return this->_data->get(trench);
|
||||
}
|
||||
|
||||
Trench*& Repository::operator[](int index){
|
||||
if(index<0 || index > this->_data->size()-1)
|
||||
throw RepoException("Index out of bounds");
|
||||
return (*this->_data)[index];
|
||||
}
|
||||
void Repository::update(int index, int price, int quantity){
|
||||
if(index<0 || index > this->_data->size()-1)
|
||||
throw RepoException("Index out of bounds");
|
||||
Trench* trench = (*this->_data)[index];
|
||||
if(price!=-1 && price<=0)
|
||||
throw RepoException("Invalid price");
|
||||
if(quantity!=-1 && quantity<0)
|
||||
throw RepoException("Invalid quantity");
|
||||
if(price>0)
|
||||
trench->price(price);
|
||||
if(quantity>=0)
|
||||
trench->quantity(quantity);
|
||||
}
|
||||
|
||||
int Repository::size(){
|
||||
return this->_data->size();
|
||||
}
|
||||
|
||||
Trench** Repository::begin(){
|
||||
return this->_data->begin();
|
||||
}
|
||||
Trench** Repository::end(){
|
||||
return this->_data->end();
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
#include "../vector/vector.h"
|
||||
#include "../domain/trench.h"
|
||||
|
||||
class Repository {
|
||||
private:
|
||||
Vector<Trench*>* _data;
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Constructor for the Repository class
|
||||
* Input: -
|
||||
* Output: repository object
|
||||
*/
|
||||
Repository();
|
||||
|
||||
/*
|
||||
* Destructor for the Repository class
|
||||
* Input: -
|
||||
* Output: -
|
||||
*/
|
||||
~Repository();
|
||||
|
||||
/*
|
||||
* Adds a trench to the repository
|
||||
* Input: trench - trench object
|
||||
* Output: -
|
||||
* Throws: RepoException if trench already exists
|
||||
*/
|
||||
void add(Trench* trench);
|
||||
|
||||
/*
|
||||
* Removes a trench from the repository
|
||||
* Input: trench - trench object
|
||||
* Output: -
|
||||
* Throws: RepoException if trench does not exist
|
||||
*/
|
||||
void remove(Trench* trench);
|
||||
|
||||
/*
|
||||
* Removes a trench from the repository
|
||||
* Input: index - index of the trench
|
||||
* Output: -
|
||||
* Throws: RepoException if index is out of bounds
|
||||
*/
|
||||
void remove(int index);
|
||||
|
||||
/*
|
||||
* Returns the index of a trench in the repository
|
||||
* Input: trench - trench object
|
||||
* Output: index of the trench. -1 if trench does not exist
|
||||
*/
|
||||
int get(Trench* trench);
|
||||
|
||||
/*
|
||||
* Returns a trench from the repository
|
||||
* Input: index - index of the trench
|
||||
* Output: trench object
|
||||
* Throws: RepoException if index is out of bounds
|
||||
*/
|
||||
Trench*& operator[](int index);
|
||||
|
||||
/*
|
||||
* Updates a trench from the repository
|
||||
* Input: index - index of the trench
|
||||
* price - new price
|
||||
* quantity - new quantity
|
||||
* Output: -
|
||||
* Throws: RepoException if index is out of bounds
|
||||
*/
|
||||
void update(int index, int price, int quantity);
|
||||
|
||||
/*
|
||||
* Returns the size of the repository
|
||||
* Input: -
|
||||
* Output: size of the repository
|
||||
*/
|
||||
int size();
|
||||
|
||||
/*
|
||||
* Returns an iterator to the beginning of the repository
|
||||
* Input: -
|
||||
* Output: iterator to the beginning of the repository
|
||||
*/
|
||||
Trench** begin();
|
||||
|
||||
/*
|
||||
* Returns an iterator to the end of the repository
|
||||
* Input: -
|
||||
* Output: iterator to the end of the repository
|
||||
*/
|
||||
Trench** end();
|
||||
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
#include<stdio.h>
|
||||
#include "tests/domain_tests/domain_tests.h"
|
||||
#include "tests/vector_tests/vector_tests.h"
|
||||
#include "tests/repo_tests/repo_tests.h"
|
||||
#include "tests/admin_controller_tests/admin_controller_tests.h"
|
||||
#include "tests/user_controller_tests/user_controller_tests.h"
|
||||
|
||||
|
||||
int main(){
|
||||
|
||||
test_domain();
|
||||
test_vector();
|
||||
test_repo();
|
||||
test_admin_controller();
|
||||
test_user_controller();
|
||||
printf("\nDone\n\n");
|
||||
return 0;
|
||||
}
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
#include "admin_controller_tests.h"
|
||||
#include "../../controllers/admin_controller/admin_controller.h"
|
||||
#include "../../repository/repository.h"
|
||||
#include "../../domain/trench.h"
|
||||
#include "../../exceptions/exceptions.h"
|
||||
|
||||
#include<assert.h>
|
||||
#include<string.h>
|
||||
#include<stdlib.h>
|
||||
#include<stdio.h>
|
||||
|
||||
void test_admin_controller(void){
|
||||
Repository* repo = new Repository();
|
||||
AdminController* controller = new AdminController(repo);
|
||||
int check = 0;
|
||||
|
||||
try{
|
||||
controller->add(0,"1",1,1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Size must be greater than 0")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->add(1,"",1,1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Colour must not be empty")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->add(1,"1",0,1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Price must be greater than 0")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->add(1,"1",1,-1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Quantity must be greater than or equal to 0")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->add(1,"1",1,1,"");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Photograph must not be empty")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
controller->add(1,"1",1,1,"1");
|
||||
try{
|
||||
controller->add(1,"1",1,1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Trench already exists")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->remove(0,"1","1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Size must be greater than 0")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->remove(1,"","1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Colour must not be empty")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->remove(1,"1","");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Photograph must not be empty")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
controller->remove(1,"1","1");
|
||||
try{
|
||||
controller->remove(1,"1","1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Trench does not exists")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
controller->add(1,"1",1,1,"1");
|
||||
controller->remove(0);
|
||||
try{
|
||||
controller->remove(1);
|
||||
}
|
||||
catch(RepoException& e){
|
||||
assert(strcmp(e.what(),"Index out of bounds")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
controller->add(1,"1",1,1,"1");
|
||||
|
||||
|
||||
try{
|
||||
controller->update(0,"1",1,1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Size must be greater than 0")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->update(1,"",1,1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Colour must not be empty")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->update(1,"1",0,1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Price must be greater than 0")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->update(1,"1",1,-2,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Quantity must be greater than or equal to 0")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->update(1,"1",1,1,"");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Photograph must not be empty")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
controller->update(1,"1",2,2,"1");
|
||||
try{
|
||||
controller->update(2,"1",1,1,"1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Trench does not exist")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->get(0,"1","1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Size must be greater than 0")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->get(1,"","1");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Colour must not be empty")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
try{
|
||||
controller->get(1,"1","");
|
||||
}
|
||||
catch(AdminControllerException& e){
|
||||
assert(strcmp(e.what(),"Photograph must not be empty")==0);
|
||||
check=1;
|
||||
}
|
||||
assert(check);
|
||||
check=0;
|
||||
assert(controller->get(1,"1","1")==0);
|
||||
assert(controller->size()==1);
|
||||
assert((*controller)[0]->size()==1);
|
||||
assert(controller->getAll()==repo);
|
||||
|
||||
delete controller;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void test_admin_controller(void);
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "domain_tests.h"
|
||||
#include "../../domain/trench.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
void test_domain(void){
|
||||
Trench trench(1,"red",100,10,"photo");
|
||||
assert(trench.size()==1);
|
||||
assert(strcmp(trench.colour(),"red")==0);
|
||||
assert(trench.price()==100);
|
||||
assert(trench.quantity()==10);
|
||||
assert(strcmp(trench.photograph(),"photo")==0);
|
||||
trench.size(2);
|
||||
assert(trench.size()==2);
|
||||
trench.colour("blue");
|
||||
assert(strcmp(trench.colour(),"blue")==0);
|
||||
trench.price(200);
|
||||
assert(trench.price()==200);
|
||||
trench.quantity(20);
|
||||
assert(trench.quantity()==20);
|
||||
trench.photograph("photo2");
|
||||
assert(strcmp(trench.photograph(),"photo2")==0);
|
||||
Trench trench2(trench);
|
||||
assert(trench2.size()==2);
|
||||
assert(strcmp(trench2.colour(),"blue")==0);
|
||||
assert(trench2.price()==200);
|
||||
assert(trench2.quantity()==20);
|
||||
assert(strcmp(trench2.photograph(),"photo2")==0);
|
||||
trench2.size(3);
|
||||
assert(trench2.size()==3);
|
||||
assert(trench.size()==2);
|
||||
trench2.colour("green");
|
||||
assert(strcmp(trench2.colour(),"green")==0);
|
||||
assert(strcmp(trench.colour(),"blue")==0);
|
||||
trench2.price(300);
|
||||
assert(trench2.price()==300);
|
||||
assert(trench.price()==200);
|
||||
trench2.quantity(30);
|
||||
assert(trench2.quantity()==30);
|
||||
assert(trench.quantity()==20);
|
||||
trench2.photograph("photo3");
|
||||
assert(strcmp(trench2.photograph(),"photo3")==0);
|
||||
assert(strcmp(trench.photograph(),"photo2")==0);
|
||||
Trench trench3 = trench2;
|
||||
assert(trench2==trench3);
|
||||
assert(!(trench==trench3));
|
||||
trench3.price(100);
|
||||
assert(trench2.price()==300);
|
||||
assert(trench3.price()==100);
|
||||
char* string = trench.toString();
|
||||
assert(strcmp(string,"Size: 2 | Colour: blue | Price: 200 | Quantity: 20 | Photograph Link: photo2 \n")==0);
|
||||
delete[] string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void test_domain(void);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user