Jump to content
jeffsui

Progress Bar

Recommended Posts

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]

 

Share this post


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

Edited by deanishe
Make explanation clearer (hopefully)

Share this post


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

 

Edited by deanishe
Correct comment

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...