From b086795769ee1888f51773278c8f98caafa80f98 Mon Sep 17 00:00:00 2001 From: TupikovAA Date: Fri, 20 Jun 2025 21:39:04 +0300 Subject: [PATCH] project: last version --- histogram.cpp | 35 ++++++++++++++---------- histogram.h | 3 +- histogram.svg | 9 ++++++ histogram_internal.h | 2 +- lab1.cbp | 4 +++ lab1.depend | 33 ++++++++++++++++++++++ lab1.layout | 30 ++++++++++++++++++++ main.cpp | 23 +++++++++++++--- svg.cpp | 65 ++++++++++++++++++++++++++++++++------------ svg.h | 8 +++--- unittest.cbp | 3 ++ unittest.cpp | 52 +++++++++++++++++++++++++++++++++++ unittest.depend | 63 ++++++++++++++++++++++++++++++++++++++++++ unittest.layout | 20 ++++++++++++++ 14 files changed, 308 insertions(+), 42 deletions(-) create mode 100644 histogram.svg create mode 100644 lab1.depend create mode 100644 lab1.layout create mode 100644 unittest.cpp create mode 100644 unittest.depend create mode 100644 unittest.layout diff --git a/histogram.cpp b/histogram.cpp index dd5f5ed..e281a24 100644 --- a/histogram.cpp +++ b/histogram.cpp @@ -3,17 +3,21 @@ #include "histogram_internal.h" #include #include +#include +using namespace std; +int find_minmax(const std::vector& numbers, double& min, double& max) { + if(numbers.size()){ + min = numbers[0]; + max = numbers[0]; + } -void find_minmax(const std::vector& numbers, double& min, double& max) { - if (numbers.empty()) return; - min = numbers[0]; - max = numbers[0]; for (double num : numbers) { if (num < min) min = num; if (num > max) max = num; } + return numbers.size(); } std::vector make_histogram(const std::vector& numbers, size_t bin_count) { @@ -56,24 +60,27 @@ Input input_data() { return in; } -void show_histogram_text(const std::vector& bins, size_t max_width) { +void show_histogram_text(const vector& bins, size_t block_width) { if (bins.empty()) return; - size_t max_count = *std::max_element(bins.begin(), bins.end()); + const size_t max_count = *max_element(bins.begin(), bins.end()); if (max_count == 0) return; + + const size_t max_console_width = 60; + + + const double scale = static_cast(max_console_width) / max_count; + for (size_t count : bins) { - if (count < 100) std::cout << " "; - if (count < 10) std::cout << " "; + size_t stars = static_cast(count * scale); - std::cout << count << "|"; + if (count < 100) cout << " "; + if (count < 10) cout << " "; - size_t bar_length = (count * max_width) / max_count; - for (size_t i = 0; i < bar_length; ++i) { - std::cout << "*"; - } - std::cout << std::endl; + cout << count << "|"; + cout << string(stars, '*') << endl; } } diff --git a/histogram.h b/histogram.h index 05847f1..6fccc34 100644 --- a/histogram.h +++ b/histogram.h @@ -5,11 +5,10 @@ struct Input { std::vector numbers; - size_t bin_count{}; + size_t bin_count; size_t number_count; }; - Input input_data(); std::vector make_histogram(const std::vector& numbers, size_t bin_count); void show_histogram_text(const std::vector& bins, size_t max_width = 80); diff --git a/histogram.svg b/histogram.svg new file mode 100644 index 0000000..fe91e9f --- /dev/null +++ b/histogram.svg @@ -0,0 +1,9 @@ + + +4 + +1 + +1 + + diff --git a/histogram_internal.h b/histogram_internal.h index 4ca4ae4..23403fd 100644 --- a/histogram_internal.h +++ b/histogram_internal.h @@ -3,6 +3,6 @@ #include -void find_minmax(const std::vector& numbers, double& min, double& max); +int find_minmax(const std::vector& numbers, double& min, double& max); #endif diff --git a/lab1.cbp b/lab1.cbp index a01ffa6..bd673a5 100644 --- a/lab1.cbp +++ b/lab1.cbp @@ -32,7 +32,11 @@ + + + + diff --git a/lab1.depend b/lab1.depend new file mode 100644 index 0000000..1925996 --- /dev/null +++ b/lab1.depend @@ -0,0 +1,33 @@ +# depslib dependency file v1.0 +1750444036 source:c:\users\taa41\desktop\прога\lab1\main.cpp + + "histogram.h" + "svg.h" + + +1749173822 c:\users\taa41\desktop\прога\lab1\histogram.h + + +1750443911 source:c:\users\taa41\desktop\прога\lab1\svg.cpp + "svg.h" + + + + +1750442384 c:\users\taa41\desktop\прога\lab1\svg.h + + + + + +1750443947 source:c:\users\taa41\desktop\прога\lab1\histogram.cpp + + "histogram.h" + "histogram_internal.h" + + + + +1749200462 c:\users\taa41\desktop\прога\lab1\histogram_internal.h + + diff --git a/lab1.layout b/lab1.layout new file mode 100644 index 0000000..e471d9c --- /dev/null +++ b/lab1.layout @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/main.cpp b/main.cpp index ded870c..5353335 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,24 @@ -#include "histogram.h" #include +#include "histogram.h" +#include "svg.h" +#include +using namespace std; int main() { - auto in = input_data(); - auto bins = make_histogram(in.numbers, in.bin_count); - show_histogram_text(bins); + Input data = input_data(); + + + size_t block_width = svg::input_block_width(); + + auto bins = make_histogram(data.numbers, data.bin_count); + + + show_histogram_text(bins, block_width); + + ofstream svg_file("histogram.svg"); + svg::show_histogram_svg(svg_file, bins, block_width); + svg_file.close(); + + return 0; } diff --git a/svg.cpp b/svg.cpp index 3bd0ae0..3e843ab 100644 --- a/svg.cpp +++ b/svg.cpp @@ -1,10 +1,34 @@ #include "svg.h" #include #include +#include using namespace std; namespace svg { + size_t BLOCK_WIDTH = 10; + + size_t input_block_width() { + size_t width; + while (true) { + cout << "Введите ширину блока гистограммы (3-30px): "; + cin >> width; + + if (width < 3) { + cout << "Ширина слишком мала. Минимальное значение: 3px. Пожалуйста, повторите ввод.\n"; + } else if (width > 30) { + cout << "Ширина слишком велика. Максимальное значение: 30px. Пожалуйста, повторите ввод.\n"; + } else { + break; + } + } + return width; + } + + void set_block_width(size_t width) { + BLOCK_WIDTH = width; + } + void begin(ostream& out, double width, double height) { out << "\n"; out << "\n"; } - void show_histogram_svg(ostream& out, const vector& bins) { - begin(out, IMAGE_WIDTH, IMAGE_HEIGHT); +void show_histogram_svg(ofstream& out, const vector& bins, size_t block_width) { + begin(out, IMAGE_WIDTH, IMAGE_HEIGHT); - if (bins.empty()) { - end(out); - return; - } + if (bins.empty()) { + end(out); + return; + } + const size_t max_count = *max_element(bins.begin(), bins.end()); + if (max_count == 0) { + end(out); + return; + } - size_t max_count = *max_element(bins.begin(), bins.end()); - double scale = (max_count > 0) ? (IMAGE_WIDTH - TEXT_WIDTH) / static_cast(max_count) : 1.0; - double top = 0; - for (size_t bin : bins) { - const double bin_width = bin * scale; - text(out, TEXT_LEFT, top + TEXT_BASELINE, to_string(bin)); + const double max_svg_width = IMAGE_WIDTH - TEXT_WIDTH - 40; - string fill_color = (static_cast(top / BIN_HEIGHT) % 2 == 0) ? "#aaffaa" : "#aaaaff"; - rect(out, TEXT_WIDTH, top, bin_width, BIN_HEIGHT, "black", fill_color); + const double scale = max_svg_width / max_count; - top += BIN_HEIGHT; - } + double top = 0; + for (size_t bin : bins) { - end(out); + double width = bin * scale * (block_width / 10.0); + + text(out, TEXT_LEFT, top + TEXT_BASELINE, to_string(bin)); + rect(out, TEXT_WIDTH, top, width, BIN_HEIGHT, "black", "#aaffaa"); + + top += BIN_HEIGHT; } + + end(out); +} } diff --git a/svg.h b/svg.h index 28d0fd6..f70f8eb 100644 --- a/svg.h +++ b/svg.h @@ -4,7 +4,7 @@ #include #include #include - +#include const size_t IMAGE_WIDTH = 400; const size_t IMAGE_HEIGHT = 300; @@ -12,7 +12,6 @@ const size_t TEXT_LEFT = 20; const size_t TEXT_BASELINE = 20; const size_t TEXT_WIDTH = 50; const size_t BIN_HEIGHT = 30; -const size_t BLOCK_WIDTH = 10; namespace svg { void begin(std::ostream& out, double width, double height); @@ -20,8 +19,9 @@ namespace svg { void text(std::ostream& out, double left, double baseline, const std::string& text); void rect(std::ostream& out, double x, double y, double width, double height, const std::string& stroke = "black", const std::string& fill = "#dddddd"); - - void show_histogram_svg(std::ostream& out, const std::vector& bins); + void show_histogram_svg(std::ofstream& out, const std::vector& bins, size_t block_width); + size_t input_block_width(); + void set_block_width(size_t width); } #endif 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 new file mode 100644 index 0000000..f864898 --- /dev/null +++ b/unittest.cpp @@ -0,0 +1,52 @@ +#define DOCTEST_CONFIG_NO_MULTITHREADING +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" +#include "histogram_internal.h" + +TEST_CASE("distinct positive numbers") { + double min = 0; + double max = 0; + find_minmax({1, 2}, min, max); + CHECK(min == 1); + CHECK(max == 2); +} + +TEST_CASE("empty vector") { + double min = 0; + double max = 0; + int sz = find_minmax({}, min, max); + + CHECK(sz == 0); +} + +TEST_CASE("single element vector") { + double min = 0; + double max = 0; + find_minmax({5}, min, max); + CHECK(min == 5); + CHECK(max == 5); +} + +TEST_CASE("negative numbers") { + double min = 0; + double max = 0; + find_minmax({-3, -1, -5}, min, max); + CHECK(min == -5); + CHECK(max == -1); +} + +TEST_CASE("identical elements") { + double min = 0; + double max = 0; + find_minmax({7, 7, 7}, min, max); + CHECK(min == 7); + CHECK(max == 7); +} + +TEST_CASE("mixed positive and negative numbers") { + double min = 0; + double max = 0; + find_minmax({-2, 3, 0, -5, 4}, min, max); + CHECK(min == -5); + CHECK(max == 4); +} diff --git a/unittest.depend b/unittest.depend new file mode 100644 index 0000000..a2ab931 --- /dev/null +++ b/unittest.depend @@ -0,0 +1,63 @@ +# depslib dependency file v1.0 +1749200479 source:c:\users\taa41\desktop\прога\lab1\histogram.cpp + + "histogram.h" + "histogram_internal.h" + + + +1749173822 c:\users\taa41\desktop\прога\lab1\histogram.h + + +1749200462 c:\users\taa41\desktop\прога\lab1\histogram_internal.h + + +1749200396 source:c:\users\taa41\desktop\прога\lab1\unittest.cpp + "doctest.h" + "histogram_internal.h" + +1749168294 c:\users\taa41\desktop\прога\lab1\doctest.h + + + + + + + "doctest_fwd.h" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unittest.layout b/unittest.layout new file mode 100644 index 0000000..409f499 --- /dev/null +++ b/unittest.layout @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + +