Instructions
Requirements and Specifications
Source Code
#include "Ledger.h"
#include "Transaction.h"
#include "State.h"
Ledger::Ledger() {
head = nullptr;
tail = nullptr;
size = 0;
}
Ledger::~Ledger() {
Node* curr = head;
while(curr != nullptr) {
Node* tmp = curr->getNext();
delete curr;
curr = tmp;
}
}
Ledger& Ledger::operator+=(const Transaction& t) {
Node* tNode = new Transaction(t.getFromName(), t.getToName(), t.getAmount());
if (tail == nullptr) {
head = tNode;
tail = tNode;
size = 1;
}
else {
tail->setNext(tNode);
tail = tNode;
if (size % STEP == STEP - 1) {
std::map<std::string, double> result = calc();
Node* sNode = new State(result);
tail->setNext(sNode);
tail = sNode;
}
size++;
}
return *this;
}
Ledger& Ledger::operator-=(const Transaction& t) {
int steps = size / STEP;
Node* curr = head;
Node* prev = nullptr;
for(int i = 0; i<steps; i++) {
for (int j = 0; j<STEP; j++) {
curr = curr->getNext();
}
if (i == steps - 1) {
prev = curr;
curr = curr->getNext();
break;
}
curr = curr->getNext();
}
while(curr != nullptr) {
Transaction* tNode = dynamic_cast<Transaction*>(curr);
if (tNode->getFromName() == t.getFromName() && tNode->getToName() == t.getToName() && tNode->getAmount() == t.getAmount()) {
if (prev == nullptr) {
head = tNode->getNext();
if (head == nullptr) {
tail = nullptr;
}
}
else {
prev->setNext(tNode->getNext());
if (prev->getNext() == nullptr) {
tail = prev;
}
}
delete tNode;
size--;
break;
}
prev = curr;
curr = curr->getNext();
}
return *this;
}
void Ledger::Clear() {
size = 0;
head = nullptr;
}
void Ledger::Settle() {
std::map<std::string, double> result = calc();
std::map<std::string, double>::iterator it;
for (it = result.begin(); it != result.end(); it++) {
std::cout << it->first << ": " << it->second << std::endl;
}
}
std::map<std::string, double> Ledger::calc() {
int steps = size / STEP;
Node* curr = head;
std::map<std::string, double> result;
for(int i = 0; i<steps; i++) {
for (int j = 0; j<STEP; j++) {
curr = curr->getNext();
}
if (i == steps - 1) {
result = (dynamic_cast<State*>(curr))->getAll();
curr = curr->getNext();
break;
}
curr = curr->getNext();
}
while(curr != nullptr) {
std::string from = (dynamic_cast<Transaction*>(curr))->getFromName();
std::string to = (dynamic_cast<Transaction*>(curr))->getToName();
double amount = (dynamic_cast<Transaction*>(curr))->getAmount();
if (from != EXTERNAL_ACCOUNT) {
if (result.find(from) != result.end()) {
result[from] -= amount;
}
else {
result[from] = -amount;
}
}
if (to != EXTERNAL_ACCOUNT) {
if (result.find(to) != result.end()) {
result[to] += amount;
}
else {
result[to] = amount;
}
}
curr = curr->getNext();
}
return result;
}
void Ledger::InTheBlack() {
std::map<std::string, double> result = calc();
std::map<std::string, double>::iterator it;
for (it = result.begin(); it != result.end(); it++) {
if (it->second > 0.0) {
std::cout << it->first << ": " << it->second << std::endl;
}
}
}
void Ledger::InTheRed() {
std::map<std::string, double> result = calc();
std::map<std::string, double>::iterator it;
for (it = result.begin(); it != result.end(); it++) {
if (it->second < 0.0) {
std::cout << it->first << ": " << it->second << std::endl;
}
}
}
std::ostream& operator<<(std::ostream& os, const Ledger& l) {
Node* curr = l.head;
int counter = 0;
while(curr != nullptr) {
if (counter % l.STEP == 0) {
curr = curr->getNext();
}
os << curr->to_string() << std::endl;
curr = curr->getNext();
counter++;
}
return os;
}