Skip to content

fixed unicode output #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ obj/
bin/
lib/
src/stdafx.h.gch
build/
58 changes: 31 additions & 27 deletions include/tqdm/tqdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ Includes a default range iterator printing to stderr.
#include <type_traits> // is_pointer, ...
#include <utility> // swap
#include <functional> // function
// #include <wchar.h> // wchar_t (TODO: stdafx, use for unicode!)
#include <iostream>
#include <iomanip>
#include <sstream>
#include "tqdm/utils.h"

namespace tqdm {
Expand Down Expand Up @@ -131,17 +133,11 @@ template <typename _Iterator> class Tqdm : public IteratorWrapper<_Iterator> {
sp["\n"];
}

template <typename String,
typename = typename std::enable_if<
std::is_same<String, std::string>::value ||
std::is_same<String, std::wstring>::value>::type>
// TODO
static String format_meter(difference_type n, difference_type total,
float elapsed, int ncols, const String &prefix,
const String &ascii, const String &unit,
static std::string format_meter(difference_type n, difference_type total,
float elapsed, int ncols, const std::string &prefix,
const std::string &ascii, const std::string &unit,
bool unit_scale, float rate,
const String &bar_format) {
typedef typename String::value_type Char;
const std::string &bar_format) {
// sanity check: total
if (n > total)
total = -1;
Expand Down Expand Up @@ -194,13 +190,13 @@ template <typename _Iterator> class Tqdm : public IteratorWrapper<_Iterator> {
rate <= 0 ? "?" : format_interval(size_t((total - n) / rate));

// format the stats displayed to the left and right sides of the bar
String l_bar;
std::string l_bar;
char reserve[256];
sprintf_s(reserve, "%s%3.0f%%%s",
prefix.empty() ? "" : (prefix + ": ").c_str(), percentage,
ncols > 0 ? "|" : "");
l_bar = reserve;
String r_bar = String(ncols > 0 ? "|" : "") + " " + n_fmt + "/" +
std::string r_bar = std::string(ncols > 0 ? "|" : "") + " " + n_fmt + "/" +
total_fmt + " [" + elapsed_str + "<" + remaining_str +
", " + rate_fmt + "]";
if (ncols <= 0)
Expand Down Expand Up @@ -251,33 +247,41 @@ template <typename _Iterator> class Tqdm : public IteratorWrapper<_Iterator> {
: 10;

int bar_length, frac_bar_length;
String bar;
Char frac_bar;
std::string bar;
std::string frac_bar;
// format bar depending on availability of unicode/ascii chars
if (!ascii.empty()) {
std::tie(bar_length, frac_bar_length) =
divmod(int(frac * N_BARS * int(ascii.size() - 1)),
int(ascii.size() - 1));

bar = String(bar_length, Char(ascii.back()));
bar = std::string(bar_length, ascii.back());
frac_bar = frac_bar_length ? 48 + frac_bar_length : ' ';
} else {
std::tie(bar_length, frac_bar_length) =
divmod(int(frac * N_BARS * 8), 8);

bar = String(bar_length, Char(0x2588));
frac_bar = frac_bar_length ? Char(0x2590 - frac_bar_length) : ' ';
for (int i = 0; i < bar_length; ++i) {
bar += "\u2588";
}
if (frac_bar_length) {
char u[4] = "\u2590";
u[2] -= frac_bar_length;
frac_bar = u;
} else {
frac_bar = ' ';
}
}
String full_bar;
std::string full_bar;
// whitespace padding
if (bar_length < N_BARS)
full_bar = bar + frac_bar +
String(std::max(N_BARS - bar_length - 1, 0), ' ');
std::string(std::max(N_BARS - bar_length - 1, 0), ' ');
else
full_bar = bar + String(std::max(N_BARS - bar_length, 0), ' ');
full_bar = bar + std::string(std::max(N_BARS - bar_length, 0), ' ');

// Piece together the bar parts
return String(l_bar.c_str()) + full_bar + r_bar;
return std::string(l_bar.c_str()) + full_bar + r_bar;
}
}

Expand Down Expand Up @@ -401,7 +405,7 @@ template <typename _Iterator> class Tqdm : public IteratorWrapper<_Iterator> {
throw std::out_of_range(
"exhausted"); // TODO: don't throw, just double total
if (n < 0) {
printf("n (%s) cannot be negative", _s(n));
std::cerr << "n (" << n << ") cannot be negative";
throw std::out_of_range("negative step in forward iterator");
} else if (!n)
return;
Expand Down Expand Up @@ -494,19 +498,19 @@ template <typename SizeType = int>
using RangeTqdm = Tqdm<RangeIterator<SizeType>>;
template <typename SizeType>
RangeTqdm<SizeType> range(SizeType n, Params p = Params()) {
return RangeTqdm<SizeType>(RangeIterator<SizeType>(n),
RangeIterator<SizeType>(n), p);
return RangeTqdm<SizeType>(RangeIterator<SizeType>(0, n),
RangeIterator<SizeType>(n, n), p);
}
template <typename SizeType>
RangeTqdm<SizeType> range(SizeType start, SizeType end, Params p = Params()) {
return RangeTqdm<SizeType>(RangeIterator<SizeType>(start, end),
RangeIterator<SizeType>(start, end), p);
RangeIterator<SizeType>(end, end), p);
}
template <typename SizeType>
RangeTqdm<SizeType> range(SizeType start, SizeType end, SizeType step,
Params p = Params()) {
return RangeTqdm<SizeType>(RangeIterator<SizeType>(start, end, step),
RangeIterator<SizeType>(start, end, step), p);
RangeIterator<SizeType>(end, end, step), p);
}

} // tqdm
Expand Down
19 changes: 3 additions & 16 deletions include/tqdm/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,6 @@ inline T diff(const time_point &to, const time_point &from) {
return std::chrono::duration_cast<duration<T>>(to - from).count();
}

#ifndef _s
/**
Converts anything to a c-string.
* TODO: could this cause a memory leak?
@author Casper da Costa-Luis
*/
#define _s(obj) std::to_string(obj).c_str()
#endif // _S

template <typename _Iterator>
/**
Wrapper for pointers and std containter iterators.
Expand Down Expand Up @@ -279,19 +270,15 @@ class RangeIterator
return (total - current) / step;
}

/** here be dragons */
inline bool operator==(const RangeIterator &rhs) const {
return current == rhs.total;
return current == rhs.current;
}
inline bool operator<(const RangeIterator &rhs) const {
return current < rhs.total;
return current < rhs.current;
}
inline noconst_value_type operator-(const RangeIterator &rhs) const {
// it's used in `end - begin`, but `end` is only a sentinel
// so let's use `begin `to be consistent
return rhs.size_remaining();
return current - rhs.current;
}
/** end of dubious section */

inline bool operator!=(const RangeIterator &rhs) const {
return !(*this == rhs);
Expand Down
13 changes: 11 additions & 2 deletions test/test-example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ int main() {
// if (i) printf("\r%d", i);
if (i < 0)
printf(" \b");

{
tqdm::Params p;
p.desc = "range-based array";
p.miniters = 1;
Expand All @@ -39,10 +39,19 @@ int main() {
for (auto &i : tqdm::tqdm(a, p))
if (i < 0)
printf(" \b");
}
tqdm::Params p;
p.desc = "range-based array (unicode)";
p.ascii = "";
p.dynamic_ncols = true;
for (auto &i : tqdm::tqdm(a, p)) {
if (i < 0)
printf(" \b");
}

printf("iterator-based pythonic range()\n");
for (auto it = tqdm::range(N); !it.ended(); ++it)
;
;

printf("ye moste pythonic range(), auto type inference\n");
float m = 2, n = float(N), s = 2;
Expand Down