This program mimics the “digital stream” visualization from the science fiction movie The Matrix. Random beads of binary “rain” stream up from the bottom of the screen, creating a cool, hacker-like visualization. (Unfortunately, due to the way text moves as the screen scrolls down, it’s not possible to make the streams fall downward without using a module such as bext
.)
When you run digitalstream.py, the output will look like this:
Digital Stream Screensaver, by Al Sweigart [email protected]
Press Ctrl-C to quit.
0 0
0 0
1 0 0 1 1 0 1
0 0 0 1 0 0 0 0 0
0 1 0 0 0 1 0 0 1 0 1
0 1 0 0 1 011 1 1 0 1 0
0 1 0 0 0 000 11 0 0 1 1 0
1 1 0 1 0 1 1 110 10 1 0 1 0 1 0
1 101 0 0 1 000 11 1 1 11 1 1 1
0 100 1 0 11 00 0 1 01 0
1 1 001 1 1 0 1 10 0 10 0
0 0 010 0 1 1 11 11 0 0
--snip--
Like Project 15, “Deep Cave,” this program uses the scrolling caused by print()
calls to create an animation. Each column is represented by an integer in the columns list: columns[0]
is an integer for the leftmost column, columns[1]
is an integer for the column to the right of that one, and so on. The program initially sets these integers to 0
, meaning it prints ' '
(an empty space string) instead of a stream in that column. Randomly, it changes each integer to a value between MIN_STREAM_LENGTH
and MAX_STREAM_LENGTH
. That integer decreases by 1
each time a line is printed. As long as a column’s integer is greater than 0
, the program prints a random 1
or 0
in that column. This produces the “digital stream” effect you see on the screen.
1. """Digital Stream, by Al Sweigart [email protected]
2. A screensaver in the style of The Matrix movie's visuals.
3. This code is available at https://nostarch.com/big-book-small-python-programming
4. Tags: tiny, artistic, beginner, scrolling"""
5.
6. import random, shutil, sys, time
7.
8. # Set up the constants:
9. MIN_STREAM_LENGTH = 6 # (!) Try changing this to 1 or 50.
10. MAX_STREAM_LENGTH = 14 # (!) Try changing this to 100.
11. PAUSE = 0.1 # (!) Try changing this to 0.0 or 2.0.
12. STREAM_CHARS = ['0', '1'] # (!) Try changing this to other characters.
13.
14. # Density can range from 0.0 to 1.0:
15. DENSITY = 0.02 # (!) Try changing this to 0.10 or 0.30.
16.
17. # Get the size of the terminal window:
18. WIDTH = shutil.get_terminal_size()[0]
19. # We can't print to the last column on Windows without it adding a
20. # newline automatically, so reduce the width by one:
21. WIDTH -= 1
22.
23. print('Digital Stream, by Al Sweigart [email protected]')
24. print('Press Ctrl-C to quit.')
25. time.sleep(2)
26.
27. try:
28. # For each column, when the counter is 0, no stream is shown.
29. # Otherwise, it acts as a counter for how many times a 1 or 0
30. # should be displayed in that column.
31. columns = [0] * WIDTH
32. while True:
33. # Set up the counter for each column:
34. for i in range(WIDTH):
35. if columns[i] == 0:
36. if random.random() <= DENSITY:
37. # Restart a stream on this column.
38. columns[i] = random.randint(MIN_STREAM_LENGTH,
39. MAX_STREAM_LENGTH)
40.
41. # Display an empty space or a 1/0 character.
42. if columns[i] > 0:
43. print(random.choice(STREAM_CHARS), end='')
44. columns[i] -= 1
45. else:
46. print(' ', end='')
47. print() # Print a newline at the end of the row of columns.
48. sys.stdout.flush() # Make sure text appears on the screen.
49. time.sleep(PAUSE)
50. except KeyboardInterrupt:
51. sys.exit() # When Ctrl-C is pressed, end the program.
After entering the source code and running it a few times, try making experimental changes to it. The comments marked with (!)
have suggestions for small changes you can make. On your own, you can also try to figure out how to do the following:
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(' ', end='')
on line 46 to print('.', end='')
?PAUSE = 0.1
on line 11 to PAUSE = -0.1
?columns[i] > 0
on line 42 to columns[i] < 0
?columns[i] > 0
on line 42 to columns[i] <= 0
?columns[i] -= 1
on line 44 to columns[i] += 1
?