Jump to content

Progress Bar


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 comment

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).

Edited by deanishe
Make explanation clearer (hopefully)
Link to comment

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))

 

Edited by deanishe
Correct comment
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...