Console

This module contains classes that print things to the terminal during execution. Most of them are meant to be used as decorators of a for statement, where they can help track where you are in the loop.

You can also use them manually to customise behaviour within a loop or anywhere else in your scripts.

Wheel

Use Wheel as an iterable’s decoration to have a turning wheel printed during a for loop, turning as fast as the iterations go. By default the iteration index is printed next to the wheel, but you can choose to print the iteration value instead of the iteration index with argument print_value = True.

When used over a standard range(n), it accepts n as an argument for the iterable.

from pyux.console import Wheel
from time import sleep

myrange = 'An iterable string'
for step in Wheel(myrange, print_value = True):
   sleep(0.2)

for step in Wheel(20):
   sleep(0.1)

If you must, you can also instantiate Wheel outside of a loop then trigger it manually. It is useful mainly to customise the message you want to print.

Note that when using it manually, you may want to close the wheel when you’re done : it prints the length of the iterable or a message if provided, and flushes a new line. Otherwise the console cursor is still on the previous line. When decorating a for loop, it is automatically called when the loop finishes.

from time import sleep
from pyux.console import Wheel

wheel = Wheel()                  # no need for an iterator argument in that case
for index, word in enumerate(['coffee', 'vanilla', 'cocoa']):
    wheel.print(step = index, message = 'Running on word %s            ' % word)
    sleep(1)                  # renders best if iterations are not too fast
wheel.close(message = 'No more words to think about.')

Wheel can also be used to decorate a generator object rather than an iterable, which is especially useful with os.walk(), for instance, to know both if your script is still running and the total number of read paths. This also makes it compatible with enumerate().

Speak and wordy

wordy is a decorator function that prints a message at each call of the decorated function. You can catch exceptions from the decorated function with catch = True and print a specific message when the exception is catch.

By default, . is printed if the call is successful, and ! if it isn’t, allowing easy and concise error tracking within loops. When catching an exception, the exception is returned in place of the function response.

from pyux.console import wordy

@wordy(catch = True, failure_message = 'x')
def error_4(x):
    if x == 4:
        raise ValueError
[error_4(x) for x in range(10)]

Class Speak does roughly the same as wordy, but decorates an iterable in a for loop rather than a function. It thus prints a message at each iteration or every given number of iterations. It does not provide any exception catching environment. For that, you’ll have to decorate the function which you want to catch from with wordy instead of using Speak.

As for all other iterable’s decorators in this package, standard range(n) iterables can be given with just n as the iterable argument.

from pyux.console import Speak

for x in Speak(45, every = 5):
    pass

Both wordy and Speak print their messages with sys.stdout.write(), and not print(), so that the console cursor can stay on the same line within the same loop. When using Speak on an iterable in a for loop, a close() method is automatically called when the loop finished to flush a new line. When used manually, you’ll have to flush \n (or print('')) to make the cursor go to the new line.

ProgressBar

Use ProgressBar as an iteratable’s decoration to have a progress bar printed during a for loop. It mimics, in a extremely simplified way, the behavior of the great tqdm progress bar. As for Wheel, you can also use it manually.

Integers for iterable argument are read as range(n).

from pyux.console import ProgressBar
from time import sleep

for index in ProgressBar(2500):
    sleep(0.001)

Since ProgressBar needs to know at initialisation the total number of iterations (to calculate the bar’s width and the percentage), it is not usable with generators. A workaround is to give it an approximate number of iterations as iterable argument, and use it manually. Careful though, should the approximation be too short, the bar will expand further than the console width (or never reach 100% if too big).

from pyux.console import ProgressBar
from time import sleep

def simple_generator(n):
   for i in range(n):
      yield i

bar = ProgressBar(1000)
for value in simple_generator(1200):
   sleep(0.002)
   bar.print(step = value)
print('Too long !')

bar.current_console_step = 0    # resetting bar to zero
for value in simple_generator(800):
    sleep(0.002)
    bar.print(step = value)
print('Too short !')

A manual ProgressBar can also be used to track progression on scripts with distinct stages that are not necessarily in the form of a loop, should there be so many of them that it makes sense.

Do use ProgressBar.close() method to be sure that the 100% iteration will be printed and the console cursor flushed to a new line when you use it manually. When decorating a for statement, it is automatically called when the loop finishes.

bar = ProgressBar()

# here goes stage 1
bar.print(step = 1)

# here goes ...
bar.print(step = ...)

bar.close()

ColourPen

Use ColourPen as its name indicates : to write colored text in terminal. It uses colorama package. Use a single instance for different styles thanks to the possibility of chaining write instructions.

from pyux.console import ColourPen

pen = ColourPen()
pen.write('Hello', color = 'cyan', style = 'normal')\
    .write(' this is another', color = 'red')\
    .write(' color on the same line.', color = 'green', newline = True)\
    .write("The same color on a new line. I'm reseting styles after that.", newline = True, reset = True)\
    .write('A normal goodbye.')\
    .close()

ColourPen.close() resets styles to normal, flushes to a new line and closes colorama, which means that if you do not initialise a pen instance again, the colouring and styling won’t work anymore.

Detailed documentation

class pyux.console.ColourPen

Bases: object

Write colored and styled messages in console.

Only one pen instance is needed to print texts with different styles. By default, styles and colours remain the same until changed or reset, allowing to write successive prints with the same format, without having to specify format at each call.

Available colors are :

  • black
  • red
  • green
  • yellow
  • blue
  • magenta
  • cyan
  • white
  • reset (to reset color to default)

Available styles are :

  • dim (thin)
  • normal
  • bright
  • reset_all (to reset both color and style)

Any other value will raise a ColorValueError or a StyleValueError.

Example:
>>> pen = ColourPen()
>>> pen.write('A blue bright message', color = 'cyan', style = 'bright')
>>> pen.write('Still a blue message', reset = True, newline = True)
>>> pen.write('That message is back to normal')
>>> pen.close()
close() → None

Reset all styles and close colorama util.

The method flushes an empty message with reset styles and a new line. Closing make the sys.stdout go back to normal : styling and colouring will not be recognised after it.

write(message: str = '', color: str = None, style: str = None, flush: bool = True, newline: bool = False, reset: bool = False)

Write a colored and styled message.

The method returns self so that calls to the method can be chained from a single instance.

Parameters:
  • message (str) – default '' : the message to write
  • color (str) – default None : the colour to use, checked against possible values
  • style (str) – default None : the style to use, checked against possible values
  • flush (bool) – default True : flush the message to the console
  • newline (bool) – default False : insert a new line after the message
  • reset (bool) – default False : reset style and colour after writing the message

The default behavior is to pass on current style to subsequent calls, so you only need to style and colour once if you want to keep the same format for following messages. This is accomplished through None values given for the color and/or style arguments, which means that giving None does not ignore style and color !

To remove style for the message to print, use style = 'RESET_ALL'. To remove style after printing the styled message, use reset = True.

Message is printed with sys.stdout.write() rather than print(), allowing precise control over where to print in the console. The default behavior is to flush at each print and to keep the console cursor where it is.

You can decide to “write” several messages and flush them all at once, and you can add a newline after a message to get the equivalent of a print() statement.

Returns:self
Raises:ColorValueError, StyleValueError
Example:
>>> pen = ColourPen()
>>> pen.write('Hello... ', color = 'cyan')        >>>     .write('Goodbye !', reset = True, newline = True)
class pyux.console.ProgressBar(iterable=None, ascii_only: bool = False)

Bases: object

Print a progress bar with progression percentage and number of iterations.

ProgressBar is meant to be used as a decorator in a for statement : for each iteration, it prints the percentage of progress, the number of iterations against the total number of iterations to do, and a progress bar.

Parameters:
  • iterable (iterable or int) – default None : an iterable, or an integer for standard range(n) values
  • ascii_only (bool) – Use ascii character = to print the bar

A progress bar can also be created manually if you want to call it outside of a for statement. However it still needs an iterable to know the total number of iterations. This means it cannot be used with generators.

A workaround if you really want to use it even if you don’t know how long the iteration will last, give an approximation as an integer to the iterable argument. This might cause unwanted behaviour in console, especially if your approximation is too short.

Raise:TypeError if iterable is not an iterable
Example:
>>> from time import sleep
>>> for _ in ProgressBar(3000, ascii_only = True):
>>>     sleep(0.001)
close() → None

Print the bar with 100% completion.

When the for loop has finished, this prints a last progress bar with 100% completion. This method is automatically called at the end of a for loop when ProgressBar decorates a for statement.

Without closing, the iteration index would end just before reaching 100% due to index starting from zero rather than one.

Example:
>>> ProgressBar(iterable = 'A string iterable').close()
print(step: int) → None

Print the progress bar for the current iteration.

class pyux.console.Speak(iterable=None, every: int = 1, message: str = '.', newline: bool = False)

Bases: object

Print a message after each iteration or every n iterations.

This class decorates an iterable in a for statement by printing a message either after each iteration, or after a given amount of iterations.

Parameters:
  • iterable (iterable or int) – default None : an iterable, or an integer for standard range(n) values
  • every (int) – default 1 : frequency of printing messages
  • message (str) – default '.' : message to print
  • newline (bool) – default False : flushes a new line after printing

Printing is done with sys.stdout, so that the default behavior is to keep the console cursor on the current line. To print the message on a newline at each step, use newline = True.

Example:
>>> for _ in Speak(50, every = 5, message = '*'):
>>>     pass
close() → None

Flush a new line when self.newline = False.

This method is automatically called when the for loop finishes, so that the console cursor starts a new line when the loop is over.

Returns:None
class pyux.console.Wheel(iterable=None, print_value: bool = False)

Bases: object

Print a wheel turning at the same speed as iterations.

This class decorates an iterable in a for statement by printing a turning wheel and the iteration index at each step.

Parameters:
  • iterable (iterable or int) – default None : an iterable, or an integer for standard range(n) values
  • print_value (bool) – default False : print the iteration value instead of the iteration index next to the wheel

Wheel can also be used manually (without iterable), which is useful if you need to print messages different than the iteration value or index. It is compatible with generators, which makes it a good indicator that the code is still running when you do not know the total number of iterations beforehand.

Raise:TypeError if iterable is not an iterable
Example:
>>> for _ in Wheel(['a', 'b', 'c', 'd']):    # print the index
>>> for _ in Wheel(5):                       # same behaviour than previous
>>> for letter in Wheel(['a', 'b', 'c', 'd'], print_value = True):
>>>     # this whill print the iteration value (letters)
>>>     # rather than the iteration index
close(message: str = None) → None

Print the wheel for the last iteration then flush console.

This method makes the last printed value equal to the number of iterations. If a message is provided, it is printed instead of the former.

Parameters:message (str) – default None : message to print next to the wheel

This method is automatically called when the wheel is used as decorator of an iterable in a for statement.

When close is called with no iterable given as argument at class instanciation, it will print 0 since a missing iterable as argument is internally seen as an iterable of length zero. A workaround is to use close(message = '') if you want the last printed value to stay, or any other message if you want it to be replaced by a closing message.

Example:
>>> wheel = Wheel(iterable = 'A string iterable')
>>> wheel.close()
>>> wheel.close(message = 'Overriding length of iterable')
static print(step: int, message: str = None) → None

Print the wheel for a given step and message.

pyux.console.wordy(message: str = '.', catch: bool = False, failure_message: str = '!', colors: tuple = None)

Print a message at each function call.

A decorator to print a message at each function call with sys.stdout. Exceptions can be catch and returned as the function’s result, or raised. If an exception is catch, a specific message can be printed.

Parameters:
  • message (str) – default '.' : message to print after function call
  • catch (bool) – default False : catch an exception from the decorated function rather than raising it
  • failure_message (str) – default '!' : message to print if an exception is catch during function call
  • colors (tuple) – default None : a tuple of one or two colors for the the printed messages
Returns:

a function decorated with a printed message after execution

Both message and failure_message can be printed (internally using ColourPen). If colors is not specified, standard terminal tex color will be used. When catch = True, if specified, the colors tuple must be of length two.

Example:
>>> @wordy()
>>> def one():
>>>     return 1
>>> [one() for _ in range(10)]