Sep 20-24, 2021 Vikrant Patil
These notes are available online at https://notes.pipal.in/2021/arcesium_finop_batch1/
© Pipal Academy LLP
We will be using jupyter hub from https://lab.pipal.in for this training.
create a notebook with name module2-day3
Problems
!python3 head.py 5 zen.txt
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
!python3 grep.py zen.txt ugly
Beautiful is better than ugly.
!python tail.py 3 zen.txt
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 head.py
"""module head implements unix command head
pyhton3 head.py n filename
here n is number of lines to be displayed
filename is filename whose contents will be displayed
"""
import sys
def head1(filename, n):
with open(filename) as f:
for i, line in enumerate(f, start=1):
print(line, end="")
if i>n:
break
def head(filename, n):
"""prints first n lines from a file "filename"
"""
with open(filename) as f:
for i in range(n):
print(f.readline(), end="")
def head2(filename, n):
with open(filename) as f:
for i in range(n):
print(next(f), end="")
def head3(filename, n):
with open(filename) as f:
i = 0
while i<n:
print(f.readline(), end="")
i = i + 1
n = int(sys.argv[1])
filename = sys.argv[2]
head(filename, n)
Overwriting head.py
!python3 head.py 3 zen.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly.
!python3 head.py 4 zen.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit.
x = 10
x = 20
x = 30
import head # we have not given any argument when we say import module!
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-7-4686af9faae2> in <module> ----> 1 import head ~/trainings/2021/arcesium_finop_batch1/head.py in <module> 40 41 ---> 42 n = int(sys.argv[1]) 43 filename = sys.argv[2] 44 head(filename, n) ValueError: invalid literal for int() with base 10: '-f'
%%file testmodule1.py
print("X"*5, __name__)
Writing testmodule1.py
!python3 testmodule1.py # if we execute it as a script ... __name__ => "__main__"
XXXXX __main__
import testmodule1 # if we import then __name__ = modulename
XXXXX testmodule1
%%file head1.py
"""module head implements unix command head
pyhton3 head.py n filename
here n is number of lines to be displayed
filename is filename whose contents will be displayed
"""
import sys
def head(filename, n):
"""prints first n lines from a file "filename"
"""
with open(filename) as f:
for i in range(n):
print(f.readline(), end="")
if __name__ == "__main__": # this will get executed only when you call this from commadline as a script
n = int(sys.argv[1])
filename = sys.argv[2]
head(filename, n)
Writing head1.py
!python3 head1.py 5 zen.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex.
import head1
head1.head("zen.txt", 3)
The Zen of Python, by Tim Peters Beautiful is better than ugly.
!head -n 3 zen.txt mymodule.py # this is unix commnad/application
==> zen.txt <== The Zen of Python, by Tim Peters Beautiful is better than ugly. ==> mymodule.py <== """This is my first python module which I have created from jupyter notebook """
!cat cat.py
import sys
def cat(filename):
with open(filename) as f:
print(f.read())
# outside the if block you put only defination
if __name__ == "__main__": # in both you will have to give two _ at start and at _ end
# you put execution part here and it comes at end of .py file
cat(sys.argv[1])
import cat
cat.cat("zen.txt")# filename has to be given
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!
zen = open("zen.txt")
cat.cat("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 modulezyx.py
def foo(x):
print(x)
Overwriting modulezyx.py
import modulezyx
modulezyx.foo()
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-31-c2eff6e4ec4b> in <module> ----> 1 modulezyx.foo() ~/trainings/2021/arcesium_finop_batch1/modulezyx.py in foo() 1 2 def foo(): ----> 3 print(x) 4 NameError: name 'x' is not defined
import modulezyx
modulezyx.foo()
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-34-c2eff6e4ec4b> in <module> ----> 1 modulezyx.foo() ~/trainings/2021/arcesium_finop_batch1/modulezyx.py in foo() 1 2 def foo(x): ----> 3 print(x) 4 NameError: name 'x' is not defined
%%file unixcommand.py
import cat
import head1
import sys
if __name__ == "__main__":
if sys.argv[1] == "cat":
cat.cat(sys.argv[2])
else:
head1.head(sys.argv[3], int(sys.argv[2]))
Overwriting unixcommand.py
!python3 unixcommand.py head 3 zen.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly.
x == 30
True
import cat
cat.__name__
'cat'
!python3 cat.py zen.txt # here __name__ will be "__main__"
def foo():
pass
foo.__name__
'foo'
%%file grep.py
import sys
def grep(searchtext, filename):
with open(filename) as f:
for line in f: # f is an itearator ..you can put a for loop
if searchtext in line:
print(line, end="")
if __name__ == "__main__":
searchtext = sys.argv[1]
filename = sys.argv[2]
grep(searchtext, filename)
Overwriting grep.py
!python3 grep.py complex zen.txt
Simple is better than complex.
%%file tail.py
import sys
def tail(n, filename):
with open(filename) as f:
lines = f.readlines() # list complete eading of file has happned here!
for line in lines[-n:]: # take last n items
print(line)
def tail1(n , filename):
"""this is memory efficient
"""
with open(filename) as f:
window = [next(f) for i in range(n)] # read first n lines as list
for line in f: # go over remaining lines
window.pop(0) # remove one oldest line from start
window.append(line) # add new latest line at end
for line in window:
print(line, end="")
if __name__ == "__main__":
n = int(sys.argv[1])
filename = sys.argv[2]
tail1(n, filename)
Overwriting tail.py
f = open("numbers.csv")
f.readlines() # read complete file and give a list
print(f.read()) # empty string
print(f.readlines()) # empty list
print([line for line in f]) # empty list
[] []
f = open("numbers.csv")
for line in f.readlines(): # this will read entire file ..create a list of lines and on that for loop
print(line, end="")
1,2,3,4 1,2,3,4 1,2,3,4
f = open("numbers.csv")
i = 0
for line in f: # this will not read entire file before for loop
print(line, end="")
i = i+1
if i >1:
dom
1,2,3,4 1,2,3,4
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-10-35568ee8493f> in <module> 5 i = i+1 6 if i >1: ----> 7 dom NameError: name 'dom' is not defined
f.readline()
'1,2,3,4\n'
!python3 tail.py 4 zen.txt
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!
def tail1(n , filename):
"""this is memory efficient
"""
with open(filename) as f: # f contains all the when you opne
window = [next(f) for i in range(n)] # read first n lines as list
# aftwewords f starts at n+1th line
for line in f: # go over remaining lines
window.pop(0) # remove one oldest line from start
window.append(line) # add new latest line at end
for line in window:
print(line, end="")
1 1 1 1 1 1 1 1 1 1 1 1 1 1
- - -
1 1 1 1 1 1 1 1 1 1 1 1 1 1
- - - ^
- - - ^
- - - ^
- - - ^
- - -
%%file bank0.py
balance = 100
def get_balace():
return balance # only acess
def deposit(amount):
global balance # this will make sure that assignment operator will not create a local
balance = balance + amount
def withdraw(amount):
global balance
balance = balance - amount
if __name__ == "__main__":
# will not get executed if you import the module
print("This is initial balance:".rjust(50), get_balace())
deposit(500)
print("Balance after depositing money".rjust(50),get_balace())
withdraw(200)
print("Balance after withdrawing money".rjust(50),get_balace())
Overwriting bank0.py
!python3 bank0.py
This is initial balance: 100
Balance after depositing money 600
Balance after withdrawing money 400
import bank0
bank0.get_balace()
100
bank0.deposit(200)
bank0.get_balace()
300
bank0.withdraw(100)
bank0.get_balace()
200
%%file bank1.py
def create_account(balance):
return {"balance":balance} # dictionary
def get_balance(account):
return account['balance']
def deposit(account, amount):
account['balance'] += amount
def withdraw(account, amount):
account['balance'] -= amount
Overwriting bank1.py
import bank1
a1 = bank1.create_account(100)
a2 = bank1.create_account(200)
bank1.deposit(a1, 1000)
bank1.get_balance(a1)
1100
bank1.get_balance(a2)
200