0% found this document useful (0 votes)
1 views569 pages

Python Notes Neeraj Sir

The document is an introductory lecture on computer programming, focusing on programming languages, particularly Python. It discusses the importance of programming languages for automating tasks, the advantages of Python, and provides guidance on getting started with Python, including installation and usage of Jupyter Notebooks. Additionally, it covers fundamental concepts such as data types, expressions, operators, and string manipulation in Python.

Uploaded by

vivekkumargond61
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views569 pages

Python Notes Neeraj Sir

The document is an introductory lecture on computer programming, focusing on programming languages, particularly Python. It discusses the importance of programming languages for automating tasks, the advantages of Python, and provides guidance on getting started with Python, including installation and usage of Jupyter Notebooks. Additionally, it covers fundamental concepts such as data types, expressions, operators, and string manipulation in Python.

Uploaded by

vivekkumargond61
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

MTL5004/MTL505: Introduction to Computer

Programming
(Lecture 1)

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 1 / 13


Introductory Remarks

Introductory Remarks

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 2 / 13


Introductory Remarks

What is a Programming Language?

A programming language is nothing more than a well-structured subset of


words and special characters that allow us to describe operations that our
computer would like to perform on our behalf.
The programming language translates words and symbols into instructions
that the computer can execute.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 3 / 13


Introductory Remarks

Why We Need Programming Languages?

Programming languages enable us to automate repetitive processes and


carry out complex calculations considerably more quickly and precisely
than conventional manual methods.
A programming language provides a structured way to give instructions to
the computer, enabling it to perform specific tasks such as data processing,
simulation, or controlling devices.
Programming languages are used to create all software, including web
applications and operating systems. Hence, they are crucial for the
development of modern digital tools and technologies that contribute to
society in a meaningful way.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 4 / 13


Introductory Remarks

Why Python?

Easy to learn and use compared to other programming languages.


Designed with readability in mind.
Excellent tool for efficient data handling.
One of the most popular programming language, and an increasing
standard for data analysis in industry.
Besides data analysis, it can be effectively used for websites, database
management, web scraping, financial modeling, data visualization, etc.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 5 / 13


Introductory Remarks

Some Other Programming Languages

R has an impressive ecosystem of statistical packages, and is an excellent


choice for pure data science. It could be a useful language to learn for
projects that are entirely statistical.
Matlab has much more natural notation for writing linear algebra heavy
code. However, it is: (a) expensive; (b) poor at dealing with data analysis;
(c) grossly inferior to Python as a language; and (d) being left behind as
Python and Julia ecosystems expand to more packages.
Julia is in part a far better version of Matlab, which can be as fast as
Fortran or C. However, it has a young and immature environment and is
currently more appropriate for academics and scientific computing
specialists.

Run time performance can be slow in R/Python for some specific tasks.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 6 / 13


Introductory Remarks

Why Open Source Programming?

Open source languages are easier for everyone in the world to write and
share packages because the code is accessible and available.
With the right kinds of open source licenses; academics, businesses, and
hobbyists all have incentives to contribute.
Because open-source languages are managed on publicly accessible sites
(e.g. GitHub), it is easier to build a community and collaborate.
Package management systems (i.e. a way to find, download, install, and
upgrade packages) in open-source languages can be very open and
accessible since they don’t need to deal with proprietary software licenses.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 7 / 13


Getting Started with Python

Getting Started with Python

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 8 / 13


Getting Started with Python

Python in the Cloud

The easiest way to start coding in Python is by running it in the cloud.


That is, by using a remote server that already has Python installed.
One free and reliable option is Google Colab.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 9 / 13


Getting Started with Python

Anaconda

Another approach is to install a Python distribution that contains the core


Python language and compatible versions of the most popular scientific
libraries.
The best such distribution is Anaconda Python. Anaconda is very popular
and comprehensive.
Anaconda also comes with a package management system to organize your
code libraries.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 10 / 13


Getting Started with Python

Installing Anaconda

To install Anaconda, download the binary and follow the instructions.


Make sure you install the correct version for your operating system.
If you are asked during the installation process whether you would like to
make Anaconda your default Python installation, say yes.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 11 / 13


Getting Started with Python

Jupyter Notebooks

Jupyter notebooks are one of the many possible ways to interact with
Python and the scientific libraries.
They use a browser-based interface to Python with
1 The ability to write and execute Python commands.
2 Formatted output in the browser, including tables, figures, animation, etc.
3 The option to mix in formatted text and mathematical expressions.
Because of these features, Jupyter is now a major player in the scientific
computing ecosystem.
The Jupyter notebook displays an active cell, into which you can type
Python commands.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 12 / 13


Getting Started with Python

Notebook Basics

A cell with a flashing cursor will appear, and some command can be
written to this cell.
When you are ready to execute the code in a cell, press “Shift-Enter”
instead of the usual Enter.
Python supports unicode, allowing the use of characters such as α and β as
names in your code. In a code cell, try typing α and then hitting the “tab”
key on your keyboard.

Neeraj Joshi (IIT Delhi) Lecture 1 July 24, 2025 13 / 13


MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 2)

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 1 / 13


Data Types in Python

Data Types in Python

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 2 / 13


Data Types in Python

Data Objects

Manipulating data objects is an important task in programming.


The type of the objects defines the kind of operations that programs can
perform.
For example, 50 is a number, and one can add/subtract/multiply/divide it.
‘Hello’ is a sequence of characters (known as strings). One can extract
substrings from it, but one cannot divide it by a number.

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 3 / 13


Data Types in Python

Numeric Type

int (Integer Values), for example, x=2.


float (floating point numbers), for example, x = 2.3.
complex (complex numbers), for example, x=4+5j [complex(4,5)].

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 4 / 13


Data Types in Python

Boolean Type

x = True
y = False
print(x and y)

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 5 / 13


Data Types in Python

None Type

Special and has one value, None.

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 6 / 13


Data Types in Python

Text Type

x = “Hello World”
print(len(s)) [Number of characters]

len() is a built-in function that returns the number of items in an


object such as number of characters/elements/tuples, etc.)

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 7 / 13


Data Types in Python

Type Function

type() can be used to see the type of an object.


Try type(5), type(9.2), etc.

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 8 / 13


Data Types in Python

Type Conversion

m=5
p = str(m) [Converts to “5”]

str() stands for string. It is a built-in function that converts other


data types into strings.

float(3) converts the int(3) [integer] to float(3.0).


int(3.4) converts float(3.4) to int(3).
round(4.3) returns the integer 4.

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 9 / 13


Expressions, Operators, and Variables

Expressions, Operators, and Variables

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 10 / 13


Expressions, Operators, and Variables

Expressions

An expression has a value, which has a type, e.g.,


2 + 5 has value 7 and type int.
7/2 has a value of 3.5 and a type of float.
Python evaluates expressions and stores the value. It does not store
expressions!
Try the following expressions
(7+2)*5-3
type((7+2)*5-3)
float((7+2)*5-3)

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 11 / 13


Expressions, Operators, and Variables

Operations on int and float

i+j [sum]
i-j [difference]
i*j [product]

In the above cases, if both i and j are ints, result is int. If either
or both are floats, result is float.

i/j [division] result is always a float.


i//j [floor division]
i%j [remainder when i is divided by j]
i**j [i to the power j]

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 12 / 13


Expressions, Operators, and Variables

Variables

The variables in programming are different from Mathematics. For


example, a + 5 = b − 3 or a ∗ a = b can represent many values in
Mathematics.
In computer science, variables are bound to one single value at a given
time. For example a = b + 3 or m = 5, n = m ∗ 6.
While binding variables to values, the equality sign is an assignment.
For example, while executing x = 5/2, the value on the right-hand side is
computed. This value stored in computer memory. Thereafter, it is binded
to the left-hand side. The value can be retrieved associated with name by
invoking the name.

Neeraj Joshi (IIT Delhi) Lecture 2 July 28, 2025 13 / 13


MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 3)

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 1 / 21


Strings

Strings

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 2 / 21


Strings

Strings

The string (str) is a sequence of case-sensitive characters, such as letters,


special characters, spaces, digits, etc.
When defining strings in Python, enclose them in single or double quotes.
For example,
x = “student”
y = “professor”
Check the output of the following code:
w=“student”
x=“professor”
y=w+x
z=w + “ ” + x
m=w*5

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 3 / 21


Strings

String Operations

The length of a string can be found using the len() function.


w=“xyz”
u=len(w)

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 4 / 21


Strings

Slicing in a String

How do we get one character?


We need to execute indexing into a string to get the value at a certain
position.
Consider w=“xyz”
w[0] will give “x”
w[1] will give “y”
w[2] will give “z”
What about w[3]?
Also try w[-1], w[-2], w[-3].
Positive indexing always starts at 0.

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 5 / 21


Strings

Slicing in a String (Contd.)

How to get a substring?


Use [start:stop:step]
Consider z=“stuvwxy”
Try the following and observe the output
z[2:5], z[2:5:2], z[:], z[::-2], z[5:1:-2]
In Python, [start:stop] returns a substring starting at index start and
ending at index stop - 1 (i.e., it does not include the character at index
stop).
Following is the syntax structure:
start (index to start from)
stop (index to stop before)
step (positions to skip each time)

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 6 / 21


Strings

Immutable Strings

Strings cannot be modified (they are immutable).


New objects can be created that are versions of the original string.
Have a look!
w=“YOU”
Try to run
w[0]=“WE” [observe the output]
Try to run
w’ = “WE”+w[1:len(w)] [observe the output]

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 7 / 21


Strings

Immutable Strings (Example)

Try to write a command to revere the word “student”


g=“student”
g’=[::-1]
Note: In the above command, START defaults to the end of the string
(because step is negative), STOP defaults to the start of the string (and
goes until before index - 1), STEP means move backwards, one character
at a time. So, it starts from the last character and moves backwards by 1,
collecting each character until the beginning.

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 8 / 21


Input/Output

Input/Output

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 9 / 21


Input/Output

Output in Python

The print() function is used to display information on the screen.


print(“hello world”) will give hello world.
One can print strings, numbers, variables, multiple items, etc.

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 10 / 21


Input/Output

Input in Python

The input() function is used to get data from the user. For example
name = input(“Enter your name: ”)
print(“Hello,”, name)
The input() function always returns a string. To get a number, you have to
convert it. For example
age = int(input(“Enter your age: ”))
print(age)

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 11 / 21


Branching Conditions

Branching Conditions

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 12 / 21


Branching Conditions

Binding Variables and Values

How to deal with assignment and equality?


variable = value [assignment]
Changes the stored value of the variable to value.
x = 5 [This is not checking if x is equal to 10. Rather, it simply stores 5 in
x.]
expression1 == expression2 [test for equality]
No binding (assignment) is happening.
Expressions are evaluated to values.
The entire expression is replaced by True or False.
Example:
x=5
print(x == 5)
print(x == 7)
We are examining whether x currently holds the value 5.

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 13 / 21


Branching Conditions

Comparison Operators

Suppose x and y are variable names of type int, float, str, etc.
Following comparisons evaluate to the Boolean type (True or False):
x>y
x >= y
x<y
x <= y
x == y [True if x is the same as y] [equality test]
x! = y [True if x is not the same as y] [inequality test]

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 14 / 21


Branching Conditions

Logical Operators

Suppose x and y are variable names of boolean type.


not x [True if x is False, False if x is True]
x and y [True if both are True]
x or y [True if either or both are True]
Execute the following command:
mathscore = 85
sciencescore = 90
print(mathscore < sciencescore)

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 15 / 21


Branching Conditions

Importance of bool in Programming

When dealing with the flow of control, one needs a way of knowing if a
condition is true.
We often deal with programming problems such as, if something is true, do
this, otherwise, do that.
Boolean variables play a vital role here.

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 16 / 21


Branching Conditions

A Simple Flow Chart

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 17 / 21


Branching Conditions

Understanding Branching

if <condition>:
<code>
<code>
..
.
<rest of program>
<condition> has a value True or False.
Write code within if block if condition is True.
Indentation should not be ignored.

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 18 / 21


Branching Conditions

Understanding Branching (Contd.)

if <condition>:
<code>
<code>
...
else:
<code>
<code>
...
<rest of program>
<condition> has a value True or False.
Write code within if block if condition is True OR write code within else
block if condition is False.
Indentation should not be ignored.

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 19 / 21


Branching Conditions

Understanding Branching (Contd.)


if <condition>:
<code>
<code>
...
elif:
<code>
<code>
...
elif:
<code>
<code>
...
<rest of program>
<condition> has a value True or False.
Run the first block whose corresponding condition is True.
Indentation should not be ignored.

Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 20 / 21


Branching Conditions

Understanding Branching (Contd.)


if <condition>:
<code>
<code>
...
elif:
<code>
<code>
...
else:
<code>
<code>
...
<rest of program>
<condition> has a value True or False.
Run the first block whose corresponding condition is True.
The else block runs when no conditions were True.
Indentation should not be ignored.
Neeraj Joshi (IIT Delhi) Lecture 3 July 30, 2025 21 / 21
MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 4)

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 1 / 16


Branching Examples

Branching Examples

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 2 / 16


Branching Examples

Example 1

Write and execute a Python program to take an integer input from the user
and check whether it is even or odd.

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 3 / 16


Branching Examples

Example 1 (Solution)

num = int(input(“Enter a number: ”))


if num % 2 == 0:
print(“Even”)
else:
print(“Odd”)

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 4 / 16


Branching Examples

Example 2

Write and execute a Python program to take your MTL5004/MTL505


percentage as input and print the grade based on the following:
80 and above: A
70 to 79: A-
60 to 69: B
50 to 59: B-
45 to 49: C
40 to 44: C-
30 to 39: D
Below 30: F

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 5 / 16


Branching Examples

Example 2 (Solution)

percentage = float(input(“Enter your percentage: ”))


if percentage >= 80:
print(“Grade: A”)
elif percentage >= 70:
print(“Grade: A-”)
elif percentage >= 60:
print(“Grade: B”)
elif percentage >= 50:
print(“Grade: B-”)
elif percentage >= 45:
print(“Grade: C”)
elif percentage >= 40:
print(“Grade: C-”)
elif percentage >= 30:
print(“Grade: D”)
else:
print(“Grade: F”)

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 6 / 16


Branching Examples

Example 3

Write and execute a Python program to take a number as input and


determine whether it is positive, negative, or zero.

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 7 / 16


Branching Examples

Example 3 (Solution)

num = float(input(“Enter a number: ”))


if num > 0:
print(“Positive”)
elif num < 0:
print(“Negative”)
else:
print(“Zero”)

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 8 / 16


Branching Examples

Example 4

Write and execute a Python program to input three numbers and print the
largest one.

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 9 / 16


Branching Examples

Example 4 (Solution)

a = int(input(“Enter first number: ”))


b = int(input(“Enter second number: ”))
c = int(input(“Enter third number: ”))
if a >= b and a >= c:
print(“Largest is:”, a)
elif b >= a and b >= c:
print(“Largest is:”, b)
else:
print(“Largest is:”, c)

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 10 / 16


Branching Examples

Example 5

Write and execute a Python program to check whether a given year is a


leap year.

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 11 / 16


Branching Examples

Example 5 (Solution)

year = int(input(“Enter a year: ”))


if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
print(“Leap year”)
else:
print(“Not a leap year”)

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 12 / 16


Nested Branching

Nested Branching

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 13 / 16


Nested Branching

Nested Branching

Nested branching means placing one if, else, or elif statement inside
another if block. It allows for checking multiple levels of conditions.

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 14 / 16


Nested Branching

Example 1

Write and execute a Python code to check whether a given number is


positive/negative and even/odd. If it is 0, print “Zero”.

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 15 / 16


Nested Branching

Solution

num = int(input(“Enter a number: ”))


if num == 0:
print(“Zero”)
else:
if num > 0:
if num % 2 == 0:
print(“Positive and Even”)
else:
print(“Positive and Odd”)
else:
if num % 2 == 0:
print(“Negative and Even”)
else:
print(“Negative and Odd”)

Neeraj Joshi (IIT Delhi) Lecture 4 July 31, 2025 16 / 16


MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 5)

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 1 / 21


Iteration

Iteration

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 2 / 21


Iteration

while Loops

A while loop is used to repeatedly run a block of statements until a


specified condition is met.
The line that appears right after the loop of the program is executed when
the condition is changed to false.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 3 / 21


Iteration

Control Flow of the while Loops

while <condition>:
<code>
<code>
...
The <condition> evaluates to a boolean (True/False).
If <condition> is True, run all the steps inside the while code block.
Check <condition> again.
Repeat until <condition> is False.
If <condition> is never False, then will loop forever.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 4 / 21


Iteration

while Loops: Example 1

Write and execute a Python program to print numbers from 1 to 10 using a


while loop.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 5 / 21


Iteration

while Loops: Example 1 - Solution

i=1
while i <= 10:
print(i)
i += 1
Here, we first set up a counter variable i, starting at 1.
The while condition ensures that the loop will keep running as long as
i≤ 10. The loop will stop when i becomes 11.
The print command ensures that we print the current value of i inside the
loop.
The i+ = 1 condition ensures an increment in i by 1 after each loop,
otherwise the loop will run forever and become infinite.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 6 / 21


Iteration

while Loops: Example 2

Write and execute a Python program to compute the factorial of a number


using the while loop.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 7 / 21


Iteration

while Loops: Example 2 - Solution

n = int(input(“Enter a number: ”))


factorial = 1
i=1
while i <= n:
factorial *= i
i += 1
print(“Factorial:”, factorial)
Here we first set loop variable outside the while loop.
We initialize the factorial product to 1.
The loop variable is tested based on the condition.
Incorporate the running product.
Increase the loop variable by 1 inside the while loop.
Print the final value outside the loop.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 8 / 21


Iteration

for Loops

A for loop is used to iterate over a sequence like lists, tuples, strings, and
ranges.
It allows us to apply the same operation to every item within loop.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 9 / 21


Iteration

Control Structure of the for Loops

for <variable> in sequence of <values>:


<code>
...
The <variable> takes a value each time through the loop.
First time, <variable> is the first value in sequence.
Next time, <variable> gets the second value.
This process continues until <variable> runs out of values.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 10 / 21


Iteration

for Loops: A Common Sequence of Values

for <variable> in range (<some num>):


<code>
<code>
...
The <variable> takes a value each time through the loop.
First time, <variable> starts at 0.
Next time, <variable> gets the value 1.
Next time, <variable> gets the value 2.
This process continues until <variable> gets some num-1.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 11 / 21


Iteration

Range

Generate a sequence of integers (ints), following a pattern.


Syntax: range(start, stop, step).
start: first integer generated.
stop: controls last integer generated (go up to but not including this
integer).
step: used to generate the next integer in sequence.
start defaults to 0.
step defaults to 1 unless otherwise defined.
string is similar to range syntax wise, but with colons (not commas) and
square brackets (not parentheses).

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 12 / 21


Iteration

for Loops: Example 1

Write and execute a Python program to find the sum of the first n natural
numbers using a for loop.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 13 / 21


Iteration

for Loops: Example 1 - Solution

n = 10
total = 0
for i in range(1, n+1):
total += i
print(total)

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 14 / 21


Iteration

for Loops: Example 2

Write and execute a Python program to print all even numbers from 1 to
30 using a for loop.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 15 / 21


Iteration

for Loops: Example 2 - Solution

for i in range(1, 31):


if i % 2 == 0:
print(i, end=‘ ’)

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 16 / 21


Iteration

for Loops: Example 3

Write and execute a Python program to print each character of


MATHEMATICS in a new line using a for loop.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 17 / 21


Iteration

for Loops: Example 3 - Solution

text = “MATHEMATICS”
for char in text:
print(char)

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 18 / 21


Iteration

for Loops: Example 4

Write and execute a Python program to compute the factorial of a number


using the for loop.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 19 / 21


Iteration

for Loops: Example 4 - Solution

n = int(input(“Enter a number: ”))


factorial = 1
for i in range(1, n + 1):
factorial *= i
print(factorial)

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 20 / 21


Iteration

Important Observation Regarding Print Function

When we put print() inside a loop, it runs on every iteration. That means
it will print something each time the loop runs.
When we put print() outside the loop, it only runs once, after the loop has
finished.

Neeraj Joshi (IIT Delhi) Lecture 5 August 4, 2025 21 / 21


MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 6)

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 1 / 22


Iteration Continued...

Iteration Continued...

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 2 / 22


Iteration Continued...

break Statement

The break statement immediately exits the nearest enclosing for or while
loop, even if the loop condition is still True.
One can use it to stop the loop early based on some condition.
It only exits the innermost loop, not outer loops if you are using nested
loops.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 3 / 22


Iteration Continued...

break Statement: Syntax

while condition:
if condition to stop:
break
for item in sequence:
if condition:
break

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 4 / 22


Iteration Continued...

break Statement: Example 1

Write and execute a Python program that prints each character of the
string “MATHEMATICS” one by one. The program should stop printing
as soon as it encounters the letter “I”, without printing “I” or any letter
after it.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 5 / 22


Iteration Continued...

break Statement: Example 1 - Solution

for letter in “MATHEMATICS”:


if letter ==“I”:
break
print(letter)

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 6 / 22


Iteration Continued...

break Statement: Example 2

Write and execute a Python program that prints numbers from 1 to 10


using a while loop. The program should terminate the loop early if the
number 5 is encountered, so that the numbers after 5 are not printed.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 7 / 22


Iteration Continued...

break Statement: Example 2 - Solution

i=1
while i <= 10:
print(i)
if i == 5:
break
i += 1

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 8 / 22


Iteration Continued...

Strings and Loops

The for and while loops can be used to iterate through each character of
a string.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 9 / 22


Iteration Continued...

Strings and Loops: Syntax

for character in string:


# code

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 10 / 22


Iteration Continued...

Strings and Loops: Example 1

Write and execute a Python command to print each character of the string
“HELLO” one by one using the for loop.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 11 / 22


Iteration Continued...

Strings and Loops: Example 1 Solution

word = “HELLO”
for char in word:
print(char)

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 12 / 22


Iteration Continued...

Strings and Loops: Example 2

Write and execute a Python command for the Example 1 task using
range() function.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 13 / 22


Iteration Continued...

Strings and Loops: Example 2 Solution

word = “HELLO”
for i in range(len(word)):
print(word[i])

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 14 / 22


Iteration Continued...

Strings and Loops: Example 3

Do the same Example 1 task using while loop.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 15 / 22


Iteration Continued...

Strings and Loops: Example 2 Solution

word = “HELLO”
i=0
while i < len(word):
print(word[i])
i+=1

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 16 / 22


Iteration Continued...

Strings and Loops: Example 4

Write and execute a Python program to count the number of vowels in the
string “Programming” using for loop.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 17 / 22


Iteration Continued...

Strings and Loops: Example 4 Solution

text = “Programming”
vowels = “aeiouAEIOU”
count = 0
for char in text:
if char in vowels:
count +=1
print(“Number of vowels:”, count)

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 18 / 22


Iteration Continued...

Strings and Loops: Example 5

Write and execute a Python program to reverse the string “Programming”


using for loop.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 19 / 22


Iteration Continued...

Strings and Loops: Example 5 Solution

text = “Programming”
reversed text = “ ”
for char in text:
reversed text = char + reversed text
print(reversed text)

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 20 / 22


Iteration Continued...

Strings and Loops: Example 6

Write and execute a Python program to count the number of unique


characters in the string “Programming” using for loop.

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 21 / 22


Iteration Continued...

Strings and Loops: Example 6 Solution

s = “Programming”
t = “”
for char in s:
if char not in s:
t += char
print(t)
print(len(t))

Neeraj Joshi (IIT Delhi) Lecture 6 August 6, 2025 22 / 22


MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 7)

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 1 / 24


Iteration Continued...

Iteration Continued...

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 2 / 24


Iteration Continued...

f-String

f-string (formatted string) allows expressions to be embedded directly


inside strings using curly braces {}.
An f-string is defined by prefixing the string with the letter f or F.

Syntax:
f“some text expression”

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 3 / 24


Iteration Continued...

f-String: Example 1

Write and execute a Python program to count the vowels in a word.

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 4 / 24


Iteration Continued...

f-String: Example 1 - Solution

word = input(“Enter a word: ”)


vowels = “aeiouAEIOU”
count = 0
for char in word:
if char in vowels:
count += 1
print(f“The word ‘{word}’ contains {count} vowels.”)

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 5 / 24


Iteration Continued...

f-String: Example 2

Write and execute a Python program to print the squares of numbers from
1 to 20.

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 6 / 24


Iteration Continued...

f-String: Example 2 - Solution

n = int(input(“Enter the upper limit: ”))


for i in range(1, n+1):
print(f“{i**2}”)

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 7 / 24


Iteration Continued...

f-String: Example 3

Write and execute a Python program to check the strength of a password.

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 8 / 24


Iteration Continued...

f-String: Example 3 - Solution

password = input(“Enter your password: ”)


if len(password) < 6:
print(f“The password ‘{password}’ is too short.”)
else:
print(f“The password ‘{password}’ is acceptable.”)

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 9 / 24


Guess and Check

Guess and Check

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 10 / 24


Guess and Check

Basic Idea

“Guess and Check” is an important task in programming when one needs


to do a lot of enumeration.
It applies to a problem where (1) one is able to guess a value for solution,
(2) want to check if a solution is correct.
We can keep guessing until we find the solution or have guessed all values.

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 11 / 24


Guess and Check

Flow Chart

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 12 / 24


Guess and Check

Finding Square Root

Suppose an integer (int), x is given and we want to check whether there is


another integer which is the square root of x.
We start with a guess and check if it is the right answer.
We can start in a systematic way, like with guess = 0, then 1, then 2, etc.
If x is a perfect square, we will eventually find its root and can stop.
However, if x is not a perfect square, we need to know where to stop. We
can use algebra if guess squared is bigger than x, and can stop.

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 13 / 24


Guess and Check

Finding Square Root: Positive Squares

guess = 0

x = int ( input ( " Enter an integer : " ))

while guess **2 < x :


guess = guess + 1

if guess **2 == x :
print ( " Square root of " , x , " is " , guess )
else :
print (x , " is not a perfect square " )

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 14 / 24


Guess and Check

Finding Square Root: Positive and Negative Squares

x = int ( input ( " Enter an integer : " ))

if x < 0:
print ( " Square root of a negative number is not real . " )
else :
for guess in range ( x + 1):
if guess **2 == x :
print ( " Positive square root of " , x , " is " , guess )
print ( " Negative square root of " , x , " is " , - guess )

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 15 / 24


Guess and Check

Finding Cube Root: Positive Cubes

cube = int ( input ( " Enter an integer : " ))

for guess in range ( cube +1):


if guess **3 == cube :
print ( " Cube root of " , cube , " is " , guess )

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 16 / 24


Guess and Check

Finding Cube Root: Positive and Negative Cubes

cube = int ( input ( " Enter an integer : " ))

for guess in range ( abs ( cube )+1):


if guess **3 == abs ( cube ):
if cube < 0:
guess = - guess
print ( " Cube root of " + str ( cube )+ " is " + str ( guess ))

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 17 / 24


Binary Numbers

Binary Numbers

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 18 / 24


Binary Numbers

A Simple Code

x = 0
for i in range (10):
x += 0.1
print ( x == 1)
print (x , ' == ' , 10*0.1)

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 19 / 24


Binary Numbers

Floating Point Representation

All programming languages use “floating point” to approximate real


numbers.
The term “floating point” refers to the way these numbers are stored in the
computer.

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 20 / 24


Binary Numbers

Floating Point Representation (Contd.)

This representation depends on computer hardware (not on programming


language implementation).
Numbers (and everything else) are represented as a sequence of bits (0 or
1).
When we write numbers, the notation uses base 10. 0.1 stands for the
rational number 1/10.
It influences the coding style.

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 21 / 24


Binary Numbers

Why Binary?

Easy to implement in hardware—build components that can be in one of


two states.
Computer hardware is built around methods that can efficiently store
information as 0‘s or 1‘s and do arithmetic with this repetition.

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 22 / 24


Binary Numbers

Binary Numbers

Consider a number 1225. It can be written as base 10:


1225 = 1 ∗ 103 + 2 ∗ 102 + 2 ∗ 101 + 5 ∗ 100 = 1000 + 200 + 20 + 5.
Binary representation of this number is same but with base 2. So basically
divide the number by 2 and record the reminders:
122510 = 100110010012 =
1∗210 +0∗29 +0∗28 +1∗27 +1∗26 +0∗25 +0∗24 +1∗23 +0∗22 +0∗21 +1∗20

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 23 / 24


Binary Numbers

Python Program for Binary Representation

num = 1225
if num < 0:
is_neg = True
num = abs ( num )
else :
is_neg = False
result = ' '
if num == 0:
result = '0 '
while num > 0:
result = str ( num % 2) + result
num = num // 2
if is_neg :
result = ' - ' + result
print ( " Binary representation : " , result )

Neeraj Joshi (IIT Delhi) Lecture 7 August 11, 2025 24 / 24


MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 8)

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 1 / 16


Fractions to Binary

Fractions to Binary

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 2 / 16


Fractions to Binary

Fractions

Integers (positive and negative) have straightforward representations in


binary (see Lecture 7).
What about fractions?
What does the decimal fraction [Link] mean (here a,b,c are digits from 0 to
9)?
a ∗ 10−1 + b ∗ 10−2 + c ∗ 10−3
For example 0.543 = 5 ∗ 10−1 + 4 ∗ 10−2 + 3 ∗ 10−3
We use the same idea for binary representation as follows:
a ∗ 2−1 + b ∗ 2−2 + c ∗ 2−3
That means to convert a fraction f into binary, one needs to find the values
of a,b,c,...,etc., such that

f = 0.5a + 0.25b + 0.125c + 0.0625d + ...

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 3 / 16


Fractions to Binary

Convert Fraction into Binary: Intuitive Recipe

f = 0.625
Multiple the fraction 0.625 by 2 and write down the integer part (0 or 1):
0.625 × 2 = 1.25 (integer part 1, fractional part 0.25).
Multiple the fraction 0.25 by 2 and write down the integer part (0 or 1):
0.25 × 2 = 0.5 (integer part 0, fractional part 0.5).
Multiple the fraction 0.5 by 2 and write down the integer part (0 or 1):
0.5 × 2 = 1 (integer part 1, fractional part 0).
Now the fractional part has become 0, we can stop.
The integer part in order is 101.
So the binary representation would be 0.1012 , and 0.62510 = 0.1012 .

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 4 / 16


Fractions to Binary

Convert Fraction into Binary: Simple Method

Write f = 0.625 = 625/1000.


Simplify it as 5/8.
Recognize the denominator as a power of 2, i.e., 8 = 23 . That means the
binary fraction will have exactly 3 bits after the decimal point.
Now convert the numerator to binary (5 → 101 [3 bits]).
Place the bits after the decimal. Done! (0.62510 = 0.1012 ).

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 5 / 16


Fractions to Binary

Convert Fraction into Binary: Important Observation

If there is no integer n such that f ∗ (2n ) is a whole number, then internal


representation is always an approximation.
So, the floating point conversion works for numbers like 5/8 (and not for
1/10).

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 6 / 16


Fractions to Binary

Convert Fraction into Binary: Python Code

fraction = 0.625
binary = " 0. "

while fraction > 0:


fraction *= 2
bit = int ( fraction ) # Extract integer part (0 or 1)
binary += str ( bit )
fraction -= bit # Keep only the fractional part

print ( binary )

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 7 / 16


Floats

Floats

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 8 / 16


Floats

Storing Floating Point Numbers

Floating point is a pair of integers


The maximum number of significant digits decides the precision with which
numbers can be represented.
Most modern computers use 32 bits to represent significant digits.
If a number is represented with more than 32 bits in binary, the number will
be rounded.

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 9 / 16


Floats

Storing Floating Point Numbers (Contd.)

Exact in binary: 0.125 Not exact in binary: 0.1


x = 0
x = 0
for i in range(10):
for i in range(10):
x += 0.1
x += 0.125
print(x == 1)
print(x == 1.25)
print(x, '==', 10*0.1)

Since 0.125 is exact in binary, adding it 10 times should produce exactly


1.25 in floating-point, with no rounding error.
Since 0.1 is not exact in binary, so it is stored as an approximation.

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 10 / 16


Approximation Methods

Approximation Methods

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 11 / 16


Approximation Methods

Background

We have seen that “Guess-and-check” provides a simple algorithm for


solving problems. But it has some limitations.
We deal with exhaustive enumeration which works for enumerable sets.
Increment in this method is usually an integer.
This method can not give approximate solutions to varying degrees.

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 12 / 16


Approximation Methods

Approximation: Dealing with the Limitations of Guess


and Check

The idea is to find an approximation to an answer.


Sometimes exact answer may not be accessible.
So we need an answer that is close enough to the correct one.
Also, we can not test infinite possible answers.
We have to deal with floating point errors as well.

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 13 / 16


Approximation Methods

Finding Roots Using Approximation

Guess-and-Check worked well for perfect squares.


If the given number is not a perfect square, exhaustive search is infinite.
In that situation, find an r such that |r2 − x|< ϵ.
Start with a small guess, say g, then increment by a.
Continue until it is close enough to x.
Here ϵ stands for closeness to answer.
Increment means step size for guesses.
Smaller increment is slower but more accurate.
Larger ϵ is less accurate but faster.

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 14 / 16


Approximation Methods

Approximation Example

x = 100
epsilon = 0.01
num_guesses = 0
guess = 0.0
increment = 0.0001

while abs ( guess **2 - x ) >= epsilon :


guess += increment
num_guesses += 1

print ( ' num_guesses = ' , num_guesses )


print ( guess , ' is close to square root of ' , x )

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 15 / 16


Approximation Methods

Handling “Step Fast” in the Previous Example

while abs ( guess **2 - x ) >= epsilon and guess **2 <= x :
guess += increment
num_guesses += 1

if abs ( guess **2 - x ) >= epsilon :


print ( ' Failed on square root of ' , x )
else :
print ( guess , ' is close to square root of ' , x )

Neeraj Joshi (IIT Delhi) Lecture 8 August 13, 2025 16 / 16


MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 9)

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 1 / 12


Bisection Search

Bisection Search

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 2 / 12


Bisection Search

What is Bisection Search?

Bisection search is used to efficiently find approximate solutions to


equations.
It works as follows:
Start with an interval while solving an equation (answer lies within some
interval).
Repeatedly divide the search interval into two halves.
Check whether the target lies in the left or right half.
Keep narrowing the interval until you find the target, or the interval
becomes very small.
This method is more efficient than an exhaustive search.

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 3 / 12


Bisection Search

Finding Square Root

Suppose that you know that the answer lies between 0 and x.
In that situation, it is better to pick a number in the middle of this
interval. In an exhaustive search, we try things starting at 0.
If the midpoint g is close enough, it is perfect.
If not, check whether your guess is extremely large or small.
How to check?
If g 2 > x, then g is too large. In that case, find the midpoint (g ′ ) of the
interval, [0, g].
2
If g ′ < x, then g ′ is too small. In that case, find the midpoint (g ′′ ) of the
interval, [g ′ , g].
At each stage, reduce range of values by half.

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 4 / 12


Bisection Search

Square Root Example

Write and execute a Python code to find the square root of 73245 using
Bisection method (calculate the number of guesses as well). Compare
Bisection method with the Approximation method.

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 5 / 12


Bisection Search

Square Root Example: Solution

x = 73245
epsilon = 0.01
count_guesses = 0
lower = 0
upper = x
solution = ( upper + lower )/2.0

while abs ( solution **2 - x ) >= epsilon :


if solution **2 < x :
lower = solution
else :
upper = solution
solution = ( upper + lower )/2.0
count_guesses += 1

print ( count_guesses )
print ( solution )

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 6 / 12


Bisection Search

What are the Key Observations?

Bisection search reduces the number of guesses, thereby computation time


drastically.
One can observe linear growth in steps while implementing an
approximation method.
In contrast, Bisection search implies logarithmic growth.

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 7 / 12


Bisection Search

Square Root Example: What if 0 < x < 1?

If x < 1, search space is different (basically we are searching from 0 to x).


But square root, g is greater than x and less than 1 (x < g < 1).

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 8 / 12


Bisection Search

Square Root Example Code: Covering All Cases

x = 0.5
epsilon = 0.01

if x >= 1:
lower = 1.0
upper = x
else :
lower = x
upper = 1.0
solution = ( upper + lower ) / 2

while abs ( solution **2 - x ) >= epsilon :


if solution **2 < x :
lower = solution
else :
upper = solution
solution = ( upper + lower ) / 2.0
print ( solution )

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 9 / 12


Bisection Search

Newton-Rapshon Method

To find roots of a polynomial in one variable.


Consider
p(x) = an xn + an−1 xn−1 + · · · + a1 x + a0 .
If g is an approximation to the root, then

p(g)
g− .
p′ (g)

is a better approximation, where p′ is derivative of p


The method can be used to find the square root.

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 10 / 12


Bisection Search

Square Root Using Newton-Rapshon Method

Consider the polynomial, x2 − r


First derivative is 2x
Given a guess g for root of r, a better guess is

g2 − r
g− .
2g
This eventually gives an approximation to the square root of r.

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 11 / 12


Bisection Search

Square Root Using Newton-Rapshon Method (Contd.)

To find the square root of 36 [f (x) = x2 − 36].


An efficient and alternative way:

epsilon = 0.01
r = 36.0
g = r /2.0
count_guesses = 0

while abs ( g * g - r ) >= epsilon :


count_guesses += 1
g = g - ((( g **2) - r )/(2* g ))

print ( count_guesses )
print ( g )

Neeraj Joshi (IIT Delhi) Lecture 9 August 18, 2025 12 / 12


MTL5004/MTL505: Introduction to Computer
Programming
(Lecture 10)

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 1 / 21


Decomposition and Abstraction

Decomposition and Abstraction

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 2 / 21


Decomposition and Abstraction

Decomposition

The idea is to divide a Python program into self-contained parts that can
be combined to solve the given problem.
Basically, we want to break down a big, complex problem into smaller,
self-contained parts.
Each part is easier to write, debug, and reuse.
It can be achieved using functions, classes, and modules.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 3 / 21


Decomposition and Abstraction

Abstraction

The idea is to hide unnecessary details; focus only on what something does,
not how it does.
The aim is to make codes easier to understand, modify, and use.
It can be achieved using functions, classes, and libraries.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 4 / 21


Decomposition and Abstraction

Intuitive Idea

Can we view something in terms of


its inputs,
its outputs,
how outputs are related to the inputs, without any knowledge of its internal
workings.
Knowledge of the interface is sufficient to know the workings of a system.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 5 / 21


Decomposition and Abstraction

Abstraction Enables Decomposition

Complex systems consist of many independent parts, often built by


different manufacturers.
Components interact only through well-defined specifications.
Each manufacturer can solve sub-problems independently, reusing common
sub-parts.
This principle applies equally to hardware and software.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 6 / 21


Decomposition and Abstraction

How to Implement Abstraction in Python?

The user has a piece of code.


Tedious coding details must be hidden from the user.
Reuse that piece of code at different parts of the code without
copying/pasting.
Creates details and designs an interface.
No need to see the details.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 7 / 21


Decomposition and Abstraction

How to Implement Abstraction in Python? (Contd.)

The abstraction can be achieved with a function.


A function enables us to capture the code within a black box.
Once the function is created, it will produce an output from input, while
hiding details of how it does the computation.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 8 / 21


Decomposition and Abstraction

How to Create Structure with Decomposition?

Abstraction allows code to be divided into self-contained, reusable modules.


Modules help break code into logical pieces, making it organized and
coherent.
Decomposition can be achieved with functions and classes.
Decomposition builds complex systems from simpler parts through
abstraction.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 9 / 21


Decomposition and Abstraction

Functions

Reusable pieces of code are functions or procedures.


They capture the steps of a computation that can be used with any input.
A function is just some code written in a special, reusable way.
Defining a function tells Python that some code now exists in memory.
Functions are only useful when they are run.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 10 / 21


Decomposition and Abstraction

Characteristics of a Function

A function has a name.


It has parameters (0 or more) [inputs].
It has a docstring (although it is optional). Its like a comment represented
by """ (triple quotes) that provides a specification for the function.
It has a structure, that means a set of instructions to be executed.
It returns something.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 11 / 21


Decomposition and Abstraction

How to Write Functions?

def is_even ( i ) :
"""
Input : i , a positive int
Returns True if i is even , otherwise False
"""
if i % 2 == 0:
return True
else :
return False

def: Keyword
is_even: Name
(i):: Parameters or Arguments

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 12 / 21


Decomposition and Abstraction

How to Call (Invoke) a Function?

is_even(5)
is_even(9)
def is_even ( i ) :
return i % 2 == 0:
is_even (3)

Python replaces: formal parameters in function definition with values from


function call.
Example: i replaced with 3.
Python executes expressions in the body: return 3%2 == 0
A function‘s code only runs when you call (or invoke) the function.

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 13 / 21


Decomposition and Abstraction

Example 1

Write and execute a Python code that satisfies the following specs:
def div \ _by (n , d ) :
"""
n and d are ints > 0
Returns True if d divides n evenly and False otherwise
"""

Test your code with: (n = 15, d = 7), (n = 175, d = 16)

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 14 / 21


Decomposition and Abstraction

Insert Functions in Code

print ( " Numbers between 1 and 10: even or odd " )

for i in range (1 , 10) :


if is_even ( i ) :
print (i , " even " )
else :
print (i , " odd " )

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 15 / 21


Decomposition and Abstraction

Example 2

Suppose that we want to add all the odd integers between a and b (both
including).
Input: values for a and b
Output: sum of odds

def sum_odd (a , b ) :
# your code here
return sum_of_odds

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 16 / 21


Decomposition and Abstraction

Example 2 (Contd.)

while loop:
def sum_odd (a , b ) :
sum_of_odds = 0
i = a
while i <= b :
if i % 2 == 1:
sum_of_odds += i
print (i , sum_of_odds )
i += 1
return sum_of_odds

print ( sum_odd (2 ,4) )

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 17 / 21


Decomposition and Abstraction

Example 2 (Contd.)

for loop:
def sum_odd (a , b ) :
sum_of_odds = 0
for i in range (a , b +1) :
if i % 2 == 1:
sum_of_odds += i
print (i , sum_of_odds )
return sum_of_odds

print ( sum_odd (2 ,4) )

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 18 / 21


Decomposition and Abstraction

Example 3

Add all numbers between a and b (both including).


Use a loop

def sum_odd (a , b ) :
# your code here
return sum_of_odds

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 19 / 21


Decomposition and Abstraction

Example 3 (Contd.)

while loop:
def sum_odd (a , b ) :
sum_of_odds = 0
i = a
while i <= b :
sum_of_odds += i
print (i , sum_of_odds )
i += 1
return sum_of_odds

print ( sum_odd (2 ,4) )

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 20 / 21


Decomposition and Abstraction

Example 3 (Contd.)

for loop:
def sum_odd (a , b ) :
sum_of_odds = 0
for i in range (a , b +1) :
sum_of_odds += i
print (i , sum_of_odds )
return sum_of_odds

print ( sum_odd (2 ,4) )

Neeraj Joshi (IIT Delhi) Lecture 10 August 25, 2025 21 / 21


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 11)

Python Programming Lecture 11 August 27, 2025 1 / 29


Functions as Objects

Functions as Objects

Python Programming Lecture 11 August 27, 2025 2 / 29


Functions as Objects

Important Points

A function always returns something.


Python returns the value None if no return is given.
None represents the absence of a value.
If invoked in the cell, nothing is printed.
No static semantic error is generated.

Python Programming Lecture 11 August 27, 2025 3 / 29


Functions as Objects

Difference between return and print

return print
Only has meaning inside a Can be used inside or outside
function. functions.
Only one return is executed per Many prints can run in one call.
call. Execution continues after print.
Code after return is not Sends text to console; the
executed. expression print(...) itself
Produces a value for the caller. returns None.

Python Programming Lecture 11 August 27, 2025 4 / 29


Functions as Objects

Bisection Square-Root Method as a Function

def bisection_root ( x ) :
epsilon = 0.01
lower = 0
upper = x
guess = ( lower + upper ) / 2.0
while abs ( guess **2 - x ) >= epsilon :
if guess **2 < x :
lower = guess
else :
upper = guess
guess = ( lower + upper ) / 2.0
return guess
print ( bisection_root (65) )

Python Programming Lecture 11 August 27, 2025 5 / 29


Functions as Objects

Exercise

Write a function that counts how many integers have square roots within
the epsilon of n? Here n is an int > 2 and epsilon is a positive number
< 1.

Python Programming Lecture 11 August 27, 2025 6 / 29


Functions as Objects

Solution

def c o u n t _ n u m s _ w i t h _ s q r t _ c l o s e _ t o (n , epsilon ) :
"""
n is an int > 2
epsilon is a positive number < 1
Returns how many integers have a square root within
epsilon of n
"""
count = 0
start = int (( n - epsilon ) **2)
end = int (( n + epsilon ) **2) + 1

for x in range ( start , end + 1) :


approx = bisection_root ( x )
if abs ( approx - n ) <= epsilon :
count += 1
return count
print ( c o u n t _ n u m s _ w i t h _ s q r t _ c l o s e _ t o (10 , 0.1) )

Python Programming Lecture 11 August 27, 2025 7 / 29


Functions as Objects

How Python Execute Function Calls?

How does Python know what value is associated with a variable name?
It creates a new environment with every function call!
Like a mini program that it needs to complete.
The mini program runs with assigning its parameters to some inputs.
It does the work (body of the function).
It returns a value.
The environment disappears after it returns the value.

Python Programming Lecture 11 August 27, 2025 8 / 29


Functions as Objects

Environments

Global environment
Where user interacts with Python interpreter
Where the program starts out
Invoking a function creates a new environment (frame/scope).

Python Programming Lecture 11 August 27, 2025 9 / 29


Functions as Objects

Variable Scope

Formal parameters get bound to the value of input parameters.


Scope is a mapping of names to objects.
Defines context in which body is evaluated.
Values of variables given by bindings of names.
Expressions in body of function evaluated w.r.t. this new scope.

def f ( x ) :
x = x + 1
print ( x )
return x

x = 3
z = f(x)

Python Programming Lecture 11 August 27, 2025 10 / 29


Functions as Objects

Variable Scope (Contd.)

def f ( x ) :
x = x + 1
print ( x )
return x

x = 3
z = f(x)

Global scope has a binding for name f.


Function object created, but body not executed yet.

Python Programming Lecture 11 August 27, 2025 11 / 29


Functions as Objects

Variable Scope (Contd.)

def f ( x ) :
x = x + 1
print ( x )
return x

x = 3
z = f(x)

A new function scope is created.


Local variable x = 3 inside function f.
Execution happens inside this temporary environment.

Python Programming Lecture 11 August 27, 2025 12 / 29


Functions as Objects

Variable Scope (Contd.)

def f ( x ) :
x = x + 1
print ( x )
return x

y = 3
z = f(y)

Global scope: variable y = 3


New function scope created with parameter x = 3
Separate bindings in global and function scope

Python Programming Lecture 11 August 27, 2025 13 / 29


Functions as Objects

Functions as Arguments

Objects in Python have a type


int, float, str, bool, NoneType, function
Objects can appear on RHS of an assignment statement
Bind a name to an object
Objects:
Can be used as an argument to a procedure
Can be returned as a value from a procedure
Functions are also first-class objects!
Treat functions just like the other types
Functions can be arguments to another function
Functions can be returned by another function

Python Programming Lecture 11 August 27, 2025 14 / 29


Functions as Objects

Function as a Parameter

def calculate ( operate , x , y ) :


return operate (x , y )

def add (a , b ) :
return a + b

def div (a , b ) :
if b != 0:
return a / b
print (" Denominator was 0.")

print ( calculate ( add , 2 , 3) )

Python Programming Lecture 11 August 27, 2025 15 / 29


Functions as Objects

Function as a Parameter: Step 1

Evaluate the function definitions.


Global frame gets names bound to function objects:
calculate, add, div
None of their bodies have run yet.

Python Programming Lecture 11 August 27, 2025 16 / 29


Functions as Objects

Function as a Parameter: Step 2

Evaluate the call expression: print(calculate(add, 2, 3)).


First evaluate the arguments:
add → a function object.
2 → an int object.
3 → an int object.
Then call calculate with these arguments.

Python Programming Lecture 11 August 27, 2025 17 / 29


Functions as Objects

Function as a Parameter: Step 3

A new environment (frame) for calculate is created.


Local variables inside this frame:
operate → bound to add function object.
x → bound to 2.
y → bound to 3.

Python Programming Lecture 11 August 27, 2025 18 / 29


Functions as Objects

Function as a Parameter: Step 4

Evaluate the body of calculate.


return operate(x, y)
Since operate = add, this becomes:
return add(2, 3)

Python Programming Lecture 11 August 27, 2025 19 / 29


Functions as Objects

Function as a Parameter: Step 5

To evaluate add(2, 3), a new frame for add is created.


Local variables inside this frame:
a → 2.
b → 3.

Python Programming Lecture 11 August 27, 2025 20 / 29


Functions as Objects

Function as a Parameter: Step 6

Evaluate the body of add.


return a + b.
a + b = 2 + 3 = 5.
So the value 5 is returned to calculate.

Python Programming Lecture 11 August 27, 2025 21 / 29


Functions as Objects

Function as a Parameter: Step 7

calculate receives the result 5.


Returns this value to the global frame.
The function call calculate(add, 2, 3) evaluates to 5.

Python Programming Lecture 11 August 27, 2025 22 / 29


Functions as Objects

Function as a Parameter: Step 8

Now the outer expression is print(5).


This prints 5 in the console.

Python Programming Lecture 11 August 27, 2025 23 / 29


Functions as Objects

Exercise 1

Write a function that applies a function twice.

Python Programming Lecture 11 August 27, 2025 24 / 29


Functions as Objects

Exercise 1: Solution

def apply_twice ( func , x ) :


return func ( func ( x ) )

def square ( n ) :
return n * n

print ( apply_twice ( square , 2) ) # 16

Python Programming Lecture 11 August 27, 2025 25 / 29


Functions as Objects

Exercise 2

Write a function calculate(op, a, b) where op can be either add or


subtract.

Python Programming Lecture 11 August 27, 2025 26 / 29


Functions as Objects

Exercise 2: Solution

def calculate ( operation , a , b ) :


return operation (a , b )

def add (x , y ) :
return x + y

def subtract (x , y ) :
return x - y

print ( calculate ( add , 5 , 3) ) # 8


print ( calculate ( subtract , 5 , 3) ) # 2

Python Programming Lecture 11 August 27, 2025 27 / 29


Functions as Objects

Exercise 3

Define a function greet(name, msg="Hello") that prints a message.

Python Programming Lecture 11 August 27, 2025 28 / 29


Functions as Objects

Exercise 3: Solution

def greet ( name , msg =" Hello ") :


print ( msg , name )

greet (" Alice ") # Hello Alice


greet (" Bob " , msg =" Welcome ") # Welcome Bob

Python Programming Lecture 11 August 27, 2025 29 / 29


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 12)

Python Programming Lecture 12 August 28, 2025 1 / 19


Lambda Functions

Lambda Functions

Python Programming Lecture 12 August 28, 2025 2 / 19


Lambda Functions

Anonymous Functions

Sometimes we don’t want to name functions, especially simple ones.


The named function

def is_even ( x ) :
return x % 2 == 0

can be written as an anonymous function using lambda as follows:


lambda x : x % 2 == 0

lambda creates a function object, but simply does not bind a name to it.

Python Programming Lecture 12 August 28, 2025 3 / 19


Lambda Functions

Anonymous Functions (Contd.)

Function call with a named function:

apply ( is_even , 15)

Function call with an anonymous function:

apply ( lambda x : x % 2 == 0 , 15)

Note that lambda functions are one-time use; they cannot be reused.

Python Programming Lecture 12 August 28, 2025 4 / 19


Lambda Functions

Exercise 1

Write a function do twice(n, fn) that takes an integer n, and a function fn


and returns the result of applying fn two times to n.

Python Programming Lecture 12 August 28, 2025 5 / 19


Lambda Functions

Exercise 1: Solution

def do_twice (n , fn ) :
return fn ( fn ( n ) )

print ( do_twice (12 , lambda x : x **2) )

Python Programming Lecture 12 August 28, 2025 6 / 19


Tuples

Tuples

Python Programming Lecture 12 August 28, 2025 7 / 19


Tuples

Tuples

We have various types of scalar in Python such as int, float, bool.


In addition, one compound type is string.
Tuple is a more general type of compound data.
Tuples are indexed sequences of elements, which themselves could be
compound structures.
Tuples are immutable.

Python Programming Lecture 12 August 28, 2025 8 / 19


Tuples

Tuples (Contd.)

Indexable ordered sequence of objects.


Objects can be any type: integers, strings, tuples, etc.
Immutable – elements cannot be changed.

te = ()
ts = (2 ,)

t = (2 , " IIT " , 3)


print ( t [0]) # 2
print ((2 , " IIT " ,3) + (5 ,6) ) # (2 ," IIT " ,3 ,5 ,6)
print ( t [1:2]) # (" IIT " ,)
print ( t [1:3]) # (" IIT " ,3)
print ( len ( t ) ) # 3
print ( max ((3 ,5 ,0) ) ) # 5

t [1] = 4 # Error ! Tuples are immutable

Python Programming Lecture 12 August 28, 2025 9 / 19


Tuples

Indices and Slicing

seq = (2 , 'a ' ,4 ,(1 ,2) )

print ( len ( seq ) ) # 4


print ( seq [3]) # (1 ,2)
print ( seq [ -1]) # (1 ,2)
print ( seq [3][0]) # 1
print ( seq [4]) # Error

print ( seq [1]) # 'a '


print ( seq [ -2:]) # (4 ,(1 ,2) )
print ( seq [1:4:2]) # ( ' a ' ,(1 ,2) )
print ( seq [: -1]) # (2 , ' a ' ,4)
print ( seq [1:3]) # ( ' a ' ,4)

for e in seq :
print ( e )

Python Programming Lecture 12 August 28, 2025 10 / 19


Tuples

Tuples: Swapping Values

Tuples provide a convenient way to swap variables.

x = 1
y = 2

# Traditional way
temp = x
x = y
y = temp

# Pythonic way using tuples


(x , y ) = (y , x )

print (x , y ) # 2 1

Python Programming Lecture 12 August 28, 2025 11 / 19


Tuples

Tuples: Returning Multiple Values

Functions can return more than one value using tuples.

def qu oti e n t _ a n d _ r e m ain de r (x , y ) :


q = x // y
r = x % y
return (q , r )

both = q uo t i e n t _ a n d _ re ma in der (10 , 3)


print ( both ) # (3 , 1)

( quot , rem ) = q u o t i e nt_ an d_ rem ai nd er (5 , 2)


print ( quot , rem ) # 2 1

Python Programming Lecture 12 August 28, 2025 12 / 19


Tuples

Variable Number of Arguments

Some built-in functions take a variable number of arguments (e.g. min).


Python allows programmers to define such functions using *args.
Inside the function, args is a tuple of all supplied values.

def mean (* args ) :


total = 0
for a in args :
total += a
return total / len ( args )

print ( mean (1 , 2 , 3 , 4 , 5 , 6) ) # 3.5

Python Programming Lecture 12 August 28, 2025 13 / 19


Lists

Lists

Python Programming Lecture 12 August 28, 2025 14 / 19


Lists

Lists

Indexable ordered sequence of objects.


Usually homogeneous (all integers, all strings, etc.) but can contain mixed
types.
Denoted by square brackets: [].
Mutable – elements can be changed.

Python Programming Lecture 12 August 28, 2025 15 / 19


Lists

Indices and Ordering

a_list = []
L = [2 , 'a ' , 4 , [1 ,2]]

print ([1 ,2] + [3 ,4]) # [1 ,2 ,3 ,4]


print ( len ( L ) ) # 4
print ( L [0]) # 2
print ( L [2] + 1) # 5
print ( L [3]) # [1 ,2]
print ( L [4]) # Error

i = 2
print ( L [i -1]) # 'a '

print ( max ([3 ,5 ,0]) ) # 5

Python Programming Lecture 12 August 28, 2025 16 / 19


Lists

Iterating Over a List

Compute the sum of elements of a list.


Elements are indexed 0 to len(L)-1.
range(n) goes from 0 to n-1.

total = 0
for i in range ( len ( L ) ) :
total += L [ i ]
print ( total )

total = 0
for i in L :
total += i
print ( total )

Python Programming Lecture 12 August 28, 2025 17 / 19


Lists

Iterating Over a List in a Function

Natural to capture iteration inside a function.


Example: list sum([8,3,5]).

def list_sum ( L ) :
total = 0
for i in L :
total += i
return total

print ( list_sum ([8 ,3 ,5]) ) # 16

Python Programming Lecture 12 August 28, 2025 18 / 19


Lists

Lists Support Iteration

Lists are ordered sequences, so they work naturally with iteration.

def list_sum ( L ) :
total = 0
for e in L :
total += e
return total

print ( list_sum ([1 ,3 ,5]) ) # 9

def len_sum ( L ) :
total = 0
for s in L :
total += len ( s )
return total

print ( len_sum ([ ' ab ' , ' def ' , 'g ' ]) ) # 6

Python Programming Lecture 12 August 28, 2025 19 / 19


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 13)

Python Programming Lecture 13 September 1, 2025 1 / 23


Lists and Mutability

Lists and Mutability

Python Programming Lecture 13 September 1, 2025 2 / 23


Lists and Mutability

Indices and Ordering in Lists

a_list = [] # Empty List

L = [1 , 'a ' , 2 , [1 ,2]]


len ( L ) # 4
L [0] # 1
L [3] # [1 ,2]
L [1:3] # [ ' a ', 2]
for e in L : # loop variable becomes each element in L
print ( e )
L [3] = 10 # mutates L to [1 , ' a ' ,2 ,10]

[2 , 'a '] + [3 ,4] # [2 , ' a ' ,3 ,4]

max ([4 ,5 ,0]) # 5

Python Programming Lecture 13 September 1, 2025 3 / 23


Lists and Mutability

Mutability

Lists are mutable!


Assigning to an element at an index changes the value

L = [1 , 2 , 3]
L [1] = 4
# L is now [1 , 4 , 3]; same object L

Python Programming Lecture 13 September 1, 2025 4 / 23


Lists and Mutability

Mutability (Contd.)

Making L by mutating an element vs. creating a new object:

L = [1 , 2 , 3]
L [1] = 4 # [1 , 4 , 3]

t = (1 , 2 , 3)
t = (1 , 4 , 3) # creates a new tuple

Python Programming Lecture 13 September 1, 2025 5 / 23


Lists and Mutability

Operation on Lists – append

Add an element to end of list with [Link](element)


Mutates the list!

L = [1 ,2 ,3]
L . append (4) # L is now [1 ,2 ,3 ,4]

Python Programming Lecture 13 September 1, 2025 6 / 23


Lists and Mutability

Operation on Lists – append (Contd.)

When append returns None?

L = [1 ,2 ,3]
L . append (4) # L is now [1 ,2 ,3 ,4]
L = L . append (4) # L becomes None

Note
The append operation does a mutation but returns the None object as a result.

Python Programming Lecture 13 September 1, 2025 7 / 23


Lists and Mutability

Operation on Lists – append (Contd.)

L = [1 ,2 ,3]
L . append (4) # [1 ,2 ,3 ,4]
L . append (4) # [1 ,2 ,3 ,4 ,4]
print ( L ) # [1 ,2 ,3 ,4 ,4]

Python Programming Lecture 13 September 1, 2025 8 / 23


Lists and Mutability

Try It!

What is the value of L1, L2, L3 and L at the end?


L1 = [ 'a ']
L2 = [ 'b ']
L3 = [ 'c ']

L4 = L1 + L2
L3 . append ( L4 )
L = L1 . append ( L3 )

Python Programming Lecture 13 September 1, 2025 9 / 23


Lists and Mutability

Operation on Lists: append (Contd.)

Example: L = [1,2,3]
[Link](4) (L is an object of some type, append represents a function
that works on an object of this type, (4) represents the function argument.)
What is the dot (.)?
Lists are Python objects (everything in Python is an object)
Objects have data
Object types also have associated operations (methods)
Access this information by object [Link] something()
Equivalent to calling append with arguments L and 4

Python Programming Lecture 13 September 1, 2025 10 / 23


Lists and Mutability

Exercise 1

Write a function that meets these specs:


def make_or dered_ list ( n ) :
""" n is a positive int
Returns a list containing all ints in order
from 0 to n ( inclusive )
"""

Python Programming Lecture 13 September 1, 2025 11 / 23


Lists and Mutability

Exercise 1: Solution

Write a function that meets the following specification:


def make_or dered_ list ( n ) :
""" n is a positive int
Returns a list containing all ints in order
from 0 to n ( inclusive )
"""
return list ( range ( n +1) )
print ( make_o rdered _list (0) )
print ( make_o rdered _list (3) )
print ( make_o rdered _list (5) )

Python Programming Lecture 13 September 1, 2025 12 / 23


Lists and Mutability

Exercise 2

Write a function that meets the following specification:


def remove_element (L , e ) :
"""
L is a list
Returns a new list with elements in the same order as L
but without any elements equal to e .
"""

Python Programming Lecture 13 September 1, 2025 13 / 23


Lists and Mutability

Exercise 2: Solution

Write a function that meets the following specification:


def remove_element (L , e ) :
"""
L is a list
Returns a new list with elements in the same order as L
but without any elements equal to e .
"""
new_list = []
for item in L :
if item != e :
new_list . append ( item )
return new_list
print ( remove_element ([ 'a ' , 'b ' , 'a ' , 'c '] , 'a ') )

Python Programming Lecture 13 September 1, 2025 14 / 23


Lists and Mutability

Strings to Lists

Convert string to list with list(s) (Every character from s is an element


in a list)
Use [Link]() to split a string on a character parameter, splits on spaces
if called without a parameter

s = " Introduction to Computer Programming " # s is a string


L = list ( s )
L1 = s . split ( ' ')
L2 = s . split ( ' to ')

Python Programming Lecture 13 September 1, 2025 15 / 23


Lists and Mutability

Lists to Strings

Convert a list of strings back to a string.


Use ' '.join(L) to turn a list of strings into a bigger string.
You can give a character in quotes to add char between every element.

L = [ 'a ' , 'b ' , 'c ']


A = ' '. join ( L ) # " abc "
B = '_ '. join ( L ) # " a_b_c "

C = ' '. join ([1 ,2 ,3]) # error


C = ' '. join ([ '1 ' , '2 ' , '3 ' ]) # "123"

Python Programming Lecture 13 September 1, 2025 16 / 23


Lists and Mutability

Try It!

Write a function that meets the following specifications:


def count_words ( statement ) :
""" statement is a string representing a sentence
Returns how many words are in statement
( a word is a sequence of characters between spaces ) . """

print ( count_words ( " Hello it 's me " ) )

Python Programming Lecture 13 September 1, 2025 17 / 23


Lists and Mutability

Try It!

Write a function that meets the following specifications:


def count_words ( statement ) :
""" statement is a string representing a sentence
Returns how many words are in statement
( a word is a sequence of characters between spaces ) . """
return len ( statement . split () )
print ( count_words ( " Hello it 's me " ) )

Python Programming Lecture 13 September 1, 2025 18 / 23


Lists and Mutability

Some Other List Operations

Add element: [Link](element) (mutates list)


Sort: [Link]() (mutates list)
Reverse: [Link]() (mutates list)
Sorted: sorted(L) (returns a new sorted list)

L = [3 ,2 ,5]
L . sort () # L becomes [2 ,3 ,5]
L . reverse () # L becomes [5 ,2 ,3]
L_new = sorted ( L ) # returns [2 ,3 ,5] , original unchanged

Python Programming Lecture 13 September 1, 2025 19 / 23


Lists and Mutability

Mutability

L = [6 ,7 ,5 ,2]
L . append (4) # L = [6 ,7 ,5 ,2 ,4]

a = sorted ( L ) # returns new sorted list , does not mutate L


b = L . sort () # mutates L to [2 ,4 ,5 ,6 ,7] , returns None
L . reverse () # mutates L to [4 ,2 ,5 ,7 ,6] , returns None

Python Programming Lecture 13 September 1, 2025 20 / 23


Lists and Mutability

Mutability (contd.)

L = [9 ,6 ,0 ,3]
L . append (5) # [9 ,6 ,0 ,3 ,5]

a = sorted ( L ) # [0 ,3 ,5 ,6 ,9]
b = L . sort () # L mutated to [0 ,3 ,5 ,6 ,9] , b = None
L . reverse () # L mutated to [9 ,6 ,5 ,3 ,0]

Python Programming Lecture 13 September 1, 2025 21 / 23


Lists and Mutability

Try it!

def sort_words ( s ) :
""" s is a string representing a sentence
Returns a list containing all the words in s but
sorted in alphabetical order . """

print ( sort_words ( " how are you " ) )

Python Programming Lecture 13 September 1, 2025 22 / 23


Lists and Mutability

Try it!

def sort_words ( s ) :
""" s is a string representing a sentence
Returns a list containing all the words in s but
sorted in alphabetical order . """
words = s . split ()
words . sort ()
return words

print ( sort_words ( " how are you " ) )

Python Programming Lecture 13 September 1, 2025 23 / 23


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 14)

Python Programming Lecture 14 September 3, 2025 1 / 13


Iteration in Lists

Iteration in Lists

Python Programming Lecture 14 September 3, 2025 2 / 13


Iteration in Lists

Example 1

Write and execute a Python program to square every element of a list,


mutating the original list.

Python Programming Lecture 14 September 3, 2025 3 / 13


Iteration in Lists

Example 1: Solution

def square_list ( L ) :
for i in range ( len ( L ) ) :
L [ i ] = L [ i ]**2

L = [5 ,6 ,7]
print ( L ) # [5 ,6 ,7]
square_list ( L )
print ( L ) # [25 ,36 ,49]

Python Programming Lecture 14 September 3, 2025 4 / 13


Iteration in Lists

Mutation

Lists are mutable structures.


Advantage: Can update a single element without copying the whole list.
For example, updating one record in a very large personnel list.
This flexibility can also introduce unexpected challenges.

Python Programming Lecture 14 September 3, 2025 5 / 13


Iteration in Lists

Some Ideas for Mutation

Loop over indices of L, mutate L each time (adds elements).


Loop over elements of L, mutate L each time (adds elements).
Loop over elements of L, reassigning L to a new object each time.
Loop over elements of L, mutate L by removing elements.

Python Programming Lecture 14 September 3, 2025 6 / 13


Iteration in Lists

Stepwise Appending Example 1

L = [1 ,2 ,3 ,4]
for i in range ( len ( L ) ) :
L . append ( i )
print ( L )
# 1 st : [1 ,2 ,3 ,4 ,0]
# 2 nd : [1 ,2 ,3 ,4 ,0 ,1]
# 3 rd : [1 ,2 ,3 ,4 ,0 ,1 ,2]
# 4 th : [1 ,2 ,3 ,4 ,0 ,1 ,2 ,3]

Iteration based on fixed range.


Each step adds new element but loop count remains fixed.

Python Programming Lecture 14 September 3, 2025 7 / 13


Iteration in Lists

Stepwise Appending Example 2

L = [1 ,2 ,3 ,4]
i = 0
for e in L :
L . append ( i )
i += 1
print ( L )
# Never stops ! List keeps growing .

Python Programming Lecture 14 September 3, 2025 8 / 13


Iteration in Lists

Combining Lists

L1 = [1 ,2 ,3]
L2 = [4 ,5 ,6]

L3 = L1 + L2 # [1 ,2 ,3 ,4 ,5 ,6]

Python Programming Lecture 14 September 3, 2025 9 / 13


Iteration in Lists

Combining Lists (Contd.)

L1 = [1 ,2 ,3]
L2 = [4 ,5 ,6]

L3 = L1 + L2 # [1 ,2 ,3 ,4 ,5 ,6]
L1 . extend ([0 ,6]) # [1 ,2 ,3 ,0 ,6]

Python Programming Lecture 14 September 3, 2025 10 / 13


Iteration in Lists

Combining Lists (Contd.)

L1 = [2 ,1 ,3]
L2 = [4 ,5 ,6]

L3 = L1 + L2 # [2 ,1 ,3 ,4 ,5 ,6]
L1 . extend ([0 ,6]) # [2 ,1 ,3 ,0 ,6]
L2 . extend ([[1 ,2] ,[3 ,4]]) # [4 ,5 ,6 ,[1 ,2] ,[3 ,4]]

Python Programming Lecture 14 September 3, 2025 11 / 13


Iteration in Lists

Combining Example 1

L = [1 ,2 ,3 ,4]
for e in L :
L = L + L
print ( L )

1st: new L = [1,2,3,4,1,2,3,4]


2nd: doubles again → [1,2,3,4,...] length 16
3rd: doubles again → length 32
4th: doubles again → length 64

Python Programming Lecture 14 September 3, 2025 12 / 13


Iteration in Lists

Empty Out a List (Same Object)

A list can be mutated to remove all its elements. This does not make a new
empty list!
Use [Link]().
To check whether a list is the same object in memory, id() function can be
used.

L = [4 ,5 ,6]
id ( L )

L . append (8)
id ( L )

L . clear () # same object , emptied


id ( L )

L = [] # new empty list , different id


id ( L )

Python Programming Lecture 14 September 3, 2025 13 / 13


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 15)

Python Programming Lecture 15 September 4, 2025 1 / 26


Aliasing and Cloning

Aliasing and Cloning

Python Programming Lecture 15 September 4, 2025 2 / 26


Aliasing and Cloning

Making a Copy of the List

Can make a copy of a list object by duplicating all elements (top-level) into
a new list object
Lcopy = L[:]
Equivalent to looping over L and appending each element to Lcopy
This does not make a copy of elements that are lists

Loriginal = [4 ,5 ,6]
Lnew = Loriginal [:]

Loriginal # [4 ,5 ,6]
Lnew # [4 ,5 ,6]

Python Programming Lecture 15 September 4, 2025 3 / 26


Aliasing and Cloning

Exercise 1

Write a function that meets the following specification.

def remove_all (L , e ) :
"""
L is a list
Mutates L to remove all elements in L that are equal to
e
Returns None
"""

L = [1 ,2 ,2 ,2]
remove_all (L , 2)
print ( L ) # prints [1]

Python Programming Lecture 15 September 4, 2025 4 / 26


Aliasing and Cloning

Exercise 1: Solution

def remove_all (L , e ) :
"""
L is a list
Mutates L to remove all elements in L that are equal to
e
Returns None
"""
copy_L = L [:]
L . clear ()
for item in copy_L :
if item != e :
L . append ( item )

L = [1 ,2 ,2 ,2]
remove_all (L , 2)
print ( L ) # prints [1]

Python Programming Lecture 15 September 4, 2025 5 / 26


Aliasing and Cloning

Operation on Lists: remove

del(L[index]) – delete element at a specific index


[Link]() – remove element at end of list (returns it)
[Link](element) – removes first occurrence of element

L = [2 ,1 ,3 ,6 ,3 ,7 ,0] # do below in order

L . remove (2) # [1 ,3 ,6 ,3 ,7 ,0]


L . remove (3) # [1 ,6 ,3 ,7 ,0]
a = L . pop () # returns 0 , L = [1 ,6 ,3 ,7]
del ( L [1]) # [1 ,3 ,7]

Python Programming Lecture 15 September 4, 2025 6 / 26


Aliasing and Cloning

Exercise 1 with remove

Rewrite the code of Exercise 1 to remove e as long as it is still in the list.

Python Programming Lecture 15 September 4, 2025 7 / 26


Aliasing and Cloning

Exercise 1 with remove: Solution

def remove_all (L , e ) :
"""
L is a list
Mutates L to remove all elements in L that are equal to
e
Returns None .
"""
while e in L :
L . remove ( e )

L = [1 , 2 , 2 , 2]
remove_all (L , 2)
print ( L )

Python Programming Lecture 15 September 4, 2025 8 / 26


Aliasing and Cloning

Exercise 1 with remove: Solution

def remove_all (L , e ) :
"""
L is a list
Mutates L to remove all elements in L that are equal to
e
Returns None .
"""
for x in L :
if x == e :
L . remove ( e )

L = [1 ,2 ,2 ,2]
remove_all (L , 2)
print ( L ) # what is the output ?

Python Programming Lecture 15 September 4, 2025 9 / 26


Aliasing and Cloning

Exercise 1 with remove: Solution

def remove_all (L , e ) :
"""
L is a list
Mutates L to remove all elements in L that are equal to
e
Returns None .
"""
for x in L [:]:
if x == e :
L . remove ( e )

L = [1 ,2 ,2 ,2]
remove_all (L , 2)
print ( L ) # compare with the previous output ?

Python Programming Lecture 15 September 4, 2025 10 / 26


Aliasing and Cloning

Exercise 2

Write and execute a Python program to mutate the list L1 to remove any
elements that are also in another list L2.

Python Programming Lecture 15 September 4, 2025 11 / 26


Aliasing and Cloning

Mutation and Iteration without Clone

def remove_dups ( L1 , L2 ) :
for e in L1 :
if e in L2 :
L1 . remove ( e )

L1 = [10 , 20 , 30 , 40]
L2 = [10 , 20 , 50 , 60]
remove_dups ( L1 , L2 ) # check the output of L1

Python Programming Lecture 15 September 4, 2025 12 / 26


Aliasing and Cloning

Mutation and Iteration with Clone

def remove_dups ( L1 , L2 ) :
L1_copy = L1 [:]
for e in L1_copy :
if e in L2 :
L1 . remove ( e )

L1 = [10 , 20 , 30 , 40]
L2 = [10 , 20 , 50 , 60]
remove_dups ( L1 , L2 ) # compare the output with previous one

Python Programming Lecture 15 September 4, 2025 13 / 26


Aliasing and Cloning

Aliasing

Aliasing means giving two (or more) names to the same object in memory.
If one name is used to modify the object, the changes will be visible when
accessed through the other name too.
For example, a city may be known by many names.
All nicknames point to the same city.
Add new attribute to one nickname (all aliases share it).

Python Programming Lecture 15 September 4, 2025 14 / 26


Aliasing and Cloning

Mutation and Iteration with Alias

When you pass a list as a parameter to a function, you are making an alias.
The actual parameter (from the call) is an alias for the formal parameter
(from the function definition).
Assignment (=) on a mutable object creates an alias, not a clone.
So iterating over alias is like iterating original list.

def remove_dups ( L1 , L2 ) :
L1_copy = L1
for e in L1_copy :
if e in L2 :
L1 . remove ( e )

L1 = [10 , 20 , 30 , 40]
L2 = [10 , 20 , 50 , 60]
remove_dups ( L1 , L2 )

Python Programming Lecture 15 September 4, 2025 15 / 26


Aliasing and Cloning

Mutation and Iteration with Alias

def remove_dups ( L1 , L2 ) :
L1_copy = L1
for e in L1_copy :
if e in L2 :
L1 . remove ( e )

La = [10 , 20 , 30 , 40]
Lb = [10 , 20 , 50 , 60]
remove_dups ( La , Lb )
print ( La ) # [20 ,30 ,40]

Python Programming Lecture 15 September 4, 2025 16 / 26


Aliasing and Cloning

Aliases, Shallow Copies, and Deep Copies

Assignment just creates a new alias.


Shallow copy duplicates only the top-level list.
Deep copy duplicates all nested structures too.
Useful distinction when elements themselves are mutable.

Python Programming Lecture 15 September 4, 2025 17 / 26


Aliasing and Cloning

Control Copying

Assignment creates a new pointer to the same object.


Mutating one affects the other.

old_list = [[1 ,2] ,[3 ,4] ,[5 , 'x ' ]]


new_list = old_list

new_list [2][1] = 6

print ( " New list : " , new_list )


print ( " Old list : " , old_list )

Python Programming Lecture 15 September 4, 2025 18 / 26


Aliasing and Cloning

Control Copying (Contd.)

Suppose we want to create a copy of a list, not just a shared pointer.


Shallow copying does this at the top level of the list.
Equivalent to syntax [:].
Any mutable elements are NOT copied.
Use this when your list contains immutable objects only.

import copy

old_list = [[1 ,2] ,[3 ,4] ,[5 ,6]]


new_list = copy . copy ( old_list )

print ( " New list : " , new_list )


print ( " Old list : " , old_list )

Python Programming Lecture 15 September 4, 2025 19 / 26


Aliasing and Cloning

Control Copying (Contd.)

old_list = [[1 ,2] ,[3 ,4] ,[5 ,6]]


new_list = copy . copy ( old_list )

print ( " New list : " , new_list )


print ( " Old list : " , old_list )

Python Programming Lecture 15 September 4, 2025 20 / 26


Aliasing and Cloning

Control Copying (Contd.)

Mutate the top-level structure.

import copy

old_list = [[1 ,2] ,[3 ,4] ,[5 ,6]]


new_list = copy . copy ( old_list )

old_list . append ([7 ,8])

print ( " New list : " , new_list )


print ( " Old list : " , old_list )

Python Programming Lecture 15 September 4, 2025 21 / 26


Aliasing and Cloning

Control Copying (Contd.)

But if we change an element in one of the sub-structures, they are shared!


If your elements are not mutable, then this is not a problem.

import copy

old_list = [[1 ,2] ,[3 ,4] ,[5 ,6]]


new_list = copy . copy ( old_list )

old_list . append ([7 ,8])


old_list [1][1] = 9

print ( " New list : " , new_list )


print ( " Old list : " , old_list )

Python Programming Lecture 15 September 4, 2025 22 / 26


Aliasing and Cloning

Control Copying (Contd.)

old_list = [[1 ,2] ,[3 ,4] ,[5 ,6]]


new_list = copy . copy ( old_list )

old_list . append ([7 ,8])


old_list [1][1] = 9

print ( " New list : " , new_list )


print ( " Old list : " , old_list )

Python Programming Lecture 15 September 4, 2025 23 / 26


Aliasing and Cloning

Control Copying – Deep Copy

If we want all structures to be new copies, we need a deep copy.


Use deep copy when your list might have mutable elements.

import copy

old_list = [[1 ,2] ,[3 ,4] ,[5 ,6]]


new_list = copy . deepcopy ( old_list )

old_list . append ([7 ,8])


old_list [1][1] = 9

print ( " New list : " , new_list )


print ( " Old list : " , old_list )

Python Programming Lecture 15 September 4, 2025 24 / 26


Aliasing and Cloning

Control Copying – Deep Copy (Contd.)

old_list = [[1 ,2] ,[3 ,4] ,[5 ,6]]


new_list = copy . deepcopy ( old_list )

old_list . append ([7 ,8])


old_list [1][1] = 9

print ( " New list : " , new_list )


print ( " Old list : " , old_list )

Python Programming Lecture 15 September 4, 2025 25 / 26


Aliasing and Cloning

Cloning a List

Create a new list and copy every element using a clone.

old_list = [1 , 2 , 3 , 4]
new_list = old_list [:] # clone

print ( " Old : " , old_list ) # [1 , 2 , 3 , 4]


print ( " New : " , new_list ) # [1 , 2 , 3 , 4]
print ( old_list is new_list )

Python Programming Lecture 15 September 4, 2025 26 / 26


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 16)

Python Programming Lecture 16 September 8, 2025 1 / 21


List Comprehensions

List Comprehensions

Python Programming Lecture 16 September 8, 2025 2 / 21


List Comprehensions

List Comprehensions

An important task in Python is to apply a function to every element of a


sequence and create a new list with these values.
def f ( L ) :
Lnew = []
for element in L :
Lnew . append ( element **2)
return Lnew

L = [1 , 2 , 3 , 4 , 5]
print ( L )
print ( f ( L ) )

List comprehension is a concise way to execute this task. It creates a new list
and applies a function to every element of another iterable. It only applies to
elements that satisfy a test which is optional.

Python Programming Lecture 16 September 8, 2025 3 / 21


List Comprehensions

List Comprehensions (Contd.)

When a condition needs to be tested:


def f ( L ) :
Lnew = []
for x in L :
if x %2==0:
Lnew . append ( x **2)
return Lnew

L = [1 , 2 , 3 , 4 , 5 , 6]
print ( L )
print ( f ( L ) )

Python Programming Lecture 16 September 8, 2025 4 / 21


List Comprehensions

List Comprehensions (Contd.)

General form and examples:


def f ( expression , old_list , test = lambda x : True ) :
new_list = []
for x in old_list :
if test ( x ) :
new_list . append ( expression ( x ) )
return new_list

[ x **2 for x in range (6) ]


[ x **2 for x in range (8) if x %2==0]
[[ x , x **2] for x in range (4) if x %2!=0]

Python Programming Lecture 16 September 8, 2025 5 / 21


Functions: Default Parameters

Functions: Default Parameters

Python Programming Lecture 16 September 8, 2025 6 / 21


Functions: Default Parameters

Square Root with Bisection

def bisection_root ( x ) :
epsilon = 0.01
lower = 0
upper = x
guess = ( upper + lower ) /2.0
while abs ( guess **2 - x ) >= epsilon :
if guess **2 < x :
lower = guess
else :
upper = guess
guess = ( upper + lower ) /2.0
return guess

print ( bisection_root (179) )

Python Programming Lecture 16 September 8, 2025 7 / 21


Functions: Default Parameters

Another Parameter

How to obtain a more accurate answer? Some possible options are provided
below:
Change epsilon inside function (affects all calls).
Use epsilon outside function (global variables are bad).
Add epsilon as an argument to the function.

Python Programming Lecture 16 September 8, 2025 8 / 21


Functions: Default Parameters

Epsilon as a Parameter

def bisection_root (x , epsilon ) :


lower = 0
upper = x
guess = ( upper + lower ) /2.0
while abs ( guess **2 - x ) >= epsilon :
if guess **2 < x :
lower = guess
else :
upper = guess
guess = ( upper + lower ) /2.0
return guess

print ( bisection_root (179 , 0.01) )

Python Programming Lecture 16 September 8, 2025 9 / 21


Functions: Default Parameters

Keyword Parameters & Default Values

We have added epsilon as an argument to the function.


Most of the time we want some standard value, e.g. 0.01.
Sometimes, we may want to use another value.
Use a keyword or a default parameter.

Python Programming Lecture 16 September 8, 2025 10 / 21


Functions: Default Parameters

Epsilon as a Keyword Parameter

def bisection_root (x , epsilon =0.01) :


lower = 0
upper = x
guess = ( lower + upper ) /2.0
while abs ( guess **2 - x ) >= epsilon :
if guess **2 < x :
lower = upper
else :
upper = guess
guess = ( upper + lower ) /2.0
return guess

print ( bisection_root (179) )


print ( bisection_root (179 , 0.5) )

Python Programming Lecture 16 September 8, 2025 11 / 21


Functions: Default Parameters

Rules for Keyword Parameters

In the function definition:


Default parameters must go at the end
These are fine for calling a function:
bisection root new(179)
bisection root new(179, 0.001)
bisection root new(179, epsilon=0.001)
bisection root new(x=179, epsilon=0.1)
bisection root new(epsilon=0.1, x=179)
These are not fine for calling a function:
bisection root new(epsilon=0.001, 123)
bisection root new(0.001, 123)

Python Programming Lecture 16 September 8, 2025 12 / 21


Functions Returning Functions

Functions Returning Functions

Python Programming Lecture 16 September 8, 2025 13 / 21


Functions Returning Functions

Functions Returning Functions

A function can create and return another function instead of just returning
a value like a number or string.
This is possible because in Python, functions are first-class objects —
meaning they can be passed around, stored in variables, and returned just
like any other object.

Python Programming Lecture 16 September 8, 2025 14 / 21


Functions Returning Functions

Example

Define a Python function make prod(a) that returns another function


g(b). The inner function g(b) should take one argument b and return the
product of a and b. Demonstrate the use of this function by evaluating
make prod(2)(3).

Python Programming Lecture 16 September 8, 2025 15 / 21


Functions Returning Functions

Solution

def make_prod ( a ) :
def g ( b ) :
return a * b
return g

value = make_prod (2) (3)


print ( value )

Python Programming Lecture 16 September 8, 2025 16 / 21


Functions Returning Functions

Step-by-Step Execution

1 Call make prod(2).


Inside make prod, the parameter a becomes 2.
The inner function g(b) is defined; it returns a × b.
make prod returns the function object g. This returned function
remembers the value a = 2 — this is called a closure.
2 Immediately call the returned function with (3).
This executes g(3) with the remembered a = 2.
Inside g, compute a × b = 2 × 3 = 6.
The call returns 6.
3 Assign and print.
The result 6 is stored in val and printed, so the program outputs: 6.

Python Programming Lecture 16 September 8, 2025 17 / 21


Functions Returning Functions

Example

Write a function power function(n) that returns another function to


compute xn . Demonstrate it by creating a square function and a cube
function.

Python Programming Lecture 16 September 8, 2025 18 / 21


Functions Returning Functions

Solution

def power_function ( n ) :
def inner ( x ) :
return x ** n
return inner

square = power_function (2)


cube = power_function (3)

print ( square (5) ) # 25


print ( cube (2) ) # 8

Python Programming Lecture 16 September 8, 2025 19 / 21


Functions Returning Functions

Example

Write a function make adder(k) that returns another function which,


when given a number x, computes x + k. Demonstrate it by creating a
function that adds 10 to any number.

Python Programming Lecture 16 September 8, 2025 20 / 21


Functions Returning Functions

Solution

def make_adder ( k ) :
def adder ( x ) :
return x + k
return adder

add10 = make_adder (10)


print ( add10 (5) ) # 15
print ( add10 (20) ) # 30

Python Programming Lecture 16 September 8, 2025 21 / 21


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 17)

Python Programming Lecture 17 September 10, 2025 1 / 21


Introduction to Dictionaries

A dictionary in Python is a collection of key-value pairs.


Also known as an associative array or hash map.
Keys must be unique and immutable (e.g., string, number, tuple).
Values can be of any type and can be duplicated.

Python Programming Lecture 17 September 10, 2025 2 / 21


Creating Dictionaries

1 # Empty dictionary
2 d1 = {}
3
4 # Dictionary with values
5 d2 = { " name " : " A " , " age " : 25 , " city " : " Delhi " }
6
7 # Using dict () constructor
8 d3 = dict ( name = " B " , age =30 , city = " Mumbai " )
9
10 print ( d1 )
11 print ( d2 )
12 print ( d3 )

Python Programming Lecture 17 September 10, 2025 3 / 21


Accessing Dictionary Elements

1 person = { " name " : " A " , " age " : 25 , " city " : " Delhi " }
2
3 print ( person [ " name " ]) # A
4 print ( person [ " age " ]) # 25
5
6 # Using get () method
7 print ( person . get ( " city " ) ) # Delhi
8 print ( person . get ( " salary " , " Not Found " ) )
9 # Avoids error if key is missing

Python Programming Lecture 17 September 10, 2025 4 / 21


Adding and Updating Elements

1 person = { " name " : " A " , " age " : 25}
2
3 # Adding a new key - value pair
4 person [ " city " ] = " Delhi "
5
6 # Updating existing key
7 person [ " age " ] = 26
8
9 print ( person )
10 # { ‘ name ’: ‘A ’, ‘ age ’: 26 , ‘ city ’: ‘ Delhi ’}

Python Programming Lecture 17 September 10, 2025 5 / 21


Removing Elements

1 person = { " name " : " A " , " age " : 25 , " city " : " Delhi " }
2
3 # Using pop ()
4 person . pop ( " age " )
5
6 # Using del keyword
7 del person [ " city " ]
8
9 # Using popitem () - removes last inserted item
10 person . popitem ()
11
12 print ( person ) # {}

Python Programming Lecture 17 September 10, 2025 6 / 21


Dictionary Traversal

1 student = { " name " : " B " , " age " : 22 , " marks " : 85}
2
3 # Loop over keys
4 for key in student :
5 print ( key , student [ key ])
6
7 # Loop using items ()
8 for key , value in student . items () :
9 print ( key , " : " , value )

Python Programming Lecture 17 September 10, 2025 7 / 21


Dictionary Methods

1 info = { " name " : " A " , " age " : 25}
2
3 print ( info . keys () ) # dict_keys ([ ‘ name ’, ‘ age ’])
4 print ( info . values () ) # dict_values ([ ‘ A ’, 25])
5 print ( info . items () ) # dict_items ([( ‘ name ’,‘A ’) ,( ‘ age ’ ,25) ])
6
7 # Copying dictionary
8 d_copy = info . copy ()
9 print ( d_copy )

Python Programming Lecture 17 September 10, 2025 8 / 21


Nested Dictionaries

1 students = {
2 " s1 " : { " name " : " A " , " marks " : 90} ,
3 " s2 " : { " name " : " B " , " marks " : 85}
4 }
5
6 print ( students [ " s1 " ][ " name " ]) # A
7 print ( students [ " s2 " ][ " marks " ]) # 85

Python Programming Lecture 17 September 10, 2025 9 / 21


Dictionary Comprehension

1 # Square of numbers
2 squares = { x : x * x for x in range (6) }
3 print ( squares )
4
5 # Filtering with comprehension
6 even_squares = { x : x * x for x in range (10) if x %2==0}
7 print ( even_squares )

Python Programming Lecture 17 September 10, 2025 10 / 21


Checking Membership

1 person = { " name " : " A " , " age " : 25}
2
3 print ( " name " in person ) # True
4 print ( " city " in person ) # False
5 print ( " A " in person . values () ) # True

Python Programming Lecture 17 September 10, 2025 11 / 21


fromkeys() Method

1 keys = [ " a " , " b " , " c " ]


2
3 # Create dictionary with same default value
4 d = dict . fromkeys ( keys , 0)
5 print ( d )
6 # { ‘ a ’: 0 , ‘b ’: 0 , ‘c ’: 0}

Python Programming Lecture 17 September 10, 2025 12 / 21


setdefault() Method

1 person = { " name " : " A " }


2
3 # Returns value if key exists
4 print ( person . setdefault ( " name " , " Unknown " ) )
5
6 # Adds key with default if missing
7 print ( person . setdefault ( " age " , 25) )
8
9 print ( person )
10 # { ‘ name ’: ‘A ’, ‘ age ’: 25}

Python Programming Lecture 17 September 10, 2025 13 / 21


Dictionary as Frequency Counter

1 text = " banana "


2
3 freq = {}
4 for char in text :
5 freq [ char ] = freq . get ( char , 0) + 1
6
7 print ( freq )
8 # { ‘ b ’: 1 , ‘a ’: 3 , ‘n ’: 2}

Python Programming Lecture 17 September 10, 2025 14 / 21


Merging Dictionaries

1 d1 = { " a " : 1 , " b " : 2}


2 d2 = { " b " : 3 , " c " : 4}
3
4 # Method 1: update ()
5 d1 . update ( d2 )
6 print ( d1 )
7
8 # Method 2: Dictionary unpacking
9 d3 = {** d1 , ** d2 }
10 print ( d3 )

Python Programming Lecture 17 September 10, 2025 15 / 21


Sorting a Dictionary

1 scores = { " A " : 90 , " B " : 75 , " C " : 85}


2
3 # Sort by keys
4 print ( dict ( sorted ( scores . items () ) ) )
5
6 # Sort by values
7 print ( dict ( sorted ( scores . items () , key = lambda x : x [1]) ) )

Python Programming Lecture 17 September 10, 2025 16 / 21


Dictionary vs List

List: ordered collection of elements, accessed by index.


Dictionary: unordered collection of key-value pairs, accessed by key.
Lists are good for sequences, dictionaries for mappings.

Python Programming Lecture 17 September 10, 2025 17 / 21


Shallow vs Deep Copy

1 import copy
2
3 d1 = { " a " : [1 ,2] , " b " : [3 ,4]}
4
5 # Shallow copy
6 d2 = d1 . copy ()
7
8 # Deep copy
9 d3 = copy . deepcopy ( d1 )
10
11 d1 [ " a " ][0] = 100
12 print ( d1 ) # { ‘ a ’: [100 , 2] , ‘b ’: [3 , 4]}
13 print ( d2 ) # { ‘ a ’: [100 , 2] , ‘b ’: [3 , 4]} ( affected )
14 print ( d3 ) # { ‘ a ’: [1 , 2] , ‘b ’: [3 , 4]} ( safe )

Python Programming Lecture 17 September 10, 2025 18 / 21


Applications of Dictionaries

Storing structured data (e.g., student records).


Counting frequency of elements.
Implementing lookup tables.
Fast membership tests.
JSON objects (used in APIs) are essentially dictionaries.

Python Programming Lecture 17 September 10, 2025 19 / 21


Example: Word Count

1 sentence = " python is great and python is easy "


2
3 word_count = {}
4 for word in sentence . split () :
5 word_count [ word ] = word_count . get ( word , 0) + 1
6
7 print ( word_count )
8 # { ‘ python ’: 2 , ‘ is ’: 2 , ‘ great ’: 1 , ‘ and ’: 1 , ‘ easy ’: 1}

Python Programming Lecture 17 September 10, 2025 20 / 21


Summary

Dictionary = key-value store, fast lookups.


Keys: immutable and unique.
Values: any data type.
Supports creation, access, update, deletion.
Useful in data analysis, frequency counting, JSON handling.

Python Programming Lecture 17 September 10, 2025 21 / 21


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 18)

Python Programming Lecture 18 September 11, 2025 1 / 20


Recursion

Python Programming Lecture 18 September 11, 2025 2 / 20


What is Recursion?

Definition: Recursion is a method where a function calls itself


directly or indirectly.
Key Idea: Solve a large problem by breaking it into smaller
subproblems.
Two Parts:
1 Base Case: Condition under which the recursion stops.
2 Recursive Case: The function calls itself with a simpler/smaller input.

Python Programming Lecture 18 September 11, 2025 3 / 20


Structure of a Recursive Function

1 def recurs iv e_f un ct ion ( parameters ) :


2 if bas e _c a s e_ c o ndition :
3 return result # Base Case
4 else :
5 return r ec ur sive_function ( modified_parameters ) #
Recursive Case

Explanation:
def defines a function.
if checks for the base case.
return sends the result back.
Recursive call continues until base case is reached.

Python Programming Lecture 18 September 11, 2025 4 / 20


Example 1: Factorial Function

1 def factorial ( n ) :
2 if n == 0 or n == 1: # Base Case
3 return 1
4 else :
5 return n * factorial (n -1) # Recursive Case
6
7 print ( factorial (5) )

Explanation:
Factorial n! = n × (n − 1)!
Base case: 0! = 1, 1! = 1
Recursive step reduces the problem size.

Python Programming Lecture 18 September 11, 2025 5 / 20


Tracing Factorial Function

factorial(5) execution:
1 factorial(5) → 5× factorial(4)
2 factorial(4) → 4× factorial(3)
3 factorial(3) → 3× factorial(2)
4 factorial(2) → 2× factorial(1)
5 factorial(1) = 1 (base case)
Final Result: 5 × 4 × 3 × 2 × 1 = 120

Python Programming Lecture 18 September 11, 2025 6 / 20


Example 2: Fibonacci Sequence

1 def fibonacci ( n ) :
2 if n == 0: # Base Case
3 return 0
4 elif n == 1: # Base Case
5 return 1
6 else :
7 return fibonacci (n -1) + fibonacci (n -2)
8
9 print ( fibonacci (6) )

Explanation:
Fibonacci sequence: F (n) = F (n − 1) + F (n − 2)
Base cases: F (0) = 0, F (1) = 1
Recursive calls generate sequence step by step.

Python Programming Lecture 18 September 11, 2025 7 / 20


Tracing Fibonacci Function

For fibonacci(5):
F (5) = F (4) + F (3)
F (4) = F (3) + F (2), F (3) = F (2) + F (1)
F (2) = F (1) + F (0)
Tree of Calls:
Many repeated subproblems (inefficient).
Motivation for memoization.

Python Programming Lecture 18 September 11, 2025 8 / 20


Example 3: Sum of Natural Numbers

1 def sum_natural ( n ) :
2 if n == 0: # Base Case
3 return 0
4 else :
5 return n + sum_natural (n -1)
6
7 print ( sum_natural (10) )

Explanation:
Base case: sum of 0 = 0
Recursive step: sum of n = n+ sum of (n − 1)
Example: sum of 10 = 10 + 9 + 8 + · · · + 1

Python Programming Lecture 18 September 11, 2025 9 / 20


Visualization of Sum Function

S(4) = 4 + S(3)
S(3) = 3 + S(2)
S(2) = 2 + S(1)
S(1) = 1 + S(0), S(0) = 0
Final Answer: 10

Python Programming Lecture 18 September 11, 2025 10 / 20


Recursion vs Iteration

Python Programming Lecture 18 September 11, 2025 11 / 20


Recursion vs Iteration

Iteration: Repetition using loops (for, while).


Recursion: Repetition by self-calling functions.
Both achieve repetition but differ in approach.

Python Programming Lecture 18 September 11, 2025 12 / 20


Example: Sum of Numbers (Iteration)

1 def sum_iterative ( n ) :
2 total = 0
3 for i in range (1 , n +1) :
4 total += i
5 return total
6
7 print ( sum_iterative (10) )

Explanation:
Loop adds numbers one by one.
No function self-call.

Python Programming Lecture 18 September 11, 2025 13 / 20


Example: Sum of Numbers (Recursion)

1 def sum_recursive ( n ) :
2 if n == 0:
3 return 0
4 else :
5 return n + sum_recursive (n -1)
6
7 print ( sum_recursive (10) )

Comparison:
Iteration uses loop and variable.
Recursion uses stack memory implicitly.

Python Programming Lecture 18 September 11, 2025 14 / 20


Applications of Recursion

Python Programming Lecture 18 September 11, 2025 15 / 20


Example 4: Binary Search (Recursive)

1 def binary_search ( arr , low , high , x ) :


2 if high >= low :
3 mid = ( low + high ) // 2
4 if arr [ mid ] == x :
5 return mid
6 elif arr [ mid ] > x :
7 return binary_search ( arr , low , mid -1 , x )
8 else :
9 return binary_search ( arr , mid +1 , high , x )
10 else :
11 return -1
12
13 print ( binary_search ([1 ,2 ,3 ,4 ,5 ,6] , 0 , 5 , 4) )

Python Programming Lecture 18 September 11, 2025 16 / 20


Explanation: Binary Search

Works on sorted arrays.


Base case: when low > high, element not found.
Recursive step: compare middle element and search half.
Reduces search space by half each time.

Python Programming Lecture 18 September 11, 2025 17 / 20


Example 5: GCD using Euclid’s Algorithm

1 def gcd (a , b ) :
2 if b == 0: # Base Case
3 return a
4 else :
5 return gcd (b , a % b ) # Recursive Case
6
7 print ( gcd (48 , 18) )

Explanation:
GCD(a, b) = GCD(b, a mod b)
Stops when b = 0

Python Programming Lecture 18 September 11, 2025 18 / 20


Example 6: Reverse a String

1 def reverse_string ( s ) :
2 if len ( s ) == 0:
3 return s
4 else :
5 return reverse_string ( s [1:]) + s [0]
6
7 print ( reverse_string ( " hello " ) )

Explanation:
Base case: empty string returns itself.
Recursive case: reverse substring + first character.

Python Programming Lecture 18 September 11, 2025 19 / 20


Visualization of String Reversal

For "abc":
reverse(”abc”) = reverse(”bc”) + ”a”
reverse(”bc”) = reverse(”c”) + ”b”
reverse(”c”) = reverse(””) + ”c”
Final result: "cba"

Python Programming Lecture 18 September 11, 2025 20 / 20


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 19)

Python Programming Lecture 19 September 22, 2025 1 / 29


Recursion on Non-Numerics

Python Programming Lecture 19 September 22, 2025 2 / 29


Recursion on Non-Numerics

Recursion is a natural fit for strings and lists.


Simpler, clear code for many algorithms: traversal, search,
transformation.
Demonstrates base case plus recursive case pattern in non-numeric
contexts.

Python Programming Lecture 19 September 22, 2025 3 / 29


Recursion vs Iteration

Recursion: function calls itself with simpler/smaller data.


Iteration: loops and mutable state.
Tradeoffs: readability v/s performance.

Python Programming Lecture 19 September 22, 2025 4 / 29


Common Patterns

Process head and recurse on tail (lists/strings).


Rebuild a new object from the recursive results.
Always design a clear base case.

Python Programming Lecture 19 September 22, 2025 5 / 29


Recursion on Strings

Strings are sequences; treat the first character and rest.


Many problems: reverse, palindrome, count characters, replace.

Python Programming Lecture 19 September 22, 2025 6 / 29


Reverse a String (Recursive) Contd.

Write and execute a Python program to reverse a string using


recursion.

Python Programming Lecture 19 September 22, 2025 7 / 29


Reverse a String (Recursive)

1 def reverse ( s ) :
2 # base case : empty or single char
3 if len ( s ) <= 1:
4 return s
5 # recursive case : last char + reverse ( prefix )
6 return s [ -1] + reverse ( s [: -1])
7
8 print ( reverse ( " hello " ) ) # " olleh "

Python Programming Lecture 19 September 22, 2025 8 / 29


Palindrome Check (Recursive)

Write and execute a Python program to check whether a given string


is palindrome using recursion.

Python Programming Lecture 19 September 22, 2025 9 / 29


Palindrome Check (Recursive) Contd.

1 def is_palindrome ( s ) :
2 # normalize : remove spaces , lowercase
3 s = " " . join ( s . split () ) . lower ()
4 if len ( s ) <= 1:
5 return True
6 if s [0] != s [ -1]:
7 return False
8 return is_palindrome ( s [1: -1]) # This trims the first and
last characters and calls the function again .
9
10 print ( is_palindrome ( " R A D A R " ) )

Python Programming Lecture 19 September 22, 2025 10 / 29


Count Vowels in String

Write and execute a Python program to count vowels in a given string


using recursion.

Python Programming Lecture 19 September 22, 2025 11 / 29


Count Vowels in String Contd.

1 VOWELS = " aeiouAEIOU "


2
3 def count_vowels ( s ) :
4 if s == " " :
5 return 0
6 return (1 if s [0] in VOWELS else 0) + count_vowels ( s
[1:]) # recursive call on the rest of the string
7
8 print ( count_vowels ( " recursion " ) ) # 4

Python Programming Lecture 19 September 22, 2025 12 / 29


Replace all Occurrences of a Character

Write and execute a Python program to replace all occurrences of a


character using recursion.

Python Programming Lecture 19 September 22, 2025 13 / 29


Replace all Occurrences of a Character Contd.

1 def replace_char (s , old , new ) :


2 if s == " " :
3 return " "
4 head = new if s [0] == old else s [0]
5 return head + replace_char ( s [1:] , old , new )
6
7 print ( replace_char ( " banana " , " a " , " o " ) ) # " bonono "

Python Programming Lecture 19 September 22, 2025 14 / 29


Recursion on Lists

Lists are sequences: handle head (first element) and tail (rest list).
Useful for nested lists (flatten), search, count, map-like transforms.

Python Programming Lecture 19 September 22, 2025 15 / 29


Example: Flatten a Nested List

Write and execute a Python program to flatten a nested list using


recursion.

Python Programming Lecture 19 September 22, 2025 16 / 29


Example: Flatten a Nested List Contd.

1 # flatten nested lists of arbitrary depth


2
3 def flatten ( lst ) :
4 if not lst :
5 return []
6
7 head = lst [0] # first element
8 tail = lst [1:] # rest of the list
9
10 if type ( head ) . __name__ == " list " :
11 return flatten ( head ) + flatten ( tail )
12 else :
13 return [ head ] + flatten ( tail )
14
15 print ( flatten ([1 ,[2 ,3] ,[4 ,[5 ,6]] ,7]) )
16 # Output : [1 , 2 , 3 , 4 , 5 , 6 , 7]

Python Programming Lecture 19 September 22, 2025 17 / 29


Find Maximum Element Recursively

Write and execute a Python program to find the maximum element in


a list using recursion.

Python Programming Lecture 19 September 22, 2025 18 / 29


Find Maximum Element Recursively Contd.

1 def recursive_max ( lst ) :


2 if len ( lst ) == 1:
3 return lst [0]
4 head , * tail = lst
5 m_tail = recursive_max ( tail )
6 return head if head > m_tail else m_tail
7
8 print ( recursive_max ([3 ,1 ,9 ,2]) ) # 9

Python Programming Lecture 19 September 22, 2025 19 / 29


Count Occurrences of an Element

Write and execute a Python program to count the number of


occurrences of an element in a list using recursion.

Python Programming Lecture 19 September 22, 2025 20 / 29


Count Occurrences of an Element Contd.

1 def count_occ ( lst , x ) :


2 if not lst :
3 return 0
4 head , * tail = lst
5 return (1 if head == x else 0) + count_occ ( tail , x )
6
7 print ( count_occ ([ " a " ," b " ," a " ," c " ," a " ] , " a " ) ) # 3

Python Programming Lecture 19 September 22, 2025 21 / 29


Merge Two Sorted Lists (Recursive)

Write and execute a Python program to merge two sorted lists using
recursion.

Python Programming Lecture 19 September 22, 2025 22 / 29


Merge Two Sorted Lists (Recursive) Contd.

1 def merge_sorted (a , b ) :
2 if not a :
3 return b
4 if not b :
5 return a
6 if a [0] <= b [0]:
7 return [ a [0]] + merge_sorted ( a [1:] , b )
8 else :
9 return [ b [0]] + merge_sorted (a , b [1:])
10
11 print ( merge_sorted ([1 ,3 ,5] , [2 ,4 ,6]) )
12 # [1 ,2 ,3 ,4 ,5 ,6]

Python Programming Lecture 19 September 22, 2025 23 / 29


Tuples: Structural Recursion

Write and execute a Python program to convert nested tuples to a


flat list using recursion.

Python Programming Lecture 19 September 22, 2025 24 / 29


Tuples: Structural Recursion Contd.

1 # Convert nested tuples to flat list


2 def flatten_tuple ( t ) :
3 if len ( t ) == 0:
4 return []
5
6 head = t [0] # first element
7 tail = t [1:] # rest of the tuple
8
9 if type ( head ) . __name__ == " tuple " :
10 head_list = flatten_tuple ( head )
11 else :
12 head_list = [ head ]
13
14 return head_list + flatten_tuple ( tail )
15
16 print ( flatten_tuple ((1 ,(2 ,3) ,(4 ,(5 ,) ) ) ) )
17 # Output : [1 , 2 , 3 , 4 , 5]

Python Programming Lecture 19 September 22, 2025 25 / 29


Dictionaries: Nested Search

Write and execute a Python program to search for a key in a nested


dictionary using recursion.

Python Programming Lecture 19 September 22, 2025 26 / 29


Dictionaries: Nested Search Contd.

1 # search for key in nested dict


2
3 def nested_get (d , key ) :
4 for k in d :
5 if k == key :
6 return d [ k ]
7
8 for k in d :
9 v = d[k]
10 if type ( v ) == dict :
11 found = nested_get (v , key )
12 if found is not None :
13 return found
14
15 return None
16
17 config = { " a " :1 , " b " : { " c " : 2 , " d " : { " e " : 3}}}
18 print ( nested_get ( config , " e " ) ) # 3

Python Programming Lecture 19 September 22, 2025 27 / 29


Count Keys Recursively

Write and execute a Python program to count keys in a dictionary


using recursion.

Python Programming Lecture 19 September 22, 2025 28 / 29


Count Keys Recursively Contd.

1 def count_keys ( d ) :
2 total = 0
3 # Iterate over dictionary manually
4 for k in d :
5 total += 1
6 v = d[k]
7 # Check manually if value is a dictionary
8 if type ( v ) == dict :
9 total += count_keys ( v )
10 return total
11
12 print ( count_keys ({ " a " :1 , " b " : { " c " :2 , " d " :{}}}) ) # 4

Python Programming Lecture 19 September 22, 2025 29 / 29


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 20)

Python Programming Lecture 20 October 6, 2025 1 / 23


Python for Scientific Computing,
Data Analysis & Visualization

Python Programming Lecture 20 October 6, 2025 2 / 23


Overview

Python is an extremely popular programming tool for performing


scientific computing and data-oriented tasks.
The nature of Python is accessible and expressive.
Python includes various high-quality scientific libraries.
Python plays a vital role in exploring the modern techniques of data
science, machine learning, and artificial intelligence.

Python Programming Lecture 20 October 6, 2025 3 / 23


Scientific Libraries

A natural question is: Why do we use scientific libraries?


They provide routines (integration, root finding, linear algebra, etc.).
Pure Python is elegant, but often too slow.
Libraries accelerate execution via compilers translating Python-like
code to fast machine code.

Python Programming Lecture 20 October 6, 2025 4 / 23


Scientific Libraries (Contd.)

Some important libraries are listed below:


NumPy: Core library for numerical computation; provides
n-dimensional arrays, vectorized operations, linear algebra, etc.
SciPy: Builds on NumPy; adds scientific routines for optimization,
integration, interpolation, differential equations, statistics, and more.
Numba: A just-in-time compiler that speeds up Python functions,
especially those involving NumPy arrays.

Python Programming Lecture 20 October 6, 2025 5 / 23


Scientific Libraries (Contd.)

Pandas: Data structures like DataFrame and Series for easy data
manipulation and analysis.
Matplotlib: Foundational plotting library; works with NumPy arrays
for 2D and 3D plots.
scikit-learn: Classical machine learning algorithms, such as regression,
classification, clustering, priciple component analysis, etc.
TensorFlow: Deep learning framework.
Statsmodels: Statistical modeling: regression, time series, hypothesis
testing, etc.

Python Programming Lecture 20 October 6, 2025 6 / 23


NumPy

Python Programming Lecture 20 October 6, 2025 7 / 23


What is NumPy?

NumPy stands for numerical Python.


It provides support for
Multi-dimensional arrays (ndarrays),
Fast mathematical operations,
Linear algebra, random number generation, etc.
Foundation library for data science and scientific computing in
Python.

Python Programming Lecture 20 October 6, 2025 8 / 23


Why NumPy?

Lists in Python are slow for numerical operations.


NumPy arrays are
Memory efficient,
Much faster,
Vectorized (no loops required).

Python Programming Lecture 20 October 6, 2025 9 / 23


Importing NumPy

1 import numpy as np
2 # ’ np ’ is the standard alias used across all tasks .

Python Programming Lecture 20 October 6, 2025 10 / 23


NumPy Arrays

The essential problem that NumPy solves is fast array processing.


The most important structure that NumPy defines is an array data
type, formally called a [Link].
NumPy arrays power a very large proportion of the scientific Python
ecosystem.
To create a NumPy array containing only zeros we use [Link].

Python Programming Lecture 20 October 6, 2025 11 / 23


NumPy Arrays (Contd.)

1 a = np . zeros (3)
2 a # array ([0. , 0. , 0.])
3 type ( a ) # numpy . ndarray

Python Programming Lecture 20 October 6, 2025 12 / 23


NumPy Arrays (Contd.)

NumPy arrays are somewhat like native Python lists, except that
Data must be homogeneous (all elements of the same type).
These types must be one of the data types (dtypes) provided by
NumPy.
The most important of these dtypes are:
float64: 64 bit floating-point number
int64: 64 bit integer
bool: 8 bit True or False
There are also dtypes to represent complex numbers, unsigned
integers, etc.
On modern machines, the default dtype for arrays is float64.

Python Programming Lecture 20 October 6, 2025 13 / 23


NumPy Arrays (Contd.)

1 a = np . zeros (3)
2 type ( a [0]) # numpy . float64

If we want to use integers we can specify as follows:


1 a = np . zeros (3 , dtype = int )
2 type ( a [0]) # numpy . int64

Python Programming Lecture 20 October 6, 2025 14 / 23


Shape and Dimension

Consider the following assignment


1 z = np . zeros (10)

Here z is a flat array with no dimension — neither row nor column vector.
The dimension is recorded in the shape attribute, which is a tuple.
1 z . shape # (10 ,)

Here the shape tuple has only one element, which is the length of the
array (tuples with one element end with a comma).

Python Programming Lecture 20 October 6, 2025 15 / 23


Shape and Dimension (Contd.)

To give dimension to the shape tuple, we can change the shape attribute
1 z . shape = (10 ,1)
2 z
3 # array ([[0.] ,
4 [0.] ,
5 [0.] ,
6 [0.] ,
7 [0.] ,
8 [0.] ,
9 [0.] ,
10 [0.] ,
11 [0.] ,
12 [0.]])

Python Programming Lecture 20 October 6, 2025 16 / 23


Shape and Dimension (Contd.)

1 z = np . zeros (4)
2 z . shape = (2 , 2)
3 z
4 # array ([[0. , 0.] ,
5 [0. , 0.]])

In the last case, to make the 2 by 2 array, we could also pass a tuple to the
zeros() function, as in z = [Link]((2, 2)).

Python Programming Lecture 20 October 6, 2025 17 / 23


Creating Arrays

The [Link] function creates an array of zeros.


Guess what [Link] creates.
[Link] creates arrays in memory that can later be populated with
data.
1 z = np . empty (3)
2 z # array ([0. , 0. , 0.])

(Python allocates 3 contiguous 64 bit pieces of memory, and the existing


contents of those memory slots are interpreted as float64 values)

Python Programming Lecture 20 October 6, 2025 18 / 23


Creating Arrays (Contd.)

To set up a grid of evenly spaced numbers use [Link]


1 z = np . linspace (2 , 4 , 5) # From 2 to 4 , with 5 elements

To create an identity matrix use either [Link] or [Link].


1 z = np . identity (2)
2 z
3 # array ([[1. , 0.] ,
4 [0. , 1.]])

Python Programming Lecture 20 October 6, 2025 19 / 23


Creating Arrays (Contd.)

NumPy arrays can be created from Python lists, tuples, etc. using
[Link]().
1 z = np . array ([10 , 20]) # ndarray from Python list
2 z # array ([10 , 20])
3 type ( z ) # numpy . ndarray

Python Programming Lecture 20 October 6, 2025 20 / 23


Creating Arrays (Contd.)

The dtype argument can be specified to control the type of data.


1 z = np . array ((10 , 20) , dtype = float )
2 # Here ’ float ’ is equivalent to ’ np . float64 ’
3 z
4 # array ([10. , 20.])

Python Programming Lecture 20 October 6, 2025 21 / 23


Creating Arrays (Contd.)

Multi-dimensional arrays can be created from nested lists.


1 z = np . array ([[1 , 2] , [3 , 4]]) # 2 D array from list of
lists
2 z
3 # array ([[1 , 2] ,
4 [3 , 4]])

Python Programming Lecture 20 October 6, 2025 22 / 23


Creating Arrays (Contd.)

[Link]() performs a similar function to [Link](), but does


not make a distinct copy if the input is already a NumPy array.
1 na = np . linspace (10 , 20 , 2)
2
3 na is np . asarray ( na ) # Does not copy NumPy arrays
4 # True
5
6 na is np . array ( na ) # Does make a new copy --- perhaps
unnecessarily
7 # False

Reading Data from Files


To read numeric array data from a text file, use: [Link]() or
[Link]().

Python Programming Lecture 20 October 6, 2025 23 / 23


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 21)

Python Programming Lecture 21 October 8, 2025 1 / 19


Array Indexing

For a flat array, indexing works just like Python sequences.


1 z = np . linspace (1 , 2 , 5)
2 z
3 # array ([1. , 1.25 , 1.5 , 1.75 , 2. ])
4
5 z [0]
6 # np . float64 (1.0)
7
8 z [0:2] # Two elements , starting at element 0
9 # array ([1. , 1.25])
10
11 z [ -1]
12 # np . float64 (2.0)

Python Programming Lecture 21 October 8, 2025 2 / 19


Array Indexing (Contd.)

For 2D arrays, the index syntax uses row and column indices.
1 z = np . array ([[1 , 2] , [3 , 4]])
2 z
3 # array ([[1 , 2] ,
4 [3 , 4]])
5
6 z [0 , 0]
7 # np . int64 (1)
8
9 z [0 , 1]
10 # np . int64 (2)

Note
Indices are still zero-based, to maintain compatibility with Python
sequences.

Python Programming Lecture 21 October 8, 2025 3 / 19


Array Indexing (Contd.)

Rows and columns can be extracted using a slicing syntax.


1 z [0 , :] # First row
2 # array ([1 , 2])
3
4 z [: , 1] # Second column
5 # array ([2 , 4])

Python Programming Lecture 21 October 8, 2025 4 / 19


Array Indexing (Contd.)

NumPy arrays of integers can be used to extract elements.


1 z = np . linspace (2 , 4 , 5)
2 z
3 # array ([2. , 2.5 , 3. , 3.5 , 4. ])
4
5 indices = np . array ((0 , 2 , 3) )
6 z [ indices ]
7 # array ([2. , 3. , 3.5])

Python Programming Lecture 21 October 8, 2025 5 / 19


Array Indexing (Contd.)

Boolean arrays (dtype=bool) can be used for conditional selection.


1 z
2 # array ([2. , 2.5 , 3. , 3.5 , 4. ])
3
4 d = np . array ([0 , 1 , 1 , 0 , 0] , dtype = bool )
5 d
6 # array ([ False , True , True , False , False ])
7
8 z[d]
9 # array ([2.5 , 3. ])

Python Programming Lecture 21 October 8, 2025 6 / 19


Array Indexing (Contd.)

All elements of an array can be set equal to one number using slice
notation.
1 z = np . empty (3)
2 z
3 # array ([2. , 3. , 3.5])
4
5 z [:] = 42
6 z
7 # array ([42. , 42. , 42.])

Python Programming Lecture 21 October 8, 2025 7 / 19


Array Methods

NumPy arrays have many useful methods, all carefully optimized for
performance.
1 a = np . array ((4 , 3 , 2 , 1) )
2 a
3 # array ([4 , 3 , 2 , 1])
4
5 a . sort () # Sorts a in place
6 a
7 # array ([1 , 2 , 3 , 4])

Note
Unlike sorted(), [Link]() modifies the array in place.

Python Programming Lecture 21 October 8, 2025 8 / 19


Array Methods (Contd.)

Basic descriptive statistics and aggregation functions:


1 a . sum () # Sum
2 # np . int64 (10)
3
4 a . mean () # Mean
5 # np . float64 (2.5)
6
7 a . max () # Max
8 # np . int64 (4)
9
10 a . argmax () # Index of the maximal element
11 # np . int64 (3)

Python Programming Lecture 21 October 8, 2025 9 / 19


Array Methods (Contd.)

Cumulative operations and statistical measures:


1 a . cumsum () # Cumulative sum
2 # array ([ 1 , 3 , 6 , 10])
3
4 a . cumprod () # Cumulative product
5 # array ([ 1 , 2 , 6 , 24])
6
7 a . var () # Variance
8 # np . float64 (1.25)
9
10 a . std () # Standard deviation
11 # np . float64 ( 1 .1 1 8 03 3988749895)

Python Programming Lecture 21 October 8, 2025 10 / 19


Array Methods (Contd.)

Arrays can be reshaped and transposed easily.


1 a . shape = (2 , 2)
2 a
3 # array ([[1 , 2] ,
4 [3 , 4]])
5
6 a.T # Equivalent to a . transpose ()
7 # array ([[1 , 3] ,
8 [2 , 4]])

Python Programming Lecture 21 October 8, 2025 11 / 19


Array Methods (Contd.)

Another useful method is searchsorted(), which helps with ordered


data.
1 z = np . linspace (2 , 4 , 5)
2 z
3 # array ([2. , 2.5 , 3. , 3.5 , 4. ])
4 z . searchsorted (2.2)
5 # np . int64 (1) [ This returns the index position where the
given value ( or values ) should be inserted to maintain
sorted order . For a value larger than all elements , it
returns len ( z ) ]

Equivalent NumPy Functions


1 a = np . array ((4 , 3 , 2 , 1) )
2 np . sum ( a ) # Equivalent to a . sum ()
3 np . mean ( a ) # Equivalent to a . mean ()

Python Programming Lecture 21 October 8, 2025 12 / 19


Arithmetic Operations

The operators +, -, *, /, and ** act element-wise on arrays.


1 a = np . array ([1 , 2 , 3 , 4])
2 b = np . array ([5 , 6 , 7 , 8])
3
4 a + b
5 array ([6 , 8 , 10 , 12])
6
7 a * b
8 array ([ 5 , 12 , 21 , 32])

Python Programming Lecture 21 October 8, 2025 13 / 19


Arithmetic Operations (Contd.)

Scalars can be added to each array element directly.


1 a + 10
2 array ([11 , 12 , 13 , 14])

Scalar multiplication works the same way.


1 a * 10
2 array ([10 , 20 , 30 , 40])

Python Programming Lecture 21 October 8, 2025 14 / 19


Arithmetic Operations (Contd.)

Two-dimensional arrays follow the same general element-wise rules.


1 A = np . ones ((2 , 2) )
2 B = np . ones ((2 , 2) )
3
4 A + B
5 array ([[2. , 2.] ,
6 [2. , 2.]])
7
8 A + 10
9 array ([[11. , 11.] ,
10 [11. , 11.]])

Python Programming Lecture 21 October 8, 2025 15 / 19


Arithmetic Operations (Contd.)

Element-wise multiplication is performed with *.


1 A * B
2 array ([[1. , 1.] ,
3 [1. , 1.]])

Important Note
A * B is not the matrix product — it is an element-wise product. To
perform matrix multiplication, use A @ B or [Link](A, B).

Python Programming Lecture 21 October 8, 2025 16 / 19


Matrix Multiplication

From Python 3.5 onwards (including Anaconda distributions), the @


operator is used for matrix multiplication.
1 A = np . ones ((2 , 2) )
2 B = np . ones ((2 , 2) )
3
4 A @ B
5 array ([[2. , 2.] ,
6 [2. , 2.]])

Note
For older versions of Python or NumPy, use [Link](A, B) instead of A @
B.

Python Programming Lecture 21 October 8, 2025 17 / 19


Matrix Multiplication (Contd.)

The @ operator can also be used for the inner product of two flat
arrays.
1 A = np . array ((1 , 2) )
2 B = np . array ((10 , 20) )
3
4 A @ B
5 np . int64 (50)

Interpretation
The result corresponds to the dot (inner) product of the two 1D arrays.

Python Programming Lecture 21 October 8, 2025 18 / 19


Matrix Multiplication (Contd.)

The @ operator can also work when one operand is a Python list or
tuple.
1 A = np . array (((1 , 2) , (3 , 4) ) )
2 A
3 array ([[1 , 2] ,
4 [3 , 4]])
5
6 A @ (0 , 1)
7 array ([2 , 4])

Observation
Since we are post-multiplying, the tuple is treated as a column vector.

Python Programming Lecture 21 October 8, 2025 19 / 19


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 22)

Python Programming Lecture 22 October 9, 2025 1 / 25


Broadcasting

What is Broadcasting?
Broadcasting is a feature in NumPy that allows arrays of different shapes
to participate in element-wise operations by “stretching” the smaller
array(s) to a compatible shape when possible.

Avoids explicit for loops → faster numerical code.


Helps perform operations without fully allocating expanded
dimensions in memory.

Python Programming Lecture 22 October 9, 2025 2 / 25


Basic Broadcasting Example

1 a = np . array ([[1 , 2 , 3] ,
2 [4 , 5 , 6] ,
3 [7 , 8 , 9]])
4 b = np . array ([3 , 6 , 9])
5
6 a + b

Output:
1 array ([[ 4 , 8 , 12] ,
2 [ 7 , 11 , 15] ,
3 [10 , 14 , 18]])

Here, b (shape (3, )) is automatically “broadcast” to shape (3, 3) before


addition.

Python Programming Lecture 22 October 9, 2025 3 / 25


Broadcasting with Column Vector

1 b = np . array ([3 , 6 , 9])


2 b . shape = (3 , 1)
3
4 a + b

Output:
1 array ([[ 4 , 5 , 6] ,
2 [10 , 11 , 12] ,
3 [16 , 17 , 18]])

Here b is of shape (3, 1), and is broadcast to (3, 3) to match a. Equivalent


to adding the column vector to each row of a.

Python Programming Lecture 22 October 9, 2025 4 / 25


Both Operands Expand

1 a = np . array ([3 , 6 , 9]) # shape (3 ,)


2 b = np . array ([2 , 3 , 4])
3 b . shape = (3 , 1)
4
5 a + b

Output:
1 array ([[ 5 , 8 , 11] ,
2 [ 6 , 9 , 12] ,
3 [ 7 , 10 , 13]])

Here both a and b expand: a → (3, 3), b → (3, 3) before the element-wise
addition.

Python Programming Lecture 22 October 9, 2025 5 / 25


When Broadcasting Fails

1 a = np . array ([[1 , 2] ,
2 [4 , 5] ,
3 [7 , 8]])
4 b = np . array ([3 , 6 , 9])
5
6 a + b # Error

Error:
1 # ValueError : operands could not be broadcast together with
shapes (3 ,2) (3 ,)

Why? Because you cannot align (3, 2) with (3, ) in a consistent way under
broadcasting rules.

Python Programming Lecture 22 October 9, 2025 6 / 25


Broadcasting Rules (Steps)

Here are the rules NumPy uses to decide how to broadcast:


1 **Add dimensions on the left** for the array with fewer dimensions.
E.g. (3, ) becomes (1, 3), (2) becomes (1, 2), etc.
2 **Match dimensions one by one** (now same number of dims): Two
dimensions are compatible if they are equal or one of them is 1.
3 If after those steps the shapes are not compatible, **raise a
ValueError**.
Examples:
(3, 3) + (3, ) → (3, 3)
(3, 3) + (3, 1) → (3, 3)
(2, 2, 3) + (2, 2) (→ becomes (1, 2, 2)) → incompatible ⇒ ValueError

Python Programming Lecture 22 October 9, 2025 7 / 25


Higher-Dimensional Broadcasting Example

1 a = np . array (
2 [[[1 , 2] ,
3 [2 , 3]] ,
4 [[2 , 3] ,
5 [3 , 4]]]) # shape (2 ,2 ,2)
6
7 b = np . array ([[1 , 7] ,
8 [7 , 1]]) # shape (2 ,2)
9
10 a + b

Output:
1 array ([[[ 2 , 9] ,
2 [ 9 , 4]] ,
3 [[ 3 , 10] ,
4 [10 , 5]]])

Here b (shape (2, 2)) is promoted to (1, 2, 2), then broadcast to (2, 2, 2) to
align with a.
Python Programming Lecture 22 October 9, 2025 8 / 25
Another Higher-D Example

1 a = np . array (
2 [[[1 , 2] ,
3 [3 , 4]] ,
4 [[4 , 5] ,
5 [6 , 7]] ,
6 [[7 , 8] ,
7 [9 ,10]]]) # shape (3 ,2 ,2)
8
9 b = np . array ([3 , 6]) # shape (2 ,)
10
11 a + b

Python Programming Lecture 22 October 9, 2025 9 / 25


Another Higher-D Example (Contd.)

Output:
1 array ([[[ 4 , 8] ,
2 [ 6, 10]] ,
3 [[ 7 , 11] ,
4 [ 9, 13]] ,
5 [[10 , 14] ,
6 [12 , 16]]])

Broadcasting process:

(3, 2, 2) + (2, ) → (1, 2, 2) + (3, 2, 2) → (3, 2, 2) + (3, 2, 2)

Python Programming Lecture 22 October 9, 2025 10 / 25


Key Takeaways on Broadcasting

Broadcasting is a core feature that gives NumPy flexibility with


different shaped arrays.
Follow the three-step rules (left-pad dims, match or expand dims, else
error).
Many real-world uses in data manipulation, linear algebra, statistics
rely on broadcasting.
Always check compatibility before trusting automatic broadcasting.

Python Programming Lecture 22 October 9, 2025 11 / 25


Mutability and Copying Arrays

Key Concept: NumPy arrays are mutable data types, like Python lists. In
other words, their contents can be altered (mutated) in memory after
initialization.
Example:
1 a = np . array ([42 , 44])
2 a
3 # array ([42 , 44])
4
5 a [ -1] = 0 # Change last element to 0
6 a
7 # array ([42 , 0])

Python Programming Lecture 22 October 9, 2025 12 / 25


Mutability and Copying Arrays (contd.)

Mutability leads to the following behavior:


1 a = np . random . randn (3)
2 a
3 # array ([ -0.91128778 , -1.26108567 , 0.9262362 ])
4
5 b = a
6 b [0] = 0.0
7 a
8 # array ([ 0. , -1.26108567 , 0.9262362 ])

Python Programming Lecture 22 October 9, 2025 13 / 25


Explanation

What happened is that we have changed a by changing b.


The name b is bound to a and becomes just another reference to the
array.
Hence, it has equal rights to make changes to that array.

This behavior follows Python’s assignment model — variables are just


references to objects in memory.

Python Programming Lecture 22 October 9, 2025 14 / 25


Why is this Useful?

Passing arrays by reference avoids unnecessary copying.


Copying large arrays is expensive in both:
Speed – since memory operations take time.
Memory – since duplicates consume extra space.

This makes NumPy efficient for numerical computation.

Python Programming Lecture 22 October 9, 2025 15 / 25


Making Copies

It is possible to make b an independent copy of a when required.


This can be done using the [Link]() function.
1 a = np . random . randn (3)
2 a
3 # array ([ 1.72747602 e +00 , -6.26961796 e -05 , -5.81158845 e -01])
4
5 b = np . copy ( a )
6 b
7 # array ([ 1.72747602 e +00 , -6.26961796 e -05 , -5.81158845 e -01])

Python Programming Lecture 22 October 9, 2025 16 / 25


Independent (Deep) Copy

Now b is an independent copy (called a deep copy ) of a.


1 b [:] = 1
2 b
3 # array ([1. , 1. , 1.])
4
5 a
6 # array ([ 1.72747602 e +00 , -6.26961796 e -05 , -5.81158845 e -01])

Observation: The change to b has not affected a.

Python Programming Lecture 22 October 9, 2025 17 / 25


Summary

[Link]() creates a new independent copy of the array in memory.


Changes to the new array do not impact the original one.
This is useful when you need to preserve the original data.

Key takeaway: Use [Link]() to explicitly avoid shared references when


mutability is not desired.

Python Programming Lecture 22 October 9, 2025 18 / 25


Vectorized Functions

NumPy provides versions of standard mathematical functions (log, exp,


sin, etc.) that act element-wise on arrays.
1 z = np . array ([1 , 2 , 3])
2 np . sin ( z )
3 # array ([0.84147098 , 0.90929743 , 0.14112001])

This eliminates the need for explicit element-by-element loops.

Python Programming Lecture 22 October 9, 2025 19 / 25


Without Vectorization

1 n = len ( z )
2 y = np . empty ( n )
3 for i in range ( n ) :
4 y [ i ] = np . sin ( z [ i ])

Observation:
Such loops are slow.
NumPy’s vectorized functions are much faster and cleaner.

Python Programming Lecture 22 October 9, 2025 20 / 25


UFuncs (Universal Functions)

Because they act element-wise on arrays, these are called vectorized


functions or ufuncs (universal functions).
1 z = np . array ([1 , 2 , 3])
2 (1 / np . sqrt (2 * np . pi ) ) * np . exp ( -0.5 * z **2)
3 # array ([0.24197072 , 0.05399097 , 0.00443185])

Note: Arithmetic operations like +, *, etc. also work element-wise,


combining naturally with ufuncs.

Python Programming Lecture 22 October 9, 2025 21 / 25


Non-Vectorized User-Defined Functions

Not all user-defined functions are automatically vectorized.


1 def f ( x ) :
2 return 1 if x > 0 else 0
3
4 x = np . random . randn (4)
5 f(x)
6 # ValueError : The true value of an array is ambiguous

NumPy provides [Link] as a vectorized alternative.

Python Programming Lecture 22 October 9, 2025 22 / 25


Using [Link]

1 x = np . random . randn (4)


2 x
3 # array ([ 1.4470857 , -0.16689569 , -0.78666749 ,
-1.23508006])
4
5 np . where ( x > 0 , 1 , 0)
6 # array ([1 , 0 , 0 , 0])

Interpretation: [Link](condition, value if true,


value if false) acts element-wise and provides a fast, clean vectorized
alternative.

Python Programming Lecture 22 October 9, 2025 23 / 25


Vectorizing a Function

You can also use [Link] to convert a scalar function into a


vectorized one.
1 f = np . vectorize ( f )
2 f(x)
3 # array ([1 , 0 , 0 , 0])

Note: While [Link] allows array inputs, it does not guarantee the
same speed as built-in vectorized functions.

Python Programming Lecture 22 October 9, 2025 24 / 25


Summary

Vectorized functions operate element-wise on arrays.


They eliminate explicit Python loops, increasing speed and readability.
Built-in NumPy ufuncs are optimized and should be preferred.
[Link] and [Link] extend vectorization to custom
operations.

Python Programming Lecture 22 October 9, 2025 25 / 25


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 23)

Python Programming Lecture 23 October 13, 2025 1 / 22


Comparisons

As a rule, comparisons on arrays are done element-wise.


1 z = np . array ([2 , 3])
2 y = np . array ([2 , 3])
3 z == y
4 # array ([ True , True ])
5
6 y [0] = 5
7 z == y
8 # array ([ False , True ])
9
10 z != y
11 # array ([ True , False ])

The same applies for comparison operators >, <, >=, and <=.

Python Programming Lecture 23 October 13, 2025 2 / 22


Comparisons Against Scalars

Array elements can also be compared directly with scalars.


1 z = np . linspace (0 , 10 , 5)
2 z
3 # array ([ 0. , 2.5 , 5. , 7.5 , 10. ])
4
5 z > 3
6 # array ([ False , False , True , True , True ])

This feature is often used for building boolean masks and extracting
specific elements.

Python Programming Lecture 23 October 13, 2025 3 / 22


Conditional Extraction

We can extract elements of an array conditionally using boolean masks.


1 b = z > 3
2 b
3 # array ([ False , False , True , True , True ])
4
5 z[b]
6 # array ([ 5. , 7.5 , 10. ])

Interpretation: Only the elements of z for which the condition z > 3


holds are selected.

Python Programming Lecture 23 October 13, 2025 4 / 22


Compact Conditional Selection

The same operation can be done more compactly in a single step.


1 z [ z > 3]
2 # array ([ 5. , 7.5 , 10. ])

Key Point:
Boolean array indexing is a powerful tool in NumPy.
It allows fast, expressive conditional data extraction without explicit
loops.

Python Programming Lecture 23 October 13, 2025 5 / 22


Summary

Comparisons between arrays are performed element-wise.


The result of a comparison is a Boolean array.
Boolean arrays can be used to filter or extract array elements.
This approach eliminates explicit looping for conditional data
selection.

Python Programming Lecture 23 October 13, 2025 6 / 22


Sub-packages in NumPy

NumPy provides additional functionality for scientific programming


through its sub-packages.
Examples include:
[Link] for random number generation
[Link] for linear algebra operations

These sub-packages greatly extend NumPy’s core numerical capabilities.

Python Programming Lecture 23 October 13, 2025 7 / 22


Using [Link]

We’ve already seen that we can generate random variables using


[Link].
1 z = np . random . randn (10000) # Generate 10 ,000 standard
normals
2 y = np . random . binomial (10 , 0.5 , size =1000) # 1 ,000 draws
from Bin (10 , 0.5)
3
4 y . mean ()
5 # np . float64 (4.963)

Key Point:
[Link] provides functions to draw from many discrete and
continuous distributions.

Python Programming Lecture 23 October 13, 2025 8 / 22


Using [Link]

Another commonly used subpackage is [Link], which supports linear


algebra operations.
1 A = np . array ([[1 , 2] , [3 , 4]])
2
3 np . linalg . det ( A ) # Compute the determinant
4 # np . float64 ( -2.0000000000000004)
5
6 np . linalg . inv ( A ) # Compute the inverse
7 # array ([[ -2. , 1. ] ,
8 # [ 1.5 , -0.5]])

Python Programming Lecture 23 October 13, 2025 9 / 22


Relation to SciPy

Much of NumPy’s functionality is also available in SciPy, which is a


collection of scientific modules built on top of NumPy.
SciPy extends NumPy with specialized tools for:
Optimization
Integration
Signal and image processing
Statistical modeling

Python Programming Lecture 23 October 13, 2025 10 / 22


Documentation and Resources

For a comprehensive list of available sub-packages and functions, refer to


the official documentation:
[Link]
Summary:
NumPy’s sub-packages enhance its computational power.
They are optimized for speed and numerical accuracy.
SciPy builds upon NumPy to offer even more scientific computing
tools.

Python Programming Lecture 23 October 13, 2025 11 / 22


Vectorization vs Loops

Let’s begin with some non-vectorized code, which uses a native Python
loop to generate, square, and sum a large number of random variables.
1 n = 1 _000_000
2 with qe . Timer () :
3 y = 0 # Will accumulate and store sum
4 for i in range ( n ) :
5 x = random . uniform (0 , 1)
6 y += x **2
7 # 0.42 seconds elapsed

This implementation uses explicit looping — which is slow in Python. [Use


!pip install quantecon to install quantecon then use import quantecon as
qe. Also use import random]

Python Programming Lecture 23 October 13, 2025 12 / 22


Vectorized Implementation

Now consider the vectorized version of the same computation:


1 with qe . Timer () :
2 x = np . random . uniform (0 , 1 , n )
3 y = np . sum ( x **2)
4 # 0.02 seconds elapsed

Observation: The vectorized version runs much faster than the


loop-based implementation.

Python Programming Lecture 23 October 13, 2025 13 / 22


Why Vectorized Code is Faster

The second code block breaks the loop into three optimized batch
operations:
1 Draw n uniforms
2 Square them
3 Sum them

Key Points:
These operations are executed by compiled C or Fortran code, not
the Python interpreter.
Apart from small overheads, the result is C/Fortran-like speed.

Python Programming Lecture 23 October 13, 2025 14 / 22


Vectorization Summary

Vectorization means expressing computations as operations on entire


arrays, rather than element-by-element loops.
This is one of the main advantages of NumPy.
Vectorized code is both:
Faster — due to optimized low-level routines.
Cleaner — due to concise syntax and readability.

In short, NumPy’s vectorized operations combine the simplicity of Python


with the speed of compiled languages.

Python Programming Lecture 23 October 13, 2025 15 / 22


Universal Functions (UFuncs)

Many functions provided by NumPy are called universal functions


(ufuncs).
UFuncs operate element-wise on arrays, allowing for fast vectorized
computations.
By exploiting ufuncs, many operations can be vectorized, leading to
faster execution.

Python Programming Lecture 23 October 13, 2025 16 / 22


Example Problem Setup

Consider the problem of maximizing a function f of two variables


(x, y ) over the square [−3, 3] × [−3, 3].
Let
cos(x 2 + y 2 )
f (x, y ) =
1 + x2 + y2

Python Programming Lecture 23 October 13, 2025 17 / 22


Python Function Definition

1 def f (x , y ) :
2 return np . cos ( x **2 + y **2) / (1 + x **2 + y **2)

This function works seamlessly with NumPy arrays because of the


ufunc behavior of [Link], [Link], and [Link].

Python Programming Lecture 23 October 13, 2025 18 / 22


Creating the Grid

Approach:
Evaluate f (x, y ) for all (x, y ) in a grid.
Return the maximum of observed values.

Define the grid:


1 xgrid = np . linspace ( -3 , 3 , 1000)
2 ygrid = xgrid
3 x , y = np . meshgrid ( xgrid , ygrid )

[Link] creates evenly spaced points in [−3, 3].


[Link] creates coordinate matrices from coordinate vectors.

Python Programming Lecture 23 October 13, 2025 19 / 22


Non-vectorized Version (Using Loops)

Python loop implementation:


1 with qe . Timer () :
2 m = - np . inf
3 for x in grid :
4 for y in grid :
5 z = f (x , y )
6 if z > m :
7 m = z

Output:
1 1.53 seconds elapsed

Observation:
Loops in Python are slow because each iteration is handled at the
interpreter level.

Python Programming Lecture 23 October 13, 2025 20 / 22


Vectorized Version

NumPy-based vectorized implementation:


1 with qe . Timer () :
2 x , y = np . meshgrid ( grid , grid )
3 np . max ( f (x , y ) )

Output:
1 0.02 seconds elapsed

Explanation:
All looping takes place in compiled C code.
The operation leverages NumPy’s universal functions (ufuncs).
Results in dramatic speed improvement.

Python Programming Lecture 23 October 13, 2025 21 / 22


Performance Comparison

Non-vectorized: 1.53 seconds


Vectorized: 0.02 seconds

Key Takeaway:
Vectorization
Batch operations on arrays eliminate explicit Python loops and utilize
optimized machine code for fast execution.

Python Programming Lecture 23 October 13, 2025 22 / 22


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 24)

Python Programming Lecture 24 October 15, 2025 1 / 13


Matplotlib: Overview

Matplotlib is an outstanding graphics library designed for scientific


computing.
It provides:
High-quality two and three-dimensional plots.
Output in all common formats (PDF, PNG, etc.).
LaTeX integration.
Fine-grained control over all presentation aspects.
Support for animation.

Python Programming Lecture 24 October 15, 2025 2 / 13


Matplotlib’s Split Personality

Matplotlib offers two different interfaces:


1 A simple MATLAB-style application programming interface (API) —
created for MATLAB users transitioning to Python.
2 A more Pythonic object-oriented API.
The second (object-oriented) API is recommended for most
applications.

Python Programming Lecture 24 October 15, 2025 3 / 13


The APIs in Matplotlib

Matplotlib’s flexibility allows users to choose between two approaches:

MATLAB-style API for quick and simple plotting


Object-oriented API for structured, reusable code

Python Programming Lecture 24 October 15, 2025 4 / 13


The MATLAB-style API

Here’s an example using the MATLAB-style API:


1 import matplotlib . pyplot as plt
2 import numpy as np
3
4 x = np . linspace (0 , 10 , 200)
5 y = np . sin ( x )
6
7 plt . plot (x , y , "b - " , linewidth =2)
8 plt . show ()

Here ”b-” represents “plot a solid blue line”. One may use ‘r–’ (Red
dashed line), ‘g’ (Green dotted line), ‘k-’ (Black solid line), ‘bo’ (Blue
circles-no connecting line), etc. as well.

Python Programming Lecture 24 October 15, 2025 5 / 13


The MATLAB-style API (Contd.)

Look at the output of the previous code:


This is simple and convenient, but also somewhat limited and
un-Pythonic.
For example, in the function calls, a lot of objects get created and
passed around without making themselves known to the programmer.
Python programmers tend to prefer a more explicit style of
programming (run import this in a code block and look at the second
line).
This leads us to the alternative, object-oriented Matplotlib API.

Python Programming Lecture 24 October 15, 2025 6 / 13


The Object-Oriented API

Matplotlib also provides an object-oriented interface for plotting, which


offers greater control and flexibility.
The figure and axes are explicitly created.
Plotting commands are called as methods of the axes object.
1 import matplotlib . pyplot as plt
2 import numpy as np
3
4 x = np . linspace (0 , 10 , 200)
5 y = np . sin ( x )
6
7 fig , ax = plt . subplots () # Create figure and axes
8 ax . plot (x , y , "b - " , linewidth =2) # Plot on the axes
9 plt . show ()

Python Programming Lecture 24 October 15, 2025 7 / 13


The Object-Oriented API (Contd.)

The call fig, ax = [Link]() returns a pair, where:


fig is a Figure instance — think of it as a blank canvas.
ax is an AxesSubplot instance — think of it as a frame for plotting
within the canvas.

The plot() function is actually a method of the ax object.

While this approach requires a bit more typing, the explicit use of
objects provides:
Greater control over the figure layout and style.
Easier management of multiple plots and axes.

Python Programming Lecture 24 October 15, 2025 8 / 13


Tweaks in Matplotlib Plots

We can easily modify plot appearance — for example, changing color


or adding a legend:
1 fig , ax = plt . subplots ()
2 ax . plot (x , y , "r - " , linewidth =2 , label = ’ sine function ’ ,
alpha =0.6)
3 ax . legend ()
4 plt . show ()

The argument alpha=0.6 makes the line slightly transparent, giving


a smoother look.
The location of the legend can be customized using loc:
1 fig , ax = plt . subplots ()
2 ax . plot (x , y , "r - " , linewidth =2 , label = " sine function " ,
alpha =0.6)
3 ax . legend ( loc = " upper center " )
4 plt . show ()

Python Programming Lecture 24 October 15, 2025 9 / 13


Adding LaTeX to Plots

If LaTeX is properly configured, you can include LaTeX-style math


directly in labels.
1 fig , ax = plt . subplots ()
2 ax . plot (x , y , "r - " , linewidth =2 , label = r " $y =\ sin ( x ) $ " , alpha
=0.6)
3 ax . legend ( loc = " upper center " )
4 plt . show ()

The string prefix r (as in r"y = sin(x)") ensures that backslashes are
interpreted literally.
This enables smooth integration of mathematical notation into plots.

Python Programming Lecture 24 October 15, 2025 10 / 13


Adding Titles and Customizing Ticks

We can control ticks, add titles, and further annotate the plot:
1 fig , ax = plt . subplots ()
2 ax . plot (x , y , "r - " , linewidth =2 , label = r " $y =\ sin ( x ) $ " , alpha
=0.6)
3 ax . legend ( loc = " upper center " )
4 ax . set_yticks ([ -1 , 0 , 1])
5 ax . set_title ( " Test plot " )
6 plt . show ()

[Link] yticks() controls tick positions on the y-axis.


[Link] title() adds a descriptive title to the plot.

Python Programming Lecture 24 October 15, 2025 11 / 13


More Features in Matplotlib

Matplotlib offers a large set of functions and features. We’ll illustrate a


few commonly used capabilities:
Multiple plots on a single axis.
Multiple subplots in a figure.
3D plotting.
Customizing helper functions using the object-oriented API.

Python Programming Lecture 24 October 15, 2025 12 / 13


Multiple Plots on One Axis
It’s straightforward to draw several curves on the same axes. Example:
generate three random normal densities and label each with its mean.
1 from scipy . stats import norm
2 from random import uniform
3 import numpy as np
4 import matplotlib . pyplot as plt
5
6 fig , ax = plt . subplots ()
7 x = np . linspace ( -4 , 4 , 150)
8
9 for i in range (3) :
10 m , s = uniform ( -1 , 1) , uniform (1 , 2)
11 y = norm . pdf (x , loc =m , scale = s )
12 current_label = rf " $ \ mu = { m :.2} $ "
13 ax . plot (x , y , linewidth =2 , alpha =0.6 , label =
current_label )
14
15 ax . legend ()
16 plt . show ()

Python Programming Lecture 24 October 15, 2025 13 / 13


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 25-26)

Python Programming Lecture 25-26 October 16, 2025 1 / 21


Multiple Subplots (Grid of Axes)
Create multiple subplots in one figure (e.g., a 3×2 grid) and draw a
histogram in each.
1 from scipy . stats import norm
2 from random import uniform
3 import numpy as np
4 import matplotlib . pyplot as plt
5
6 num_rows , num_cols = 3 , 2
7 fig , axes = plt . subplots ( num_rows , num_cols , figsize =(10 ,
12) )
8 for i in range ( num_rows ) :
9 for j in range ( num_cols ) :
10 m , s = uniform ( -1 , 1) , uniform (1 , 2)
11 x = norm . rvs ( loc =m , scale =s , size =100)
12 axes [i , j ]. hist (x , alpha =0.6 , bins =20)
13 t = rf " $ \ mu = { m :.2} , \ quad \ sigma = { s :.2} $ "
14 axes [i , j ]. set ( title =t , xticks =[ -4 , 0 , 4] , yticks
=[])
15 plt . show ()

Python Programming Lecture 25-26 October 16, 2025 2 / 21


3D Plots
Matplotlib supports 3D plotting (via the mpl toolkits mplot3d toolkit).
2 +y 2 )
Example: surface plot of f (x, y ) = cos(x
1+x 2 +y 2
.
1 from mpl_toolkits . mplot3d . axes3d import Axes3D
2 from matplotlib import cm
3 import numpy as np
4 import matplotlib . pyplot as plt
5 def f (x , y ) :
6 return np . cos ( x **2 + y **2) / (1 + x **2 + y **2)
7
8 xgrid = np . linspace ( -3 , 3 , 50)
9 ygrid = xgrid
10 x , y = np . meshgrid ( xgrid , ygrid )
11
12 fig = plt . figure ( figsize =(10 , 6) )
13 ax = fig . add_subplot (111 , projection = " 3 d " )
14 ax . plot_surface (x , y , f (x , y ) , rstride =2 , cstride =2 , cmap = cm
. jet , alpha =0.7 , linewidth =0.25)
15 ax . set_zlim ( -0.5 , 1.0)
16 plt . show ()
Python Programming Lecture 25-26 October 16, 2025 3 / 21
A Customizing Function (Helper for subplots)
You can build reusable helper functions that return fig, ax after applying
preferred customizations. Example: place axes through the origin and
enable grid lines.
1 import matplotlib . pyplot as plt
2 import numpy as np
3
4 def subplots () :
5 " Custom subplots with axes through the origin "
6 fig , ax = plt . subplots ()
7
8 # Put left and bottom spines ( axes ) at zero
9 for spine in [ " left " , " bottom " ]:
10 ax . spines [ spine ]. set_position ( " zero " )
11 # Hide top and right spines
12 for spine in [ " right " , " top " ]:
13 ax . spines [ spine ]. set_color ( " none " )
14
15 ax . grid ()
16 return fig , ax

Python Programming Lecture 25-26 October 16, 2025 4 / 21


A Customizing Function (Helper for subplots) (Contd.)

You can build reusable helper functions that return fig, ax after applying
preferred customizations. Example: place axes through the origin and
enable grid lines.
1 import matplotlib . pyplot as plt
2 import numpy as np
3
4 # Use the custom function
5 fig , ax = subplots ()
6 x = np . linspace ( -2 , 10 , 200)
7 y = np . sin ( x )
8 ax . plot (x , y , "r - " , linewidth =2 , label = " sine function " ,
alpha =0.6)
9 ax . legend ( loc = " lower right " )
10 plt . show ()

Python Programming Lecture 25-26 October 16, 2025 5 / 21


Notes on the Custom Function

The helper subplots():


calls the standard [Link]() internally,
customizes the ax object (spines, grid, etc.),
returns the fig, ax pair for plotting.
This pattern is powerful: centralize your plotting preferences and
reuse them across figures.
The object-oriented API makes such customizations straightforward
and maintainable.

Python Programming Lecture 25-26 October 16, 2025 6 / 21


Style Sheets in Matplotlib
Matplotlib provides style sheets for consistent plot formatting.
They define visual defaults such as colors, grids, backgrounds, and
fonts.
You can list available styles with:
1 import matplotlib . pyplot as plt
2 print ( plt . style . available )
Output (abbreviated):
1 [ " Solarize_Light2 " , " _classic_test_patch " , " _mpl - gallery " , "
_mpl - gallery - nogrid " , " bmh " , " classic " , " dark_background
" , " fast " , " fivethirtyeight " , " ggplot " , " grayscale " , "
petroff10 " , " seaborn - v0_8 " , " seaborn - v0_8 - bright " , "
seaborn - v0_8 - colorblind " , " seaborn - v0_8 - dark " , " seaborn -
v0_8 - dark - palette " , " seaborn - v0_8 - darkgrid " , " seaborn -
v0_8 - deep " , " seaborn - v0_8 - muted " , " seaborn - v0_8 - notebook
" , " seaborn - v0_8 - paper " , " seaborn - v0_8 - pastel " , " seaborn
- v0_8 - poster " , " seaborn - v0_8 - talk " , " seaborn - v0_8 - ticks "
, " seaborn - v0_8 - white " , " seaborn - v0_8 - whitegrid " , "
tableau - colorblind10 " ]
Python Programming Lecture 25-26 October 16, 2025 7 / 21
Using Style Sheets

Apply a style using the function:


1 plt . style . use ( " seaborn - v0_8 " )

The chosen style remains active until changed or reset.


Let”s define a function that takes a style name and draws four kinds
of plots with that style.

Python Programming Lecture 25-26 October 16, 2025 8 / 21


Defining a Function to Compare Styles

1 from scipy . stats import norm


2 import numpy as np
3 import matplotlib . pyplot as plt
4
5 def draw_graphs ( style = " default " ) :
6
7 # Set the style sheet
8 plt . style . use ( style )
9
10 fig , axes = plt . subplots ( nrows =1 , ncols =4 , figsize =(10 ,
3) )
11 x = np . linspace ( -13 , 13 , 150)
12 np . random . seed (9)
13
14 for i in range (3) :
15 m , s = np . random . uniform ( -8 , 8) , np . random . uniform
(2 , 2.5)

Code continued to the next slide


Python Programming Lecture 25-26 October 16, 2025 9 / 21
Defining a Function to Compare Styles (Contd.)
1
2 # Normal density curve
3 y = norm . pdf (x , loc =m , scale = s )
4 axes [0]. plot (x , y , linewidth =3 , alpha =0.7)
5
6 # Scatter plot
7 rnormX = norm . rvs ( loc =m , scale =s , size =150)
8 rnormY = norm . rvs ( loc =m , scale =s , size =150)
9 axes [1]. plot ( rnormX , rnormY , ls = " none " , marker = " o " ,
alpha =0.7)
10
11 # Histogram
12 axes [2]. hist ( rnormX , alpha =0.7)
13
14 # Random line graph
15 axes [3]. plot (x , rnormY , linewidth =2 , alpha =0.7)
16
17 style_name = style . split ( " -" ) [0]
18 plt . suptitle ( f " Style : { style_name } " , fontsize =13)
19 plt . show ()
Python Programming Lecture 25-26 October 16, 2025 10 / 21
Discussion

The figure shows four plots — a density curve, a scatter plot, a


histogram, and a line graph — all styled with the seaborn-v0 8
theme.
Style sheets enable consistency across all visualizations.
You can:
Use built-in style names (e.g., ggplot, bmh, dark background).
Create and save custom styles in .mplstyle files.
Combine multiple style sheets at once:
1 plt . style . use ([ " seaborn - v0_8 " , " dark_background " ])

This feature is particularly useful in large projects or publications


requiring uniform visuals.

Python Programming Lecture 25-26 October 16, 2025 11 / 21


Exploring Different Matplotlib Styles

We can experiment with other built-in style sheets.


For example, using the grayscale style removes all colors:
1 draw_graphs ( style = " grayscale " )

Python Programming Lecture 25-26 October 16, 2025 12 / 21


Example: ggplot Style

Matplotlib also supports a ggplot style, inspired by R’s ggplot2


package.
1 draw_graphs ( style = " ggplot " )

Python Programming Lecture 25-26 October 16, 2025 13 / 21


Example: Dark Background Style

We can invert the color scheme using the dark background style.
1 draw_graphs ( style = " dark_background " )

Python Programming Lecture 25-26 October 16, 2025 14 / 21


Creating or Customizing Style Sheets

You can explore or modify Matplotlib’s styling parameters using:


1 import matplotlib . pyplot as plt
2 print ( plt . rcParams . keys () )

The rcParams object is a dictionary-like variable storing global


configuration values.
Two main methods to modify styles:
1 Create your own matplotlibrc file.
2 Update style parameters directly in Python via [Link].

Python Programming Lecture 25-26 October 16, 2025 15 / 21


Customizing Style Parameters with rcParams

We can modify global plotting parameters dynamically.


Example: Adjusting the appearance of overlaid density lines.
1 plt . rcParams [ " lines . linewidth " ] = 3
2 plt . rcParams [ " lines . linestyle " ] = " --"
3 plt . rcParams [ " lines . color " ] = " navy "
4 plt . rcParams [ " axes . facecolor " ] = " # f5f5f5 "

These changes remain active for the current session.


To revert to defaults:
1 plt . rcdefaults ()

Python Programming Lecture 25-26 October 16, 2025 16 / 21


Changing the Style of Overlaid Density Lines (Second
Method)
Let’s change the style of our overlaid density lines using the second
method:

1 from cycler import cycler


2

3 # set to the default style sheet


4 plt . style . use ( " default " )
5
6 # You can update single values using keys :
7
8 # Set the font style to italic
9 plt . rcParams [ " font . style " ] = " italic "
10
11 # Update linewidth
12 plt . rcParams [ " lines . linewidth " ] = 2

Python Programming Lecture 25-26 October 16, 2025 17 / 21


Changing the Style of Overlaid Density Lines (Second
Method)

1
2 # You can also update many values at once using the update ()
method :
3 parameters = {
4 # Change default figure size
5 " figure . figsize " : (5 , 4) ,
6 # Add horizontal grid lines
7 " axes . grid " : True ,
8 " axes . grid . axis " : " y " ,
9 # Update colors for density lines
10 " axes . prop_cycle " : cycler ( " color " ,
11 [ " dimgray " , " slategrey " , "
darkgray " ])
12 }
13 plt . rcParams . update ( parameters )

Python Programming Lecture 25-26 October 16, 2025 18 / 21


Global Effect of rcParams Settings

Any plot generated after changing parameters in .rcParams will be


affected by the setting.

1 fig , ax = plt . subplots ()


2 x = np . linspace ( -4 , 4 , 150)
3 for i in range (3) :
4 m , s = uniform ( -1 , 1) , uniform (1 , 2)
5 y = norm . pdf (x , loc =m , scale = s )
6 current_label = rf " $ \ mu = { m :.2} $ "
7 ax . plot (x , y , linewidth =2 , alpha =0.6 , label =
current_label )
8 ax . legend ()
9 plt . show ()

Python Programming Lecture 25-26 October 16, 2025 19 / 21


Reverting to Default Style Sheet

Apply the default style sheet again to change your style back to
default:

1 plt . style . use ( " default " )


2
3 # Reset default figure size
4 plt . rcParams [ " figure . figsize " ] = (10 , 6)

Python Programming Lecture 25-26 October 16, 2025 20 / 21


Discussion

Style sheets provide visual consistency and easy customization.


You can:
Switch between built-in themes like ggplot, grayscale, or
dark background.
Fine-tune individual parameters using [Link].
Save personal or organizational standards as .mplstyle files.
This flexibility makes Matplotlib a powerful tool for both
publication-quality figures and exploratory analysis.

Python Programming Lecture 25-26 October 16, 2025 21 / 21


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 27)

Python Programming Lecture 27 October 25, 2025 1 / 13


Example

Plot the function


f (x, θ) = cos(πθx)e −x
over the interval x ∈ [0, 5] for each θ ∈ [Link](0, 2, 10).
Place all the curves in the same figure.

Python Programming Lecture 27 October 25, 2025 2 / 13


Solution

1 import numpy as np
2 import matplotlib . pyplot as plt
3
4 def f (x , theta ) :
5 return np . cos ( np . pi * theta * x ) * np . exp ( - x )
6
7 theta_vals = np . linspace (0 , 2 , 10)
8 x = np . linspace (0 , 5 , 200)
9 fig , ax = plt . subplots ()
10
11 for theta in theta_vals :
12 ax . plot (x , f (x , theta ) )
13
14 plt . show ()

Python Programming Lecture 27 October 25, 2025 3 / 13


Example

Plot the functions


y1 = sin(x), y2 = cos(x)
over the interval x ∈ [0, 2π].
Display both curves in one figure with appropriate labels and legend.

Python Programming Lecture 27 October 25, 2025 4 / 13


Solution

1 import numpy as np
2 import matplotlib . pyplot as plt
3
4 x = np . linspace (0 , 2* np . pi , 200)
5 y1 = np . sin ( x )
6 y2 = np . cos ( x )
7
8 plt . plot (x , y1 , label = " sin ( x ) " , linewidth =2)
9 plt . plot (x , y2 , label = " cos ( x ) " , linewidth =2)
10 plt . legend ()
11 plt . show ()

Python Programming Lecture 27 October 25, 2025 5 / 13


Example

Plot the exponential function

f (x; λ) = e −λx

for λ = 0.5, 1.0, 1.5, 2.0 over x ∈ [0, 5].


Show all curves in one plot.

Python Programming Lecture 27 October 25, 2025 6 / 13


Solution

1 import numpy as np
2 import matplotlib . pyplot as plt
3
4 x = np . linspace (0 , 5 , 200)
5 lambda_vals = [0.5 , 1.0 , 1.5 , 2.0]
6
7 for lam in lambda_vals :
8 plt . plot (x , np . exp ( - lam * x ) , label = f " lambda ={ lam } " )
9
10 plt . xlabel ( " x " )
11 plt . ylabel ( " f ( x ; lambda ) " )
12 plt . legend ()
13 plt . show ()

Python Programming Lecture 27 October 25, 2025 7 / 13


Example

Generate and display histograms of 3 normal random samples, each with different
means µ and standard deviations σ:

(µ, σ) = (0, 1), (1, 1.5), (2, 0.5)


Each histogram should be semi-transparent for comparison.

Python Programming Lecture 27 October 25, 2025 8 / 13


Solution

1 import numpy as np
2 import matplotlib . pyplot as plt
3
4 params = [(0 , 1) , (1 , 1.5) , (2 , 0.5) ]
5
6 for mu , sigma in params :
7 x = np . random . normal ( mu , sigma , 1000)
8 plt . hist (x , bins =30 , alpha =0.5 , label = f " mu ={ mu } , sigma ={
sigma } " )
9
10 plt . legend ()
11 plt . show ()

Python Programming Lecture 27 October 25, 2025 9 / 13


Example

Create a 2 × 2 grid of subplots displaying the following:


1. y = x
2. y = x 2
3. y = sin(x)
4. y = e −x
Each subplot should have a title.

Python Programming Lecture 27 October 25, 2025 10 / 13


Solution
1 import numpy as np
2 import matplotlib . pyplot as plt
3
4 x = np . linspace (0 , 5 , 100)
5 fig , axes = plt . subplots (2 , 2 , figsize =(8 , 6) )
6
7 axes [0 , 0]. plot (x , x )
8 axes [0 , 0]. set_title ( " y = x " )
9
10 axes [0 , 1]. plot (x , x **2)
11 axes [0 , 1]. set_title ( " y = x ^2 " )
12
13 axes [1 , 0]. plot (x , np . sin ( x ) )
14 axes [1 , 0]. set_title ( " y = sin ( x ) " )
15
16 axes [1 , 1]. plot (x , np . exp ( - x ) )
17 axes [1 , 1]. set_title ( " y = exp ( - x ) " )
18
19 plt . tight_layout ()
20 plt . show ()
Python Programming Lecture 27 October 25, 2025 11 / 13
Example

Plot the parametric curve

x(t) = cos(t), y (t) = sin(2t)

for t ∈ [0, 2π].


Label the axes and provide a title.

Python Programming Lecture 27 October 25, 2025 12 / 13


Solution

1 import numpy as np
2 import matplotlib . pyplot as plt
3
4 t = np . linspace (0 , 2* np . pi , 300)
5 x = np . cos ( t )
6 y = np . sin (2* t )
7
8 plt . plot (x , y )
9 plt . xlabel (" x ( t ) = cos ( t ) ")
10 plt . ylabel (" y ( t ) = sin (2 t ) ")
11 plt . title (" Parametric Curve ")
12 plt . show ()

Python Programming Lecture 27 October 25, 2025 13 / 13


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 28)

Python Programming Lecture 28 October 27, 2025 1 / 16


SciPy

SciPy builds on top of NumPy to provide common tools for scientific


programming such as
linear algebra
numerical integration
interpolation
optimization
distributions and random number generation
signal processing
Like NumPy, SciPy is stable, mature and widely used.

Python Programming Lecture 28 October 27, 2025 2 / 16


SciPy versus NumPy

SciPy is a package that contains various tools that are built on top of
NumPy, using its array data type and related functionality.

Note: In older versions of SciPy (scipy < 0.15.1), importing the


package would also import NumPy symbols into the global namespace, as
can be seen from this excerpt of the SciPy initialization file:
1 from numpy import *
2 from numpy . random import rand , randn
3 from numpy . fft import fft , ifft
4 from numpy . lib . scimath import *

Python Programming Lecture 28 October 27, 2025 3 / 16


SciPy versus NumPy (Contd.)

It is better practice to use NumPy functionality explicitly:


1 import numpy as np
2 a = np . identity (3)

More recent versions of SciPy (1.15+) no longer automatically import


NumPy symbols.

What is useful in SciPy is the functionality in its sub-packages:


[Link],
[Link],
[Link],
etc.

Python Programming Lecture 28 October 27, 2025 4 / 16


[Link] Subpackage

The [Link] subpackage supplies


numerous random variable objects (densities, cumulative distributions,
random sampling, etc.),
some estimation procedures, and
some statistical tests.

Python Programming Lecture 28 October 27, 2025 5 / 16


Random Variables and Distributions

Recall that [Link] provides functions for generating random


variables:
1 np . random . beta (5 , 5 , size =3)
2 # array ([0.68550473 , 0.49141026 , 0.41039465])

This generates a draw from the beta distribution with parameters


a, b = 5, 5.

Sometimes we need access to the density itself, or the cdf, the quantiles,
etc. For this, we can use [Link], which provides all of this
functionality as well as random number generation in a single consistent
interface.

Python Programming Lecture 28 October 27, 2025 6 / 16


Beta Density Plot

1 from scipy . stats import beta


2 import numpy as np
3 import matplotlib . pyplot as plt
4
5 q = beta (5 , 5) # Beta (a , b ) , with a = b = 5
6 obs = q . rvs (2000) # 2000 observations
7 grid = np . linspace (0.01 , 0.99 , 100)
8
9 fig , ax = plt . subplots ()
10 ax . hist ( obs , bins =40 , density = True )
11 ax . plot ( grid , q . pdf ( grid ) , "k - " , linewidth =2)
12 plt . show ()

Python Programming Lecture 28 October 27, 2025 7 / 16


Useful Methods of Distribution Objects

The object q that represents the beta distribution in the previous slide has
additional useful methods, including:
1 q . cdf (0.4) # Cumulative distribution function
2 # np . float64 ( 0 . 2 6 6 5 6 7 6800 00000 03)
3
4 q . ppf (0.8) # Quantile ( inverse cdf ) function
5 # np . float64 ( 0 . 6 3 3 9 1 34834642708)
6
7 q . mean ()
8 # np . float64 (0.5)

Python Programming Lecture 28 October 27, 2025 8 / 16


General Syntax for Creating Distribution Objects

The general syntax for creating these objects that represent distributions
(of type rv frozen) is:

name = [Link] name(shape params, loc=c, scale=d)

Here dist name is one of the distribution names in [Link].

The loc and scale parameters transform the original random variable X
into c + dX .

Python Programming Lecture 28 October 27, 2025 9 / 16


Alternative Syntax

There is an alternative way of calling the methods described above.

For example, the code that generates the figure in the previous slide can
be replaced by:
1 obs = beta . rvs (5 , 5 , size =2000)
2 grid = np . linspace (0.01 , 0.99 , 100)
3
4 fig , ax = plt . subplots ()
5 ax . hist ( obs , bins =40 , density = True )
6 ax . plot ( grid , beta . pdf ( grid , 5 , 5) , "k - " , linewidth =2)
7 plt . show ()

Python Programming Lecture 28 October 27, 2025 10 / 16


Roots and Fixed Points
A root or zero of a real function f on [a, b] is an x ∈ [a, b] such that
f (x) = 0.
For example, if we plot the function

f (x) = sin(4(x − 1/4)) + x + x 20 − 1, x ∈ [0, 1]

we get (unique root is approximately 0.408)


1 f = lambda x : np . sin (4 * ( x - 1/4) ) + x + x **20 - 1
2 x = np . linspace (0 , 1 , 100)
3
4 fig , ax = plt . subplots ()
5 ax . plot (x , f ( x ) , label = " $f ( x ) $ " )
6 ax . axhline ( ls = " --" , c = " k " )
7 ax . set_xlabel ( " $x$ " , fontsize =12)
8 ax . set_ylabel ( " $f ( x ) $ " , fontsize =12)
9 ax . legend ( fontsize =12)
10 plt . show ()

Python Programming Lecture 28 October 27, 2025 11 / 16


Bisection

One of the most common algorithms for numerical root-finding is


bisection.
To understand the idea, consider the function

f (x) = sin(4(x − 1/4)) + x + x 20 − 1, x ∈ [0, 1].

Python Programming Lecture 28 October 27, 2025 12 / 16


Bisection Algorithm in Python

1 def bisect (f , a , b , tol =10 e -5) :


2 """
3 Implements the bisection root finding algorithm ,
assuming that f is a
4 real - valued function on [a , b ] with f ( a ) < 0 < f ( b ) .
5 """
6 lower , upper = a , b
7
8 while upper - lower > tol :
9 middle = 0.5 * ( upper + lower )
10 if f ( middle ) > 0: # root is between lower and
middle
11 lower , upper = lower , middle
12 else : # root is between middle and
upper
13 lower , upper = middle , upper
14
15 return 0.5 * ( upper + lower )
16 bisect (f , 0 , 1) # 0. 408294677734375

Python Programming Lecture 28 October 27, 2025 13 / 16


SciPy’s Built-in Bisection Function

SciPy provides its own bisection function.


Let’s test it using the same function f defined earlier.
1 import numpy as np
2 from scipy . optimize import bisect
3
4 # Define the function
5 f = lambda x : np . sin (4 * ( x - 1/4) ) + x + x **20 - 1
6
7 # Apply SciPy ’s built - in bisection method
8 root = bisect (f , 0 , 1)
9
10 print ( root )
11 # Output :
12 # 0.408293 50 42 80 66 39

Python Programming Lecture 28 October 27, 2025 14 / 16


The Newton-Raphson Method

Another very common root-finding algorithm is the


Newton-Raphson method.
In SciPy, this algorithm is implemented by
[Link].
Unlike bisection, the Newton-Raphson method uses local slope
information to increase the speed of convergence.
Let’s investigate this using the same function
f (x) = sin(4(x − 1/4)) + x + x 20 − 1.

Python Programming Lecture 28 October 27, 2025 15 / 16


The Newton-Raphson Method (Contd.)

1 import numpy as np
2 from scipy . optimize import newton
3
4 # Define the function
5 f = lambda x : np . sin (4 * ( x - 1/4) ) + x + x **20 - 1
6
7 # Newton - Raphson method with a suitable initial guess
8 root1 = newton (f , 0.2)
9 print ( root1 )
10 # Output :
11 # 0.40829 35 0 4 27 9 3 56 7 3
12
13 # Failure to converge with a different initial guess
14 root2 = newton (f , 0.7)
15 print ( root2 )
16 # Output :
17 # 0.700170 00 00 00 02 79

Python Programming Lecture 28 October 27, 2025 16 / 16


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 29)

Python Programming Lecture 29 October 29, 2025 1 / 24


Pandas

Pandas is a package of fast, efficient data analysis tools for Python.


Its popularity has surged in recent years, coincident with the rise of
fields such as data science and machine learning.

Python Programming Lecture 29 October 29, 2025 2 / 24


Pandas (contd.)

Just as NumPy provides the basic array data type plus core array
operations, pandas
defines fundamental structures for working with data, and
endows them with methods that facilitate operations such as
reading in data,
adjusting indices,
working with dates and time series,
sorting, grouping, re-ordering and general data munging,
dealing with missing values, etc., etc.
More sophisticated statistical functionality is left to other packages, such
as statsmodels and scikit-learn, which are built on top of pandas.

Python Programming Lecture 29 October 29, 2025 3 / 24


Pandas (Contd.)

Two important data types defined by pandas are Series and DataFrame.
A Series can be thought of as a “column” of data, such as a
collection of observations on a single variable.
A DataFrame is a two-dimensional object for storing related columns
of data.

Python Programming Lecture 29 October 29, 2025 4 / 24


Series

Let’s start with Series. Start with creating a series of four random
observations:
1 import pandas as pd
2 import numpy as np
3 s = pd . Series ( np . random . randn (4) , name = " daily returns "
)
4 s
5 # Output :
6 0 0.094222
7 1 -2.868577
8 2 0.401491
9 3 -0.001977
10 Name : daily returns , dtype : float64
Here you can imagine the indices 0, 1, 2, 3 as indexing of four listed
companies, and the values being daily returns on their shares.

Python Programming Lecture 29 October 29, 2025 5 / 24


Series Operations
Pandas Series are built on top of NumPy arrays and support many similar
operations:
1 s * 100
2 # Output :
3 0 9.422204
4 1 -286.857734
5 2 40.149094
6 3 -0.197658
7 Name : daily returns , dtype : float64
8
9 np . abs ( s )
10 # Output :
11 0 0.094222
12 1 2.868577
13 2 0.401491
14 3 0.001977
15 Name : daily returns , dtype : float64

Python Programming Lecture 29 October 29, 2025 6 / 24


Series Methods and Indices

Series provide more than NumPy arrays. They have additional


(statistically oriented) methods:
1 s . describe ()
2 # Output :
3 count 4.000000
4 mean -0.593710
5 std 1.526308
6 min -2.868577
7 25% -0.718627
8 50% 0.046123
9 75% 0.171039
10 max 0.401491
11 Name : daily returns , dtype : float64

Python Programming Lecture 29 October 29, 2025 7 / 24


Series Methods and Indices (Contd.)

Their indices are also more flexible:


1 s . index = [ " A " , " B " , " C " , " D " ]
2 s
3 # Output :
4 A 0.094222
5 B -2.868577
6 C 0.401491
7 D -0.001977
8 Name : daily returns , dtype : float64

Python Programming Lecture 29 October 29, 2025 8 / 24


Series as Dictionaries
Viewed in this way, Series are like fast, efficient Python dictionaries (with
the restriction that all items have the same type).
One can use similar syntax as Python dictionaries:
1 s["A"]
2 # Output :
3 np . float64 ( 0 . 0 9 4 2 2 2 0 4 3041 15929 )
4
5 s["A"] = 0
6 s
7 # Output :
8 A 0.000000
9 B -2.868577
10 C 0.401491
11 D -0.001977
12 Name : daily returns , dtype : float64
13
14 " A " in s
15 # Output :
16 True

Python Programming Lecture 29 October 29, 2025 9 / 24


DataFrames

While a Series is a single column of data, a DataFrame is several


columns, one for each variable.
In essence, a DataFrame in pandas is analogous to a (highly
optimized) Excel spreadsheet.
Thus, it is a powerful tool for representing and analyzing data that
are naturally organized into rows and columns, often with descriptive
indices for individual rows and individual columns.

Python Programming Lecture 29 October 29, 2025 10 / 24


Reading a CSV File into a DataFrame

Let’s look at an example that reads data from the CSV file
pandas/data/test [Link], taken from the Penn World Tables.
The dataset contains the following indicators:
Variable Name Description
POP Population (in thousands)
XRAT Exchange Rate to US $
tcgdp Total PPP Converted GDP
(in million international $)
cc Consumption Share of PPP Converted
GDP Per Capita (%)
cg Government Consumption Share of PPP
Converted GDP Per Capita (%)

Python Programming Lecture 29 October 29, 2025 11 / 24


Creating a DataFrame from a CSV File

We can read the dataset directly from the provided URL using
[Link] csv:
1 import pandas as pd
2
3 df = pd . read_csv (
4 " https :// raw . githu buserc ontent . com / QuantEcon /
lecture - python - programming / master / source /
_static / lecture_specific / pandas / data / test_pwt .
csv "
5 )
6
7 type ( df )
8 # Output :
9 pandas . core . frame . DataFrame
10 print ( df )
The variable df is now a pandas DataFrame containing the data.

Python Programming Lecture 29 October 29, 2025 12 / 24


Select Data by Position

Example: Selecting specific rows using slicing in pandas.

Listing 1: Selecting rows by position in pandas


1 import pandas as pd
2
3 # Read the dataset
4 df = pd . read_csv (
5 " https :// raw . githu buserc ontent . com / QuantEcon /
lecture - python - programming / master / source /
_static / lecture_specific / pandas / data / test_pwt .
csv "
6 )
7

8 # Select rows by position


9 df [2:5]

Python Programming Lecture 29 October 29, 2025 13 / 24


Selecting Rows and Columns in pandas

Example: Different ways to select rows and columns.

Listing 2: Selecting specific columns


1 # Select specific columns by name
2 df [[ " country " , " tcgdp " ]]

Listing 3: Selecting rows and columns by integer position using iloc


1 # Select rows 2 to 4 and columns 0 to 3
2 df . iloc [2:5 , 0:4]

Listing 4: Selecting rows and columns by labels using loc


1 # Select rows 2 to 4 and specific columns by name
2 df . loc [ df . index [2:5] , [ " country " , " tcgdp " ]]

Python Programming Lecture 29 October 29, 2025 14 / 24


Select Data by Conditions

Instead of indexing rows and columns using integers and names, we


can also obtain a sub-dataframe of our interests that satisfies certain
(potentially complicated) conditions.
The most straightforward way is with the [] operator.
1 df [ df . POP >= 20000]

Python Programming Lecture 29 October 29, 2025 15 / 24


Understanding Conditional Selection

To understand what is going on here, notice that [Link] >= 20000


returns a series of boolean values.
1 df . POP >= 20000

1 0 True
2 1 False
3 2 True
4 3 False
5 4 False
6 5 True
7 6 True
8 7 False
9 Name : POP , dtype : bool

In this case, df[ ] takes a series of boolean values and only returns
rows with the True values.

Python Programming Lecture 29 October 29, 2025 16 / 24


Conditional Selection in pandas

We can combine multiple conditions to extract subsets of data.


1 df [( df . country . isin ([
2 " Argentina " , " India " , " South Africa " ]) ) &
3 ( df . POP > 40000) ]

However, there is another way of doing the same thing using query(),
which can be slightly faster and more readable.
1 # Equivalent expressions
2 df . query ( " POP >= 20000 " )
3 df . query ( " country in [ " Argentina " , " India " , " South Africa " ]
and POP > 40000 " )

Python Programming Lecture 29 October 29, 2025 17 / 24


Conditional Selection in pandas (Contd.)

We can also perform arithmetic operations between columns.


1 df [( df . cc + df . cg >= 80) & ( df . POP <= 20000) ]
2
3 # Equivalent using query
4 df . query ( " cc + cg >= 80 & POP <= 20000 " )

To select the country with the largest consumption share:


1 df . loc [ df . cc == max ( df . cc ) ]

Or select specific columns from the sub-dataframe:


1 df . loc [( df . cc + df . cg >= 80) & ( df . POP <= 20000) ,
2 [ " country " , " year " , " POP " ]]

Python Programming Lecture 29 October 29, 2025 18 / 24


Application: Subsetting DataFrame

Motivation: Real-world datasets can be enormous. It is sometimes


desirable to work with a subset of data to enhance computational
efficiency and reduce redundancy.
Example: Suppose we are only interested in the Population (POP) and
Total GDP (tcgdp). We can create a smaller DataFrame containing only
these variables.
1 df_subset = df [[ " country " , " POP " , " tcgdp " ]]
2 df_subset

This subset can now be used for faster and more focused analysis. After
creating a smaller DataFrame for focused analysis, we can save it as a
CSV file for future use.

1 df_subset . to_csv ( " pwt_subset . csv " , index = False )

Python Programming Lecture 29 October 29, 2025 19 / 24


Apply Method

The [Link]() method applies a function to each row or column and


returns a Series. The function can be:
A built-in function (e.g., max)
A lambda function
A user-defined function

Python Programming Lecture 29 October 29, 2025 20 / 24


Apply Method (Contd.)

Example 1: Using a built-in function


1 df [[ " year " , " POP " , " XRAT " , " tcgdp " , " cc " , " cg " ]]. apply ( max )

year 2.000000e+03
POP 1.006300e+06
XRAT 5.954381e+01
tcgdp 9.898700e+06
cc 7.897874e+01
cg 1.407221e+01
dtype: float64

Example 2: Using a lambda function


1 df . apply ( lambda row : row , axis =1)

Python Programming Lecture 29 October 29, 2025 21 / 24


Note on .apply() Method

Axis Parameter:
axis = 0 – apply function to each column (variables)
axis = 1 – apply function to each row (observations)
axis = 0 is the default parameter.
We can use it together with .loc[] to do some more advanced selection

Python Programming Lecture 29 October 29, 2025 22 / 24


Advanced Selection
1 complexCondition = df . apply (
2 lambda row : row . POP > 40000
3 if row . country in [ " Argentina " , " India " , " South
Africa " ]
4 else row . POP < 20000 ,
5 axis =1) , [ " country " , " year " , " POP " , " XRAT " , " tcgdp " ]
6 complexCondition

(0 False
1 True
2 True
3 True
4 True
5 True
6 False
7 True
dtype: bool,
["country", "year", "POP", "XRAT", "tcgdp"])
Python Programming Lecture 29 October 29, 2025 23 / 24
Advanced Selection (Contd.)

When we apply this condition to the dataframe, the result will be


1 df . loc [ complexCondition ]

Python Programming Lecture 29 October 29, 2025 24 / 24


MTL5004/MTL505
Introduction to Computer Programming
(Lecture 30)

Python Programming Lecture 30 October 30, 2025 1 / 13


Make Changes in DataFrames

Overview: The ability to modify DataFrames is essential for generating


clean datasets for subsequent analysis.
1. Using [Link](): The where() method is used to “keep” the rows
that satisfy a condition and replace the rest with another value.
1 df . where ( df . POP >= 20000 , False )

Explanation:
Rows where POP >= 20000 are retained.
Other rows are replaced with False.

Python Programming Lecture 30 October 30, 2025 2 / 13


Make Changes in DataFrames (contd.)

2. Modifying Specific Columns: We can use the .loc[] method to


specify which rows and columns to modify, and then assign new values.
1 df . loc [ df . cg == max ( df . cg ) , " cg " ] = np . nan
2 df

Explanation:
Finds the row(s) where cg takes its maximum value.
Replaces those entries in column cg with NaN.

Python Programming Lecture 30 October 30, 2025 3 / 13


Make Changes in DataFrames (contd.)

3. Using .apply() to Modify Rows/Columns: The .apply() method


can modify entire rows or columns based on custom logic.
1 def update_row ( row ) :
2 # modify POP
3 row . POP = np . nan if row . POP <= 10000 else row . POP
4
5 # modify XRAT
6 row . XRAT = row . XRAT / 10
7 return row
8
9 df . apply ( update_row , axis =1)

Explanation:
Sets POP to NaN if its value ≤ 10000.
Divides all XRAT values by 10.
axis=1 applies the function row-wise.

Python Programming Lecture 30 October 30, 2025 4 / 13


Make Changes in DataFrames (contd.)

4. Using .map() to Modify All Entries: The .map() method can be


used to apply a function to every individual entry in the DataFrame.
1 # Round all decimal numbers to 2 decimal places
2 df . map ( lambda x : round (x , 2) if type ( x ) != str else x )

Explanation:
Each element in the DataFrame is processed individually.
Numeric values are rounded to 2 decimal places.
String values remain unchanged.

Python Programming Lecture 30 October 30, 2025 5 / 13


Application: Missing Value Imputation

Replacing missing values is an important step in data munging.


Let’s randomly insert some NaN values in the dataset for demonstration.

Code
1 for idx in list ( zip ([0 , 3 , 5 , 6] , [3 , 4 , 6 , 2]) ) :
2 df . iloc [ idx ] = np . nan
3
4 df

Python Programming Lecture 30 October 30, 2025 6 / 13


Application: Missing Value Imputation (Contd.)

The zip() function here creates pairs of values from the two lists (i.e. [0,3],
[3,4], . . . ).
We can use the .map() method again to replace all missing values with 0.

Code
1 # replace all NaN values by 0
2 def replace_nan ( x ) :
3 if type ( x ) != str :
4 return 0 if np . isnan ( x ) else x
5 else :
6 return x
7
8 df . map ( replace_nan )

Python Programming Lecture 30 October 30, 2025 7 / 13


Application: Missing Value Imputation (Contd.)

Pandas also provides convenient methods to replace missing values.


Single imputation using variable means can be easily done in pandas.

Code
1 # Single imputation using variable means
2 df = df . fillna ( df . iloc [: , 2:8]. mean () )
3 df

Python Programming Lecture 30 October 30, 2025 8 / 13


Standardization and Visualization

Let’s imagine that we’re only interested in the population (POP) and total
GDP (tcgdp).
One way to strip the data frame df down to only these variables is to
overwrite the dataframe using the selection method described above.

Code
1 df = df [[ " country " , " POP " , " tcgdp " ]]
2 df

Python Programming Lecture 30 October 30, 2025 9 / 13


Standardization and Visualization (Contd.)

The index 0, 1, ..., 7 is redundant because we can use the country


names as an index.
To do this, we set the index to be the country variable in the dataframe.

Code
1 df = df . set_index ( " country " )
2 df

Python Programming Lecture 30 October 30, 2025 10 / 13


Standardization and Visualization (Contd.)

We can give the columns slightly better and more meaningful names.

Code
1 df . columns = " population " , " total GDP "
2 df

The population variable is in thousands. Let’s revert it to single units.

Code
1 df [ " population " ] = df [ " population " ] * 1 e3
2 df

Python Programming Lecture 30 October 30, 2025 11 / 13


Standardization and Visualization (Contd.)

Add a new column showing real GDP per capita, multiplying by 1,000,000
as total GDP is in millions.
Generate a bar plot of GDP per capita using pandas’ built-in plotting.

Code
1 df [ " GDP percap " ] = df [ " total GDP " ] * 1 e6 / df [ " population " ]
2 df
3
4 ax = df [ " GDP percap " ]. plot ( kind = " bar " )
5 ax . set_xlabel ( " country " , fontsize =12)
6 ax . set_ylabel ( " GDP per capita " , fontsize =12)
7 plt . show ()

Python Programming Lecture 30 October 30, 2025 12 / 13


Standardization and Visualization (Contd.)

The dataframe is currently ordered alphabetically by country.


Sort the data by GDP per capita in descending order.
Plot the reordered data.

Code
1 df = df . sort_values ( by = " GDP percap " , ascending = False )
2 df
3
4 ax = df [ " GDP percap " ]. plot ( kind = " bar " )
5 ax . set_xlabel ( " country " , fontsize =12)
6 ax . set_ylabel ( " GDP per capita " , fontsize =12)
7 plt . show ()

Python Programming Lecture 30 October 30, 2025 13 / 13

You might also like