There are a number of problems with this code in its current form.
The big problem is that the totalPct() function must contain at least one indented line. Since the first line in totalPct() is not indented, the code will not compile.
Since indentation is critical in Python, and your indentation is out of whack, I'm unclear about the intent of the function. If you indent all of the lines below def totalPct(total) an additional 4 spaces, the code will compile, but this may not be what you want.
It's no problem to have an embedded function, but your observation about "return totalPct" is a good one. If this statement is indented so it's included in the makeTotalPct() function, the result will be that you return a reference to the totalPct function. You can make a call using that function object after it's returned. If you add parentheses (e.g. return totalPct(x)), you will be making a function call and returning its result instead of returning a reference to the function.
It's all a matter of intent.
If you want to return a function object that you can use to make a function call later, use "return totalPct".
If you want to call a function and return its result, use "return totalPct()".

Greg H.
tutor
Max:
The key here is to recognize that a function is an object in Python. You can treat that object like any other Python object, which means you can do things like pass it into a function as an argument or return it as a function value.
"totalPct" is interpreted as a reference to a function object. This reference can be assigned, returned, etc., just like any other object.
"totalPct()" uses the object reference to call the function. The parentheses are a signal to the interpreter that you want to call the function. totalPct(1.0) passes a value of 1.0 to the totalPct function.
When you say "return totalPct", you're returning a reference to the function object.
When you say "return totalPct()", you're asking the interpreter to call the function and return its result.
The startValue and years arguments are effectively stored as attributes of the function object so they can be used when you make the function call later on. This is possible because of Python closures. If you want the gory details, google "python closure".
Note that this is a topic that raises a lot of passion in language purists.
I've modified your code slightly so it calls the function returned by makeTotalPct(). Try it yourself to see how it works (Python 2.x; you'll need to convert the print statements to functions for Python 3).
-------
def pctIncrease(begin, end):
return 100*(end/begin-1)
def increaseByPct(begin, pct):
return begin+begin*pct/100
def makeTotalPct(startValue, years):
def totalPct(pct):
value = startValue
for year in range(years):
value = increaseByPct(value, pct)
return pctIncrease(startValue, value)
print "totalPct: ", totalPct
print "totalPct(1.0): ", totalPct(1.0)
return totalPct
totalPct = makeTotalPct(175.1, 5)
result1 = totalPct(1.0)
result2 = totalPct(2.0)
print "result1: ", result1
print "result2: ", result2
totalPct2 = makeTotalPct(154.4, 10)
result3 = totalPct2(3.0)
result4 = totalPct2(4.0)
print "result3: ", result3
print "result4: ", result4
return 100*(end/begin-1)
def increaseByPct(begin, pct):
return begin+begin*pct/100
def makeTotalPct(startValue, years):
def totalPct(pct):
value = startValue
for year in range(years):
value = increaseByPct(value, pct)
return pctIncrease(startValue, value)
print "totalPct: ", totalPct
print "totalPct(1.0): ", totalPct(1.0)
return totalPct
totalPct = makeTotalPct(175.1, 5)
result1 = totalPct(1.0)
result2 = totalPct(2.0)
print "result1: ", result1
print "result2: ", result2
totalPct2 = makeTotalPct(154.4, 10)
result3 = totalPct2(3.0)
result4 = totalPct2(4.0)
print "result3: ", result3
print "result4: ", result4
Report
03/17/15
Max H.
03/16/15