99 bottles of beer on the wall in Python 3

Posted on

Problem

This is my try on the 99 bottles of beer on the wall lyrics, made in Python 3. I am a beginner willing to learn so be gentle 🙂

def lyrics():
    if count > 1:
        print(f"{count} bottles of beer on the wall,")
        print("")
        print(f"{count} bottles of beer.")
        print("")
        print("Take one down, pass it around,")
        print("")
    else:
        print(f"{count} bottle of beer on the wall.")
        print("")
        print(f"{count} bottle of beer on the wall,")
        print("")
        print(f"{count} bottle of beer.")
        print("")
        print("Take it down, pass it around,")
        print("")
        print("No more bottles of beer on the wall.")


def bottles():
    global count
    while count > 1:
        lyrics()
        count = count - 1
        if count > 1:
            print(f"{count} bottles of beer on the wall.")
            print("")
        else:
            lyrics()


if __name__ == '__main__':
    count = 99
    bottles()

Solution

  1. You have the wrong version of 99 bottles of beers
  2. Global variables are bad except for constants (and some special cases)
  3. print() is equal to print('') but there are two other amazing solutions.
  4. If you come from another language, forget all you know about loops

1.

Ok the first fix is easy, just add:

No more bottles of beer on the wall, no more bottles of beer. 
Go to the store and buy some more, 99 bottles of beer on the wall.

to the end

2.

The second is very important for all your future projects. Use arguments instead of global variables. Using globals is only ok if you define constants of if your script is short, but as soon as your project grows, it will become unmanageable. Globals are also less performant than locals because locals can only be modified in the function itself, that permits the compiler to do assumptions which can’t be done with globals. Avoid globals as much as possible.

3.

print('hello')
print('')
# is the same as
print('hello', end='n') # 'n' is a newline which is the default
print()
# which is the same as
print('hello')
print()
# which is the same as
print('hello', end='nn')
# which is the same as
print('hellon')
# which is the same as
print('he', end='llo')
print()
print()

In summary, either use end='nn' or append n to your string.

4.

In Python, there is this concept of iterable, for i in range(start, end, step) is the way you do the classic looping over integers. range(10) is an iterator that will take all the values from 0 to 9, you know what, lists, tuple, dictionaries files, and even strings are iterables for i in 'babar': print(i). That’s why while loops are less used in python, it is because iterables are cool, don’t use a while.

def bottles():
    for i in range(99, 1, -1):
        print(f"{i} bottles of beer on the wall, {i} bottles of beer.")
        print(f"Take one down, pass it around, {i-1} bottles of beer on the walln")
    i -= 1
    print(f"{i} bottle of beer on the wall, {i} bottle of beer.")
    print("Take it down, pass it around, No more bottles of beer on the wall.n")
    print("No more bottles of beer on the wall, no more bottles of beer.")
    i = 99
    print(f"Go to the store and buy some more, {i} bottles of beer on the wall.n")
    bottles() # remove this line if you don't like beers

bottles()

Update:

Apparently, OP can’t use numbers, this version doesn’t contain numbers:

def bottles(count):
    for i in reversed(range(count+True)):
        s='s' if i-True else ''
        print(f"{i} bottle{s} of beer on the wall, {i} bottle{s} of beer.")
        if not i-True: break
        print(f"Take one down, pass it around, {i-1} bottle{s} of beer on the walln")
    print("Take one down, pass it around, no more bottles of beer on the walln")
    print("No more bottles of beer on the wall, no more bottles of beer.")
    print(f"Go to the store and buy some more, {count} bottles of beer on the wall.n")
    bottles(count)  # If you don't want to go to the store and buy some more remove this line

bottles(99)
```

You can reduce the need to use print("") by adding a n after each statement. You can also use a one-line if statement to reduce the four line if statement.

count = count - 1 is the same as count -= 1, which reduces the amount of code you need to write.

This is assuming you are using Python 3.6

def lyrics():
    if count > 1:
        print(f"{count} bottles of beer on the wall,n")
        print(f"{count} bottles of beer.n")
        print("Take one down, pass it around,n")
    else:
        print(f"{count} bottle of beer on the wall.n")
        print(f"{count} bottle of beer on the wall,n")
        print(f"{count} bottle of beer.n")
        print("Take it down, pass it around,n")
        print("No more bottles of beer on the wall.n")

def bottles():
    global count
    while count > 1:
        lyrics()
        count -= 1
        print(f"{count} bottles of beer on the wall.n") if count > 1 else lyrics()

if __name__ == '__main__':
    count = 99
    bottles()

Leave a Reply

Your email address will not be published. Required fields are marked *