diff options
feat(Week05): Add solutions
16 files changed, 1087 insertions, 0 deletions
| -rw-r--r-- | Week05/Exercise01/NumSeries.cpp | 88 | ||||
| -rw-r--r-- | Week05/Exercise01/NumSeries.h | 27 | ||||
| -rw-r--r-- | Week05/Exercise02/String.cpp | 103 | ||||
| -rw-r--r-- | Week05/Exercise02/String.h | 32 | ||||
| -rw-r--r-- | Week05/Exercise02/Text.cpp | 67 | ||||
| -rw-r--r-- | Week05/Exercise02/Text.h | 27 | ||||
| -rw-r--r-- | Week05/Exercise03/Person.cpp | 40 | ||||
| -rw-r--r-- | Week05/Exercise03/Person.h | 37 | ||||
| -rw-r--r-- | Week05/Exercise03/String.cpp | 70 | ||||
| -rw-r--r-- | Week05/Exercise03/String.h | 26 | ||||
| -rw-r--r-- | Week05/Exercise03/TaxDatabase.cpp | 333 | ||||
| -rw-r--r-- | Week05/Exercise03/TaxDatabase.h | 80 | ||||
| -rw-r--r-- | Week05/Exercise03/TaxReport.cpp | 25 | ||||
| -rw-r--r-- | Week05/Exercise03/TaxReport.h | 29 | ||||
| -rw-r--r-- | Week05/Exercise03/test.cpp | 100 | ||||
| -rw-r--r-- | Week05/README.md | 3 |
diff --git a/Week05/Exercise01/NumSeries.cpp b/Week05/Exercise01/NumSeries.cpp new file mode 100644 index 0000000..be8c816 --- /dev/null +++ b/Week05/Exercise01/NumSeries.cpp @@ -0,0 +1,88 @@ +#include "NumSeries.h" +#include <cmath> + +void NumSeries::free() { + delete[] numbers; +} + +void NumSeries::copyFrom(const NumSeries& other) { + allocated = other.allocated; + size = other.size; + + numbers = new double[allocated]; + for (unsigned i = 0; i < size; ++i) + numbers[i] = other.numbers[i]; +} + +void NumSeries::resize() { + allocated *= 2; + + double* newNumbers = new double[allocated]; + for (unsigned i = 0; i < size; ++i) + newNumbers[i] = numbers[i]; + + delete[] numbers; + numbers = newNumbers; +} + +NumSeries::NumSeries() { + numbers = nullptr; + allocated = size = 0; +} + +NumSeries::~NumSeries() { + free(); +} + +NumSeries::NumSeries(const NumSeries& other) { + copyFrom(other); +} + +NumSeries& NumSeries::operator=(const NumSeries& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +NumSeries::NumSeries(NumSeries&& other) { + numbers = other.numbers; + allocated = other.allocated; + size = other.size; + + other.numbers = nullptr; + other.allocated = 0; + other.size = 0; +} + +NumSeries& NumSeries::operator=(NumSeries&& other) { + if (this != &other) { + free(); + + numbers = other.numbers; + allocated = other.allocated; + size = other.size; + + other.numbers = nullptr; + other.allocated = 0; + other.size = 0; + } + return *this; +} + +void NumSeries::Push(double element) { + if (size >= allocated) + resize(); + numbers[size++] = element; +} + +double NumSeries::At(unsigned index) const { + if (index >= size) + return NAN; + return numbers[index]; +} + +unsigned NumSeries::Length() const { + return size; +} diff --git a/Week05/Exercise01/NumSeries.h b/Week05/Exercise01/NumSeries.h new file mode 100644 index 0000000..b7d89a7 --- /dev/null +++ b/Week05/Exercise01/NumSeries.h @@ -0,0 +1,27 @@ +#ifndef NUMSERIES +#define NUMSERIES + +class NumSeries { + double* numbers; + unsigned allocated; + unsigned size; + + void free(); + void copyFrom(const NumSeries& other); + + void resize(); +public: + NumSeries(); + ~NumSeries(); + NumSeries(const NumSeries& other); + NumSeries& operator=(const NumSeries& other); + + NumSeries(NumSeries&& other); + NumSeries& operator=(NumSeries&& other); + + void Push(double element); + double At(unsigned index) const; + unsigned Length() const; +}; + +#endif /* NUMSERIES */ diff --git a/Week05/Exercise02/String.cpp b/Week05/Exercise02/String.cpp new file mode 100644 index 0000000..e2b082d --- /dev/null +++ b/Week05/Exercise02/String.cpp @@ -0,0 +1,103 @@ +#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); +} + +String String::Substring(unsigned startIndex, unsigned length) const { + String result; + if (startIndex >= this->length) { + return result; + } + + if (startIndex + length >= this->length) { + length = this->length - startIndex; + } + + result.length = length; + result.str = new char[length + 1]; + strncpy(result.str, str, length); + result.str[length + 1] = '\0'; + + return result; +} + +void String::Concat(const String& end) { + char* newStr = new char[length + end.length + 1]; + strncpy(newStr, str, length); + strncpy(newStr + length, end.str, end.length + 1); + + delete[] str; + str = newStr; + length += end.length; +} + +unsigned String::CountWords() const { + unsigned words = 0; + bool prevBlank = true; + + for (const char* s = str; *s != '\0'; ++s) { + if (prevBlank && *s != ' ') + ++words; + prevBlank = *s == ' '; + } + + return words; +} diff --git a/Week05/Exercise02/String.h b/Week05/Exercise02/String.h new file mode 100644 index 0000000..f47b7c8 --- /dev/null +++ b/Week05/Exercise02/String.h @@ -0,0 +1,32 @@ +#ifndef _STRING +#define _STRING + +class String { + char* str; + // Не е нужно да пазим и дължината като атрибут, + // можем винаги да си я смятаме с strlen, но + // е по-културно така + 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); + String Substring(unsigned startIndex, unsigned length) const; + void Concat(const String& end); + + /* Помощна функция */ + + unsigned CountWords() const; +}; + +#endif /* _STRING */ diff --git a/Week05/Exercise02/Text.cpp b/Week05/Exercise02/Text.cpp new file mode 100644 index 0000000..b6143c0 --- /dev/null +++ b/Week05/Exercise02/Text.cpp @@ -0,0 +1,67 @@ +#include "Text.h" + +void Text::free() { + delete[] lines; +} + +void Text::copyFrom(const Text& other) { + lineCount = other.lineCount; + + lines = new String[lineCount]; + for (unsigned i = 0; i < lineCount; ++i) + lines[i] = other.lines[i]; +} + +Text::Text() { + lines = nullptr; + lineCount = 0; +} + +Text::~Text() { + free(); +} + +Text::Text(const Text& other) { + copyFrom(other); +} + +Text& Text::operator=(const Text& other) { + if (this != &other) { + free(); + copyFrom(other); + } + return *this; +} + +Text::Text(Text&& other) { + lines = other.lines; + lineCount = other.lineCount; + + other.lines = nullptr; + other.lineCount = 0; +} + +unsigned Text::LineCount() const { + return lineCount; +} + +unsigned Text::WordCount() const { + unsigned totalCount = 0; + + for (unsigned i = 0; i < lineCount; ++i) + totalCount += lines[i].CountWords(); + + return totalCount; +} + +Text Text::SubText(unsigned startLine, unsigned startCol, unsigned endLine, unsigned endCol) const { + Text result; + result.lineCount = endLine - startLine + 1; + result.lines = new String[lineCount]; + + for (unsigned i = 0; i < result.lineCount; ++i) { + result.lines[i] = lines[i + startLine].Substring(startCol, endCol - startCol + 1); + } + + return result; +} diff --git a/Week05/Exercise02/Text.h b/Week05/Exercise02/Text.h new file mode 100644 index 0000000..a1366e0 --- /dev/null +++ b/Week05/Exercise02/Text.h @@ -0,0 +1,27 @@ +#ifndef _TEXT +#define _TEXT + +#include "String.h" + +class Text { + String* lines; + unsigned lineCount; + + void free(); + void copyFrom(const Text& other); + +public: + Text(); + ~Text(); + Text(const Text& other); + Text& operator=(const Text& other); + + Text(Text&& other); + Text& operator=(Text&& other); + + unsigned LineCount() const; + unsigned WordCount() const; + Text SubText(unsigned startLine, unsigned startCol, unsigned endLine, unsigned endCol) const; +}; + +#endif /* _TEXT */ 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; +} diff --git a/Week05/README.md b/Week05/README.md new file mode 100644 index 0000000..3124cee --- /dev/null +++ b/Week05/README.md @@ -0,0 +1,3 @@ +# Задачи + +<https://syndamia.com/teaching/oop-2025/week05/> |
