#!/usr/bin/env python
"""
 print out the lyrics for '99 bottles of beer on the wall'

 See wikiepdia:99_Bottles_of_Beer and
     http://www.99-bottles-of-beer.net/
 particularly
     http://www.99-bottles-of-beer.net/language-python-573.html

 -- Jim M for python class on Oct 6 2006, talking about functions

 === start sample output ==========================

  $ ./song.py 

  7 bottles of beer on the wall, 7 bottles of beer,
  you take one down, pass it around,
  6 bottles of beer on the wall.
  
  6 bottles of beer on the wall, 6 bottles of beer,
  you take one down, pass it around,
  5 bottles of beer on the wall.
  
  5 bottles of beer on the wall, 5 bottles of beer,
  you take one down, pass it around,
  4 bottles of beer on the wall.
  
  4 bottles of beer on the wall, 4 bottles of beer,
  you take one down, pass it around,
  3 bottles of beer on the wall.
  
  3 bottles of beer on the wall, 3 bottles of beer,
  you take one down, pass it around,
  2 bottles of beer on the wall.
  
  2 bottles of beer on the wall, 2 bottles of beer,
  you take one down, pass it around,
  1 bottles of beer on the wall.
  
  1 bottle of beer on the wall, 1 bottle of beer,
  you take one down, pass it around,
  no bottles of beer on the wall.

 === end sample output ============================
 
"""

def long_phrase(n):
    """ >>> long_phrase(27)                     # This is just a 'doc string'
        27 bottles of beer on the wall          # that describes what it does.
        """
    return "%s bottles of beer on the wall" % n
    # That last line used 'string formats', which is a way to
    # interpolate numbers or other strings into strings,
    # which I mentioned in class once but haven't done in any detail.
    # For example,
    #     " The number '%d' is written '%s'." % (2, 'two')
    # replaces %d with a representation of the number 2 as a decimal digit (d),
    # and replaces %s with a representation of 'two' as a string (s).
    # See http://docs.python.org/lib/typesseq-strings.html for the nitty-gritty.
    # For integers, this same '%' operator is 'mod arithmetic;
    # for example, (13 % 3) is 1 (i.e. the remainder of 13/3 is 1).
    #
    # Note that other than in comments and documentation,
    # this is the only place that for example 'beer on the wall'
    # occurs in the code.  Changing it here changes it throughout the song.

def short_phrase(n):
    """ >>> short_phrase(27)
        27 bottles of beer
        """
    long = long_phrase(n)  # longer phrase
    return long[:-12]      # without the last twelve characters
    
def verse(n):
    """ >>> verse(27)
        27 bottles of beer on the wall, 27 bottles of beer,
        you take one down, pass it around,
        26 bottles of beer on the wall.
        
        """
    return long_phrase(n) + ", " + short_phrase(n) + ",\n" \
           + "you take one down, pass it around,\n" \
           + long_phrase(n-1) + ".\n"

def last_verse():
    """ >>> last_verse()
        1 bottle of beer on the wall, 1 bottle of beer,
        you take one down, pass it around,
        no bottles of beer on the wall.
        
        """
    # --- we could do this to fix plural/singular and 'no' for '0' ------
    # verse_1 = verse(1)
    # verse_1 = verse_1.replace('1 bottles', '1 bottle')
    # verse_1 = verse_1.replace('0 bottles', 'no bottles')
    # return verse_1
    # --- or instead just do all of that in one swoop : -----------------
    return verse(1).replace('1 bottles', \
                            '1 bottle').replace('0 bottles', \
                                                'no bottles')

def sing(start_n=99):                   
    """print the song starting from the given verse, or 99 if none given. """
    print                               # initial blank line
    for n in range(start_n, 1, -1):     # all the plural verses
        print verse(n)
    print last_verse()                  # last singular verse

# Run the program starting with 7 bottles.
sing(7)

syntax highlighted by Code2HTML, v. 0.93pm6