File size: 3,232 Bytes
ba5dcdc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
'''
Utilities for showing progress bars, controlling default verbosity, etc.
'''

# If the tqdm package is not available, then do not show progress bars;
# just connect print_progress to print.
try:
    from tqdm import tqdm, tqdm_notebook
except:
    tqdm = None

default_verbosity = False

def verbose_progress(verbose):
    '''
    Sets default verbosity level.  Set to True to see progress bars.
    '''
    global default_verbosity
    default_verbosity = verbose

def tqdm_terminal(it, *args, **kwargs):
    '''
    Some settings for tqdm that make it run better in resizable terminals.
    '''
    return tqdm(it, *args, dynamic_ncols=True, ascii=True,
            leave=(not nested_tqdm()), **kwargs)

def in_notebook():
    '''
    True if running inside a Jupyter notebook.
    '''
    # From https://stackoverflow.com/a/39662359/265298
    try:
        shell = get_ipython().__class__.__name__
        if shell == 'ZMQInteractiveShell':
            return True   # Jupyter notebook or qtconsole
        elif shell == 'TerminalInteractiveShell':
            return False  # Terminal running IPython
        else:
            return False  # Other type (?)
    except NameError:
        return False      # Probably standard Python interpreter

def nested_tqdm():
    '''
    True if there is an active tqdm progress loop on the stack.
    '''
    return hasattr(tqdm, '_instances') and len(tqdm._instances) > 0

def post_progress(**kwargs):
    '''
    When within a progress loop, post_progress(k=str) will display
    the given k=str status on the right-hand-side of the progress
    status bar.  If not within a visible progress bar, does nothing.
    '''
    if nested_tqdm():
        innermost = max(tqdm._instances, key=lambda x: x.pos)
        innermost.set_postfix(**kwargs)

def desc_progress(desc):
    '''
    When within a progress loop, desc_progress(str) changes the
    left-hand-side description of the loop toe the given description.
    '''
    if nested_tqdm():
        innermost = max(tqdm._instances, key=lambda x: x.pos)
        innermost.set_description(desc)

def print_progress(*args):
    '''
    When within a progress loop, post_progress(k=str) will display
    the given k=str status on the right-hand-side of the progress
    status bar.  If not within a visible progress bar, does nothing.
    '''
    if default_verbosity:
        printfn = print if tqdm is None else tqdm.write
        printfn(' '.join(str(s) for s in args))

def default_progress(verbose=None, iftop=False):
    '''
    Returns a progress function that can wrap iterators to print
    progress messages, if verbose is True.
   
    If verbose is False or if iftop is True and there is already
    a top-level tqdm loop being reported, then a quiet non-printing
    identity function is returned.

    verbose can also be set to a spefific progress function rather
    than True, and that function will be used.
    '''
    global default_verbosity
    if verbose is None:
        verbose = default_verbosity
    if not verbose or (iftop and nested_tqdm()) or tqdm is None:
        return lambda x, *args, **kw: x
    if verbose == True:
        return tqdm_notebook if in_notebook() else tqdm_terminal
    return verbose