From ccff7aed06ddfe57aff6a2785558e2c335f8cf61 Mon Sep 17 00:00:00 2001 From: "Varvara (ZeninaVA)" Date: Mon, 5 May 2025 14:30:28 +0300 Subject: [PATCH] =?UTF-8?q?code:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=86=D0=B5=D0=BD=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- histogram.cpp | 26 +++++++-- histogram.h | 2 +- histogram_internal.h | 2 +- lab1.cbp | 15 ++++++ svg.cpp | 76 +++++++++++++++++--------- svg.h | 1 - text.cpp | 123 ++++++++++++++++++++++--------------------- text.h | 1 + unittest.cbp | 3 ++ unittest.cpp | 11 ++-- unittest.depend | 56 +++++++++++++++++++- 11 files changed, 217 insertions(+), 99 deletions(-) diff --git a/histogram.cpp b/histogram.cpp index 4b8b614..2df43a2 100644 --- a/histogram.cpp +++ b/histogram.cpp @@ -1,6 +1,10 @@ #include "histogram.h" - -void find_minmax(vector vec, double& min, double& max) { +#include +bool find_minmax(vector vec, double& min, double& max) { + if (vec.size() == 0) { + cerr << "Empty vec"; + return false; + } min = vec[0]; max = vec[0]; for (double x : vec) { @@ -12,8 +16,8 @@ void find_minmax(vector vec, double& min, double& max) { max = x; } } + return true; } - vector make_histogram(size_t number, vector vec) { vector bins(number); double mn, mx; @@ -36,3 +40,19 @@ vector make_histogram(size_t number, vector vec) { } return bins; } +vector make_percentages(const vector& bins) { + size_t total = 0; + for (auto x : bins) { + total += x; + } + vector pct(bins.size()); + for (size_t i = 0; i < bins.size(); i++) { + if (total > 0) { + pct[i] = static_cast(round(100.0 * bins[i] / total)); + } + else { + pct[i] = 0; + } + } + return pct; +} diff --git a/histogram.h b/histogram.h index ecd9643..8eda100 100644 --- a/histogram.h +++ b/histogram.h @@ -4,5 +4,5 @@ #include using namespace std; vector make_histogram(size_t number, vector vec); - +vector make_percentages(const vector& bins); #endif // HISTOGRAM_H_INCLUDED diff --git a/histogram_internal.h b/histogram_internal.h index 4567891..34fdb31 100644 --- a/histogram_internal.h +++ b/histogram_internal.h @@ -1,6 +1,6 @@ #ifndef HISTOGRAM_INTERNAL_H_INCLUDED #define HISTOGRAM_INTERNAL_H_INCLUDED -void find_minmax(std::vector vec, double& min, double& max); +bool find_minmax(std::vector vec, double& min, double& max); #endif // HISTOGRAM_INTERNAL_H_INCLUDED diff --git a/lab1.cbp b/lab1.cbp index a01ffa6..2825699 100644 --- a/lab1.cbp +++ b/lab1.cbp @@ -32,7 +32,22 @@ + + + + + + + + + + + diff --git a/svg.cpp b/svg.cpp index 5f9db92..0d67261 100644 --- a/svg.cpp +++ b/svg.cpp @@ -1,5 +1,5 @@ #include "svg.h" - +#include using namespace std; void @@ -34,38 +34,62 @@ svg_rect(double x, double y, double width, double height, string stroke = "black -void -show_histogram_svg(const vector& bins) -{ - const auto IMAGE_WIDTH = 400; - const auto IMAGE_HEIGHT = 300; - const auto TEXT_LEFT = 20; + +void show_histogram_svg(const vector& bins) + { + const auto ORIG_WIDTH = 400; + const auto PADDING_RIGHT = 50; + const auto IMAGE_WIDTH = ORIG_WIDTH + PADDING_RIGHT; + const auto IMAGE_HEIGHT = 300; + const auto TEXT_LEFT = 20; const auto TEXT_BASELINE = 20; - const auto TEXT_WIDTH = 50; - const auto BIN_HEIGHT = 30; - const auto BLOCK_WIDTH = 10; - const auto GREEN = "green" - const auto RED = "red"; - const auto MAX_WIDTH = IMAGE_WIDTH - TEXT_WIDTH; + const auto TEXT_WIDTH = 50; + const auto BIN_HEIGHT = 30; + const auto BLACK = "black"; + const auto RED = "red"; + const auto MAX_WIDTH = ORIG_WIDTH - TEXT_WIDTH; + const auto PERCENT_X = TEXT_WIDTH + MAX_WIDTH + 10; + svg_begin(IMAGE_WIDTH, IMAGE_HEIGHT); - svg_begin(IMAGE_WIDTH,IMAGE_HEIGHT); + double max_count = 0; + for (auto b : bins) { + if (b > max_count) { + max_count = b; + } + } + + size_t total_count = 0; + for (auto b : bins) { + total_count += b; + } double top = 0; - double max_count = bins[0]; - for (size_t i = 0; i < bins.size(); i++) - { - if (max_count < bins[i]) - { - max_count = bins[i]; + for (auto b : bins) { + + double bin_width = 0; + if (max_count > 0) { + bin_width = MAX_WIDTH * (b / max_count); } - } - for (size_t bin : bins) - { - double bin_width = (MAX_WIDTH) * (bin/max_count); - svg_text(TEXT_LEFT, top + TEXT_BASELINE, to_string(bin)); - svg_rect(TEXT_WIDTH, top, bin_width, BIN_HEIGHT, GREEN, RED); + + svg_text(TEXT_LEFT, top + TEXT_BASELINE, to_string(b)); + + svg_rect(TEXT_WIDTH, top, bin_width, BIN_HEIGHT, BLACK, RED); + + + int pct = 0; + if (total_count > 0) { + pct = static_cast(round(100.0 * b / total_count)); + } + string pct_str = to_string(pct); + if (pct < 10) { + pct_str = "0" + pct_str; + } + pct_str += "%"; + + svg_text(PERCENT_X, top + TEXT_BASELINE, pct_str); + top += BIN_HEIGHT; } diff --git a/svg.h b/svg.h index bd721d0..979300b 100644 --- a/svg.h +++ b/svg.h @@ -1,6 +1,5 @@ #ifndef SVG_H_INCLUDED #define SVG_H_INCLUDED - #include #include #include diff --git a/text.cpp b/text.cpp index 57e803a..516cdc5 100644 --- a/text.cpp +++ b/text.cpp @@ -1,9 +1,15 @@ #include "text.h" +#include "histogram.h" +#include +#include +#include -void show_histogram(std::vector bins) { +void show_histogram(vector bins) { bool gigant = false; - auto spaces = 0; + size_t spaces = 0; size_t mx_count = 0; + + for (auto x : bins) { if (x > 76) { gigant = true; @@ -11,73 +17,68 @@ void show_histogram(std::vector bins) { if (x > mx_count) { mx_count = x; } - auto len = 0; - while (x > 0) { - x /= 10; + size_t len = 0; + size_t t = x; + do { + t /= 10; len++; - } + } while (t > 0); if (len > spaces) { spaces = len; } + } + size_t bar_max_width; + if (gigant) { + bar_max_width = 76; + } else { + bar_max_width = mx_count; } - if (spaces == 1) { - for (size_t i = 0; i < bins.size(); i++) { - std::cout << " " << bins[i] << "|"; - if (gigant) { - if (bins[i] == mx_count) { - for (size_t j = 0; j < 76; j++) { - std::cout << "*"; - } - } - else - { - for (size_t j = 0; j < 76 * static_cast(bins[i]) / mx_count; j++) { - std::cout << "*"; - } - } - } - else - { - for (size_t j = 0; j < bins[i]; j++) { - std::cout << "*"; - } - std::cout << std::endl; - } + + auto percentages = make_percentages(bins); + + for (size_t i = 0; i < bins.size(); ++i) { + + size_t len = 0; + size_t t = bins[i]; + do { + t /= 10; + len++; + } while (t > 0); + for (size_t s = len; s < spaces + 1; ++s) { + cout << " "; } - } - else - { - for (size_t i = 0; i < bins.size(); i++) { - int len = 1; - int k = bins[i]; - for (; k /= 10; ++len); - while (len < spaces) { - std::cout << " "; - len++; - } - std::cout << bins[i]; - std::cout << "|"; - if (gigant) { - if (bins[i] == mx_count) { - for (size_t j = 0; j < 76; j++) { - std::cout << "*"; - } - } - else - { - for (size_t j = 0; j < (76 * static_cast(bins[i]) / mx_count - 1); j++) { - std::cout << "*"; - } - } - } - else - { - for (size_t j = 0; j < bins[i]; j++) { - std::cout << "*"; - } + cout << bins[i] << "|"; + + + size_t star_count = 0; + if (gigant) { + if (bins[i] == mx_count) { + star_count = 76; + } else { + star_count = static_cast(76 * static_cast(bins[i]) / mx_count); } - std::cout << std::endl; + } else { + star_count = bins[i]; + } + for (size_t j = 0; j < star_count; ++j) { + cout << "*"; } + + size_t pad = bar_max_width - star_count; + for (size_t p = 0; p < pad + 2; ++p) { + cout << " "; + } + + int pct = percentages[i]; + string pct_str; + if (pct < 10) { + pct_str = "0" + to_string(pct); + } else { + pct_str = to_string(pct); + } + pct_str += "%"; + + cout << pct_str << "\n"; } } diff --git a/text.h b/text.h index 7773cb9..bd50674 100644 --- a/text.h +++ b/text.h @@ -3,6 +3,7 @@ #include #include + void show_histogram(std::vector bins); #endif // TEXT_H_INCLUDED diff --git a/unittest.cbp b/unittest.cbp index 7f9621b..534f497 100644 --- a/unittest.cbp +++ b/unittest.cbp @@ -31,6 +31,9 @@ + + + diff --git a/unittest.cpp b/unittest.cpp index 37074ec..6e346f2 100644 --- a/unittest.cpp +++ b/unittest.cpp @@ -3,6 +3,8 @@ #include "doctest.h" #include "histogram_internal.h" +using namespace std; + TEST_CASE("distinct positive numbers") { double min = 0; double max = 0; @@ -10,12 +12,13 @@ TEST_CASE("distinct positive numbers") { CHECK(min == 1); CHECK(max == 2); } -TEST_CASE("distinct negative numbers"){ + +TEST_CASE("empty vector"){ double min = 0; double max = 0; - find_minmax({-1, -2}, min, max); - CHECK(min == -2); - CHECK(max == -1); + vector empty; + bool result = find_minmax(empty, min, max); + CHECK(!result); } TEST_CASE("vector of the same elements"){ double min = 0; diff --git a/unittest.depend b/unittest.depend index 4bddb1d..74bc9d4 100644 --- a/unittest.depend +++ b/unittest.depend @@ -1,8 +1,60 @@ # depslib dependency file v1.0 -1746270053 source:c:\users\professional\desktop\cs-lab34\lab1\histogram.cpp +1746444035 source:c:\users\professional\desktop\cs-lab34\lab1\histogram.cpp "histogram.h" + -1746269334 c:\users\professional\desktop\cs-lab34\lab1\histogram.h +1746443248 c:\users\professional\desktop\cs-lab34\lab1\histogram.h +1746274690 source:c:\users\professional\desktop\cs-lab34\lab1\unittest.cpp + "doctest.h" + "histogram_internal.h" + +1746271199 c:\users\professional\desktop\cs-lab34\lab1\doctest.h + + + + + + + "doctest_fwd.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1746444163 c:\users\professional\desktop\cs-lab34\lab1\histogram_internal.h +