From 0b0a082372b5fd4aabdc4fee8cce16c808ca0c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ozan=20=C4=B0rsoy?= Date: Wed, 27 Dec 2023 16:15:03 -0500 Subject: [PATCH] Add python docstrings, logo, fix final double output in no-tty (#34) --- barkeep/barkeep.h | 7 ++- docs/README.md | 11 ++++ docs/img/barkeep-logo-black.png | Bin 0 -> 16078 bytes pyproject.toml | 2 +- python/README.md | 107 ++++++++++++++------------------ python/barkeep.cpp | 81 +++++++++++++++++++++++- python/tests/test.py | 2 +- 7 files changed, 143 insertions(+), 67 deletions(-) create mode 100644 docs/img/barkeep-logo-black.png diff --git a/barkeep/barkeep.h b/barkeep/barkeep.h index 445875b..4cbb823 100644 --- a/barkeep/barkeep.h +++ b/barkeep/barkeep.h @@ -16,7 +16,7 @@ #include #include -#define BARKEEP_VERSION "0.0.5" +#define BARKEEP_VERSION "0.0.6" namespace barkeep { @@ -167,7 +167,10 @@ class AsyncDisplay { { std::unique_lock lock(completion_m_); complete = complete_; - if (not complete) { completion_.wait_for(lock, interval); } + if (not complete) { + completion_.wait_for(lock, interval); + complete = complete_; + } } display_(); if (complete) { diff --git a/docs/README.md b/docs/README.md index c5f2d22..8129f4f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,16 @@ +
+ ## barkeep +
+ +
+ + + + +
+ Small, single C++ header to display async animations, counters, and progress bars. Use it by including `barkeep.h` in your project. __barkeep__ also has [python bindings](https://pypi.python.org/pypi/barkeep). diff --git a/docs/img/barkeep-logo-black.png b/docs/img/barkeep-logo-black.png new file mode 100644 index 0000000000000000000000000000000000000000..33f7e9515efccbed1775020419466694a0983ca8 GIT binary patch literal 16078 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 status pypi +__Installation:__ `pip install barkeep` + --- - Display a waiting animation with a message: - ```cpp - using namespace std::chrono_literals; - namespace bk = barkeep; + ```python + import time + import barkeep as bk - auto anim = bk::Animation().message("Working"); - anim.show(); - /* do work */ std::this_thread::sleep_for(10s); - anim.done(); + anim = bk.Animation(message="Working") + anim.show() + time.sleep(10) # do work + anim.done() ``` @@ -28,8 +30,8 @@ Small, C++-based python library to display async animations, counters, and progr - Supports several styles: - ```cpp - auto anim = bk::Animation().message("Downloading...").style(bk::Earth); + ```python + anim = bk.Animation(message="Working", style=bk.Earth) ``` @@ -39,18 +41,13 @@ Small, C++-based python library to display async animations, counters, and progr - Display a counter to monitor a numeric variable while waiting: - ```cpp - int work{0}; - auto c = bk::Counter(&work) - .message("Reading lines") - .speed(1.) - .speed_unit("line/s"); - c.show(); - for (int i = 0; i < 505; i++) { - std::this_thread::sleep_for(13ms); // read & process line - work++; - } - c.done(); + ```python + c = bk.Counter(message="Reading lines", speed=1.0, speed_unit="line/s") + c.show() + for i in range(505): + time.sleep(0.013) # read & process line + c += 1 + c.done() ``` @@ -60,19 +57,13 @@ Small, C++-based python library to display async animations, counters, and progr - Display a progress bar to monitor a numeric variable and measure its completion by comparing against a total: - ```cpp - int work{0}; - auto bar = bk::ProgressBar(&work) - .message("Reading lines") - .speed(1.) - .speed_unit("line/s") - .total(505); - bar.show(); - for (int i = 0; i < 505; i++) { - std::this_thread::sleep_for(13ms); // read & process line - work++; - } - bar.done(); + ```python + bar = bk.ProgressBar(message="Reading lines", speed=1.0, speed_unit="line/s", total=505) + bar.show() + for i in range(505): + time.sleep(0.013) # read & process line + bar += 1 + bar.done() ``` @@ -82,19 +73,19 @@ Small, C++-based python library to display async animations, counters, and progr - Combine diplays using `|` operator to monitor multiple variables: - ```cpp - std::atomic sents{0}, toks{0}; - auto bar = - bk::ProgressBar(&sents).total(1010).message("Sents") | - bk::Counter(&toks).message("Toks").speed_unit("tok/s").speed(1.); - bar.show(); - for (int i = 0; i < 1010; i++) { - // do work - std::this_thread::sleep_for(13ms); - sents++; - toks += (1 + rand() % 5); - } - bar.done(); + ```python + import random + + sents = bk.ProgressBar(total=1010, message="Sents") + toks = bk.Counter(message="Toks", speed_unit="tok/s", speed=1.0) + bar = sents | toks + bar.show() + for i in range(1010): + # do work + time.sleep(0.013) + sents += 1 + toks += 1 + random.randrange(5) + bar.done() ``` @@ -104,21 +95,13 @@ Small, C++-based python library to display async animations, counters, and progr - Use "no tty" mode to, e.g., output to log files: - ```cpp - std::atomic sents{0}, toks{0}; - auto bar = bk::ProgressBar(&sents) - .total(401) - .message("Sents") - .speed(1.) - .interval(1.) - .no_tty(); - bar.show(); - for (int i = 0; i < 401; i++) { - std::this_thread::sleep_for(13ms); - sents++; - toks += (1 + rand() % 5); - } - bar.done(); + ```python + bar = bk.ProgressBar(total=401, message="Sents", speed=1.0, interval=1.0, no_tty=True) + bar.show() + for i in range(401): + time.sleep(0.013) + bar += 1 + bar.done() ``` diff --git a/python/barkeep.cpp b/python/barkeep.cpp index d7b9e79..1d7f118 100644 --- a/python/barkeep.cpp +++ b/python/barkeep.cpp @@ -182,7 +182,8 @@ class Composite_ : public Composite { }; PYBIND11_MODULE(barkeep, m) { - m.doc() = "Python bindings for barkeep"; + m.doc() = + "Small, C++-based python library to display async animations, counters, and progress bars."; m.attr("__version__") = BARKEEP_VERSION; py::enum_(m, "AnimationStyle") @@ -226,6 +227,23 @@ PYBIND11_MODULE(barkeep, m) { if (no_tty) { a.no_tty(); } return a; }), + R"docstr( + Displays a simple animation with a message. + + Parameters + ---------- + file : file-like object, optional + File to write to. Defaults to stdout. + message : str, optional + Message to display. Defaults to "". + interval : float, optional + Interval between frames in seconds. If None, defaults to 1 if + not no_tty, 60 otherwise. + style : AnimationStyle, optional + Animation style. Defaults to AnimationStyle.Ellipsis. + no_tty : bool, optional + If True, use no-tty mode (no \r, slower refresh). Defaults to False. + )docstr", "file"_a = py::none(), "message"_a = "", "interval"_a = 1., @@ -298,6 +316,34 @@ PYBIND11_MODULE(barkeep, m) { default: throw std::runtime_error("Unknown dtype"); return {}; } }, + R"docstr( + Monitors and displays a single numeric value with a message. + + Parameters + ---------- + value : int or float, optional + Initial value of the counter. Defaults to 0. + file : file-like object, optional + File to write to. Defaults to stdout. + message : str, optional + Message to display. Defaults to "". + interval : float, optional + Interval between frames in seconds. If None, defaults to 1 if + not no_tty, 60 otherwise. + speed : float, optional + Discount factor in [0, 1] to use in computing the speed. + Previous increments are weighted by (1-discount). + If discount is 0, all increments are weighted equally. + If discount is 1, only the most recent increment is + considered. If discount is None (default), speed is not + computed. + speed_unit : str, optional + Unit of speed. Defaults to "". + no_tty : bool, optional + If True, use no-tty mode (no \r, slower refresh). Defaults to False. + dtype : DType, optional + Data type of the value. Defaults to DType.Int. + )docstr", "value"_a = 0, "file"_a = py::none(), "message"_a = "", @@ -357,6 +403,39 @@ PYBIND11_MODULE(barkeep, m) { default: throw std::runtime_error("Unknown dtype"); return {}; } }, + R"docstr( + Displays a progress bar, by comparing the progress value being monitored to + a given total value. + + Parameters + ---------- + value : int or float, optional + Initial value of the progress bar value. Defaults to 0. + total : int or float, optional + Total value of the bar. Defaults to 100. + file : file-like object, optional + File to write to. Defaults to stdout. + message : str, optional + Message to display. Defaults to "". + interval : float, optional + Interval between frames in seconds. If None, defaults to 1 if + not no_tty, 60 otherwise. + style : ProgressBarStyle, optional + Progress bar style. Defaults to ProgressBarStyle.Blocks. + speed : float, optional + Discount factor in [0, 1] to use in computing the speed. + Previous increments are weighted by (1-discount). + If discount is 0, all increments are weighted equally. + If discount is 1, only the most recent increment is + considered. If discount is None (default), speed is not + computed. + speed_unit : str, optional + Unit of speed. Defaults to "". + no_tty : bool, optional + If True, use no-tty mode (no \r, slower refresh). Defaults to False. + dtype : DType, optional + Data type of the value. Defaults to DType.Int. + )docstr", "value"_a = 0, "total"_a = 100, "file"_a = py::none(), diff --git a/python/tests/test.py b/python/tests/test.py index 169ee42..86a2ad0 100644 --- a/python/tests/test.py +++ b/python/tests/test.py @@ -116,7 +116,7 @@ def test_constant_counter(dtype, amount, discount, unit, no_tty): expected += f"(0.00 {unit}) " for part in parts: - assert part == expected + assert part.replace("(-0.00", "(0.00") == expected def extract_counts(prefix: str, parts: list[str], py_dtype):