Aug 10-14, 2020 Vikrant Patil
These notes are available online at http://notes.pipal.in/2020/arcesium_finop_batch1_module1/day3.html
© Pipal Academy LLP
Day 1 | Day 2 | Day 3 | Day 4 | Day 5
We will be using jupyter hub from http://lab1.pipal.in for this training.
make use of notebook module1-day3.ipynb for today's session.
problems
NAV. Compute NAV for total assets of 25,00,00,000 , liabilities 30,00,000 and 1000 shares.numeric_value which returns actual numeric value. For example a value "(1234)" should return -1234 and "1234" should return 1234.Have a look at following python code what will it print? can you correct it?
def twice(x)
print(2*x)
print(twice(twice(3))
Solution 1
def NAV(total_assets, liabilities, sharecount):
return (total_assets - liabilities)/sharecount
NAV(250000000, 3000000, 1000)
def NAV(x, y, z): ## functionality wise this will work.
return (x-y)/z
Solution 2
def numeric_value(strnum):
numeric_str = strnum.replace("(", "-").replace(")","")
return float(numeric_str)
numeric_value("(1212)")
numeric_value("3433")
Solution 3
def twice(x):
print(2*x)
twice(5)
twice(twice(5))
x = twice(5)
print(x)
twice(None)
def twice(x):
return 2*x
twice(twice(4))
x = 15
y = 13
def sumit():
print(x+y)
x = 15
y = 13
def sum_it():
print(x+y)
x = 15
y = 13
def sum_it(x, y):
print(x+y)
x = 15
y = 13
def sum_it(x, y):
return x+y
sum_it(2, 4)
sum_it(5, 6)
A black box with no input!
+---------+
| |----->
+---------+
help(input)
sum([1, 2, 3, 45])
sum(['a',"b", "d"])
numeric_value(34343) ## the function expects a string not an integer
def say_hello(name, greeting):
print(greeting, name + "!")
say_hello("vikrant", "hello")
say_hello("hello", "vikrant")
def compound_interest(P, r, n, t):
return P*(1+r/n)**(n*t)
compound_interest(25000, 0.07, 4, 5)
compound_interest(0.07, 25000, 4, 5)
If by mistake we give wrong order of paramenters, we might get in trouble for geting an answer which is wrong. How do we handle it! Python has a solution for it which is called as named arguments
compound_interest(r = 0.07, P = 25000, n = 4, t =5)
compound_interest(P=25000, n = 4, r= 0.07, t = 5)
compound_interest(25000, r = 0.07, t = 5, n=4)
say_hello(greeting="Namaskar", name="Vikrant")
def compound_interest(P, n, t, r=0.05): # default argument allows us to give default value for the argument
return P*(1+r/n)**(n*t)
compound_interest(5000, 4, 5) # r is taken as 0.05 ...default value
sum([0, 0, 0, 0, 0], start=5)
sum([0, 0, 0, 0, 0])
!python3 --version
compound_interest
def foo(x):
x = x**2 + x + 1
y = 2*x
z = x+y
return x, y, z # one can return multiple values from a function
a, b, c = foo(10)
x, y, z
Variables defined at top level of program where main script starts are called as global variables. At this level globals and locals are same. Onece we call a function, as soon as function executaion starts , all variables cretaeted there are local to that function. Variables passed as argument to function are passed by reference. It means they refer same object, which is passed to function. Only diffence is they are called with diffrent name inside the function. As soon as the function call is over the namespace created for storing names of locals in function is deleted.
x
def foo():
x = 10
print(x)
foo()
print(x)
a = 10
def foo():
print(a)
foo()
x = 5
def foo():
y = x # we are trying to read from x
x = 10 #unless you declare iniatially x as global you can not do reading and writing same time
print(x, y)
foo()
x = 5
def foo():
global x
x = 10
foo()
print(x)
x = 5
def foo():
global x
y = x
x = 10
print(x, y)
foo()
Problems
x = 10
def foo():
x = 20
foo()
print(x)
``` x = 10
def foo():
print(x)
foo()
3.
x = 10
def foo():
x = x+1
foo()
print(x)
4.
x = [1, 1, 1]
def appendzero(y):
y = y + [0]
appendzero(x)
print(x)
5.
x = [1, 1, 1]
def appendzero(y):
y.append(0)
appendzero(x)
print(x)
```
x = 10
def foo():
x = x+1 ##<--- trying to read and write global
foo()
print(x)
x = [1, 1, 1]
def appendzero(y):
y = y + [0]
appendzero(x)
print(x)
Functions in python are just similar to any other data!
x = 1
y = x
print(x, y)
def foo():
print("foobar")
foo
print(foo)
bar = foo
bar
foo()
bar()
def square(x):
return x*x
def sumofsquares(x, y):
return square(x) + square(y)
def cube(x):
return x*x*x
def sumofcubes(x, y):
return cube(x) + cube(y)
def sumof(x, y, func):
return func(x) + func(y)
sumof(3, 5, square)
sumof(3, 5, cube)
This idea of passing functions as arguments is very usefull and many python builtins make use of this idea. For example
words = ["ones", "two", "three", "four", "five", "six"]
max(words) ## gives max by ASCII order
max(words, key=len)
sorted(words) # by ASCII order
sorted(words, key=len)
min(words, key=len)
max([1, 1, 333, 5, 333])
Suppose we have dabase with following records. Record has name, value, gain.
records = [
("TATA", 200.0, 5.5),
("INFY", 2000.0, -5),
("RELIANCE", 1500, 50.0),
("HCL", 1200, 70.5)
]
max(records) # max by name, ASCII order
def get_name(r):
return r[0]
def get_value(r):
return r[1]
def get_gain(r):
return r[2]
max(records, key=get_gain) # arecord with max gain
max(records, key=get_value) # a record with max value
records[0]
records[-1]
records[1:3]
records
nums = [1, 2, 3, 33, 44, 55, 66, 6666, 777]
def digits(n):
print("Computing digits for ", n)
return len(str(n))
digits(5555)
max(nums, key=digits)
records[0]
records[1]
records[2]
records[3]
def get_gain(r):
print("Cmputing gain for", r)
return r[2]
max(records, key=get_gain)
records[0][0] ## r[0]
records[0][1] ## r[1]
records[0][2] ## r[2]
max(nums, digits) # key argument can not be passed by position
max(nums, key=digits) # key has to be named argument
max(key=digits, nums)
def make_addder(x):
def adder(y):
return x+y
return adder
adder5 = make_addder(5)
adder5
adder5(11)
adder5(4)
adder5(3)
adder5(13)
type(3)
def make_logger(type_):
def logger(msg):
print("[" + type_.upper() + "]:", msg)
return logger
info = make_logger("info")
error = make_logger("error")
warn = make_logger("warning")
info("This is just for yor information!")
error("SOmwthing went wrong..error!")
warn("I suspect, Something might be wrong!")
def add(x, y):
return x+y
add = lambda x, y: x+y
add(2,3)
max(records, key=lambda r: r[2]) # gain
max(records, key= lambda r: r[1]) #gain
def get_gain(r):
return r[2]