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