Feb 13-17, 2023 Vikrant Patil
All notes are available online at https://notes.pipal.in/2023/arcesium_finop_jan/
Please login to https://engage.pipal.in/ and launch jupyter lab
For today create a notebook with name module2-day2
notebook names are case sensitive. Make sure you give correct name
© Pipal Academy LLP
problem
bonus
>>> data = [[11, 12, 13],
[21, 22, 23],
[31, 32, 33]]
>>> column(data, 0)
[11, 21, 31]
[e for e in range(10) if e%2==0]
[0, 2, 4, 6, 8]
sum([n for n in range(1, 1001) if n%7==0 or n%11==0])
110110
def factors(n):
return [i for i in range(1,n+1) if n%i==0]
factors(5)
[1, 5]
factors(10)
[1, 2, 5, 10]
factors(7)
[1, 7]
factors(11)
[1, 11]
factors(13)
[1, 13]
def is_prime(n):
return factors(n) == [1, n]
is_prime(4)
False
is_prime(5)
True
def primes(n):
"""generates primes numbers less than n
"""
return [p for p in range(1, n+1) if is_prime(p)]
list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
primes(20)
[2, 3, 5, 7, 11, 13, 17, 19]
primes(100)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> data = [[11, 12, 13],
[21, 22, 23],
[31, 32, 33]]
>>> column(data, 0)
[11, 21, 31]
data = [[11, 12, 13],
[21, 22, 23],
[31, 32, 33]]
data
[[11, 12, 13], [21, 22, 23], [31, 32, 33]]
data[0] #zeroth row
[11, 12, 13]
data[1] # first row
[21, 22, 23]
data[2] # second row
[31, 32, 33]
data[0][0] # zeroth item from zeroth row
11
data[1][0] # zeroth item from 1st row
21
data[2][0] # zeroth item from 2nd row
31
def column(data2d, n):
rowcount = len(data2d)
return [data2d[i][n] for i in range(rowcount)]
column(data, 0)
[11, 21, 31]
column(data, 1)
[12, 22, 32]
def column(data2d, n):
rowcount = len(data2d)
return [data2d[i][n] for i in range(rowcount)]
students = ["Akash", "Priya", "Aman"]
students[0]
'Akash'
students[2]
'Aman'
[students[i] for i in range(len(students))]
['Akash', 'Priya', 'Aman']
[student for student in students]
['Akash', 'Priya', 'Aman']
def column(data2d, n):
"""finds nth column from 2d matrix
"""
return [row[n] for row in data2d] # naming your variables is so important! it makes the logic the simple!
column(data, 0)
[11, 21, 31]
Write a function generate_password to generate random password of length 8 to 15 characters. It should have alphanumeric characters and one of special symbols from "!@#$%^&*()". The password should have random length between 8 to 15. Hint: make use of random.choice function from random module which selects random element from a list/string
>>> generate_password()
'AsKsgfSd&1'
>>> generate_password()
'hJ%lk)$sdTTdf'
def generate_password():
alphanumeric = string.ascii_letters + string.digits
special = "!@#$%^&*()"
symbol = random.choice(special)
chars = [random.choice(alphanumeric) for i in range(14)] + [symbol]
return "".join(chars)
import string
string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
import random
random.choice(string.ascii_letters)
'j'
generate_password()
'egh7SfbvOmb5Qc#'
random.choice(range(7, 15))
11
def generate_password():
alphanumeric = string.ascii_letters + string.digits
special = "!@#$%^&*()"
symbol = random.choice(special)
length = random.choice(range(7, 15))
return "".join([random.choice(alphanumeric) for i in range(length)]) + symbol
generate_password()
'YxyxneffdaxT#'
generate_password()
'bZixCTO0r4)'
generate_password()
'J5TYMFj4EJVw&'
generate_password()
'fM0$fIqpDKV%'
random.choice(primes(100))
83
random.random() # this generates random number between 0 to 1
0.1618221782343795
%%file poem.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!
Writing poem.txt
with open("poem.txt") as filehandle:
for line in filehandle:
print(line)
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!
with open("poem.txt") as filehandle:
for line in filehandle:
print(line, end="")
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!
text = "hello world"
print(text)
hello world
anothertext = """hello
world"""
print(anothertext)
hello world
anothertext
'hello\nworld'
with open("poem.txt") as filehandle:
lines = [line for line in filehandle]
lines
['The Zen of Python, by Tim Peters\n', '\n', 'Beautiful is better than ugly.\n', 'Explicit is better than implicit.\n', 'Simple is better than complex.\n', 'Complex is better than complicated.\n', 'Flat is better than nested.\n', 'Sparse is better than dense.\n', 'Readability counts.\n', "Special cases aren't special enough to break the rules.\n", 'Although practicality beats purity.\n', 'Errors should never pass silently.\n', 'Unless explicitly silenced.\n', 'In the face of ambiguity, refuse the temptation to guess.\n', 'There should be one-- and preferably only one --obvious way to do it.\n', "Although that way may not be obvious at first unless you're Dutch.\n", 'Now is better than never.\n', 'Although never is often better than *right* now.\n', "If the implementation is hard to explain, it's a bad idea.\n", 'If the implementation is easy to explain, it may be a good idea.\n', "Namespaces are one honking great idea -- let's do more of those!\n"]
import os
os.getcwd()
'/home/vikrant/trainings/2023/arcesium_finop_jan'
filepath = os.path.join('/home/vikrant/trainings/2023/arcesium_finop_jan', "poem.txt")
filepath
'/home/vikrant/trainings/2023/arcesium_finop_jan/poem.txt'
with open(filepath) as f:
completefiledata = f.read()
completefiledata
"The Zen of Python, by Tim Peters\n\nBeautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\n"
print(completefiledata)
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!
with open(filepath) as f:
for line in f:
print(line, end="")
print("="*10)
for line in f: # here f has reached at end of file!
print(line, end="")
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! ==========
!cat poem.txt # this is not python, cat is linux command
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 cat.py
import sys
def print_contents(filepath):
with open(filepath) as f:
for line in f:
print(line, end="")
filepath = sys.argv[1]
print_contents(filepath)
Writing cat.py
!python3 cat.py poem.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 stats.py
def mean(nums):
return sum(nums)/len(nums)
def std(nums):
print("Yet to be implemented!")
def quintile(nums, q):
pass
Writing stats.py
import stats
stats.mean([1, 2, 3, 4])
2.5
stats.std([])
Yet to be implemented!
%%file cat.py
import sys
def print_contents(filepath):
with open(filepath) as f:
for line in f:
print(line, end="")
filepath = sys.argv[1]
print_contents(filepath)
Overwriting cat.py
import cat
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) Cell In[133], line 1 ----> 1 import cat File ~/trainings/2023/arcesium_finop_jan/cat.py:10 6 print(line, end="") 8 filepath = sys.argv[1] ---> 10 print_contents(filepath) File ~/trainings/2023/arcesium_finop_jan/cat.py:4, in print_contents(filepath) 3 def print_contents(filepath): ----> 4 with open(filepath) as f: 5 for line in f: 6 print(line, end="") FileNotFoundError: [Errno 2] No such file or directory: '-f'
%%file cat1.py
import sys
def print_contents(filepath):
with open(filepath) as f:
for line in f:
print(line, end="")
if __name__ == "__main__": # magic variable defined by python!
filepath = sys.argv[1]
print_contents(filepath)
Writing cat1.py
!python cat1.py poem.txt # __name__ -> "__main__"
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!
import cat1 # __name__ -> cat1
%%file myemail_module.py
import sys
def extract_emails_with_subject_contents_like(matching_word):
pass
def extract_target_pdf(emails):
pass
def send_email(emailaddress, pdf):
pass
if __name__ == "__main__":
matching_word = sys.argv[1]
send_email_add = sys.argv[2]
emails = extract_emails_with_subject_contents_like(matching_word)
pdf = extract_target_pdf(emails)
send_email(send_email_add, pdf)
Overwriting myemail_module.py
!python3 myemail_module.py Microsoft mircosoft_team@arcesium.com
%%file another_program1.py
import myemail_module
import sys
def summarize(emails):
pass
with open(sys.argv[1]) as f:
subject = f.read()
emails= myemail_module.extract_emails_with_subject_contents_like(subject)
target_message = summarize(emails)
myemail_module.send_email(sys.argv[2], target_message)
Writing another_program1.py
!python3 another_program1.py XYZ sdsad@dsds.com
Traceback (most recent call last):
File "/home/vikrant/trainings/2023/arcesium_finop_jan/another_program1.py", line 7, in <module>
with open(sys.argv[1]) as f:
FileNotFoundError: [Errno 2] No such file or directory: 'XYZ'
import another_program1 # sys.argv does not come into picture with import module
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) Cell In[150], line 1 ----> 1 import another_program1 File ~/trainings/2023/arcesium_finop_jan/another_program1.py:7 4 def summarize(emails): 5 pass ----> 7 with open(sys.argv[1]) as f: 8 subject = f.read() 10 emails= myemail_module.extract_emails_with_subject_contents_like(subject) FileNotFoundError: [Errno 2] No such file or directory: '-f'
%%file cat1.py
import sys
def print_contents(filepath):
with open(filepath) as f:
for line in f:
print(line, end="")
if __name__ == "__main__": # magic variable defined by python!
filepath = sys.argv[1]
print_contents(filepath)
Overwriting cat1.py
problems
head.py which shows first 5 lines of a file passed as argument. Make sure you write a function head which can be used as function who imports head as a module!python head.py poem.txt
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
>>> import head
>>> head.head("poem.txt")
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
for i in range(10):
print(i)
if i>5:
break
0 1 2 3 4 5 6
import myemail_module
sys
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[154], line 1 ----> 1 sys NameError: name 'sys' is not defined
myemail_module.sys
<module 'sys' (built-in)>
%%file head.py
import sys
def head(filepath, n):
with open(filepath) as f:
for i, line in enumerate(f):
print(line, end="")
if i>= n:
break
if __name__ == "__main__":
n = int(sys.argv[1])
filename = sys.argv[2]
head(filename, n)
Writing head.py
!python head.py 4 poem.txt
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex.
!python head.py 8 poem.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.
import head
head.head("poem.txt" , 3)
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit.
with open("poem.txt") as f:
for i in range(5):
print(f.readline(), end="")
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex.
with open("poem.txt") as f:
lines = [f.readline() for i in range(5)]
print("".join(lines))
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex.
import typer
def head(filepath, n):
with open(filepath) as f:
for i, line in enumerate(f):
print(line, end="")
if i>= n:
break
def head(filepath:str, n:int): # these are called type hints
with open(filepath) as f:
for i, line in enumerate(f):
print(line, end="")
if i>= n:
break
%%file head1.py
import typer
app = typer.Typer()
@app.command() # decorator
def head(filepath:str, n:int):
with open(filepath) as f:
for i, line in enumerate(f):
print(line, end="")
if i>= n:
break
if __name__ == "__main__":
app()
Writing head1.py
!python head1.py --help
Usage: head1.py [OPTIONS] FILEPATH N
Arguments:
FILEPATH [required]
N [required]
Options:
--install-completion [bash|zsh|fish|powershell|pwsh]
Install completion for the specified shell.
--show-completion [bash|zsh|fish|powershell|pwsh]
Show completion for the specified shell, to
copy it or customize the installation.
--help Show this message and exit.
!python head1.py poem.txt 5
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.
%%file welcome.py
import typer
app = typer.Typer()
@app.command()
def welcome(name:str):
print("Hello", name, "!")
if __name__ == "__main__":
app()
Writing welcome.py
!python welcome.py --help
Usage: welcome.py [OPTIONS] NAME
Arguments:
NAME [required]
Options:
--install-completion [bash|zsh|fish|powershell|pwsh]
Install completion for the specified shell.
--show-completion [bash|zsh|fish|powershell|pwsh]
Show completion for the specified shell, to
copy it or customize the installation.
--help Show this message and exit.
%%file welcome1.py
import typer
app = typer.Typer()
@app.command()
def welcome(n:int, name:str):
for i in range(n):
print("Hello", name, "!")
if __name__ == "__main__":
app()
Overwriting welcome1.py
!python welcome1.py --help
Usage: welcome1.py [OPTIONS] N NAME
Arguments:
N [required]
NAME [required]
Options:
--install-completion [bash|zsh|fish|powershell|pwsh]
Install completion for the specified shell.
--show-completion [bash|zsh|fish|powershell|pwsh]
Show completion for the specified shell, to
copy it or customize the installation.
--help Show this message and exit.
with open("digits.txt", "w") as f: # open file in write mode
f.write("one")
!python cat1.py digits.txt
one
with open("digits.txt", "w") as f:
f.write("one") # this will not add new line of its own
f.write("two")
!python cat1.py digits.txt
onetwo
with open("digits.txt", "w") as f:
f.write("one\n") # this will not add new line of its own
f.write("two\n")
f.write("three\n")
!python cat1.py digits.txt
one two three
with open("digits.txt", "a") as f: # open file in append mode
f.write("foure\n") # this will not add new line of its own
f.write("five\n")
f.write("six\n")
!python cat.py digits.txt
one two three foure five six
data
[[11, 12, 13], [21, 22, 23], [31, 32, 33]]
def write_csv(data2d, filename):
with open(filename, "w") as f:
for row in data2d:
strnums = [str(item) for item in row]
textline = ",".join(strnums)
f.write(textline) # it expects str
f.write("\n")
str(data[0])
'[11, 12, 13]'
[str(item) for item in data[0]]
['11', '12', '13']
",".join([str(item) for item in data[0]])
'11,12,13'
write_csv(data,"2ddata.txt")
!python cat.py 2ddata.txt
11,12,13 21,22,23 31,32,33
"This data takes one name another person and third friend and prints together"
def foomagic(name, person, friend):
return f"This data takes one {name} another {person} and third {friend} and prints together"
foomagic("Akash", "Aman", "Ashok")
'This data takes one Akash another Aman and third Ashok and prints together'
x = "whatever data"
f"this is data which makes use of {x}"
'this is data which makes use of whatever data'
template_email ="""
Dear {participant},
Here are your login credentials for the upcoming training
username: {username}
password: {password}
please login to https://engage.pipal.in using above details
Regards,
Pipal Academy
"""
print(template_email.format(participant="Akash", username="akash", password="kjshdhe@kajh"))
Dear Akash,
Here are your login credentials for the upcoming training
username: akash
password: kjshdhe@kajh
please login to https://engage.pipal.in using above details
Regards,
Pipal Academy
def generate_username(person):
return person.lower()
def send_email(person):
username = generate_username(person)
password = generate_password()
body = template_email.format(username=username, password=password, participant=person)
print(body)
f"hello {x}"
'hello whatever data'
def generate_email_body(participant, username, password):
return f"""
Dear {participant},
Here are your login credentials for the upcoming training
username: {username}
password: {password}
please login to https://engage.pipal.in using above details
Regards,
Pipal Academy
"""
def generate_username(person):
return person.lower()
def send_email(person):
username = generate_username(person)
password = generate_password()
body = generate_email_body(username=username, password=password, participant=person)
print(body)
send_email("Akash")
Dear Akash,
Here are your login credentials for the upcoming training
username: akash
password: Of2C5QZ6^
please login to https://engage.pipal.in using above details
Regards,
Pipal Academy
problem
tables that generates multiplication tables from 1 to 10 and writes it in csv file.>>> tables("tables.csv")
>>> print_contents("table.csv")
1,2,3,4,5,6,7,8,9,10
2,4,6,....