Pergunta

I'm new to python and I'm trying to create a simple program to allow the user to choose to use an 8, 12 or 24 sided dice and then display the result from rolling it.

This is my code but I am unsure why when I enter whether I wish to roll again it produces an error.

import random

def dice4():
 min=1
 max=4
 print random.randint(min, max);
 return;

def dice6():
 min=1
 max=6
 print random.randint(min, max);
 return;

def dice12():
 min=1
 max=12
 print random.randint(min, max);
 return;

roll = "yes"
y = 1

while roll == "yes" or roll == "y":
  x = input("What dice do you want to use? 4/6/12?");
  if x ==8:
   dice4();
  elif x==12:
   dice6();
  elif x==16:
   dice12();
  else:
   print "You have not entered a valid dice number";

  roll = input("Do you want to roll again? y/n");

print "Thanks for rolling!";
input("Press <Enter> to quit");

Thanks for any help, I realise it is probably a trivial error.

Foi útil?

Solução

I am unsure why when I enter whether I wish to roll again it produces an error.

So the problem is in that part of the code. Let's look at it:

roll = input("Do you want to roll again? y/n");

You're using the input function. That will try to evaluate whatever you type as a Python expression.

So, if you type yes, it will try to find the value of yes, and raise a NameError. The same for n or no.

If you type y, the same thing should happen… except because you happen to have an extraneous variable named y lying around, it will actually find a value, 1. So, when you check that later, in while roll == "yes" or roll == "y":, obviously 1 is not equal to either of those strings, so it will just exit.

The only thing you could type that would work is "y" or "yes" (or the same with single quotes). Which obviously you don't want your users to have to type.

The solution is to use raw_input instead of input, which just gives you the input as a string, instead of trying to evaluate it.

roll = raw_input("Do you want to roll again? y/n");

This is one reason using input is usually a bad idea. Even in the earlier case, where you want an integer, the errors for typos are going to be ugly.

For an even better reason, see what happens when you type __import__('os').system('dir C:\\') (substitute ls / if you're on Unix instead of Windows), and imagine how much mischief your user could cause with other inputs.

So, I would recommend always using raw_input. If you want to convert the input to an integer, pass it to int. If you want to treat it as a literal value of any type, use ast.literal_eval. If you really want to evaluate it as arbitrary Python code, use eval (which is no safer than input, but at least it's more explicit).

Outras dicas

Let me just add other problems with your code. You overwrite the builtins minand max in your functions and you use semicolons which are not needed. You use empty return statements.

Then you repeat too much code with dice4, dice6 and dice12. You should use one function with a parameter. Now you will be able to throw a lot of different dice.

def dice(value):
    print random.randint(1, value)

dice(4)
dice(6)
dice(8)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top