-from typing import Sequence
+import threading
+import time
+import typing
from tqdm import tqdm
@@ -182,11 +184,12 @@ Source code for audeer.core.tqdm
[docs]def progress_bar(
-
iterable: Sequence = None,
+
iterable: typing.Sequence = None,
*,
total: int = None,
desc: str = None,
disable: bool = False,
+
maximum_refresh_time: float = None,
) -> tqdm:
r"""Progress bar with optional text on the right.
@@ -220,6 +223,11 @@
Source code for audeer.core.tqdm
total: total number of iterations
desc: text shown on the right of the progress bar
disable: don't show the display bar
+ maximum_refresh_time: refresh the progress bar
+ at least every ``maximum_refresh_time`` seconds,
+ using another thread.
+ If ``None``,
+ no refreshing is enforced
Returns:
progress bar object
@@ -227,8 +235,9 @@ Source code for audeer.core.tqdm
"""
if desc is None:
desc = ""
- return tqdm(
+ return tqdm_wrapper(
iterable=iterable,
+ maximum_refresh_time=maximum_refresh_time,
ncols=config.TQDM_COLUMNS,
bar_format=config.TQDM_FORMAT,
total=total,
@@ -236,6 +245,48 @@ Source code for audeer.core.tqdm
desc=format_display_message(desc, pbar=True),
leave=config.TQDM_LEAVE,
)
+
+
+def tqdm_wrapper(
+ iterable: typing.Sequence,
+ maximum_refresh_time: float,
+ *args,
+ **kwargs,
+) -> tqdm:
+ r"""Tqdm progress bar wrapper to enforce update once a second.
+
+ When using tqdm with large time durations
+ between single steps of the iteration,
+ it will not automatically update the elapsed time,
+ but needs to be forced,
+ see https://github.com/tqdm/tqdm/issues/861#issuecomment-2197893883.
+
+ Args:
+ iterable: sequence to iterate through
+ maximum_refresh_time: refresh the progress bar
+ at least every ``maximum_refresh_time`` seconds,
+ using another thread.
+ If ``None``,
+ no refreshing is enforced
+ args: arguments passed on to ``tqdm``
+ kwargs: keyword arguments passed on to ``tqdm``
+
+ Returns:
+ progress bar object
+
+ """
+ pbar = tqdm(iterable, *args, **kwargs)
+
+ def refresh():
+ while not pbar.disable:
+ time.sleep(maximum_refresh_time)
+ pbar.refresh()
+
+ if maximum_refresh_time is not None:
+ thread = threading.Thread(target=refresh, daemon=True)
+ thread.start()
+
+ return pbar
@@ -251,7 +302,7 @@
Source code for audeer.core.tqdm
diff --git a/_modules/audeer/core/utils.html b/_modules/audeer/core/utils.html
index 56c59f2..66ca24b 100644
--- a/_modules/audeer/core/utils.html
+++ b/_modules/audeer/core/utils.html
@@ -63,7 +63,7 @@
- v2.0.0
+ v2.1.0
@@ -156,7 +156,7 @@
Source code for audeer.core.utils
import uuid
import warnings
-from audeer.core import tqdm
+from audeer.core.tqdm import progress_bar as audeer_progress_bar
from audeer.core.version import LooseVersion
@@ -681,7 +681,8 @@ Source code for audeer.core.utils
multiprocessing: bool = False,
progress_bar: bool = False,
task_description: str = None,
-) -> typing.Sequence[typing.Any]:
+ maximum_refresh_time: float = None,
+) -> typing.List[typing.Any]:
r"""Run parallel tasks using multprocessing.
.. note:: Result values are returned in order of ``params``.
@@ -702,6 +703,14 @@ Source code for audeer.core.utils
progress_bar: show a progress bar
task_description: task description
that will be displayed next to progress bar
+ maximum_refresh_time: refresh the progress bar
+ at least every ``maximum_refresh_time`` seconds,
+ using another thread.
+ If ``None``,
+ no refreshing is enforced
+
+ Returns:
+ list of computed results
Examples:
>>> power = lambda x, n: x**n
@@ -714,10 +723,11 @@ Source code for audeer.core.utils
results = [None] * num_tasks
if num_workers == 1: # sequential
- with tqdm.progress_bar(
+ with audeer_progress_bar(
params,
total=len(params),
desc=task_description,
+ maximum_refresh_time=maximum_refresh_time,
disable=not progress_bar,
) as pbar:
for index, param in enumerate(pbar):
@@ -729,9 +739,10 @@ Source code for audeer.core.utils
else:
executor = concurrent.futures.ThreadPoolExecutor
with executor(max_workers=num_workers) as pool:
- with tqdm.progress_bar(
+ with audeer_progress_bar(
total=len(params),
desc=task_description,
+ maximum_refresh_time=maximum_refresh_time,
disable=not progress_bar,
) as pbar:
futures = []
@@ -805,7 +816,7 @@ Source code for audeer.core.utils
class QueueWithProgbar(queue.Queue):
def __init__(self, num_tasks, maxsize=0):
super().__init__(maxsize)
- self.pbar = tqdm.progress_bar(
+ self.pbar = audeer_progress_bar(
total=num_tasks,
desc=task_description,
)
@@ -969,6 +980,31 @@ Source code for audeer.core.utils
uid = uid[-8:]
return uid
+
+
+[docs]def unique(sequence: typing.Iterable) -> typing.List:
+
r"""Unique values in its original order.
+
+
This is an alternative to ``list(set(x))``,
+
which does not preserve the original order.
+
+
Args:
+
sequence: sequence of values
+
+
Returns:
+
unique values from ``x`` in order of appearance
+
+
Examples:
+
>>> list(set([2, 2, 1]))
+
[1, 2]
+
>>> unique([2, 2, 1])
+
[2, 1]
+
+
"""
+
# https://stackoverflow.com/a/480227
+
seen = set()
+
seen_add = seen.add
+
return [x for x in sequence if not (x in seen or seen_add(x))]
@@ -984,7 +1020,7 @@ Source code for audeer.core.utils
diff --git a/_modules/audeer/core/version.html b/_modules/audeer/core/version.html
index f77321e..c58b715 100644
--- a/_modules/audeer/core/version.html
+++ b/_modules/audeer/core/version.html
@@ -63,7 +63,7 @@
- v2.0.0
+ v2.1.0
@@ -524,7 +524,7 @@ Source code for audeer.core.version
diff --git a/_modules/index.html b/_modules/index.html
index 286d8db..de3aa14 100644
--- a/_modules/index.html
+++ b/_modules/index.html
@@ -63,7 +63,7 @@
- v2.0.0
+ v2.1.0
@@ -158,7 +158,7 @@ All modules for which code is available
- Built with Sphinx on 2024/01/25 using the audEERING theme
+ Built with Sphinx on 2024/07/05 using the audEERING theme
diff --git a/_sources/api/audeer.rst.txt b/_sources/api/audeer.rst.txt
index 6171999..aa780a2 100644
--- a/_sources/api/audeer.rst.txt
+++ b/_sources/api/audeer.rst.txt
@@ -44,3 +44,4 @@ audeer
to_list
touch
uid
+ unique
diff --git a/_sources/api/audeer.unique.rst.txt b/_sources/api/audeer.unique.rst.txt
new file mode 100644
index 0000000..2466147
--- /dev/null
+++ b/_sources/api/audeer.unique.rst.txt
@@ -0,0 +1,6 @@
+unique\(\)
+==========
+
+.. currentmodule:: audeer
+
+.. autofunction:: audeer.unique
\ No newline at end of file
diff --git a/api/audeer.LooseVersion.html b/api/audeer.LooseVersion.html
index 48d4449..12e89a1 100644
--- a/api/audeer.LooseVersion.html
+++ b/api/audeer.LooseVersion.html
@@ -65,7 +65,7 @@
- v2.0.0
+ v2.1.0
@@ -146,6 +146,7 @@
to_list()
touch()
uid()
+
unique()
Index
@@ -365,7 +366,7 @@
version_re on 2024/01/25 using the audEERING theme
+ Built with Sphinx on 2024/07/05 using the audEERING theme
diff --git a/api/audeer.StrictVersion.html b/api/audeer.StrictVersion.html
index 45faa71..8c95ff7 100644
--- a/api/audeer.StrictVersion.html
+++ b/api/audeer.StrictVersion.html
@@ -65,7 +65,7 @@
- v2.0.0
+ v2.1.0
@@ -147,6 +147,7 @@
to_list()
touch()
uid()
+
unique()
Index
@@ -392,7 +393,7 @@
version_re on 2024/01/25 using the audEERING theme
+ Built with Sphinx on 2024/07/05 using the audEERING theme
diff --git a/api/audeer.basename_wo_ext.html b/api/audeer.basename_wo_ext.html
index 4a32df7..e7fb172 100644
--- a/api/audeer.basename_wo_ext.html
+++ b/api/audeer.basename_wo_ext.html
@@ -65,7 +65,7 @@
- v2.0.0
+ v2.1.0
@@ -134,6 +134,7 @@
to_list()
touch()
uid()
+
unique()
Index
@@ -232,7 +233,7 @@
basename_wo_ext() on 2024/01/25 using the audEERING theme
+ Built with Sphinx on 2024/07/05 using the audEERING theme
diff --git a/api/audeer.common_directory.html b/api/audeer.common_directory.html
index 7c0423b..0fd7c4b 100644
--- a/api/audeer.common_directory.html
+++ b/api/audeer.common_directory.html
@@ -65,7 +65,7 @@
- v2.0.0
+ v2.1.0
@@ -134,6 +134,7 @@
to_list()
touch()
uid()
+
unique()
Index
@@ -236,7 +237,7 @@
common_directory() on 2024/01/25 using the audEERING theme
+ Built with Sphinx on 2024/07/05 using the audEERING theme
diff --git a/api/audeer.config.html b/api/audeer.config.html
index 992ad98..ae10e81 100644
--- a/api/audeer.config.html
+++ b/api/audeer.config.html
@@ -65,7 +65,7 @@
- v2.0.0
+ v2.1.0
@@ -147,6 +147,7 @@
to_list()
touch()
uid()
+
unique()
Index
@@ -331,7 +332,7 @@
TQDM_LEAVE on 2024/01/25 using the audEERING theme
+ Built with Sphinx on 2024/07/05 using the audEERING theme
diff --git a/api/audeer.create_archive.html b/api/audeer.create_archive.html
index 30ff002..cc73d10 100644
--- a/api/audeer.create_archive.html
+++ b/api/audeer.create_archive.html
@@ -65,7 +65,7 @@
- v2.0.0
+ v2.1.0
@@ -134,6 +134,7 @@
to_list()
touch()
uid()
+
unique()
Index
@@ -258,7 +259,7 @@
create_archive() on 2024/01/25 using the audEERING theme
+ Built with Sphinx on 2024/07/05 using the audEERING theme
diff --git a/api/audeer.deprecated.html b/api/audeer.deprecated.html
index 2170ede..13d988b 100644
--- a/api/audeer.deprecated.html
+++ b/api/audeer.deprecated.html
@@ -65,7 +65,7 @@