Module II - Day 2

Python Made Easy: Science and Math Edition

Sep-Dec 2025 batch, Vikrant Patil

Date: 08 Nov 2025

Click here for All Notes

© Vikrant Patil

Scripts

python scripts are text files with extension .py and it has python program written in it.

%%file x.txt
this is some text file 
which has some dummy text in it
we will save it as x.txt
Writing x.txt
%%file hello.py

print("hello")
Writing hello.py
!dir
about.qmd~      module2-day1.ipynb       students-module1-day4.ipynb
cat.py          notes.qmd            students-module2-day2.ipynb
hello.py        notes.qmd~           styles.css
index.qmd       poem.txt             testargs.py
index.qmd~      promotions           today.org
Makefile        push             topics.qmd
Makefile~       _quarto.yml          topics.qmd~
module1-day1.ipynb  _quarto.yml~         trainer.qmd
module1-day2.ipynb  revision.ipynb       trainer.qmd~
module1-day3.ipynb  _site            x.txt
module1-day4.ipynb  students-module1-day2.ipynb
module1-day5.ipynb  students-module1-day3.ipynb
!ls
about.qmd~      module2-day1.ipynb       students-module1-day4.ipynb
cat.py          notes.qmd            students-module2-day2.ipynb
hello.py        notes.qmd~           styles.css
index.qmd       poem.txt             testargs.py
index.qmd~      promotions           today.org
Makefile        push             topics.qmd
Makefile~       _quarto.yml          topics.qmd~
module1-day1.ipynb  _quarto.yml~         trainer.qmd
module1-day2.ipynb  revision.ipynb       trainer.qmd~
module1-day3.ipynb  _site            x.txt
module1-day4.ipynb  students-module1-day2.ipynb
module1-day5.ipynb  students-module1-day3.ipynb
!python hello.py
hello
%%file test_args.py
import sys

print(sys.argv)
Writing test_args.py
!python test_args.py
['test_args.py']
!python test_args.py hello
['test_args.py', 'hello']
!python test_args.py hello howdy
['test_args.py', 'hello', 'howdy']
!python test_args.py hello howdy jh kjhjkh  fsdkjfh kjhsdfsjkh
['test_args.py', 'hello', 'howdy', 'jh', 'kjhjkh', 'fsdkjfh', 'kjhsdfsjkh']
!python test_args.py hello 1 2 3
['test_args.py', 'hello', '1', '2', '3']
import sys
sys.argv
['/home/vikrant/usr/local/default/lib/python3.11/site-packages/ipykernel_launcher.py',
 '-f',
 '/home/vikrant/.local/share/jupyter/runtime/kernel-25a57f7c-66cc-44bb-8ddf-1c040d352940.json']
%%file say_hello.py
import sys

name = sys.argv[1]
print("Hello", name, "!")
Overwriting say_hello.py
!python say_hello.py vikrant
Hello vikrant !
import os
os.getcwd()
'/home/vikrant/programming/work/github/vikrant.dev/python-made-easy-science-math'
%%file square.py
import sys

n = int(sys.argv[1])

print(n**2)
Writing square.py
!python square.py 3
9
!python square.py 45
2025
%%file power.py
import sys
base = int(sys.argv[1])
exp = int(sys.argv[2])

print(base**exp)
Writing power.py
!python power.py 56 45
4660808027410506132900915088997417305944355117847144307414511042169984019070976
%%file  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!
Writing zen.txt

linux command head works like as given below. it takes filename as argument and prints it’s first 10 lines

problem

  • Write a python program head.py which will print first 10 lines of a file (which can be given as argument to the program)
%%file head.py
import sys

def print_10(filename):
    """prints first 10 lines of given file
    """
    with open(filename) as f:
        for i in range(10):
            print(f.readline(), end="")

filepath = sys.argv[1]
print_10(filepath)
    
Overwriting head.py
!python head.py 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.
!python head.py /home/vikrant/Downloads/Paytm_Wallet_Txn_History_Csv_Jan2018_8552969377.csv
"Date","Activity","Source/Destination","Wallet Txn ID","Comment","Debit","Credit","Transaction Breakup"
"03/01/2018 12:13:20","Bonus Added","Paytm Order #CST_BUS_TICKETS-NEW-BONUS-12791","17290661578","","","39",""
"03/01/2018 12:10:04","Restored to Paytm Cash against failed order","Paytm BUS Order #4371207130","17290624804","","","403",""
"03/01/2018 12:09:48","Restored to Paytm Cash against failed order","Paytm BUS Order #4371207130","17290621887","","","403",""
"02/01/2018 19:13:00","Added to Paytm Cash","Paytm Order #4378724688","17283050777","","","3000",""
"01/01/2018 16:38:04","Paid for Order","Paytm Order #4372700189","17270309471","","99","",""
"01/01/2018 11:58:26","Bonus Added","Paytm Order #CASH-667743869","17267568663","","","17",""
"01/01/2018 11:57:17","Bonus Added","Paytm Order #CASH-667743868","17267555880","","","17",""
"01/01/2018 11:57:04","Paid for Order","Paytm BUS Order #4371207130","17267553378","","918","",""
"31/12/2017 11:37:15","Restored to Paytm Cash against failed order","Paytm Order #4365510241","17256923639","","","30",""
import os
import random
import datetime
%%file cat.py
import sys

def cat(file):
    with open(file) as f:
        print(f.read())

if __name__ == "__main__":
    filename = sys.argv[1]
    cat(filename)
Overwriting cat.py
import cat
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!
!python cat.py 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!
import os
%%file maths_test.py

def square(x):
    return x*x

def power(x, y):
    return x**y


square(int(sys.argv[1]))
Writing maths_test.py
!python maths_test.py 5
Traceback (most recent call last):
  File "/home/vikrant/programming/work/github/vikrant.dev/python-made-easy-science-math/maths_test.py", line 9, in <module>
    square(int(sys.argv[1]))
               ^^^
NameError: name 'sys' is not defined
%%file maths_test.py
import sys

def square(x):
    return x*x

def power(x, y):
    return x**y


s = square(int(sys.argv[1]))
print(s) # print is necessary
Overwriting maths_test.py
!python maths_test.py 5
25
import maths_test
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[44], line 1
----> 1 import maths_test

File ~/programming/work/github/vikrant.dev/python-made-easy-science-math/maths_test.py:10
      6 def power(x, y):
      7     return x**y
---> 10 s = square(int(sys.argv[1]))
     11 print(s) # print is necessary

ValueError: invalid literal for int() with base 10: '-f'
sys.argv[1]
'-f'
%%file maths_test_new.py
import sys

def square(x):
    return x*x

def power(x, y):
    return x**y

if __name__ == "__main__":
    s = square(int(sys.argv[1]))
    print(s) # print is necessary
Writing maths_test_new.py
import maths_test_new
maths_test_new.square(5)
25
maths_test_new.power(4, 5)
1024

problem

  • Write a python program backup.py which will copy “.txt” files from source directory to destination dorectory. Your program should take source and destination as arguments to your script. make sure that you also write a function backup which takes two arguments src and dest and copied “.txt” files from src to dest folder.
%%file backup.py

def backup(src, dest, ext):
    

if __name__ == "main__":
    src = 
    dest = 
    ext
    backup(src, dest)
os.listdir()
['students-module1-day4.ipynb',
 'about.qmd~',
 'index.qmd',
 'say_hello.py',
 'topics.qmd~',
 'maths_test_new.py',
 'zen.txt',
 'notes.qmd',
 '_quarto.yml',
 'students-module2-day2.ipynb',
 'notes.qmd~',
 'push',
 'styles.css',
 'hello.py',
 'module1-day5.ipynb',
 'square.py',
 'trainer.qmd',
 'maths_test.py',
 'power.py',
 'promotions',
 '.quarto',
 'index.qmd~',
 '__pycache__',
 'testargs.py',
 'head.py',
 'x.txt',
 '_quarto.yml~',
 '_site',
 '.gitignore',
 'students-module1-day2.ipynb',
 'module1-day1.ipynb',
 'module1-day2.ipynb',
 'topics.qmd',
 'cat.py',
 'module2-day1.ipynb',
 'trainer.qmd~',
 'test_args.py',
 'module1-day3.ipynb',
 'revision.ipynb',
 'Makefile~',
 'poem.txt',
 'students-module1-day3.ipynb',
 'Makefile',
 '.ipynb_checkpoints',
 'module1-day4.ipynb',
 'today.org']
os.listdir("/home/vikrant/Downloads/(4) WhatsApp_files/")
['180005040_453720339259962_5368109512336153976_n.jpg',
 'bootstrap_qr-e2b403f65ed52d327e90.css',
 '185546772_831040937612399_3354811957197905299_n.jpg',
 '2617e32ba41ae37a81350005624747b8_w_2219-40.png',
 '201508185_5643018052380614_6407965225824007693_n.jpg',
 'runtime.eec711118910bb31a0e9.js',
 'lazy_loaded_high_priority_components.28727c2e97a12de0730e.css',
 '290586532_608858897465375_3003610072311444366_n.jpg',
 '263339536_3298849273693494_6905473995516229735_n.jpg',
 '300281757_438105841673864_6141358954324473083_n.jpg',
 'bootstrap_qr.bfdc9aa860df389e0e77.js',
 '300113676_213524927667264_2933781485502229424_n.jpg',
 '299355672_763426878269415_7784161758856899170_n.jpg',
 'libsignal-protocol-ee5b8ba.min.js',
 '298017554_781717376596317_983843700116375888_n.jpg',
 '180005040_453720339259962_5368109512336153976_n_002.jpg',
 'vendor1~bootstrap_qr.e2addc7b55065fc8b3e2.js',
 '173647552_902747126957292_1725969723666481502_n.jpg',
 'stylex-2d46744708947781f1f33a0069cbc308.css',
 '217424826_372743817599798_1691656623479303026_n.jpg',
 '2617e32ba41ae37a81350005624747b8_w_961-40.png',
 '2617e32ba41ae37a81350005624747b8_w_2219-64.png',
 '286583185_1038144407066517_3370468006618438227_n.jpg',
 '154897788_404272827756826_6240512880025439805_n.jpg',
 'lazy_loaded_low_priority_components.30f1586fa045ee004f53.css',
 '150561101_1164301287344428_6396876267465337174_n.jpg',
 'bootstrap_main.9d6050e3d2fff5b782d3.css']
numbers = [323, 1, 2, 3, 5, 2, 5, 2, 7, 2, 42]
def is_even(x):
    return x%2==0

def filter_evens(numbers):
    nums_even = []
    for n in numbers:
        if is_even(n):
            nums_even.append(n)
    return nums_even
filter_evens(numbers)
[2, 2, 2, 2, 42]
def check_ext(filename, ext):
    return filename.split(".")[-1] == ext
check_ext("x.txt", "txt")
True
check_ext("x.txt", "pdf")
False
check_ext("x.pdf", "pdf")
True

os.copy_file_range?
Signature: os.copy_file_range(src, dst, count, offset_src=None, offset_dst=None)
Docstring:
Copy count bytes from one file descriptor to another.
  src
    Source file descriptor.
  dst
    Destination file descriptor.
  count
    Number of bytes to copy.
  offset_src
    Starting offset in src.
  offset_dst
    Starting offset in dst.
If offset_src is None, then src is read from the current position;
respectively for offset_dst.
Type:      builtin_function_or_method
import shutil
shutil.copyfile?
Signature: shutil.copyfile(src, dst, *, follow_symlinks=True)
Docstring:
Copy data from src to dst in the most efficient way possible.
If follow_symlinks is not set and src is a symbolic link, a new
symlink will be created instead of copying the file it points to.
File:      /usr/lib/python3.11/shutil.py
Type:      function
shutil.copy("zen.txt", "copyzen.txt")
'copyzen.txt'
!python head.py copyzen.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.

Homework

  • Write a python script tail.py which will print last 5 lines of a file. this is how it should work.

    python tail.py zen.txt
    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!
  • Write a python script chaos.py which prints first 10 iterations of x which is computed using follwing logic. To start with some value of x is given by user (from command line arguments). After that for each iteration new value of x is generated using the equation x = 3.9 * x * (1 - x) after computing new value of x print it to screen. See what happens to value of x at 10 itertion for different starting values of x i.e. 0.24, 0.25, 0.26, 0.3 etc.

    python chaos.py 0.25
    0.731250
    0.766441
    0.698135
    0.821896
    0.570894
    0.955399