Website Summary Files Commits Branches @commit @diff @stats
path: root / Week05 / Exercise03
diff options
context:
space:
mode:
Commit571dc57f812a685bda7bd3baf8aaf2ef56feae65 (patch)
Author
 Syndamia <kamen@syndamia.com>
2026-03-28 16:19:58 +0200
Committer
 Syndamia <kamen@syndamia.com>
2026-03-28 16:19:58 +0200
Filesd69f560eccb705339f44be22369bb8fed025e642 /Week05/Exercise03
oop-2025-solutions-571dc57f812a685bda7bd3baf8aaf2ef56feae65.tar
oop-2025-solutions-571dc57f812a685bda7bd3baf8aaf2ef56feae65.tar.gz
oop-2025-solutions-571dc57f812a685bda7bd3baf8aaf2ef56feae65.zip
Parente5c06fbc864205a9736f07f9237ace80617ca471 (diff)
feat(Week05): Add solutions
diff --git a/Week05/Exercise03/Person.cpp b/Week05/Exercise03/Person.cpp
new file mode 100644
index 0000000..fb46253
--- /dev/null
+++ b/Week05/Exercise03/Person.cpp
@@ -0,0 +1,40 @@
+#include "Person.h"
+#include <iostream>
+
+Person::Person(const String& firstName, const String& middleName, const String& lastName, unsigned long long phoneNumber, const String& email, unsigned short birthYear, unsigned long long PN) {
+ this->firstName = firstName;
+ this->middleName = middleName;
+ this->lastName = lastName;
+ this->phoneNumber = phoneNumber;
+ this->email = email;
+ this->birthYear = birthYear;
+ this->PN = PN;
+}
+
+const String& Person::GetFirstName() const {
+ return firstName;
+}
+
+const String& Person::GetMiddleName() const {
+ return middleName;
+}
+
+const String& Person::GetLastName() const {
+ return lastName;
+}
+
+unsigned long long Person::GetPhoneNumber() const {
+ return phoneNumber;
+}
+
+const String& Person::GetEmail() const {
+ return email;
+}
+
+unsigned short Person::GetBirthYear() const {
+ return birthYear;
+}
+
+unsigned long long Person::GetPN() const {
+ return PN;
+}
diff --git a/Week05/Exercise03/Person.h b/Week05/Exercise03/Person.h
new file mode 100644
index 0000000..046e691
--- /dev/null
+++ b/Week05/Exercise03/Person.h
@@ -0,0 +1,37 @@
+#ifndef _PERSON
+#define _PERSON
+
+#include "String.h"
+
+class Person {
+ String firstName;
+ String middleName;
+ String lastName;
+ unsigned long long phoneNumber;
+ String email;
+ unsigned short birthYear;
+ unsigned long long PN; // Personal Number
+
+public:
+ Person(const String& firstName, const String& middleName, const String& lastName, unsigned long long phoneNumber, const String& email, unsigned short birthYear, unsigned long long PN);
+
+ /* Помощни член-функции */
+
+ // За да създадем масив се нуждаем от празен конструктор,
+ // обаче отгоре дефинирахме някакъв конструктор, което
+ // означава че празния по подразбиране не се създава.
+ // Можем сами да си го дефинираме, но с този синтаксис
+ // можем да задължим компилатора да използва този,
+ // който би генерирал по принцип.
+ Person() = default;
+
+ const String& GetFirstName() const;
+ const String& GetMiddleName() const;
+ const String& GetLastName() const;
+ unsigned long long GetPhoneNumber() const;
+ const String& GetEmail() const;
+ unsigned short GetBirthYear() const;
+ unsigned long long GetPN() const;
+};
+
+#endif /* _PERSON */
diff --git a/Week05/Exercise03/String.cpp b/Week05/Exercise03/String.cpp
new file mode 100644
index 0000000..1a59ef4
--- /dev/null
+++ b/Week05/Exercise03/String.cpp
@@ -0,0 +1,70 @@
+#include "String.h"
+#include <cstring>
+
+void String::free() {
+ delete[] str;
+}
+
+void String::copyFrom(const String& other) {
+ length = other.length;
+
+ // Не забравяме за терминиращата нула
+ str = new char[length + 1];
+ strncpy(str, other.str, length + 1);
+}
+
+String::String() {
+ str = nullptr;
+ length = 0;
+}
+
+String::~String() {
+ free();
+}
+
+String::String(const String& other) {
+ copyFrom(other);
+}
+
+String& String::operator=(const String& other) {
+ if (this != &other) {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+String::String(String&& other) {
+ str = other.str;
+ length = other.length;
+
+ other.str = nullptr;
+ other.length = 0;
+}
+
+String& String::operator=(String&& other) {
+ if (this != &other) {
+ free();
+
+ str = other.str;
+ length = other.length;
+
+ other.str = nullptr;
+ other.length = 0;
+ }
+ return *this;
+}
+
+String::String(const char* str) {
+ length = strlen(str);
+ this->str = new char[length + 1];
+ strncpy(this->str, str, length + 1);
+}
+
+bool String::IsTheSameAs(const String& other) const {
+ return strcmp(str, other.str) == 0;
+}
+
+const char* String::GetStr() const {
+ return str;
+}
diff --git a/Week05/Exercise03/String.h b/Week05/Exercise03/String.h
new file mode 100644
index 0000000..3b0aa1d
--- /dev/null
+++ b/Week05/Exercise03/String.h
@@ -0,0 +1,26 @@
+#ifndef _STRING
+#define _STRING
+
+class String {
+ char* str;
+ unsigned length;
+
+ void free();
+ void copyFrom(const String& other);
+
+public:
+ String();
+ ~String();
+ String(const String& other);
+ String& operator=(const String& other);
+
+ String(String&& other);
+ String& operator=(String&& other);
+
+ String(const char* str);
+
+ bool IsTheSameAs(const String& other) const;
+ const char* GetStr() const;
+};
+
+#endif /* _STRING */
diff --git a/Week05/Exercise03/TaxDatabase.cpp b/Week05/Exercise03/TaxDatabase.cpp
new file mode 100644
index 0000000..c12c228
--- /dev/null
+++ b/Week05/Exercise03/TaxDatabase.cpp
@@ -0,0 +1,333 @@
+#include "TaxDatabase.h"
+#include <iostream>
+
+void TaxDatabase::free() {
+ delete[] people;
+ delete[] reports;
+}
+
+void TaxDatabase::copyFrom(const TaxDatabase& other) {
+ peopleCount = other.peopleCount;
+ peopleAllocated = other.peopleAllocated;
+
+ people = new Person[peopleAllocated];
+ for (unsigned i = 0; i < peopleCount; ++i)
+ people[i] = other.people[i];
+
+ reportsCount = other.reportsCount;
+ reportsAllocated = other.reportsAllocated;
+
+ reports = new TaxReport[reportsAllocated];
+ for (unsigned i = 0; i < reportsCount; ++i)
+ reports[i] = other.reports[i];
+}
+
+void TaxDatabase::resizePeople() {
+ unsigned newAllocated = peopleAllocated == 0 ? 8 : peopleAllocated * 2;
+ Person* newPeople = new Person[newAllocated];
+
+ for (unsigned i = 0; i < peopleCount; ++i)
+ newPeople[i] = people[i];
+
+ delete[] people;
+ people = newPeople;
+ peopleAllocated = newAllocated;
+}
+
+void TaxDatabase::resizeReports() {
+ unsigned newAllocated = reportsAllocated == 0 ? 8 : reportsAllocated * 2;
+ TaxReport* newReports = new TaxReport[newAllocated];
+
+ for (unsigned i = 0; i < reportsCount; ++i)
+ newReports[i] = reports[i];
+
+ delete[] reports;
+ reports = newReports;
+ reportsAllocated = newAllocated;
+}
+
+TaxDatabase::TaxDatabase() {
+ people = nullptr;
+ reports = nullptr;
+ peopleCount = peopleAllocated = reportsCount = reportsAllocated = 0;
+}
+
+TaxDatabase::~TaxDatabase() {
+ free();
+}
+
+TaxDatabase::TaxDatabase(const TaxDatabase& other) {
+ copyFrom(other);
+}
+
+TaxDatabase& TaxDatabase::operator=(const TaxDatabase& other) {
+ if (this != &other) {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+TaxDatabase::TaxDatabase(TaxDatabase&& other) {
+ people = other.people;
+ peopleCount = other.peopleCount;
+ peopleAllocated = other.peopleAllocated;
+
+ reports = other.reports;
+ reportsCount = other.reportsCount;
+ reportsAllocated = other.reportsAllocated;
+
+ other.people = nullptr;
+ other.reports = nullptr;
+ other.peopleCount = other.peopleAllocated = other.reportsCount = other.reportsAllocated = 0;
+}
+
+TaxDatabase& TaxDatabase::operator=(TaxDatabase&& other) {
+ if (this != &other) {
+ free();
+
+ people = other.people;
+ peopleCount = other.peopleCount;
+ peopleAllocated = other.peopleAllocated;
+
+ reports = other.reports;
+ reportsCount = other.reportsCount;
+ reportsAllocated = other.reportsAllocated;
+
+ other.people = nullptr;
+ other.reports = nullptr;
+ other.peopleCount = other.peopleAllocated = other.reportsCount = other.reportsAllocated = 0;
+ }
+ return *this;
+}
+
+bool TaxDatabase::RegisterPerson(const Person& person) {
+ for (unsigned i = 0; i < peopleCount; ++i) {
+ if (people[i].GetPN() == person.GetPN() ||
+ people[i].GetPhoneNumber() == person.GetPhoneNumber() ||
+ people[i].GetEmail().IsTheSameAs(person.GetEmail()))
+ {
+ return false;
+ }
+ }
+
+ if (peopleCount >= peopleAllocated)
+ resizePeople();
+ people[peopleCount++] = person;
+
+ return true;
+}
+
+bool TaxDatabase::LogTaxReport(const TaxReport& report) {
+ for (unsigned i = 0; i < reportsCount; ++i) {
+ if (reports[i].GetPN() == report.GetPN() &&
+ reports[i].GetYear() == report.GetYear())
+ {
+ return false;
+ }
+ }
+
+ if (reportsCount >= reportsAllocated)
+ resizeReports();
+ reports[reportsCount++] = report;
+
+ return true;
+}
+
+void TaxDatabase::PersonalReports(unsigned long long PN) const {
+ const Person* p = GetPerson(PN);
+ if (p == nullptr) {
+ std::cout << "Person not in database!" << std::endl;
+ return;
+ }
+
+ std::cout << p->GetFirstName().GetStr() << ' ' << p->GetMiddleName().GetStr() << ' ' << p->GetLastName().GetStr() << std::endl
+ << "Personal No: " << p->GetPN() << " Born: " << p->GetBirthYear() << std::endl
+ << "Tel: " << p->GetPhoneNumber() << " Email: " << p->GetEmail().GetStr() << std::endl;
+
+ for (unsigned i = 0; i < reportsCount; ++i) {
+ if (reports[i].GetPN() == PN) {
+ std::cout << reports[i].GetYear()
+ << " Income: " << reports[i].GetIncome()
+ << " Tax rate: " << reports[i].GetTaxRate() << std::endl;
+ }
+ }
+}
+
+void TaxDatabase::YearlyReports(unsigned short year) const {
+ for (unsigned i = 0; i < reportsCount; ++i) {
+ if (reports[i].GetYear() != year)
+ continue;
+
+ const Person* p = GetPerson(reports[i].GetPN());
+ if (p != nullptr) {
+ std::cout << p->GetFirstName().GetStr() << ' ' << p->GetLastName().GetStr()
+ << " Age: " << (year - p->GetBirthYear())
+ << " Income: " << reports[i].GetIncome()
+ << " Tax rate: " << reports[i].GetTaxRate() << std::endl;
+ }
+ }
+}
+
+double TaxDatabase::YearlyAvgIncome(unsigned short year) const {
+ double incomeSum = 0.0;
+ unsigned reportsInYear = 0;
+
+ for (unsigned i = 0; i < reportsCount; ++i) {
+ if (reports[i].GetYear() != year)
+ continue;
+
+ incomeSum += reports[i].GetIncome();
+ ++reportsInYear;
+ }
+
+ return incomeSum / reportsInYear;
+}
+
+double TaxDatabase::YearlyTaxedIncome(unsigned short year) const {
+ double profits = 0.0;
+
+ for (unsigned i = 0; i < reportsCount; ++i) {
+ if (reports[i].GetYear() != year)
+ continue;
+
+ profits += reports[i].GetIncome() * reports[i].GetTaxRate();
+ }
+
+ return profits;
+}
+
+const TaxReport* TaxDatabase::GetReport(unsigned long long PN, unsigned short year) const {
+ for (unsigned i = 0; i < reportsCount; ++i) {
+ if (reports[i].GetPN() == PN && reports[i].GetYear() == year)
+ return reports + i;
+ }
+ return nullptr;
+}
+
+const TaxReport* TaxDatabase::GetReportByAge(unsigned long long PN, unsigned short age) const {
+ const Person* p = GetPerson(PN);
+
+ if (p == nullptr)
+ return nullptr;
+
+ return GetReport(PN, p->GetBirthYear() + age);
+}
+
+void TaxDatabase::Reports::copyFrom(const Reports& other) {
+ reportsCount = other.reportsCount;
+
+ reports = new TaxReport*[reportsCount];
+ for (unsigned i = 0; i < reportsCount; ++i)
+ reports[i] = other.reports[i];
+}
+
+void TaxDatabase::Reports::free() {
+ delete[] reports;
+}
+
+TaxDatabase::Reports::Reports() {
+ reports = nullptr;
+ reportsCount = 0;
+}
+
+TaxDatabase::Reports::~Reports() {
+ free();
+}
+
+TaxDatabase::Reports::Reports(const Reports& other) {
+ copyFrom(other);
+}
+
+TaxDatabase::Reports& TaxDatabase::Reports::operator=(const Reports& other) {
+ if (this != &other) {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+TaxDatabase::Reports::Reports(Reports&& other) {
+ reports = other.reports;
+ reportsCount = other.reportsCount;
+
+ other.reports = nullptr;
+ other.reportsCount = 0;
+}
+
+TaxDatabase::Reports& TaxDatabase::Reports::operator=(Reports&& other) {
+ if (this != &other) {
+ free();
+
+ reports = other.reports;
+ reportsCount = other.reportsCount;
+
+ other.reports = nullptr;
+ other.reportsCount = 0;
+ }
+ return *this;
+}
+
+unsigned TaxDatabase::Reports::ReportsCount() const {
+ return reportsCount;
+}
+
+const TaxReport* TaxDatabase::Reports::At(unsigned index) const {
+ if (index >= reportsCount)
+ return nullptr;
+
+ return reports[index];
+}
+
+void TaxDatabase::Reports::Allocate(unsigned size) {
+ reportsCount = size;
+ if (reports != nullptr)
+ delete[] reports;
+ reports = new TaxReport*[size];
+}
+
+TaxReport** TaxDatabase::Reports::At(unsigned index) {
+ if (index >= reportsCount)
+ return nullptr;
+
+ return reports + index;
+}
+
+const TaxDatabase::Reports TaxDatabase::GetReports(unsigned long long PN, unsigned short startYear, unsigned short endYear) const {
+ unsigned countReports = 0;
+
+ for (unsigned i = 0; i < reportsCount; ++i) {
+ if (reports[i].GetPN() == PN && startYear <= reports[i].GetYear() && reports[i].GetYear() <= endYear)
+ ++countReports;
+ }
+
+ Reports result;
+ result.Allocate(countReports);
+
+ unsigned reportIndex = 0;
+ for (unsigned i = 0; i < reportsCount; ++i) {
+ if (reports[i].GetPN() == PN && startYear <= reports[i].GetYear() && reports[i].GetYear() <= endYear) {
+ *result.At(reportIndex++) = reports + i;
+ }
+ }
+
+ return result;
+}
+
+const TaxDatabase::Reports TaxDatabase::GetReportsByAge(unsigned long long PN, unsigned short startAge, unsigned short endAge) const {
+ const Person* p = GetPerson(PN);
+
+ if (p == nullptr)
+ return Reports();
+
+ return GetReports(PN, p->GetBirthYear() + startAge, p->GetBirthYear() + endAge);
+}
+
+const Person* TaxDatabase::GetPerson(unsigned long long PN) const {
+ for (unsigned i = 0; i < peopleCount; ++i) {
+ if (people[i].GetPN() == PN) {
+ return people + i;
+ }
+ }
+ return nullptr;
+}
diff --git a/Week05/Exercise03/TaxDatabase.h b/Week05/Exercise03/TaxDatabase.h
new file mode 100644
index 0000000..89dd1ed
--- /dev/null
+++ b/Week05/Exercise03/TaxDatabase.h
@@ -0,0 +1,80 @@
+#ifndef _TAXDATABASE
+#define _TAXDATABASE
+
+#include "Person.h"
+#include "TaxReport.h"
+
+class TaxDatabase {
+ Person* people;
+ unsigned peopleCount;
+ unsigned peopleAllocated;
+
+ TaxReport* reports;
+ unsigned reportsCount;
+ unsigned reportsAllocated;
+
+ void free();
+ void copyFrom(const TaxDatabase& other);
+
+ void resizePeople();
+ void resizeReports();
+
+public:
+ TaxDatabase();
+ ~TaxDatabase();
+ TaxDatabase(const TaxDatabase& other);
+ TaxDatabase& operator=(const TaxDatabase& other);
+
+ TaxDatabase(TaxDatabase&& other);
+ TaxDatabase& operator=(TaxDatabase&& other);
+
+ bool RegisterPerson(const Person& person);
+ bool LogTaxReport(const TaxReport& report);
+
+ void PersonalReports(unsigned long long PN) const;
+ void YearlyReports(unsigned short year) const;
+
+ double YearlyAvgIncome(unsigned short year) const;
+ double YearlyTaxedIncome(unsigned short year) const;
+
+ const TaxReport* GetReport(unsigned long long PN, unsigned short year) const;
+ const TaxReport* GetReportByAge(unsigned long long PN, unsigned short age) const;
+
+ // Можем да дефинираме класове в други класове, можем да достъпим
+ // вътрешния клас с името "TaxDatabase::Reports".
+ // Достъпността на класа следва public/protected/private, в този
+ // случай класа е публичен.
+ class Reports {
+ TaxReport** reports;
+ unsigned reportsCount;
+
+ void copyFrom(const Reports& other);
+ void free();
+
+ public:
+ Reports();
+ ~Reports();
+ Reports(const Reports& other);
+ Reports& operator=(const Reports& other);
+
+ Reports(Reports&& other);
+ Reports& operator=(Reports&& other);
+
+ unsigned ReportsCount() const;
+ const TaxReport* At(unsigned index) const;
+
+ // Тези се използват единствено от GetReports и GetReportsByAge
+ // Тоест не позволяваме на върнатата стойност да бъде изменяна
+ void Allocate(unsigned size);
+ TaxReport** At(unsigned index);
+ };
+
+ const Reports GetReports(unsigned long long PN, unsigned short startYear, unsigned short endYear) const;
+ const Reports GetReportsByAge(unsigned long long PN, unsigned short startAge, unsigned short endAge) const;
+
+ /* Помощни функции */
+
+ const Person* GetPerson(unsigned long long PN) const;
+};
+
+#endif /* _TAXDATABASE */
diff --git a/Week05/Exercise03/TaxReport.cpp b/Week05/Exercise03/TaxReport.cpp
new file mode 100644
index 0000000..2ff321f
--- /dev/null
+++ b/Week05/Exercise03/TaxReport.cpp
@@ -0,0 +1,25 @@
+#include "TaxReport.h"
+#include <iostream>
+
+TaxReport::TaxReport(unsigned long long PN, unsigned short year, double income, double taxRate) {
+ this->PN = PN;
+ this->year = year;
+ this->income = income;
+ this->taxRate = taxRate;
+}
+
+unsigned long long TaxReport::GetPN() const {
+ return PN;
+}
+
+unsigned short TaxReport::GetYear() const {
+ return year;
+}
+
+double TaxReport::GetIncome() const {
+ return income;
+}
+
+double TaxReport::GetTaxRate() const {
+ return taxRate;
+}
diff --git a/Week05/Exercise03/TaxReport.h b/Week05/Exercise03/TaxReport.h
new file mode 100644
index 0000000..1dee2a4
--- /dev/null
+++ b/Week05/Exercise03/TaxReport.h
@@ -0,0 +1,29 @@
+#ifndef _TAXREPORT
+#define _TAXREPORT
+
+class TaxReport {
+ unsigned long long PN; // Personal Number
+ unsigned short year;
+ double income;
+ double taxRate;
+
+public:
+ TaxReport(unsigned long long PN, unsigned short year, double income, double taxRate);
+
+ /* Помощни член-функции */
+
+ // За да създадем масив се нуждаем от празен конструктор,
+ // обаче отгоре дефинирахме някакъв конструктор, което
+ // означава че празния по подразбиране не се създава.
+ // Можем сами да си го дефинираме, но с този синтаксис
+ // можем да задължим компилатора да използва този,
+ // който би генерирал по принцип.
+ TaxReport() = default;
+
+ unsigned long long GetPN() const;
+ unsigned short GetYear() const;
+ double GetIncome() const;
+ double GetTaxRate() const;
+};
+
+#endif /* _TAXREPORT */
diff --git a/Week05/Exercise03/test.cpp b/Week05/Exercise03/test.cpp
new file mode 100644
index 0000000..9e8f43c
--- /dev/null
+++ b/Week05/Exercise03/test.cpp
@@ -0,0 +1,100 @@
+#include "TaxDatabase.h"
+#include "TaxReport.h"
+#include <iostream>
+
+// Силно препоръчително е да тествате големи програми,
+// дори да не ви се иска по условие
+int main() {
+ TaxDatabase td;
+
+ td.RegisterPerson(Person("Petur", "Ivanov", "Dimitrov", 888500600, "pid@mail.com", 1989, 384));
+ td.RegisterPerson(Person("Konstantin", "Filiopv", "Abrahildraganovichevich", 887111000, "k@mail.com", 1992, 591));
+
+ td.LogTaxReport(TaxReport(384, 2009, 10000, 0.1));
+ td.LogTaxReport(TaxReport(384, 2010, 15000, 0.1));
+ td.LogTaxReport(TaxReport(384, 2011, 20000, 0.1));
+ td.LogTaxReport(TaxReport(384, 2012, 30000, 0.1));
+ td.LogTaxReport(TaxReport(384, 2013, 70000, 0.2));
+ td.LogTaxReport(TaxReport(384, 2014, 100000, 0.2));
+
+ td.LogTaxReport(TaxReport(591, 2012, 3900, 0.1));
+ td.LogTaxReport(TaxReport(591, 2013, 40000, 0.2));
+ td.LogTaxReport(TaxReport(591, 2014, 45000, 0.2));
+ td.LogTaxReport(TaxReport(591, 2015, 50000, 0.15));
+
+ td.PersonalReports(384);
+ td.PersonalReports(591);
+
+ std::cout << std::endl;
+
+ td.YearlyReports(2014);
+ td.YearlyReports(2015);
+
+ std::cout << std::endl;
+
+ std::cout << td.YearlyAvgIncome(2011) << ' '
+ << td.YearlyAvgIncome(2014) << ' '
+ << td.YearlyAvgIncome(2015) << std::endl;
+
+ std::cout << std::endl;
+
+ std::cout << td.YearlyTaxedIncome(2011) << ' '
+ << td.YearlyTaxedIncome(2014) << ' '
+ << td.YearlyTaxedIncome(2015) << std::endl;
+
+ std::cout << std::endl;
+
+ const TaxReport* r;
+
+ r = td.GetReport(384, 2013);
+ if (r == nullptr)
+ std::cout << "No report for 2013" << std::endl;
+ else
+ std::cout << r->GetYear() << ' ' << r->GetPN() << ' ' << r->GetIncome() << ' ' << r->GetTaxRate() << std::endl;
+
+ r = td.GetReport(384, 2015);
+ if (r == nullptr)
+ std::cout << "No report for 2015" << std::endl;
+ else
+ std::cout << r->GetYear() << ' ' << r->GetPN() << ' ' << r->GetIncome() << ' ' << r->GetTaxRate() << std::endl;
+
+ r = td.GetReport(591, 2015);
+ if (r == nullptr)
+ std::cout << "No report for 2015" << std::endl;
+ else
+ std::cout << r->GetYear() << ' ' << r->GetPN() << ' ' << r->GetIncome() << ' ' << r->GetTaxRate() << std::endl;
+
+ std::cout << std::endl;
+
+ r = td.GetReportByAge(384, 20);
+ if (r == nullptr)
+ std::cout << "No report at 20" << std::endl;
+ else
+ std::cout << r->GetYear() << ' ' << r->GetPN() << ' ' << r->GetIncome() << ' ' << r->GetTaxRate() << std::endl;
+
+ r = td.GetReportByAge(384, 21);
+ if (r == nullptr)
+ std::cout << "No report at 21" << std::endl;
+ else
+ std::cout << r->GetYear() << ' ' << r->GetPN() << ' ' << r->GetIncome() << ' ' << r->GetTaxRate() << std::endl;
+
+ r = td.GetReportByAge(591, 23);
+ if (r == nullptr)
+ std::cout << "No report at 23" << std::endl;
+ else
+ std::cout << r->GetYear() << ' ' << r->GetPN() << ' ' << r->GetIncome() << ' ' << r->GetTaxRate() << std::endl;
+
+ std::cout << std::endl;
+
+ const TaxDatabase::Reports reports1 = td.GetReports(591, 2005, 2015);
+ for (unsigned i = 0; i < reports1.ReportsCount(); ++i)
+ std::cout << reports1.At(i)->GetPN() << ' ' << reports1.At(i)->GetYear() << std::endl;
+
+ std::cout << std::endl;
+
+ const TaxDatabase::Reports reports2 = td.GetReportsByAge(384, 20, 25);
+ for (unsigned i = 0; i < reports2.ReportsCount(); ++i)
+ std::cout << reports2.At(i)->GetPN() << ' ' << reports2.At(i)->GetYear() << std::endl;
+
+ return 0;
+}