12 Days of Chrismas

Nested loops. I looped through a range of numbers rather than a list of strings because numeric comparison (day == 1) is faster than string comparison (day == "first").

“Colly” means “black as coal”; it’s a word we don’t have in American English.

"""
Output the lyrics to "The Twelve Days of Christmas."
"""

import sys

ordinals = [   #a list of 13 strings
    None,      #Let "first" have index 1.
    "first",
    "second",
    "third",
    "fourth",
    "fifth",
    "sixth",
    "seventh",
    "eighth",
    "ninth",
    "tenth",
    "eleventh",
    "twelfth"
]

gifts = [
    None,                         #Let "partridge in a pear tree." have index 1.
    "partridge in a pear tree.",  #must be prefixed with "A " or "And a ".
    "Two turtledoves",
    "Three French hens",
    "Four colly birds",
    "Five golden rings",
    "Six geese a-laying",
    "Seven swans a-swimming",
    "Eight maids a-milking",
    "Nine ladies dancing",
    "Ten lords a-leaping",
    "Eleven pipers piping",
    "Twelve drummers drumming"
]

for day in range(1, len(ordinals)):   #Count up.
    print("On the", ordinals[day], "day of Christmas")
    print("My true love gave to me")

    for g in range(day, 0, -1):       #Count down.
        if g == 1:
            if day == 1:
                print("A ", end = "")
            else:
                print("And a ", end = "")
        print(gifts[g])

    print()

sys.exit(0)
On the first day of Christmas
My true love gave to me
A partridge in a pear tree.

On the second day of Christmas
My true love gave to me
Two turtledoves
And a partridge in a pear tree.

On the third day of Christmas
My true love gave to me
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the fourth day of Christmas
My true love gave to me
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the fifth day of Christmas
My true love gave to me
Five golden rings
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the sixth day of Christmas
My true love gave to me
Six geese a-laying
Five golden rings
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the seventh day of Christmas
My true love gave to me
Seven swans a-swimming
Six geese a-laying
Five golden rings
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the eighth day of Christmas
My true love gave to me
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying
Five golden rings
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the ninth day of Christmas
My true love gave to me
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying
Five golden rings
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the tenth day of Christmas
My true love gave to me
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying
Five golden rings
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the eleventh day of Christmas
My true love gave to me
Eleven pipers piping
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying
Five golden rings
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

On the twelfth day of Christmas
My true love gave to me
Twelve drummers drumming
Eleven pipers piping
Ten lords a-leaping
Nine ladies dancing
Eight maids a-milking
Seven swans a-swimming
Six geese a-laying
Five golden rings
Four colly birds
Three French hens
Two turtledoves
And a partridge in a pear tree.

Things to try

  1. Don’t skip a line after the last verse. Change
        print()
    
    to
        if day < len(ordinals) - 1:   #after every verse except the last,
            print()
    

  2. Change
                if day == 1:
                    print("A ", end = "")
                else:
                    print("And a ", end = "")
    
    to the following. See Conditional expressions.
                print("A " if day == 1 else "And a ", end = "")
    

  3. It’s inconsistent that "partridge in a pear tree." is the only gift that contains a period. The gifts list should hold only gifts, not the punctuation at the end of a sentence. Remove the period, and change the original
            if g == 1:
                if day == 1:
                    print("A ", end = "")
                else:
                    print("And a ", end = "")
            print(gifts[g])
    
    to the following code, which steers the computer in one of three possible directions.
            if g > 1:
                f = "{}"
            elif day == 1:
                f = "A {}."
            else:
                f = "And a {}."
    
            print(f.format(gifts[g]))
    

  4. Now let’s do something serious. It’s inconsistent that "two turtledoves" contains a number ("two") while "partridge in a pear tree" does not contain a number. We should have had three parallel lists, to make sure the items stay in synch. This is no big deal if we have only 12 items, but would be more important if we had 1000 items. Make it look like an Excel spreadsheet.
    """
    Output the lyrics to "The Twelve Days of Christmas."
    """
    
    import sys
    
    days = [
        None,
        ["first",    "one",    "partridge in a pear tree"],   #"one" is not used
        ["second",   "two",    "turtledoves"],
        ["third",    "three",  "French hens"],
        ["fourth",   "four",   "colly birds"],
        ["fifth",    "five",   "golden rings"],
        ["sixth",    "six",    "geese a-laying"],
        ["seventh",  "seven",  "swans a-simming"],
        ["eighth",   "eight",  "maids a-milking"],
        ["ninth",    "nine",   "ladies dancing"],
        ["tenth",    "ten",    "lords a-leaping"],
        ["eleventh", "eleven", "lords a-leaping"],
        ["twelfth",  "twelve", "drummers drumming"]
    ]
    
    for day in range(1, len(days)):   #Count up.
        print("On the", days[day][0], "day of Christmas")
        print("My true love gave to me")
    
        for d in range(day, 0, -1):   #Count down.
            if d > 1:
                ordinal = days[d][1]
            elif day == 1:
                ordinal = "a"
            else:
                ordinal = "and a"
    
            print(ordinal.capitalize(), days[d][2], end = "")
            print("." if d == 1 else "")
    
        if day < len(days) - 1:       #after every verse except the last,
            print()
    
    sys.exit(0)