geostat/common.cpp

92 wiersze
2.6 KiB
C++
Czysty Zwykły widok Historia

#include "common.h"
#include <vector>
const int HIST_MAX = 20;
void show_histogram(const Caches& cc, std::string Cache::*ptr, std::string caption, bool html, bool sort_by_val) {
std::map<std::string, int> histogram;
std::vector<std::pair<std::string, int>> pairs;
for (auto el : cc)
histogram[el.*ptr]++;
for (auto el : histogram)
pairs.push_back(el);
if (sort_by_val)
sort(pairs.begin(), pairs.end(), [&](std::pair<std::string, int>& a, std::pair<std::string, int>& b) { return a.second > b.second; });
else
sort(pairs.begin(), pairs.end(), [&](std::pair<std::string, int>& a, std::pair<std::string, int>& b) { return a.first < b.first; });
if (html) {
int max;
if (sort_by_val)
max = pairs[0].second;
else
max = std::max_element(pairs.begin(), pairs.end(), [&](std::pair<std::string, int>& a, std::pair<std::string, int>& b) { return a.second < b.second; })->second;
int i = 0;
std::string::size_type n;
std::cout << "<h2>" << caption << "</h2>\n";
std::cout << "<dl class=\"histogram\">\n";
for (auto own : pairs) {
if (own.first.empty()) own.first = "[unknown]";
while ((n = own.first.find('&', n + 1)) != std::string::npos)
own.first.replace(n, 1, "&amp;");
if (i < HIST_MAX)
std::cout << "<dd class=\"bar\" style=\"--percent: " << 100 * own.second / max << "%;\"><span class=\"text\">" << own.first << ": " << own.second << "</span></dd>\n";
else if (i == HIST_MAX) {
std::cout << "</dl>\n";
std::cout << "<div class=\"histogram_others\">Other: " << own.first;
}
if (i > HIST_MAX)
std::cout << ", " << own.first;
i++;
}
if (i < HIST_MAX)
std::cout << "</dl>\n";
else
std::cout << "</div>\n";
} else {
std::cout << caption << '\n';
for (auto own : pairs)
std::cout << own.first << ": " << own.second << '\n';
}
}
static bool same_day(const std::tm& a, const std::tm& b) {
return (a.tm_year == b.tm_year && a.tm_mon == b.tm_mon && a.tm_mday == b.tm_mday);
}
static void next_day(std::tm& a) {
a.tm_mday++;
mktime(&a);
}
int find_streak(const std::multimap<std::time_t, const Cache*>& cc, std::tm& start) {
int max_str = 0;
int cur_str = 0;
std::tm cur_tm;
cur_tm.tm_year = 0;
std::tm cur_start_tm = cur_tm;
start = cur_tm;
for (auto i : cc) {
if (same_day(cur_tm, *std::localtime(&i.first)))
continue;
next_day(cur_tm);
if (same_day(cur_tm, *std::localtime(&i.first))) {
cur_str++;
continue;
}
if (max_str < cur_str) {
max_str = cur_str;
start = cur_start_tm;
}
cur_str = 1;
max_str = 1;
cur_tm = cur_start_tm = start = *std::localtime(&i.first);
}
return max_str;
}