From fe51d0480dbe0d435956fdbe792e1bffaea4fa5c Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Sun, 17 Oct 2021 12:39:33 +0300 Subject: [PATCH] lesson_8 --- lesson_8/lesson_1.cpp | 203 ++++++++++++++++++++++++++++++++++++++++++ lesson_8/lesson_1.hpp | 57 ++++++++++++ lesson_8/main.cpp | 15 ++++ lesson_8/tests.hpp | 133 +++++++++++++++++++++++++++ 4 files changed, 408 insertions(+) create mode 100644 lesson_8/lesson_1.cpp create mode 100644 lesson_8/lesson_1.hpp create mode 100644 lesson_8/main.cpp create mode 100644 lesson_8/tests.hpp diff --git a/lesson_8/lesson_1.cpp b/lesson_8/lesson_1.cpp new file mode 100644 index 0000000..e65dee0 --- /dev/null +++ b/lesson_8/lesson_1.cpp @@ -0,0 +1,203 @@ +/* + * lesson_1.cpp + * + * Created on: 16 окт. 2021 г. + * Author: alexander + */ + +#include "lesson_1.hpp" + +#include +#include +#include + +/**************************** + * Person * + ****************************/ + +std::optional getOptStr(std::string &s) +{ + if (s == "") + { + return std::nullopt; + } + + return s; +} + +std::ostream& operator<<(std::ostream &out, const Person &p) +{ + out << std::setw(15) << p.firstname << std::setw(12) << p.lastname; + + if (p.patronymic.has_value()) + { + out << std::setw(17) << p.patronymic.value(); + } + else + { + out << std::setw(18); + } + + return out; +} + +bool operator<(const Person &p1, const Person &p2) +{ + return tie(p1.firstname, p1.lastname, p1.patronymic) < tie(p2.firstname, p2.lastname, p2.patronymic); +} + +bool operator==(const Person &p1, const Person &p2) +{ + return tie(p1.firstname, p1.lastname, p1.patronymic) == tie(p2.firstname, p2.lastname, p2.patronymic); +} + +/********************************* + * PhoneNumber * + *********************************/ + +bool operator<(const PhoneNumber &p1, const PhoneNumber &p2) +{ + return tie(p1.country_code, p1.city_code, p1.number, p1.additional_number) < tie(p2.country_code, p2.city_code, p2.number, p2.additional_number); +} + +std::optional getOptInt(std::string &s) +{ + if (s == "") + { + return std::nullopt; + } + + return std::stoi(s); +} + +std::ostream& operator<<(std::ostream &out, const PhoneNumber &p) +{ + out << std::setw(3) << '+' << p.country_code << '(' << p.city_code << ')' << p.number; + + if (p.additional_number.has_value()) + { + out << ' ' << p.additional_number.value(); + } + + return out; +} + +/******************************* + * PhoneBook * + *******************************/ + +PhoneBook::PhoneBook(std::istream &file) +{ + if (!file) + { + std::cout << "Не удаётся открыть файл!" << std::endl; + exit(1); + } + + for (std::string line; std::getline(file, line);) + { + std::stringstream str(line); + std::vector rowData; + + for (std::string s; getline(str, s, ';');) + { + rowData.push_back(s); + } + + std::pair entry; + + for (size_t i = 0; i < rowData.size(); ++i) + { + switch (i) + { + case 0: + entry.first.firstname = rowData[i]; + break; + case 1: + entry.first.lastname = rowData[i]; + break; + case 2: + entry.first.patronymic = getOptStr(rowData[i]); + break; + case 3: + entry.second.country_code = stoi(rowData[i]); + break; + case 4: + entry.second.city_code = stoi(rowData[i]); + break; + case 5: + entry.second.number = rowData[i]; + break; + case 6: + entry.second.additional_number = getOptInt(rowData[i]); + break; + } + } + + m_data.push_back(entry); + } +} + +std::ostream& operator<<(std::ostream &out, const PhoneBook &pb) +{ + for (const auto& [first, second] : pb.m_data) + { + out << first << ' ' << second << std::endl; + } + + return out; +} + +void PhoneBook::SortByName() +{ + sort(m_data.begin(), m_data.end(), [](const std::pair &lhs, const std::pair &rhs) + { + return lhs.first < rhs.first; + }); +} + +void PhoneBook::SortByPhone() +{ + sort(m_data.begin(), m_data.end(), [](const std::pair &lhs, const std::pair &rhs) + { + return lhs.second < rhs.second; + }); +} + +std::pair> PhoneBook::GetPhoneNumber(const std::string &firstname) +{ + std::vector phoneNumbers; + int count = 0; + + for_each(m_data.begin(), m_data.end(), [&](const auto &entry) + { + if (entry.first.firstname == firstname) + { + phoneNumbers.push_back(entry.second); + ++count; + } + }); + + switch (count) + { + case 0: + return { "not found", phoneNumbers }; + case 1: + return { "", phoneNumbers }; + default: + return { "found more than 1", phoneNumbers }; + } +} + +void PhoneBook::ChangePhoneNumber(const Person &p, const PhoneNumber &pn) +{ + auto entry = find_if(m_data.begin(), m_data.end(), [&](const auto &entry) + { + return entry.first == p; + }); + + if (entry != m_data.end()) + { + entry->second = pn; + } +} diff --git a/lesson_8/lesson_1.hpp b/lesson_8/lesson_1.hpp new file mode 100644 index 0000000..44a7eb5 --- /dev/null +++ b/lesson_8/lesson_1.hpp @@ -0,0 +1,57 @@ +/* + * lesson_1.hpp + * + * Created on: 16 окт. 2021 г. + * Author: alexander + */ + +#pragma once + +/* + * main.cpp + * + * Created on: 22 сент. 2021 г. + * Author: alexander + */ +#include +#include +#include +#include +#include + +struct Person +{ + std::string firstname; + std::string lastname; + std::optional patronymic; +}; + +struct PhoneNumber +{ + int country_code; + int city_code; + std::string number; + std::optional additional_number; +}; + +class PhoneBook +{ +private: + std::vector> m_data; +public: + PhoneBook(std::istream &file); + friend std::ostream& operator<<(std::ostream &out, const PhoneBook &pb); + void SortByName(); + void SortByPhone(); + std::pair> GetPhoneNumber(const std::string &firstname); + void ChangePhoneNumber(const Person &p, const PhoneNumber &pn); +}; + +std::optional getOptStr(std::string &s); +std::ostream& operator<<(std::ostream &out, const Person &p); +bool operator<(const Person &p1, const Person &p2); +bool operator==(const Person &p1, const Person &p2); + +bool operator<(const PhoneNumber &p1, const PhoneNumber &p2); +std::optional getOptInt(std::string &s); +std::ostream& operator<<(std::ostream &out, const PhoneNumber &p); diff --git a/lesson_8/main.cpp b/lesson_8/main.cpp new file mode 100644 index 0000000..98c45e9 --- /dev/null +++ b/lesson_8/main.cpp @@ -0,0 +1,15 @@ +/* + * main.cpp + * + * Created on: 16 окт. 2021 г. + * Author: alexander + */ + +#include "lesson_1.hpp" +#include "tests.hpp" + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/lesson_8/tests.hpp b/lesson_8/tests.hpp new file mode 100644 index 0000000..f951e91 --- /dev/null +++ b/lesson_8/tests.hpp @@ -0,0 +1,133 @@ +/* + * tests.hpp + * + * Created on: 17 окт. 2021 г. + * Author: alexander + */ + +#pragma once + +#include +#include "lesson_1.hpp" + +class TestBook: public testing::Test +{ +protected: + PhoneBook *book; + + void SetUp() override + { + std::stringstream src_stream; + src_stream << "Ivanov;Daniil;Maksimovich;7;366;7508887;;\n" + << "Aleksandrov;Georgii;;493;7637;6114861;;\n" + << "Aleksandrov;Andrey;Mikhailovich;7;247;1377660;5542;\n" + << "Markelov;Dmitrii;Vadimovich;19;7576;5734416;2;\n"; + + book = new PhoneBook(src_stream); + } + + void TearDown() override + { + delete book; + } +}; + +TEST_F(TestBook, GetPhoneNumber_notFound) +{ + std::string lastname = "Egorov"; + + auto answer = book->GetPhoneNumber(lastname); + EXPECT_EQ(std::get<0>(answer), "not found"); +} + +TEST_F(TestBook, GetPhoneNumber_foundOne) +{ + std::string lastname = "Ivanov"; + + auto answer = book->GetPhoneNumber(lastname); + EXPECT_EQ(std::get<0>(answer), ""); +} + +TEST_F(TestBook, GetPhoneNumber_foundMore) +{ + std::string lastname = "Aleksandrov"; + + auto answer = book->GetPhoneNumber(lastname); + EXPECT_EQ(std::get<0>(answer), "found more than 1"); +} + +TEST_F(TestBook, GetPhoneNumber_empty) +{ + std::string lastname = ""; + + auto answer = book->GetPhoneNumber(lastname); + EXPECT_EQ(std::get<0>(answer), "not found"); +} + +TEST_F(TestBook, ChangePhoneNumber) +{ + std::string lastname = "Ivanov"; + + ASSERT_EQ(std::get<0>(book->GetPhoneNumber(lastname)).empty(), true); + + PhoneNumber answer = std::get<1>(book->GetPhoneNumber(lastname))[0]; + EXPECT_EQ(answer.number, "7508887"); + + book->ChangePhoneNumber(Person { "Ivanov", "Daniil", "Maksimovich" }, PhoneNumber { 7, 123, "15344458", std::nullopt }); + + answer = std::get<1>(book->GetPhoneNumber(lastname))[0]; + EXPECT_EQ(answer.country_code, 7); + EXPECT_EQ(answer.city_code, 123); + EXPECT_EQ(answer.number, "15344458"); + EXPECT_EQ(answer.additional_number, std::nullopt); +} + +TEST_F(TestBook, sortByName) +{ + std::stringstream src_stream; + src_stream << " Aleksandrov Andrey Mikhailovich +7(247)1377660 5542\n" + << " Aleksandrov Georgii +493(7637)6114861\n" + << " Ivanov Daniil Maksimovich +7(366)7508887\n" + << " Markelov Dmitrii Vadimovich +19(7576)5734416 2\n"; + + book->SortByName(); + + std::stringstream dst_stream; + dst_stream << *book; + + while (!dst_stream.eof()) + { + std::string str_src; + std::string str_dst; + + src_stream >> str_src ; + dst_stream >> str_dst; + + EXPECT_EQ(str_dst, str_src); + } +} + +TEST_F(TestBook, sortByPhone) +{ + std::stringstream src_stream; + src_stream << " Aleksandrov Andrey Mikhailovich +7(247)1377660 5542\n" + << " Ivanov Daniil Maksimovich +7(366)7508887\n" + << " Markelov Dmitrii Vadimovich +19(7576)5734416 2\n" + << " Aleksandrov Georgii +493(7637)6114861\n"; + + book->SortByPhone(); + + std::stringstream dst_stream; + dst_stream << *book; + + while (!dst_stream.eof()) + { + std::string str_src; + std::string str_dst; + + src_stream >> str_src ; + dst_stream >> str_dst; + + EXPECT_EQ(str_dst, str_src); + } +}