A progress bar is a visual element that shows how much of a task has been completed. Progress bars are often used alongside downloading files or software installations. This project creates a getProgressBar()
function that returns a progress bar string based on the arguments passed to it. It simulates a downloading file, but you can reuse the progress bar code in your own projects.
When you run progressbar.py, the output will look like this:
Progress Bar Simulation, by Al Sweigart
[█████████ ] 24.6% 1007/4098
The progress bar relies on a certain trick that programs running in terminal windows can perform. Just as '\n'
and '\t'
are escape characters for newline and tab characters, respectively, '\b'
is an escape character for backspace characters. If you “print” a backspace character, the text cursor will move to the left and erase the previously printed character. This only works for the current line the text cursor is on. If you run the code print('Hello\b\b\b\b\bHowdy')
, Python will print the text “Hello,” move the text cursor back five spaces, and then print the text “Howdy.” The “Howdy” text will overwrite “Hello,” making it look as though you called “Howdy.”
We can use this technique to create an animated progress bar on a single line by printing one version of the bar, moving the text cursor back to the start, then printing an updated progress bar. This effect can generate any text animation without requiring a module such as bext
, though it will be limited to taking up a single line in the terminal window.
Once you’ve created this program, you can display progress bars in your other Python programs by running import progressbar
and printing the string returned from progressbar.getProgressBar()
.
1. """Progress Bar Simulation, by Al Sweigart [email protected]
2. A sample progress bar animation that can be used in other programs.
3. This code is available at https://nostarch.com/big-book-small-python-programming
4. Tags: tiny, module"""
5.
6. import random, time
7.
8. BAR = chr(9608) # Character 9608 is '█'
9.
10. def main():
11. # Simulate a download:
12. print('Progress Bar Simulation, by Al Sweigart')
13. bytesDownloaded = 0
14. downloadSize = 4096
15. while bytesDownloaded < downloadSize:
16. # "Download" a random amount of "bytes":
17. bytesDownloaded += random.randint(0, 100)
18.
19. # Get the progress bar string for this amount of progress:
20. barStr = getProgressBar(bytesDownloaded, downloadSize)
21.
22. # Don't print a newline at the end, and immediately flush the
23. # printed string to the screen:
24. print(barStr, end='', flush=True)
25.
26. time.sleep(0.2) # Pause for a little bit:
27.
28. # Print backspaces to move the text cursor to the line's start:
29. print('\b' * len(barStr), end='', flush=True)
30.
31.
32. def getProgressBar(progress, total, barWidth=40):
33. """Returns a string that represents a progress bar that has barWidth
34. bars and has progressed progress amount out of a total amount."""
35.
36. progressBar = '' # The progress bar will be a string value.
37. progressBar += '[' # Create the left end of the progress bar.
38.
39. # Make sure that the amount of progress is between 0 and total:
40. if progress > total:
41. progress = total
42. if progress < 0:
43. progress = 0
44.
45. # Calculate the number of "bars" to display:
46. numberOfBars = int((progress / total) * barWidth)
47.
48. progressBar += BAR * numberOfBars # Add the progress bar.
49. progressBar += ' ' * (barWidth - numberOfBars) # Add empty space.
50. progressBar += ']' # Add the right end of the progress bar.
51.
52. # Calculate the percentage complete:
53. percentComplete = round(progress / total * 100, 1)
54. progressBar += ' ' + str(percentComplete) + '%' # Add percentage.
55.
56. # Add the numbers:
57. progressBar += ' ' + str(progress) + '/' + str(total)
58.
59. return progressBar # Return the progress bar string.
60.
61.
62. # If the program is run (instead of imported), run the game:
63. if __name__ == '__main__':
64. main()
After entering the source code and running it a few times, try making experimental changes to it. On your own, you can also try to figure out how to do the following:
|
, /
, -
, and \
to produce a rotating effect.Try to find the answers to the following questions. Experiment with some modifications to the code and rerun the program to see what effect the changes have.
print('\b' * len(barStr), end='', flush=True)
on line 29?round(progress / total * 100, 1)
on line 53 to round(progress / total * 100)
?