-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.cpp
More file actions
136 lines (118 loc) · 3.71 KB
/
Copy pathmain.cpp
File metadata and controls
136 lines (118 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <sstream>
#define DEFAULT_VALID_GAP 500
class SensorInfo{
std::string name;
int count;
double minValue;
double maxValue;
double meanValue;
int totalGaps;
int lastTimestamp;
public:
SensorInfo(std::string name)
: name(name), count(0), minValue(0), maxValue(0), meanValue(0), totalGaps(0), lastTimestamp(0) {}
void update(int timestamp, double value, int validGap) {
if (count == 0) {
minValue = value;
maxValue = value;
meanValue = value;
} else {
if (value < minValue) minValue = value;
if (value > maxValue) maxValue = value;
meanValue = (meanValue * count + value) / (count + 1);
}
count++;
if (lastTimestamp != 0 && timestamp - lastTimestamp > validGap) {
totalGaps++;
}
lastTimestamp = timestamp;
}
void print() const {
std::cout << "Sensor: " << name
<< " | count: " << count
<< " | min: " << minValue
<< " | max: " << maxValue
<< " | mean: " << meanValue
<< " | gaps: " << totalGaps
<< std::endl;
}
};
class Record{
public:
int timestamp;
std::string sensorName;
double value;
bool isValid;
Record(std::string line) {
isValid = false;
std::istringstream iss(line);
std::vector<std::string> tokens;
std::string word;
while (iss >> word) tokens.push_back(word);
if (tokens.size() != 3) return;
try {
// TODO: add validtation for range, type, continuous
timestamp = std::stoi(tokens.at(0));
sensorName = tokens.at(1);
value = std::stod(tokens.at(2));
} catch (const std::exception&) {
return;
}
isValid = true;
}
};
int main(int argc, char* argv[]) {
// Args verification
if (argc < 2) {
std::cerr << "Missing filename" << std::endl;
return 1;
}
int validGap = DEFAULT_VALID_GAP;
if (argc > 2) {
try {
validGap = std::stoi(argv[2]);
} catch (const std::exception&) {
std::cerr << "Error: gap threshold must be an integer" << std::endl;
return 1;
}
if (validGap <= 0) {
std::cerr << "Error: gap threshold must be a positive integer" << std::endl;
return 1;
}
}
std::string filename = argv[1];
int malformed = 0;
std::unordered_map<std::string, SensorInfo> sensorsMap;
std::ifstream file(filename); //TODO: verify that the file is exist, if not create one?
if (!file.is_open()) {
std::cerr << "Error: could not open file '" << filename << "'" << std::endl;
return 1;
}
// Logic
std::string line;
while (std::getline(file, line)) {
Record record(line);
if (record.isValid) {
std::string sensorName = record.sensorName;
if (sensorsMap.find(sensorName) == sensorsMap.end()) {
sensorsMap.emplace(sensorName, SensorInfo(sensorName));
}
sensorsMap.at(sensorName).update(record.timestamp, record.value, validGap);
} else {
// TODO: log the malformed lines
malformed++;
}
}
file.close();
// Report
std::cout << "Malformed records: " << malformed << std::endl;
std::cout << "--- Sensor data ---" << std::endl;
for (const auto& entry : sensorsMap) {
entry.second.print();
}
return 0;
}