1
\$\begingroup\$

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()
\$\endgroup\$

2 Answers 2

5
\$\begingroup\$
  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='\n\n')
# which is the same as
print('hello\n')
# which is the same as
print('he', end='llo')
print()
print()

In summary, either use end='\n\n' 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 wall\n")
    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 wall\n")
    print("Take one 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.")
    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)
```
\$\endgroup\$
6
  • \$\begingroup\$ Thank you, but in the rules of the challange it says that besides "take one down" I shouldn't use any number of name of a number. \$\endgroup\$ Commented Feb 25, 2019 at 18:52
  • \$\begingroup\$ You mean no args ? \$\endgroup\$
    – Benoît P
    Commented Feb 25, 2019 at 18:54
  • \$\begingroup\$ Sorry, no number or name of a number inside a string. That means that the lines 5 and 8 are incorrect because I have 1 and 99 inside the print function. \$\endgroup\$ Commented Feb 25, 2019 at 19:02
  • \$\begingroup\$ Here are the rules of the challenge reddit.com/r/beginnerprojects/comments/19kxre/… \$\endgroup\$ Commented Feb 25, 2019 at 19:34
  • \$\begingroup\$ I updated the answer so it doesn't use numbers. \$\endgroup\$
    – Benoît P
    Commented Feb 25, 2019 at 21:20
3
\$\begingroup\$

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()
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.