3 # :Copyright: 2007 Riccardo Murri, Guenter Milde.
4 # Released under the terms of the GNU General Public License
10 # Print the famous `99 bottles of beer` song lyrics
12 # This is used as an introductory example to literate programming
13 # in the `LiteratePrograms.org Wiki`_.
18 # We take the lyrics from the Wikipedia_, which says in the
19 # `99 bottles of beer`_ entry:
21 # The verse format is very formulaic, and can be expressed as follows:
26 <number> bottles of beer on the wall
27 <number> bottles of beer!
28 Take one down, pass it around
29 <number - 1> bottles of beer on the wall!"""
31 # There is much variation in the final verse. One common final verse (which
32 # could potentially cause an infinite-loop motif) is::
35 No bottles of beer on the wall!
37 Go to the store and buy some more
38 99 bottles of beer on the wall!"""
43 # There are a countless number of ways to implement a program that prints the
44 # whole song in Python. The following examples uses a `for` loop and the
45 # `replace` method of string objects.
49 # Count down from 99 to 1 and print the verses::
51 def print_verses_1(start_number
=99):
52 for number
in xrange(start_number
, 0, -1):
53 verse
= verse_template
.replace("<number>", str(number
))
54 print verse
.replace("<number - 1>", str(number
-1 or "No"))
56 # Consider the singular case
58 # There is one problem left, we should check whether to print 'bottles' or
61 # An improved version will replace the "bottles" with a construct that
62 # takes into account the actual number of bottles::
64 def print_verses_2(start_number
=99):
65 for number
in xrange(start_number
, 0, -1):
66 verse
= verse_template
.replace("<number>", str(number
))
67 verse
= verse
.replace("bottles", "bottle" + plural_suffix(number
))
68 print verse
.replace("<number - 1>", str(number
-1 or "No"))
70 # where an auxiliary function returns the matching suffix (or not)::
72 def plural_suffix(number
):
78 # Still, the last line come out wrong, as here we have <number-1> bottles. To
79 # treat this case we eiter could split the last line and treat it differently,
80 # or use a modified template as e.g. ::
82 verse_template_2
= """
83 <number> bottle<s> of beer on the wall
84 <number> bottle<s> of beer!
85 Take one down, pass it around
86 <number - 1> bottle<s> of beer on the wall!"""
90 def print_verses_3(start_number
=99):
91 for number
in xrange(start_number
, 0, -1):
92 verse
= verse_template_2
.replace("<number>", str(number
))
93 verse
= verse
.replace("<s>", plural_suffix(number
), 2)
94 verse
= verse
.replace("<s>", plural_suffix(number
-1), 1)
95 print verse
.replace("<number - 1>", str(number
-1 or "No"))
101 # Print the lyrics if this script is called from the command line::
103 if __name__
== "__main__":
108 # .. _Wikipedia: http://en.wikipedia.org
109 # .. _99 bottles of beer: http://en.wikipedia.org/wiki/99_Bottles_of_Beer
110 # .. _LiteratePrograms.org Wiki:
111 # http://en.literateprograms.org/LiteratePrograms:Welcome