From 16c02cd51babf93e694abdbdc28db710971dd85f Mon Sep 17 00:00:00 2001 From: Carlchristian Eckert Date: Sat, 19 Apr 2014 19:21:59 +0200 Subject: [PATCH] Behold, there be documentations - also, minor code changes --- examples/progressbar_example.cc | 34 +++++++++---- .../elegantProgressbars/fancyProgressbar.hpp | 33 +++++++++--- .../fancyProgressbar_legacy.hpp | 34 ++++++++++++- include/elegantProgressbars/printPattern.hpp | 17 +++++-- .../elegantProgressbars/printPercentage.hpp | 18 ++++++- include/elegantProgressbars/printTime.hpp | 51 ++++++++++++++----- .../elegantProgressbars/printTime_legacy.hpp | 11 ++++ 7 files changed, 161 insertions(+), 37 deletions(-) diff --git a/examples/progressbar_example.cc b/examples/progressbar_example.cc index ee30525..2078888 100644 --- a/examples/progressbar_example.cc +++ b/examples/progressbar_example.cc @@ -2,27 +2,39 @@ #include "elegantProgressbars/fancyProgressbar_legacy.hpp" #include -int main(){ +//just some workload -> don' use optimizations, if you want that to work +void workload(){ + for(int j=0; j<2000000; ++j){ + int g = j; + if (g) + ; + } +} + +int main(){ static int const nElements = 1000; + //this one is the progressbar without C++11 features (std::chrono, most notably) for(int i=0; i(nElements); - for(int j=0; j<2000000; ++j){ - int g = i*j; - if (g) - ; - } + } + + std::cerr << "\n"; + + //the template argument is for displaying milliseconds and can be omitted (defaults to false) + for(int i=0; i(nElements); } return 0; diff --git a/include/elegantProgressbars/fancyProgressbar.hpp b/include/elegantProgressbars/fancyProgressbar.hpp index ce0d133..1afc877 100644 --- a/include/elegantProgressbars/fancyProgressbar.hpp +++ b/include/elegantProgressbars/fancyProgressbar.hpp @@ -10,8 +10,30 @@ namespace ElegantProgressbars{ - -template +/** + * Writes a fancy progressbar with minimal input + * + * Takes the total number of elements to process and creates a nice progressbar + * from that. This is intended to be called in a loop / recursion / MPI thread + * / pthread / etc. It should be called each time one of the nTotal elements is + * done processing. + * Operation can be fine-tuned to write time with high precision and different + * length of the progressbar through template arguments. + * + * @param nTotal the total number of elements to process. If multiple values + * are supplied in different calls, the function will try to use + * the highest of those values. + * @param current (optional) the element you are currently at. This can be used + * to overwrite the default behaviour (which is to assume that an + * element was successfully processed each time this function is + * called) + * @param highPrecision (template, optional) if set to true, time will be + * displayed with additional milliseconds + * @param length (template, optional) used to change the length of the printed + * progressbar + * + */ +template std::string fancyProgressBar( unsigned const nTotal, unsigned const current = 0 @@ -26,9 +48,8 @@ std::string fancyProgressBar( static time_point startTime; if(part==0){ startTime = steady_clock::now(); } // get the starting time on the very first call - int const length = 50; std::stringstream ss; - time_point const now = steady_clock::now(); + auto const now = steady_clock::now(); maxNTotal = std::max(maxNTotal, nTotal); part = current ? current : ++part; @@ -37,10 +58,10 @@ std::string fancyProgressBar( duration const timeSpent = now - startTime; if(timeSpent.count() > 0.035f*tic || part == maxNTotal){ ++tic; - float const percentage = static_cast(part) / static_cast(maxNTotal); + auto const percentage = static_cast(part) / static_cast(maxNTotal); ss << "\rProgress: ["; - ss << printPattern(tic, percentage, length); + ss << printPattern(tic, percentage); ss << "] "; ss << printPercentage(part, maxNTotal, percentage); ss << printTime(timeSpent, percentage); diff --git a/include/elegantProgressbars/fancyProgressbar_legacy.hpp b/include/elegantProgressbars/fancyProgressbar_legacy.hpp index d21d6f1..7bc754c 100644 --- a/include/elegantProgressbars/fancyProgressbar_legacy.hpp +++ b/include/elegantProgressbars/fancyProgressbar_legacy.hpp @@ -10,10 +10,41 @@ namespace ElegantProgressbars{ +/** + * Gives the difference of 1 timevals in terms of seconds with fraction. + * + * Usage is similar to the traditional way to calculate passed time + * (endTime-startTime), but this one uses timeval-structs internally to reach + * microsecond-precision. + * + * @param end the end-time + * @param start the start-time + */ float timevalDiff(timeval const end, timeval const start){ return (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) * 1e-6; } +/** + * Writes a fancy progressbar with minimal input + * + * Takes the total number of elements to process and creates a nice progressbar + * from that. This is intended to be called in a loop / recursion / MPI thread + * / pthread / etc. It should be called each time one of the nTotal elements is + * done processing. + * Can be fine-tuned for different length of the progressbar through a template + * + * @param nTotal the total number of elements to process. If multiple values + * are supplied in different calls, the function will try to use + * the highest of those values. + * @param current (optional) the element you are currently at. This can be used + * to overwrite the default behaviour (which is to assume that an + * element was successfully processed each time this function is + * called) + * @param length (template, optional) used to change the length of the printed + * progressbar + * + */ +template std::string fancyProgressBarLegacy( unsigned const nTotal, unsigned const current = 0 @@ -25,7 +56,6 @@ std::string fancyProgressBarLegacy( static timeval startTime; if(part==0){ gettimeofday(&startTime,NULL); } // get the starting time on the very first call - int const length = 50; std::stringstream ss; timeval now; gettimeofday(&now,NULL); @@ -40,7 +70,7 @@ std::string fancyProgressBarLegacy( float const percentage = static_cast(part) / static_cast(maxNTotal); ss << "\rProgress: ["; - ss << printPattern(tic, percentage, length); + ss << printPattern(tic, percentage); ss << "] "; ss << printPercentage(part, maxNTotal, percentage); ss << printTime(timeSpent, percentage); diff --git a/include/elegantProgressbars/printPattern.hpp b/include/elegantProgressbars/printPattern.hpp index 0b35b1d..5eff0dd 100644 --- a/include/elegantProgressbars/printPattern.hpp +++ b/include/elegantProgressbars/printPattern.hpp @@ -7,17 +7,24 @@ namespace ElegantProgressbars{ /** - * @brief returns a string of ascii-art in the style of a sine-wave + * Writes progress as an ascii-art progressbar + * + * Takes some external time reference and a percentage to express how far the + * progressbar should be filled. There may be supplied an additional pattern, + * which will be moving as time passes. The pattern defaults to a sine-wave + * like pattern. If no such movement and fancyness is desired, a single element + * may be used as a pattern (e.g. "#"). * * @param tic continuously increasing value related to the real outside time - * @param percentage the progress as a fraction of 1 (0-1) - * @param length the length of the finished wave. - * @param pattern the pattern of the wave (defaults to a wave) + * @param percentage the progress as a fraction of 1 + * @param pattern (optional) the pattern of the wave (defaults to a wave) + * @param length (template, optional) parameter to change the length of the + * finished pattern */ +template std::string printPattern( unsigned const tic, float const percentage, - unsigned const length, std::wstring pattern = L"ø¤º°`°º¤ø,¸," ){ diff --git a/include/elegantProgressbars/printPercentage.hpp b/include/elegantProgressbars/printPercentage.hpp index 98907e7..4e9e757 100644 --- a/include/elegantProgressbars/printPercentage.hpp +++ b/include/elegantProgressbars/printPercentage.hpp @@ -8,9 +8,25 @@ namespace ElegantProgressbars{ -std::string printPercentage(unsigned part, unsigned const maxPart, float const percentage){ +/** + * Writes progress expressed as percentage + * + * Takes the elements that were already processed, the maximum number of + * elements to process and the percentage that is described by that, which is + * somewhat redundant. These parameters are printed in a nice and + * human-friendly fashion. + * + * @param part at which element between 1 and maxPart the process is + * @param maxPart the maximum number of elements to process + * @param percentage (optional) the percentage the current task is at (as a + * fraction of 1) + */ +std::string printPercentage(unsigned part, unsigned const maxPart, float percentage = -1.f){ std::stringstream stream; + if(percentage < 0) + percentage = static_cast(part) / static_cast(maxPart); + assert(percentage <= 1.f); assert(maxPart > 0); diff --git a/include/elegantProgressbars/printTime.hpp b/include/elegantProgressbars/printTime.hpp index db1613a..c4c592b 100644 --- a/include/elegantProgressbars/printTime.hpp +++ b/include/elegantProgressbars/printTime.hpp @@ -7,6 +7,20 @@ namespace ElegantProgressbars{ +/** + * Writes the time in a human-friendly way + * + * The returned string will be formatted to display the time in terms of hours, + * minutes and seconds. If the duration is small enough, some of those will be + * omitted. A template argument allows to include also milliseconds + * Example: 5000s -> 1h 23m 20s + * 1000s -> 16m 40s + * (highPrecision) 1.1s -> 1s 100ms + * + * @param highPrecision (template, optional) if set to true, the time will also + * be displayed in terms of milliseconds + * @param time the duration to write + */ template std::string humanRepresentation( std::chrono::duration const time){ @@ -19,24 +33,37 @@ std::string humanRepresentation( typedef duration> minutes; typedef duration> hours; - int const tMsec = duration_cast(time).count()%1000; - int const tSec = duration_cast(time).count()%60; - int const tMin = duration_cast(time).count()%60; - int const tHour = duration_cast(time).count(); + auto const tMsec = duration_cast(time).count() % 1000; + auto const tSec = duration_cast(time).count() % 60; + auto const tMin = duration_cast(time).count() % 60; + auto const tHour = duration_cast(time).count(); std::stringstream ss; - if(tHour) ss << tHour << "h "; - if(tMin) ss << tMin << "m "; - if(tSec || !highPrecision) ss << tSec << "s"; + if(tHour) ss << tHour << "h "; + if(tMin) ss << tMin << "m "; + if(tSec || !highPrecision) ss << tSec << "s"; - if(highPrecision){ - ss << " " << tMsec << "ms"; - } + if(highPrecision) ss << " " << tMsec << "ms"; return ss.str(); } + + +/** + * Writes progress expressed as time passed + * + * Takes the time that was already spent on a task and the percentage of + * completion of said task. These parameters are used to calculate remaining + * time and overall time to completion and writes it in a nice, human-friendly + * fashion. + * + * @param tSpent the time that was spent at the current task + * @param percentage the percentage the current task is at (as a fraction of 1) + * @param highPrecision (template, optional) if set to true, the time will also + * be displayed in terms of milliseconds + */ template std::string printTime(std::chrono::duration const tSpent, float const percentage){ using std::chrono::duration; @@ -46,8 +73,8 @@ std::string printTime(std::chrono::duration const tSpent, float const per assert(percentage <= 1.f); - duration const tTotal = tSpent / percentage; - duration const tRemaining = tTotal - tSpent; + auto const tTotal = tSpent / percentage; + auto const tRemaining = tTotal - tSpent; stream << " after " << humanRepresentation(tSpent); stream << " (" << humanRepresentation(tTotal) <<" total"; diff --git a/include/elegantProgressbars/printTime_legacy.hpp b/include/elegantProgressbars/printTime_legacy.hpp index 93bf8b2..0501e3f 100644 --- a/include/elegantProgressbars/printTime_legacy.hpp +++ b/include/elegantProgressbars/printTime_legacy.hpp @@ -6,6 +6,17 @@ namespace ElegantProgressbars{ +/** + * Writes progress expressed as time passed + * + * Takes the time that was already spent on a task and the percentage of + * completion of said task. These parameters are used to calculate remaining + * time and overall time to completion and writes it in a nice, human-friendly + * fashion. + * + * @param tSpent the time that was spent at the current task + * @param percentage the percentage the current task is at (as a fraction of 1) + */ std::string printTime(float const timeSpent, float const percentage){ std::stringstream stream;