Skip to content
Merged
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
41 changes: 41 additions & 0 deletions .github/workflows/check-code-coverage.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# This workflow will install Progress Table and test whether basic importing works correctly
# For more information see:
# https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: check code coverage

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
strategy:
matrix:
python-version: [
"3.10",
]
os: [
"ubuntu-22.04",
]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install .
pip install pytest pytest-cov numpy pandas scikit-learn

- name: Test with pytest
run: pytest . --cov=progress_table --cov-report=xml

- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v5
2 changes: 1 addition & 1 deletion .github/workflows/check-code-quality.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# For more information see:
# https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: check code quality with python 3.10
name: check code quality

on:
push:
Expand Down
15 changes: 4 additions & 11 deletions .github/workflows/check-with-pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# For more information see:
# https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: install locally and run pytest
name: run tests

on:
push:
Expand All @@ -25,6 +25,7 @@ jobs:
]
os: [
"ubuntu-22.04",
"windows-latest",
]

runs-on: ${{ matrix.os }}
Expand All @@ -40,13 +41,5 @@ jobs:
pip install .
pip install pytest numpy pandas scikit-learn

# Fix failing importlib
- name: Set PYTHONPATH
run: echo "PYTHONPATH=$(pwd)" >> $GITHUB_ENV

# For some reason it is necessary to run pytest separately for each test.
# Otherwise tests might fail.
- name: Test with pytest 1
run: pytest tests/test_docs_auto.py --log-cli-level=WARNING
- name: Test with pytest 2
run: pytest tests/test_examples_auto.py --log-cli-level=WARNING
- name: Test with pytest
run: pytest .
2 changes: 1 addition & 1 deletion .github/workflows/install-from-pypi-run.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# For more information see:
# https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: install from pypi and run basic tests
name: install from pypi

on:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/install-locally-and-run.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# For more information see:
# https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: install locally and run basic tests
name: install locally

on:
push:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*.ipynb
__pycache__
*.egg-info
.coverage
coverage.xml

devel/
dist
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
# Progress Table

[![PyPi version](https://img.shields.io/badge/dynamic/json?label=latest&query=info.version&url=https%3A%2F%2Fpypi.org%2Fpypi%2Fprogress-table%2Fjson)](https://pypi.org/project/progress-table)
[![PyPI license](https://img.shields.io/badge/dynamic/json?label=license&query=info.license&url=https%3A%2F%2Fpypi.org%2Fpypi%2Fprogress-table%2Fjson)](https://pypi.org/project/progress-table)
[![PyPI license](https://img.shields.io/badge/dynamic/json?label=license&query=info.license&url=https%3A%2F%2Fpypi.org%2Fpypi%2Fprogress-table%2Fjson)](https://github.com/sjmikler/progress-table/blob/main/LICENSE.txt)
[![codecov](https://codecov.io/gh/sjmikler/progress-table/graph/badge.svg?token=CDJKF0FFAQ)](https://codecov.io/gh/sjmikler/progress-table)

Lightweight utility to display the progress of your process as a pretty table in the command line.

Expand Down
132 changes: 132 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
> Version 2.x.x introduces new features and new interactive modes.
>
> Version 3.x.x improves compatibility and stability.
>
> New features allow for previously impossible applications, see examples below.

# Progress Table

[![PyPi version](https://img.shields.io/badge/dynamic/json?label=latest&query=info.version&url=https%3A%2F%2Fpypi.org%2Fpypi%2Fprogress-table%2Fjson)](https://pypi.org/project/progress-table)
[![PyPI license](https://img.shields.io/badge/dynamic/json?label=license&query=info.license&url=https%3A%2F%2Fpypi.org%2Fpypi%2Fprogress-table%2Fjson)](https://pypi.org/project/progress-table)

Lightweight utility to display the progress of your process as a pretty table in the command line.

* Alternative to TQDM whenever you want to track metrics produced by your process
* Designed to monitor ML experiments, but works for any metrics-producing process
* Allows you to see at a glance what's going on with your process
* Increases readability and simplifies your command line logging

### Change this:

![example](https://raw.githubusercontent.com/sjmikler/progress-table/main/images/progress-before3.gif)

### Into this:

![example](https://raw.githubusercontent.com/sjmikler/progress-table/main/images/progress-after4.gif)

## Examples

From `examples/` directory:

* Neural network training

![example-training](https://raw.githubusercontent.com/sjmikler/progress-table/main/images/examples-training.gif)

* Progress of multi-threaded downloads

![example-download](https://raw.githubusercontent.com/sjmikler/progress-table/main/images/examples-download.gif)

* Simulation and interactive display of Brownian motion

![example-brown2d](https://raw.githubusercontent.com/sjmikler/progress-table/main/images/examples-brown2d.gif)

* Display of a game board

![example-tictactoe](https://raw.githubusercontent.com/sjmikler/progress-table/main/images/examples-tictactoe.gif)

## Quick start code

```python
import random
import time

from progress_table import ProgressTable

# Create table object:
table = ProgressTable(num_decimal_places=1)

# You can (optionally) define the columns at the beginning
table.add_column("x", color="bold red")

for step in range(10):
x = random.randint(0, 200)

# You can add entries in a compact way
table["x"] = x

# Or you can use the update method
table.update("x", value=x, weight=1.0)

# Display the progress bar by wrapping an iterator or an integer
for _ in table(10): # -> Equivalent to `table(range(10))`
# Set and get values from the table
table["y"] = random.randint(0, 200)
table["x-y"] = table["x"] - table["y"]
table.update("average x-y", value=table["x-y"], weight=1.0, aggregate="mean")
time.sleep(0.1)

# Go to the next row when you're ready
table.next_row()

# Close the table when it's finished
table.close()

```

> Go to [integrations](https://github.com/sjmikler/progress-table/blob/main/docs//integrations.md)
> page to see examples of integration with deep learning libraries.

## Advanced usage

Go to [advanced usage](https://github.com/sjmikler/progress-table/blob/main/docs//advanced-usage.md) page for more information.

## Troubleshooting

### Exceesive output

Progress Table works correctly in most consoles, but there are some exceptions:

* Some cloud logging consoles (e.g. kubernetes) don't support `\r` properly. You can still use ProgressTable, but with `interactive=0` option. This mode will not display progress bars.

* Some consoles like 'PyCharm Python Console' or 'IDLE' don't support cursor movement. You can still use ProgressTable, but with `interactive=1` option. In this mode, you can display only a single progress bar.

> By default `interactive=2`. You can change the default 'interactive' with an argument when creating the table object or by setting 'PTABLE_INTERACTIVE' environment variable, e.g. `PTABLE_INTERACTIVE=1`.

### Other problems

If you encounter different messy outputs or other unexpected behavior: please create an issue!

## Installation

Install Progress Table easily with pip:

```
pip install progress-table
```

## Links

* [See on GitHub](https://github.com/gahaalt/progress-table)
* [See on PyPI](https://pypi.org/project/progress-table)

## Alternatives

* Progress bars: great for tracking progress, but they don't provide ways to display data in clear and compact way
* `tqdm`
* `rich.progress`
* `keras.utils.Progbar`

* Libraries displaying data: great for presenting tabular data, but they lack the progress tracking aspect
* `rich.table`
* `tabulate`
* `texttable`
42 changes: 30 additions & 12 deletions docs/advanced-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ table.close()

Which might give you the following:

```
```output
╭──────────╮
│ Value │
├──────────┤
Expand All @@ -56,10 +56,12 @@ table.add_rows(4) # Adding empty rows
table.at[:] = 0.0 # Initialize all values to 0.0
table.at[0, :] = 2.0 # Set all values in the first row to 2.0
table.at[:, 1] = 2.0 # Set all values in the second column to 2.0
table.at[-2, 0] = 3.0 # Set the first column in the second-to-last row to 3.0
table.at[2, 0] = 3.0 # Set the first column in the second-to-last row to 3.0

table.close()
```

Which might give you the following:
Which should give you the following:

```
╭──────────┬──────────┬──────────┬──────────╮
Expand All @@ -69,6 +71,7 @@ Which might give you the following:
│ 0.0000 │ 2.0000 │ 0.0000 │ 0.0000 │
│ 3.0000 │ 2.0000 │ 0.0000 │ 0.0000 │
│ 0.0000 │ 2.0000 │ 0.0000 │ 0.0000 │
╰──────────┴──────────┴──────────┴──────────╯
```

## Progress Bars
Expand All @@ -90,20 +93,27 @@ It is possible to customize the looks of the embedded progress bar by specyfing
```python
from progress_table import ProgressTable

table = ProgressTable(pbar_style_embed="cdots")
table = ProgressTable(pbar_style_embed="dash")
```

Below we show a sample of available styles for embedded progress bars
Below we show a sample of available styles for embedded progress bars:

---
`dash`

```
| Name | Value | Number |
|-----------------------------------|
| test1 | 1.0 | 42 |
|---test2--|----2.0-> | 37 |
```

`cdots`
`rich`

```
| Name | Value | Number |
|-----------------------------------|
| test1 | 1.0 | 42 |
|ꞏꞏꞏtest2ꞏꞏ|ꞏꞏꞏꞏ2.0ꞏ> | 37 |
|━━━test2━━|━━━━2.0━━ | 37 |
```

`under`
Expand Down Expand Up @@ -253,20 +263,28 @@ The available keywords are:
Additionaly, you can specify the color of the progress bar using
`color` and `color_empty` arguments when creating a progress bar object.
This will override whatever color is set in `style` or `style_embed`.
We can combine this option with `colorama.Back` to modify colors
of the background instead of the foreground symbols.

```python
from progress_table import ProgressTable
import colorama
import time

table = ProgressTable()
table = ProgressTable("a", "b", "c")
table.add_rows(1)

pbar = table.pbar(
range(1000),
range(100),
style_embed="hidden",
color=colorama.Back.RED,
color_empty=colorama.Back.BLUE,
)

for _ in pbar:
time.sleep(0.1)
```

In the example above, we use a very specific embedded progress bar.
The typical progress bar symbols will be hidden, but the background color will show us the progress of the process.
Try the example above. It contains a different type of embedded progress bar.
Here the typical progress bar symbols will are hidden,
but the background color will show us the progress of the process.
17 changes: 14 additions & 3 deletions examples/brown2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ def main(random_seed=None, sleep_duration=0.001, **overrides):
MAX_ROWS = 20
STEP_SIZE = 100

distance_pbar = table.pbar(TARGET_DISTANCE, description="Distance", show_throughput=False, show_progress=True)
distance_pbar = table.pbar(
TARGET_DISTANCE,
description="Distance",
show_throughput=False,
show_progress=True,
)

current_position = (0, 0)
current_velocity = PARTICLE_VELOCITY
Expand All @@ -72,8 +77,14 @@ def main(random_seed=None, sleep_duration=0.001, **overrides):
random_direction = random.uniform(0, 2 * 3.1415)
new_velocity = random.uniform(0, PARTICLE_VELOCITY * 2)
current_velocity = current_velocity * PARTICLE_MOMENTUM + new_velocity * (1 - PARTICLE_MOMENTUM)
move_vector = (current_velocity * math.cos(random_direction), current_velocity * math.sin(random_direction))
current_position = (current_position[0] + move_vector[0], current_position[1] + move_vector[1])
move_vector = (
current_velocity * math.cos(random_direction),
current_velocity * math.sin(random_direction),
)
current_position = (
current_position[0] + move_vector[0],
current_position[1] + move_vector[1],
)
distance_from_center = calc_distance(current_position)

tick += 1
Expand Down
Loading