From 5f59b23ca1b79f85300806a9eaf83fa89ac37567 Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Fri, 27 Jul 2018 16:03:13 -0400 Subject: [PATCH 01/16] templated so it can accept varying int types. enhanced time output, added ETA to completion and ticks/second to output line --- ProgressBar.hpp | 119 ++++++++++++++++++++++++++++++++++++++++++------ main.cpp | 2 +- 2 files changed, 106 insertions(+), 15 deletions(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index b2a12f2..b9e17a0 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -3,43 +3,134 @@ #include #include +#include +#include +#include +template < typename IntType> class ProgressBar { private: - unsigned int ticks = 0; - - const unsigned int total_ticks; - const unsigned int bar_width; + IntType max_limit; + IntType ticks = 0; + const IntType total_ticks; + const IntType bar_width; const char complete_char = '='; const char incomplete_char = ' '; const std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); + static void output_time(double seconds){ + std::size_t s_in_h(60 * 60), s_in_m(60), m_in_h(60); + + IntType hours_rem = seconds / s_in_h; + + IntType minutes_rem = ( seconds - ( hours_rem * s_in_h) ) / s_in_m ; + + IntType seconds_rem = seconds - ( (hours_rem * s_in_h) + (minutes_rem * s_in_m)); + + std::ios init(nullptr), time_fmt(nullptr); + init.copyfmt(std::cout); + std::cout<< std::setfill('0') << std::setw(2); + time_fmt.copyfmt(std::cout); + //hours + std::cout.copyfmt(time_fmt); + std::cout << hours_rem; + std::cout.copyfmt(init); + //minutes + std::cout << ":"; + std::cout.copyfmt(time_fmt); + std::cout << minutes_rem; + std::cout.copyfmt(init); + //seconds + std::cout <<":"; + std::cout.copyfmt(time_fmt); + std::cout << seconds_rem; + //restore format + std::cout.copyfmt(init); + } + public: - ProgressBar(unsigned int total, unsigned int width, char complete, char incomplete) : - total_ticks {total}, bar_width {width}, complete_char {complete}, incomplete_char {incomplete} {} + ProgressBar(IntType total, IntType width, char complete, char incomplete) : + max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width}, complete_char {complete}, incomplete_char {incomplete} {} - ProgressBar(unsigned int total, unsigned int width) : total_ticks {total}, bar_width {width} {} + ProgressBar(IntType total, IntType width) : max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width} {} - unsigned int operator++() { return ++ticks; } + ProgressBar & operator++() { + if(ticks != max_limit){ + ++ticks; + } + return *this; + } + + const ProgressBar operator++(int){ + ProgressBar tmp = *this; + ++(*this); + return tmp; + } + + ProgressBar & operator--(){ + if(ticks != 0) { + --ticks; + } + return *this; + } + + const ProgressBar operator--(int){ + ProgressBar tmp = *this; + --(*this); + return tmp; + } + + template < typename NumberType > + void add_progress( NumberType prog){ + if( prog < 0){ remove_progress(-prog);}; + IntType dist_from_limit = max_limit - ticks; + if( prog <= dist_from_limit ){ + ticks = ticks + prog; + } else { + ticks = max_limit; + } + } + template < typename NumberType > + void remove_progress( NumberType prog){ + if( prog < 0){ add_progress(-prog);}; + IntType dist_from_limit = ticks - 0; + if( prog <= dist_from_limit ){ + ticks = ticks - prog; + } else { + ticks = 0; + } + } void display() const { - float progress = (float) ticks / total_ticks; - int pos = (int) (bar_width * progress); + double progress = (double) ticks / total_ticks; + IntType pos = (IntType) (bar_width * progress); std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); auto time_elapsed = std::chrono::duration_cast(now-start_time).count(); std::cout << "["; - for (int i = 0; i < bar_width; ++i) { + for (IntType i = 0; i < bar_width; ++i) { if (i < pos) std::cout << complete_char; else if (i == pos) std::cout << ">"; else std::cout << incomplete_char; } - std::cout << "] " << int(progress * 100.0) << "% " - << float(time_elapsed) / 1000.0 << "s\r"; - std::cout.flush(); + double seconds = static_cast(time_elapsed) / 1000.0; + double ticks_per_second = ticks / seconds; + double total_seconds_rem = static_cast(total_ticks-ticks) / ticks_per_second; + + std::cout << "] " << static_cast(progress * 100.0) << "% "; + + ProgressBar::output_time(seconds); + + std::cout<<" {"; + ProgressBar::output_time(total_seconds_rem); + std::cout <<" remaining}"; + + std::cout<<" (" << ticks_per_second << " t/s)"; + + std::cout<<"\r"< progressBar(total, 70, '#', '-'); for (int i = 0; i < total; i++) { ++progressBar; // record the tick From 196cc2386b74f6d58a91f7f0267802d11de737e4 Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Fri, 27 Jul 2018 17:58:49 -0400 Subject: [PATCH 02/16] needed to cast this to an integer --- ProgressBar.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index b9e17a0..498bbdb 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -128,7 +128,7 @@ class ProgressBar { ProgressBar::output_time(total_seconds_rem); std::cout <<" remaining}"; - std::cout<<" (" << ticks_per_second << " t/s)"; + std::cout<<" (" << static_cast(ticks_per_second) << " t/s)"; std::cout<<"\r"< Date: Fri, 27 Jul 2018 18:02:48 -0400 Subject: [PATCH 03/16] might need to cast this --- ProgressBar.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 498bbdb..128c586 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -117,7 +117,7 @@ class ProgressBar { else std::cout << incomplete_char; } double seconds = static_cast(time_elapsed) / 1000.0; - double ticks_per_second = ticks / seconds; + double ticks_per_second = static_cast(ticks) / seconds; double total_seconds_rem = static_cast(total_ticks-ticks) / ticks_per_second; std::cout << "] " << static_cast(progress * 100.0) << "% "; From 1a2d3490179c6313c77255a2edbb427a136a67d6 Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Fri, 27 Jul 2018 18:09:31 -0400 Subject: [PATCH 04/16] cleaning up the code a bit and trying a different way of doing things. --- ProgressBar.hpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 128c586..b90b3ac 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -103,12 +103,17 @@ class ProgressBar { void display() const { - double progress = (double) ticks / total_ticks; + double progress = static_cast(ticks) / static_cast(total_ticks); IntType pos = (IntType) (bar_width * progress); std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); auto time_elapsed = std::chrono::duration_cast(now-start_time).count(); + double seconds = static_cast(time_elapsed) / 1000.0; + double ticks_per_second = static_cast(ticks) / seconds; + double remaining_ticks = total_ticks - ticks; + double total_seconds_rem = remaining_ticks / ticks_per_second; + std::cout << "["; for (IntType i = 0; i < bar_width; ++i) { @@ -116,12 +121,12 @@ class ProgressBar { else if (i == pos) std::cout << ">"; else std::cout << incomplete_char; } - double seconds = static_cast(time_elapsed) / 1000.0; - double ticks_per_second = static_cast(ticks) / seconds; - double total_seconds_rem = static_cast(total_ticks-ticks) / ticks_per_second; + std::cout << "] " << static_cast(progress * 100.0) << "% "; + std::cout << ticks << " / " << total_ticks << " ticks "; + ProgressBar::output_time(seconds); std::cout<<" {"; From e7b43c4da75cfecfc6f7ec11db3a24a234a58160 Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Fri, 27 Jul 2018 18:20:55 -0400 Subject: [PATCH 05/16] force whitespace clearing --- ProgressBar.hpp | 69 ++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 30 deletions(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index b90b3ac..70578fd 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -6,6 +6,7 @@ #include #include #include +#include template < typename IntType> class ProgressBar { @@ -14,11 +15,12 @@ class ProgressBar { IntType ticks = 0; const IntType total_ticks; const IntType bar_width; + const IntType console_width; const char complete_char = '='; const char incomplete_char = ' '; const std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); - static void output_time(double seconds){ + static void output_time(std::stringstream & ss, double seconds){ std::size_t s_in_h(60 * 60), s_in_m(60), m_in_h(60); IntType hours_rem = seconds / s_in_h; @@ -28,31 +30,31 @@ class ProgressBar { IntType seconds_rem = seconds - ( (hours_rem * s_in_h) + (minutes_rem * s_in_m)); std::ios init(nullptr), time_fmt(nullptr); - init.copyfmt(std::cout); - std::cout<< std::setfill('0') << std::setw(2); - time_fmt.copyfmt(std::cout); + init.copyfmt(ss); + ss<< std::setfill('0') << std::setw(2); + time_fmt.copyfmt(ss); //hours - std::cout.copyfmt(time_fmt); - std::cout << hours_rem; - std::cout.copyfmt(init); + ss.copyfmt(time_fmt); + ss << hours_rem; + ss.copyfmt(init); //minutes - std::cout << ":"; - std::cout.copyfmt(time_fmt); - std::cout << minutes_rem; - std::cout.copyfmt(init); + ss << ":"; + ss.copyfmt(time_fmt); + ss << minutes_rem; + ss.copyfmt(init); //seconds - std::cout <<":"; - std::cout.copyfmt(time_fmt); - std::cout << seconds_rem; + ss <<":"; + ss.copyfmt(time_fmt); + ss << seconds_rem; //restore format - std::cout.copyfmt(init); + ss.copyfmt(init); } public: - ProgressBar(IntType total, IntType width, char complete, char incomplete) : - max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width}, complete_char {complete}, incomplete_char {incomplete} {} + ProgressBar(IntType total, IntType width, char complete, char incomplete, IntType console_width=80) : + max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width}, console_width(console_width), complete_char {complete}, incomplete_char {incomplete} {} - ProgressBar(IntType total, IntType width) : max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width} {} + ProgressBar(IntType total, IntType width, IntType console_width=80) : max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width}, console_width(console_width) {} ProgressBar & operator++() { if(ticks != max_limit){ @@ -114,28 +116,35 @@ class ProgressBar { double remaining_ticks = total_ticks - ticks; double total_seconds_rem = remaining_ticks / ticks_per_second; - std::cout << "["; + std::stringstream ss; + + ss << "["; for (IntType i = 0; i < bar_width; ++i) { - if (i < pos) std::cout << complete_char; - else if (i == pos) std::cout << ">"; - else std::cout << incomplete_char; + if (i < pos) ss << complete_char; + else if (i == pos) ss << ">"; + else ss << incomplete_char; } - std::cout << "] " << static_cast(progress * 100.0) << "% "; - std::cout << ticks << " / " << total_ticks << " ticks "; + ss << "] " << static_cast(progress * 100.0) << "% "; + + ss << ticks << " / " << total_ticks << " ticks "; + + ProgressBar::output_time(ss, seconds); + + ss<<" {"; - ProgressBar::output_time(seconds); + ProgressBar::output_time(ss, total_seconds_rem); - std::cout<<" {"; - ProgressBar::output_time(total_seconds_rem); - std::cout <<" remaining}"; + ss <<" remaining}"; - std::cout<<" (" << static_cast(ticks_per_second) << " t/s)"; + ss<<" (" << static_cast(ticks_per_second) << " t/s)"; - std::cout<<"\r"< Date: Fri, 27 Jul 2018 18:26:10 -0400 Subject: [PATCH 06/16] erases line --- ProgressBar.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 70578fd..4d2601c 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -144,7 +144,7 @@ class ProgressBar { while(ss.str().size() < bar_width) ss<<" "; - std::cout<< ss.str() <<"\r"< Date: Fri, 27 Jul 2018 18:33:18 -0400 Subject: [PATCH 07/16] escape sequences were wrong --- ProgressBar.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 4d2601c..f0c2f3d 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -142,9 +142,7 @@ class ProgressBar { ss<<" (" << static_cast(ticks_per_second) << " t/s)"; - while(ss.str().size() < bar_width) - ss<<" "; - std::cout<< ss.str() <<"\\33[2K\r"< Date: Fri, 27 Jul 2018 18:42:24 -0400 Subject: [PATCH 08/16] the order was wrong --- ProgressBar.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index f0c2f3d..4816850 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -142,7 +142,7 @@ class ProgressBar { ss<<" (" << static_cast(ticks_per_second) << " t/s)"; - std::cout<< ss.str() <<"\033[2K\r"< Date: Fri, 27 Jul 2018 18:53:07 -0400 Subject: [PATCH 09/16] this wasn't needed as that method didn't work. --- ProgressBar.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 4816850..a1dfaca 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -15,7 +15,6 @@ class ProgressBar { IntType ticks = 0; const IntType total_ticks; const IntType bar_width; - const IntType console_width; const char complete_char = '='; const char incomplete_char = ' '; const std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); @@ -52,9 +51,9 @@ class ProgressBar { public: ProgressBar(IntType total, IntType width, char complete, char incomplete, IntType console_width=80) : - max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width}, console_width(console_width), complete_char {complete}, incomplete_char {incomplete} {} + max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width}, complete_char {complete}, incomplete_char {incomplete} {} - ProgressBar(IntType total, IntType width, IntType console_width=80) : max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width}, console_width(console_width) {} + ProgressBar(IntType total, IntType width, IntType console_width=80) : max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width} {} ProgressBar & operator++() { if(ticks != max_limit){ From 704eec52d401c8416118a0c891adcd4a6bb616ca Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Fri, 27 Jul 2018 18:53:41 -0400 Subject: [PATCH 10/16] this wasn't needed as that method didn't work. --- ProgressBar.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index a1dfaca..7aa339c 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -50,10 +50,10 @@ class ProgressBar { } public: - ProgressBar(IntType total, IntType width, char complete, char incomplete, IntType console_width=80) : + ProgressBar(IntType total, IntType width, char complete, char incomplete) : max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width}, complete_char {complete}, incomplete_char {incomplete} {} - ProgressBar(IntType total, IntType width, IntType console_width=80) : max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width} {} + ProgressBar(IntType total, IntType width) : max_limit(std::numeric_limits().max()), total_ticks {total}, bar_width {width} {} ProgressBar & operator++() { if(ticks != max_limit){ From 16497f082ef0d4bf3dab3c6c67910083708d4aa2 Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Fri, 27 Jul 2018 19:54:41 -0400 Subject: [PATCH 11/16] flush the erasure first --- ProgressBar.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 7aa339c..a40d67c 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -141,7 +141,8 @@ class ProgressBar { ss<<" (" << static_cast(ticks_per_second) << " t/s)"; - std::cout<< "\033[2K\r"<< ss.str() < Date: Fri, 27 Jul 2018 20:26:48 -0400 Subject: [PATCH 12/16] put the code into the stringstream --- ProgressBar.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index a40d67c..4967767 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -116,7 +116,7 @@ class ProgressBar { double total_seconds_rem = remaining_ticks / ticks_per_second; std::stringstream ss; - + ss << "\033[2K" << "\r"; ss << "["; for (IntType i = 0; i < bar_width; ++i) { @@ -141,8 +141,7 @@ class ProgressBar { ss<<" (" << static_cast(ticks_per_second) << " t/s)"; - std::cout<< "\033[2K"< Date: Sat, 28 Jul 2018 03:28:55 -0400 Subject: [PATCH 13/16] reset function --- ProgressBar.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 4967767..5048ba0 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -149,6 +149,11 @@ class ProgressBar { display(); std::cout << std::endl; } + + void reset() { + start_time = std::chrono::steady_clock::now(); + ticks = 0; + } }; #endif //PROGRESSBAR_PROGRESSBAR_HPP From 9b9511168c89492e2c06aa6ad1593e90523e1126 Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Sat, 28 Jul 2018 03:34:40 -0400 Subject: [PATCH 14/16] can't be reset if its const --- ProgressBar.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 5048ba0..2451240 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -17,7 +17,7 @@ class ProgressBar { const IntType bar_width; const char complete_char = '='; const char incomplete_char = ' '; - const std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); static void output_time(std::stringstream & ss, double seconds){ std::size_t s_in_h(60 * 60), s_in_m(60), m_in_h(60); From 0d64f24d32aecaf8a3d317cdd4b292adde5bd3d3 Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Wed, 1 Aug 2018 21:17:21 -0400 Subject: [PATCH 15/16] unused variable --- ProgressBar.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 2451240..76b04ac 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -20,7 +20,7 @@ class ProgressBar { std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); static void output_time(std::stringstream & ss, double seconds){ - std::size_t s_in_h(60 * 60), s_in_m(60), m_in_h(60); + std::size_t s_in_h(60 * 60), s_in_m(60)/*, m_in_h(60)*/; IntType hours_rem = seconds / s_in_h; From 8cff7795d3c68643f1c15cf1825f16f8bb7620a6 Mon Sep 17 00:00:00 2001 From: Michael Gooch Date: Tue, 16 Jul 2019 11:56:57 -0400 Subject: [PATCH 16/16] fix for slow start up and inf / undef rate/time printing huge numbers --- ProgressBar.hpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ProgressBar.hpp b/ProgressBar.hpp index 76b04ac..5dabf3c 100644 --- a/ProgressBar.hpp +++ b/ProgressBar.hpp @@ -84,6 +84,9 @@ class ProgressBar { template < typename NumberType > void add_progress( NumberType prog){ if( prog < 0){ remove_progress(-prog);}; + if(ticks==0){ + reset();//try to reduce impact of any setup/allocation on ticks/sec + } IntType dist_from_limit = max_limit - ticks; if( prog <= dist_from_limit ){ ticks = ticks + prog; @@ -94,6 +97,9 @@ class ProgressBar { template < typename NumberType > void remove_progress( NumberType prog){ if( prog < 0){ add_progress(-prog);}; + if(ticks==0){ + reset();//try to reduce impact of any setup/allocation on ticks/sec + } IntType dist_from_limit = ticks - 0; if( prog <= dist_from_limit ){ ticks = ticks - prog; @@ -134,12 +140,15 @@ class ProgressBar { ProgressBar::output_time(ss, seconds); ss<<" {"; - - ProgressBar::output_time(ss, total_seconds_rem); + if(ticks) { + ProgressBar::output_time(ss, total_seconds_rem); + } else { + ss << "??:??:??"; + } ss <<" remaining}"; - ss<<" (" << static_cast(ticks_per_second) << " t/s)"; + ss<<" (" << static_cast(ticks ? ticks_per_second : 0.0) << " t/s)"; std::cout<< ss.str() << std::flush; }