Python IITM Foundational Course
Python IITM Foundational Course
Python -IITM
WEEK 1 - 1-14 LEC:
PRINT
Numbers are treated as numbers only when put without apostrophe/speech marks
print("Hello world")
print('Hello world', 'Hello mom', 'Hello nietzsche')
print(10)
VARIABLES
Input commands
print("Enter a number")
num=int(input())
print(num)
x = 10
del x
print(x)
#shows error x not defined
DATA TYPES 1
int - Integer
Python -IITM 1
list -
Self explanatory
DATA TYPES 2
bool - Boolean - Takes either true or false as input. T of true and F of false must always be capital
b1 = True
b2 = False
a = float(9)
b = int(2.4)
c = int('11')
a = bool(100)
b = bool(-10.9)
c = bool(0)
d = bool('') #empty string
💡 Follows BODMAS
MATHEMATICAL
- - Subtract
print(7/3)
#prints 2.333333333333335
Python -IITM 2
* - Multiplication
print(7//3)
#prints 2
% - Modulus - Remainder
print(7%3)
#prints 1
** - Exponential
RELATIONAL
== - Compares the two operands and returns the value as either True or False
print(5==50)
#prints False
print(5==5)
#prints True
!= - Not Equals to
print(5!=50)
#prints True
print(5!=5)
#prints False
LOGICAL
STRINGS
💡 Strings are treated like a list. Their letters are indexed just like lists. Starting from 0.
s = 'coffee'
t = 'bread'
print(s[1:3]) #1:3 - goes from 1 to 2
#prints of
print(s[1:5]) #1:5 - goes from 1 to 4
#prints offe
s='coffee'
t='bread'
print(s+t)
#prints coffeebread
s = 'good'
print(s[0]*5)
#prints ggggg
Python -IITM 3
print('apple' > 'one')
#prints False because a comes before o. it compares every letter of the string
print('abce'> 'abcd')
#prints True
s='huioiklopopopojhue'
print(len(s)) #prints length of the string
#prints 18
count = count + 1
-= , *= , /= - Self explanatory
Special operator
in - In operator - used to find some specific value in a string or variable or list, etc.
print('alpha' in 'A variable name can only contain alpha-numeric characters and underscores')
#prints True as the string contains the word alpha
print('alpha' in 'A variable name must start with a letter or the underscore character')
#prints False as the string doesn't contain the word alpha
Chaining operator
When two or more relational operators are used together.
x = 5
print(10<x<15)
#prints False as 5 is smaller than 10. Basically it acts like an OR logic gate. both statements need to be true to get the outp
Escape characters
\ - Back slash
Python -IITM 4
\n - New line in the same print command
Quotes
‘’’ ‘’’ - Multi line string
z='''Amaan
AM
AP'''
print(z)
#prints Amaan
#AM
#AP
'''comment1
comment2
comment3'''
String Methods
Code x = ‘pytHoN
Method Description Output
sTrIng mEthOds’
converts a string
lower() print(x.lower()) python string methods
into lower case
converts a string
upper() print(x.upper()) PYTHON STRING METHODS
into upper case
Python -IITM 5
Method Description Code Output
Code x=’——Python
Method Description Output
——’
strip() Returns a trimmed version of the string print(x.strip(’-’)) Python
lstrip() Returns a left trim version of the string print(x.lstrip(’-’)) Python——
rstrip() Returns a right trim version fo the string print(x.rstrip(’-’)) ——Python
we used %26 to make sure the code doesn’t break if our ‘ n ’ has z in it.
%26 = we are calling out reminder after we divide our index number with 26 - so if ‘z’ i.e. 26 is divided by 26 it’ll give
we store it in an empty string t and append it with the letters shifted +1 of our n
al='abcdefghijklmnopqrstuvwxyz'
t=''
i=0
k=1
n='amaan'
#to print bnbbo - a letter shifter of my name
t+=(al[(al.index(n[i])+k)%26])
t+=(al[(al.index(n[i+1])+k)%26])
t+=(al[(al.index(n[i+2])+k)%26])
t+=(al[(al.index(n[i+3])+k)%26])
t+=(al[(al.index(n[i+4])+k)%26])
print(t)
Python -IITM 6
https://replit.com/@weakgeek/ceaser-cipher?v=1
If statement
Python -IITM 7
WEEK 3 - 27-40 LEC:
While loop
It gets executed till the condition is met
while(yr!=1947):
print("You got it wrong. Enter once again.")
yr=int(input())
print("You got it right!")
Compute Factorial:
When the first time while loop runs f=1*1 and i is incremented by 1. Hence i becomes 2.
Now the second time runs i is 2. Hence f=1*2=2. Again i is incremented and becomes 2+1 = 3.
Python -IITM 8
n=int(input("Enter the number:"))
i=1
f=1
if (n>0):
while(i<=n):
f=f*i
i=i+1
print("Factorial is:", f)
else:
print("Invalid input")
digits = 1
while (n > 9):
n = n // 10
digits += 1
print("Number of digits are:", digits)
Python -IITM 9
n=int(input("Enter the number:"))
num=abs(n)
sum=0
while(num>0):
r=num%10
sum=sum*10+r
num=num//10
if(n<=0):
print(sum-(2*sum))
else:
print(sum)
Firstly, the num is divided by 10 to get its remiander - % is used for that. When we divide any number by 10 to
get its remainder the remainder is always the last digit of the number. So r is the last digit of the input number
now.
sum=sum*10+r puts the last digit of the input number r as the first digit of the reverse number.
num=num//10 gives the int quotient of the initial number when divided by 10. Any number when divided by 10
gives the integer quotiet the nummber itself bar the last digit of it. i.e. 1234//10 gives 123.
The sum=sum*10+r for 1234 looks like sum=4 for the first cycle. sum=4*10+3 for the second cycle. sum=43*10+2
for the third cycle. sum=432*10+1 for the last cycle.
Python -IITM 10
n=int(input("Enter the number:"))
num=abs(n)
sum=0
while(num>0):
r=num%10
sum=sum*10+r
num=num//10
if(sum==n or (sum-2*sum)==n):
print('Palindrome')
else:
print('Not a palindrome')
For loop
Adding first n numbers
Formatted Printing
end - Attribute for the end of a command/string, etc. Default value is \n (new line)
for x in range(10):
print(x, end = ' ')
#prints 0,1,2,3,4,5,6,7,8,9
d=10,m=5,y=2022
print("Today's date is", d,m,y, end=' ', sep='-')
#prints Today's date is 10-5-2022
.format - In this method of formatting the print statement the variable are assigned indices and are later designated
String modulo operator - An old way of writing print statement. Was used by C language.
%d - integer
%f - float
Python -IITM 11
pi=22/7
print('value of Pi =%f' % (pi))
#shows only 6 digits after the point - 3.142857 because its an old method
pi=22/7
print(f'Va1ue of Pi = {pi:.2f}')
print('Value of Pi = {0:.2f}'.format(pi))
print('Value of Pi = %.2f %(pi))
#prints 2 value after point i.e. 3.14
print('{0:5d}'.format(1))
print('{0:5d}'.format(11))
print('{0:5d}'.format(111))
print('{0:5d}'.format(1111))
print('{0:5d}'.format(11111))
the code above specifies that the computer must use atleast 5 characters in the print statement. {0:5d}
Nested loops
P3
Python -IITM 12
nod=int(input("Enter number of days: "))
for i in range(1,(nod+1)):
sum=0
rain=int(input("Enter the rainfall: "))
while(rain!=-1):
sum=sum+rain
rain=int(input("Enter the rainfall: "))
print('Total rainfall for {0} days is {1}'.format(i,sum))
P4
Python -IITM 13
Break, Continue and Pass
break
continue
#to print username and email service used from the input emailID
email=input("Enter the email ID: ")
for x in email:
if(x=='@'):
print('')
continue
print(x, end='')
#prints, ex:
amanaskdk
gmail.com
pass
#to print the numbers less than 10 divisible by 3 and do nothing with the numbers that aren't
for i in range(11):
if(i%3==0):
print(i)
else:
pass
Common Commands:
l=[1,2,3,4,5]
l.append(6)
print(l)
'''Prints [1,2,3,4,5,6]'''
l=[1,2,3,4,5,6]
l.remove(6)
print(l)
'''Prints [1,2,3,4,5]'''
Python -IITM 14
l=[1,2,6,8,3,5,75,854,9]
l.sort()
print(l)
'''[1, 2, 3, 5, 6, 8, 9, 75, 854]'''
m=[]
m.append([1,2,3])
m.append([4,5,6])
m.append([7,8,9])
print(m)
'''prints [[1, 2, 3], [4, 5, 6], [7, 8, 9]]'''
print(m[0][0])
print(m[0][1])
print(m[2][2])
''''prints 1
2
3'''
#this is how we create a matrix
Birthday Paradox
import random
l=[]
for i in range(60):
l.append(random.randint(1,365))
l.sort()
print(l)
i=0
flag=0
while(i<len(l)-1):
if(l[i]==l[i+1]):
print("Repeats", l[i], l[i+1])
flag=1
pass
i=i+1
if(flag==0):
print("There is no repetition")
'''
Output example:
[10, 14, 22, 24, 25, 25, 25, 34, 58, 69, 83, 84, 88, 90, 92, 97, 100, 112, 114, 116, 120, 128, 131, 134, 154, 164, 168, 173, 17
Repeats 25 25
Repeats 25 25
Repeats 294 294'''
Then we use the for loop to cycle through the random integers that randint parameter generates.
randint is used in place of random.random because the latter generates float numbers too and DOBs cant be float
numbers
We use the flag to make sure the while loop first checks all the numbers in the list and then displays if there was
repetition or not
We use the pass command to make sure our program enlists all the repetitive numbers/DOBs
import random
l=[]
for i in range(10000):
l.append(random.randint(1,10000))
while(n>-1):
n=int(input("Enter a number:, type -1 to exit")
flag=0
for i in range(len(l)):
if (a==l[i]):
print("Found it!")
flag=1
Python -IITM 15
break
if (flag==0):
print("Not found!")
l=[1,6,2,9,241,66,854,30,5,8]
m=[]
while(len(l)>0):
min=l[0]
for i in range(len(l)):
if l[i]<min:
min=l[i]
m.append(min)
l.remove(min)
print(m)
Dot Product
l=[1,6,2,9,241,66,854,30,71]
y=[342,5,61,34,77,54,85,893,8]
sum=0
for i in range(len(l)):
sum=sum+l[i]*y[i]
print(sum)
Matrix Addition
dim=3
r1=[1,2,3]
r2=[4,5,6]
r3=[7,8,9]
s1=[2,5,1]
s2=[9,8,5]
s3=[5,3,6]
A=[]
A.append(r1)
A.append(r2)
A.append(r3)
B=[]
B.append(s1)
B.append(s2)
B.append(s3)
print(A)
print(B)
C=[[0,0,0],[0,0,0],[0,0,0]]
for i in range(dim):
for j in range(dim):
C[i][j] = A[i][j]+B[i][j]
print(C)
This code can be automated by asking for inputs from the user of the elements and dimensions of matrices.
Matrix Multiplication
Python -IITM 16
This is how matrix multiplication happens.
For C[3][2] we have to find the dot product of A[3][0].B[0][2] + A[3][1].B[1][2] + A[3][2].B[2][2] + A[3][3].B[3][2] + A[3]
[4].B[4][2] + A[3][5].B[5][2] + A[3][6].B[6][2]
We observe that the row of first matrix remains same and the column changes and the column of secod matrix
remains same and its row changes.
Hence we can use a loop to find the dot products and sum them up to get the product of two matrices
dim=3
r1=[1,2,3]
r2=[4,5,6]
r3=[7,8,9]
s1=[2,5,1]
s2=[9,8,5]
s3=[5,3,6]
A=[]
A.append(r1)
A.append(r2)
A.append(r3)
B=[]
B.append(s1)
B.append(s2)
B.append(s3)
print(A)
print(B)
C=[[0,0,0],[0,0,0],[0,0,0]]
for i in range(dim):
for j in range(dim):
for k in range(dim):
C[i][j]=C[i][j]+A[i][k]*B[k][j]
print(C)
def add(a,b):
ans=a+b
print(ans)
Python -IITM 17
This is a simple function to add two numbers that are inputed
def sub(a,b):
ans=a-b
print(ans)
def disc(cost,d):
ans=cos-(cost*(d/100))
print(ans)
def add(a,b):
ans=a+b
print(ans)
a=2
b=4
ans=add(a,b)+10
print(ans)
This code will throw an error as we’ve used print(ans) instead of return(ans)
def add(a,b):
ans=a+b
return(ans)
a=2
b=4
ans=add(a,b)+10
print(ans)
This would return the value of ans instead of printing ans so we can do more mathematical operations post running
of the function on ans
def discount(cost,d):
ans=cost-(cost*(d/100))
return ans
print("Enter the cost price")
x=int(input())
print("Enter the discount")
y=int(input())
print("The final discount is:", discount(x,y))
In this code we call the function by using discount(x,y) where x and y serve as cost and d of the function
def first_element(l):
return l[0]
x=[1,2,3,4,5,6,7]
print(first_element)
'''prints 1'''
def list_min(l):
mini=l[0]
y=0
for i in range(len(l)):
if (l[i]<mini):
mini=l[i]
return mini
Python -IITM 18
l=[12,23,53,74,21,97,8,374]
print(list_min(l))
def list_maxi(l):
maxi=l[0]
for i in range(len(l)):
if (l[i]>maxi):
maxi=l[i]
return maxi
l=[1,24,53,74,94,37,32,]
print(list_maxi(l))
def list_apppendbefore(l,z):
newl=[]
for i in range(len(z)):
newl.append(z[i])
for i in range(len(l)):
newl.append(l[i])
return newl
l=[1,24,532,61]
z=[9,54,7,23,62,74]
print(list_apppendbefore(l,z))
def list_apppend(l,z):
newl=[]
for i in range(len(l)):
newl.append(l[i])
for i in range(len(z)):
newl.append(z[i])
return newl
l=[1,24,532,61]
z=[9,54,7,23,62,74]
print(list_apppend(l,z))
def list_avg(l):
sum=0
for i in range(len(l)):
sum=sum+l[i]
ans=sum/len(l)
return ans
l=[1,2,533,63,72,84]
print(list_avg(l))
def obvious_sort(l):
m=[]
while(len(l)>0):
mini=l[0]
for i in range(len(l)):
if (l[i]<mini):
mini=l[i]
m.append(mini)
l.remove(mini)
return m
Python -IITM 19
l=[24,632,7824,843,923,64,98,247,342,678,356]
print(obvious_sort(l))
def list_min(l):
mini=l[0]
y=0
for i in range(len(l)):
if (l[i]<mini):
mini=l[i]
return mini
def obvious_sort(l):
x=[]
while(len(l)>0):
mini=list_min(l)
x.append(mini)
l.remove(mini)
return l
l=[24,632,7824,843,923,64,98,247,342,678,356]
print(obvious_sort(l))
#initialize c to zero
#i need to consider two matrices A and B
#i need to find the dot product of two lists
#i need to pick ith row and jth column in a matrix
def ini_mat(dim):
C=[]
for i in range(dim):
C.append([])
for i in range(dim):
for j in range(dim):
C[i].append(0)
return C
def dot_pro(u,v):
dim=len(u)
ans=0
for i in range(dim):
ans=ans+(u[i]*v[i])
return ans
def row(M,i):
dim=len(M)
l=[]
for k in range(dim):
l.append(M[i][k])
return l
def column(M,j):
dim=len(M)
l=[]
for k in range(dim):
l.append(M[k][j])
return l
def mat_mul(A,B):
dim=len(A)
C=ini_mat(dim)
for i in range(dim):
for j in range(dim):
C[i][j]= dot_pro(row(A,i), column(B,j))
return C
A=[[1,2,3],[4,5,6],[7,8,9]]
B=[[1,2,1],[3,1,7],[6,2,3]]
print(mat_mul(A,B))
We’ve created a modular code to find the product of two square matrices using functions.
Python -IITM 20
Theoretical Introduction to Recursion
Recursion - An Illustration
def sum(n):
if (n==1):
return 1
else:
return n+sum(n-1)
print(sum(10))
Python lets you call the same function within the function.
def comp(p,n):
if (n==1):
return p*(1.1)
#1.1 = (1+10/100)
else:
return comp(p,n-1)*1.1
print(comp(2000,3))
We used (n-1 ) instead of (n) in the else statement because f(3) =f(2)*1.1
def fact(n):
if (n==1):
return 1
else:
return fact(n-1)*n
print(fact(5))
Python -IITM 21
Types of Function Arguments
def - function definition.
function call - this is the place where we are actually executing the defined function.
arguments - the values which we pass along with the function call
def add(c,a=20,b=30):
return(a+b-c)
print(add(40)) #these are called default arguments
print(add(40,10)) #10 replaces the default value of parameter a from 20 to 10
print(add(40,10,15) # replaces tha default value of a and b by 10 and 15 respectively.
def add(c,a=20,b=30):
return(a+b-c)
print(add(40,a=50)) #this is a combination of default,positional and keyword arguments
Scope of Variables
def myfunc1(x):
x=x*2
print("Value of x in function", x)
x=5
print("Value of x before function call",x) #5
myfunc1(x)
print("Value of x after function call",x) #10
Value of function comes out to be 5 and not 10 (as we expected) this is because of call by value and scope of
variable.
Call by value:
Whenever we call a function along with an argument we are not actually passing this variable x to this function.
What we are actually doing is, only passing the value of that variable to this function.
Scope of variable:
The variable inside the function is called a local variable while the variable outside the function is called global
variable.
def myfunc():
global x
x=x*2
print("Value of x in function", x)
x=5
print("Value of x before function call",x) #5
myfunc()
print("Value of x after function call",x*3) #30
This way we can use gloval variable inside the function instead of creating a local variable that takes in the value
of the global variable.
Value of x in function 10
Types of functions
Python -IITM 22
#Inbuilt functions
print(),input(),len()
#Library functions
math.log(),math.sqrt(),random.random(),random.randrange()
calender.calendar(),calendar.month()
Tutorial on functions
Find number of different types of letters in a string
def num_of_chars():
global x
return len(x)
def num_of_words():
global x
j=1
for i in range(len(x)):
if (x[i]==' '):
j=j+1
return j
def num_of_lowercase():
global x
k=0
alpha=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
for i in range(len(x)):
for j in range(len(alpha)):
if(x[i]==alpha[j]):
k=k+1
return k
def num_of_uppercase():
global x
k=0
alpha=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
for i in range(len(x)):
for j in range(len(alpha)):
if(x[i]==alpha[j]):
k=k+1
return k
Python -IITM 23
This is my code.
def upper(s):
upper=0
for c in s:
if(c.isupper()):
upper+=1
return(upper)
def lower(s):
lower=0
for c in s:
if(c.islower()):
lower+=1
return(lower)
def characters(s):
chars=0
for c in s:
chars+=1
return(chars)
def words(s):
words=1
for c in s:
if(c==' '):
words+=1
return(words)
def num_of_chars():
global x
return len(x)
def num_of_words():
global x
return len(x.split())
def num_of_lowercase():
global x
return sum(1 for c in x if c.islower())
def num_of_uppercase():
global x
return sum(1 for c in x if c.isupper())
Python -IITM 24
pi=22/7
def circle_area(x):
return pi*(x**2)
def circle_peri(x):
return 2*pi*x
def rect_area(x,y):
return x*y
def rect_peri(x,y):
return 2*(x+y)
def circle_cal(x):
if (x=='area'):
rad=float(input("Enter the radius:\n "))
print("The area of the circle is",circle_area(rad), "sq. units")
elif(x=='perimeter'):
rad=float(input("Enter the radius: \n"))
print("The perimeter of the circle is", circle_peri(rad))
def rect_cal(x):
if (x=='area'):
length=float(input("Enter length of the rectangle:\n "))
breadth=float(input("Enter the breadth of the rectangle:\n "))
print("The area of the rectangle is",rect_area(length,breadth),"sq. units")
elif (x=='perimeter'):
length=float(input("Enter lenght of the rectangle: "))
breadth=float(input("Enter the breadth of the rectangle: "))
print("The perimeter of the rectangle is",rect_peri(length,breadth))
polygon=''
calcu=''
while(polygon!='exit'):
print("\nPOLYGONS\n \nEnter'circle' for circle\nEnter 'rectangle' for rectangle\nEnter 'exit' to exit\n")
polygon=input("Choose the polygon type or exit: \n")
if(polygon=='circle'):
while(calcu!='exit'):
x=input("Enter 'area' to calculate area \n\n Enter 'perimeter' to calculate perimeter \n \n")
circle_cal(x)
break
elif(polygon=='rectangle'):
while(calcu!='exit'):
x=input("Enter 'area' to calculate area \n \n Enter 'perimeter' to calculate perimeter \n\n ")
rect_cal(x)
break
Python -IITM 25
def tri_check(a,b,c,d,e,f):
area=0
s1=abs(((c-a)**2)+((d-b))**2)**(0.5)
s2=abs(((e-c)**2)+((f-d)**2))**(0.5)
s3=abs(((e-a)**2)+((f-b)**2))**(0.5)
s=abs((s1+s2+s3)/2)
area=(s*(s-s1)*(s-s2)*(s-s3))**(0.5)
if (area==0):
print("Not a triangle")
elif(area!=0):
print("Triangle")
def coords():
a=float(input("Enter a1: \n"))
b=float(input("Enter a2: \n"))
c=float(input("Enter b1: \n"))
d=float(input("Enter b2: \n"))
e=float(input("Enter c1: \n"))
f=float(input("Enter c2: \n"))
return tri_check(a,b,c,d,e,f)
coords()
This is my code.
import math
def slope(xi,yi,xj,yj):
if(xi==xj):
return(math.inf)
else:
return((yj-yi)/(xj-xi))
Python -IITM 26
Set - No repetition allowed. Denoted by { }
y={1,2,3,4,5,73,325,63,23,15,85,79,98}
type(y)
set
79 in y
True
78 in y
False
List Set
Naive search takes a lot of time Naive search doesn’t take a lot of time
import sys
l=list(range(100))
s=set(range(100))
print(sys.getsizeof(l)) #856
print(sys.getsizeof(s)) #8408
print(l[1]) #1
print(s[1]) #throws error - 'set' object is not subscriptable
Dictionaries
d={}
d['sud']=989898
d['am']=99108
d[123]='amaan'
print(d)
malgudi=['It', 'was', 'Monday', 'morning' , 'Swaminathan', 'was', 'reluctant', 'to', 'open', 'his', 'eyes', 'he', 'considered',
print(len(malgudi))
s=set(malgudi)
print(len(s))
d={}
for x in s:
d[x]=0 #this stores every word in set s as keys and assigns the value 0 to them
#like this - d=['It'=0,'was'=0...]
for x in malgudi:
d[x]=d[x]+1 #this adds +1 to the value of the keywords (words of the sentence) every time they are iterated
print(d)
max=0
answer_word=''
d={}
for x in s:
d[x]=0
for x in malgudi:
d[x]=d[x]+1
if (d[x]>max):
max=d[x] #this stores the value of most occurred word in max
answer_word=x #this stores the keyword (word of the sentence) of the most occurred word
print(max,'-',answer_word)
We’ve created a program to check the occurrence of words in a given sentence using dictionaries.
Tuples
() - used for tuples.
Python -IITM 27
Tuples are immutable (i.e. can’t be edited).
import string
s=string.ascii_letters
a='My name is aNtOnY %12 g0nse1v1e2 @176 0^^'
b=list(a)
alpha = tuple(list(s))
r=[]
for p in b:
if p in alpha:
r.append(p)
print(r) #this prints only the letters of our inpu sentence and removes everything else
More on lists
l1=[1,2,3]
l2=[10,20,30]
l12=l1+l2
l21=l2+l1
print(l12,l21) #prints [1,2,3,10,20,30] [10,20,30,1,2,3]
l1=[0,0,0,0,0]
l2=[0]*5
print(l1,l2) #both give same output
l3=[1,2,3]*5
print(l3) #prints [1,2,3,1,2,3,1,2,3,1,2,3,1,2,3]
l1=[1,2,3]
l2=[1,2,3]
l3=[1,3,2]
print(l1==l2) #prints True
print(l2==l3) #prints False
print(l2<l3) #prints True
l=[1,2,4]
print(l) #prints [1,2,4]
l[2]=3
print(l) #prints [1,2,3]
l1=[1,2,3]
l2=l1
l1[0]=100
print(l1,l2) #prints [100,2,3] [100,2,3]
'''To create a new memory location for a list there are 3 ways'''
l1=[1,2,3]
l2=list(l1)
l3=l1[:]
l4=l1.copy()
l5=l1
l2[0]=100
l3[1]=200
l4[2]=300
print(l1,l2,l3,l4)
#[1,2,3] [100,2,3] [1,200,3]
Python -IITM 28
'''To check if python has alloted different or same memory location
we use 'is' operator'''
def add(x):
x.append(1)
return x
x=[5]
print(add(x)) #prints [5,1]
print(x) #prints [5,1]
'''LIST METHODS'''
l=[1,2,3]
print(l)
l.append(4) #Takes in only 1 value #It also adds the element at the end of the list
print(l)
l.insert(2,9) #Takes in multiple values #It adds the element at the second index of the list
print(l)
l=[2,6,1,50,3,7,5]
l.sort() #sorts in ascending order
print(l)
l=[2,6,1,50,3,7,5]
l.reverse() #prints the list in reverse order
print(l)
More on Tuples
t = 1, 2, 3
print(t,type(t)) #prints (1,2,3) <class 'tuple'> #this is packing
x,y,z = t
print(x,y,z) #prints 1,2,3 #this is unpacking
l=[10]
print(l,type(l)) #prints [10] <class 'list'>
t=(10)
print(t,type(t)) #prints 10 <class 'int'>
'''To make the type of t=(10) tuple we've to put a comma after 10'''
t=(10,)
print(t,type(t)) #prints 10 <class 'tuple'>
Python -IITM 29
t1=(1,2,3) #If values inside tuple are immutable it is referred as hashable
t2=([1,2,3],) #If values inside tuple are mutable it is referred as non-hashable
More of Dictionaries
d={'key':'value'}
We can use immutable data types as key. Hence, integer, float, boolean, string but not a list or dictionary.
Value has no restrictions, we can use integer, float, boolean, string, list, tuple, dictionary, etc.
d={0:0,1:1,2:4,3:9,4:16}
print(d)
for key in d:
print(key,d[key])
'''DICTIONARY METHODS'''
d={0:0,1:1,2:4,3:9,4:16}
print(d.keys()) #prints dict_keys([0,1,2,3,4])
print(d.values()) #prints dict_values([0,1,4,9,16])
print(d.items()) #prints dict_items([(0,0),(1,1),(2,4),(3,9),(4,16)])
#every element in the list is a tuple
More on Sets
st = {1,2,3,4,5,1,2,3,4,5}
print(st) #prints {1,2,3,4,5}
st = {1,2,3,4,5,1,2,3,4,5}
print(st[0])
Set is mutable but every value inside it has to be immutable and hashable which means you can add values into a
set but those values have to be immutable. Hence, we cannot add a dictionary or list in a set.
'''SET METHODS'''
A={1,2,3}
B={1,2,3,4,5}
print(A.issubset(B)) #prints True
print(A.issuperset(B)) #prints False
A={1,2,3}
B={3,4,5}
C1=A.union(B)
C2=A | B
print(C1,C2)
A={1,2,3}
B={3,4,5}
C1=A.intersection(B)
C2=A&B
print(C1,C2)
A={1,2,3}
B={3,4,5}
C1=A.difference(B)
C2=A-B
print(C1,C2)
Python -IITM 30
WEEK 7 - 68-75 LEC:
Introduction to Recursion
Python -IITM 31
This isn’t in correct python syntax. This program checks if a list has 0 in it and if it does it returns 1 or else 0.
Python -IITM 32
This is the logic behind the above pseudocode.
Python -IITM 33
Revision of concepts done before.
def check0(l):
#if the list is empty, return False
if (len(l)==0):
return 0
if(l[0]==0):
#if the first element is zero then return 1
return 1
else:
return check0(l[1:len(l)])
#the above code simply outsources
print(check0([1,2,3,4,5,532,0,24,16,74,8]))
Sorting Recursively
def mini(l):
mini=l[0]
for x in l:
if(x<mini):
mini=x
return mini
def sort(l):
'''recursively sort the list l'''
if(l==[])or(len(l)==1):
return l
#if the list is empty, there is nothing to sort hence we return the list as it is
m=mini(l)
#m now contains the minimum most element in l
l.remove(m)
#we remove that element from l
return [m]+sort(l)
Python -IITM 34
#we recursively sort the smaller list
l=[5,7,2,9,1,6,3]
print(sort(l))
For example - Lets consider you’ve to find the word ‘serendipity’ in a dictionary. You start out with opening the middle page of the dictionary. If
it’s of a letter that comes before the letter S you can discard half of the dictionary. Repeating this method until we find our word is called
Binary Search.
def obvious_search(L,k):
for x in L:
if x==k:
return 1
return 0
#code verified.
L=list(range(100000000))
import time
a=time.time()
#Measures time from an epoch to this moment.
print(obvious_search(L,9999999999))
b=time.time()
print(b-a)
When we search for a closer number to the limit of the big list it takes a considerable time for our code to find that
number and get the output.
Python -IITM 35
import time
def binarysearch(L,k):
'''This function is an alternative fot the obvious search.
It does exactly what is ecpected from the obvious search,
but in an efficient way.
This method is popularly called the binary search'''
#We want to shrink our list.
#We will do that using a while loop.
begin = L[0]
end=(len(L)-1)
#Use a while loop to look at the list and keep halving it.
while((end-begin)>1):
#If mid is indeed k, then we return True and stop the code.
if(L[mid]==k):
return 1
L=list(range(100*100*100))
a=time.time()
print(binarysearch(L,-1))
b=time.time()
print(b-a)
def rbinarysearch(L,k,begin,end):
'''This will recursively compute binary search'''
Python -IITM 36
'''If begin and end are the same, then we need to just
check L[begin]'''
if (begin==end):
if (L[begin]==k):
return 1
else:
return 0
'''If begin and end are consecutive, then check them
individually'''
if (end-begin==1):
if (L[begin]==k) or (L[end]==k):
return 1
else:
return 0
'''If end-begin>1'''
if (end-begin>1):
mid=(begin+end)//2
if (L[mid]>k):
#discard the right and retain the left.
end=mid-1
if (L[mid]<k):
#discard the left and retain the right.
begin=mid+1
if(L[mid]==k):
return 1
if(end-begin<0):
return 0
return rbinarysearch(L,k,begin,end)
L=list(range(10000))
k=-33
begin=L[0]
end=len(L)-1
print(rbinarysearch(L,k,begin,end))
Python -IITM 37
Reading and Writing to a File
Here, f is a variable to which we’ve assigned the open command. 'mytext.txt' is the name of the file and 'w'
We then use the variable f to call the file and write in it using f.write() command.
Python -IITM 38
'\n'
Python -IITM 39
type(s) prints the type of the variable s which is string in this case.
💡 'w' writes over the file. 'a' appends to the existing file.
Here, we first create a new file by the name newfile.txt then we add text to it.
Python -IITM 40
When we reach the end of any file it is represented by '' (null character). Hence s=='' outputted True as we’ve
reached the end of the file.
Python -IITM 41
We run this program to find a number in our text file. run command is followed by the name of the file which we
want to run. (We need to make sure the file we have to run is in the same directory as our text file.)
f=open('newfile.txt', 'r')
flag=0
s='0'
while(s!=''):
s=f.readline()
if(s!=''):
n=int(s)
if(n==10):
print("The number was found.")
flag=1
break
if (flag==0):
print("The number was not found.")
Caesar Cipher
import string
def create_caesar_dictionary():
l=string.ascii_lowercase
l=list(l)
d={}
for i in range(len(l)):
d[l[i]]=l[(i+3)%26]
return d
d=create_caesar_dictionary()
c=f.read(1)
while (c!=''):
g.write(d[c])
c=f.read(1)
Python -IITM 42
f.close()
g.close()
The code begins by importing the string module, which provides various useful string-related functions and
constants.
The create_caesar_dictionary() function is defined. It initializes an empty dictionary d and a list l containing all the
lowercase letters of the alphabet.
The function then iterates over the lowercase letters and assigns a new value to each letter in the dictionary d . The
new value is obtained by shifting the letter three units to the right (using the modulo operator % to wrap around to
the beginning of the alphabet if needed).
After defining the create_caesar_dictionary() function, the program opens the input file 'hound of baskervilles.txt' in
read mode using the open() function and assigns it to the file object f .
It also opens a new file 'encrypted sherlock.txt' in write mode using open() and assigns it to the file object g .
The program then calls the create_caesar_dictionary() function to create the Caesar cipher dictionary and assigns it
to the variable d .
The program enters a loop that reads one character at a time from the input file f using f.read(1) . The loop
continues until the end of the file is reached (denoted by an empty string '' ).
Inside the loop, the program writes the corresponding encrypted character for the current character to the output file
g using g.write(d[c]) .
Once the loop is finished, the program closes both the input and output files using f.close() and g.close()
Python -IITM 43
In the following code:
Secondly, we made a string seq that will contain whole of the text of our file using seq=f.read() command.
Then, we checked if our seq contains the patterns we want to check and it returned either False or True.
💡 f.read() works fine for smaller files but takes a lot of time for bigger files. Hence we use KMP(Knuth
Morris Pratt) algorithm to find a substring in a given big string.
Python -IITM 44
Why Pandas
Python -IITM 45
[1:] is a string slicing operation that skips over the header fields in our csv file.
f=open('scores.csv','r')
scores=f.readlines()[1:]
max=0
for record in scores:
fields=record.split(',')
if int(fields[8])>max:
max=int(fields[8])
print(max)
The above code does what we did with 8 lines of our previous code.
print(scores) prints the scores using pandas. As we can notice, pandas add an additional index column before our
first column.
At the bottom we can see (28 rows x 9 columns) this shows that we have 28 entries in 9 fields.
Python -IITM 46
print(scores.count()) shows all the values a coulmn contains.
print(scores['total'].min()) returns the minimum value of the total column. It works in a similar fashion like the max
function.
Python -IITM 47
.sort_values(ascending=False) returns the sorted values in descending order.
We can access entire data of a particular individual in a row by using the command print(scores[scores['name']=='name
of individual']) .
print(scores[scores['gender']=='M']['total'].max()) using this command we can get the boy with the maximum marks.
Similarly we can find the girl with the most marks too.
Python -IITM 48
Panda provides us with a .between() command that acts as a relational operator
.shape returns a tuple containing the number of rows and columns of that dataframe.
So, shape[0] is used since we only need rows and the index of rows is 0 in the tuple.
It can be used to condtionalize our command to check two conditions from two different columns or panda series.
Python -IITM 49
We can iterate over subjects using this code.
It returns the number of students, male and female who scored above 85 in each subjects.
import pandas as pd
scores =pd.read_csv('scores.csv')
subject = ['mathematics', 'physics', 'chemistry']
for sub in subject:
avg=scores[sub].mean()
print('Above average in', sub)
print(scores[(scores[sub]>avg) & (scores['gender']=='M')].shape[0])
print(scores[(scores[sub]>avg) & (scores['gender']=='F')].shape[0])
In these dictionaries the numbers are the cardno of the female and male students.
We can make use of the .groupby method to easily make the previous code.
Python -IITM 50
Here, Student is the class, roll_no , name are attributes and s0 is an object of the class Student .
Python -IITM 51
Here, __init__(self, roll_no,name) is a special method or function. The self parameter stores values like s0, s1, etc.
If we have some parameters like roll_no , name which we want to initialize against some variables which are
available in the class, then we have to use a constructor with parameters, and whenever we call such a constructor,
internally python executes this particular function called init .Therefore we don’t have to explicitly call this function
like other functions.
self.name and self.roll_no are object variables which are nothing but attributes of these two objects s0 and s1 .
The variable count is owned by the class Student and is shared by objects s1 and s2 . s1 and s2 will not have
their own copy of this variable. Hence, count is a class attribute and the variables roll_no and name are object
attributes.
Python -IITM 52
Here, the method result() acts as behaviour as discussed in the introduction of this week’s lectures.
When functions belong to a specific class then they are referred to as methods.
Inheritance
Python -IITM 53
Here the class Person is the parent or super class and the classes Student and Employee are children classes.
This way, we can avoid repetition and assign the common attributes to the parent class.
Method Overriding
Python -IITM 54
This is called Method Overriding. As the class employee uses its own function/method instead of the parent class’
method.
We can divide our code and make it run this way too in replit.
Python -IITM 55
This way we can make any variable secret by adding underscores in it. These variables are referred to as private
members.
Without the underscores in the variable it becomes accessible to all hence it’s called a public member.
Types of inheritance:
Simple Inheritance - Single parent and child class.
Hierarchical Inheritance - Multiple children classes. (Ex - Person, Employee and Student classes we worked on
previously.)
Python -IITM 56
Multiple Inheritance - Multiple parent classes.
Python -IITM 57
Hybrid Inheritance - Variation of previous defined inheritances.
Python -IITM 58
Python considers all these as one dimensional lists.
whereas,
Using numpy array, python considers these as matrix with their respective dimension.
Python -IITM 59
plt.bar() is used to create bar chart.
We can create subplots like these using plt.subplot() . This command takes in 3 attributes - row (x axis), column (y
axis) and position in the chronological order.
Iterator
Generator
In line statements
List comprehension
Python -IITM 60
Lambda function
Enumerator
Zip
Map
Filter
Exception handling
We use exception handling to print out meaningful error messages that may help someone encountering them solve
them.
It is considered as an industry standard.
The try: command first tries if the code under it can run without error.
Python -IITM 61
This way we can handle the FileNotFoundError.
The last except block is for unforeseen errors apart from the above 3 errors that may arrive.
Python -IITM 62
The finally block is always executed before termination of the program.
We can create our own exception warnings using raise Exception command.
Iterator:
Python -IITM 63
iter is used to iterate over any iteratable item i.e. string, list, dictionary, tuple etc.
next is used to iterate over that particular iterator if and when required.
Generator:
Here, a is an iterator and we can iterate over the iterator using same next function.
In line statements:
a=10 a=10
b=20 b=20
Python -IITM 64
print(small)
We can reduce the length of our code by using this everywhere possible.
a=5 a=5
while a>0: while a>0: print(a); a-=1
print(a)
a-=1
Python reads both the codes in equal time so there’s no time advantage in running either of the code over the other.
However, our code may become difficult to understand if its big and we write commands in a single line.
List Comprehension:
fruits=['mango','apple','pineapple',
'orange', 'watermelon', 'guava',
'banana', 'kiwi']
newlist=[]
for fruit in fruits:
if 'n' in fruit:
newlist.append(fruit.capitalize())
print(newlist)
Both of these code give the same output but the second code uses list comprehension.
In it we used inline for, inline if, and putting them together in a list creating a new list. This is called list
comprehension.
Lambda Function:
Functions that are anonymous i.e. without any function name.
print(add(10,20))
print(sub(10,20))
print(mul(10,20))
print(div(10,20))
Python -IITM 65
Advantage of using lambda functions is they reduce the length of our program.
Enumerator Function:
In this code the index values and the fruits in fruits list aren’t coupled.
The index and the name of the fruit are two different entities here.
Using the enumerate function, we’ve coupled the indexes and the name of the fruits. They’ve become a single entity.
Zip Function:
Python -IITM 66
Using the zip function we can couple two different lists.
Instead of getting our output as list we can get it as a dictionary too by using dict instead of list before the zip
function.
Map Function:
Using the map function we can map a function with its iterators.
In this case this map function will iterate over these two lists and at the same time it will exeecute this fucntions for
every single entry inside these two lists.
Python -IITM 67
We incremented every element in list a by 1 using map function.
Filter Function:
We created a filter here to filter out negative numbers from the list a using filter function.
Python -IITM 68