std.py 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504
  1. """
  2. Customisable progressbar decorator for iterators.
  3. Includes a default `range` iterator printing to `stderr`.
  4. Usage:
  5. >>> from tqdm import trange, tqdm
  6. >>> for i in trange(10):
  7. ... ...
  8. """
  9. from __future__ import absolute_import, division
  10. # compatibility functions and utilities
  11. from .utils import _supports_unicode, _screen_shape_wrapper, _range, _unich, \
  12. _term_move_up, _unicode, WeakSet, _basestring, _OrderedDict, \
  13. Comparable, _is_ascii, FormatReplace, disp_len, disp_trim, \
  14. SimpleTextIOWrapper, CallbackIOWrapper
  15. from ._monitor import TMonitor
  16. # native libraries
  17. from contextlib import contextmanager
  18. import sys
  19. from numbers import Number
  20. from time import time
  21. # For parallelism safety
  22. import threading as th
  23. from warnings import warn
  24. __author__ = {"github.com/": ["noamraph", "obiwanus", "kmike", "hadim",
  25. "casperdcl", "lrq3000"]}
  26. __all__ = ['tqdm', 'trange',
  27. 'TqdmTypeError', 'TqdmKeyError', 'TqdmWarning',
  28. 'TqdmExperimentalWarning', 'TqdmDeprecationWarning',
  29. 'TqdmMonitorWarning']
  30. class TqdmTypeError(TypeError):
  31. pass
  32. class TqdmKeyError(KeyError):
  33. pass
  34. class TqdmWarning(Warning):
  35. """base class for all tqdm warnings.
  36. Used for non-external-code-breaking errors, such as garbled printing.
  37. """
  38. def __init__(self, msg, fp_write=None, *a, **k):
  39. if fp_write is not None:
  40. fp_write("\n" + self.__class__.__name__ + ": " +
  41. str(msg).rstrip() + '\n')
  42. else:
  43. super(TqdmWarning, self).__init__(msg, *a, **k)
  44. class TqdmExperimentalWarning(TqdmWarning, FutureWarning):
  45. """beta feature, unstable API and behaviour"""
  46. pass
  47. class TqdmDeprecationWarning(TqdmWarning, DeprecationWarning):
  48. # not suppressed if raised
  49. pass
  50. class TqdmMonitorWarning(TqdmWarning, RuntimeWarning):
  51. """tqdm monitor errors which do not affect external functionality"""
  52. pass
  53. class TqdmDefaultWriteLock(object):
  54. """
  55. Provide a default write lock for thread and multiprocessing safety.
  56. Works only on platforms supporting `fork` (so Windows is excluded).
  57. You must initialise a `tqdm` or `TqdmDefaultWriteLock` instance
  58. before forking in order for the write lock to work.
  59. On Windows, you need to supply the lock from the parent to the children as
  60. an argument to joblib or the parallelism lib you use.
  61. """
  62. def __init__(self):
  63. # Create global parallelism locks to avoid racing issues with parallel
  64. # bars works only if fork available (Linux/MacOSX, but not Windows)
  65. self.create_mp_lock()
  66. self.create_th_lock()
  67. cls = type(self)
  68. self.locks = [lk for lk in [cls.mp_lock, cls.th_lock] if lk is not None]
  69. def acquire(self, *a, **k):
  70. for lock in self.locks:
  71. lock.acquire(*a, **k)
  72. def release(self):
  73. for lock in self.locks[::-1]: # Release in inverse order of acquisition
  74. lock.release()
  75. def __enter__(self):
  76. self.acquire()
  77. def __exit__(self, *exc):
  78. self.release()
  79. @classmethod
  80. def create_mp_lock(cls):
  81. if not hasattr(cls, 'mp_lock'):
  82. try:
  83. from multiprocessing import RLock
  84. cls.mp_lock = RLock() # multiprocessing lock
  85. except ImportError: # pragma: no cover
  86. cls.mp_lock = None
  87. except OSError: # pragma: no cover
  88. cls.mp_lock = None
  89. @classmethod
  90. def create_th_lock(cls):
  91. if not hasattr(cls, 'th_lock'):
  92. try:
  93. cls.th_lock = th.RLock() # thread lock
  94. except OSError: # pragma: no cover
  95. cls.th_lock = None
  96. # Create a thread lock before instantiation so that no setup needs to be done
  97. # before running in a multithreaded environment.
  98. # Do not create the multiprocessing lock because it sets the multiprocessing
  99. # context and does not allow the user to use 'spawn' or 'forkserver' methods.
  100. TqdmDefaultWriteLock.create_th_lock()
  101. class Bar(object):
  102. """
  103. `str.format`-able bar with format specifiers: `[width][type]`
  104. - `width`
  105. + unspecified (default): use `self.default_len`
  106. + `int >= 0`: overrides `self.default_len`
  107. + `int < 0`: subtract from `self.default_len`
  108. - `type`
  109. + `a`: ascii (`charset=self.ASCII` override)
  110. + `u`: unicode (`charset=self.UTF` override)
  111. + `b`: blank (`charset=" "` override)
  112. """
  113. ASCII = " 123456789#"
  114. UTF = u" " + u''.join(map(_unich, range(0x258F, 0x2587, -1)))
  115. BLANK = " "
  116. def __init__(self, frac, default_len=10, charset=UTF):
  117. if not (0 <= frac <= 1):
  118. warn("clamping frac to range [0, 1]", TqdmWarning, stacklevel=2)
  119. frac = max(0, min(1, frac))
  120. assert default_len > 0
  121. self.frac = frac
  122. self.default_len = default_len
  123. self.charset = charset
  124. def __format__(self, format_spec):
  125. if format_spec:
  126. _type = format_spec[-1].lower()
  127. try:
  128. charset = dict(a=self.ASCII, u=self.UTF, b=self.BLANK)[_type]
  129. except KeyError:
  130. charset = self.charset
  131. else:
  132. format_spec = format_spec[:-1]
  133. if format_spec:
  134. N_BARS = int(format_spec)
  135. if N_BARS < 0:
  136. N_BARS += self.default_len
  137. else:
  138. N_BARS = self.default_len
  139. else:
  140. charset = self.charset
  141. N_BARS = self.default_len
  142. nsyms = len(charset) - 1
  143. bar_length, frac_bar_length = divmod(
  144. int(self.frac * N_BARS * nsyms), nsyms)
  145. bar = charset[-1] * bar_length
  146. frac_bar = charset[frac_bar_length]
  147. # whitespace padding
  148. if bar_length < N_BARS:
  149. return bar + frac_bar + \
  150. charset[0] * (N_BARS - bar_length - 1)
  151. return bar
  152. class tqdm(Comparable):
  153. """
  154. Decorate an iterable object, returning an iterator which acts exactly
  155. like the original iterable, but prints a dynamically updating
  156. progressbar every time a value is requested.
  157. """
  158. monitor_interval = 10 # set to 0 to disable the thread
  159. monitor = None
  160. @staticmethod
  161. def format_sizeof(num, suffix='', divisor=1000):
  162. """
  163. Formats a number (greater than unity) with SI Order of Magnitude
  164. prefixes.
  165. Parameters
  166. ----------
  167. num : float
  168. Number ( >= 1) to format.
  169. suffix : str, optional
  170. Post-postfix [default: ''].
  171. divisor : float, optional
  172. Divisor between prefixes [default: 1000].
  173. Returns
  174. -------
  175. out : str
  176. Number with Order of Magnitude SI unit postfix.
  177. """
  178. for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']:
  179. if abs(num) < 999.5:
  180. if abs(num) < 99.95:
  181. if abs(num) < 9.995:
  182. return '{0:1.2f}'.format(num) + unit + suffix
  183. return '{0:2.1f}'.format(num) + unit + suffix
  184. return '{0:3.0f}'.format(num) + unit + suffix
  185. num /= divisor
  186. return '{0:3.1f}Y'.format(num) + suffix
  187. @staticmethod
  188. def format_interval(t):
  189. """
  190. Formats a number of seconds as a clock time, [H:]MM:SS
  191. Parameters
  192. ----------
  193. t : int
  194. Number of seconds.
  195. Returns
  196. -------
  197. out : str
  198. [H:]MM:SS
  199. """
  200. mins, s = divmod(int(t), 60)
  201. h, m = divmod(mins, 60)
  202. if h:
  203. return '{0:d}:{1:02d}:{2:02d}'.format(h, m, s)
  204. else:
  205. return '{0:02d}:{1:02d}'.format(m, s)
  206. @staticmethod
  207. def format_num(n):
  208. """
  209. Intelligent scientific notation (.3g).
  210. Parameters
  211. ----------
  212. n : int or float or Numeric
  213. A Number.
  214. Returns
  215. -------
  216. out : str
  217. Formatted number.
  218. """
  219. f = '{0:.3g}'.format(n).replace('+0', '+').replace('-0', '-')
  220. n = str(n)
  221. return f if len(f) < len(n) else n
  222. @staticmethod
  223. def ema(x, mu=None, alpha=0.3):
  224. """
  225. Exponential moving average: smoothing to give progressively lower
  226. weights to older values.
  227. Parameters
  228. ----------
  229. x : float
  230. New value to include in EMA.
  231. mu : float, optional
  232. Previous EMA value.
  233. alpha : float, optional
  234. Smoothing factor in range [0, 1], [default: 0.3].
  235. Increase to give more weight to recent values.
  236. Ranges from 0 (yields mu) to 1 (yields x).
  237. """
  238. return x if mu is None else (alpha * x) + (1 - alpha) * mu
  239. @staticmethod
  240. def status_printer(file):
  241. """
  242. Manage the printing and in-place updating of a line of characters.
  243. Note that if the string is longer than a line, then in-place
  244. updating may not work (it will print a new line at each refresh).
  245. """
  246. fp = file
  247. fp_flush = getattr(fp, 'flush', lambda: None) # pragma: no cover
  248. def fp_write(s):
  249. fp.write(_unicode(s))
  250. fp_flush()
  251. last_len = [0]
  252. def print_status(s):
  253. len_s = disp_len(s)
  254. fp_write('\r' + s + (' ' * max(last_len[0] - len_s, 0)))
  255. last_len[0] = len_s
  256. return print_status
  257. @staticmethod
  258. def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False,
  259. unit='it', unit_scale=False, rate=None, bar_format=None,
  260. postfix=None, unit_divisor=1000, **extra_kwargs):
  261. """
  262. Return a string-based progress bar given some parameters
  263. Parameters
  264. ----------
  265. n : int or float
  266. Number of finished iterations.
  267. total : int or float
  268. The expected total number of iterations. If meaningless (None),
  269. only basic progress statistics are displayed (no ETA).
  270. elapsed : float
  271. Number of seconds passed since start.
  272. ncols : int, optional
  273. The width of the entire output message. If specified,
  274. dynamically resizes `{bar}` to stay within this bound
  275. [default: None]. If `0`, will not print any bar (only stats).
  276. The fallback is `{bar:10}`.
  277. prefix : str, optional
  278. Prefix message (included in total width) [default: ''].
  279. Use as {desc} in bar_format string.
  280. ascii : bool, optional or str, optional
  281. If not set, use unicode (smooth blocks) to fill the meter
  282. [default: False]. The fallback is to use ASCII characters
  283. " 123456789#".
  284. unit : str, optional
  285. The iteration unit [default: 'it'].
  286. unit_scale : bool or int or float, optional
  287. If 1 or True, the number of iterations will be printed with an
  288. appropriate SI metric prefix (k = 10^3, M = 10^6, etc.)
  289. [default: False]. If any other non-zero number, will scale
  290. `total` and `n`.
  291. rate : float, optional
  292. Manual override for iteration rate.
  293. If [default: None], uses n/elapsed.
  294. bar_format : str, optional
  295. Specify a custom bar string formatting. May impact performance.
  296. [default: '{l_bar}{bar}{r_bar}'], where
  297. l_bar='{desc}: {percentage:3.0f}%|' and
  298. r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '
  299. '{rate_fmt}{postfix}]'
  300. Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt,
  301. percentage, elapsed, elapsed_s, ncols, nrows, desc, unit,
  302. rate, rate_fmt, rate_noinv, rate_noinv_fmt,
  303. rate_inv, rate_inv_fmt, postfix, unit_divisor,
  304. remaining, remaining_s.
  305. Note that a trailing ": " is automatically removed after {desc}
  306. if the latter is empty.
  307. postfix : *, optional
  308. Similar to `prefix`, but placed at the end
  309. (e.g. for additional stats).
  310. Note: postfix is usually a string (not a dict) for this method,
  311. and will if possible be set to postfix = ', ' + postfix.
  312. However other types are supported (#382).
  313. unit_divisor : float, optional
  314. [default: 1000], ignored unless `unit_scale` is True.
  315. Returns
  316. -------
  317. out : Formatted meter and stats, ready to display.
  318. """
  319. # sanity check: total
  320. if total and n >= (total + 0.5): # allow float imprecision (#849)
  321. total = None
  322. # apply custom scale if necessary
  323. if unit_scale and unit_scale not in (True, 1):
  324. if total:
  325. total *= unit_scale
  326. n *= unit_scale
  327. if rate:
  328. rate *= unit_scale # by default rate = 1 / self.avg_time
  329. unit_scale = False
  330. elapsed_str = tqdm.format_interval(elapsed)
  331. # if unspecified, attempt to use rate = average speed
  332. # (we allow manual override since predicting time is an arcane art)
  333. if rate is None and elapsed:
  334. rate = n / elapsed
  335. inv_rate = 1 / rate if rate else None
  336. format_sizeof = tqdm.format_sizeof
  337. rate_noinv_fmt = ((format_sizeof(rate) if unit_scale else
  338. '{0:5.2f}'.format(rate))
  339. if rate else '?') + unit + '/s'
  340. rate_inv_fmt = ((format_sizeof(inv_rate) if unit_scale else
  341. '{0:5.2f}'.format(inv_rate))
  342. if inv_rate else '?') + 's/' + unit
  343. rate_fmt = rate_inv_fmt if inv_rate and inv_rate > 1 else rate_noinv_fmt
  344. if unit_scale:
  345. n_fmt = format_sizeof(n, divisor=unit_divisor)
  346. total_fmt = format_sizeof(total, divisor=unit_divisor) \
  347. if total is not None else '?'
  348. else:
  349. n_fmt = str(n)
  350. total_fmt = str(total) if total is not None else '?'
  351. try:
  352. postfix = ', ' + postfix if postfix else ''
  353. except TypeError:
  354. pass
  355. remaining = (total - n) / rate if rate and total else 0
  356. remaining_str = tqdm.format_interval(remaining) if rate else '?'
  357. # format the stats displayed to the left and right sides of the bar
  358. if prefix:
  359. # old prefix setup work around
  360. bool_prefix_colon_already = (prefix[-2:] == ": ")
  361. l_bar = prefix if bool_prefix_colon_already else prefix + ": "
  362. else:
  363. l_bar = ''
  364. r_bar = '| {0}/{1} [{2}<{3}, {4}{5}]'.format(
  365. n_fmt, total_fmt, elapsed_str, remaining_str, rate_fmt, postfix)
  366. # Custom bar formatting
  367. # Populate a dict with all available progress indicators
  368. format_dict = dict(
  369. # slight extension of self.format_dict
  370. n=n, n_fmt=n_fmt, total=total, total_fmt=total_fmt,
  371. elapsed=elapsed_str, elapsed_s=elapsed,
  372. ncols=ncols, desc=prefix or '', unit=unit,
  373. rate=inv_rate if inv_rate and inv_rate > 1 else rate,
  374. rate_fmt=rate_fmt, rate_noinv=rate,
  375. rate_noinv_fmt=rate_noinv_fmt, rate_inv=inv_rate,
  376. rate_inv_fmt=rate_inv_fmt,
  377. postfix=postfix, unit_divisor=unit_divisor,
  378. # plus more useful definitions
  379. remaining=remaining_str, remaining_s=remaining,
  380. l_bar=l_bar, r_bar=r_bar,
  381. **extra_kwargs)
  382. # total is known: we can predict some stats
  383. if total:
  384. # fractional and percentage progress
  385. frac = n / total
  386. percentage = frac * 100
  387. l_bar += '{0:3.0f}%|'.format(percentage)
  388. if ncols == 0:
  389. return l_bar[:-1] + r_bar[1:]
  390. format_dict.update(l_bar=l_bar)
  391. if bar_format:
  392. format_dict.update(percentage=percentage)
  393. # auto-remove colon for empty `desc`
  394. if not prefix:
  395. bar_format = bar_format.replace("{desc}: ", '')
  396. else:
  397. bar_format = "{l_bar}{bar}{r_bar}"
  398. full_bar = FormatReplace()
  399. try:
  400. nobar = bar_format.format(bar=full_bar, **format_dict)
  401. except UnicodeEncodeError:
  402. bar_format = _unicode(bar_format)
  403. nobar = bar_format.format(bar=full_bar, **format_dict)
  404. if not full_bar.format_called:
  405. # no {bar}, we can just format and return
  406. return nobar
  407. # Formatting progress bar space available for bar's display
  408. full_bar = Bar(
  409. frac,
  410. max(1, ncols - disp_len(nobar))
  411. if ncols else 10,
  412. charset=Bar.ASCII if ascii is True else ascii or Bar.UTF)
  413. if not _is_ascii(full_bar.charset) and _is_ascii(bar_format):
  414. bar_format = _unicode(bar_format)
  415. res = bar_format.format(bar=full_bar, **format_dict)
  416. return disp_trim(res, ncols) if ncols else res
  417. elif bar_format:
  418. # user-specified bar_format but no total
  419. l_bar += '|'
  420. format_dict.update(l_bar=l_bar, percentage=0)
  421. full_bar = FormatReplace()
  422. nobar = bar_format.format(bar=full_bar, **format_dict)
  423. if not full_bar.format_called:
  424. return nobar
  425. full_bar = Bar(
  426. 0,
  427. max(1, ncols - disp_len(nobar))
  428. if ncols else 10,
  429. charset=Bar.BLANK)
  430. res = bar_format.format(bar=full_bar, **format_dict)
  431. return disp_trim(res, ncols) if ncols else res
  432. else:
  433. # no total: no progressbar, ETA, just progress stats
  434. return ((prefix + ": ") if prefix else '') + \
  435. '{0}{1} [{2}, {3}{4}]'.format(
  436. n_fmt, unit, elapsed_str, rate_fmt, postfix)
  437. def __new__(cls, *args, **kwargs):
  438. # Create a new instance
  439. instance = object.__new__(cls)
  440. # Construct the lock if it does not exist
  441. with cls.get_lock():
  442. # Add to the list of instances
  443. if not hasattr(cls, '_instances'):
  444. cls._instances = WeakSet()
  445. cls._instances.add(instance)
  446. # Create the monitoring thread
  447. if cls.monitor_interval and (cls.monitor is None or not
  448. cls.monitor.report()):
  449. try:
  450. cls.monitor = TMonitor(cls, cls.monitor_interval)
  451. except Exception as e: # pragma: nocover
  452. warn("tqdm:disabling monitor support"
  453. " (monitor_interval = 0) due to:\n" + str(e),
  454. TqdmMonitorWarning, stacklevel=2)
  455. cls.monitor_interval = 0
  456. # Return the instance
  457. return instance
  458. @classmethod
  459. def _get_free_pos(cls, instance=None):
  460. """Skips specified instance."""
  461. positions = set(abs(inst.pos) for inst in cls._instances
  462. if inst is not instance and hasattr(inst, "pos"))
  463. return min(set(range(len(positions) + 1)).difference(positions))
  464. @classmethod
  465. def _decr_instances(cls, instance):
  466. """
  467. Remove from list and reposition another unfixed bar
  468. to fill the new gap.
  469. This means that by default (where all nested bars are unfixed),
  470. order is not maintained but screen flicker/blank space is minimised.
  471. (tqdm<=4.44.1 moved ALL subsequent unfixed bars up.)
  472. """
  473. with cls._lock:
  474. try:
  475. cls._instances.remove(instance)
  476. except KeyError:
  477. # if not instance.gui: # pragma: no cover
  478. # raise
  479. pass # py2: maybe magically removed already
  480. # else:
  481. if not instance.gui:
  482. last = (instance.nrows or 20) - 1
  483. # find unfixed (`pos >= 0`) overflow (`pos >= nrows - 1`)
  484. instances = list(filter(
  485. lambda i: hasattr(i, "pos") and last <= i.pos,
  486. cls._instances))
  487. # set first found to current `pos`
  488. if instances:
  489. inst = min(instances, key=lambda i: i.pos)
  490. inst.clear(nolock=True)
  491. inst.pos = abs(instance.pos)
  492. # Kill monitor if no instances are left
  493. if not cls._instances and cls.monitor:
  494. try:
  495. cls.monitor.exit()
  496. del cls.monitor
  497. except AttributeError: # pragma: nocover
  498. pass
  499. else:
  500. cls.monitor = None
  501. @classmethod
  502. def write(cls, s, file=None, end="\n", nolock=False):
  503. """Print a message via tqdm (without overlap with bars)."""
  504. fp = file if file is not None else sys.stdout
  505. with cls.external_write_mode(file=file, nolock=nolock):
  506. # Write the message
  507. fp.write(s)
  508. fp.write(end)
  509. @classmethod
  510. @contextmanager
  511. def external_write_mode(cls, file=None, nolock=False):
  512. """
  513. Disable tqdm within context and refresh tqdm when exits.
  514. Useful when writing to standard output stream
  515. """
  516. fp = file if file is not None else sys.stdout
  517. try:
  518. if not nolock:
  519. cls.get_lock().acquire()
  520. # Clear all bars
  521. inst_cleared = []
  522. for inst in getattr(cls, '_instances', []):
  523. # Clear instance if in the target output file
  524. # or if write output + tqdm output are both either
  525. # sys.stdout or sys.stderr (because both are mixed in terminal)
  526. if hasattr(inst, "start_t") and (inst.fp == fp or all(
  527. f in (sys.stdout, sys.stderr) for f in (fp, inst.fp))):
  528. inst.clear(nolock=True)
  529. inst_cleared.append(inst)
  530. yield
  531. # Force refresh display of bars we cleared
  532. for inst in inst_cleared:
  533. inst.refresh(nolock=True)
  534. finally:
  535. if not nolock:
  536. cls._lock.release()
  537. @classmethod
  538. def set_lock(cls, lock):
  539. """Set the global lock."""
  540. cls._lock = lock
  541. @classmethod
  542. def get_lock(cls):
  543. """Get the global lock. Construct it if it does not exist."""
  544. if not hasattr(cls, '_lock'):
  545. cls._lock = TqdmDefaultWriteLock()
  546. return cls._lock
  547. @classmethod
  548. def pandas(cls, **tqdm_kwargs):
  549. """
  550. Registers the current `tqdm` class with
  551. pandas.core.
  552. ( frame.DataFrame
  553. | series.Series
  554. | groupby.(generic.)DataFrameGroupBy
  555. | groupby.(generic.)SeriesGroupBy
  556. ).progress_apply
  557. A new instance will be create every time `progress_apply` is called,
  558. and each instance will automatically `close()` upon completion.
  559. Parameters
  560. ----------
  561. tqdm_kwargs : arguments for the tqdm instance
  562. Examples
  563. --------
  564. >>> import pandas as pd
  565. >>> import numpy as np
  566. >>> from tqdm import tqdm
  567. >>> from tqdm.gui import tqdm as tqdm_gui
  568. >>>
  569. >>> df = pd.DataFrame(np.random.randint(0, 100, (100000, 6)))
  570. >>> tqdm.pandas(ncols=50) # can use tqdm_gui, optional kwargs, etc
  571. >>> # Now you can use `progress_apply` instead of `apply`
  572. >>> df.groupby(0).progress_apply(lambda x: x**2)
  573. References
  574. ----------
  575. <https://stackoverflow.com/questions/18603270/\
  576. progress-indicator-during-pandas-operations-python>
  577. """
  578. from pandas.core.frame import DataFrame
  579. from pandas.core.series import Series
  580. try:
  581. from pandas import Panel
  582. except ImportError: # TODO: pandas>0.25.2
  583. Panel = None
  584. try: # pandas>=1.0.0
  585. from pandas.core.window.rolling import _Rolling_and_Expanding
  586. except ImportError:
  587. try: # pandas>=0.18.0
  588. from pandas.core.window import _Rolling_and_Expanding
  589. except ImportError: # pragma: no cover
  590. _Rolling_and_Expanding = None
  591. try: # pandas>=0.25.0
  592. from pandas.core.groupby.generic import DataFrameGroupBy, \
  593. SeriesGroupBy # , NDFrameGroupBy
  594. except ImportError:
  595. try: # pandas>=0.23.0
  596. from pandas.core.groupby.groupby import DataFrameGroupBy, \
  597. SeriesGroupBy
  598. except ImportError:
  599. from pandas.core.groupby import DataFrameGroupBy, \
  600. SeriesGroupBy
  601. try: # pandas>=0.23.0
  602. from pandas.core.groupby.groupby import GroupBy
  603. except ImportError:
  604. from pandas.core.groupby import GroupBy
  605. try: # pandas>=0.23.0
  606. from pandas.core.groupby.groupby import PanelGroupBy
  607. except ImportError:
  608. try:
  609. from pandas.core.groupby import PanelGroupBy
  610. except ImportError: # pandas>=0.25.0
  611. PanelGroupBy = None
  612. tqdm_kwargs = tqdm_kwargs.copy()
  613. deprecated_t = [tqdm_kwargs.pop('deprecated_t', None)]
  614. def inner_generator(df_function='apply'):
  615. def inner(df, func, *args, **kwargs):
  616. """
  617. Parameters
  618. ----------
  619. df : (DataFrame|Series)[GroupBy]
  620. Data (may be grouped).
  621. func : function
  622. To be applied on the (grouped) data.
  623. **kwargs : optional
  624. Transmitted to `df.apply()`.
  625. """
  626. # Precompute total iterations
  627. total = tqdm_kwargs.pop("total", getattr(df, 'ngroups', None))
  628. if total is None: # not grouped
  629. if df_function == 'applymap':
  630. total = df.size
  631. elif isinstance(df, Series):
  632. total = len(df)
  633. elif _Rolling_and_Expanding is None or \
  634. not isinstance(df, _Rolling_and_Expanding):
  635. # DataFrame or Panel
  636. axis = kwargs.get('axis', 0)
  637. if axis == 'index':
  638. axis = 0
  639. elif axis == 'columns':
  640. axis = 1
  641. # when axis=0, total is shape[axis1]
  642. total = df.size // df.shape[axis]
  643. # Init bar
  644. if deprecated_t[0] is not None:
  645. t = deprecated_t[0]
  646. deprecated_t[0] = None
  647. else:
  648. t = cls(total=total, **tqdm_kwargs)
  649. if len(args) > 0:
  650. # *args intentionally not supported (see #244, #299)
  651. TqdmDeprecationWarning(
  652. "Except func, normal arguments are intentionally" +
  653. " not supported by" +
  654. " `(DataFrame|Series|GroupBy).progress_apply`." +
  655. " Use keyword arguments instead.",
  656. fp_write=getattr(t.fp, 'write', sys.stderr.write))
  657. try:
  658. func = df._is_builtin_func(func)
  659. except TypeError:
  660. pass
  661. # Define bar updating wrapper
  662. def wrapper(*args, **kwargs):
  663. # update tbar correctly
  664. # it seems `pandas apply` calls `func` twice
  665. # on the first column/row to decide whether it can
  666. # take a fast or slow code path; so stop when t.total==t.n
  667. t.update(n=1 if not t.total or t.n < t.total else 0)
  668. return func(*args, **kwargs)
  669. # Apply the provided function (in **kwargs)
  670. # on the df using our wrapper (which provides bar updating)
  671. try:
  672. return getattr(df, df_function)(wrapper, **kwargs)
  673. finally:
  674. t.close()
  675. return inner
  676. # Monkeypatch pandas to provide easy methods
  677. # Enable custom tqdm progress in pandas!
  678. Series.progress_apply = inner_generator()
  679. SeriesGroupBy.progress_apply = inner_generator()
  680. Series.progress_map = inner_generator('map')
  681. SeriesGroupBy.progress_map = inner_generator('map')
  682. DataFrame.progress_apply = inner_generator()
  683. DataFrameGroupBy.progress_apply = inner_generator()
  684. DataFrame.progress_applymap = inner_generator('applymap')
  685. if Panel is not None:
  686. Panel.progress_apply = inner_generator()
  687. if PanelGroupBy is not None:
  688. PanelGroupBy.progress_apply = inner_generator()
  689. GroupBy.progress_apply = inner_generator()
  690. GroupBy.progress_aggregate = inner_generator('aggregate')
  691. GroupBy.progress_transform = inner_generator('transform')
  692. if _Rolling_and_Expanding is not None: # pragma: no cover
  693. _Rolling_and_Expanding.progress_apply = inner_generator()
  694. def __init__(self, iterable=None, desc=None, total=None, leave=True,
  695. file=None, ncols=None, mininterval=0.1, maxinterval=10.0,
  696. miniters=None, ascii=None, disable=False, unit='it',
  697. unit_scale=False, dynamic_ncols=False, smoothing=0.3,
  698. bar_format=None, initial=0, position=None, postfix=None,
  699. unit_divisor=1000, write_bytes=None, lock_args=None,
  700. nrows=None,
  701. gui=False, **kwargs):
  702. """
  703. Parameters
  704. ----------
  705. iterable : iterable, optional
  706. Iterable to decorate with a progressbar.
  707. Leave blank to manually manage the updates.
  708. desc : str, optional
  709. Prefix for the progressbar.
  710. total : int or float, optional
  711. The number of expected iterations. If unspecified,
  712. len(iterable) is used if possible. If float("inf") or as a last
  713. resort, only basic progress statistics are displayed
  714. (no ETA, no progressbar).
  715. If `gui` is True and this parameter needs subsequent updating,
  716. specify an initial arbitrary large positive number,
  717. e.g. 9e9.
  718. leave : bool, optional
  719. If [default: True], keeps all traces of the progressbar
  720. upon termination of iteration.
  721. If `None`, will leave only if `position` is `0`.
  722. file : `io.TextIOWrapper` or `io.StringIO`, optional
  723. Specifies where to output the progress messages
  724. (default: sys.stderr). Uses `file.write(str)` and `file.flush()`
  725. methods. For encoding, see `write_bytes`.
  726. ncols : int, optional
  727. The width of the entire output message. If specified,
  728. dynamically resizes the progressbar to stay within this bound.
  729. If unspecified, attempts to use environment width. The
  730. fallback is a meter width of 10 and no limit for the counter and
  731. statistics. If 0, will not print any meter (only stats).
  732. mininterval : float, optional
  733. Minimum progress display update interval [default: 0.1] seconds.
  734. maxinterval : float, optional
  735. Maximum progress display update interval [default: 10] seconds.
  736. Automatically adjusts `miniters` to correspond to `mininterval`
  737. after long display update lag. Only works if `dynamic_miniters`
  738. or monitor thread is enabled.
  739. miniters : int or float, optional
  740. Minimum progress display update interval, in iterations.
  741. If 0 and `dynamic_miniters`, will automatically adjust to equal
  742. `mininterval` (more CPU efficient, good for tight loops).
  743. If > 0, will skip display of specified number of iterations.
  744. Tweak this and `mininterval` to get very efficient loops.
  745. If your progress is erratic with both fast and slow iterations
  746. (network, skipping items, etc) you should set miniters=1.
  747. ascii : bool or str, optional
  748. If unspecified or False, use unicode (smooth blocks) to fill
  749. the meter. The fallback is to use ASCII characters " 123456789#".
  750. disable : bool, optional
  751. Whether to disable the entire progressbar wrapper
  752. [default: False]. If set to None, disable on non-TTY.
  753. unit : str, optional
  754. String that will be used to define the unit of each iteration
  755. [default: it].
  756. unit_scale : bool or int or float, optional
  757. If 1 or True, the number of iterations will be reduced/scaled
  758. automatically and a metric prefix following the
  759. International System of Units standard will be added
  760. (kilo, mega, etc.) [default: False]. If any other non-zero
  761. number, will scale `total` and `n`.
  762. dynamic_ncols : bool, optional
  763. If set, constantly alters `ncols` and `nrows` to the
  764. environment (allowing for window resizes) [default: False].
  765. smoothing : float, optional
  766. Exponential moving average smoothing factor for speed estimates
  767. (ignored in GUI mode). Ranges from 0 (average speed) to 1
  768. (current/instantaneous speed) [default: 0.3].
  769. bar_format : str, optional
  770. Specify a custom bar string formatting. May impact performance.
  771. [default: '{l_bar}{bar}{r_bar}'], where
  772. l_bar='{desc}: {percentage:3.0f}%|' and
  773. r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '
  774. '{rate_fmt}{postfix}]'
  775. Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt,
  776. percentage, elapsed, elapsed_s, ncols, nrows, desc, unit,
  777. rate, rate_fmt, rate_noinv, rate_noinv_fmt,
  778. rate_inv, rate_inv_fmt, postfix, unit_divisor,
  779. remaining, remaining_s.
  780. Note that a trailing ": " is automatically removed after {desc}
  781. if the latter is empty.
  782. initial : int or float, optional
  783. The initial counter value. Useful when restarting a progress
  784. bar [default: 0]. If using float, consider specifying `{n:.3f}`
  785. or similar in `bar_format`, or specifying `unit_scale`.
  786. position : int, optional
  787. Specify the line offset to print this bar (starting from 0)
  788. Automatic if unspecified.
  789. Useful to manage multiple bars at once (eg, from threads).
  790. postfix : dict or *, optional
  791. Specify additional stats to display at the end of the bar.
  792. Calls `set_postfix(**postfix)` if possible (dict).
  793. unit_divisor : float, optional
  794. [default: 1000], ignored unless `unit_scale` is True.
  795. write_bytes : bool, optional
  796. If (default: None) and `file` is unspecified,
  797. bytes will be written in Python 2. If `True` will also write
  798. bytes. In all other cases will default to unicode.
  799. lock_args : tuple, optional
  800. Passed to `refresh` for intermediate output
  801. (initialisation, iterating, and updating).
  802. nrows : int, optional
  803. The screen height. If specified, hides nested bars outside this
  804. bound. If unspecified, attempts to use environment height.
  805. The fallback is 20.
  806. gui : bool, optional
  807. WARNING: internal parameter - do not use.
  808. Use tqdm.gui.tqdm(...) instead. If set, will attempt to use
  809. matplotlib animations for a graphical output [default: False].
  810. Returns
  811. -------
  812. out : decorated iterator.
  813. """
  814. if write_bytes is None:
  815. write_bytes = file is None and sys.version_info < (3,)
  816. if file is None:
  817. file = sys.stderr
  818. if write_bytes:
  819. # Despite coercing unicode into bytes, py2 sys.std* streams
  820. # should have bytes written to them.
  821. file = SimpleTextIOWrapper(
  822. file, encoding=getattr(file, 'encoding', None) or 'utf-8')
  823. if disable is None and hasattr(file, "isatty") and not file.isatty():
  824. disable = True
  825. if total is None and iterable is not None:
  826. try:
  827. total = len(iterable)
  828. except (TypeError, AttributeError):
  829. total = None
  830. if total == float("inf"):
  831. # Infinite iterations, behave same as unknown
  832. total = None
  833. if disable:
  834. self.iterable = iterable
  835. self.disable = disable
  836. with self._lock:
  837. self.pos = self._get_free_pos(self)
  838. self._instances.remove(self)
  839. self.n = initial
  840. self.total = total
  841. self.leave = leave
  842. return
  843. if kwargs:
  844. self.disable = True
  845. with self._lock:
  846. self.pos = self._get_free_pos(self)
  847. self._instances.remove(self)
  848. raise (
  849. TqdmDeprecationWarning(
  850. "`nested` is deprecated and automated.\n"
  851. "Use `position` instead for manual control.\n",
  852. fp_write=getattr(file, 'write', sys.stderr.write))
  853. if "nested" in kwargs else
  854. TqdmKeyError("Unknown argument(s): " + str(kwargs)))
  855. # Preprocess the arguments
  856. if ((ncols is None or nrows is None) and
  857. (file in (sys.stderr, sys.stdout))) or \
  858. dynamic_ncols: # pragma: no cover
  859. if dynamic_ncols:
  860. dynamic_ncols = _screen_shape_wrapper()
  861. if dynamic_ncols:
  862. ncols, nrows = dynamic_ncols(file)
  863. else:
  864. _dynamic_ncols = _screen_shape_wrapper()
  865. if _dynamic_ncols:
  866. _ncols, _nrows = _dynamic_ncols(file)
  867. if ncols is None:
  868. ncols = _ncols
  869. if nrows is None:
  870. nrows = _nrows
  871. if miniters is None:
  872. miniters = 0
  873. dynamic_miniters = True
  874. else:
  875. dynamic_miniters = False
  876. if mininterval is None:
  877. mininterval = 0
  878. if maxinterval is None:
  879. maxinterval = 0
  880. if ascii is None:
  881. ascii = not _supports_unicode(file)
  882. if bar_format and not ((ascii is True) or _is_ascii(ascii)):
  883. # Convert bar format into unicode since terminal uses unicode
  884. bar_format = _unicode(bar_format)
  885. if smoothing is None:
  886. smoothing = 0
  887. # Store the arguments
  888. self.iterable = iterable
  889. self.desc = desc or ''
  890. self.total = total
  891. self.leave = leave
  892. self.fp = file
  893. self.ncols = ncols
  894. self.nrows = nrows
  895. self.mininterval = mininterval
  896. self.maxinterval = maxinterval
  897. self.miniters = miniters
  898. self.dynamic_miniters = dynamic_miniters
  899. self.ascii = ascii
  900. self.disable = disable
  901. self.unit = unit
  902. self.unit_scale = unit_scale
  903. self.unit_divisor = unit_divisor
  904. self.lock_args = lock_args
  905. self.gui = gui
  906. self.dynamic_ncols = dynamic_ncols
  907. self.smoothing = smoothing
  908. self.avg_time = None
  909. self._time = time
  910. self.bar_format = bar_format
  911. self.postfix = None
  912. if postfix:
  913. try:
  914. self.set_postfix(refresh=False, **postfix)
  915. except TypeError:
  916. self.postfix = postfix
  917. # Init the iterations counters
  918. self.last_print_n = initial
  919. self.n = initial
  920. # if nested, at initial sp() call we replace '\r' by '\n' to
  921. # not overwrite the outer progress bar
  922. with self._lock:
  923. if position is None:
  924. self.pos = self._get_free_pos(self)
  925. else: # mark fixed positions as negative
  926. self.pos = -position
  927. if not gui:
  928. # Initialize the screen printer
  929. self.sp = self.status_printer(self.fp)
  930. self.refresh(lock_args=self.lock_args)
  931. # Init the time counter
  932. self.last_print_t = self._time()
  933. # NB: Avoid race conditions by setting start_t at the very end of init
  934. self.start_t = self.last_print_t
  935. def __bool__(self):
  936. if self.total is not None:
  937. return self.total > 0
  938. if self.iterable is None:
  939. raise TypeError('bool() undefined when iterable == total == None')
  940. return bool(self.iterable)
  941. def __nonzero__(self):
  942. return self.__bool__()
  943. def __len__(self):
  944. return self.total if self.iterable is None else \
  945. (self.iterable.shape[0] if hasattr(self.iterable, "shape")
  946. else len(self.iterable) if hasattr(self.iterable, "__len__")
  947. else getattr(self, "total", None))
  948. def __enter__(self):
  949. return self
  950. def __exit__(self, exc_type, exc_value, traceback):
  951. try:
  952. self.close()
  953. except AttributeError:
  954. # maybe eager thread cleanup upon external error
  955. if (exc_type, exc_value, traceback) == (None, None, None):
  956. raise
  957. warn("AttributeError ignored", TqdmWarning, stacklevel=2)
  958. def __del__(self):
  959. self.close()
  960. def __repr__(self):
  961. return self.format_meter(**self.format_dict)
  962. @property
  963. def _comparable(self):
  964. return abs(getattr(self, "pos", 1 << 31))
  965. def __hash__(self):
  966. return id(self)
  967. def __iter__(self):
  968. """Backward-compatibility to use: for x in tqdm(iterable)"""
  969. # Inlining instance variables as locals (speed optimisation)
  970. iterable = self.iterable
  971. # If the bar is disabled, then just walk the iterable
  972. # (note: keep this check outside the loop for performance)
  973. if self.disable:
  974. for obj in iterable:
  975. yield obj
  976. return
  977. mininterval = self.mininterval
  978. maxinterval = self.maxinterval
  979. miniters = self.miniters
  980. dynamic_miniters = self.dynamic_miniters
  981. last_print_t = self.last_print_t
  982. last_print_n = self.last_print_n
  983. n = self.n
  984. smoothing = self.smoothing
  985. avg_time = self.avg_time
  986. time = self._time
  987. if not hasattr(self, 'sp'):
  988. raise TqdmDeprecationWarning(
  989. "Please use `tqdm.gui.tqdm(...)` instead of"
  990. " `tqdm(..., gui=True)`\n",
  991. fp_write=getattr(self.fp, 'write', sys.stderr.write))
  992. try:
  993. for obj in iterable:
  994. yield obj
  995. # Update and possibly print the progressbar.
  996. # Note: does not call self.update(1) for speed optimisation.
  997. n += 1
  998. # check counter first to avoid calls to time()
  999. if n - last_print_n >= self.miniters:
  1000. miniters = self.miniters # watch monitoring thread changes
  1001. delta_t = time() - last_print_t
  1002. if delta_t >= mininterval:
  1003. cur_t = time()
  1004. delta_it = n - last_print_n
  1005. # EMA (not just overall average)
  1006. if smoothing and delta_t and delta_it:
  1007. rate = delta_t / delta_it
  1008. avg_time = self.ema(rate, avg_time, smoothing)
  1009. self.avg_time = avg_time
  1010. self.n = n
  1011. self.refresh(lock_args=self.lock_args)
  1012. # If no `miniters` was specified, adjust automatically
  1013. # to the max iteration rate seen so far between 2 prints
  1014. if dynamic_miniters:
  1015. if maxinterval and delta_t >= maxinterval:
  1016. # Adjust miniters to time interval by rule of 3
  1017. if mininterval:
  1018. # Set miniters to correspond to mininterval
  1019. miniters = delta_it * mininterval / delta_t
  1020. else:
  1021. # Set miniters to correspond to maxinterval
  1022. miniters = delta_it * maxinterval / delta_t
  1023. elif smoothing:
  1024. # EMA-weight miniters to converge
  1025. # towards the timeframe of mininterval
  1026. rate = delta_it
  1027. if mininterval and delta_t:
  1028. rate *= mininterval / delta_t
  1029. miniters = self.ema(rate, miniters, smoothing)
  1030. else:
  1031. # Maximum nb of iterations between 2 prints
  1032. miniters = max(miniters, delta_it)
  1033. # Store old values for next call
  1034. self.n = self.last_print_n = last_print_n = n
  1035. self.last_print_t = last_print_t = cur_t
  1036. self.miniters = miniters
  1037. finally:
  1038. # Closing the progress bar.
  1039. # Update some internal variables for close().
  1040. self.last_print_n = last_print_n
  1041. self.n = n
  1042. self.miniters = miniters
  1043. self.close()
  1044. def update(self, n=1):
  1045. """
  1046. Manually update the progress bar, useful for streams
  1047. such as reading files.
  1048. E.g.:
  1049. >>> t = tqdm(total=filesize) # Initialise
  1050. >>> for current_buffer in stream:
  1051. ... ...
  1052. ... t.update(len(current_buffer))
  1053. >>> t.close()
  1054. The last line is highly recommended, but possibly not necessary if
  1055. `t.update()` will be called in such a way that `filesize` will be
  1056. exactly reached and printed.
  1057. Parameters
  1058. ----------
  1059. n : int or float, optional
  1060. Increment to add to the internal counter of iterations
  1061. [default: 1]. If using float, consider specifying `{n:.3f}`
  1062. or similar in `bar_format`, or specifying `unit_scale`.
  1063. """
  1064. # N.B.: see __iter__() for more comments.
  1065. if self.disable:
  1066. return
  1067. if n < 0:
  1068. self.last_print_n += n # for auto-refresh logic to work
  1069. self.n += n
  1070. # check counter first to reduce calls to time()
  1071. if self.n - self.last_print_n >= self.miniters:
  1072. delta_t = self._time() - self.last_print_t
  1073. if delta_t >= self.mininterval:
  1074. cur_t = self._time()
  1075. delta_it = self.n - self.last_print_n # >= n
  1076. # elapsed = cur_t - self.start_t
  1077. # EMA (not just overall average)
  1078. if self.smoothing and delta_t and delta_it:
  1079. rate = delta_t / delta_it
  1080. self.avg_time = self.ema(
  1081. rate, self.avg_time, self.smoothing)
  1082. if not hasattr(self, "sp"):
  1083. raise TqdmDeprecationWarning(
  1084. "Please use `tqdm.gui.tqdm(...)`"
  1085. " instead of `tqdm(..., gui=True)`\n",
  1086. fp_write=getattr(self.fp, 'write', sys.stderr.write))
  1087. self.refresh(lock_args=self.lock_args)
  1088. # If no `miniters` was specified, adjust automatically to the
  1089. # maximum iteration rate seen so far between two prints.
  1090. # e.g.: After running `tqdm.update(5)`, subsequent
  1091. # calls to `tqdm.update()` will only cause an update after
  1092. # at least 5 more iterations.
  1093. if self.dynamic_miniters:
  1094. if self.maxinterval and delta_t >= self.maxinterval:
  1095. if self.mininterval:
  1096. self.miniters = delta_it * self.mininterval \
  1097. / delta_t
  1098. else:
  1099. self.miniters = delta_it * self.maxinterval \
  1100. / delta_t
  1101. elif self.smoothing:
  1102. self.miniters = self.smoothing * delta_it * \
  1103. (self.mininterval / delta_t
  1104. if self.mininterval and delta_t
  1105. else 1) + \
  1106. (1 - self.smoothing) * self.miniters
  1107. else:
  1108. self.miniters = max(self.miniters, delta_it)
  1109. # Store old values for next call
  1110. self.last_print_n = self.n
  1111. self.last_print_t = cur_t
  1112. def close(self):
  1113. """Cleanup and (if leave=False) close the progressbar."""
  1114. if self.disable:
  1115. return
  1116. # Prevent multiple closures
  1117. self.disable = True
  1118. # decrement instance pos and remove from internal set
  1119. pos = abs(self.pos)
  1120. self._decr_instances(self)
  1121. # GUI mode
  1122. if not hasattr(self, "sp"):
  1123. return
  1124. # annoyingly, _supports_unicode isn't good enough
  1125. def fp_write(s):
  1126. self.fp.write(_unicode(s))
  1127. try:
  1128. fp_write('')
  1129. except ValueError as e:
  1130. if 'closed' in str(e):
  1131. return
  1132. raise # pragma: no cover
  1133. leave = pos == 0 if self.leave is None else self.leave
  1134. with self._lock:
  1135. if leave:
  1136. # stats for overall rate (no weighted average)
  1137. self.avg_time = None
  1138. self.display(pos=0)
  1139. fp_write('\n')
  1140. else:
  1141. # clear previous display
  1142. if self.display(msg='', pos=pos) and not pos:
  1143. fp_write('\r')
  1144. def clear(self, nolock=False):
  1145. """Clear current bar display."""
  1146. if self.disable:
  1147. return
  1148. if not nolock:
  1149. self._lock.acquire()
  1150. pos = abs(self.pos)
  1151. if pos < (self.nrows or 20):
  1152. self.moveto(pos)
  1153. self.sp('')
  1154. self.fp.write('\r') # place cursor back at the beginning of line
  1155. self.moveto(-pos)
  1156. if not nolock:
  1157. self._lock.release()
  1158. def refresh(self, nolock=False, lock_args=None):
  1159. """
  1160. Force refresh the display of this bar.
  1161. Parameters
  1162. ----------
  1163. nolock : bool, optional
  1164. If `True`, does not lock.
  1165. If [default: `False`]: calls `acquire()` on internal lock.
  1166. lock_args : tuple, optional
  1167. Passed to internal lock's `acquire()`.
  1168. If specified, will only `display()` if `acquire()` returns `True`.
  1169. """
  1170. if self.disable:
  1171. return
  1172. if not nolock:
  1173. if lock_args:
  1174. if not self._lock.acquire(*lock_args):
  1175. return False
  1176. else:
  1177. self._lock.acquire()
  1178. self.display()
  1179. if not nolock:
  1180. self._lock.release()
  1181. return True
  1182. def unpause(self):
  1183. """Restart tqdm timer from last print time."""
  1184. cur_t = self._time()
  1185. self.start_t += cur_t - self.last_print_t
  1186. self.last_print_t = cur_t
  1187. def reset(self, total=None):
  1188. """
  1189. Resets to 0 iterations for repeated use.
  1190. Consider combining with `leave=True`.
  1191. Parameters
  1192. ----------
  1193. total : int or float, optional. Total to use for the new bar.
  1194. """
  1195. self.last_print_n = self.n = 0
  1196. self.last_print_t = self.start_t = self._time()
  1197. if total is not None:
  1198. self.total = total
  1199. self.refresh()
  1200. def set_description(self, desc=None, refresh=True):
  1201. """
  1202. Set/modify description of the progress bar.
  1203. Parameters
  1204. ----------
  1205. desc : str, optional
  1206. refresh : bool, optional
  1207. Forces refresh [default: True].
  1208. """
  1209. self.desc = desc + ': ' if desc else ''
  1210. if refresh:
  1211. self.refresh()
  1212. def set_description_str(self, desc=None, refresh=True):
  1213. """Set/modify description without ': ' appended."""
  1214. self.desc = desc or ''
  1215. if refresh:
  1216. self.refresh()
  1217. def set_postfix(self, ordered_dict=None, refresh=True, **kwargs):
  1218. """
  1219. Set/modify postfix (additional stats)
  1220. with automatic formatting based on datatype.
  1221. Parameters
  1222. ----------
  1223. ordered_dict : dict or OrderedDict, optional
  1224. refresh : bool, optional
  1225. Forces refresh [default: True].
  1226. kwargs : dict, optional
  1227. """
  1228. # Sort in alphabetical order to be more deterministic
  1229. postfix = _OrderedDict([] if ordered_dict is None else ordered_dict)
  1230. for key in sorted(kwargs.keys()):
  1231. postfix[key] = kwargs[key]
  1232. # Preprocess stats according to datatype
  1233. for key in postfix.keys():
  1234. # Number: limit the length of the string
  1235. if isinstance(postfix[key], Number):
  1236. postfix[key] = self.format_num(postfix[key])
  1237. # Else for any other type, try to get the string conversion
  1238. elif not isinstance(postfix[key], _basestring):
  1239. postfix[key] = str(postfix[key])
  1240. # Else if it's a string, don't need to preprocess anything
  1241. # Stitch together to get the final postfix
  1242. self.postfix = ', '.join(key + '=' + postfix[key].strip()
  1243. for key in postfix.keys())
  1244. if refresh:
  1245. self.refresh()
  1246. def set_postfix_str(self, s='', refresh=True):
  1247. """
  1248. Postfix without dictionary expansion, similar to prefix handling.
  1249. """
  1250. self.postfix = str(s)
  1251. if refresh:
  1252. self.refresh()
  1253. def moveto(self, n):
  1254. # TODO: private method
  1255. self.fp.write(_unicode('\n' * n + _term_move_up() * -n))
  1256. self.fp.flush()
  1257. @property
  1258. def format_dict(self):
  1259. """Public API for read-only member access."""
  1260. if self.dynamic_ncols:
  1261. self.ncols, self.nrows = self.dynamic_ncols(self.fp)
  1262. ncols, nrows = self.ncols, self.nrows
  1263. return dict(
  1264. n=self.n, total=self.total,
  1265. elapsed=self._time() - self.start_t
  1266. if hasattr(self, 'start_t') else 0,
  1267. ncols=ncols, nrows=nrows,
  1268. prefix=self.desc, ascii=self.ascii, unit=self.unit,
  1269. unit_scale=self.unit_scale,
  1270. rate=1 / self.avg_time if self.avg_time else None,
  1271. bar_format=self.bar_format, postfix=self.postfix,
  1272. unit_divisor=self.unit_divisor)
  1273. def display(self, msg=None, pos=None):
  1274. """
  1275. Use `self.sp` to display `msg` in the specified `pos`.
  1276. Consider overloading this function when inheriting to use e.g.:
  1277. `self.some_frontend(**self.format_dict)` instead of `self.sp`.
  1278. Parameters
  1279. ----------
  1280. msg : str, optional. What to display (default: `repr(self)`).
  1281. pos : int, optional. Position to `moveto`
  1282. (default: `abs(self.pos)`).
  1283. """
  1284. if pos is None:
  1285. pos = abs(self.pos)
  1286. nrows = self.nrows or 20
  1287. if pos >= nrows - 1:
  1288. if pos >= nrows:
  1289. return False
  1290. if msg or msg is None: # override at `nrows - 1`
  1291. msg = " ... (more hidden) ..."
  1292. if pos:
  1293. self.moveto(pos)
  1294. self.sp(self.__repr__() if msg is None else msg)
  1295. if pos:
  1296. self.moveto(-pos)
  1297. return True
  1298. @classmethod
  1299. @contextmanager
  1300. def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs):
  1301. """
  1302. stream : file-like object.
  1303. method : str, "read" or "write". The result of `read()` and
  1304. the first argument of `write()` should have a `len()`.
  1305. >>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj:
  1306. ... while True:
  1307. ... chunk = fobj.read(chunk_size)
  1308. ... if not chunk:
  1309. ... break
  1310. """
  1311. with cls(total=total, **tqdm_kwargs) as t:
  1312. if bytes:
  1313. t.unit = "B"
  1314. t.unit_scale = True
  1315. t.unit_divisor = 1024
  1316. yield CallbackIOWrapper(t.update, stream, method)
  1317. def trange(*args, **kwargs):
  1318. """
  1319. A shortcut for tqdm(xrange(*args), **kwargs).
  1320. On Python3+ range is used instead of xrange.
  1321. """
  1322. return tqdm(_range(*args), **kwargs)