Question

here is my code so far:

import random

normal_dice=6

def roll(sides):
    for i in range(sides == ""):
        return random.randint(1,normal_dice)
    for i in range(1,int(sides)):
        return random.randint(1,int(sides))
    for i in range(int(sides),1):
        print("None")

everything works except when user input is blank, I get the error message:

Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    roll()
TypeError: roll() missing 1 required positional argument: 'sides'

What I want is for when user input is blank, a random number between 1 and 6 is generated

any help would be appreciated, thanks in advance!

Was it helpful?

Solution

You haven't shown us the code that calls roll, which is where the problem is.

However, if you want to make it so that roll can be called without any argument at all, you can do that by using a default parameter value:

def roll(sides='6'):

If the default is something more complicated (e.g., instead of "use the usual rule, with 6 sides" it's "use a different rule"), you just set the default value to something that isn't valid. Either None:

def roll(sides=None):
    if sides is None:
        return special_rule()

… or, if None is a valid argument, a custom sentinel object:

_sentinel = object()
def roll(sides=_sentinel):
    if sides is _sentinel:
        return special_rule()

As a side note, your code isn't doing the right thing for almost any input. Let's step through it:

for i in range(sides == ""):
    return random.randint(1,normal_dice)

This is right, but in a very convoluted way. If sides == "", it will count from 0 to 1, and return a number from 1 to 6 the first time through the loop. Otherwise, it will count from 0 to 0, meaning we skip over the whole loop.

for i in range(1,int(sides)):
    return random.randint(1,int(sides))

Here, if sides is any number greater than 1, like "8", you will count from 1 to 8, and return randint(1, 1) the first time through, so it'll always return 1 and never get to the rest of the loop. If it's 1 or less, it will skip over the loop.

for i in range(int(sides),1):
    print("None")

And this code will print out the string None multiple times, which can't be very useful, before finally falling off the end of the function and returning None.

I think what you wanted is something like this:

def roll(sides='6'):
    sides = int(sides)
    if sides > 1:
        return random.randint(1, sides)
    else:
        raise ValueError("Can't roll a {}-sided die".format(sides))

If you took out the if check and just did a return random.randint(1, sides), passing a number smaller than 1 would raise an exception like ValueError: empty range for randrange() (1, 0, 0). That's a little hard for a user to understand. And you were (I think) explicitly checking for that case in the original version. So, I put in a simpler explicit check, which gives you a nicer error message: ValueError: can't roll a 0-sided die.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top