Python loops
In this section, we discuss a very important concept: loop or loops. A loop is used to repeat the same task with slightly different input or other factors.
Python loops, if...else conditions
Let's look at a simple loop through all the data items in an array:
>>>import numpy as np >>>cashFlows=np.array([-100,50,40,30]) >>>for cash in cashFlows: ... print(cash) ... -100 50 40 30
One type of data is called a tuple, where we use a pair of parentheses, ()
, to include all input values. One feature of a tuple variable is that we cannot modify its value. This special property could be valuable if some our variables should never be changed.A tuple is different from a dictionary, which stores data with key-value pairs. It is not ordered and it requires that the keys are hashable. Unlike a tuple, the value for a dictionary can be modified.
Note that for Python, the subscription for a vector or tuple starts from 0
. If x
has a length of 3
, the subscriptions will be 0
, 1
and 2
:
>>> x=[1,2,3] >>>x[0]=2 >>>x >>> [2, 2, 3] >>> y=(7,8,9) >>>y[0]=10 >>> TypeError: 'tuple' object does not support item assignment >>>Traceback (most recent call last): File "<stdin>", line 1, in <module> >>>type(x) >>> <class'list'> >>>type(y) >>> <class'tuple'> >>>
Assuming that we invest $100 today and $30 next year, the future cash inflow will be $10, $40, $50, $45, and $20 at the end of each year for the next 5 years, starting at the end of the second year; see the following timeline and its corresponding cash flows:
-100 -30 10 40 50 45 20 |--------|---------|--------|---------|----------|--------| 0 1 2 3 4 5 6
What is the Net Present Value (NPV) if the discount rate is 3.5%? NPVis defined as the present values of all benefits minus the present values of all costs. If a cash inflow has a positive sign while a cash outflow has a negative sign, then NPV can be defined conveniently as the summation of the present values of all cash flows. The present value of one future value is estimated by applying the following formula:
Here,PV is the present value, FV is the future value,R is the period discount rate and n is the number of periods. In Chapter 3, Time Value of Money, the meaning of this formula will be explained in more detail. At the moment, we just want to write annpv_f()
function which applies the preceding equation n times, where n is the number of cash flows. The complete NPV program is given here:
def npv_f(rate, cashflows): total = 0.0 for i in range(0,len(cashflows)): total += cashflows[i] / (1 + rate)**i return total
In the program, we used a for
loop. Again, the correct indentation is important for Python. Lines from 2 to 5 are all indented by one unit, thus they belong to the same function, called npv_f
. Similarly, line 4 is indented two units, that is, after the second column (:
), it belongs to the for
loop. The command of total +=a
is equivalent to total=total +a
.
For the NPV function, we use a for
loop. Note that the subscription of a vector in Python starts from zero, and the intermediate variable i
starts from zero as well. We could call this function easily by entering two sets of input values. The output is shown here:
>>>r=0.035 >>>cashflows=[-100,-30,10,40,50,45,20] >>>npv_f(r,cashflows) 14.158224763725372
Here is another npv_f()
function with a function called enumerate()
. This function willgenerate a pair of indices, starting from0
, and its corresponding value:
def npv_f(rate, cashflows): total = 0.0 for i, cashflow in enumerate(cashflows): total += cashflow / (1 + rate)**i return total
Here is an example illustrating the usage of enumerate()
:
x=["a","b","z"] for i, value in enumerate(x): print(i, value)
Unlike the npv_f
function specified previously, the NPV function from Microsoft Excel is actually a PV
function, meaning that it can be applied only to the future values. Its equivalent Python program, which is called npv_Excel
, is shown here:
def npv_Excel(rate, cashflows): total = 0.0 for i, cashflow in enumerate(cashflows): total += cashflow / (1 + rate)**(i+1) return total
The comparisons are shown in the following table. The result from the Python program is shown in the left panel while the result by calling the Excel NPV function is shown in the right panel. Please pay enough attention to the preceding program shown itself and how to call such a function:
By using a loop, we can repeat the same task with different inputs. For example, we plan to print a set of values. The following is such an example for a while
loop:
i=1 while(i<10): print(i) i+=1
The following program will report a discount (or any number of discount rates), making its corresponding NPV equal zero. Assume the cash flow will be 550
, -500
, -500
, -500
, and 1000
at time 0
, at the end of each year of the next 4 years. In Chapter 3, Time Value of Money, we will explain the concept of this exercise in more detail.
Write a Python program to find out which discount rate makes NPV equal zero. Since the direction of cash flows changes twice, we might have two different rates making NPV equal zero:
cashFlows=(550,-500,-500,-500,1000) r=0 while(r<1.0): r+=0.000001 npv=npv_f(r,cashFlows) if(abs(npv)<=0.0001): print(r)
The corresponding output is given here:
0.07163900000005098 0.33673299999790873
Later in the chapter, a for
loop is used to estimate the NPV of a project.
When we need to use a few math functions, we can import the math
module first:
>>>import math >>>dir(math) ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc'] >>>math.pi 3.141592653589793 >>>
The sqrt()
, square root, function is contained in the math
module. Thus, to use the sqrt()
function, we need to use math.sqrt()
; see the following code:
>>>sqrt(2) NameError: name 'sqrt' is not defined >>>Traceback (most recent call last): File "<stdin>", line 1, in <module> math.sqrt(2) 1.4142135623730951 >>>
If we want to call those functions directly, we can use from math import *
; see the following code:
>>>from math import * >>>sqrt(3) 1.7320508075688772 >>>
To learn about individual embedded functions, we can use thehelp()
function;see the following code:
>>>help(len) Help on built-in function len in module builtins: len(obj, /) Return the number of items in a container. >>>