Reputation: 13
So I made a dice rolling simulator in python, and while it does everything that I want it to I was told I could implement lists or a dictionary and it would be "better" code. I have tried adding both to my code and am completely lost. If any of you could help/show me that would be awesome. Here's my code, thanks so much.
from random import randint
print ""
die_amount = raw_input(">How many dice would you like to roll?: " )
die_amount = int(die_amount)
print ""
print "\t %s die are being rolled:" % die_amount
def dieroll(die_amount):
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
for i in range(1, die_amount+1):
roll = randint(1,6)
print "\t You rolled: %s" % roll
if roll == 1:
one +=1
elif roll == 2:
two +=1
elif roll ==3:
three +=1
elif roll == 4:
four +=1
elif roll == 5:
five+=1
elif roll == 6:
six +=1
print """
One's rolled: %s
Two's rolled: %s
Three's rolled: %s
Four's rolled: %s
Five's rolled: %s
Six's rolled: %s
""" % (one, two, three, four, five, six )
return [one, two, three, four, five, six]
dieroll(die_amount)
Upvotes: 1
Views: 349
Reputation: 1785
If you want an answer that more closely matches your original implementation, but uses a list instead, here is a replacement for dieroll()
:
def dieroll(die_amount):
rolls = [0] * 6
for i in range(die_amount):
roll = randint(1,6)
print "\t You rolled: %s" % roll
rolls[roll-1] += 1
print """
One's rolled: %s
Two's rolled: %s
Three's rolled: %s
Four's rolled: %s
Five's rolled: %s
Six's rolled: %s
""" % tuple(rolls)
return rolls
Upvotes: 0
Reputation: 4928
A Counter
data structure does exactly what you are trying to do.
from collections import Counter
c = Counter()
for i in range(die_amount):
roll = randint(1,6)
c[roll] += 1
Or, even easier:
c = Counter(randint(1,6) for i in range(die_amount))
c[1]
then contains the number of times 1
was rolled etc.
To print out the roll counts, you can use
for number, count in c.iteritems():
print "{}'s rolled: {}".format(number, count)
A Counter
is basically a Python dictionary with a default value of zero. This makes it particularly suitable for counting how many objects occur in a list, for instance.
There are several reasons why this approach works better than keeping a separate variable for each count.
If you wanted to have a hundred-sided dice, you would have to define 100 separate variables. That's much more error prone.
It's, in principle, much faster. Having six different variables necessitates looping through them with a series of if-statements. Imagine you roll a six. You will have to evaluate five different if-statements until you get to if roll == 6
. By contrast, the counter uses a hash table, so c[roll]
takes the same amount of time, regardless of how many rolls you make.
This begs the question: how can you know when you should be using a collection as opposed to a set of variables? The rule of thumb is that if a set of objects are different instances of the same thing, and we intend to use each object in exactly the same manner, they probably belong in a collection. In this case, a roll of 1 or a roll of 4 is essentially identical as far as the program flow is concerned. We will always treat them identically. They should therefore be kept in a collection.
Upvotes: 3