Jump to content

Progress Bar


jeffsui

Recommended Posts

  • 3 weeks later...
  • 4 months later...

Could you provide an explanation on this function?

 

def string_from_count(c):
	"""Returns a fancy string to show in the workflow from the count item"""

	blue  = "\\U0001F535\\U0000FE0F"
	white = "\\U000026AA\\U0000FE0F"
	black = "\\U000026AB\\U0000FE0F"

	ret = black + black + black + black + black + white + black + black + black + black + black

	mod = 2 * (5 - (c % 5))

	return ret.decode('unicode_escape')[mod:][0:10]

 

Link to post

First of all, there's a lot of unnecessary code in the function. There's no need to manipulate then decode byte strings: just use Unicode. The \U0000FE0F characters are also unnecessary. They mean "display the previous character in full colour" (technically, "in emoji mode"), which is the default behaviour on OS X.

 

So here's a simplified, more Pythonic version that does the same thing:

# length of progress bar
BAR_SIZE = 5


def progress_bar(n):
    """Wrap-around Unicode progress bar."""
    # create all-black bar of BAR_SIZE length
    bar = [u'\U000026AB'] * BAR_SIZE
    # get index between 0 and BAR_SIZE - 1
    i = n % BAR_SIZE
    # replace "current" character with white ball
    bar[i] = u'\U000026AA'
    # combine to a single Unicode string
    return u''.join(bar)


for i in range(100):
    print(progress_bar(i))

 

The basic idea is that for n+1 you get a new progress bar with the white ball shifted one position to the right (or back to first position if it's already at the end).

 

The critical code is i = n % BAR_SIZE.

 

n % 5 is the remainder of n divided by 5, so it always "wraps around" to a number from 0 to 4, i.e. 1 % 5 = 1, 2 % 5 = 25 % 5 = 0 and 6 % 5 = 1.

 

So regardless of whether n = 1 or n = 200000, i will always be between 0 and BAR_SIZE - 1 (i.e. the index of one of the balls in the bar), and n+1 will give you i+1 (or i = 0 if n is a multiple of BAR_SIZE).

Link to post

FWIW, this technique is very useful for displaying "spinners" in a shell:

from __future__ import print_function
import sys
import time


# progress bar characters
SPINNER = r'-\|/'


for i in range(100):
    # get "next" character index
    j = i % len(SPINNER)
    # write character & message plus carriage return to
    # move cursor back to start of line
    msg = ' {} {:2d}% ...'.format(SPINNER[j], i)
    print(msg, end='\r')
    # flush buffer so spinner is displayed
    sys.stdout.flush()
    time.sleep(0.1)
# add extra whitespace to ensure previous message
# is fully overwritten
print('done' + ' ' * len(msg))

 

Link to post

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...