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-day4
import bank0
import bank1
a1 = bank1.create_account(200)
accounts = [bank1.create_account(100) for i in range(10)]
bank1.deposit(accounts[0], 1000)
balances = [bank1.get_balance(a) for a in accounts]
balances
[1100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
!python3 cat.py 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
class BankAccount:
def __init__(self, balance):
self.balance = balance
def get_balance(self):
return self.balance
def deposit(self, amount):
self.balance += amount # self.balance = self.balance + amount
def withdra(self, amount):
self.balance -= amount # self.balance = self.balance - amount
a1 = BankAccount(400) # this is how you call somthing called constructor, somthing that creates an instance!
# when you call class like a function .. it actually __init__()
a1
<__main__.BankAccount at 0x7f221b9c5f40>
type(a1)
__main__.BankAccount
type(1)
int
type([1, 2, 3, 4])
list
num = [1, 2, 3, 4, 5]
num
[1, 2, 3, 4, 5]
num.count(2)
1
a1.get_balance() # no need giving self
400
a1.withdra(200)
a1.get_balance()
200
a1.balance # because I have not put any restriction that outsiders should not aceess this
200
a1.deposit(10000) # no need of giving self!
a1.get_balance()
10200
class foo:
def __init__(self):
pass
def method():
print("Foo")
def method2(self):
print("Helllo from method2")
f = foo()
f.method() # python internally passed self as f
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-31-c7e42685bc61> in <module> ----> 1 f.method() # python internally passed self as f TypeError: method() takes 0 positional arguments but 1 was given
f.method2()
Helllo from method2
!cat 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
class BankAccount:
def __init__(self, balance):
self.balance = balance
def get_balance(self):
return self.balance
def deposit(self, amount):
self.balance += amount # self.balance = self.balance + amount
def withdra(self, amount):
self.balance -= amount # self.balance = self.balance - amount
class BankAccount1:
def __init__(account, balance): # altough it does not matter that first arg should be named self
account.balance = balance
def get_balance(account):
return account.balance
def deposit(account, amount):
account.balance += amount # self.balance = self.balance + amount
def withdra(account, amount):
account.balance -= amount # self.balance = self.balance - amount
def func(x):# when you write like this ..this function can not be accessed from insance
print(x)
a2 = BankAccount1(300)
a2.func(4)
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-43-21debc61385b> in <module> 1 a2 = BankAccount1(300) ----> 2 a2.func(4) TypeError: func() takes 1 positional argument but 2 were given
BankAccount1.func(5) # this can be called from class .. it beahves module
5
Question: What is the difference between module and class
class Light:
def __init__(self):
"""This is constructor for the class Light.
It is not compulsory.
before __init__ gets called it actually creates empty instance of Light
"""
self.status = 0 # 0 means switched off
def switchon(self):
self.status = 1 # 1 means switched on
def switchoff(self):
self.status = 0
class Fan:
def __init__(self):
self.status = 0 # we can have 5 positions of speed and 0 means off
def adjust_position(self, pos):
if pos>5 or pos < 0:
raise Error("speed position greater than 5 or less than 0 is not allowed")
self.status = pos
def switchoff(self):
self.status = 0
def swithoff_equiptments(equipments_from_a_room):
for equipment in equipments_from_a_room:
equipment.switchoff()
equips = [Light(), Light(), Fan(), Fan(), Fan()]
equips
[<__main__.Light at 0x7f221bb15490>, <__main__.Light at 0x7f221bb15dc0>, <__main__.Fan at 0x7f221bb157f0>, <__main__.Fan at 0x7f221bb15880>, <__main__.Fan at 0x7f221bb15fd0>]
equips[0].switchon()
equips[0].status
1
[e.status for e in equips]
[1, 0, 0, 0, 0]
equips[3].adjust_position(3)
[e.status for e in equips]
[1, 0, 0, 3, 0]
swithoff_equiptments(equips)
[e.status for e in equips]
[0, 0, 0, 0, 0]
equips[4].status = -3 # -3 is not allowed! but we set it !
a1
<__main__.BankAccount at 0x7f221b9c5f40>
a1.balance = 400 # we don't want this...so we provide mechanism to change
selfclass BankAccount1:
def __init__(self, balance):
self.balance = balance # this public variable
def get_balance(self):
return self.balance
def deposit(self, amount):
self.balance += amount # self.balance = self.balance + amount
def withdra(self, amount):
self.balance -= amount # self.balance = self.balance - amount
class BankAccount2:
def __init__(self, balance):
self._balance = balance # adding underscore make this variable private
def get_balance(self):
return self._balance
def deposit(self, amount):
self._balance += amount # self.balance = self.balance + amount
def withdra(self, amount):
self._balance -= amount # self.balance = self.balance - amount
# public variable can be accessed as an attribute by an ousider
# private attribute can be accesses only by class code /class methods
b2 = BankAccount2(200)
b1 = BankAccount1(100)
b1.
200
class EbookReader:
def __init__(self, file):
with open(file) as f:
self._lines = f.readlines()
self._pagesize = 20
self._position = 0 # position is line nunber not page
def get_next_page(self):
if self._position < len(self._lines):
page = self._lines[self._position:self._position+self._pagesize] # list[start:end]
self._position += self._pagesize
return "".join(page)
else:
return "" # or return last page
def read_next_page(self):
print(self.get_next_page())
def go_to_start(self):
self.go_to(0)
def go_to(self, linenum):
if linenum >= 0 and linenum < len(self._lines):
self._position = linenum
with open("data.txt", "w") as f: # create new , if exists overwrite
multiline = """some text
to demo the writing
of file
"""
f.write(multiline)
!python3 cat.py data.txt
some text
to demo the writing
of file
with open("data.txt", "a") as f: # create new , or append if exists
multiline = """some text
to demo the writing
of file
"""
f.write(multiline)
!python3 cat.py data.txt
some text
to demo the writing
of file
some text
to demo the writing
of file
with open("data1.txt", "w") as f: # create new , if exists overwrite
multiline = """some text
to demo the writing
of file
"""
f.write(multiline)
f.write("this is one item that I am writing")
f.write("one more")
!python3 cat.py data1.txt
some text
to demo the writing
of file
this is one item that I am writingone more
with open("data1.txt", "w") as f: # create new , if exists overwrite
multiline = """some text
to demo the writing
of file
"""
f.write(multiline)
f.write("this is one item that I am writing\n")
f.write("one more")
!python3 cat.py 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])
!python3 cat.py data1.txt
some text
to demo the writing
of file
this is one item that I am writing
one more
def create_book_file(from_filename,to_file,n):
with open(from_filename) as f:
contents = f.read()
#reading is over
with open(to_file, "w") as f:
# writing in another file
for i in range(n):
f.write(contents) # repeat the contents n time
create_book_file("zen.txt", "zenbook.txt", 10)
ebookreader = EbookReader("zenbook.txt")
ebookreader.read_next_page()
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.
ebookreader.read_next_page()
Namespaces are one honking great idea -- let's do more of those! 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.
ebookreader.read_next_page()
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! 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.
ebookreader.read_next_page()
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! 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.
ebookreader.read_next_page()
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! 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.
ebookreader.go_to(30)
ebookreader.read_next_page()
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! 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.
!wc zen.txt
21 144 857 zen.txt
!wc zenbook.txt
210 1440 8570 zenbook.txt
We want to find word freq of words from one file
def get_words(file):
with open(file) as f:
contents = f.read()
return contents.split()
def wordfreq(words):
freq = {}
for w in words:
if w in freq:
freq[w] = freq[w] + 1
else:
freq[w] = 1
return freq
def wordfreqfile(filename):
words = get_words(filename)
return wordfreq(words)
[1, 2, 3, 4, 1, 2, 3, 1, 3, 1, 1]
item count 1
1 1+1 2
2 1 3
3 1 4
4 1 1
wordfreqfile("zen.txt")
{'The': 1,
'Zen': 1,
'of': 3,
'Python,': 1,
'by': 1,
'Tim': 1,
'Peters': 1,
'Beautiful': 1,
'is': 10,
'better': 8,
'than': 8,
'ugly.': 1,
'Explicit': 1,
'implicit.': 1,
'Simple': 1,
'complex.': 1,
'Complex': 1,
'complicated.': 1,
'Flat': 1,
'nested.': 1,
'Sparse': 1,
'dense.': 1,
'Readability': 1,
'counts.': 1,
'Special': 1,
'cases': 1,
"aren't": 1,
'special': 1,
'enough': 1,
'to': 5,
'break': 1,
'the': 5,
'rules.': 1,
'Although': 3,
'practicality': 1,
'beats': 1,
'purity.': 1,
'Errors': 1,
'should': 2,
'never': 2,
'pass': 1,
'silently.': 1,
'Unless': 1,
'explicitly': 1,
'silenced.': 1,
'In': 1,
'face': 1,
'ambiguity,': 1,
'refuse': 1,
'temptation': 1,
'guess.': 1,
'There': 1,
'be': 3,
'one--': 1,
'and': 1,
'preferably': 1,
'only': 1,
'one': 2,
'--obvious': 1,
'way': 2,
'do': 2,
'it.': 1,
'that': 1,
'may': 2,
'not': 1,
'obvious': 1,
'at': 1,
'first': 1,
'unless': 1,
"you're": 1,
'Dutch.': 1,
'Now': 1,
'never.': 1,
'often': 1,
'*right*': 1,
'now.': 1,
'If': 2,
'implementation': 2,
'hard': 1,
'explain,': 2,
"it's": 1,
'a': 2,
'bad': 1,
'idea.': 2,
'easy': 1,
'it': 1,
'good': 1,
'Namespaces': 1,
'are': 1,
'honking': 1,
'great': 1,
'idea': 1,
'--': 1,
"let's": 1,
'more': 1,
'those!': 1}
%%file words.txt
one
one two
one two three
one two three four
one two three four five
one two three four six
one two three seven six
one two eight seven six
one nine eight seven six
ten nine eight seven six
ten nine eight seven
ten nine eight
ten nine
ten
Overwriting words.txt
wordfreqfile("words.txt")
{'one': 1,
'one,two,': 1,
'one,two,three': 1,
'one,two,three,four': 1,
'one,two,three,four,five': 1,
'one,two,three,four,six': 1,
'one,two,three,seven,six': 1,
'one,two,eight,seven,six': 1,
'one,nine,eight,seven,six': 1,
'ten,nine,eight,seven,six': 1,
'ten,nine,eight,seven': 1,
'ten,nine,eight': 1,
'ten,nine': 1,
'ten': 1}
with open("words.txt") as f:
cont = f.read()
with open("words.txt", "w") as f:
f.write(cont.replace(","," "))
def get_words(file):
with open(file) as f:
contents = f.read()
return contents.split()
def wordfreq1(words):
freq = {}
for w in words:
if w in freq:
freq[w] = freq[w] + 1
else:
freq[w] = 1
return freq
def wordfreq(words):
freq = {}
for w in words:
freq[w] = freq.get(w, 0) + 1
return freq
def wordfreqfile(filename):
words = get_words(filename)
return wordfreq(words)
d = {"A":1, "B":2}
d['A']
d.get('A')
d.get('C', 1) # if C is not there in dict give me 1
1
freq = wordfreqfile("words.txt")
freq
{'one': 9,
'two': 7,
'three': 5,
'four': 3,
'five': 1,
'six': 5,
'seven': 5,
'eight': 5,
'nine': 5,
'ten': 5}
for word in freq:
print(word, freq[word])
one 9 two 7 three 5 four 3 five 1 six 5 seven 5 eight 5 nine 5 ten 5
for word, f in freq.items():
print(word, f)
one 9 two 7 three 5 four 3 five 1 six 5 seven 5 eight 5 nine 5 ten 5
def get_freq(t):
return t[1]
for word, f in sorted(freq.items(), key=get_freq):
print(word.rjust(6), f)
five 1 four 3 three 5 six 5 seven 5 eight 5 nine 5 ten 5 two 7 one 9
def get_freq(t):
return t[1]
for word, f in sorted(freq.items(), key=get_freq, reverse=True):
print(word.rjust(6), f)
one 9 two 7 three 5 six 5 seven 5 eight 5 nine 5 ten 5 four 3 five 1
def get_freq(t):
return t[1]
for word, f in sorted(freq.items(), key=get_freq, reverse=True):
print(word.rjust(6), f, "*"*f)
one 9 ********* two 7 ******* three 5 ***** six 5 ***** seven 5 ***** eight 5 ***** nine 5 ***** ten 5 ***** four 3 *** five 1 *