Bugfix: ignore blank lines in test for end of code block
[pylit.git] / rstdocs / examples / 99bottles.py
blob8fdb69b65000e748c40d60d38d3b64f6c036119b
1 #!/usr/bin/env python
3 # :Copyright: 2007 Riccardo Murri, Guenter Milde.
4 # Released under the terms of the GNU General Public License
5 # (v. 2 or later)
7 # 99bottles.py
8 # ============
9 # Introductory Example to Literate Programming
10 # ++++++++++++++++++++++++++++++++++++++++++++
12 # Print the famous `99 bottles of beer` song lyrics
15 # This is used as an introductory example to literate programming
16 # in the `LiteratePrograms.org Wiki`_.
18 # The lyrics
19 # ----------
21 # We take the lyrics from the Wikipedia_, which says in the
22 # `99 bottles of beer`_ entry:
24 # The verse format is very formulaic, and can be expressed as follows:
26 # From 99 down to 1::
28 verse_template = """
29 <number> bottles of beer on the wall
30 <number> bottles of beer!
31 Take one down, pass it around
32 <number - 1> bottles of beer on the wall!"""
34 # There is much variation in the final verse. One common final verse (which
35 # could potentially cause an infinite-loop motif) is::
37 final_verse = """
38 No bottles of beer on the wall!
39 No bottles of beer!
40 Go to the store and buy some more
41 99 bottles of beer on the wall!"""
43 # The Python program
44 # ------------------
46 # There are a countless number of ways to implement a program that prints the
47 # whole song in Python. The following examples uses a `for` loop and the
48 # `replace` method of string objects.
50 # Basic version
52 # Count down from 99 to 1 and print the verses::
54 def print_verses_1(start_number=99):
55 for number in xrange(start_number, 0, -1):
56 verse = verse_template.replace("<number>", str(number))
57 print verse.replace("<number - 1>", str(number-1 or "No"))
59 # Consider the singular case
61 # There is one problem left, we should check whether to print 'bottles' or
62 # 'bottle'.
64 # An improved version will replace the "bottles" with a construct that
65 # takes into account the actual number of bottles::
67 def print_verses_2(start_number=99):
68 for number in xrange(start_number, 0, -1):
69 verse = verse_template.replace("<number>", str(number))
70 verse = verse.replace("bottles", "bottle" + plural_suffix(number))
71 print verse.replace("<number - 1>", str(number-1 or "No"))
73 # where an auxiliary function returns the matching suffix (or not)::
75 def plural_suffix(number):
76 if number != 1:
77 return "s"
78 else:
79 return ""
81 # Still, the last line come out wrong, as here we have <number-1> bottles. To
82 # treat this case we either could split the last line and treat it differently,
83 # or use a modified template as e.g. ::
85 verse_template_2 = """
86 <number> bottle<s> of beer on the wall
87 <number> bottle<s> of beer!
88 Take one down, pass it around
89 <number - 1> bottle<s> of beer on the wall!"""
91 # together with::
93 def print_verses_3(start_number=99):
94 for number in xrange(start_number, 0, -1):
95 verse = verse_template_2.replace("<number>", str(number))
96 verse = verse.replace("<s>", plural_suffix(number), 2)
97 verse = verse.replace("<s>", plural_suffix(number-1), 1)
98 print verse.replace("<number - 1>", str(number-1 or "No"))
101 # Command line use
102 # ----------------
104 # Print the lyrics if this script is called from the command line::
106 if __name__ == "__main__":
107 print_verses_3()
108 print final_verse
111 # .. _Wikipedia: http://en.wikipedia.org
112 # .. _99 bottles of beer: http://en.wikipedia.org/wiki/99_Bottles_of_Beer
113 # .. _LiteratePrograms.org Wiki:
114 # http://en.literateprograms.org/LiteratePrograms:Welcome