Dice roller repeat issue in python3

Question:

I’m fairly new to programming in general and have been learning python3 for the last week or so. I tried building a dice roller and ran into an issue when asking the user if they wanted to repeat the roller or end the program.

import random as dice

d100 = dice.randint(1,100)
d20 = dice.randint(1,20)
d10 = dice.randint(1,10)
d8 = dice.randint(1,8)
d6 = dice.randint(1,6)
d4 = dice.randint(1,4)
d2 = dice.randint(1,2)

repeat = 'Y'
while repeat == 'Y' or 'y' or 'yes' or 'Yes':
    roll = (input('What would you like to roll? A d100, d20,  d10, d8, d6, d4, or d2?:'))
    quantity = (input('How many would you like to roll?'))
    quantity = int(quantity)
    if roll == 'd100':
        print('You rolled a: ' + str(d100 * quantity) + '!')

    elif roll == 'd20':
        print('You rolled a: ' + str(d20 * quantity) + '!')

    elif roll == 'd10':
        print('You rolled a: ' + str(d10 * quantity) + '!')

    elif roll == 'd8':
        print('You rolled a: ' + str(d8 * quantity) + '!')

    elif roll == 'd6':
        print('You rolled a: ' + str(d6 * quantity) + '!')

    elif roll == 'd4':
        print('You rolled a: ' + str(d4 * quantity) + '!')

    elif roll == 'd2':
        print('You rolled a: ' + str(d2 * quantity) + '!')        

    else:
        print('That is not an available die! Please select a die.')

    repeat = input('Would you like to continue?: ')
    if repeat == 'yes' or 'Y' or 'y' or 'Yes':
        continue

As of right now, despite what is input for the repeat variable it always continues even if it isn’t "yes", "Y", "y", or "Yes". I’m sure the answer is simple and right in front of me but I’m stumped! Thanks in advance!

Asked By: Owen Hall

||

Answers:

It’s a problem of precedence: repeat == 'Y' or 'y' or 'yes' or 'Yes' is interpreted as (repeat == 'Y') or 'y' or 'yes' or 'Yes' and then it tries to check whether 'y' counts as true, which it does (it’s a non-empty string).

What you want is while repeat in ('Y', 'y', 'yes', 'Yes'):

By the way, you don’t need the if statement at the end of the loop since it will exit automatically if repeat is something other than 'Y', 'y', 'yes', or 'Yes'.

Answered By: Jiří Baum

Two things

continue means go to the top of the loop (and then check whether to re-enter it), not guaranteed to go through the loop again. It might be better named skip because it really means "skip the rest of this iteration". Hence you don’t need if ... continue because you’re already at the end of the iteration.

The real loop control is what follows while. You’ve made a common mistake by assuming Python can group those or operators as one set of options opposite the ==. It can’t. Only the first string is compared to repeat and the others are treated as individual conditions. A string on its own is True as long as it’s not empty. Hence Python reads that as

while repeat is 'Y', or 'y' is not empty, or 'Yes' is not empty, or 'yes' is not empty

Since all three of those strings are by definition not empty, it doesn’t matter if repeat is 'Y', the whole condition will always be True.

The way to do multiple options for equality is

while repeat in ('Yes', 'yes', 'Y', 'y')

This means that repeat must appear in that list of options.

Note that you can simplify by normalizing or casefolding repeat.

while repeat.upper() in ('Y', 'YES')

Or be even simpler and less strict

while repeat.upper().startswith('Y')

You should also strip repeat to further eliminate user error of whitespace:

while repeat.strip().upper().startswith('Y')

Then you begin to arrive at a best practice for user-ended loops 🙂

Answered By: Luke Sawczak
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.