View difference between Paste ID: bM866tqM and YCY3kQcw
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
}