Module III - Day 1

Python Made Easy: Science and Math Edition

Sep-Dec 2025 batch, Vikrant Patil

Date: 20 Dec 2025

Click here for All Notes

Live note are here https://vikrant.dev/python-made-easy-science-math/module3-day1.html

Please login to https://traininghub.vikrant.dev and create a notebook with name module3-day1.ipynb

© Vikrant Patil

Functions as arguments

def foo(a, b):
    return a + b
    
foo
<function __main__.foo(a, b)>
def square(x):
    return x*x

def cube(x):
    return x*x*x

def sumofsquares(a, b, c):
    return square(a) + square(b) + square(c)


def sumofcubes(a, b, c):
    return cube(a) + cube(b) + cube(c)


def sumof(a, b, c, func):
    return func(a) + func(b) + func(c)

    
sumofsquares(12, 34, 15)
1525
sumof(12, 34, 15, sqaure)
1525
sumofcubes(23, 12, 34)
53199
sumof(23, 12, 34, cube)
53199
words = ["one", "two", "three", "four", "five", "six", "seven"]
max(words) # maximum by dictionary order , alphabetical 
'two'
max(words, key=len)
'three'
nums = [1,1, 2, 3, 5, 5]
max(nums)
5
def mylen(word):
    print(word)
    return len(word)
max(words, key=mylen)
one
two
three
four
five
six
seven
'three'
def mymax(items, key=None):
    m = words[0]
    v = key(words[0])
    for word in words[1:]:
        v1 = key(word)
        if v1 > v:
            m = word
            v = v1
    return m
mymax(words, key=mylen)
one
two
three
four
five
six
seven
'three'
records = [
    ("TATA", 200.0, 5.5),
    ("INFY", 2000.0, -5),
    ("RELIANCE", 1505.5, 50.0),
    ("HCL", 1200, 70.5)
  ]
records[0]
('TATA', 200.0, 5.5)
r = records[0]
r
('TATA', 200.0, 5.5)
r[0]
'TATA'
r[1]
200.0
r[2]
5.5
def get_value(r):
    return r[1]

def get_gain(r):
    return r[2]
max(records)
('TATA', 200.0, 5.5)
max(records, key=get_value)
('INFY', 2000.0, -5)
max(records, key=get_gain)
('HCL', 1200, 70.5)
min(records, key=get_gain)
('INFY', 2000.0, -5)
min(records, key=get_value)
('TATA', 200.0, 5.5)
%%file records.csv
symbol,value,gain
"TATA",200.0,5.5
"INFY",2000.0,-5
"RELIANCE",1505.5,50.0
"HCL",1200,70.5
Writing records.csv
import csv
def read_data(filename):
    with open(filename) as f:
        fd = csv.DictReader(f)
        return [line for line in fd]
    
read_data("records.csv")    
[{'symbol': 'TATA', 'value': '200.0', 'gain': '5.5'},
 {'symbol': 'INFY', 'value': '2000.0', 'gain': '-5'},
 {'symbol': 'RELIANCE', 'value': '1505.5', 'gain': '50.0'},
 {'symbol': 'HCL', 'value': '1200', 'gain': '70.5'}]
data = read_data("records.csv")
data
[{'symbol': 'TATA', 'value': '200.0', 'gain': '5.5'},
 {'symbol': 'INFY', 'value': '2000.0', 'gain': '-5'},
 {'symbol': 'RELIANCE', 'value': '1505.5', 'gain': '50.0'},
 {'symbol': 'HCL', 'value': '1200', 'gain': '70.5'}]
data[0]
{'symbol': 'TATA', 'value': '200.0', 'gain': '5.5'}
def get_value(dictrow):
    return float(dictrow['value'])
max(data, key=get_value)
{'symbol': 'INFY', 'value': '2000.0', 'gain': '-5'}
def get_gain(dictrow):
    return float(dictrow['gain'])
max(data, key=get_gain)
{'symbol': 'HCL', 'value': '1200', 'gain': '70.5'}
sorted(data, key=get_value)
[{'symbol': 'TATA', 'value': '200.0', 'gain': '5.5'},
 {'symbol': 'HCL', 'value': '1200', 'gain': '70.5'},
 {'symbol': 'RELIANCE', 'value': '1505.5', 'gain': '50.0'},
 {'symbol': 'INFY', 'value': '2000.0', 'gain': '-5'}]
sorted(words, key=len)
['one', 'two', 'six', 'four', 'five', 'three', 'seven']

Automatation of invoice generation

items to take input

  • document number
  • coustomer details
  • po (file)

Items to be generated automatically

  • date
  • Invoice number

items that will remain constant

  • vendor
  • hsn
  • address
  • logo
  • gst
  • account details
%%file hello.py
import sys

name = sys.argv[1]

print("Hello", name)
Overwriting hello.py
!python hello.py vikrant
Hello vikrant
import typer
%%file invoice-generator.py
import typer


def generate_invoice(document_num:str, pofile:str, customer:str):
    pass


if __name__ == "__main__":
    typer.run(generate_invoice)
Writing invoice-generator.py
!python invoice-generator.py --help
                                                                                

 Usage: invoice-generator.py [OPTIONS] DOCUMENT_NUM POFILE CUSTOMER             

                                                                                

╭─ Arguments ──────────────────────────────────────────────────────────────────╮

│ *    document_num      TEXT  [required]                                      │

│ *    pofile            TEXT  [required]                                      │

│ *    customer          TEXT  [required]                                      │

╰──────────────────────────────────────────────────────────────────────────────╯

╭─ Options ────────────────────────────────────────────────────────────────────╮

│ --help          Show this message and exit.                                  │

╰──────────────────────────────────────────────────────────────────────────────╯


!python invoice-generator.py AASAS121323 bosch-po1.csv bosch.csv
%%file po1.csv
item,description,quntity,unitprice,totalprice
10,plc service1,2,10000,20000
20,plc service2,3,4000,12000
30,plc service3,1,20000,20000
Writing po1.csv
%%file hypotheticals.csv
name, address, GSTIN
Hypothetical Ltd,"240,At post ABC, near XYZ, CITY, 411020", 27ZOBLL95691Z0
Overwriting hypotheticals.csv
%%file invoice-generator.py
import typer
import csv


GSTIN = "27ASBLL55591Z0"

def read_po(pofile):
    with open(pofile) as f:
        d_po = csv.DictReader(f)
        return [line for line in d_po]

def read_customer_details(customerfile):
    with open(customerfile) as f:
        d_po = csv.DictReader(f)
        return next(d_po)
    

def generate_invoice(document_num:str, pofile:str, customer:str):
    print(document_num)
    print(read_po(pofile))
    print(read_customer_details(customer))
    

if __name__ == "__main__":
    typer.run(generate_invoice)
Overwriting invoice-generator.py
!python invoice-generator.py --help
                                                                                

 Usage: invoice-generator.py [OPTIONS] DOCUMENT_NUM POFILE CUSTOMER             

                                                                                

╭─ Arguments ──────────────────────────────────────────────────────────────────╮

│ *    document_num      TEXT  [required]                                      │

│ *    pofile            TEXT  [required]                                      │

│ *    customer          TEXT  [required]                                      │

╰──────────────────────────────────────────────────────────────────────────────╯

╭─ Options ────────────────────────────────────────────────────────────────────╮

│ --help          Show this message and exit.                                  │

╰──────────────────────────────────────────────────────────────────────────────╯


!python invoice-generator.py SASA7647236 po1.csv hypotheticals.csv
SASA7647236
[{'item': '10', 'description': 'plc service1', 'quntity': '2', 'unitprice': '10000', 'totalprice': '20000'}, {'item': '20', 'description': 'plc service2', 'quntity': '3', 'unitprice': '4000', 'totalprice': '12000'}, {'item': '30', 'description': 'plc service3', 'quntity': '1', 'unitprice': '20000', 'totalprice': '20000'}]
{'name': 'Hypothetical Ltd', ' address': '240,At post ABC, near XYZ, CITY, 411020', ' GSTIN': ' 27ZOBLL95691Z0'}
import csv
with open("po1.csv") as f:
    d = csv.DictReader(f)
    print(next(d))
{'item': '10', 'description': 'plc service1', 'quntity': '2', 'unitprice': '10000', 'totalprice': '20000'}
import xlsxwriter
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[72], line 1
----> 1 import xlsxwriter

ModuleNotFoundError: No module named 'xlsxwriter'
!pip install xlsxwriter
Collecting xlsxwriter
  Using cached xlsxwriter-3.2.9-py3-none-any.whl.metadata (2.7 kB)
Using cached xlsxwriter-3.2.9-py3-none-any.whl (175 kB)
Installing collected packages: xlsxwriter
Successfully installed xlsxwriter-3.2.9
import xlsxwriter
import xlsxwriter

workbook = xlsxwriter.Workbook('image.xlsx')
worksheet = workbook.add_worksheet()

logo = '/home/vikrant//logo.png'
# Original image.
worksheet.insert_image('B2', logo)

# Same size as original, despite row/col changes.
worksheet.insert_image('E8', logo)

# Make column F narrower.
worksheet.set_column('F:F', 2)

# Hide row 10 (zero indexed).
worksheet.set_row(9, None, None, {'hidden': True})

workbook.close()
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In[76], line 8
      6 logo = '/home/vikrant/Picutures/logo.png'
      7 # Original image.
----> 8 worksheet.insert_image('B2', logo)
     10 # Same size as original, despite row/col changes.
     11 worksheet.insert_image('E8', logo)

File ~/usr/local/default/lib/python3.13/site-packages/xlsxwriter/worksheet.py:114, in convert_cell_args.<locals>.cell_wrapper(self, *args, **kwargs)
    111     new_args = xl_cell_to_rowcol(first_arg)
    112     args = new_args + args[1:]
--> 114 return method(self, *args, **kwargs)

File ~/usr/local/default/lib/python3.13/site-packages/xlsxwriter/worksheet.py:1584, in Worksheet.insert_image(self, row, col, source, options)
   1581     return -1
   1583 # Convert the source to an Image object.
-> 1584 image = self._image_from_source(source, options)
   1586 image._row = row
   1587 image._col = col

File ~/usr/local/default/lib/python3.13/site-packages/xlsxwriter/worksheet.py:5254, in Worksheet._image_from_source(self, source, options)
   5252     image.image_name = source
   5253 else:
-> 5254     image = Image(source)
   5256 return image

File ~/usr/local/default/lib/python3.13/site-packages/xlsxwriter/image.py:70, in Image.__init__(self, source)
     67 self._y_dpi: float = DEFAULT_DPI
     68 self._digest: Union[str, None] = None
---> 70 self._get_image_properties()

File ~/usr/local/default/lib/python3.13/site-packages/xlsxwriter/image.py:181, in Image._get_image_properties(self)
    178     data = self.image_data.getvalue()
    179 else:
    180     # Open the image file and read in the data.
--> 181     with open(self.filename, "rb") as fh:
    182         data = fh.read()
    184 # Get the image digest to check for duplicates.

FileNotFoundError: [Errno 2] No such file or directory: '/home/vikrant/Picutures/logo.png'