Reputation: 75
I am a beginner in python. I am making a Toss Simulator. This is my code:
import random
class TossSimulator():
heads = 0
tails = 0
def doFlip(self):
x = random.randint(0,1)
if(x == 0):
return True
else:
return False
def getScore(self, flip_function):
if flip_function is True:
self.heads+=1
else:
self.tails+=1
obj = TossSimulator()
obj.getScore(doFlip())
The error I am recieving is :
NameError : name 'doFlip' is not defined at line 24
Upvotes: 0
Views: 57
Reputation: 12948
You really do not need a class for this, but if you just want to practice, then practice well! The problem is, as stated in the comments, that doFlip
does not exist in the scope in which you are trying to call it. Wrapping some of the comments up into a solution that illustrates some nice features:
import random
class TossSimulator():
def __init__(self, flip_function):
"""
Args:
flip_function: function that returns True (heads) or False (tails)
"""
self.heads = 0
self.tails = 0
self.flip = flip_function
def get_score(self):
if self.flip(): # call stored flip function
self.heads += 1
else:
self.tails += 1
print('Heads: {}\tTails: {}'.format(self.heads, self.tails))
def do_flip():
return random.randint(0, 1) == 0 # skip the middle man
obj = TossSimulator(do_flip)
obj.get_score() # prints the running total heads and tails
# Heads: 0 Tails: 1
A couple of important changes were made. First, I added the __init__
function, which is the constructor for Python objects. This is where you want to define any of your member variables, initialize things, etc. With the class defined this way, you can make multiple instances of your TossSimulator
and they will each keep a record of their own scores:
obj1 = TossSimulator(do_flip)
obj2 = TossSimulator(do_flip)
obj1.getScore() # Heads: 1 Tails: 0
obj1.getScore() # Heads: 1 Tails: 1
obj2.getScore() # Heads: 0 Tails: 1 (scored separately)
obj2.getScore() # Heads: 0 Tails: 2
Second, I made flip_function
a parameter that is passed to your constructor. Now you can define a special flip function for each instance of your TossSimulator
when you create it, and then get_score
will use the flip function defined for that instance every time you call it:
def always_heads():
return True
obj1 = TossSimulator(do_flip)
obj2 = TossSimulator(always_heads)
obj1.getScore() # Heads: 0 Tails: 1
obj1.getScore() # Heads: 1 Tails: 1 (random flips)
obj2.getScore() # Heads: 1 Tails: 0
obj2.getScore() # Heads: 2 Tails: 0 (always will be heads)
Third, I cleaned a couple of things up. You can, for instance, replace something like this:
if x == y:
return True
else:
return False
with return x == y
. They're exactly the same, but one is much more concise (and possibly very slightly more efficient?). You can also directly check the "truthiness" of a function's return, so you do not need to use if self.flip() == True:
; you can just use if self.flip():
.
You can take that last point a step further and directly check the "truthiness" of a numeric value. In Python, zero is False
and all other integers are True
. A summary of what values are true and what values are false can be found here.
Upvotes: 1