Python Virtual Training For Arcesium - Module II - Day 2¶

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

  • find sum of multiples of 7 or 11 below 1000
  • Write a function which finds all factors of given number(include 1 and self)
  • Write a function is_prime which checks if given number is prime or not
  • Write a list comprehension to generate prime numbers

bonus

  • There is a string "abrakadabra", we want to capitalize alternate character from it. how can we do it? can a list comprehension be used to do this?
  • Write a function to extract a column from 2D list
>>> data = [[11, 12, 13],
            [21, 22, 23],
            [31, 32, 33]]
>>> column(data, 0)
[11, 21, 31]
In [1]:
[e for e in range(10) if e%2==0]
Out[1]:
[0, 2, 4, 6, 8]
In [3]:
sum([n for n in range(1, 1001) if n%7==0 or n%11==0]) 
Out[3]:
110110
In [4]:
def factors(n):
    return [i for i in range(1,n+1) if n%i==0]
In [5]:
factors(5)
Out[5]:
[1, 5]
In [6]:
factors(10)
Out[6]:
[1, 2, 5, 10]
In [7]:
factors(7)
Out[7]:
[1, 7]
In [8]:
factors(11)
Out[8]:
[1, 11]
In [9]:
factors(13)
Out[9]:
[1, 13]
In [10]:
def is_prime(n):
    return factors(n) == [1, n]
In [11]:
is_prime(4)
Out[11]:
False
In [12]:
is_prime(5)
Out[12]:
True
In [16]:
def primes(n):
    """generates primes numbers less than n
    """
    return [p for p in range(1, n+1) if is_prime(p)]
In [14]:
list(range(10))
Out[14]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [15]:
list(range(1, 11))
Out[15]:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In [17]:
primes(20)
Out[17]:
[2, 3, 5, 7, 11, 13, 17, 19]
In [18]:
primes(100)
Out[18]:
[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]
  • Write a function to extract a column from 2D list
>>> data = [[11, 12, 13],
            [21, 22, 23],
            [31, 32, 33]]
>>> column(data, 0)
[11, 21, 31]
In [21]:
data = [[11, 12, 13],
        [21, 22, 23],
        [31, 32, 33]]
In [20]:
data
Out[20]:
[[11, 12, 13], [21, 22, 23], [31, 32, 33]]
In [22]:
data[0] #zeroth row
Out[22]:
[11, 12, 13]
In [23]:
data[1] # first row
Out[23]:
[21, 22, 23]
In [24]:
data[2] # second row
Out[24]:
[31, 32, 33]
In [25]:
data[0][0] # zeroth item from zeroth row
Out[25]:
11
In [26]:
data[1][0] # zeroth item from 1st row
Out[26]:
21
In [27]:
data[2][0] # zeroth item from 2nd row
Out[27]:
31
In [28]:
def column(data2d, n):
    rowcount = len(data2d)
    return [data2d[i][n] for i in range(rowcount)]
        
In [29]:
column(data, 0)
Out[29]:
[11, 21, 31]
In [30]:
column(data, 1)
Out[30]:
[12, 22, 32]
In [ ]:
def column(data2d, n):
    rowcount = len(data2d)
    return [data2d[i][n] for i in range(rowcount)]
        
In [31]:
students = ["Akash", "Priya", "Aman"]
In [32]:
students[0]
Out[32]:
'Akash'
In [33]:
students[2]
Out[33]:
'Aman'
In [35]:
[students[i] for i in range(len(students))]
Out[35]:
['Akash', 'Priya', 'Aman']
In [36]:
[student for student in students]
Out[36]:
['Akash', 'Priya', 'Aman']
In [41]:
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!
        
In [38]:
column(data, 0)
Out[38]:
[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'
In [88]:
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)
    
In [89]:
import string
In [90]:
string.ascii_letters
Out[90]:
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
In [91]:
import random
In [92]:
random.choice(string.ascii_letters)
Out[92]:
'j'
In [93]:
generate_password()
Out[93]:
'egh7SfbvOmb5Qc#'
In [64]:
random.choice(range(7, 15))
Out[64]:
11
In [99]:
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
    
In [100]:
generate_password()
Out[100]:
'YxyxneffdaxT#'
In [96]:
generate_password()
Out[96]:
'bZixCTO0r4)'
In [68]:
generate_password()
Out[68]:
'J5TYMFj4EJVw&'
In [77]:
 
In [81]:
generate_password()
Out[81]:
'fM0$fIqpDKV%'
In [101]:
random.choice(primes(100))
Out[101]:
83
In [103]:
random.random() # this generates random number between 0 to 1
Out[103]:
0.1618221782343795

Reading files¶

In [104]:
%%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
In [105]:
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!

In [106]:
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!
In [107]:
text = "hello world"
In [108]:
print(text)
hello world
In [109]:
anothertext = """hello
world"""
In [110]:
print(anothertext)
hello
world
In [111]:
anothertext
Out[111]:
'hello\nworld'
In [112]:
with open("poem.txt") as filehandle:
    lines = [line for line in filehandle]
In [113]:
lines
Out[113]:
['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"]
In [114]:
import os
In [115]:
os.getcwd()
Out[115]:
'/home/vikrant/trainings/2023/arcesium_finop_jan'
In [116]:
filepath = os.path.join('/home/vikrant/trainings/2023/arcesium_finop_jan', "poem.txt")
In [117]:
filepath
Out[117]:
'/home/vikrant/trainings/2023/arcesium_finop_jan/poem.txt'
In [118]:
with open(filepath) as f:
    completefiledata = f.read()
In [119]:
completefiledata
Out[119]:
"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"
In [120]:
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!

In [123]:
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!
==========

Example of cat command¶

In [125]:
!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!
In [126]:
%%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
In [127]:
!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!
In [128]:
%%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
In [129]:
import stats
In [130]:
stats.mean([1, 2, 3, 4])
Out[130]:
2.5
In [131]:
stats.std([])
Yet to be implemented!
In [132]:
%%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
In [133]:
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'
In [134]:
%%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
In [136]:
!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!
In [138]:
import cat1 # __name__ -> cat1 
  • all emails having a word "Mircosoft" in subject
  • from those emails extact pdf
  • email it to internal team internalteam@arcsium.com
In [141]:
%%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
In [142]:
!python3 myemail_module.py Microsoft mircosoft_team@arcesium.com
In [148]:
%%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
In [149]:
!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'
In [150]:
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'
In [151]:
%%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

  • Write a script 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.
In [ ]:
 
In [152]:
for i in range(10):
    print(i)
    if i>5:
        break
0
1
2
3
4
5
6
In [153]:
import myemail_module
In [154]:
sys
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[154], line 1
----> 1 sys

NameError: name 'sys' is not defined
In [155]:
myemail_module.sys
Out[155]:
<module 'sys' (built-in)>
In [156]:
%%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
In [ ]:
 
In [157]:
!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.
In [158]:
!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.
In [159]:
import head
In [160]:
head.head("poem.txt" , 3)
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
In [162]:
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.
In [163]:
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.

In [164]:
import typer
In [165]:
def head(filepath, n):
    with open(filepath) as f:
        for i, line in enumerate(f):
            print(line, end="")
            if i>= n:
                break
                
In [166]:
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
                
In [167]:
%%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
In [168]:
!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.
In [169]:
!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.
In [170]:
%%file welcome.py
import typer
app = typer.Typer()

@app.command()
def welcome(name:str):
    print("Hello", name, "!")
    
if __name__ == "__main__":
    app()
Writing welcome.py
In [171]:
!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.
In [174]:
%%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
In [175]:
!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.

Writing files¶

In [176]:
with open("digits.txt", "w") as f: # open file in write mode
    f.write("one")
In [178]:
!python cat1.py digits.txt
one
In [179]:
with open("digits.txt", "w") as f:
    f.write("one") # this will not add new line of its own
    f.write("two")
In [180]:
!python cat1.py digits.txt
onetwo
In [181]:
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")
In [182]:
!python cat1.py digits.txt
one
two
three
In [183]:
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")
In [185]:
!python cat.py digits.txt
one
two
three
foure
five
six
In [186]:
data
Out[186]:
[[11, 12, 13], [21, 22, 23], [31, 32, 33]]
In [198]:
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")
    
In [189]:
str(data[0])
Out[189]:
'[11, 12, 13]'
In [190]:
[str(item) for item in data[0]]
Out[190]:
['11', '12', '13']
In [192]:
",".join([str(item) for item in data[0]])
Out[192]:
'11,12,13'
In [199]:
write_csv(data,"2ddata.txt")
In [200]:
!python cat.py 2ddata.txt
11,12,13
21,22,23
31,32,33

String formatting¶

In [ ]:
"This data takes one name another person and third friend and prints together"
In [201]:
def foomagic(name, person, friend):
    return f"This data takes one {name} another {person} and third {friend} and prints together"
In [202]:
foomagic("Akash", "Aman", "Ashok")
Out[202]:
'This data takes one Akash another Aman and third Ashok and prints together'
In [203]:
x = "whatever data"
In [204]:
f"this is data which makes use of {x}"
Out[204]:
'this is data which makes use of whatever data'
In [205]:
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
"""
In [208]:
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

In [211]:
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)
In [209]:
f"hello {x}"
Out[209]:
'hello whatever data'
In [213]:
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)
In [214]:
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

  • Write a function 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,....
In [ ]: