Dec 17-23, 2020 Vikrant Patil
These notes are available online at http://notes.pipal.in/2020/arcesium_finop_batch3/module2-day3.html
© Pipal Academy LLP
Day 1 | Day 2 | Day 3 | Day 4 | Day 5
We will be using jupyter hub from http://lab.pipal.in for this training. Create a notebook with name module2-day3.ipynb for today's session. Before you start shutdown all kernel except today's notebook.
problems
cat.py which mimics uniz command cat. Essentially cat.py should print contents of file to standard output (print statement).!python3 cat.py zen.txt
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
wc.py which mimics unix command wc. It should print line count, word count and char count and filename.python3 wc.py zen.txt
21 144 857 zen.txt
csvparse which will load data from file and create a list as shown below.file%% data.csv
symbol,day,price
IBM,Monday,111.23
IBM,Tuesday,112.54
APPLE,Monday,200.45
APPLE,Tuesday,205.54
```
csvparse("data.csv") [['IBM', 'Monday', 111.23], ['IBM','Tuesday',112.54], ['APPLE','Monday',200.45] ['APPLE','Tuesday',205.54]]
%%file cat.py
import sys
def cat(filename):
with open(filename) as f:
print(f.read()) # this reads comple contents of file in memory
if __name__ == "__main__":
filename = sys.argv[1]
cat(filename)
!python3 cat.py zen.txt
%%file head.py
import sys
def head(filename, n):
with open(filename) as f:
for i in range(n):
print(f.readline(), end="")
if __name__ == "__main__": ## double underscores to both name as well as for main
n = int(sys.argv[1]) #text->int
filename = sys.argv[2]
head(filename, n)
!python3 head.py 3 zen.txt
import this
%%file zen.txt
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
%%file wc.py
import sys
def line_count(filename):
with open(filename) as f:
return len(f.readlines())
def word_count(filename):
with open(filename) as f:
words = f.read().split() # will take all white spaces- space/tab/newline
return len(words)
def char_count(filename):
with open(filename) as f:
return len(f.read())
if __name__ == "__main__":
f = sys.argv[1]
print(line_count(f), word_count(f), char_count(f), f)
!python3 wc.py zen.txt
import wc
wc.line_count("module1-day1_2.ipynb")
!ls
!pwd
%%file data.csv
symbol,day,price
IBM,Monday,111.23
IBM,Tuesday,112.54
APPLE,Monday,200.45
APPLE,Tuesday,205.54
%%file parsecsvdata.py
def csvparse(filename):
with open(filename) as f:
heder = f.readline() # read header
data = []
for line in f: # f is iterator , so it understands where the current position is
fields = line.split(",")
data.append(fields)
return data
import parsecsvdata # will import only once
parsecsvdata.csvparse("data.csv")
%%file parsecsvdata1.py
def csvparse(filename):
with open(filename) as f:
heder = f.readline() # read header
data = []
for line in f: # f is iterator , so it understands where the current position is
fields = line.strip().split(",")
data.append(fields)
return data
import parsecsvdata1
parsecsvdata1.csvparse("data.csv")
%%file parsecsvdata1.py
def csvparse(filename):
with open(filename) as f:
heder = f.readline() # read header
data = []
for line in f: # f is iterator , so it understands where the current position is
fields = line.strip().split(",")
data.append(fields)
return data
if __name__ == "__main__":
print(csvparse("data.csv")) # testing
def csvparse(filename):
with open(filename) as f:
heder = f.readline() # read header
data = []
for line in f: # f is iterator , so it understands where the current position is
fields = line.strip().split(",")
data.append(fields)
return data
data = csvparse("data.csv")
data
data[0][-1]
def convert(fields):
return fields[:2] + [float(fields[-1])]
def csvparse(filename):
with open(filename) as f:
heder = f.readline() # read header
data = []
for line in f: # f is iterator , so it understands where the current position is
fields = line.strip().split(",")
fields = convert(fields)
data.append(fields)
return data
csvparse("data.csv")
f = open("data.csv")
f.readline()
f.readline()
l = f.readline()
l
l.split(",")
l.strip().split(",")
f.close()
``` ======== =========================================== mode meaning ======== =========================================== w Write, overwrite if file exists a append mode, if file exists ..write to end. rb or b read in binary mode wb write binary mode ab append in binary mode ======== ===========================================
url = "https://raw.githubusercontent.com/vikipedia/python-trainings/master/online_course/source/module2/indexdata.txt"
import requests
def download(url, filename):
with open(filename, "wb") as bf:
r = requests.get(url)
bf.write(r.content)
!python3 -m pip install requests
download(url, "indexdata.txt")
!python3 head.py 20 indexdata.txt
def parseSerialFormat(filename):
with open(filename) as f:
tabular = []
row = []
for line in f:
item = line.strip()
if item=="":
tabular.append(row) # this makes it 2D data
row = []
else:
row.append(item)
if row:
tabular.append(row)
return tabular
parseSerialFormat("indexdata.txt")
tabdata = parseSerialFormat("indexdata.txt")
def writeCSV(tabular, filename):
with open(filename, "w") as f:
for row in tabular:
f.write(",".join(row))
f.write("\n")
writeCSV(tabdata, "index.csv")
!python3 head.py 5 index.csv
weeklydata = csvparse("data.csv")
weeklydata
writeCSV(weeklydata, "weekly.csv")
def writeCSV(tabular, filename):
with open(filename, "w") as f:
for row in tabular:
stritems = [str(item) for item in row]
f.write(",".join(stritems))
f.write("\n")
writeCSV(weeklydata, "weekly.csv")
!cat weekly.csv
writeCSV(tabdata, "index.csv")
!cat index.csv
",".join(weeklydata[0])
",".join( [ str(item) for item in weeklydata[0]])
def parseSerialFormat(filename):
with open(filename) as f:
tabular = []
row = []
for line in f:
item = line.strip()
if item=="":
tabular.append(row) # this makes it 2D data
row = []
else:
row.append(item)
#if row: # this takes care of last set of values where empty line will not come after it, instead file will end
# tabular.append(row)
return tabular
parseSerialFormat("indexdata.txt")
Lets take simple example of implemeting code for bank account
%%file bank0.py
balance = 0
def deposit(amount):
global balance # don't make a local variable... it is global variable
balance += amount
def withdraw(amount):
global balance
balance -= amount
def get_balance():
return balance
if __name__ == "__main__":
pass # empty statement
import bank0
bank0.get_balance()
bank0.deposit(42000)
bank0.get_balance()
bank0.withdraw(2344)
bank0.get_balance()
l = []
l.append(1)
l
%%file bank2.py
def create_account(balance=0):
return {"balance":balance}
def deposit(account, amount):
account['balance'] += amount
def withdraw(account, amount):
if account['balance'] > amount:
account['balance'] -= amount
def get_balance(account):
return account['balance']
if __name__ == "__main__":
pass
import bank2
a1 = bank2.create_account(100)
a2 = bank2.create_account()
bank2.get_balance(a1)
bank2.get_balance(a2)
bank2.deposit(a1, 424242)
bank2.deposit(a2, 42000)
bank2.get_balance(a1)
bank2.get_balance(a2)
bank2.withdraw(a1, 4543)
bank2.get_balance(a1)
del bank1
class BankAccount:
def __init__(self, balance=0): # we these functions as methods
self.balance = balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
def get_balance(self):
return self.balance
BankAccount
b1 = BankAccount(100) # this will call __init__
b1
b1.deposit(2000)
b1.get_balance()
b1.withdraw(20)
b1.get_balance()
b2 = BankAccount()
b2.get_balance()
l = list("thres")
l
l = list((1, 2, 3, 4))
l
b1
Instance of class
+-----------------+
| | <------------methods to manipulate data
| data | <------------ method
| |
+-----------------+
|
+----------------->----- method to access data
Light
+--------------+
| |<---------- switch_on
| on=True |
| |<---------- switch_off
+--------------+
|
+-------------->--- is_on
`
class Light:
def __init__(self):
self.on = False
def switch_on(self):
self.on = True
def switch_off(self):
self.on = False
def is_on(self):
return self.on
def toggle(self):
if self.on:
self.switch_off()
else:
self.switch_on()
l1 = Light() # this will call __init__ method from class Light
l1.is_on()
l1.switch_on()
l1.is_on()
class WhiteLight:
color = "white" # class variable
def __init__(self):
self.on = False
def switch_on(self):
self.on = True
def switch_off(self):
self.on = False
def is_on(self):
return self.on
def toggle(self):
if self.on:
self.switch_off()
else:
self.switch_on()
w1 = WhiteLight()
w2 = WhiteLight()
w1.is_on()
w1.switch_on()
w1.is_on()
w2.is_on()
w1.color
w2.color
WhiteLight.color
WhiteLight.on
w1.on
w2.on
WhiteLight.color = "Tinted White"
WhiteLight.color
w1.color
w2.color
w1.color
class GreenLight(Light): # in bracker we specify parent class
color = "green"
g1 = GreenLight()
g1.switch_on()
g1.is_on()
g1.color
type("tyter")
isinstance(g1, GreenLight)
isinstance(g1, Light)
Problem
Implement a class for Stock which should have methods and data encapsulation as given below
Stock
+--------------------+
| name |----------> update_value
| value |
| high |
| low |
+--------------------+
| | | |
| | | +-------- get_name
| | +------------- get_value
| +----------------- get_high
+--------------------- get_low