Advertisement
kutuzzzov

Урок 7 Практические рекомендации

Mar 7th, 2023
1,143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.66 KB | None | 0 0
  1. // main.cpp
  2. #include "libstat.h"
  3.  
  4. #include <iostream>
  5. using namespace std;
  6.  
  7. int main() {
  8.     statistics::tests::AggregSum();
  9.     statistics::tests::AggregMax();
  10.     statistics::tests::AggregMean();
  11.     statistics::tests::AggregStandardDeviation();
  12.     statistics::tests::AggregMode();
  13.     statistics::tests::AggregPrinter();
  14.  
  15.     cout << "Test passed!"sv << endl;
  16. }
  17.  
  18. // libstat.h
  19. #pragma once
  20. #include <algorithm>
  21. #include <cmath>
  22. #include <iostream>
  23. #include <optional>
  24. #include <string>
  25. #include <string_view>
  26. #include <unordered_map>
  27.  
  28. using namespace std::literals;
  29. namespace statistics {
  30. namespace aggregations {
  31.    
  32. class Sum { // сумма
  33. public:
  34.     void PutValue(double value);
  35.     std::optional<double> Get() const;
  36.  
  37.     static std::string_view GetValueName() {
  38.         return "sum"sv;
  39.     }
  40.  
  41. private:
  42.     double sum_ = 0;
  43. };
  44.  
  45. class Max { // максимум
  46. public:
  47.     void PutValue(double value);
  48.     std::optional<double> Get() const;
  49.  
  50.     static std::string_view GetValueName() {
  51.         return "max"sv;
  52.     }
  53.  
  54. private:
  55.     std::optional<double> cur_max_;
  56. };
  57.  
  58. class Mean { // среднее арифметическое
  59. public:
  60.     void PutValue(double value);
  61.     std::optional<double> Get() const;
  62.  
  63.     static std::string_view GetValueName() {
  64.         return "mean"sv;
  65.     }
  66.  
  67. private:
  68.     aggregations::Sum sum_;
  69.     size_t count_ = 0;
  70. };
  71.  
  72. class StandardDeviation { // стандартное отклонение
  73. public:
  74.     void PutValue(double value);
  75.     std::optional<double> Get() const;
  76.  
  77.     static std::string_view GetValueName() {
  78.         return "standard deviation"sv;
  79.     }
  80.  
  81. private:
  82.     aggregations::Sum sum_;
  83.     aggregations::Sum sum_sq_;
  84.     size_t count_ = 0;
  85. };
  86.  
  87. class Mode { // мода
  88. public:
  89.     void PutValue(double value);
  90.     std::optional<double> Get() const;
  91.  
  92.     static std::string_view GetValueName() {
  93.         return "mode"sv;
  94.     }
  95.  
  96. private:
  97.     std::unordered_map<double, size_t> counts_;
  98.     std::optional<double> cur_max_;
  99.     size_t cur_count_ = 0;
  100. };
  101.  
  102. } // конец namespace statistics::aggregations
  103.  
  104. namespace tests {
  105.    
  106. void AggregSum();
  107. void AggregMax();
  108. void AggregMean();
  109. void AggregStandardDeviation();
  110. void AggregMode();
  111. void AggregPrinter();
  112.    
  113. } // конец namespace tests
  114.  
  115. template <typename Aggreg>
  116. class AggregPrinter {
  117. public:
  118.     void PutValue(double value) {
  119.         inner_.PutValue(value);
  120.     }
  121.  
  122.     void Print(std::ostream& out) const {
  123.         auto val = inner_.Get();
  124.         out << inner_.GetValueName() << " is "sv;
  125.         if (val) {
  126.             out << *val;
  127.         } else {
  128.             out << "undefined"sv;
  129.         }
  130.         out << std::endl;
  131.     }
  132.  
  133. private:
  134.     Aggreg inner_;
  135. };
  136.    
  137. } // конец namespace statistics
  138.  
  139. // libstat.cpp
  140. #include "libstat.h"
  141.  
  142. void statistics::aggregations::Sum::PutValue(double value) {
  143.     sum_ += value;
  144. }
  145.  
  146. std::optional<double> statistics::aggregations::Sum::Get() const {
  147.     return sum_;
  148. }
  149.  
  150. void statistics::aggregations::Max::PutValue(double value) {
  151.     cur_max_ = std::max(value, cur_max_.value_or(value));
  152. }
  153.  
  154. std::optional<double> statistics::aggregations::Max::Get() const {
  155.     return cur_max_;
  156. }
  157.  
  158. void statistics::aggregations::Mean::PutValue(double value) {
  159.     sum_.PutValue(value);
  160.     ++count_;
  161. }
  162.  
  163. std::optional<double> statistics::aggregations::Mean::Get() const {
  164.     auto val = sum_.Get();
  165.     if (!val || count_ == 0) {
  166.         return std::nullopt;
  167.     }
  168.  
  169.     return *val / count_;
  170. }
  171.  
  172. void statistics::aggregations::StandardDeviation::PutValue(double value) {
  173.     sum_.PutValue(value);
  174.     sum_sq_.PutValue(value * value);
  175.     ++count_;
  176. }
  177.  
  178. std::optional<double> statistics::aggregations::StandardDeviation::Get() const {
  179.     auto val = sum_.Get();
  180.     auto val2 = sum_sq_.Get();
  181.  
  182.     if (!val || !val2 || count_ < 2) {
  183.         return std::nullopt;
  184.     }
  185.  
  186.     return ::std::sqrt((*val2 - *val * *val / count_) / count_);
  187. }
  188.  
  189. void statistics::aggregations::Mode::PutValue(double value) {
  190.     const size_t new_count = ++counts_[round(value)];
  191.  
  192.     if (new_count > cur_count_) {
  193.         cur_max_ = value;
  194.         cur_count_ = new_count;
  195.     }
  196. }
  197.  
  198. std::optional<double> statistics::aggregations::Mode::Get() const {
  199.     return cur_max_;
  200. }
  201.  
  202. // libstat_test.cpp
  203. #include "libstat.h"
  204.  
  205. #include <cassert>
  206. #include <cmath>
  207. #include <sstream>
  208.  
  209. namespace statistics::tests::detail {
  210.    
  211. template <typename T>
  212. std::string GetPrinterValue(statistics::AggregPrinter<T>& printer) {
  213.     std::ostringstream out;
  214.     printer.Print(out);
  215.  
  216.     return std::move(out).str();
  217. }
  218.    
  219. }  // конец namespace detail
  220.  
  221. void statistics::tests::AggregSum() {
  222.     statistics::aggregations::Sum aggreg;
  223.     assert(*aggreg.Get() == 0);
  224.  
  225.     aggreg.PutValue(10.);
  226.     aggreg.PutValue(20.);
  227.     aggreg.PutValue(-40.);
  228.  
  229.     assert(*aggreg.Get() == -10.);
  230. }
  231.  
  232. void statistics::tests::AggregMax() {
  233.     statistics::aggregations::Max aggreg;
  234.     assert(!aggreg.Get());
  235.  
  236.     aggreg.PutValue(10.);
  237.     aggreg.PutValue(20.);
  238.     aggreg.PutValue(-40.);
  239.  
  240.     assert(*aggreg.Get() == 20.);
  241. }
  242.  
  243. void statistics::tests::AggregMean() {
  244.     statistics::aggregations::Mean aggreg;
  245.     assert(!aggreg.Get());
  246.  
  247.     aggreg.PutValue(10.);
  248.     aggreg.PutValue(20.);
  249.     aggreg.PutValue(-40.);
  250.     aggreg.PutValue(30.);
  251.  
  252.     assert(*aggreg.Get() == 5.);
  253. }
  254.  
  255. void statistics::tests::AggregStandardDeviation() {
  256.     statistics::aggregations::StandardDeviation aggreg;
  257.     assert(!aggreg.Get());
  258.  
  259.     aggreg.PutValue(10.);
  260.     aggreg.PutValue(10.);
  261.     aggreg.PutValue(10.);
  262.     aggreg.PutValue(10.);
  263.  
  264.     assert(std::abs(*aggreg.Get()) < 1e-5);
  265.  
  266.     aggreg.PutValue(20.);
  267.     aggreg.PutValue(20.);
  268.     aggreg.PutValue(20.);
  269.     aggreg.PutValue(20.);
  270.  
  271.     assert(std::abs(*aggreg.Get() - 5.) < 1e-5);
  272. }
  273.  
  274. void statistics::tests::AggregMode() {
  275.     statistics::aggregations::Mode aggreg;
  276.     assert(!aggreg.Get());
  277.  
  278.     aggreg.PutValue(1.1);
  279.     aggreg.PutValue(0.9);
  280.     aggreg.PutValue(2.1);
  281.     aggreg.PutValue(2.2);
  282.     aggreg.PutValue(2.1);
  283.     aggreg.PutValue(-1.0);
  284.     aggreg.PutValue(3.0);
  285.     aggreg.PutValue(3.0);
  286.     aggreg.PutValue(1000.);
  287.  
  288.     assert(std::round(*aggreg.Get()) == 2.);
  289. }
  290.  
  291. void statistics::tests::AggregPrinter() {
  292.     statistics::AggregPrinter<statistics::aggregations::Max> printer;
  293.  
  294.     assert(statistics::tests::detail::GetPrinterValue(printer) == "max is undefined\n"s);
  295.     printer.PutValue(10.);
  296.     printer.PutValue(20.);
  297.     printer.PutValue(-40.);
  298.  
  299.     std::ostringstream out;
  300.     out << 20.;
  301.  
  302.     assert(statistics::tests::detail::GetPrinterValue(printer) == "max is "s + out.str() + "\n"s);
  303. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement