A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://inventwithpython.com/bigbookpython/project22.html below:

Ducklings

#22
Ducklings

This program creates a scrolling field of ducklings. Each duckling has slight variations: they can face left or right and have two different body sizes, four types of eyes, two types of mouths, and three positions for their wings. This gives us 96 different possible variations, which the Ducklings program produces endlessly.

The Program in Action

When you run ducklings.py, the output will look like this:

Duckling Screensaver, by Al Sweigart [email protected]
Press Ctrl-C to quit...
                                             =" )
=")                                          (  v)=")
( ^)                                          ^ ^ ( v) >'')
 ^^                                                ^^  (  ^)
                              >")                       ^ ^
                              ( v)      =^^)
 ("<  ("<                >")   ^^       (  >)
(^ ) (< )                ( ^)            ^ ^
 ^^   ^^             ("<  ^^                       (``<>^^)
 (^^=               (^ )                          (<  )(  ^)
(v  ) ( "<           ^^                            ^ ^  ^ ^
--snip--
How It Works

This program represents ducklings with a Duckling class. The random features of each ducking are chosen in the __init__() method of this class, while the various body parts of each duckling are returned by the getHeadStr(), getBodyStr(), and getFeetStr() methods.

  1. """Duckling Screensaver, by Al Sweigart [email protected]
  2. A screensaver of many many ducklings.
  3.
  4. >" )   =^^)    (``=   ("=  >")    ("=
  5. (  >)  (  ^)  (v  )  (^ )  ( >)  (v )
  6.  ^ ^    ^ ^    ^ ^    ^^    ^^    ^^
  7.
  8. View this code at https://nostarch.com/big-book-small-python-projects
  9. Tags: large, artistic, object-oriented, scrolling"""
 10.
 11. import random, shutil, sys, time
 12.
 13. # Set up the constants:
 14. PAUSE = 0.2  # (!) Try changing this to 1.0 or 0.0.
 15. DENSITY = 0.10  # (!) Try changing this to anything from 0.0 to 1.0.
 16.
 17. DUCKLING_WIDTH = 5
 18. LEFT = 'left'
 19. RIGHT = 'right'
 20. BEADY = 'beady'
 21. WIDE = 'wide'
 22. HAPPY = 'happy'
 23. ALOOF = 'aloof'
 24. CHUBBY = 'chubby'
 25. VERY_CHUBBY = 'very chubby'
 26. OPEN = 'open'
 27. CLOSED = 'closed'
 28. OUT = 'out'
 29. DOWN = 'down'
 30. UP = 'up'
 31. HEAD = 'head'
 32. BODY = 'body'
 33. FEET = 'feet'
 34.
 35. # Get the size of the terminal window:
 36. WIDTH = shutil.get_terminal_size()[0]
 37. # We can't print to the last column on Windows without it adding a
 38. # newline automatically, so reduce the width by one:
 39. WIDTH -= 1
 40.
 41.
 42. def main():
 43.     print('Duckling Screensaver, by Al Sweigart')
 44.     print('Press Ctrl-C to quit...')
 45.     time.sleep(2)
 46.
 47.     ducklingLanes = [None] * (WIDTH // DUCKLING_WIDTH)
 48.
 49.     while True:  # Main program loop.
 50.         for laneNum, ducklingObj in enumerate(ducklingLanes):
 51.             # See if we should create a duckling in this lane:
 52.             if (ducklingObj == None and random.random() <= DENSITY):
 53.                     # Place a duckling in this lane:
 54.                     ducklingObj = Duckling()
 55.                     ducklingLanes[laneNum] = ducklingObj
 56.
 57.             if ducklingObj != None:
 58.                 # Draw a duckling if there is one in this lane:
 59.                 print(ducklingObj.getNextBodyPart(), end='')
 60.                 # Delete the duckling if we've finished drawing it:
 61.                 if ducklingObj.partToDisplayNext == None:
 62.                     ducklingLanes[laneNum] = None
 63.             else:
 64.                 # Draw five spaces since there is no duckling here.
 65.                 print(' ' * DUCKLING_WIDTH, end='')
 66.
 67.         print()  # Print a newline.
 68.         sys.stdout.flush()  # Make sure text appears on the screen.
 69.         time.sleep(PAUSE)
 70.
 71.
 72. class Duckling:
 73.     def __init__(self):
 74.         """Create a new duckling with random body features."""
 75.         self.direction = random.choice([LEFT, RIGHT])
 76.         self.body = random.choice([CHUBBY, VERY_CHUBBY])
 77.         self.mouth = random.choice([OPEN, CLOSED])
 78.         self.wing = random.choice([OUT, UP, DOWN])
 79.
 80.         if self.body == CHUBBY:
 81.             # Chubby ducklings can only have beady eyes.
 82.             self.eyes = BEADY
 83.         else:
 84.             self.eyes = random.choice([BEADY, WIDE, HAPPY, ALOOF])
 85.
 86.         self.partToDisplayNext = HEAD
 87.
 88.     def getHeadStr(self):
 89.         """Returns the string of the duckling's head."""
 90.         headStr = ''
 91.         if self.direction == LEFT:
 92.             # Get the mouth:
 93.             if self.mouth == OPEN:
 94.                 headStr += '>'
 95.             elif self.mouth == CLOSED:
 96.                 headStr += '='
 97.
 98.             # Get the eyes:
 99.             if self.eyes == BEADY and self.body == CHUBBY:
100.                 headStr += '"'
101.             elif self.eyes == BEADY and self.body == VERY_CHUBBY:
102.                 headStr += '" '
103.             elif self.eyes == WIDE:
104.                 headStr += "''"
105.             elif self.eyes == HAPPY:
106.                 headStr += '^^'
107.             elif self.eyes == ALOOF:
108.                 headStr += '``'
109.
110.             headStr += ') '  # Get the back of the head.
111.
112.         if self.direction == RIGHT:
113.             headStr += ' ('  # Get the back of the head.
114.
115.             # Get the eyes:
116.             if self.eyes == BEADY and self.body == CHUBBY:
117.                 headStr += '"'
118.             elif self.eyes == BEADY and self.body == VERY_CHUBBY:
119.                 headStr += ' "'
120.             elif self.eyes == WIDE:
121.                 headStr += "''"
122.             elif self.eyes == HAPPY:
123.                 headStr += '^^'
124.             elif self.eyes == ALOOF:
125.                 headStr += '``'
126.
127.             # Get the mouth:
128.             if self.mouth == OPEN:
129.                 headStr += '<'
130.             elif self.mouth == CLOSED:
131.                 headStr += '='
132.
133.         if self.body == CHUBBY:
134.             # Get an extra space so chubby ducklings are the same
135.             # width as very chubby ducklings.
136.             headStr += ' '
137.
138.         return headStr
139.
140.     def getBodyStr(self):
141.         """Returns the string of the duckling's body."""
142.         bodyStr = '('  # Get the left side of the body.
143.         if self.direction == LEFT:
144.             # Get the interior body space:
145.             if self.body == CHUBBY:
146.                 bodyStr += ' '
147.             elif self.body == VERY_CHUBBY:
148.                 bodyStr += '  '
149.
150.             # Get the wing:
151.             if self.wing == OUT:
152.                 bodyStr += '>'
153.             elif self.wing == UP:
154.                 bodyStr += '^'
155.             elif self.wing == DOWN:
156.                 bodyStr += 'v'
157.
158.         if self.direction == RIGHT:
159.             # Get the wing:
160.             if self.wing == OUT:
161.                 bodyStr += '<'
162.             elif self.wing == UP:
163.                 bodyStr += '^'
164.             elif self.wing == DOWN:
165.                 bodyStr += 'v'
166.
167.             # Get the interior body space:
168.             if self.body == CHUBBY:
169.                 bodyStr += ' '
170.             elif self.body == VERY_CHUBBY:
171.                 bodyStr += '  '
172.
173.         bodyStr += ')'  # Get the right side of the body.
174.
175.         if self.body == CHUBBY:
176.             # Get an extra space so chubby ducklings are the same
177.             # width as very chubby ducklings.
178.             bodyStr += ' '
179.
180.         return bodyStr
181.
182.     def getFeetStr(self):
183.         """Returns the string of the duckling's feet."""
184.         if self.body == CHUBBY:
185.             return ' ^^  '
186.         elif self.body == VERY_CHUBBY:
187.             return ' ^ ^ '
188.
189.     def getNextBodyPart(self):
190.         """Calls the appropriate display method for the next body
191.         part that needs to be displayed. Sets partToDisplayNext to
192.         None when finished."""
193.         if self.partToDisplayNext == HEAD:
194.             self.partToDisplayNext = BODY
195.             return self.getHeadStr()
196.         elif self.partToDisplayNext == BODY:
197.             self.partToDisplayNext = FEET
198.             return self.getBodyStr()
199.         elif self.partToDisplayNext == FEET:
200.             self.partToDisplayNext = None
201.             return self.getFeetStr()
202.
203.
204.
205. # If this program was run (instead of imported), run the game:
206. if __name__ == '__main__':
207.     try:
208.         main()
209.     except KeyboardInterrupt:
210.         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.

Exploring the Program

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.

  1. What happens if you change random.choice([LEFT, RIGHT]) on line 75 to random.choice([LEFT])?
  2. What happens if you change self.partToDisplayNext = BODY on line 194 to self.partToDisplayNext = None?
  3. What happens if you change self.partToDisplayNext = FEET on line 197 to self.partToDisplayNext = BODY?
  4. What happens if you change return self.getHeadStr() on line 195 to return self.getFeetStr()?

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4