7
\$\begingroup\$

For a game I am writing in Python 3.6.5, I made a text-based animation to indicate the passage of time (when chopping a tree or mining a rock, etc). I did a lot of trial and error to get the output how I wanted it, however it seems like I went about it in an overly-complicated way. I was wondering if there is a more efficient way to write this.

import os
import time


def progress_bar(text,secs):
    bar = '['
    c = 0 #used in sum method to determine number of Xs in bar

    for i in range(0,11):
        print(text+'\n')
        bar = bar.replace(' ','') #get rid of previous spaces added to bar
        num_of_X = sum(c == 'X' for c in bar) #get number of Xs (progress)
        for x in range(0,(10 - num_of_X)): #Fill remaining space after Xs
            bar += ' '
        print(bar + ']') 
        bar += 'X'
        time.sleep(secs)
        os.system('cls' if os.name == 'nt' else 'clear') #clears terminal

    input('Loading complete!')

progress_bar('Enter Your Text Here!',0.15)
\$\endgroup\$
6
\$\begingroup\$
  1. You can use bar.count rather than your sum
  2. You can use ' ' * n, rather than your for loop.
  3. You don't need [ in your bar.
  4. You don't need to add whitespace, str.format can do that for you.

    >>> '[{:<10}]'.format('XX')
    '[XX        ]'
    
  5. You don't need the bar variable.

  6. I'd move the input out of the function, as it doesn't have much to do with the bar.
  7. You could change the size of the bar with another argument.
def progress_bar(text, secs, size=10):
    for i in range(size + 1):
        print('{}\n\n[{:<{}}]'.format(text, 'X' * i, size))
        time.sleep(secs)
        os.system('cls' if os.name == 'nt' else 'clear')

You can also remove the need for os if your terminal support \r. This will mean that you can remove text from the function too, as IMO it shouldn't really be there either.

def progress_bar(secs, size=10):
    for i in range(size + 1):
        print('\r[{:<{}}]'.format('X' * i, size), end='', flush=True)
        time.sleep(secs)
    print()

print('Your text here!\n')
progress_bar(0.15)
input('>')

Alternately you can use \b, this is better if you want to allow text like bar: [].

def progress_bar(secs, size=10):
    for i in range(size + 1):
        print('[{:<{}}]{}'.format('X' * i, size, '\b' * (size + 2)), end='', flush=True)
        time.sleep(secs)
    print()

print('bar: ', end='', flush=True)
progress_bar(0.15)
input('>')
\$\endgroup\$
  • \$\begingroup\$ I need to learn more about string formatting as you've shown me. I will dive into it now, very helpful answer. Thank you! \$\endgroup\$ – ShroomBandit May 22 '18 at 20:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.