Reputation: 21
I need to increment a variable each time a certain number of calls to a certain function is made in Python 2.7.3.
For example, feetTraveled = 0
. for
every 12 calls to travelOneInch()
, feetTraveled += 1
.
Is it optimal to use a for loop or should I be using something different? If it is optimal to use a for loop like the one above, what should be placed instead of 'every 12 calls to'?
Another example: I have four servants. They each do one task in a clock tick, and the time counter is initially time = 0
. So for every four calls to servantDo()
, time += 1
.
Upvotes: 1
Views: 238
Reputation: 6095
Probably the best implementation is to use an object to store the status and use the function to modify it:
class Position(object):
def __init__(self):
self.pos = 0
def advance(self,inches=1):
self.pos += inches
def pos_as_foot(self):
return self.pos // 12
If you find this approach a little to boring (even if it's the most correct one), you can try a more esoteric approach: you can use internal values of the function, i.e. treating it like an object
def foo():
foo.value+=1
if foo.value and not foo.value%12:
foo.result+=1
foo.value=0
foo.result=0
for i in range(15):
foo()
print foo.value
#15
print foo.result
#1
It's not the most easy solution, and have problem if you need several counters, but it's interesting to know. It has the advantage to remove some cluttering code (at least in simple cases) from the class definition (that is using under the hood), and keep the state accessible whereever you will use the function, without tampering with global variables (that i reaaaly don't like)
Upvotes: 0
Reputation: 833
mgilson (above) knows what's up. If I were you, I'd do the following, to make things easier:
class Foo(object):
def __init__(self):
self.__inches = 0
def travel_one_inch(self):
self.__inches += 1
def feetTraveled(self):
return self.__inches // 12
But, in terms of optimality, if you're just doing this once, then you can use temporary variables:
feetTraveled = 0
inchesTraveled = 0
for i in xrange(72):
# as in mgilson's answer
inchesTraveled += 1
if inchesTraveled > 11:
inchesTraveled = 0
feetTraveled += 1
Upvotes: 0
Reputation:
If you want to work in the global namespace:
inches = 0
feet = 0
def travelOneInch(sure):
inches += 1
if (inches % 12) == 0:
feet += 1
#...
And using inches % 12 == 0
is better than inches > 12
in case you want your function to recognize the second and furher feet.
Upvotes: 0
Reputation: 310257
In this case, I think I'd use an instance method:
class Foo(object):
def __init__(self):
self.inches = 0
self.feet = 0
def travel_one_inch(self):
self.inches += 1
if self.inches > 11:
self.inches = 0
self.feet += 1
def __str__(self):
return "{feet} feet and {inches} inches".format(feet=self.feet,inches=self.inches)
a = Foo()
for _ in range(123):
a.travel_one_inch()
print(a)
A vast majority of the time, if you want a function to remember some sort of state between calls, you're not looking for a function at all -- You're looking for a class with an instance method.
Upvotes: 3