views:

91

answers:

3

A python program that I'm debugging has the following code (including print statements for debugging):

print "BEFORE..."
print "oup[\"0\"] = " + str(oup["0"])
print "oup[\"2008\"] = " + str(oup["2008"])
print "oup[\"2009\"] = " + str(oup["2009"])

oup0 = oup["0"]
oup2008 = oup["2008"]
oup2009 = oup["2009"]
ouptotal = oup2008 + oup2009
print "ouptotal = " + str(ouptotal)

if ouptotal > 0:
    oup["2008"] = oup2008 + oup0 * (oup2008 / ouptotal)
    oup["2009"] = oup2009 + oup0 * (oup2009 / ouptotal)

print "AFTER..."
print "oup[\"0\"] = " + str(oup["0"])
print "oup[\"2008\"] = " + str(oup["2008"])
print "oup[\"2009\"] = " + str(oup["2009"])

Up until that point, the variables update correctly. When I run that code, I get the following on the screen:

BEFORE...                                                                       
oup["0"] = 22032                                                                
oup["2008"] = 541                                                               
oup["2009"] = 15223                                                             
ouptotal = 15764                                                                
AFTER...                                                                        
oup["0"] = 22032                                                                
oup["2008"] = 541                                                               
oup["2009"] = 15223                                                             

Why aren't oup["2008"] and oup["2009"] updating?

(Python version is 2.6.2 on a "Jaunty" Ubuntu machine.)

+6  A: 

If the values are integers, then (oup2008 / ouptotal) will be zero, so they will be updated to their own value + 0, hence no change.

Convert them to floats for the calculation, then back if required, and it should work as expected.

Example:

oup["2008"] = oup2008 + int(oup0 * (float(oup2008) / ouptotal))
Wogan
That did it! Thank you!
Chip Uni
+3  A: 

Integer division results in integer results. either use float() on one of the division terms or add from __future__ import division at the top.

Ignacio Vazquez-Abrams
+1  A: 

They are, you're just updating them with the same value. In Python 2.6, / is still an integer division operator(reference), so dividing (oup2008 / ouptotal) is dividing a number by a bigger number, which always results in zero. If you want the behavior from later versions, were / is a floating-point operator, you can get it with a future statement importing division.

coppro
Thanks for the reference.
Chip Uni