2

I am trying to make a fake boot sequence in Python, and one of the elements is a progress bar. The progress bar should stay on one line, instead of repetitively printing over multiple lines. After some time, I had created this code:

from time import sleep
import random

def progressbar(title, length):
    add = 0
    strlength = len(title) + 3
    barlength = '['
    for i in range(length - 1):
        barlength = barlength + '.'
    barlength = barlength + ']'
    progress = title + ': ' + barlength
    for i in range(length):
        print(progress, end='\r')
        append = add + strlength
        progress = list(progress)
        progress[append] = '#'
        progress = str(''.join(progress))
        sleep(random.uniform(0.2, 1.0))
        add = add + 1

print("Username: TestUserABC, Password: password1")
sleep(1)
print('---[STARTING BOOT SEQUENCE]---')
print(':-Welcome to GMOS (Generic Movie Operating System)-:')
progressbar('Checking Filesystem', 10)

However, instead of overwriting one line, it outputs this:

Username: TestUserABC, Password: password1
---[STARTING BOOT SEQUENCE]---
:-Welcome to GMOS (Generic Movie Operating System)-:
Checking Filesystem: [.........]Checking Filesystem: [#........]Checking Filesystem: 
[##.......]Checking Filesystem: [###......]Checking Filesystem: [####.....]Checking Filesystem: 
[#####....]Checking Filesystem: [######...]Checking Filesystem: [#######..]Checking Filesystem: 
[########.]Checking Filesystem: [#########]

I would appreciate any help, as I have no idea what could have caused this. For clarity, I am on Windows 10, just in case the string... things are different between OSs, which I doubt for this kind of thing. (Can somebody tell me what things like \n or \r are called?)

2 Answers2

1

This can be accomplished by using the "sys.stdout.flush()". You can read more about this function here: https://www.geeksforgeeks.org/python-sys-stdout-flush/

Usage example with your code:

from time import sleep
import random
import sys

def progressbar(title, length):
    add = 0
    strlength = len(title) + 3
    barlength = '['
    for i in range(length - 1):
        barlength = barlength + '.'
    barlength = barlength + ']'
    progress = title + ': ' + barlength
    for i in range(length):
        print(progress, end='\r')
        sys.stdout.flush()
        append = add + strlength
        progress = list(progress)
        progress[append] = '#'
        progress = str(''.join(progress))
        sleep(random.uniform(0.2, 1.0))
        add = add + 1

print("Username: TestUserABC, Password: password1")
sleep(1)
print('---[STARTING BOOT SEQUENCE]---')
print(':-Welcome to GMOS (Generic Movie Operating System)-:')
progressbar('Checking Filesystem', 10)
print('')

Added:

  • import sys
  • sys.stdout.flush()
  • print('')
0

This (simplified) code works for me:

from time import sleep
import random

def progressbar(title, length):
    progress = ['.' for _ in range(10)]
    
    print(f"\r{title}: [{''.join(progress)}]", end='', flush=True)
    for i in range(10):
        print(f"\r{title}: [{''.join(progress)}]", end='', flush=True)
        sleep(random.uniform(0.2, 1.0))
        progress[i] = '#'
    print(f"\r{title}: [{''.join(progress)}]", flush=True)

print("Username: TestUserABC, Password: password1")
sleep(1)
print('---[STARTING BOOT SEQUENCE]---')
print(':-Welcome to GMOS (Generic Movie Operating System)-:')
progressbar('Checking Filesystem', 10)

Output:

Username: TestUserABC, Password: password1
---[STARTING BOOT SEQUENCE]---
:-Welcome to GMOS (Generic Movie Operating System)-:

Checking Filesystem: [..........] # up to Checking Filesystem: [##########]

Save as 'test.py' , use the console and call it via python.exe test.py (python.exe in %PATH%). See How to flush output of print function?.

You can get more influence over your output using f.e. the curses (*nix) or UniCurses (Win*) module.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69