window下tqdm进度条

avatar
作者
筋斗云
阅读量:0

原代码是linux下运行,修改后可在window下运行。

#ifndef TQDM_H #define TQDM_H  #include <chrono> #include <ctime> #include <numeric> #include <ios> #include <string> #include <cstdlib> #include <iostream> #include <vector> #include <math.h> #include <algorithm> #include <io.h> class tqdm { private: 	// time, iteration counters and deques for rate calculations 	std::chrono::time_point<std::chrono::system_clock> t_first = std::chrono::system_clock::now(); 	std::chrono::time_point<std::chrono::system_clock> t_old = std::chrono::system_clock::now(); 	int n_old = 0; 	std::vector<double> deq_t; 	std::vector<int> deq_n; 	int nupdates = 0; 	int total_ = 0; 	int period = 1; 	unsigned int smoothing = 50; 	bool use_ema = true; 	float alpha_ema = 0.1;  	std::vector<const char*> bars = { " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" };  	bool in_screen = (system("test $STY") == 0); 	bool in_tmux = (system("test $TMUX") == 0); 	bool is_tty = _isatty(1); 	bool use_colors = true; 	bool color_transition = true; 	int width = 40;  	std::string right_pad = "▏"; 	std::string label = "";  	void hsv_to_rgb(float h, float s, float v, int& r, int& g, int& b) { 		if (s < 1e-6) { 			v *= 255.; 			r = v; g = v; b = v; 		} 		int i = (int)(h*6.0); 		float f = (h*6.) - i; 		int p = (int)(255.0*(v*(1. - s))); 		int q = (int)(255.0*(v*(1. - s * f))); 		int t = (int)(255.0*(v*(1. - s * (1. - f)))); 		v *= 255; 		i %= 6; 		int vi = (int)v; 		if (i == 0) { r = vi; g = t;  b = p; } 		else if (i == 1) { r = q;  g = vi; b = p; } 		else if (i == 2) { r = p;  g = vi; b = t; } 		else if (i == 3) { r = p;  g = q;  b = vi; } 		else if (i == 4) { r = t;  g = p;  b = vi; } 		else if (i == 5) { r = vi; g = p;  b = q; } 	}  public: 	tqdm() { 		if (in_screen) { 			set_theme_basic(); 			color_transition = false; 		} 		else if (in_tmux) { 			color_transition = false; 		} 	}  	void reset() { 		t_first = std::chrono::system_clock::now(); 		t_old = std::chrono::system_clock::now(); 		n_old = 0; 		deq_t.clear(); 		deq_n.clear(); 		period = 1; 		nupdates = 0; 		total_ = 0; 		label = ""; 	}  	void set_theme_line() { bars = { "─", "─", "─", "╾", "╾", "╾", "╾", "━", "═" }; } 	void set_theme_circle() { bars = { " ", "◓", "◑", "◒", "◐", "◓", "◑", "◒", "#" }; } 	void set_theme_braille() { bars = { " ", "⡀", "⡄", "⡆", "⡇", "⡏", "⡟", "⡿", "⣿" }; } 	void set_theme_braille_spin() { bars = { " ", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠇", "⠿" }; } 	void set_theme_vertical() { bars = { "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "█" }; } 	void set_theme_basic() { 		bars = { " ", " ", " ", " ", " ", " ", " ", " ", "#" }; 		right_pad = "|"; 	} 	void set_label(std::string label_) { label = label_; } 	void disable_colors() { 		color_transition = false; 		use_colors = false; 	}  	void finish() { 		progress(total_, total_); 		printf("\n"); 		fflush(stdout); 	} 	void progress(int curr, int tot) { 		if (is_tty && (curr%period == 0)) { 			total_ = tot; 			nupdates++; 			auto now = std::chrono::system_clock::now(); 			double dt = ((std::chrono::duration<double>)(now - t_old)).count(); 			double dt_tot = ((std::chrono::duration<double>)(now - t_first)).count(); 			int dn = curr - n_old; 			n_old = curr; 			t_old = now; 			if (deq_n.size() >= smoothing) deq_n.erase(deq_n.begin()); 			if (deq_t.size() >= smoothing) deq_t.erase(deq_t.begin()); 			deq_t.push_back(dt); 			deq_n.push_back(dn);  			double avgrate = 0.; 			if (use_ema) { 				avgrate = deq_n[0] / deq_t[0]; 				for (unsigned int i = 1; i < deq_t.size(); i++) { 					double r = 1.0*deq_n[i] / deq_t[i]; 					avgrate = alpha_ema * r + (1.0 - alpha_ema)*avgrate; 				} 			} 			else { 				double dtsum = std::accumulate(deq_t.begin(), deq_t.end(), 0.); 				int dnsum = std::accumulate(deq_n.begin(), deq_n.end(), 0.); 				avgrate = dnsum / dtsum; 			}  			// learn an appropriate period length to avoid spamming stdout 			// and slowing down the loop, shoot for ~25Hz and smooth over 3 seconds 			if (nupdates > 10) { 				period = (int)(std::min(std::max((1.0 / 25)*curr / dt_tot, 1.0), 5e5)); 				smoothing = 25 * 3; 			} 			double peta = (tot - curr) / avgrate; 			double pct = (double)curr / (tot*0.01); 			if ((tot - curr) <= period) { 				pct = 100.0; 				avgrate = tot / dt_tot; 				curr = tot; 				peta = 0; 			}  			double fills = ((double)curr / tot * width); 			int ifills = (int)fills;  			printf("\015 "); 			if (use_colors) { 				if (color_transition) { 					// red (hue=0) to green (hue=1/3) 					int r = 255, g = 255, b = 255; 					hsv_to_rgb(0.0 + 0.01*pct / 3, 0.65, 1.0, r, g, b); 					printf("\033[38;2;%d;%d;%dm ", r, g, b); 				} 				else { 					printf("\033[32m "); 				} 			} 			for (int i = 0; i < ifills; i++) std::cout << bars[8]; 			if (!in_screen && (curr != tot)) printf("%s", bars[(int)(8.0*(fills - ifills))]); 			for (int i = 0; i < width - ifills - 1; i++) std::cout << bars[0]; 			printf("%s ", right_pad.c_str()); 			if (use_colors) printf("\033[1m\033[31m"); 			printf("%4.1f%% ", pct); 			if (use_colors) printf("\033[34m");  			std::string unit = "Hz"; 			double div = 1.; 			if (avgrate > 1e6) { 				unit = "MHz"; div = 1.0e6; 			} 			else if (avgrate > 1e3) { 				unit = "kHz"; div = 1.0e3; 			} 			printf("[%4d/%4d | %3.1f %s | %.0fs<%.0fs] ", curr, tot, avgrate / div, unit.c_str(), dt_tot, peta); 			printf("%s ", label.c_str()); 			if (use_colors) printf("\033[0m\033[32m\033[0m\015 ");  			if ((tot - curr) > period) fflush(stdout);  		} 	} }; #endif

主函数: 

#include "MyClass.h" #include <windows.h> int main() {  	int N = 2000; 	tqdm bar;  	std::cout << "Overhead of loop only:" << std::endl; 	for (int i = 0; i < 100000000; i++) { 		bar.progress(i, 100000000); 	} 	bar.finish();   	std::cout << "Basic:" << std::endl; 	bar.reset(); 	bar.set_theme_basic(); 	for (int i = 0; i < N; i++) { 		bar.progress(i, N); 		Sleep(1000); 	} 	bar.finish();  	std::cout << "Braille:" << std::endl; 	bar.reset(); 	bar.set_theme_braille(); 	for (int i = 0; i < N; i++) { 		bar.progress(i, N); 		Sleep(300); 	} 	bar.finish();  	std::cout << "Line:" << std::endl; 	bar.reset(); 	bar.set_theme_line(); 	for (int i = 0; i < N; i++) { 		bar.progress(i, N); 		Sleep(300); 	} 	bar.finish();  	std::cout << "Circles:" << std::endl; 	bar.reset(); 	bar.set_theme_circle(); 	for (int i = 0; i < N; i++) { 		bar.progress(i, N); 		Sleep(300); 	} 	bar.finish();  	bar.reset(); 	std::cout << "Vertical bars:" << std::endl; 	bar.reset(); 	bar.set_theme_vertical(); 	for (int i = 0; i < N; i++) { 		bar.progress(i, N); 		Sleep(3000); 	} 	bar.finish();  	return 0; }

源码 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!