You are on page 1of 233

1.

Introduction to Computers and Programming

Outline:
1.1 Introduction to computer programming.
1.2 A quick look at the Python programming language and common constructs
1.3 Exercise

1.1 Introduction to computer programming.

1.1.1 The age of computers


Today, computers are everywhere. You may not notice them because they are getting smaller and smaller.
Actually, your smartphones and tablet pcs are also computers, and you may not notice that every car has a
computer inside. A computer used to be a machine that is as large as a room in the 1950s, but general
smartphones today are much faster those computers in the 1950s.

1.1.2 A computer program


A computer program is a sequence of instructions to be executed by computers. Examples of computer
programs in various forms shown as follows. “Programming” means an act of developing computer programs.

0001 1001 MOV AX,10


1001 1110 SUB BX,AX sum = 0
1000 1011 MOV [DX],AX for i in range(1,101):
1100 1011 JMP 200 sum = sum+i
1110 0010 MOV CX,5
1001 0111 MOV AX,10
1100 1011 MUL AX,CX Instructions in Python
1110 0010 CMP BX,AX programming language
1001 0111 JLE 500
1100 1011 JMP 400

Machine instructions Instructions in Assembly


language
More readable

Machine instruction is a machine language that only a computer can understand because it is written in
binary numbers including 0 and 1. Assembly language is a low-level programming language that is used in the
past and still quite difficult to understand by general people. It is designed for a specific type of processor,
and its code can be converted to a machine language by using an assembler. The computer program that

01204111 Computers and Programming, 1


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
took Apollo11 to the moon in 1969 was developed by Assembly language. Python which is the programming
language we are learning in this course is called high-level programming language. As opposed to the low-
level programming language, the high-level programming language uses natural language elements so that it
can be read and understood easily. Apart from Python, examples of high-level programming languages in
active use today are Visual Basic, C#, Java, and many others.

To understand how computer works, let’s try to make an analogy with how people solve a problem.

Problem: It’s the first day of school. You want to go to school from your home. What do you have to do?
Assume that your home is close to the school enough to walk to.

Solution: If you know the way to the school, you can just walk. But if you don’t, you may need to look at
the map and use it to plan your route to the school. Note that if you can plan your walking route with a
map, you can solve this kind of problems not just for going from your home to the school, but from any
place to any other place.

In a way, you are a “computer”. If you want to know the route from your home to the school, you need the
location of your home, the location of the school, and the map as “inputs”. Then you figure out the route
from your home to the school as an “output”.

Inputs
Location of
your home
Output

Location of
school

Route from
home to school
A computer that
Map solves the route-
finding problem

01204111 Computers and Programming, 2


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Once, if you know how to figure out this kind of route-finding problem, you can teach other people to solve
the same problem by giving them instructions step by step. For instance, “If you have a map, you can find
your way from one place to another using the following instructions. First, locate your location……”. And
these kinds of instructions to a computer is a program.

1.1.3 A computer components


A computer abstractly has components as follows:

Central
Processing
Unit
Input
(CPU)
&
Output

Memory

• Central Processing Unit (CPU): Performs calculation and makes a decision based on instructions and
data in the memory
• Input and output: Provide means (method) for the CPU to interact with the outside world through
various devices
• Memory: Stores data and instructions

01204111 Computers and Programming, 3


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Image of the real computer components*:

Power supply CPU

Memory

Other devices are input or


output devices
Hard drive
(external memory)

*Image from Wikimedia Commons: https://en.wikipedia.org/wiki/File:Personal_computer,_exploded_6.svg

Inside the memory


The smallest unit of information that can be processed by digital computers is a single binary digit (a bit),
which can be either 0 or 1. We usually group them in groups of 8 bits, each called a byte. A lot of bytes can
be stored in a memory unit.

0 1

Two bits

0 1 0 1 1 1 0 0

One byte

• 1 kB = 1,000 bytes
• 1 MB = 1,000,000 bytes
• 1 GB = 1,000,000,000 bytes

01204111 Computers and Programming, 4


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
IEEE-1541 recommendation
• 1 kiB = 210 bytes = 1,024 bytes
• 1 MiB = 220 bytes = 1,024 kiB
• 1 GiB = 230 bytes = 1,024 MiB

1.1.4 The instructions


The memory, not only keeps the data to be processed with the CPU, but it also keeps the instructions.

Memory

0001 1001
1001 1110
1000 1011
1100 1011
1110 0010
1001 0111
1100 1011
1110 0010
1001 0111
1100 1011

These instructions are in the format that the CPU can easily understand, referred to as “machine
instructions”. When writing a program, we rarely write in machine instructions. Instead of working directly with
machine instructions, people usually develop software with higher-level programming languages. But the
program must be translated into a form that the computer can understand. This process is called “program
translation”.
0001 1001
1001 1110
1000 1011
1100 1011
sum = 0 1110 0010
for i in range(1,101): 1001 0111
sum = sum + i 1100 1011
1110 0010
1001 0111
1100 1011
A program in Translation
high-level Machine
language instructions

01204111 Computers and Programming, 5


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1.2 A quick look at the Python programming language and common constructs

1.2.1 Python programming language


In this course, we will use Python programming language to teach you computer programming.

We will focus more on learning how to program and how to write good codes, skills that can be applied with
any popular computer programming languages.

Let's try Python (1)


Guess what the following Python program does. This may not look exactly like English, but it is not hard to
guess what the program will do.

print("Hello, Python")

The output:
Hello, Python

Let’s try Python (2)


Guess what the following Python program does.

a = int(input())
b = int(input())
result = a + b
print(f"{a} + {b} = {result}")

The output:
11
27
11 + 27 = 38

01204111 Computers and Programming, 6


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The above program reads two integers and outputs their summation. But something looks difficult.
a = int(input())
b = int(input())

If this is the first time you see computer programs, you may feel that these lines of code may look fairly
difficult. But as you continue to see and write more programs, it will be much easier to understand.

Let’s try Python (3)


Guess what the following Python program does.

import math

r = float(input())
print(math.pi*r*r)

The output:

10
314.15926538979

The above program reads a number and outputs pi times that number squared. Actually, the goal of this
program is to compute the area of the circle with radius r. Thus, we can write a better program as follows
which performs the same task but easier to understand because it states its intention fairly clearly.

import math

radius = float(input("Enter circle radius: "))


area = math.pi*radius*radius
print("The area of the circle is",area)

12.2.2 Typical Python programs


More details are provided in the next chapters, but here is an image of the typical structure of the Python
program.

01204111 Computers and Programming, 7


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Flow of
"""Rectangle area calculator
program Ask rectangle's length and width from user, Docstrings
then compute rectangle area
"""

import math Function


definition
def rectangle_area(length,width):

"""Compute area of rectangle of specified length and width"""

return length*width

Main program
# ask user to input length and width of a rectangle

length = int(input("Enter length: "))


width = int(input("Enter width: ")) Comments

# then compute and print out the area

area = rectangle_area(length,width)
print(f"Rectangle area is {area}")

First of all, each line of code is executed one by one from top to bottom. Apart from the “main program”
which is the main part every program must have, there may be “function definition”, “docstrings” and
“comments”.

Function Definition
A function is a group of organized, reusable code that is used to perform a single, related action. Functions
provide better modularity and a high degree of code reusing. You can define your own functions to provide
the required functionality. We may call “function”, a subroutine which has exactly the same meaning.

Comments and Docstrings


Comments and Docstrings are in the code to provide insights into what code is doing, how code works, or
give other notes. They do not affect how the program works. Docstrings are displayed when calling for help.

01204111 Computers and Programming, 8


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
A lot of keywords in Python
The Python language uses many “keywords” (e.g. import, def or return in the squares) to let you describe
your ideas precisely. You will later learn the usage of some of the keywords, but not all.

import math

def rectangle_area(length,width):

return length*width

12.2.3 Integrated Development Environment --- IDE


We will write our Python programs in application software that provides editing facility and translation
services for Python. This type of software is known as IDE (integrated development environment). Example of
IDE shown as follows.

01204111 Computers and Programming, 9


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
12.2.4 Edit-Run-Test Loop
Because everything in life doesn’t always work the first time you try it, your program may not always do
exactly like what you want. It may be correct in some cases, but it might fail in some other. Therefore, you
need to test your program. If it is not correct, you have to fix it (debug it) and try to test it again. Your process
for writing a Python program would look like this.

RUN

EDIT TEST

Debugging
When programmers try to fix mistakes in their codes, they usually refer to the activity as “debugging” (killing
the bugs). In the early days of computing, there was actually a bug in the machine. Therefore, problems with
computers are often referred to as bugs.

12.2.5 Python Turtle Graphics


Python comes with the Turtle graphics module that allows you to control the movement of a robotic turtle
on the screen. The turtle draws over the path he moves on as follows.

01204111 Computers and Programming, 10


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Basic Turtle Movements
• turtle.forward(d) – tell Turtle to walk forward d steps
• turtle.right(a) – tell Turtle to turn right for a degrees
• turtle.left(a) – tell Turtle to turn left for a degrees
The code is executed sequentially from top to bottom
import turtle

turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)

Turtle movement shown as follows.

Guess the result, what is Turtle drawing?


import turtle

turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.left(45)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)

01204111 Computers and Programming, 11


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
turtle.forward(100)
turtle.left(90)

From the above codes, the turtle movement shown follows.

Abstraction with subroutines


A set of instructions can be defined into a subroutine (or a function) so that they can be called for execution
later. A subroutine "draw_square" is defined in the dashed line square in the following program.

import turtle

def draw_square():
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90) Define a subroutine "draw_square"
turtle.forward(100)
turtle.left(90)
turtle.forward(100)
turtle.left(90)

draw_square()
turtle.left(45) Call the subroutine "draw_square"
draw_square()

Please note that the above program gives the same output as the previous program which has lengthy code.

Make it more general


The draw_square subroutine can be generalized to draw rectangles of any sizes by using a parameter as
follows.

01204111 Computers and Programming, 12


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
import turtle
"draw_square" now takes a parameter
def draw_square(size):
turtle.forward(size)
turtle.left(90)
turtle.forward(size)
turtle.left(90)
turtle.forward(size)
turtle.left(90)
turtle.forward(size)
turtle.left(90)

draw_square(100) Draw a square of size 100


turtle.left(45)
draw_square(50) Draw a square of size 50

Thus, the result has changed to as follows.

Get rid of repetitive code


Most programming languages provide special constructs for repeated actions.

import turtle

def draw_square(size): import turtle


turtle.forward(size)
turtle.left(90) def draw_square(size):
turtle.forward(size) for _ in range(4):
turtle.left(90) turtle.forward(size)
turtle.forward(size) turtle.left(90)
turtle.left(90)
turtle.forward(size) draw_square(100)
turtle.left(90) turtle.left(45)
draw_square(50)
draw_square(100)
turtle.left(45)
draw_square(50)

These two programs are giving the same result.

01204111 Computers and Programming, 13


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Execute actions selectively
Some actions need to be executed only when certain conditions are met.

import turtle This code is executed only when


size is greater than zero.
def draw_square(size):
if size > 0:

for _ in range(4):
turtle.forward(size)
turtle.left(90)

draw_square(100)
turtle.left(45)
draw_square(-50) This call gives no result
turtle.left(90)
draw_square(80)

Thus, the turtle draws only two squares with having the size of 100 and 80 as follows.

1.3 Exercise

1) Explain the definition of “debugging”.

2) From the sentences below, answer True or False into the blanks.
___(A)___ The smallest unit of information that can be processed by digital is a single binary (a
bit).
___(B)___ The computer memory only keeps the data to be processed with CPU.
___(C)___ People rarely write a program in machine language instructions.

01204111 Computers and Programming, 14


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
___(D)___ People usually develop software with higher-level programming languages which
need to be translated into a form that the computer can understand.
___(E)___ Programming is the process of developing a computer program.
___(F)___ Debugging is the process of finding errors and fixing them within a program.

3) Suppose there is a water bottle.

Sort the following instructions to open the water bottle correctly.


o Remove cap.
o Twist counter-clockwise until the seal is broken.
o Grip cap with index finger and thumb.

4) Write the program that orders turtle to draw a movement path like a house as follows.

Note:
- The width and height of each grid square side are 100.
- The turtle can repeat the same path.
- Each side of the triangle on the roof of the house is 70.

01204111 Computers and Programming, 15


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
2. Expressions, Variables, and Sequential Programs

Outline:
2.1 Simple Sequential programs
2.2 Operator Precedence
2.3 Variable
2.4 Values and Types
2.5 Input Statement
2.6 Output Formatting
2.7 Exercise

2.1 Simple sequential programs

Task: Dining Bill


At a dining place with your friends, here are five items you ordered. Write a program to compute the total
cost of the bill.
Item Price

Salad 82
Soup 64
Steak 90

Wine 75
Orange Juice 33

Ideas and Steps - We simply want to know the summation of all the five numbers. Somehow, we need to
tell the order to the computer to show the result of all these numbers added up.

2.1.1 Shell mode and Script mode


Solving in Shell Mode (Interactive Mode)
In shell mode (as known as, interactive mode), you can enter Python statements or expressions interactively.
When the Shell window shows prompt sign (>>>), you can enter Python code. Then, press <ENTER> (↵). When

01204111 Computers and Programming, 16


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
you enter the print statement (print(82+64+90+75+33)) or the expression (82+64+90+75+33) shown as
follows, the result (344) will be shown immediately after hitting <ENTER> (↵).

*Note: A print statement prints a result on the screen

Solving in Script Mode


In the script mode, firstly you have to create a new python file by choosing from menu File > New File or
hitting <Ctrl + N> then, enter Python code. After finished entering the code, go to the menu File > Save to
save the program as Python file (.py) with giving a file name. You can run the program by choosing the menu
Run > Run Module or hitting <F5>. The result (the output of the program) will be shown in the Shell
windows.

01204111 Computers and Programming, 17


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
2.1.2 What is a statement and Expression?
Statement: A (programming) statement is a complete command to order the computer to do something. For
example, for the following line;
print(82+64+90+75+33)

The above line is equivalent to giving a command, “Hey! Please print the value of the expression
82+64+90+75+33.”

Normally, a program usually consists of many statements.


Expression: An expression is something that can be evaluated to a value. An expression can be a
combination of values, variables, and operators. A value all by itself is considered an expression, and so is a
variable. An arithmetic expression which is a kind of expression can be evaluated to a numerical value. For
example, for the following part;
82+64+90+75+33

After this part gets evaluated by the computer, it is evaluated to a numerical value of 344.
Another example, the following part;
10+(2*A)

After this part gets evaluated by the computer, it is evaluated to a value of 20, in the case that variable A is 5.

Other Statement Examples:


print(20)
• Displays a single value, 20, and moves the cursor to the new line.
print()
• Simply move the cursor to the new line.
print('Hello')
• displays the text Hello and moves the cursor to the new line. Please note that 'Hello' is a string
expression.

Task: Dining Bill – Revised Program


Modify the previous example to make it be able to output more informative.
print('Total cost is ')
print(82+64+90+75+33)

01204111 Computers and Programming, 18


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Now, the program has two statements executed from top to bottom.
Why programming is better than a calculator?
Of course, programming is better than using a simple calculator for this task might seem much easier.
However,
• Repeating the whole task is tedious, especially with many numbers.
• When use calculator, if making a small mistake the whole process must be restarted from the
beginning.
With a program, all steps can be easily repeated and modified.

2.2 Operator Precedence

Task: Discounted Dining Bill


Based on the previous scenario, one of your friends just happens to carry a member card with a 20%
discount. Modify the program to compute the final cost.

Ideas: Start with the same summation expression. Then, with a 20% discount, the final cost will be 80% of
the original. Therefore, we just multiply the original expression by 0.8. Please note that, in most programming
languages, star symbol (*) means multiply
print('Total cost is ')
print(82+64+90+75+33 * 0.8)

Caveats – Operator Precedence


• In Python (and most programming languages), different operators have different precedence in order
of operations.
• For example, * has precedence over + in this expression, no matter how many spaces are used.
◦ Therefore, the expression of:
82+64+90+75+33 * 0.8
is equivalent to:
82+64+90+75+ (33*0.8)
which has the wrong meaning that different from the intended meaning.

01204111 Computers and Programming, 19


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Operation Precedence
• Python (and most programming languages) evaluates expressions in this order.
• Operations of the same precedence are evaluated from left to right
• One exception ** is evaluated from right to left (** is Exponentiation)
• When not sure about the precedence, always use parentheses
• % (remainder after division)
• // (integer division)

Operators Precedence
( ) Highest
** :
* / // % :
+ - Lowest

Examples of Operator Precedence:

Expression Equivalent to
2*3+4*5 (2*3)+(4*5)
1+2+3+4 ((1+2)+3)+4
(2+3)/5*4 ((2+3)/5)*4
3-2-5-(7+6) ((3-2)-5)-(7+6)
10+9%2+30 (10+(9%2))+30
10/2*5%3 ((10/2)*5)%3

Task: Discounted Dining Bill – Revised Program


Then, the program after corrected operation precedence will be like this.
print('Total cost is ')
print( (82+64+90+75+33) * 0.8)

01204111 Computers and Programming, 20


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
2.3 Variable

Task: Bill Sharing


At the same restaurant, five people are splitting the bill and share the total cost. Write a program to compute
the amount each person has to pay.

Item Price

Salad 82

Soup 64
Steak 90
Wine 75

Orange Juice 33

Ideas:
• Just compute the total and divide it by 5
• The result should be the amount each person has to pay
print('Total amount: ')
print( 82+64+90+75+33 )
print('Each has to pay: ')
print( (82+64+90+75+33) / 5.0 )

01204111 Computers and Programming, 21


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The result should be correct. However, the summation expression (82+64+90+75+33) gets repeated twice.
We now store the result of the total amount in a variable.

total = 82+64+90+75+33
print('Total amount: ')
print(total)
print('Each has to pay: ')
print(total/5)

• Any values such as 85, 23+8, "Hello" are objects that get stored inside a computer's memory.
• A variable is like a name tag given to such an object

2.3.1 Binding variable to values


An assignment statement (=) creates a new variable, gives it a value (an object in memory), and binds a
name to the value.
my_int = 82

• The variable name is my_int


• The assignment operator, also known as the equal sign (=)
• The object that is being tied to the variable name is 82

Reassigning Variables
Binding can be changed with a new assignment statement. Previous objects may still reside in memory, but
will be removed later on like this example.
>>> my_int = 82
>>> my_int = 64
>>> my_int
64

Assign variable x to be an integer and reassign variable x to be a string.


>>> x = 76
>>> print(x)
76
>>> x = 'Sammy'
>>> print(x)
Sammy

Expressions in Assignment Statements


An assignment statement (=) creates a new variable and gives it a value (344 in this case).
>>> total = 82+64+90+75+33
>>> print(total)
344

01204111 Computers and Programming, 22


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
2.3.2 Naming Variables
Different programming languages may have slightly different rules for naming a variable and also some
common rules as follows.
• A name consists of only alphanumeric characters (A-Z, a-z, 0-9) and underscores (_).
• A name must not have any spacing or other special characters (symbols). e.g. !, @, #, $
• A name cannot begin with a number.
• Lowercase and uppercase letters mean different things.
• A name must not be a reserved word (keyword).

You don’t have to memorize this list. In most development environments, keywords will be displayed in a
different color right after you type them into the code.

Examples of Naming Variables:


• radius can be a variable name.
• pay_rate can be a variable name.
• G-force cannot be a variable name because it contains a symbol -
• while cannot be a variable name because it is a reserved word.
• 8bus cannot be a variable name because it starts with a number.
• _class can be a variable name.
• Class can be a variable name.
• class cannot be a variable name because it is a reserved word.

01204111 Computers and Programming, 23


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Your program is written not only for a computer, but also humans have to read. Besides, variable names
should be meaningful, for examples:
Bad Example Good Example
a = 30 height = 30
b = 50 weight = 50
c = a * b area = height * weight

How a Variable stores Value?


• A variable can be created only once.
• Assignment can be done over and over. However, a variable can store one value at a time.
>>> x = 5
>>> x
5
>>> x = 20
>>> x
20

>>> x = 5
>>> x = 20
>>> x
20
>>> y = x*2
>>> x = 8
>>> x = x+1
>>> x
9
>>> y
40

2.4 Values and Types

Sometimes you need to store something other than an integer in a variable. Python provides several data
types (or classes) for different purposes. Some important types are listed here
Type Value Usage Example

int a whole number (positive, negative, zero) total = 25

float a number with fraction g_force = 9.81

first = 'A'
string a sequence of zero or more character(s) name = 'John'

01204111 Computers and Programming, 24


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
2.4.1 String Operations
We can’t perform mathematical operations on strings, even if the strings look like numbers, so the following
are illegal:
'2'-'1'
'eggs'/'easy'
'third'*'a charm'

There are two exceptions, + and *


>>> first = 'throat'
>>> second = 'warbler'
>>> first + second
'throatwarbler'
>>> print('Spam'*3)
SpamSpamSpam
>>>

*Note: + used for string concatenation


* used for string repetition

2.4.2 Checking Object Types


• Check type of the object literal "Hello"
>>> type("Hello")
<class 'str'>

• Check type of the object literal 10


>>> type(10)
<class 'int'>

• Check type of the object literal 10.0


>>> type(10.0)
<class 'float'>

• Check type of variable x currently refers to


>>> x = (38+50+21)/3
>>> x
36.333333333333336
>>> type(x)
<class 'float'>

What is the most appropriate variable data type to store each of the following items?
1. The number of students in a class ==> int
2. The height of a person in meters ==> float

01204111 Computers and Programming, 25


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3. A student's family name ==> string
4. A person's national ID ==> string
5. Your friend's mobile phone number ==> string
6. Your letter grade for this course ==> string
7. Your grade point for this course ==> float

2.4.3 Printing Quotes


• To print a text containing quote characters such as the following statement will NOT work.
print('He said, 'Goodbye.'')

The reason is the second appearance of the quote (') indicates the end of the string 'He said,'

• We can use double quotes in place of single quotes


print("He said, 'Goodbye.'")

or
print('He said, "Goodbye."')

• Python allows various kinds of quotes to create a string literal:


◦ single quotes ('...')
◦ double quotes ("...")
◦ triple single quotes ('''...''')
◦ triple double quotes ("""...""")
Triple quotes also allow strings to contain multiple lines.

Examples:
>>> s1 = "String with ' inside"
>>> s2 = 'String with " inside'
>>> s3 = """String with both ' and " inside"""
>>> s4 = '''Another string with both ' and " inside'''
>>> s5 = """This form also supports multiple lines.
Like this."""
>>> print(s1)
String with ' inside
>>> print(s2)
String with " inside
>>> print(s3)
String with both ' and " inside
>>> print(s4)
Another string with both ' and " inside
>>> print(s5)
This form also supports multiple lines.
Like this.
>>>

01204111 Computers and Programming, 26


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
2.4.4 Integer and Floating-Point Division
• is integer division, when dividing two integers (whole numbers) the result is also a whole number.
//

Similar to a long division taught in primary school. Also, the fraction part is discarded.
• / is floating point division.
• % is division remainder.

Examples:
10/4 = 2.5
10//4 = 2 (not 2.5)
10//5 = 2 (not 2.0)
10/5 = 2.0
10%3 =1
10.0%3 = 1.0

2.5 Input Statement


We use input() function to read input from the keyboard. This function returns a string value.
For example:
celcius = input()

This is equivalent to giving a command 'Hey! Please ask input from the user and refer to it with the variable
celsius'. This will wait for the user to enter a value from the keyboard.

Input Statement Syntax:


- Basic command:
variable_name = input()

- Print a string, then immediately prompt the user to enter a value (the cursor will be on the same line
after the string)
variable_name = input(string)

- For example, suppose we run input() and the user enters 25.
>>> celcius = input('Enter temp: ')
Enter temp: 25

01204111 Computers and Programming, 27


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The above output shows that the program prompts the user to enter a value, and 25 is entered.
- input() returns a string, which cannot directly be added to a number. We will get the following

response after we run the following statement.


>>> print(celsius+273.15)
Traceback (most recent call last):
File "<stdin>", line 1, in
<module>TypeError: must be str, not int

This means we cannot add string and int together.


input() function returns a string. Even though that value looks like a number to you, but to Python,

it’s a string, NOT a number. So, it cannot be added to a number. Therefore, we must convert a string
to a number before using + operator. Besides, to use + operator, data must have the same type.

Converting String to Numeric Types


Functions that converting string to numeric type are available for both float and int data types
- float(s) converts the string s into a float (a number with a fraction)
gpa = float('3.14');

- int(s) converts the string s into an int (integer)


age = int('21');

Consider the following statements that perform input operations:


>>> celsius_str = input()
42.1
>>> celsius = float(celsius_str)
>>> type(celsius_str)
<class 'str'>
>>> type(celsius)
<class 'float'>

Let’s break it down. Suppose that the user enters 42.1 via keyboard. The Type of celsius_str is string. After
that, the data is converted to float by float(celsius_str) function and assigned to the variable name
celsius.

2.6 Output Formatting


We can compose a string and values in variables on the same line of output. In Python 3, we can use
f-string formatting which allows a string and values in variables (contained in {}) to be in the same line as
follows.

01204111 Computers and Programming, 28


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
width = 30
height = 60
print(f'Size = {width} x {height}')

The response (output) will be;


Size = 30 x 60

f-string allows more complex expressions.


import math
radius = 8.2
print(f"The circle's area is {radius*radius*math.pi:.2f}.")

Output:
The circle's area is 211.24.

Note: Please use :.2f to specify that you want to display the float number with 2 decimal places.

However, very complex expressions should be avoided. Keep in mind that readability counts, so it’s better to
re-write the above codes as follows.
import math
radius = 8.2
area = radius*radius*math.pi
print(f"The circle's area is {area:.2f}.")

An expression inside {} may be followed by a formatting specification that controls the length, precision
(decimal places), and alignment of the expression's displayed value. The following program prints the value
of 200/3 with different numbers of decimal places and alignments.
x = 200/3
print(f"Value of x is [{x}]") # default formatting
print(f"Value of x is [{x:<10.3f}]") # left-aligned, 10-letter wide, 3 decimal places
print(f"Value of x is [{x:^10.3f}]") # center-aligned, 10-letter wide, 3 decimal places
print(f"Value of x is [{x:>10.3f}]") # right-aligned, 10-letter wide, 3 decimal places
print(f"Value of x is [{x:>10.6f}]") # right-aligned, 10-letter wide, 6 decimal places
print(f"Value of x is [{x:>5.1f}]") # right-aligned, 5-letter wide, 1 decimal place

Output:
Value of x is [66.66666666666667]
Value of x is [66.667 ]
Value of x is [ 66.667 ]
Value of x is [ 66.667]
Value of x is [ 66.666667]
Value of x is [ 66.7]

01204111 Computers and Programming, 29


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
2.7 Exercise

1) Complete the following variable assignment in the blank (A) so that it gives the output as shown.
>>> text1 = ____(A)______
>>> print(text1)
"print" is a function.

2) Complete the following variable assignment in the blank (A) so that it gives the output as shown.
>>> text2 = ____(A)______
>>> print(text2)
"That's good," he said.

3) Compute the number of whole minutes and remaining seconds from the specified total number of
seconds defined in the variable total_seconds by entering expressions with appropriate division
operators in the blanks (A) and (B). (Your expression MUST work with any value of total_seconds.)
>>> total_seconds = 381
>>> minutes = _____(A)_____
>>> seconds = _____(B)_____
>>> print(minutes)
6
>>> print(seconds)
21

4) Write a program that takes the number of seconds passed and displays the same amount of time in
hours, minutes, and seconds.
Output Example 1:
How many seconds? 378
That equals 0 hour(s) 6 minute(s) and 18 second(s).

Output Example 2:
How many seconds? 8000
That equals 2 hour(s) 13 minute(s) and 20 second(s).

Hint: Use the operators // (integer division) and % (remainder after division).

01204111 Computers and Programming, 30


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3. Subroutines – Part 1
Outline:
3.1 Subroutine concept
3.2 Built-in functions and standard modules
3.3 Composition
3.4 Defining functions
3.5 Parameters and arguments
3.6 Seeking and providing help
3.7 Exercise

3.1 Subroutine concept

A subroutine is a sequence of one or more actions grouped into a single task. The task won't be performed
until the subroutine itself is used. E.g.
• The smart television which has the function to watch YouTube, will not show any YouTube video
clip until you click or push the “YouTube” button on the remote control.
Subroutines are also known by other names like subroutines, functions, method, or procedures.
print(82+64+90+75+33)
print('Hello')
val = input()

These are parts of the Python’s built-in functions, they are readily available to use. Functions are always
followed by parentheses. Within parentheses, It may contain argument(s) of the function. Note that, a
function may have no argument or 1 or more argument. From the above Python program, 82+64+90+75+33
and 'Hello' are arguments of print function, but input function (input()) does not have any argument.

3.2 Built-in functions and standard modules


3.2.1 Essential built-in functions
Some examples of built-in functions:

01204111 Computers and Programming, 31


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
abs() float() input() int()
len() list() max() pow()
print() range() round() sum() type()

No need to remember all of these now. We will eventually learn how to use them later. For each function,
you need to learn how to use it, i.e. what argument(s) to send.

3.2.2 Function
Function usually has input(s) and/or output(s). For example, in math, suppose you have a math function
(not Python) f(x) defined as follows;
f(x) = 2x + 1.
This means x is an input to the function f(x), and the function produces a result (output) of the expression 2x
+ 1.

3.2.3 Calling a Function


In Temperature Conversion task, we call the function float() to convert a string to a number as follows.
celsius_str = input()
celsius = float(celsius_str)

Task: Phone Bill


Long-distance rate for a domestic call is 2 baht/minute, while a fraction of a minute is charged as a whole
minute. For example,
• 1 minute call: charge rate is 2 baht
• 3 minute call: charge rate is 6 baht
• 5.2 minute call: charge rate is 12 baht
Write a program that asks the user how many seconds is used for the call. Then computes the total charge
for the call.

Ideas: At first, the problem looks like a typical division problem. However, the fraction of the result must not
be discarded this time but will be rounded up to the nearest integer. E.g., 3 is rounded up to 3, while 3.1 is
rounded up to 4. From the problem, let x represent the call length in minutes. This mean, we want to know
the smallest integer that is larger or equal to x. Mathematically, we are computing the ceiling of x.

⌈𝑥𝑥⌉

01204111 Computers and Programming, 32


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Steps:
BEGIN

Read minutes from user

Compute rounded_minutes = ⌈𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚⌉

Compute charge = 2 × 𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟_𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚

Report charge on screen

END

Program:
1: import math
2: minutes_str = input('Enter call length in minutes: ')
3: minutes = float(minutes_str)
4: rounded_minutes = math.ceil(minutes)
5: charge = 2*rounded_minutes
6: print(f'Charge is {charge:.2f} Baht.')

import math imports the math module that contains additional mathematical functions. Line 3, the
expression math.ceil(minutes) is evaluated to ⌈𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚𝑚⌉ .

3.2.4 Math Module


In addition to built-in functions, Python provides many mathematical functions and constants in the math
module. Some common functions and constants are:

01204111 Computers and Programming, 33


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Expression Evaluated to Remark

math.ceil(x) ⌈𝑥𝑥⌉ compute smallest integer larger or equal to x

math.floor(x) ⌊𝑥𝑥⌋ compute largest integer smaller or equal to x


math.cos(x) cos(x) compute cosine of angle x in radians
math.sin(x) sin(x) compute sine of angle x in radians

math.degrees(x) 180𝑥𝑥/𝜋𝜋 convert angle x from radians to degrees


math.radians(x) 𝑥𝑥𝑥𝑥/180 convert angle x from degrees to radians angle x from degrees to radians

math.sqrt(x) 𝑥𝑥 compute square-root of x

math.pi 𝜋𝜋 yield the value of 𝜋𝜋 (approx. 3.14159)


math.e 𝑒𝑒 yield the value of 𝑒𝑒 (approx. 2.71828)

Examples:
>>> import math
>>> math.fabs(-12.34)
12.34
>>> math.ceil(3.29)
4
>>> math.floor(3.29)
3
>>> math.cos(math.pi/4)
0.7071067811865476
>>> math.pow(5,3)
125.0
>>> math.sqrt(2)
1.4142135623730951
>>> math.exp(1)
2.718281828459045
>>> math.log(4)
1.3862943611198906
>>> math.log10(100)
2.0
>>> math.log(8,2)
3.0
>>> math.pi
3.141592653589793
>>> math.e
2.718281828459045

01204111 Computers and Programming, 34


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Two ways of importing
• Importing a module as a whole, names inside are accessed via the module name.
import math
value = math.cos(math.pi/2)

• Importing only specified names inside a module. These imported names can be used directly.
from math import cos, pi
value = cos(pi/2)

Task: Bring Turtle Home


Our little robotic turtle is lost in the field. Please help guide him from his location at (0,0) to his home at
(x,y). He cannot walk very fast, so we must head him to the right direction so that he can walk with the
shortest distance. Write a program to take the values x and y, then report the values of θ and distance.

Ideas:
We need to analyze the relationship among all the variables to solve the two unknowns.
From Pythagorean theorem (x,y)

𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑒𝑒 2 = 𝑥𝑥 2 + 𝑦𝑦 2

And from Trigonometry y

𝑦𝑦
𝑡𝑡𝑡𝑡𝑡𝑡 𝜃𝜃 =
𝑥𝑥
θ
Therefore,
(0,0) x
𝑦𝑦
𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑 = �𝑥𝑥 2 + 𝑦𝑦 2 and 𝜃𝜃 = arctan
𝑥𝑥

Radians vs. Degrees


In most programming languages, the unit of angles used by trigonometry functions is radians, not
degrees. A full circle (360 degrees) is 2π radians. In Python, we can use math.radians() and
math.degrees() to convert between radians and degrees.

>>> math.degrees(math.asin(1))
90.0

01204111 Computers and Programming, 35


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program:
import math
x = float(input('Enter x: '))
y = float(input('Enter y: '))
distance = math.sqrt((x*x) + (y*y))
heading = math.degrees(math.atan(y/x))
print(f'Heading: {heading:.2f} degree')
print(f'Distance: {distance:.2f} units')

3.3 Composition
Some functions return a value, which can be used as part of an expression. Also is an argument of another
function.
As part of an expression of the following program:
rounded_minutes = math.ceil(minutes)
charge = 2*rounded_minutes

From the above program, the variable rounded_minutes contains the rounded-up value of minutes. After
that, it is multiplied by 2. Therefore, we can revise/shorten the above program as follows:
charge = 2*math.ceil(minutes)

Function that has a value can also be part of an argument of another function:
minutes_str = input('Enter call length in minutes: ')
minutes = float(minutes_str)

Thus, we can revise/shorten the above program as follows:


minutes = float(input('Enter call length in minutes: '))

From now on, we will write the input statement this way when reading a number.

Task: Savings Account


When you have a savings account, the bank usually deposits interest back into your account every year. You
would like to know how much money you will have after a certain number of years. Write a program that
requires the user to input the principal, rate (%), and years, then generates the output which is the amount
the user will have after the specified number of years.
Ideas:
Let us analyze the relationship among the amount in the account, principal (p), rate (r), and years (n). The
table shows the method of calculating compound interest.

01204111 Computers and Programming, 36


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Year Amount

0 𝑝𝑝

𝑟𝑟
1 𝑝𝑝 �1 +
100

𝑟𝑟 𝑟𝑟 𝑟𝑟 2
2 𝑝𝑝 �1 + � �1 + � = 𝑝𝑝 �1 + �
100 100 100

𝑟𝑟 2 𝑟𝑟 𝑟𝑟 3
3 𝑝𝑝 �1 + � �1 + � = 𝑝𝑝 �1 + �
100 100 100

: :
𝑟𝑟 𝑛𝑛
It follows that on nth year, the amount will be 𝑝𝑝 �1 + 100�

Steps:
BEGIN

Read principal, rate, and years from user

𝑦𝑦𝑦𝑦𝑦𝑦𝑦𝑦𝑦𝑦
Compute amount = 𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝𝑝 �1 + 𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟
100

Report amount on screen

END
Program:
import math
principal = float(input('Principal (Baht): '))
rate = float(input('Rate (% per year): '))
years = int(input('Time (years): '))
amount = principal * math.pow(1 + rate/100, years)
print(f'Amount: {amount:.2f}')

Note: expression math.pow(1 + rate/100, years) has the same meaning as (1 + rate/100)**years

01204111 Computers and Programming, 37


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3.4 Defining functions
3.4.1 Defining your own function
Python lets you use and also define your original functions. We group up a number of
statements/computations together and then give them a name. This enables the reuse of these statements
(just like we use built-in functions). By using your own functions, the program is shorter by eliminating
repetitive codes, easier to understand, and less error-prone. Besides, If a change is needed, you can make it in
one place.

Simple Function Definition


1: def my_hello(parameter_name):
2: print(f'Hello, {name}.')
3: my_hello('Jon Snow')

• def (in line 1) is the Python keyword that means, I am defining a function.
• The name of your defined function (e.g. my_hello in line 1) follows the naming rules.
• You can define parameters (e.g. parameter_name in line 1) of your defined function as many as
you need.
• The statement my_hello('Jon Snow') (in line 3) calls your defined function.
• Note that, functions must be defined before use.

3.4.2 Function Declaration Syntax

header def function_name(...):


...
body ...
statements
...

Very important: space in front of every statement must be the same.


- Right after function_name, you can define 0 or more parameter names in the parentheses.

Task: Circle Area


The program will ask the user to input the radius value of a circle. After that, calculate the circle’s area and
then print the resulting circle’s area to screen.

01204111 Computers and Programming, 38


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Ideas:
Firstly, you need to know what is the radius of the underlying circle. Then compute the circle’s area from the
following formula:

area = π × radius × radius

Finally, show the result to the screen.


Steps:
• Tell the user to input the radius to the program.
• Get the input radius from the user
• Calculate the Area
area = π × radius × radius
• Print the resulting Area

Program 1:
1: radius = float(input('Enter a radius: '))
2: area = math.pi*radius**2
3: print('Area of a circle with radius
{radius} is {area:.2f}')

Start

Enter a radius:

radius = …

2
area = π × radius

Print result

End

Program 1 is the program that computes the circle’s area without any defining functions. The flowchart of the
program is shown above.

01204111 Computers and Programming, 39


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program 2:
1: def compute_circle_area():
2: radius = float(input('Enter a radius: '))
3: area = math.pi*radius**2
4: print(f'Area of a circle with radius {radius} is {area:.2f}')
5: compute_circle_area()

Program 2 is the program that has the original new defining function compute_circle_area() without
parameter (shown in line 1 to line 4). Then, in line 4, the statement compute_circle_area() calls the
defined function. The flowchart of the program is shown as follows.

Enter a radius:
Start
radius = …
Call the function compute_circle_area
2
area = π × radius

End
Print result

3.4.3 Function Names


Follow the conventions for creating an identifier.

Examples:
def compute_circle_area(...):
...
...
statements
...

Example of function name:


calculate_sales_tax()
assign_section_number()
display_results()
convert_input_value()

01204111 Computers and Programming, 40


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3.4.4 Flow of Execution
When executing the following program:

def compute_circle_area() :
radius = float(input('Enter a radius: '))
1 3 area = math.pi*radius**2
print(f'Area of a circle with radius {radius} is {area:.2f}')

2 compute_circle_area()

1. Function compute_circle_area() is defined.


2. Main part of the user program, also called main program is calling function compute_circle_area().
3. Statements within the function are executed

3.5 Parameters and arguments


3.5.1 Returning a Value
Function can return a value. Let’s recall a built-in function float()
celsius = float('35')

In the above statement, the argument '35' (type String) is sent to a built-in function float(). After that,
function float() returns a float value that equal to 35.0. Finally, 35.0 is stored in a variable celsius. In
other words, the term float('35') is equal to 35.0. You can write your own function that returns a value by
using return keyword.

Program 3:
1: def compute_circle_area(radius):
2: circle_area = math.pi*radius**2
3: return circle_area
4:
5: r = float(input('Enter a radius: '))
6: area = compute_circle_area(r)
7: print(f'Area of a circle with radius {r} is {area:.2f}')

In program 3, a value in circle_area (in line 3) is returned to the main program and then stored in the
variable area (in line 6). The flowchart of the program is shown as follows.

01204111 Computers and Programming, 41


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Start

Input radius from user

2
Call the function compute_circle_area area = π × radius

Print result

End

Program 4:
1: def compute_circle_area(radius):
2: return math.pi*radius**2
3:
4: r = float(input('Enter a radius: '))
5: area = compute_circle_area(r)
6: print(f'Area of a circle with radius {r} is {area:.2f}')

In program 4, you will see a little change in the content of function compute_circle_area(radius). The
statement circle_area = math.pi*radius**2 in program 3 is disappear. This means the result of expression
math.pi*radius**2 (in line 2) is returned to the main program and then stored in the variable area (in line

5).

3.5.2 Passing Parameters


Mechanism of copying the value from an argument to its corresponding parameter is shown as follows:

def compute_circle_area(radius):

... parameter
}

r = float(input("Enter a radius: "))


area = compute_circle_area(r)

argument

01204111 Computers and Programming, 42


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3.6 Seeking and providing help

The built-in help() function can be used in the shell to provide more details about any object as shown in
the following pictures:

Providing help with docstring


A docstring can be added at the beginning of a function to be shown by the help() function.

def compute_circle_area(radius):
"""
Compute and return the area of a circle docstring
with the specified radius
"""
return math.pi*radius**2

01204111 Computers and Programming, 43


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3.7 Exercise
1) Execute each command in the shell and confirm the result.
>>> len("Hello, Python!")
__________
>>> pow(3,5)
__________
>>> 3**5
__________
>>> q,r = divmod(135,60)
>>> q
__________
>>> r
__________

2) Complete the following program in the blank (A) so that it computes the value of �𝑥𝑥 2 + 𝑦𝑦 2 +𝑧𝑧 2 and
stores the result in the variable distance, then prints it out. The variables x, y, and z are already
defined.
import math
x,y,z = 8,4,3
_____(A)______
print(distance)

01204111 Computers and Programming, 44


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3) Write a program that takes a circle's radius from the user, then reports the area and the
circumference of the circle with two decimal places.
Requirements: You MUST define two functions: circle_area(r) and circle_circumference(r) that
return the area and the circumference of a circle of radius r, respectively.

Output Example 1:
Enter circle radius: 10
The circumference of the circle is 62.83
The area of this circle is 314.16

Output Example 2:
Enter circle radius: 38.1
The circumference of the circle is 239.39
The area of this circle is 4560.37

Output Example 3 (Shell Mode):


>>> circle_area(83)
21642.431790580085
>>> circle_circumference(55)
345.57519189487726

Hints
1. The circumference of a circle of radius r is 2𝜋𝜋𝜋𝜋.
2. The area of a circle of radius r is 𝜋𝜋𝑟𝑟 2 .

01204111 Computers and Programming, 45


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
4 Subroutines – Part 2

Outline:
4.1 Local and global variables
4.2 Multiple returned values
4.3 Calling functions with positional and named arguments
4.4 Exercises

4.1 Local and global variables

Task: Circle Area - Revisited


From the following program for the circle’s area calculation in the previous chapter.
1: import math
2:
3: def compute_circle_area(radius):
4: circle_area = math.pi*radius**2
5: return circle_area
6:
7: r = float(input("Enter a radius: "))
8: area = compute_circle_area(r)
9: print(f"Area of the circle is {area:.2f}")

Let’ try to add the statement print(circle_area) to the above program (into line 11 in the following
program).

1: import math
2:
3: def compute_circle_area(radius):
4: circle_area = math.pi*radius**2
5: return circle_area
6:
7: r = float(input("Enter a radius: "))
8: area = compute_circle_area(r)
9: print(f"Area of the circle is {area:.2f}")
10:
11: print(circle_area)

Then, an error as shown below will occur.

01204111 Computers and Programming, 46


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The reason why the error occurred: variable circle_area is only locally known to the function
compute_circle_area(). Thus, using variable circle_area at line 11 which is outside the function

compute_circle_area() cannot be done.

4.1.1 Local vs. Global Variables


In Python, a variable defined inside a function can only be used inside that function.

1: def function1():
2:  x = 300
3: print(f"Inside function1(): x = {x}")
4:
5:  x = 50
6: function1()
7: print(f"Outside function1(): x = {x}")

x at  (in line 2) is called a local variable of function1()


x at  (in line 5) is called a global variable

These two x's are different variables. x in function1() can only be used inside its function and has a value of
300. Thus, the output of the above program shown as follows.

Note that, a variable that is referenced, but not defined inside a function is considered a global variable
(variable x in line 2 in the following program). However, these variables are read-only by default.

01204111 Computers and Programming, 47


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: def function1():
2: print(f"Inside function1(): x = {x}")
3:
4: x = 50
5: function1()
6: x = 80
7: function1()

The output of the above program shown as follows:

Reason: after function1() is called at line 5, variable x in line 2 is then referenced, but at this moment x is
not defined inside function1() yet. Thus, x is considered a global variable which has a value of 50 (which
has already been assigned at line 4). Therefore, a statement “print(f"Inside function1(): x = {x}") in
line 2, then outputs “Inside function1(): x = 50”.

4.1.2 Online execution


The web http://pythontutor.com provides an excellent visualization tool for code execution. Click "Start
visualizing your code now" and try to paste the code from the example in the box. Then, click “Next” or
“Prev” to see the output and also the behavior of the program step by step.

01204111 Computers and Programming, 48


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Task: Flat Washers
You work for a hardware company that manufactures flat washers. To estimate shipping costs, your company
needs a program that computes the weight of a specified quality of flat washers.

Ideas:
A flat washer resembles a small donut (see the figure). To compute the weight of a single flat washer, you
need to know its rim area, thickness, and density of the material. Here, we can reuse compute_circle_area()
function.

Requirements:
- The radius of the flat washer (outer radius) and
the radius of the hole (inner raduis)
- Thickness
- Density
- Quantity
We will assume that the material used is aluminum, whose density is well-known.

Steps:
1. Get the flat washer’s outer radius, inner radius, thickness, and quantity.
2. Compute the weight of one flat washer
unit_weight = rim_area × thickness × density

3. Compute the weight of the batch of washers


total_weight = unit_weight × quantity

4. Print the resulting weight of the batch

01204111 Computers and Programming, 49


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Start

Read Input for outer_radius, inner_ radius,


thickness and quantity

Call FlatWasherWeight to calculate weight

Calculate the total weight

Print result

End

Program:
1: import math
2:
3: MATERIAL_DENSITY = 2.70
4:
5: def compute_circle_area(radius):
6: return math.pi*radius**2;
7:
8: def flat_washer_weight(outer_r,inner_r,thickness):
9: rim_area=compute_circle_area(outer_r)-compute_circle_area(inner_r)
10: return rim_area*thickness*MATERIAL_DENSITY
11:
12: outer_radius = float(input('Enter the outer radius (cm.): '))
13: inner_radius = float(input('Enter inner radius (cm.): '))
14: thickness = float(input('Enter thickness (cm.): '))
15: quantity = int(input('Enter the quantity (pieces): '))
16: unit_weight = flat_washer_weight(outer_radius,inner_radius,thickness)
17: total_weight = unit_weight * quantity
18: print(f'Weight of the batch is {total_weight:.2f} grams')

Note: The variable MATERIAL_DENSITY (in line 3) is defined and used as a global variable.

Output Example:

01204111 Computers and Programming, 50


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
4.2 Multiple returned values

Task: Average of Three


The program will ask three integer input values from the user, calculate the average of those three values,
and then print the result to the screen.

Ideas:
Need to know the three integer values, i.e. val1, val2, val3
Compute the average.
average = (val1 + val2 + val3)/3

Show the result to the screen.

Steps:
1. Get input three input integer values from the user.
2. Calculate the average.
average = (val1 + val2 + val3)/3

3. Print the resulting average.


Start

Read val1, val2, and val3

Call Average3 to calculate average

Print result

End

01204111 Computers and Programming, 51


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program #1:
1: def average3(x, y, z):
2: return (x+y+z)/3;
3:
4: # read three integers
5: val1 = int(input('1st value: '))
6: val2 = int(input('2nd value: '))
7: val3 = int(input('3rd value: '))
8:
9: # compute and output their average
10: average = average3(val1, val2, val3)
11: print(f'average is {average:.4f}')

Output Example:

4.2.1 Returning Multiple Values


A function can return multiple values by separating them by comma sign (‘,’). Values must be assigned the
same number as the return values.

def Read3Integers():

...
return x, y, z

send to

val1, val2, val3 = Read3Integers()

Program #2:
1: def read_3integers():
2: # read three integers
3: a1 = int(input("1st value: "))
4: a2 = int(input("2nd value: "))
5: a3 = int(input("3rd value: "))
6: return a1, a2, a3
7:
8: def average3(x, y, z):
9: return (x+y+z)/3
10:
11: val1, val2, val3 = read_3integers()
12: # compute and output their average
13: print(f"average is {average3(val1, val2, val3):.4f}")

01204111 Computers and Programming, 52


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
In program #2. After function read_3integers() in line 11 is called, function read_3integers() will get input
from user and assign to variables a1, a2, a3. After that, function read_3integers() returns the value of
variables a1, a2, a3 in line 6 to variables val1, val2, val3 in line 11, respectively. Specifically, the value
of a1 is returned to val1, the value of a2 is returned to val2, and the value of a3 is returned to val3.

Task: Trapezoid
In Euclidean geometry, a convex quadrilateral with at least one pair of parallel sides is referred to as a
trapezoid. (ref: https://en.wikipedia.org/wiki/Trapezoid)
a

h a+b
𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎 = ℎ
2

b
Steps:
1. Get three double values from the user:
- (parallel) side1
- (parallel) side2
- height
2. Calculate the trapezoid area.
area = ((side1 + side2)/2) × height
3. Finally, Print the resulting area.

Start

Read side1, side2, and height

Call TrapezoidArea to calculate area

Print result

End

01204111 Computers and Programming, 53


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program:
1: def read_trapezoid():
2: print("Enter the properties of your trapezoid.")
3: a = float(input("Length of parallel side 1: "))
4: b = float(input("Length of parallel side 2: "))
5: h = float(input("Height: "))
6: return a,b,h
7:
8: def trapezoid_area(a,b,h):
9: return 0.5*(a+b)*h
10:
11: # main program
12: a,b,h = read_trapezoid()
13: area = trapezoid_area(a,b,h)
14: print(f"Trapezoid's area is {area:.2f}")

Output Example:

Task: Triangle Area (Heron)


In geometry, Heron's formula (sometimes called Hero's formula), named after Hero of Alexandria, gives the
area of a triangle by requiring no arbitrary choice of the side as base or vertex as origin, contrary to other
formulas for the area of a triangle, such as half the base times the height. Write a program to calculate the
area of a triangle by using Heron’s formula when x-y coordinate of the triangle’s 3 vertices are given as an
input. (ref: https://en.wikipedia.org/wiki/Heron’s_formula)
(x2, y2)

(x3, y3) (x1, y1)

Heron's formula states that the area of a triangle whose sides have lengths a, b, and c is

𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎 = �𝑠𝑠(𝑠𝑠 − 𝑎𝑎)(𝑠𝑠 − 𝑏𝑏)(𝑠𝑠 − 𝑐𝑐)

where s is the semi perimeter of the triangle; that is,


𝑎𝑎 + 𝑏𝑏 + 𝑐𝑐
𝑠𝑠 =
2

01204111 Computers and Programming, 54


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Step and ideas:
• Get the x-y coordinate of the triangle’s 3 vertices.
• Calculate the length of the lines a, b, and c which are connected to those 3 vertices.
• Calculate the semi perimeter.
• Calculate the triangle’s area using the Heron’s formula.
• Print the resulting area.

Program:
1: import math
2:
3: def line_length(x1, y1, x2, y2):
4: """
5: Given X-Y coordinates of 2 points, compute the line length that
6: joins them
7: """
8: return math.sqrt((x1-x2)**2+(y1-y2)**2);
9:
10: def triangle_area(x1, y1, x2, y2, x3, y3):
11: """
12: Given the 3 vertices, compute triangle area using Heron's Formula
13: """
14: a = line_length(x1, y1, x2, y2)
15: b = line_length(x2, y2, x3, y3)
16: c = line_length(x3, y3, x1, y1)
17: s = (a+b+c)/2
18: return math.sqrt(s*(s-a)*(s-b)*(s-c))
19:
20: def read_coordinates():
21: x = float(input("x? "))
22: y = float(input("y? "))
23: return x,y
24:
25: def read_triangle():
26: """
27: Read X-Y co-ordinates of 3 vertices of a triangle
28: """
29: print("Enter X-Y coordinates of the three vertices of triangle:")
30: print("1st vertex:")
31: x1,y1 = read_coordinates()
32: print("2nd vertex:")
33: x2,y2 = read_coordinates()
34: print("3rd vertex:")
35: x3,y3 = read_coordinates()
36: return x1,y1,x2,y2,x3,y3
37:
38: # main program
39: x1,y1,x2,y2,x3,y3 = read_triangle()
40: area = triangle_area(x1,y1,x2,y2,x3,y3)
41: print(f"area of the triangle is {area:.2f}")

01204111 Computers and Programming, 55


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
In this program, we start with the main program (from line 39 to line 41) that shows simple steps and ideas of
the whole program. Firstly, read x-y co-ordinates of the three vertices of the triangle by calling function
read_triangle(). Then, use function triangle_area() (from line 10 to line 18) to calculate the triangle area

by using Heron’s formula. In this function, function line_length() (from line 3 to line 8) is called to
compute line length between each two x-y coordinates, then by using those line length, the triangle area is
calculated and returned back to the variable area. Finally, the result is output on the screen.

Output Example:

4.3 Calling functions with positional and named arguments

4.3.1 Positional & Named Arguments


When you call a function, you need to know the parameters that the function takes, i.e. the number of
arguments as well as the order. In addition, you may need to know the unit, i.e. sin() or cos() uses radians,
not degrees. Note that, you don’t have to remember all details because you can use help() function to
inquire about that information.

So far, when we call a function, arguments are arranged in the order according to the parameters called
“positional arguments”
def trapezoid_area(a, b, h):
return 0.5*(a+b)*h;

The above function is currently called by the following statement.


area = trapezoid_area(side1,side2,height)

01204111 Computers and Programming, 56


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Notice that the positions of arguments match the positions of parameters. Specifically, argument side1
matches with parameter a, argument side2 matches with parameter b, and argument height matches with
parameter h, respectively.
Another way, “named arguments” can be used so that positions do not need to match as shown in the
following statement.
area = trapezoid_area(h=height,a=side1,b=side2)

4.4 Exercises
1) Complete the following program by filing code in the blank (A), so that it can correctly compute the
amount of Thai Baht corresponding to the given USD amount based on the current exchange rate in
the global variable EXCHANGE_RATE.
def usd_to_thb(usd):
_______(A)________

EXCHANGE_RATE = 34.09
print(f"The current exchange rate is {EXCHANGE_RATE} THB per USD")
print(f"You get {usd_to_thb(100):.2f} Thai Baht for 100 USD")

EXCHANGE_RATE = 33.15
print(f"The current exchange rate is {EXCHANGE_RATE} THB per USD")
print(f"You get {usd_to_thb(100):.2f} Thai Baht for 100 USD")

EXCHANGE_RATE = 35.26
print(f"The current exchange rate is {EXCHANGE_RATE} THB per USD")
print(f"You get {usd_to_thb(100):.2f} Thai Baht for 100 USD")

Output:
The current exchange rate is 34.09 THB per USD
You get 3409.00 Thai Baht for 100 USD
The current exchange rate is 33.15 THB per USD
You get 3315.00 Thai Baht for 100 USD
The current exchange rate is 35.26 THB per USD
You get 3526.00 Thai Baht for 100 USD

2) Define a function rectangle_area_and_perimeter(length,width) that takes the length and width of


a rectangle, then computes and returns the area and the perimeter of the rectangle, respectively.
(Notes: beware of indentation.)

01204111 Computers and Programming, 57


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
def rectangle_area_and_perimeter(length,width):
____________________
____________________
____________________

def read_rectangle():
length = float(input("Enter rectangle length: "))
width = float(input("Enter rectangle width: "))
return length,width

side1,side2 = read_rectangle()
area,peri = rectangle_area_and_perimeter(side1,side2)
print(f"The area of the rectangle is {area:.2f}")
print(f"The perimeter of the rectangle is {peri:.2f}")

3) BMI (Body Mass Index) can be computed using the formula:


weight
BMI =
height 2

Then, the function to calculate BMI can be defined as follows, where weight is in kilograms,
and height is in meters.
def bmi(weight,height):
return weight/(height**2)

Call the function bmi() by filling blank (A), using named arguments with 63 kg for weight and 1.71
meters for height.
>>> bmi(____(A)______)
21.545090797168363

Hint: Use positional arguments.

01204111 Computers and Programming, 58


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
5 Control structure: Selections

Outline:
5.1 Boolean Expressions
5.2 Operator Precedence in Python
5.3 Fundamental Flow Controls
5.4 Flowcharts
5.5 Basic Selections
5.6 Programming Examples
5.7 Exercises

5.1 Boolean Expressions

5.1.1 Boolean Expressions in general


In Mathematics, a Boolean expression is an expression whose value is either True or False.
• 20 > 10
• 5 is a factor of 153
• 18 is not a prime number and is divisible by 3
• x > 5 or x < -5
Evaluating a Boolean expression is just like answering a yes/no question in human languages:
• Do you want the coffee? (yes/no)
• Have you found the answer? (yes/no)
• Is 20 greater than 10? (yes/no)
• Is 5 a factor of 153? (yes/no)

5.1.2 Boolean Expressions in Python


In Python, a Boolean expression is an expression of type bool, which is evaluated to either True or False.
You can use print() to evaluate a boolean expression and print the result as follows:

01204111 Computers and Programming, 59


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
>>> print(5 > 3)
True
>>> print(5 < 3)
False
>>> print(5 > 3 and 'pig' != 'rat')
True
>>> x = 5
>>> pet = 'pig'
>>> print(x > 3 and pet != 'rat')
True
>>> print(x*2 > 100 or x+2 > 100)
False

In interactive mode, print() can be omitted.


>>> x > 3
True
>>> x > 10 or x < 0
False

True and False are values. So, these values can be assigned to variable as follows:
>>> x = True
>>> y = False
>>> print(x)
True
>>> print(y)
False

Also, you can check their types as the following output examples:
>>> type(True)
<class 'bool'>
>>> type(False)
<class 'bool'>
>>> type(x)
<class 'bool'>

Importance: Python is case-sensitive, so False and false are not the same. Python’s bool constants are
written precisely as:

• True
• False

01204111 Computers and Programming, 60


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Relational operators: they are used to compare two things:

Meaning Operator
Equal ==

Not equal !=

Greater than >

Greater than or equal >=

Less than <

Less than or equal <=

Logical operators: they are used to combine two or more Boolean expressions:

Meaning Operator
Boolean AND and

Boolean OR or

Boolean NOT not

Logical operators calculation:

p q p and q p or q
True True True True
True False False True
False True False True
False False False False

p not p
True False
False True

01204111 Computers and Programming, 61


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Hands-On Examples
>>> i = 10
>>> j = 15
>>> print(j < i)
False

A boolean expression can be assigned to a variable.


>>> r = i+2 >= 10
>>> print(r)
True

Both expressions are logically equivalent.


>>> print((i%2) != 0)
False
>>> print(not ((i%2) == 0))
False

Both expressions are logically equivalent.


>>> print(i+j >= 5 and i+j <= 25)
True
>>> print(5 <= i+j <= 25)
True

Also, you can nest them.


>>> print((not r) or (i > 20 and i <= j))
False

5.2 Operator Precedence in Python


From the highest precedence to the lowest down the table. Operators on the same row have the same
precedence.
Category Operators Associativity
Subscription, call, attribute a[x] f(x) x.attribute left to right
Exponentiation ** right to left
Unary sign +x -x left to right
Multiplicative * / // % left to right
Additive + - left to right
Relational (comparison) == != < > <= >= left to right
Boolean NOT Not left to right
Boolean AND And left to right
Boolean OR Or left to right

01204111 Computers and Programming, 62


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Operator Precedence Examples 1:

The above statement is quale to:


passed = (((i/(j**3))-2) < 10 ) or ((math.sqrt(i*j)) >= 20)

Operator Precedence Examples 2:


>>> 4**2**3
65536
>>> (4**2)**3
4096
>>> 4**(2**3)
65536

In the above examples, the operator ** is right-to-left associative.

5.3 Fundamental Flow Controls


• Sequence
• Subroutine
• Selection (or Branching)
• Repetition (or Iteration or Loop)
5.3.1 Schematic View of Flow Controls
So far, we have already learned about the flow control of Sequence and Subroutine. In this chapter, we
will newly learn about the flow control of Selection.

01204111 Computers and Programming, 63


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Sequence
Repetition

Subroutine Selection

5.4 Flowcharts

The Flowchart is the graphical representation of controls.


Basic flowchart symbols:

Terminator

Process

Input/output

Condition

Connector

Flow line

01204111 Computers and Programming, 64


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Example:

START

nOdd, nEven = 0, 0

True
End of input ? write nOdd, nEven

False
read k END

True False
k%2 == 0

nEven = nEven+1 nOdd = nOdd+1

Figure out what kind of task this flowchart trying to do. Then try to run this flowchart with the input
sequence: 5, 1, 4, 9, 8

5.5 Basic Selections

5.5.1 Basic Selections: if statements

Normal Sequential Flow:


This is the default program flow unless specified otherwise. The sequential flow of the program executes like
a train that runs on the straight track without any branch.

x = int(input())
y = int(input())
print(x+y)
print("Hello",x)
z = x * y + 10
print(z)

01204111 Computers and Programming, 65


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Selection flow with if-statement:
Selection flow is also called conditional execution. The selection flow of the program executes like a train
that runs on the track with a branch that has two paths to go. When the train reaches the branch, which path
to proceed is determined by the result of a condition. As shown in the following picture, if the result of the
condition is true, the train will proceed to the main path. On the other hand, if the result of the condition is
fault, the train will proceed to the other path which acts like a detour path.

height <= 140 True

False

1: price = 40
2: if height <= 140:
3: print('Hello kids!')
4: price = 0
5: print('price =', price)

From the above program, when height is 160, the result of the condition height <= 140 is False. Then, after
line 1 is executed, the program executes like the orange line which skips line 3 and line 4, and executes line
5. On the other hand, when height is 120, the result of the condition height <= 140 is True. Then, the
program executes like the green line which executes all lines in the program.

If Statement:
if statement is used to decide whether a code block is to be executed or not, depending on a condition.
The statements in the code block will be executed only if the condition is True.

01204111 Computers and Programming, 66


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Python Syntax: Semantics:
False
condition

if condition:
True

statement1 statement
statement2 1

...
...
statementn
a code block statement
2

statement
n

• Condition must be a Boolean expression.


• If the condition is True, the statement(s) in the code block will be executed (the code inside the
dotted line square in the above pictures).

Example of the program with if statement:


The MRT provides a free ride to the children under the height of 140 cm. Flow control of the program is
written in the flowchart below.

Program 1: Program without defining a function


price = 40
price = 40

if height <= 140:


print('Hello kids!') height <= 140
price = 0

print('price =', price)

print 'Hello kids!'


Program 2: Program with defining a function
def mrt_fee(height): price = 0

price = 40

if height <= 140:


print('Hello kids!')
price = 0
print price

print('price =', price)

01204111 Computers and Programming, 67


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The flowchart depicted on the right side can represent both programs on the left side. Program 1 which is the
same program as explained in sub-section “Selection flow with if-statement:” in 5.5.1 is written without
defining a function. Then, the contents of program 1 are used as they are for the definition of function
mrt_fee() in program 2.

Output Example of Program 2 (shell mode):


>>> mrt_fee(140)
Hello kids!
price = 0
>>> mrt_fee(150)
price = 40
>>>

Code Blocks:
In Python, a line that ends with : (colon) indicates that the next line starts a new “code block”. A code
block consists of one or more statements that are indented equally deeply from the left. In the example
below, the first code block which has 3 statements is written inside the dotted line square and its indentation
level shown by the dotted line arrow. Then, the second code block which has 2 statements is written inside
the solid line square and its indentation level shown by the solid line arrow.

def mrt_fee(height) :

price = 40

if height <= 140 :

print('Hello kids!')
price = 0

print('price =', price)

Be careful, Python uses the concept of blocks extensively. Thus, you must be very careful about indentation.

01204111 Computers and Programming, 68


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Good example of indentation: Bad example of indentation:
Fdskfjsdlkfslkdjfdsff Fdskfjsdlkfslkdjfdsff
fdskfsdflksdlkfdsf: fdskfsdflksdlkfdsf:

fddslfldskf fddslfldskf

fdsfkdsfdsfd fdsfkdsfdsfd
fdkfddfdfd fdkfddfdfd
fdkfdlf fdkfdlf

fdkfddfdfd fdsfkdsfdsfd
fdkfdlf fdkfddfdf

Pass-statement:
In Python, we cannot have an empty block.

If you want a block that does nothing, use the pass statement.

if height <= 140:


pass
print("I'm here")

Example: Find the larger of two integers.

Step for creating function max_of_two()


• receives two number parameters a and b.
• returns the larger of them.

01204111 Computers and Programming, 69


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program:
max = a
def max_of_two(a, b):
max = a
if b > max: F
max = b b > max
return max
T
max = b
Output Example (shell mode):
>>> max_of_two(2, 3)
3
>>> max_of_two(3, 2) return max
3
>>> max_of_two(3, 3)
3

5.5.2 Basic Selections: if-else statements


Compare between if and if-else statement.

if statement if-else statement

If-else statement:
If-else statement is used to decide whether a code block is to be executed or not, depending on a
condition. In the following phyton syntax code and flowchart semantics, the statements in the code block1
will be executed only if the condition is True, and the statements in the code block2 will be executed only if
the condition is False.

01204111 Computers and Programming, 70


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Python Syntax: Semantics:

if condition: True False


Code Block1 condition
else:
Code Block2
Code Block Code Block
1 2

Note: Do not forget the colons and indentation.

Comparing if statement and if-else statement:

(A) Function max_of_two() using if statement without else.


• uses if statement (without else)
max = a
Program:
def max_of_two(a, b): False
max = a b > max
if b > max:
max = b
True
return max
max = b
Output example:
>>> max_of_two(2, 3)
3
>>> max_of_two(3, 3) return max
3

(B) Function max_of_two() using if-else statement.


• uses if-else statement
True False
a > b

Program Pattern 1:
max = a max = b
def max_of_two(a, b):
if a > b:
max = a
else:
max = b
return max
return max

01204111 Computers and Programming, 71


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program Pattern 2:
def max_of_two(a, b):
if a > b:
return a
else:
return b

Output example ( pattern 1 and pattern 2 of the program have the same output):
>>> print(max_of_two(3,2))
3
>>> max_of_two(3, 2)
3
>>> max_of_two(2, 3)
3
>>> x = 5
>>> max_of_two(3*x, x**2)
25

Note: In interactive mode, print() can be omitted.

Example of if and else code blocks with several statements:


1: def payment(nitems, itemprice):
2: price = nitems*itemprice
3:
4: if nitems > 10:
5: print('You got 10% discount.')
6: price = 0.9*price
7: print(f'You also got {nitems//3} stamps.')
8: else:
9: print('You got 5% discount.')
10: price = 0.95*price
11: print(f'Total payment is {price} baht.')

Output Example:
>>> payment(10, 3)
You got 5% discount.
Total payment is 28.5 baht.
>>> payment(itemprice=5, nitems=20)
You got 10% discount.
You also got 6 stamps.
Total payment is 90.0 baht.
>>>

01204111 Computers and Programming, 72


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
5.6 Programming Examples

Task: Solving quadratic equations


Given the three coefficients a, b, and c of a quadratic equation ax2 + bx + c = 0 where a ≠ 0, find the roots
of the equation. A root is a value of x that satisfies the equation.

Ideas: The roots of a quadratic equation ax2 + bx + c = 0 can be calculated by the formula:

−𝑏𝑏 ± √𝑏𝑏 2 − 4𝑎𝑎𝑎𝑎


x=
2𝑎𝑎

The term b2 − 4ac in the formula is called the discriminant (D) of the equation because it can discriminate
between the possible types of roots. The discriminant D = b2 − 4ac of the equation determines the type of
roots as follows:
−𝑏𝑏+ √𝐷𝐷 −𝑏𝑏 − √𝐷𝐷
• If D > 0, there are two real roots: 2𝑎𝑎
and 2𝑎𝑎
−𝑏𝑏
• If D = 0, there is only one real root: 2𝑎𝑎
−𝑏𝑏 −𝑏𝑏
• If D < 0, there are two complex roots: 2𝑎𝑎 + 𝑖𝑖 √−𝐷𝐷
2𝑎𝑎
and 2𝑎𝑎 − 𝑖𝑖 √−𝐷𝐷
2𝑎𝑎
Now we've got enough information to write the program. Next, we are going to demonstrate a useful,
effective development technique called Incremental Development together with Incremental test.

The main routine:


1. Reads the three coefficients a, b, and c, making sure that a is not zero.
2. Uses a, b, and c to solve and output the roots.

Main Program (main routine):


1: import sys
2: from math import sqrt
3:
4: # ----- main ----- #
5: a, b, c = read_coefficients()
6: if a == 0:
7: print("1st coefficient can't be zero. Program exits.")
8: sys.exit() # exit this running program immediately
9: solve_and_output(a, b, c)

01204111 Computers and Programming, 73


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The supreme commander main usually doesn’t do things itself. It only gives orders.
Then, we add some scaffolding code to be able to test the main routine as follows.
1: import sys
2: from math import sqrt
3:
4: def read_coefficients():
5: print('In read_coefficients:') # dummy code
6: return 1, 2, 3 # dummy code
7:
8: def solve_and_output(a, b, c):
9: print("In solve_and_output:", a, b, c) # dummy code
10:
11: # ----- main ----- #
12: a, b, c = read_coefficients()
13: print('In main: main receives', a, b, c) # dummy code
14: if a == 0:
15: print("1st coefficient can't be zero. Program exits.")
16: sys.exit() # exit this running program immediately
17: solve_and_output(a, b, c)

Test run result:


In read_coefficients:
In main: main receives 1 2 3
In solve_and_output: 1 2 3

Then, in function read_coefficients() in line 6, change a returned value from 1 to 0, as follows.


4: def read_coefficients():
5: print('In read_coefficients:') # dummy code
6: return 0, 2, 3 # dummy code

Test run result:


In read_coefficients:
In main: main receives 0 2 3
1st coefficient can't be zero. Program exits.

The main routine has been tested and it works correctly. Next, we are going to create function
read_coefficients() and solve_and_output() to complete the program.

Reading the inputs (function read_coefficients()):


The function read_coefficients() reads and returns the coefficients a, b and c.
def read_coefficients():
a = float(input('Enter 1st coefficient: '))
b = float(input('Enter 2nd coefficient: '))
c = float(input('Enter 3rd coefficient: '))
return a, b, c

01204111 Computers and Programming, 74


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Then, insert the newly created function read_coefficients() into the previous program as follows.
1: import sys
2: from math import sqrt
3:
4: def read_coefficients():
5: a = float(input('Enter 1st coefficient: '))
6: b = float(input('Enter 2nd coefficient: '))
7: c = float(input('Enter 3rd coefficient: '))
8: return a, b, c
9:
10: def solve_and_output(a, b, c):
11: print("In solve_and_output:", a, b, c) # dummy code
12:
13: # ----- main ----- #
14: a, b, c = read_coefficients()
15: print('In main: main receives', a, b, c) # dummy code
16: if a == 0:
17: print("1st coefficient can't be zero. Program exits.")
18: sys.exit() # exit this running program immediately
19: solve_and_output(a, b, c)

Execute a test run. Then, an example output is shown as follows:


Enter 1st coefficient: 1
Enter 2nd coefficient: 2
Enter 3rd coefficient: 3
In main: main receives 1.0 2.0 3.0
In solve_and_output: 1.0 2.0 3.0

Execute a test run again.


Enter 1st coefficient: 0
Enter 2nd coefficient: 1
Enter 3rd coefficient: 2
In main: main receives 0.0 1.0 2.0
1st coefficient can't be zero. Program exits.

The Solving Engine (the function solve_and_output()):


We are going to finish the function solve_and_output() which is the main solving engine.
Steps:
- Computes the discriminant.
- Uses the discriminant (D) (represented as disc in the function) to select either the function to find
real roots or the one to find complex roots.
• If D ≥ 0, the equation has real root(s). If D < 0, the equation has complex roots.
def solve_and_output(a, b, c):
disc = b*b - 4*a*c
if disc >= 0: # has real roots
compute_real_roots(a, b, disc)
else: # has complex roots
compute_complex_roots(a, b, disc)

01204111 Computers and Programming, 75


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Then, insert the newly created function solve_and_output() into the previous program, and add some new
scaffolds code (dummy code) of functions compute_real_roots() and compute_complex_roots() as shown
in line 17-21.
1: import sys
2: from math import sqrt
3:
4: def read_coefficients():
5: a = float(input('Enter 1st coefficient: '))
6: b = float(input('Enter 2nd coefficient: '))
7: c = float(input('Enter 3rd coefficient: '))
8: return a, b, c
9:
10: def solve_and_output(a, b, c):
11: disc = b*b - 4*a*c
12: if disc >= 0: # has real roots
13: compute_real_roots(a, b, disc)
14: else: # has complex roots
15: compute_complex_roots(a, b, disc)
16:
17: def compute_real_roots(a, b, disc):
18: print("In compute_real_roots:", a, b, disc) # dummy code
19:
20: def compute_complex_roots(a, b, disc):
21: print("In compute_complex_roots:", a, b, disc) # dummy code
22:
23: # ----- main ----- #
24: a, b, c = read_coefficients()
25: if a == 0:
26: print("1st coefficient can't be zero. Program exits.")
27: sys.exit() # exit this running program immediately
28: solve_and_output(a, b, c)

Execute a test run.

- Discriminant is 0 (the equation has real root):


Enter 1st coefficient: 1
Enter 2nd coefficient: -4
Enter 3rd coefficient: 4
In compute_real_roots: 1.0 -4.0 0.0

- Discriminant > 0 (the equation has real root):


Enter 1st coefficient: 2
Enter 2nd coefficient: 1
Enter 3rd coefficient: -1
In compute_real_roots: 2.0 1.0 9.0

- Discriminant < 0 (the equation has complex root):


Enter 1st coefficient: 2
Enter 2nd coefficient: 1
Enter 3rd coefficient: 1
In compute_complex_roots: 2.0 1.0 -7.0

01204111 Computers and Programming, 76


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The function compute_real_roots().
Next, we complete the function compute_real_roots() to computes and prints the real root(s).
Steps:
- Uses the discriminant to select either the formula for one real root or two real roots.
- Computes and outputs the root(s).
def compute_real_roots(a, b, disc):
if disc == 0:
root = -b / (2*a)
print(f'Only one real root: {root}')
else:
root1 = (-b + sqrt(disc)) / (2*a)
root2 = (-b - sqrt(disc)) / (2*a)
print(f'Two real roots: {root1} and {root2}')

Insert the newly created function compute_real_roots() into the previous program, then execute a test run
again.
1: import sys
2: from math import sqrt
3:
4: def read_coefficients():
5: a = float(input('Enter 1st coefficient: '))
6: b = float(input('Enter 2nd coefficient: '))
7: c = float(input('Enter 3rd coefficient: '))
8: return a, b, c
9:
10: def solve_and_output(a, b, c):
11: disc = b*b - 4*a*c
12: if disc >= 0: # has real roots
13: compute_real_roots(a, b, disc)
14: else: # has complex roots
15: compute_complex_roots(a, b, disc)
16:
17: def compute_real_roots(a, b, disc):
18: if disc == 0:
19: root = -b / (2*a)
20: print(f'Only one real root: {root}')
21: else:
22: root1 = (-b + sqrt(disc)) / (2*a)
23: root2 = (-b - sqrt(disc)) / (2*a)
24: print(f'Two real roots: {root1} and {root2}')
25:
26: def compute_complex_roots(a, b, disc):
27: print("In compute_complex_roots:", a, b, disc) # dummy code
28:
29: # ----- main ----- #
30: a, b, c = read_coefficients()
31: if a == 0:
32: print("1st coefficient can't be zero. Program exits.")
33: sys.exit() # exit this running program immediately
34: solve_and_output(a, b, c)

01204111 Computers and Programming, 77


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Execute a test run.

- Discriminant is 0 (one real root):


Enter 1st coefficient: 1
Enter 2nd coefficient: -4
Enter 3rd coefficient: 4
Only one real root: 2.0

- Discriminant > 0 (two real roots):


Enter 1st coefficient: 2
Enter 2nd coefficient: 1
Enter 3rd coefficient: -1
Two real roots: 0.5 and -1.0

- Discriminant < 0 (complex root):


Enter 1st coefficient: 2
Enter 2nd coefficient: 1
Enter 3rd coefficient: 1
In compute_complex_roots: 2.0 1.0 -7.0

The function compute_complex_roots().


For the last function to be completed, the function compute_complex_roots() computes and prints the two
complex roots.

def compute_complex_roots(a, b, disc):


val1 = -b / (2*a)
val2 = abs(sqrt(-disc) / (2*a))
print(f'Two complex roots: {val1}+{val2}i and {val1}-{val2}i')

Then the final program is shown as follows:

01204111 Computers and Programming, 78


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: import sys
2: from math import sqrt
3:
4: def read_coefficients():
5: a = float(input('Enter 1st coefficient: '))
6: b = float(input('Enter 2nd coefficient: '))
7: c = float(input('Enter 3rd coefficient: '))
8: return a, b, c
9:
10: def solve_and_output(a, b, c):
11: disc = b*b - 4*a*c
12: if disc >= 0: # has real roots
13: compute_real_roots(a, b, disc)
14: else: # has complex roots
15: compute_complex_roots(a, b, disc)
16:
17: def compute_real_roots(a, b, disc):
18: if disc == 0:
19: root = -b / (2*a)
20: print(f'Only one real root: {root:.1f}')
21: else:
22: root1 = (-b + sqrt(disc)) / (2*a)
23: root2 = (-b - sqrt(disc)) / (2*a)
24: print(f'Two real roots: {root1:.1f} and {root2:.1f}')
25:
26: def compute_complex_roots(a, b, disc):
27: root1 = (-b / (2*a))
28: root2 = abs(sqrt(-disc) / (2*a)) # change value to positive
29: print(f'Two complex roots: {root1:.1f}+{root2:.1f}i and {root1:.1f}-
{root2:.1f}i')
30:
31: # ----- main ----- #
32: a, b, c = read_coefficients()
33: if a == 0:
34: print("1st coefficient can't be zero. Program exits.")
35: sys.exit() # exit this running program immediately
36: solve_and_output(a, b, c)

Final test run:

01204111 Computers and Programming, 79


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
5.7 Exercises

1) Suppose that the following program has been executed.


x = 7
is_odd = (x%2 == 1)

def divisible_by_7(num):
return num%7 == 0

def too_fast(speed):
return speed > 120

What is the result of each following Boolean expression when run in shell mode?

• x%2 != 1
• is_odd
• divisible_by_7(x)
• divisible_by_7(x+12)
• too_fast(80)
• too_fast(180)

2) A mobile phone company gives you a special discount rate of 1 baht/min for any call of 30 minutes
or longer. Otherwise, when the call duration is less than 30 minutes, the normal rate of 2 baht/min is
applied. Complete the function below by filling blank (A) (B) (C) so that it can correctly compute the
charge of a call of the duration which is given in minutes.
def calling_charge(duration):
if _____(A)_____ :
rate = _____(B)_____
else:
rate = _____(C)_____
return duration*rate

Output Example:
>>> calling_charge(5)
10
>>> calling_charge(20)
40
>>> calling_charge(30)
30
>>> calling_charge(40)
40

01204111 Computers and Programming, 80


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3) The Python Electric Appliance Store sells used TVs, DVD players, and audio systems. All products of
the same kind have the same price as shown in the table below:
Product Price per unit (baht)
TV 3000
DVD player 750
Audio systems 1500

The store offers a 12% discount to the customer who purchases more than 10000 baht in total.
Write a program that reads the number of each product purchased, then calculates and prints total
payment (with possible 12% discount) in 2 decimal points.

Example Output 1:
How many TVs do you want? 1
How many DVD players do you want? 0
How many audio systems do you want? 1
Your total amount is 4500.00 baht.
Your payment is 4500.00 baht. Thank you.

Example Output 2:
How many TVs do you want? 0
How many DVD players do you want? 2
How many audio systems do you want? 3
Your total amount is 6000.00 baht.
Your payment is 6000.00 baht. Thank you.

Example Output 3:
How many TVs do you want? 2
How many DVD players do you want? 3
How many audio systems do you want? 2
Your total amount is 11250.00 baht.
You got a discount of 1350.00 baht.
Your payment is 9900.00 baht. Thank you.

01204111 Computers and Programming, 81


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
6. Control structure: Multiple Selections
Outline:
6.1 Introduction to multiple selections
6.2 Nested Conditionals
6.3 Chained Conditionals
6.4 Programming examples
6.5 Exercise

6.1 Introduction to multiple selections


Multiple selections select one of three or more paths of execution. For example, the following flowchart
has 3 possible paths.

T F
x > y

m = x m = y

F
z = x-y
z > m

m = 1

r = x+z-m

These are 2 kinds of multiple selections in Python.


• Nested Conditionals
• Chained Conditionals

01204111 Computers and Programming, 82


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
6.2 Nested Conditionals

pass x = y+1 print('hi') if x > y: if x > y:


m = x m = x
z = x+y z = x+y
if x > y: else: else:
if x > y: m = x m = y m = y
m = x z = x+y z = x-y

Each box above is actually a single statement. Thus, each can be put into any statement (statement ~
1

statement ) as in the following program example.


5

if condition:
statement
1
statement
2
else:
statement
3
statement
4
statement
5

Example in Python
When an if or if-else statement is put within another if or if-else statement, we call it a nested
conditional construct. Note that indentation is very important as shown in the following example.

if x > 0: if x > 0: if x > 0:


Code block1 Code block1
i = 2 i = 2
Code block1 if y > 1: if y > 1:
k = 2 k = 2
else: else: Code block2 else: Code block2
if z < 10: if z < 10:
k = 5
if y > 5:
Code block2 Code block3 k = x+y
else:
k = x-y

In the above diagram, you can see that nested conditionals start as just a single statement of if-else. Then,
the other statements are nested(put) into code block1 and code block2. Subsequently, the statements other

01204111 Computers and Programming, 83


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
than those nested in code block1 and code block2 are nested(put) into code block3. Note that a code block
follows the line that ends with a colon.

Example Program Flow Chart

if x > 0:
T F
i = 2 x > 0
if y > 1:
F
k = 2 i = 2 Z < 10
else:
if z < 10: T
F
k = 5 y > 1 k = 5
if y > 5:
T
k = x+y
T F
else: k = 2 y > 5
k = x-y

k=x+y k=x-y

From above, the flowchart on the right side shows the execution flow of the program on the left. According
to the flowchart, there are 5 possible paths that the program can execute.

6.2.1 Programming Example on Nested Conditionals

Task: The maximum of three numbers


Write a program that reads three numbers. Then, computes and prints the maximum of the three.

Example Output 1:
Enter 1st number: 25.5
Enter 2nd number: 30
Enter 3rd number: 20.2
The max is 30

01204111 Computers and Programming, 84


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Example Output 2:
Enter 1st number: 0
Enter 2nd number: -10
Enter 3rd number: -7
The max is 0

Example Output 3:
Enter 1st number: 50
Enter 2nd number: 5
Enter 3rd number: 50
The max is 50

Ideas:
The maximum of 3 numeric values is the value that is not less than the other two. Therefore, to find the
maximum is to look for a value that is not less than the other two. It’s OK if some of them are equal, or even
all of them are equal. Thus, the following is the topmost level in the main routine.
• Reads three numbers.
• Computes the max by calling function max_of_three()
• Prints the max.

Main Program (main routine):


1: # --- main --- #
2: x = float(input("Enter 1st number: "))
3: y = float(input("Enter 2nd number: "))
4: z = float(input("Enter 3rd number: "))
5: max = max_of_three(x,y,z)
6: print(f"The maximum number is {max}")

Function max_of_three()
Now it’s time to write the function max_of_three(). There are many ways to write it. We’ll show a few
different ways to demonstrate the use of nested conditionals.

The function max_of_three() – Version 1

Algorithm:
if (a is not less than the other two)
a is the max
else # a is not the max
Compete b with c for the max

01204111 Computers and Programming, 85


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: def max_of_three(a, b, c):
2: if a >= b and a >= c: # check a
3: return a
4: else: # a is not the max
5: if b > c:
6: return b
7: else:
8: return c

The function max_of_three() – Version 2

Algorithm:
if (a > b) # so a may be the max
Compete a with c for the max
else # so b may be the max
Compete b with c for the max

1: def max_of_three(a, b, c):


2: if a > b: # a may be the max
3: if a > c:
4: return a
5: else:
6: return c
7: else: # b may be the max
8: if b > c:
9: return b
10: else:
11: return c

The function max_of_three() – Version 3

Algorithm:
• Let max be the value of a
• if (b > max) then
Let max be the value of b
• if (c > max) then
Let max be the value of c

01204111 Computers and Programming, 86


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: def max_of_three(a, b, c):
2: max = a
3: if b > max:
4: max = b
5: if c > max:
6: max = c
7: return max

Note that this 3rd version is actually a sequence of two if statements, not a nested if construct. Besides, this
version can be easily extended to 4 or more numbers.

The function max_of_three() – Version 4

In Python, actually, we have a built-in function max(). Thus, you can use this function, instead of creating
your own program to compute max value.

6.3 Chained conditionals


A chained conditional is the use of an orderly sequence of k conditions (k ≥ 2) to select one of k+1 code
block to execute. It is also informally called the if-elseif-else control structure.

Example
Try to select a planned activity on Monday, Tuesday, Wednesday, or Thursday by using the following
flowchart.

01204111 Computers and Programming, 87


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
F T
Today is
Friday

F Today is T
Saturday Play_Football

F Today is T Go_Swimming
Sunday

Play_Basketbal
Go_Jogging

From the above flowchart, we use 3 conditions (written in the rhombus/diamond shape) to select only one
out of the four sets of planned activity. As you can see from the flow of the execution, when either condition
becomes true, one of the three related actions (Play_Football, Go_Swimming, Play_Basketball) will be
selected. And when all the conditions are false, the fourth action (Go_Jogging) is selected.

6.3.1 Chained conditionals in Python


Example of Chained conditionals implemented by nested conditionals if-elseif-else
if cond1:
code_block1
else:
if cond2:
code_block2
else:
if cond3:
code_block3
else:
code_block4

01204111 Computers and Programming, 88


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The program uses 3 conditions (cond1, cond2, cond3) to select one out of 4 code blocks. You can see the
nested conditionals construct in the program. We call the syntax of this kind of program construction, an if-
elseif -else statement. Note that this whole box is actually a single Python statement. The following flow
chart shows the flow execution of the program.

F T
cond
1

F T
cond
2
code block
1

F T
cond
3

code block
2
code block code block
4 3

Example of Chained conditionals implemented by if-elif-else statements

if cond1: if cond1:
code_block1 code_block1
else: elif cond2:
if cond2: code_block2
code_block2 elif cond3:
else: code_block3
if cond3: else:
code_block3 code_block4
else:
code_block4

Firstly, the program on the right-side above works exactly the same as the left one. The difference is else:
followed by if has been replaced to Python keyword elif, and that re-indent has been done. We call the

01204111 Computers and Programming, 89


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
syntax of the program construction in the right-side, an if-elif-else statement. Then, the flowchart is
rearranged accordingly as shown below.

T
cond code block
1 1

F
T
cond 3 code block
2 2

F
T
cond code block
3 3

code block
4

The flow charts of both implementations of if- elseif -else statement and if- elif -else statement show that
these two Python program construction work exactly the same too.

Example: Check how an integer is divided by 5


Write a function divfive() to check how an integer is divided by 5.

Output Example:
>>> divfive(50)
50 is divisible by 5
>>> divfive(54)
54 is not divisible by 5
the remainder is 4
>>> divfive(53)
53 is not divisible by 5
the remainder is 3
>>> divfive(52)
52 is not divisible by 5
the remainder is 2
>>> divfive(51)
51 is not divisible by 5
the remainder is 1

01204111 Computers and Programming, 90


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The function divfive() - Version 1
1: def divfive(d): # version 1
2: rem = d % 5
3: if rem == 1:
4: print(d, 'is not divisible by 5')
5: print('the remainder is 1')
6: elif rem == 2:
7: print(d, 'is not divisible by 5')
8: print('the remainder is 2')
9: elif rem == 3:
10: print(d, 'is not divisible by 5')
11: print('the remainder is 3')
12: elif rem == 4:
13: print(d, 'is not divisible by 5')
14: print('the remainder is 4')
15: else:
16: print(d, 'is divisible by 5')

Version 1 shows that you can have as many elif-clauses as you need. Besides, note that the last choice is
written in the code block after else:.

The function divfive() - Version 2


1: def divfive(d): # version 2
2: rem = d % 5
3: if rem == 0:
4: print(d, 'is divisible by 5')
5: elif rem == 1:
6: print(d, 'is not divisible by 5')
7: print('the remainder is 1')
8: elif rem == 2:
9: print(d, 'is not divisible by 5')
10: print('the remainder is 2')
11: elif rem == 3:
12: print(d, 'is not divisible by 5')
13: print('the remainder is 3')
14: elif rem == 4:
15: print(d, 'is not divisible by 5')
16: print('the remainder is 4')

Version 2 shows that you can have no else-clause at all if you don't need it.

The function divfive() - Version 3

01204111 Computers and Programming, 91


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: def divfive(d): # version 3
2: rem = d % 5
3: if rem == 0:
4: print(d, 'is divisible by 5')
5: else:
6: print(d, 'is not divisible by 5')
7: print('the remainder is', rem)

Version 3 shows that you can have no elif-clauses at all if you don't need them.

Please understand that all these three versions produce exactly the same result.

6.4 Programming examples

Task: BMI and Weight Status


Write a function bmi_and_status() that receives weight (in kg) and height (in meters) as parameters, then
computes the body-mass index (BMI) and returns the BMI and weight status.

Idea:
Given the weight (in kilograms) and the height (in meters) of a person, the Body-Mass Index (BMI) of the
person can be computed by the following formula:

weight
BMI =
height × height

The Weight Status of a person is categorized by the BMI as follows:

BMI Weight Status

BMI < 18.5 Underweight

18.5 ≤ BMI < 25.0 Normal

25.0 ≤ BMI < 30.0 Overweight

BMI ≥ 30.0 Obese

01204111 Computers and Programming, 92


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Algorithm of the function bmi_and_status() - Version 1

Compute BMI

T
BMI < 18.5 wstatus = "underweight"

F
T
BMI < 25.0 wstatus = "normal"

F
T
BMI < 30.0 wstatus = "overweight"

F
wstatus = "obese"

Program of the function bmi_and_status() - Version 1


1: def bmi_and_status(weight, height):
2: bmi = weight/(height*height)
3:
4: if bmi < 18.5:
5: wstatus = "underweight"
6: elif bmi < 25.0:
7: wstatus = "normal"
8: elif bmi < 30.0:
9: wstatus = "overweight"
10: else:
11: wstatus = "obese"
12:
13: return bmi, wstatus

Algorithm of the function bmi_and_status() - Version 2

01204111 Computers and Programming, 93


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Compute BMI

T
BMI >= 30.0 wstatus = "underweight"

F
T
BMI >= 25.0 wstatus = "normal"

F
T
BMI >= 18.5 wstatus = "overweight"

F
wstatus = "obese"

Program of the function bmi_and_status() - Version 2


1: def bmi_and_status(weight, height):
2: bmi = weight/(height*height)
3:
4: if bmi >= 30.0:
5: wstatus = "obese"
6: elif bmi >= 25.0:
7: wstatus = "overweight"
8: elif bmi >= 18.5:
9: wstatus = "normal"
10: else:
11: wstatus = "underweight"
12:
13: return bmi, wstatus

Please compare both algorithm and program of version 1 and version2 to understand what is different.
Note that both versions produce exactly the same result.

Complete the program and test the program.


The main routine is added in line 15 to line 18 as follows.

01204111 Computers and Programming, 94


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: def bmi_and_status(weight, height): # ---- version 1 ---- #
2: bmi = weight/(height*height)
3:
4: if bmi < 18.5:
5: wstatus = "underweight"
6: elif bmi < 25.0:
7: wstatus = "normal"
8: elif bmi < 30.0:
9: wstatus = "overweight"
10: else:
11: wstatus = "obese"
12: return bmi, wstatus
13:
14: # ---- main routine ---- #
15: weight = float(input("Enter your weight (in kilograms): "))
16: height = float(input("Enter your height (in meters): "))
17: bmi, status = bmi_and_status(weight, height)
18: print(f"BMI is {bmi:.2f}, weight status: {status}")

After that, test the program thoroughly by inputting values that yield all possible outputs, and also Also try
some inputs that hit all the three boundary cases which are 18.5, 25.0, 30.0.

01204111 Computers and Programming, 95


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
6.5 Exercise

1) Given the following group() function, put appropriate values in the blanks (A) to (D) to get the output as
shown below.
def group(x):
if x>0:
if x%3 == 0 and x%7 == 0:
print("Group A")
else:
print("Group B")
else:
if x%2 == 0 or x%5 == 0:
print("Group C")
else:
print("Group D")

Example output:
>>> group(_____(A)_____)
Group A
>>> group(_____(B)_____)
Group B
>>> group(_____(C)_____)
Group C
>>> group(_____(D)_____)
Group D

2) The following function returns a grade letter (A,B,C,F) based on a given score.

def letter_grade(score):
if score >= 80:
return "A"
elif score >= 70:
return "B"
elif score >= 60:
return "C"
elif score >= 50:
return "D"
else:
return "F"

Example output:
>>> letter_grade(90)
'A'
>>> letter_grade(75)
'B'
>>> letter_grade(36)
'F'

01204111 Computers and Programming, 96


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Rewrite the function letter_grade() by filling the blank (A) to (D), so that it behaves the same but
considers the score from low to high instead.

def letter_grade(score):
if _____(A)_____:
return "F"
elif _____(B)_____:
return "D"
elif _____(C)_____:
return "C"
elif _____(D)_____:
return "B"
else:
return "A"

3) Write a Python program to get input from the user and check whether that input is odd or even
number.
Example output 1:
Enter number: 105
105 more than 100

Example output 2:
Enter number: 91
91 is even

Example output 3:
Enter number: 80
80 is odd

01204111 Computers and Programming, 97


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
7. Control structure: Repetition – Part 1

Outline:
7.1 Repetition Control Flow
7.2 Programming Examples
7.3 More About Strings
7.4 A Numerical Example
7.5 Exercises

7.1 Repetition Control Flow

Schematic View of Flow Controls

Sequence
Repetition
Subroutine Selection

So far, we have already learned about the flow control of Sequence, Subroutine, and Selection
(branching). In this chapter, we will newly learn about the flow control of Repetition.

01204111 Computers and Programming, 98


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
7.1.1 Repetition Flow Control

Computers are often used to do repetitive tasks because humans don’t like to do the same thing over and
over again. In computer programs, repetition flow control is used to execute a group of instructions
repeatedly. Repetition flow control is also called iteration or loop. In Python, repetition flow control can be
expressed by a for-statement or a while-statement that allows us to execute a code block repeatedly.

7.1.2 Definite Loops: the for statement

Syntax:
for variable in sequence :
code_block

The variable after for is called the “loop index”. It takes on each successive value in “sequence” in the
order they appear in the sequence. The sequence can be one of the Python sequence objects such as a
string, a list, a tuple, or a range of integers from the built-in function range() (we will explain about function
range() in the next subsection). In the following flowchart, the number of times the code_block is executed

is precisely the number of items in the sequence.

False
more items in sequence ?

True
variable = next item

code_block

01204111 Computers and Programming, 99


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Hands-on Example:
>>> my_string = 'python'
>>> k = 0
>>> for c in my_string:

k = k + 1
print(f'round {k} : c is {c}')

round 1 : c is p
round 2 : c is y
round 3 : c is t
round 4 : c is h
round 5 : c is o
round 6 : c is n

For the explanation of the above program;


• The variable c is the loop index.
• The variable my_string is the sequence 'p', 'y', 't', 'h', 'o', 'n'.
• The code block (written inside the dotted line square) is executed repeatedly for each value of c.

>>> k = 0
>>> for i in range(4):

k = k + 1
print(f'round {k} : i is {i}')

round 1 : i is 0
round 2 : i is 1
round 3 : i is 2
round 4 : i is 3

For the explanation of the above program;


• The variable i is the loop index.
• The object range(4) generates the sequence 0, 1, 2, 3. (we will explain about function range()
in the next subsection)
• The code block (written inside the dotted line square) is executed repeatedly for each value of i.

01204111 Computers and Programming, 100


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
7.1.2 The range() function
Syntax:
range(start, stop, step)

In its most general form, the range() function takes three integer arguments: start, stop, and step.
range(start, stop, step) produces the sequence of integers:

start, start + step, start + 2*step, start + 3*step, …

- If step is positive, the last element is the largest integer less than stop.

When step
is positive
+step +step +step +step +step

...
start stop

values in the sequence


(in left-to-right order)

- If step is negative, the last element is the smallest integer greater than stop.

When step
is negative
+step +step +step +step +step

...
stop start

values in the sequence


(in left-to-right order)

01204111 Computers and Programming, 101


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Hands-on Example:
To see the type of object range()
>>> type(range(-4,14,3))
<class 'range'>

This doesn't show the sequence generated by range().


>>> range(-4,14,3)
range(-4, 14, 3)

Use the built-in function list() to show the sequence.


>>> list(range(-4,14,3))
[-4, -1, 2, 5, 8, 11]

Try a negative step.


>>> list(range(14,-4,-3))
[14, 11, 8, 5, 2, -1]

Produces the empty sequence because step is positive and start is not less than stop.
>>> list(range(5,3,1))
[]

Produces the empty sequence because step is negative and start is not greater than stop.
>>> list(range(3,5,-1))
[]

Note: the stop value will never appear in the generated sequence.
>>> list(range(3,8,1))
[3, 4, 5, 6, 7]

If step is omitted, the default step is 1.


>>> list(range(3,8))
[3, 4, 5, 6, 7]
>>> list(range(0,5))
[0, 1, 2, 3, 4]

If start is omitted, the default start is 0.


>>> list(range(5))
[0, 1, 2, 3, 4]
>>> for i in range(4):
print('i is', i)
i is 0
i is 1
i is 2
i is 3

01204111 Computers and Programming, 102


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
So, range(4) is the same as range(0,4) and range(0,4,1).

Task: Hello World n times


Write a function hello(n) to write Hello World! n times, where n ≥ 0 is the input. After that, write Goodbye!
once as shown in the following test run example.
>>> hello(3)
Hello World!
Hello World!
Hello World!
Goodbye!
>>> hello(0)
Goodbye!
>>> hello(1)
Hello World!
Goodbye!

Step:
A simple step of function hello().
hello(n):
• receive n as its parameter.
• repeat n times:
o write 'Hello World!'
• write 'Goodbye!'

Program:
1: def hello(n):
2: for i in range(n):
3: print('Hello World!')
4: print('Goodbye!')

Test run example:

01204111 Computers and Programming, 103


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
7.2 Programming Examples

Task: Print a Fahrenheit-to-Celcius Table


Write a function to print a Fahrenheit-to-Celsius conversion table from 212 F to 32 F, decremented in each
step by 20 F.
>>> fah_to_cel()
Fahrenheit Celcius
---------- -------
212 100.0
192 88.9
172 77.8
152 66.7
132 55.6
112 44.4
92 33.3
72 22.2
52 11.1
32 0.0
---------- -------

Ideas: The formula to convert Fahrenheit to Celcius:


celcius = (5/9)*(fahrenheit-32)

We’ll write a function fah_to_cel() to do the task. We’ll use a for-loop in which the loop index holds the
Fahrenheit values. The for-loop will iterate over a sequence from 212 down to 32 generated by range().
First, let's experiment with the range of Fahrenheit values:
>>> list(range(212,32,-20))
[212, 192, 172, 152, 132, 112, 92, 72, 52]
>>>

From the above example, the result shows that 32 is missing. We should use one less than 32 so that 32 can
be included in the sequence. Now, we've got a correct sequence running from 212 down to 32 as follows.

01204111 Computers and Programming, 104


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
>>> list(range(212,31,-20))
[212, 192, 172, 152, 132, 112, 92, 72, 52, 32]
>>>

Thus, the function fah_to_cel() can be defined as follows.


1: def fah_to_cel():
2: print(f"{'Fahrenheit':>12}{'Celcius':>12}")
3: print(f"{'----------':>12}{'-------':>12}")
4:
5: for fah in range(212,31,-20):
6: cel = (5/9)*(fah-32)
7: print(f"{fah:12}{cel:12.1f}")
8:
9: print(f"{'----------':>12}{'-------':>12}")

Test run result:


>>> fah_to_cel()
Fahrenheit Celcius
---------- -------
212 100.0
192 88.9
172 77.8
152 66.7
132 55.6
112 44.4
92 33.3
72 22.2
52 11.1
32 0.0
---------- -------

Supplementation: the layout (justification) configuration of function print


Let's do some experiments to see how the layout (justification) configuration of function print works.

1: def test_print():
2: print('12345678901234567890')
3: print(f"{'python':>10}{'idle':>10}")
4: print(f"{'python':<10}{'idle':<10}")
5: print(f"{'python':^10}{'idle':^10}")
6: cel = 32/3
7: print('12345678901234567890')
8: print(f"{cel:>10.1f}{cel:>10.3f}")
9: print(f"{cel:<10.1f}{cel:<10.3f}")
10: print(f"{cel:^10.1f}{cel:^10.3f}")
11: print('12345678901234567890')

01204111 Computers and Programming, 105


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Test run result:
>>> test_print()
12345678901234567890
python idle
python idle
python idle
12345678901234567890
10.7 10.667
10.7 10.667
10.7 10.667
12345678901234567890
>>>
• Left-justification can be specified by symbol < and follows by the integer number which defines the
total space of that portion to be justified. Note that, left-justification is the default for strings.
• Right-justification can be specified by symbol > and follows by the integer number which defines the
total space of that portion to be justified. Note that, right-justification is the default for numbers.
• Centering-justification can be specified by symbol ^ and follows by the integer number which defines
the total space of that portion to be justified.

Make function fah_to_cel() more general:


Next step, let’s make function fah_to_cel() more general. Add three keyword parameters: start, end and
step to control the Fahrenheit values to be printed. Test run results are shown as follows.

>>> fah_to_cel(32,100,20)
Fahrenheit Celcius
---------- -------
32 0.0
52 11.1
72 22.2
92 33.3
---------- -------
>>> fah_to_cel(100,32,-20)
Fahrenheit Celcius
---------- -------
100 37.8
80 26.7
60 15.6
40 4.4
---------- -------
>>> fah_to_cel(step=-20,start=100,end=0)
Fahrenheit Celcius
---------- -------
100 37.8
80 26.7
60 15.6
40 4.4
20 -6.7
---------- -------
>>>

01204111 Computers and Programming, 106


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The generalized fah_to_cel() function:
1: def fah_to_cel(start=32, end=213, step=20):
2: print(f"{'Fahrenheit':>12}{'Celcius':>12}")
3: print(f"{'----------':>12}{'-------':>12}")
4:
5: for fah in range(start, end, step):
6: cel = (5/9)*(fah-32)
7: print(f"{fah:12}{cel:12.1f}")
8: print(f"{'----------':>12}{'-------':>12}")

Run each of these following examples to see how the default values, 32, 213, and 20, works.
>>> fah_to_cel()
Fahrenheit Celcius
---------- -------
32 0.0
52 11.1
72 22.2
92 33.3
112 44.4
132 55.6
152 66.7
172 77.8
192 88.9
212 100.0
---------- -------
>>> fah_to_cel(100)
Fahrenheit Celcius
---------- -------
100 37.8
120 48.9
140 60.0
160 71.1
180 82.2
200 93.3
---------- -------
>>> fah_to_cel(50,100)
Fahrenheit Celcius
---------- -------
50 10.0
70 21.1
90 32.2
---------- -------
>>>

Task: Computing the factorial


Suppose you have five pens of different colors to give to five kids. How many ways are there to give those
five pens to those kids?

01204111 Computers and Programming, 107


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Answer: 5*4*3*2*1 = 120 ways, this value is called the factorial of 5, or simply 5!
More generally, the factorial is defined as a function of nonnegative integers (0, 1, 2, …) such that:
n! = n(n-1)(n-2)…(2)(1) when n > 0, and 0! = 1

Let's write a Python function factorial(n) to compute and return the value of n!
>>> factorial(5)
120
>>> factorial(3)
6
>>> factorial(1)
1
>>> factorial(0)
1
>>> factorial(10)
3628800
>>>

An Accumulating Algorithm:
The calculate of 3! and 5! are performed as follows.
3! = 3*2*1 = 6
5! = 5*4*3*2*1 = 120

Since the function factorial(n) must work for every value of n, so we'll devise an accumulating algorithm
that works for every value of n. We can compute 4! by accumulating results as follows. Let's use a variable
result to hold the accumulating result.
• Start at 1
• Take that 1, then 1*4 = 4
• Take that 4, then 4*3 = 12
• Take that 12, then 12*2 = 24
• Done!
Then, translate our above algorithm into Python statements
result = 1
result = result*4
result = result*3
result = result*2
return result

Notice that for 4! the multiplication calculation is repeated 3 times through the sequence 4, 3, 2.
Therefore, for n! the multiplication calculation is repeated n-1 times through the sequence n, n-1, n-2 …, 3, 2
01204111 Computers and Programming, 108
Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
result = 1
result = result*n
result = result*(n-1)
result = result*(n-2)
...
result = result*2
return result

This repetition is exactly the for-loop:


for i in range(n,1,-1):
result = result*i

Finally, we can convert from the algorithm to code as follows.

1: def factorial(n):
2: result = 1
3: for i in range(n,1,-1):
4: result = result*i
5: return result

Next, let’s check if our function can work properly when n=0 or n=1.
From our function factorial(n), when n = 0 or 1, the range() in the for-statement becomes range(0,1,-
1) or range(1,1,-1) respectively. Then, use the built-in function list() to show the output sequence (list)

generated by range(0,1,-1) and range(1,1,-1).


>>> list(range(0,1,-1))
[]
>>> list(range(1,1,-1))
[]

As a result, the output are both empty sequence (empty list). Thus, If we use an empty sequence in for-
statement, nothing will be generated as an output because statement(s) inside the loop doesn't get executed
at all, as shown as follows.
>>> for i in []:
print("Yappadapadoo")
>>>

1: def factorial(n):
2: result = 1
3: for i in range(n,1,-1):
4: result = result*i
5: return result

By the explanation given above, when n=0 or n=1, the range() in the for-statement becomes range(0,1,-1)
or range(1,1,-1) and both of them generate empty sequence (empty list). Thus, the statement result=

01204111 Computers and Programming, 109


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
result*i inside for-statement don’t get executed, so the initial value of variable result which is 1 is
returned (line 5). As a result, function factorial(n) gives 1 which is the correct answer when n=0 or n=1.

7.3 More About Strings

7.3.1 String Indexing


Accessing Characters in a String:
A Python string is an object of type str, which represents a sequence of characters. We can access each
individual character in a string with an expression (type int) in the bracket operator []. Such expression in the
bracket is called a string index.
str_object[expression]

The indexes of characters in a string are numbered from the left, starting with 0.

greet
H e l l o D a n

index 0 1 2 3 4 5 6 7 8

>>> greet = 'Hello Dan'


>>> greet
'Hello Dan'
>>> greet[0]
'H'
>>> greet[4]
'o'
>>> print(greet[1], greet[4]+greet[8])
e on

Both of these are type of str.


>>> type(greet)
<class 'str'>
>>> type(greet[4])
<class 'str'>

greet[1] is a string object so it can be assigned to a variable.


>>> letter = greet[1]
>>> letter
'e'

01204111 Computers and Programming, 110


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
String indexes can be any expressions of type int.
>>> k = 1
>>> greet[k]
'e'
>>> greet[k+5]
'D'
>>> greet[2*k+5]
'a'
>>> greet[1.5]
TypeError: string indexes must be integers

Indexing also works on string literals.


>>> 'python'[0]
'p'
>>> "python"[3]
'h'
>>> 'python'[k+2]
'h'

The built-in function len() returns the length of its string argument.
>>> greet = 'Hello Dan'
>>> len(greet)
9
>>> len("I'm happy.")
10
>>> greet + 'ny!'
'Hello Danny!'
>>> len(greet + 'ny!')
12

The last index of string greet is 8, not 9.


>>> length = len(greet)
>>> length
9
>>> lastchar = greet[length]
IndexError: string index out of range

Correct index of the last character.


>>> lastchar = greet[length-1]
>>> lastchar
'n'

01204111 Computers and Programming, 111


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Negative indexes:

greet
H e l l o D a n

Index (positive indexes) 0 1 2 3 4 5 6 7 8

Index (negative indexes) -9 -8 -7 -6 -5 -4 -3 -2 -1

You can use negative indexes to index backward from the end of the string.
>>> greet = 'Hello Dan'

Last character:
>>> greet[-1]
'n'

Second last character:


>>> greet[-2]
'a'

First character:
>>> greet[-9]
'H'
>>> greet[-len(greet)]
'H'

Notice the positive indexes that refer to the same positions as their negative counterparts.
>>> length = len(greet)

Last character:
>>> greet[length-1]
'n'

Second-last character:
>>> greet[length-2]
'a'

First character:
>>> greet[0]
'H'
>>> greet[length-len(greet)]
'H'

01204111 Computers and Programming, 112


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Python string objects are immutable.
That means the characters within a string object cannot be changed.
>>> greet = 'Hello Dan'

A new string object 'Hello Dan' is created and then assigned to the variable greet. Then, we expect to
change Dan to Jan
>>> greet[6] = 'J'
TypeError: 'str' object does not support item assignment
>>> 'Hello Dan'[6] = 'J'
TypeError: 'str' object does not support item assignment
>>> greet
'Hello Dan'
>>> greet = greet + 'ny'
>>> greet
'Hello Danny'

The above examples show that in Python we cannot change any character in the string, but we can append
character(s) to the string. Note that the variable greet has been changed twice by assignment, but the two
string objects, 'Hello Dan' and 'Hello Danny', can never be changed.

7.3.2 String Traversal


Lots of computations involve processing a string one character at a time in this pattern:
1. Get a string.
2. Repeat from the beginning until the end of the string:
o Get next character.
o Do something with the character.

This pattern of processing is called a traversal. In Python, one way to implement a string traversal is by using
a for-loop.

Traversal Example:
We want to write a program that prints each character in a string, one per line, enclosed in / /. Without using
a loop, we may write a Python program to traverse the string assigned to a variable text like this:
text = 'a dog'
c = text[0]; print(f'/{c}/')
c = text[1]; print(f'/{c}/')
c = text[2]; print(f'/{c}/')
c = text[3]; print(f'/{c}/')
c = text[4]; print(f'/{c}/')

01204111 Computers and Programming, 113


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Note that the symbol ; allows two or more statements on the same line. But since a string is a sequence
type like a range() object, we can use for statements with strings in a similar way:
text = 'a dog'
for c in text:
print(f'/{c}/')

Both examples work effectively the same and the test run result shown as follows:
>>> text = 'a dog'
>>> for c in text:
print(f'/{c}/')
/a/
/ /
/d/
/o/
/g/

Let’s generalize and encapsulate it into a function spread_str(text).


def spread_str(text):
"""print text, one char per line within ()"""
for c in text:
print(f'/{c}/')

Test it again.
>>> spread_str('a')
/a/
>>> spread_str('')
>>> spread_str("T'Rex")
/T/
/'/
/R/
/e/
/x/

Looping Over String Indexes:


These two blocks of code work effectively the same.

text = 'a dog' text = 'a dog'


c = text[0]; print(f'/{c}/') print(f'/{text[0]}/')
c = text[1]; print(f'/{c}/') print(f'/{text[1]}/')
c = text[2]; print(f'/{c}/') print(f'/{text[2]}/')
c = text[3]; print(f'/{c}/') print(f'/{text[3]}/')
c = text[4]; print(f'/{c}/') print(f'/{text[4]}/')

01204111 Computers and Programming, 114


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The index’s number suggests that we can also do this task by looping over the string indexes. Recall that the
indexes of any string s are in the range 0, 1, 2, …, len(s)-1
>>> s = 'a dog'
>>> list(range(len(s)))
[0, 1, 2, 3, 4]

Thus, this is an alternative version of function spread_str(text).


def spread_str(text):
"""print text, one char per line within / /"""
for i in range(len(text)):
print(f'/{text[i]}/')

Besides, following is also the alternative version of function spread_str(text) which can work the same.
def spread_str(text):
"""print text, one char per line within / /"""
for c in text:
print(f'/{c}/')

Counting a Character:
We want to write a program that counts the number of times a character appears in a string. Suppose we
want to count the number of 'e' in a string 'pete', we may write a program like this:

1: text = 'pete'
2: count = 0
3: c=text[0]; if c=='e': count = count+1
4: c=text[1]; if c=='e': count = count+1
5: c=text[2]; if c=='e': count = count+1
6: c=text[3]; if c=='e': count = count+1
7: print(count)

Each statement in line 3 until line 6 traverses the string from left to right, and If the current character is 'e',
the variable count will be incremented by 1. This repetition is exactly the for-loop as follows:
for c in text:
if c == 'e':
count = count+1

Make the full program that can work.


text = 'pete'
count = 0
for c in text:
if c == 'e':
count = count+1
print(count)

01204111 Computers and Programming, 115


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Let’s generalize and encapsulate it into a function.
def count_char(char, text):
"""counts the no. of times
'char' appears in 'text'"""
count = 0
for c in text:
if c == char:
count = count+1
return count

Test run result:


>>> count_char('a', 'anaconda')
3
>>> count_char('x', 'python')
0
>>> count_char(' ', 'I am happy')
2
>>> count_char(text='python', char='y')
1

Alternatively, we may loop over string indexes with still have the same result.
def count_char(char, text): #version 2
"""counts the no. of times 'char' appears in 'text'"""
count = 0
for i in range(len(text)):
if text[i] == char:
count = count+1
return count

7.4 A Numerical Example

Task: Average of Numbers


Write a program to read n numbers and calculate their average. The inputs of the program are the values of
n and all of the n numbers. n is a positive integer and each number is a float number.

Example Output 1:
How many numbers? 4
Enter number #1: 12
Enter number #2: 11.5
Enter number #3: 13
Enter number #4: 10.5
The average of 4 number(s) is 11.75

01204111 Computers and Programming, 116


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Example Output 2:
How many numbers? 0
Nothing to do. Bye!

Topmost Steps:
Algorithm of the Main Routine
1) Read the value of n, making sure that n > 0
2) Read each of the n numbers and calculate the average.
3) Output the average.
Then, translate it into Python program.
1: import sys
2: # ---- main ---- #
3: n = int(input('How many numbers? '))
4: if n <= 0:
5: print('Nothing to do. Bye!')
6: sys.exit()
7: avg = average(n)
8: print(f'The average of {n} number(s) is {avg}')

From the above program, step 1) in the algorithm is translated to the code in line 3 to line 6. It receives the
value of n from the user, and uses “if statement” written in line 4 to line 6 to make sure whether received n
is greater than 0 or not. If n is less than or equal to 0, the program will stop by sys.exit() statement (in line
6). We'll write the function average() to do the read/calculate task.

Algorithm of function average()


1) Gets the count of numbers n as its parameter.
2) Reads each of the n numbers and calculate the sum:
sum = number1 + number2 + … + numbern

3) Calculates the average with:


average = sum / n

4) Returns the average.

Accumulating Algorithm Once Again:


Reads each of the n numbers and calculate the sum:
sum = number1 + number2 + … + numbern

Transform the sum formula into an accumulating algorithm.

01204111 Computers and Programming, 117


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
• sum = 0
• Read number1; sum = sum + number1
• Read number2; sum = sum + number2
• ...
• n) Read numbern; sum = sum + numbern

The above accumulating algorithm shows repeated statements that read the number and add that number
with sum. Thus, we can convert to for-loop using n as the loop iterations as follows.
• sum = 0
• Repeat n times:
- Read a new number into the variable number
- sum = sum + number
Then translate it into Python code.
sum = 0
for i in range(n):
number = float(input(f'Enter number #{i+1}: '))
sum = sum + number

Complete Program:
1: import sys
2: def average(n):
3: sum = 0
4: for i in range(n):
5: number = float(input(f'Enter number #{i+1}: '))
6: sum = sum + number
7: return sum/n
8:
9: # ---- main ---- #
10: n = int(input('How many numbers? '))
11: if n <= 0:
12: print('Nothing to do. Bye!')
13: sys.exit()
14: avg = average(n)
15: print(f'The average of {n} number(s) is {avg}')

Test run result:


How many numbers? 4
Enter number #1: 12
Enter number #2: 11.5
Enter number #3: 13
Enter number #4: 10.5
The average of 4 number(s) is 11.75

How many numbers? 0


Nothing to do. Bye!

01204111 Computers and Programming, 118


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
7.5 Exercises

1) Complete the program below (in the blank (A)) so that it prints out a message many times as the
user specifies, as shown.
msg = input("What do you want me to say? ")
num = int(input("How many times you want me to say it? "))

_____________
_____(A)_____
_____________

Example output:
What do you want me to say? Thank you
How many times you want me to say it? 3
Thank you #1
Thank you #2
Thank you #3

2) Complete the code in the blanks (A) and (B) so that it creates a simple bar graph of the function g(x) =
x2, where x = 1,2,3,4,5.

def g(x):
return _____(A)_____

print(" x | g(x)")
print("---+---------------------------------")
for _____(B)_____:
bars = "#" * round(g(x+1))
print(f" {x+1} | {bars} ({g(x+1)})")

Example output:
x | g(x)
---+---------------------------------
1 | # (1)
2 | #### (4)
3 | ######### (9)
4 | ################ (16)
5 | ######################### (25)

3) Write a Python program print the words “Programming” backward as the following output. Note that
each character must be in the same line.
Output:
gnimmargorP

01204111 Computers and Programming, 119


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
4) Write a program that draws a square block using any character. The size of the block and the
character to draw it with are given by the user.
Example output 1:
What is the block size? 3
Enter the character to use: #
###
###
###

Example output 2:
What is the block size? 5
Enter the character to use: *
*****
*****
*****
*****
*****

5) Write a Python program that takes a message from the user, then prints the message out diagonally.
Example output 1:
Input a message: Hello
H
e
l
l
o

Example output 2:
Input a message: Good bye
G
o
o
d

b
y
e

01204111 Computers and Programming, 120


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
8. Control structure: Repetition – Part 2

Outline:

8.1 Definite Loops: A Quick Review


8.2 Conditional Loops: While Statement
8.3 A Logical Bug: Infinite Loop
8.4 Common Loop Pattern:
8.4.1 Common Loop Pattern: Counting Loops
8.4.2 Common Loop Pattern: Interactive Loops
8.4.3 Common Loop Pattern: Sentinel Loops
8.5 One More Example: Finding the Maximum
8.6 Exercise

8.1 Definite Loops: A Quick Review

We've already learned that the Python for-statement provides a simple kind of loops that iterate through a
sequence of values.

for variable in sequence :


code_block False
more items in sequence ?

The number of times the code_block is


True
executed is precisely the number of items
variable = next item
in the sequence. Therefore, the for-loop is
also called the definite loop because it
repeats its loop body a definite number code_block
of times.

01204111 Computers and Programming, 121


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Task: Fahrenheit-to-Celcius Table – Revisited
From the following program in the previous chapter.
1: def fah_to_cel(start, end, step):
2: print(f"{'Fahrenheit':>12}{'Celcius':>12}")
3: print(f"{'----------':>12}{'-------':>12}")
4:
5: for fah in range(start, end, step):
6: cel = (5/9)*(fah-32)
7: print(f"{fah:12}{cel:12.1f}")
8:
9: print(f"{'----------':>12}{'-------':>12}")

Test run again.


>>> fah_to_cel(40, 50, 0.5)
Fahrenheit Celcius
---------- -------
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
fah_to_cel(40, 50, 0.5)
File "C:/Users/patta/Python/Chapter8/Fahrenheit-to-Celcius.py", line 5, in fah_to_cel
for fah in range(start, end, step):
TypeError: 'float' object cannot be interpreted as an integer
>>>

The result is a run-time error because the range() function requires only integer arguments, but 0.5 is not an
integer. Thus, we need another kind of loop that is more flexible than the for-loop, which is “while-loop”.
While-loop is also called the condition loops.

8.2 Conditional Loops: While Statement

8.2.1 While Statement

Syntax of While Statement:

while condition :
code_block

• condition is a Boolean expression.


• code_block is, as usual, an indented sequence of one or more statements.

01204111 Computers and Programming, 122


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Semantic of While Statement:

False
condition

True

code_block

Example of While Statement:


Example of the countdown program Flow chart of the countdown program

1: def countdown(n):
2: False
3: while n > 0: n > 0
4: print(n)
5: n = n-1 True
6:
7: print("Go!") print(n)

Test run output. n = n-1

>>> countdown(4)
4
3
2
1
Go! print("Go!")
>>> countdown(0)
Go!

From the test run output of countdown(0), the result shows that the code block of the loop body written in
line 4 and line 5 of the program didn’t get executed at all. It is because the condition of while statement (n>
0) is False, so that the execution of statements in the code block (written in line 4 and line 5) are bypassed as

shown in the flow chart above.

01204111 Computers and Programming, 123


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
8.2.2 A Conditional-Loop Algorithm:
Let's try to revise the function fah_to_cel() in the previous section to make fractional steps (float number
steps) input possible by using while-loop.

>>> fah_to_cel(40, 50, 2.5)


Fahrenheit Celcius
---------- -------
40.00 4.44
42.50 5.83
45.00 7.22
47.50 8.61
---------- -------
>>>

We then devise a conditional-loop algorithm for the new version of function fah_to_cel() as follows.

fah = start

False
fah < end

True

cel = (5/9)*(fah-32)

print fah,cel

fah = fah+step

Algorithm:
• Set fah to the value of start before the first iteration.
• The condition fah < end is used to decide whether to execute another iteration or exit the loop.
• Computation to be done for each iteration: calculate cel from fah, then print a line of the table.
• Increment fah by step, to ready fah for the next iteration.

01204111 Computers and Programming, 124


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Next, convert from the algorithm to python code by using while statement.

fah = start

while fah < end:


cel = (5/9)*(fah-32)
print(f"{fah:12.2f}{cel:12.2f}")
fah = fah + step

Finally, the new version of the function fah_to_cel() (# version 2) can be defined as follows.
1: def fah_to_cel(start, end, step): # version 2
2: print(f"{'Fahrenheit':>12}{'Celcius':>12}")
3: print(f"{'----------':>12}{'-------':>12}")
4:
5: fah = start
6: while fah < end:
7: cel = (5/9)*(fah-32)
8: print(f"{fah:12.2f}{cel:12.2f}")
9: fah = fah + step
10:
11: print(f"{'----------':>12}{'-------':>12}")

Test run again.


>>> fah_to_cel(40, 50, 2.5)
Fahrenheit Celcius
---------- -------
40.00 4.44
42.50 5.83
45.00 7.22
47.50 8.61
---------- -------
The above result shows that it works fine when step is a float number.

>>> fah_to_cel(40, 50, 3)


Fahrenheit Celcius
---------- -------
40.00 4.44
43.00 6.11
46.00 7.78
49.00 9.44
---------- -------
The above result shows that it also works fine when step is an integer.

01204111 Computers and Programming, 125


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
8.3 A Logical Bug: Infinite Loop
Some values of the arguments start, stop, and step produces strange outputs. Let’s see if they are normal, or
bugs?

Output Example 1:
For the input of the function fah_to_cel(), gives 50 as start, 40 as stop, and increment step by 2.5.
>>> fah_to_cel(50, 40, 2.5)
Fahrenheit Celcius
---------- -------
---------- -------
The above output which produced an empty table is really sensible, so it should be considered as normal,
because the step is positive and the start 50 already exceeds the stop 40.

Output Example 2:
For the input of the function fah_to_cel(), gives 50 as start, 40 as stop, and decrement step by 0.5.
>>> fah_to_cel(50, 40, -0.5)
Fahrenheit Celcius
---------- -------
---------- -------
The above output is not sensible, because the step is negative so we'd rather see a table running from 50
down to 40. Thus, this should be considered as a bug.

Output Example 3:
For the input of the function fah_to_cel(), gives 30 as start, 40 as stop, and decremented by 2.5. Since
start is already less than stop, you'd expect to see an empty table. But what you see is;
>>> fah_to_cel(30, 40, -2.5)
Fahrenheit Celcius
---------- -------
30.00 -1.11
27.50 -2.50
25.00 -3.89
22.50 -5.28
20.00 -6.67
17.50 -8.06
15.00 -9.44
12.50 -10.83
10.00 -12.22
7.50 -13.61
5.00 -15.00
2.50 -16.39
0.00 -17.78
-2.50 -19.17

01204111 Computers and Programming, 126


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
A few moments later, you have encountered an “infinite loop”.
-41152.50 -22880.28
-41155.00 -22881.67
-41157.50 -22883.06
-41160.00 -22884.44
-41162.50 -22885.83
-41165.00 -22887.22
-41167.50 -22888.61
-41170.00 -22890.00
-41172.50 -22891.39
-41175.00 -22892.78
-41177.50 -22894.17
-41180.00 -22895.56
-41182.50 -22896.94
-41185.00 -22898.33
KeyboardInterrupt
>>>

The program is still running indefinitely, so you decide to hit <Ctrl+C> to stop the program.

How does the infinite loop happen?

fah = start

False
fah < end

True

cel = (5/9)*(fah-32)

print fah,cel

fah = fah+step

01204111 Computers and Programming, 127


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
According to the flowchart, let’s consider the call fah_to_cel(30, 40, -2.5) in the output example 3. It
should have produced an empty table, so the infinite loop is obviously a bug. Before entering the loop, since
the first argument start is 30, the value of fah is 30. And since the second argument end is 40, the
condition fah<40 (30<40) is True, so that the program can enter the loop and statements in the code block
will be executed. Here, please note that the condition fah<40 has to be False for the loop to exit. Since the
third argument step is -2.5, which is negative, fah always becomes smaller in the next iteration. Therefore,
the ever-decreasing fah will never reach 40, so fah<40 is always True and the loop will never exit. Thus, “the
infinite loop” occurs.
Besides, from the call fah_to_cel(50, 40, -0.5) in the output example 2, we should have seen a table
running from 50 down to 40, decremented by 0.5, rather than the empty table. Thus, this should be also
considered as a bug.
So, our loop algorithm version2 (fah_to_cel() #version 2) has bugs that cause two abnormal behaviors as
described. It can work correctly only with positive steps but not with negative steps. You can try to modify
fah_to_cel() to correct these bugs in the exercise.

8.4 Common Loop Pattern:


Conditional loops as realized in the Python while statement allows for many common loop patterns
frequently used in programs:
• Counting loops (or counter-controlled loops)
• Interactive loops
• Sentinel loops
• Loop and a half
• Post-test loops
• Nested loops

8.4.1 Common Loop Pattern: Counting Loops


Counting loops (also called counter-controlled loops) are one of the most frequently used loop patterns in
programming. A counting loop uses a counter variable to control the number of times the loop will repeat.
How many times the loop will repeat can be easily predicted before the loop starts.

01204111 Computers and Programming, 128


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Flow chart of Counting Loops Pattern

Initialize the counter

counter False
is within the
limit?
True

Execute some computations

Update the counter

The flow chart of the counting loops can be translated into a while-loop algorithm as follows:

Initialize the counter


while counter is within the limit:

Execute some computations


Update the counter

Note that, from the above while-loop algorithm, counter is a variable. And, “some computation statements”
may or may not use the counter variable in the computations.

Again, let’s look at the python code of function fah_to_cel() #version2, which actually uses the counting
loop.
Then, we will compare in sequence which line of the python code corresponds to which part of the
algorithm.

01204111 Computers and Programming, 129


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Python code of the counting loop While-loop algorithm of the counting loop
1: def fah_to_cel(start, end, step): # version 2
2: print(f"{'Fahrenheit':>12}{'Celcius':>12}")
3: print(f"{'----------':>12}{'-------':>12}")
4:
5: fah = start Initialize the counter
6: while fah < end: while counter is within the limit:
7: cel = (5/9)*(fah-32)
8: print(f"{fah:12.2f}{cel:12.2f}") } Execute some computations
9: fah = fah + step Update the counter
10:
11: print(f"{'----------':>12}{'-------':>12}")

• Initialize the counter: Variable start is initialized to fah (line 5). Here, fah is our counter.
• while counter is within the limit: Check the condition fah<end (line 6). If the condition is True,
then executes the following statements (line 7 and line 8), in each iteration.
cel = (5/9)*(fah-32)
print(f"{fah:12.2f}{cel:12.2f}")
• Update the counter: fah is decremented by step before ending of each loop (line 9), in each
iteration.

Example Program of Counting Loops: Function factorial(n) revisited.


Let’s revisit the function factorial(n) from the previous chapter.

A definition-loop version (for-loop):


1: def factorial(n): #version 1
2: result = 1
3: for i in range(n,1,-1):
4: result = result*i
5: return result

We have once used a for-loop to implement an accumulating algorithm that computes the factorial of n as
follows:
result = 1
result = result*n
result = result*(n-1)
result = result*(n-2)
...
result = result*2
return result

This accumulating algorithm can also be easily implemented by using a counting loop (while-loop) by the
following ideas.

01204111 Computers and Programming, 130


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Ideas:
- Use the variable count as the counter that holds the successive values of n, n-1, n-2, …, 2.
While-loop algorithm of the counting loop
- Variable count is initialized to n before entering the loop. Initialize the counter
- Each iteration in the loop executes the statement: while counter is within the limit:
result = result*count Execute some computation(s)
- A variable count is decremented by 1 in each iteration. Update the counter
- The loop continues while count is greater than or equal to 2.

Thus, we can implement factorial(n) by using a counting loop (while-loop) as follows:


A counting-loop version (while-loop):
1: def factorial(n): #version 2
2: result= 1
3: count = n
4: while count >= 2:
5: result = result*count
6: count = count-1
7: return result

In fact, since the value of n is not used again elsewhere, n can be the counter itself. Thus, another slimmer
counting-loop version shown as follows:
1: def factorial(n): #version 2.1
2: result= 1
3: while n >= 2:
4: result = result*n
5: n = n-1
6: return result

One last thing before we leave factorial(n), Make sure you understand why all these versions work
correctly when n = 0 or n = 1.

Test run result:

01204111 Computers and Programming, 131


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The result shows that it gave the correct output of 1, when n=0 (factorial(0)) and n=1 (factorial(1)). This
is because, even when n is 0 or 1, the condition n>=2 becomes false and line 4 and line 5 are not executed.
Thus, in line 6 the value of result=1 (which is already initialized in line2) is returned.

8.4.2 Common Loop Pattern: Interactive Loop

Task: Average of Numbers


In the previous chapter, we have written a program that calculates the average of n numbers, which runs like
this.
How many numbers? 4
Enter number #1: 12
Enter number #2: 11.5
Enter number #3: 13
Enter number #4: 10.5
The average of 4 number(s) is 11.75

The program we wrote uses a for-loop so it needs to know in advance how many input numbers there are.
This is because the for-loop is a definite loop, meaning that the number of iterations is determined when the
loop starts. Thus, we have to count the input numbers before running. Therefore, the program can be
inconvenient especially when we have too many input numbers to count.
Thus, let's write another version of this program that counts the input numbers automatically.

Task: Average of Numbers - version 2


We want the program which runs like this.
Enter a number: 20
Another number? (y or n): y
Enter a number: 25
Another number? (y or n): yes
Enter a number: 15
Another number? (y or n): yeah
Enter a number: 30
Another number? (y or n): no
The average of 4 number(s) is 22.5

The program will be only interested in the first character of these responses (y). Each iteration of the loop
does the following steps:

01204111 Computers and Programming, 132


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1. Read a number.
2. Count and process the number.
3. Then ask if there is more data to enter.
After the user says there is no more data, the program calculates and prints the two results: the count of
numbers and the average. We call the algorithm of such special loop pattern, “the interactive loop”.

Flow chart of Interactive Loop Pattern

Set more_data to 'yes'

False
more_data is 'yes' ?

True

Read the next data item

Process the data item

Ask if there is more_data

Interactive loops allow the user to repeat a certain portion of the program on-demand, by interactive control.
The flow chart of the Interactive loops can be translated into a while-loop algorithm as follows:

Set more_data to 'yes'


while more_data is 'yes':
Read the next data item
Process the data item
Ask if there is more_data

01204111 Computers and Programming, 133


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Let’s look at the python code of function average() which uses the interactive loop. Then, we will compare
in sequence which line of the python code corresponds to which part of the algorithm.

Python code of the interactive loop While-loop algorithm of the interactive loop
1: def average():
2: sum = 0
3: count = 0
4: more_data = 'yes' Set more_data to 'yes'
5: while more_data[0] == 'y': while more_data is 'yes':
6: number = float(input('Enter a number:')) Read the next data item
7: sum = sum + number
8: count = count + 1
} Process the data item
9: more_data = input('Another number? (y or n):') Ask if there is more_data
10: return count, sum/count
11:
12: # ---- main ---- #
13: n, avg = average()
14: print(f'The average of {n} number(s) is {avg}')

The function average() has the sequence of operations like this:


• Set more_data to 'yes': Assign a string 'yes' to more_data (line 4).
• while more_data is 'yes': Check the first character of string more_data. If the first character is
equal to 'y', it can be interpreted that more_data is 'yes', then executes the following statements (line
6 ~ line 9), in each iteration.
o Read the next data item (line 6).
o Process the data item (line 7 and line 8).
sum = sum + number
count = count + 1
o Ask if there is more_data, before ending of the loop.

The main routine is then added (line 13 and 14) to call the function average() and print the results. Test run
result is shown as follows:

01204111 Computers and Programming, 134


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
8.4.3 Common Loop Pattern: Sentinel Loops
From the previous task of the function average() version 2, it's good that the user doesn't have to count the
input numbers before running the program. But the user will surely get quite annoyed by having to type yes
(or the like) for every new input number as follows.
Enter a number: 20
Another number? (y or n): y
Enter a number: 25
Another number? (y or n): yes
Enter a number: 15
Another number? (y or n): yeah
Enter a number: 30
Another number? (y or n): no
The average of 4 number(s) is 22.5

To make the input process easier, we may employ another loop pattern, “the sentinel loop”.
• Sentinel loops (also called sentinel-controlled loops) is a leaner kind of the interactive loops.
• Sentinel loops continue to read and process data until reaching a special value that signals the
end of data.
• This special value is called the sentinel.
• The sentinel must be distinguishable from the data since it is not processed as part of the data.

Flow chat of Sentinel-Loop Pattern

Read the first data

False
item is not the sentinel

True

Process the data item

Read the next data item

01204111 Computers and Programming, 135


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The flow chart of the sentinel loop can be translated into a while-loop algorithm as follows:

Read the first data item


while item is not the sentinel :
Process the data item

Read the next data item

Task: Average of Numbers - version 3


Assume that we are to find the average of test scores, so there will be no input number below 0. Therefore,
our program will use any negative number as the sentinel. We want the program to run like this:
Enter a number (negative to quit): 30
Enter a number (negative to quit): 25
Enter a number (negative to quit): 20
Enter a number (negative to quit): 35
Enter a number (negative to quit): -1
The average of 4 number(s) is 27.5

A negative input number serves as the sentinel that signals the end of data. The average() function #version
3 can be defined as follows. Then, we will compare in sequence which line of the python code corresponds
to which part of the algorithm.

Python code of the sentinel loop While-loop algorithm of the sentinel loop
1: def average(): # version 3 : sentinel loop
2: sum = 0
3: count = 0
4: number = float(input('Enter a number Read the first data item
(negative to quit): '))
5: while number >= 0: while item is not the sentinel :
6: sum = sum + number
7: count = count + 1
} Process the data item
8: number = float(input('Enter a number
(negative to quit): ')) } Read the next data item
9:
10: return count, sum/count
11:
12: # ---- main ---- #
13: n, avg = average()
14: print(f'The average of {n} number(s) is {avg}')

01204111 Computers and Programming, 136


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
• Read the first data item: Read and assign the first data item to number (line 4).
• while Item is not the sentinel: Check the condition number>=0 (line 5). If the condition is True,
then executes the following statements (line 6 and line 7), in each iteration.
sum = sum + number
count = count + 1
Note that the variables sum and count are used as accumulators.
• Read the next data item: Read and assign the data to number before ending each loop (line 8), in
each iteration.

A flaw in function average() - version 3


Let's see what will happen if the first input number is the sentinel itself, which should mean that we have no
data to enter, so there's nothing to calculate. Let's try to predict it first from our code. Suppose we enter the
sentinel value (i.e. any negative number) as the first number (see the statement in line 4 of function
average() #version3). So, the while-loop condition is false at the very first test (in line 5). Therefore, the loop

exits immediately, which means count remains to be 0. That renders sum/count a division by zero, which will
crash the program. A test run proves our prediction.

Handling an empty data set by a run-time error is rather disgraceful. Let's modify our function average()
version 3 to print this more poetic message for empty data set as follows:
Enter a number (negative to quit): -3
The average of 0 number(s) is nothingness
>>>

Just add an if-statement as follows before return statement. This will solve the problem.
if count == 0:
return 0, 'nothingness'

01204111 Computers and Programming, 137


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Let's call the corrected one version 3.1
1: def average(): # version 3.1 : sentinel loop
2: sum = 0
3: count = 0
4: number = float(input('Enter a number (negative to quit): '))
5: while number >= 0:
6: sum = sum + number
7: count = count + 1
8: number = float(input('Enter a number (negative to quit): '))
9: if count == 0:
10: return 0, 'nothingness'
11: return count, sum/count
12:
13: # ---- main ---- #
14: n, avg = average()
15: print(f'The average of {n} number(s) is {avg}')

But even this nice version 3.1 still has a serious shortcoming. It cannot average a data set that contains both
positive and negative numbers because negative numbers have been used as the sentinel.

Hint: If this shortcoming is to be resolved, the sentinel can no longer be a number. Look at the statement in
line 4, the function input() actually returns a string, so we may use a character-based sentinel instead of a
numeric one. In fact, using the empty string ('') as the sentinel is very convenient.

The better version 4.0 of function average() uses the empty string as the sentinel. We want it to run like this:
Enter a number (or just <Enter> to quit): 30
Enter a number (or just <Enter> to quit): 0
Enter a number (or just <Enter> to quit): 25
Enter a number (or just <Enter> to quit): -10
Enter a number (or just <Enter> to quit): -30.5
Enter a number (or just <Enter> to quit): 15.8
Enter a number (or just <Enter> to quit): ↵
The average of 6 number(s) is 5.05

The other output example:


Enter a number (or just <Enter> to quit): ↵
The average of 0 number(s) is nothingness

Note that, the symbol ↵ in the above output example means that the user hits <Enter> as an input. As a
result, the empty string ('') then will be given to the program as an input.
Let this version 4.0 be your programming exercise.

01204111 Computers and Programming, 138


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Now, we are going to show how to use the empty string as the sentinel. Recall that input() always returns
the whole entered line as a string as follows:
>>> s = input('Enter a number: ')
Enter a number: 31.55
>>> s
'31.55'
>>> type(s)
<class 'str'>

We've got to convert such input string to a numeric type (float or int) to be processed as a number.
>>> x = float(s)
>>> x
31.55
>>> type(x)
<class 'float'>
>>> x+3
34.55
>>>

If the user just hit <Enter> here, then input() returns the empty string.
>>> s = input('Enter a number: ')
Enter a number: ↵
>>> s
''
>>> type(s)
<class 'str'>

Now, can you figure out how to use the empty string as the sentinel for a data set.

8.5 One More Example: Finding the Maximum

Task: Maximum of Numbers


Write a function maximum() that reads a data set of nonnegative float numbers and finds the maximum of
them. Since the inputs are all nonnegative, our program will use any negative number as the sentinel. We
want the program to run like this:

01204111 Computers and Programming, 139


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
>>> maximum()
Enter a number (negative to quit): 30
Enter a number (negative to quit): 5.6
Enter a number (negative to quit): 30
Enter a number (negative to quit): 19.5
Enter a number (negative to quit): -3
The maximum is 30.0

The other output example:


>>> maximum()
Enter a number (negative to quit): -1
Nothing to do.

Algorithm design:
Suppose we have three input numbers 20, 25, and 10, a simple procedure to find the maximum could be like
this.

read 20
assign 20 to max
20 >= 0, so do the following:
if 20 > max:
assign 20 to max
read 25
25 >= 0, so do the following:
if 25 > max:
assign 25 to max
read 10
10 >= 0, so do the following:
if 10 > max:
assign 10 to max
read -1
-1 < 0, so the data ends.
print max

Let's use a variable number to hold each input number. This suggests a sentinel-loop algorithm with the loop
condition number>=0. Each iteration in the dotted line squares does the following steps:

01204111 Computers and Programming, 140


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1. If number > max :
assign number to max
2. Read the next number into number.

Thus, we can convert the above iteration to the while-loop as follows:

while number >= 0:


if number > max:
assign number to max
read next number into number

Then, the algorithm of the whole program will be like this.

read number into number


assign number to max
while number >= 0:
if number > max:
assign number to max
read next number into number
print max

Before printing max, we ought to add a check here for the case when the very first number is the sentinel
itself, meaning an empty data set. Thus, the complete function can be defined as follows.
1: def maximum():
2: number = float(input('Enter a number (negative to quit): '))
3: max = number
4: while number >= 0:
5: if number > max:
6: max = number
7: number = float(input('Enter a number (negative to quit): '))
8: if max < 0:
9: print('Nothing to do.')
10: else:
11: print(f'The maximum is {max}')

01204111 Computers and Programming, 141


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Test run result.

8.6 Exercise

1) Fill the blanks (A), (B), (C) to convert the following for-loop into a while-loop.
for i in range(10,22,3):
print(i)

_____(A)_____
while ____(B)____ :
print(i)
____(C)____

2) The version 2 of fah_to_cel() explained in this chapter has two limitations:


• It does not support listing values from high to low.
For example, fah_to_cel(20,10,-1) gives an empty table.
• It has a serious bug that can cause an infinite loop.
For example, fah_to_cel(10,20,-1) produces infinite output.
def fah_to_cel(start, end, step): # version 2
print(f"{'Fahrenheit':>12}{'Celcius':>12}")
print(f"{'----------':>12}{'-------':>12}")
fah = start
while fah < end:
cel = (5/9)*(fah-32)
print(f"{fah:12.2f}{cel:12.2f}")
fah = fah + step
print(f"{'----------':>12}{'-------':>12}")

01204111 Computers and Programming, 142


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Modify the above function so that it allows a start value greater than an end value, and also
prevents an infinite loop.

Examples Output (shell mode):

>>> fah_to_cel(15,20,1)
Fahrenheit Celcius
---------- -------
15.00 -9.44
16.00 -8.89
17.00 -8.33
18.00 -7.78
19.00 -7.22
---------- -------

>>> fah_to_cel(20,15,-1)
Fahrenheit Celcius
---------- -------
20.00 -6.67
19.00 -7.22
18.00 -7.78
17.00 -8.33
16.00 -8.89
---------- -------

>>> fah_to_cel(15,20,-1)
Fahrenheit Celcius
---------- -------
---------- -------

>>> fah_to_cel(20,15,1)
Fahrenheit Celcius
---------- -------
---------- -------

>>>

3) Write a Python program that reads a sequence of numbers from the user, and prints out the
maximum, minimum, and the average of those numbers with two decimal places. The program stops
reading input when the user simply presses <Enter> without entering any number. (I.e., the sentinel is
an empty input.)

Examples Output 1:
Enter a number (just [Enter] to quit): 10
Enter a number (just [Enter] to quit): ↵
The maximum value is 10.00
The minimum value is 10.00
The average value is 10.00

01204111 Computers and Programming, 143


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Examples Output 2:
Enter a number (just [Enter] to quit): 10.2
Enter a number (just [Enter] to quit): 20.5
Enter a number (just [Enter] to quit): -2.6
Enter a number (just [Enter] to quit): -8.98
Enter a number (just [Enter] to quit): ↵
The maximum value is 20.50
The minimum value is -8.98
The average value is 4.78

Examples Output 3:
Enter a number (just [Enter] to quit): ↵
Nothing to do.

4) Write a Python program print the words “Programming” backward as the following output using
while-loop. Note that each character must be in the same line.

Output:
gnimmargorP

01204111 Computers and Programming, 144


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
9. Control structure: Repetition – Part 3

Outline:
9.1 Loop and a Half
9.2 Forever Loops with break
9.3 Nested Loops
9.4 Exercises

9.1 Loop and a Half

The loop and a half is a loop that may exit (on a special condition) somewhere in the middle of the loop
body. Such a premature loop exit could be done by the return statement, or the break statement, or the
continue statement. We will not cover continue in this course, though. It’s quite handy in simple programs

but can make more complex programs harder to comprehend, so some purist programmers tend to avoid
using it.

9.1.1 Loop and a half with the return statement


Look at the following flowchart. Recall that executing the return statement causes the running function to
exit and go back to the caller. Whenever the “special exit condition” (in a second rhombus/diamond shape)
becomes true at an iteration, the return statement will get executed, causing an immediate return to the
caller. This immediate return causes “the rest of the loop body” to be skipped at the last iteration. Thus,
the so-called “the loop and a half”. On the other hand, if “the special exit condition” becomes false at
an iteration, “the rest of the loop body” will get executed.

01204111 Computers and Programming, 145


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Pre-loop statements

False
loop condition

True
early loop body

special exit False


condition
True
return

The rest of loop body

Task: Finding a Character in a String


Write a function find(text,char,index) such that:
• It scans the string text starting at the string index number index, searching for the first occurrence of
the character char. The default index is 0.
• If char is found, it returns the index number of text where char is.
• If char is not found, it returns -1
We want the function find() to behave like this:

01204111 Computers and Programming, 146


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
>>> find('Que sera, sera', 'e', 0)
2
Exactly the same as the previous call
>>> find('Que sera, sera', 'e') since the default starting index is 0.
2
>>> find('Que sera, sera', 'e', 2)
2
>>> find('Que sera, sera', 'e', 6)
11
>>> find('Que sera, sera', 'e', 12)
-1
>>> find('Que sera, sera', 'Q')
0
>>> find('Que sera, sera', 'q')
-1
>>> find('Que sera, sera', ',')
8
>>> find('', 's')
-1
>>>

Algorithm:
Let’s try to figure out what find() should do for this call.
>>> find('Que sera, sera', 'e', 3)

Algorithm:
1: The three parameters:
2: text is 'Que sera, sera'
3: char is 'e'
4: index is 3
5:
6: index is 3 and text[index] != char, so increment index by 1 to become 4
7: index is 4 and text[index] != char, so increment index by 1 to become 5
8: index is 5 and text[index] == char, so char has been found, return index

From the above algorithm, you can see repeated actions from line 6 to line 8. Thus, these repeated actions
suggest a loop algorithm. The loop is to scan text searching for char, so it should iterate over the indexes of
text. Whenever char is found within text, the loop immediately exits via return with the current index (line

8). Therefore, text[index] == char is the special exit condition. Thus, we can convert from the algorithm to
the code as follows:
1: def find(text, char, index=0):
2: textlength = len(text)
3: while index < textlength:
4: if text[index] == char:
5: return index
6: index = index + 1
7:
8: return -1

01204111 Computers and Programming, 147


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
First, in line 1 of the program, we set the default starting index to 0. The loop iterates over the indexes of
text which can be seen in line 3. Each iteration keeps looking for char within text by using if statement, as

you can see in line 4. When char has been found in text, the condition text[index]==char which is the
special exit condition becomes true, and then return statement in line 5 will get executed, causing an
immediate return of index to the caller. Note that, line 8 is a normal exit of the loop means char is not
found in text.
The test run result is shown as follows:

9.1.2 For loop and a half


The loop-and-a-half with the return statement can be implemented by the for statement as well. As an
example, let’s implement a much simpler, scaled-down version of find(). Call it the function has_char()
which runs like this:
>>> has_char('Que sera, sera', 'e')
True
>>> has_char('Que sera, sera', '3')
False

01204111 Computers and Programming, 148


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The function has_char() requires two parameters, a string and a character. It returns True if the string
contains the character at least once, or False otherwise. This function can use the same algorithm as find(),
except that it doesn't have to care about the indexes at all. Thus, the function has_char() can be defined as
follows:
def has_char(text, char):
"""returns True
if there is the character <char> in the string <text>
or False otherwise"""
for c in text:
if c == char:
return True
return False

As you can see in the above program, a for loop containing a return statement is also “a loop and a half”.

9.1.3 Loop and a half with the break statement

Pre-loop statements

loop False
condition
True

early loop body

special exit False


condition
True

break

The rest of loop body

01204111 Computers and Programming, 149


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
From the flowchart, executing the break statement terminates the loop in which it is contained, and transfers
control to the code (the statement) immediately following the loop. Whenever the “special exit condition”
(in a second rhombus/diamond shape) becomes true at an iteration, the break statement will get executed,
causing an immediate break out of the loop (go to the first statement following the loop). This immediate
break causes “the rest of the loop body” to be skipped at the last iteration. Thus, the so-called “loop and
a half”. On the other hand, if “the special exit condition” becomes false at an iteration, “the rest of the
loop body” will get executed.

Back to the function find(), we are going to create the alternative version using break. The previous version
of function find() is as follows:

def find(text, char, index=0): #version 1


textlength = len(text)

while index < textlength:


if text[index] == char:
return index
index = index + 1

return -1

Instead of the immediate return the value of index inside the dashed line square, it can break out of the
loop first and then return the result after the loop. Thus, the function find() version 2 can be modified as
follows:

def find(text, char, index=0): #version 2


result = -1
textlength = len(text)

while index < textlength:


if text[index] == char:
result = index
break
index = index + 1

return result

First, it initializes the result to the not found status by assigning -1 to result. In the dashed line square,
whenever char is found in text, the current index is the result, then break out of the loop. Finally, notice

01204111 Computers and Programming, 150


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
that if char is never found in text, the loop will exit normally and result remains to be -1. On the other
hand, if char is found in text, result which has already been assigned the value of index will be returned.
You can see that both versions work effectively the same.

Let’s create the alternative version of the function has_char() using break. The previous version of the
function has_char() is as follows:

def has_char(text, char): #version 1

for c in text:
if c == char:
return True

return False

Instead of the immediate return in a dashed line square, it can break out of the loop first and then return the
result after the loop. Thus, the function has_char() version 2 can be modified as follows.

def has_char(text, char): #version 2


result = False

for c in text:
if c == char:
result = True
break

return result

First, it initializes the result to False (the not found status). Whenever char is found, set result to True (the
found status), then break out of the loop. Notice that if char is never found in text, the loop will exit
normally and result remains to be False.

01204111 Computers and Programming, 151


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
9.2 Forever Loop with break

9.2.1 The Forever Loop


Some algorithms call for a loop that repeats its body unconditionally, i.e. without a loop condition. Thus, the
so-called “forever loop” repeats forever. The forever loop with break is a more sensible kind of the forever
loop. Though it has no loop condition to check before each iteration, it may exit on a specified exit condition
somewhere in the middle of the loop body. Therefore, the forever loop with break is a special, simple kind of
the loop and a half.

The Forever Loop with break is not “forever”.

Pre-loop statements

early loop body

exit False
condition
Ture

break

The rest of loop body

01204111 Computers and Programming, 152


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Without any loop condition, the loop body is repeated unconditionally, thus the term "forever loop".
Whenever this exit condition becomes true at an iteration, the break statement will get executed, causing an
immediate break out of the loop (go to the first statement following the loop). The immediate break causes
the rest of the loop body to be skipped at the last iteration. In Python, since the loop condition True is
always true, the loop repeats forever as the following process.

pre-loop statements
while True:
early loop body
if exit_condition == True
break
the rest of loop body

This break upon exit_condition makes it possible for the loop to terminate eventually.

A Simple Example:
1: print('Hi there.')
2: while True:
3: s = input('Enter something: ')
4: if s == 'quit':
5: break
6: print(f'You entered {len(s)} characters')
7: print('Bye now.')

The program is asking the user to input something (in line 3). Then, it checks the condition if the inputted
string is 'quit' or not. If the condition is true, it immediately breaks out of the loop and goes to execute the
first statement following the loop in line 7. Otherwise, the program continues asking for the input. The test
run example is shown as follows.
Hi there.
Enter something: python
You entered 6 characters
Enter something: Time flies.
You entered 11 characters An empty line is entered.
Enter something:
You entered 0 characters
Enter something: quit This word hits the exit condition.
Bye now.
>>>

01204111 Computers and Programming, 153


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Revisited to the sentinel-loop pattern from the previous chapter.

Read next data item

False
item is not the sentinel

True

Process the data item

Read the next data item

The flow chart of the sentinel loop can be translated into a while-loop algorithm as follows:

Read next data item


while item is not the sentinel :
Process the data item

Read the next data item

Sentinel-loop pattern requires two of the same read statements, one before the loop, and the other within
the loop. A forever loop with break can reduce to only one read. Now, rewrite it as a forever loop having
only one read call “The Sentinel Loop via the Forever Loop” as follows. Note that, both patterns work
effectively the same.
while True :
Read next data item
if item is the sentinel:
break
Process the data item

01204111 Computers and Programming, 154


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Example:
The standard sentinel loop with two reads.
number = float(input('Enter a number (negative to quit): '))
while number >= 0:
sum = sum + number
count = count + 1
number = float(input('Enter a number (negative to quit): '))

An alternative forever loop with one read


while True:
number = float(input('Enter a number (negative to quit): '))
if number < 0:
break
sum = sum + number
count = count + 1

More Example - Input Validation:


Suppose we want to write a function read_positive() that reads and returns only a positive number. If the
user enters a zero or a negative number, it continues to prompt until the user enters a valid number. A
function read_positive() should behave like this:
>>> read_positive()
Enter a positive number: 0
0.0 is not positive. Please retry.
Enter a positive number: -3
-3.0 is not positive. Please retry.
Enter a positive number: -10.75
-10.75 is not positive. Please retry.
Enter a positive number: 7
7.0
>>>

The function read_positive() by a forever loop with break can be defined as follows:
1: def read_positive():
2: """reads and returns only a positive number.
3: Invalid input will prompt the user to re-enter.
4: """
5: while True:
6: n = float(input('Enter a positive number: '))
7: if n > 0: # valid input
8: break
9: print(f'{n} is not positive. Please retry.')
10: return n

01204111 Computers and Programming, 155


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
It's easy to implement the function with a forever loop with break. Note that this reverses the sense of the
usual sentinel loop because it will break out of loop whenever the input is valid and normal.

9.3 Nested Loops


In the topic of multiple selections, we've learned that we can nest if statements. We can also nest loops.
When a for or a while statement is put within another for or while statement, we've got nested loops as
follows:

for k in range(1, 4):


i = 1

while i <= k:

for _ in range(i):
print('$', end='')

print()
i = i+1

print(i) if x > y: for i in range(4): while i <= k: while True:


m = x k = 2*i-1 print(i*'$') s = input('>')
else: print(k*'$') sum = sum+i if s == 'quit':
x = y+1 m = y i = i+1 break
print(len(s))

Each box above is actually a single statement. Thus, each can put into any statement (statement ~
1

statement ) as in the example of the following programs.


6

while condition: for var in sequence:


statement1 statement4
statement2 statement5
statement3 statement6

Nested Loops happen naturally on demand. Suppose we want to write a line of n dollar-signs ($) where n is a
given positive integer. A single call of print() can do the task.
>>> n = 5
>>> print(n*'$')
$$$$$

01204111 Computers and Programming, 156


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
This for-loop also produces the same result.
>>> n = 5
>>> for i in range(n):
print('$', end='')
The default value of end is '\n'
$$$$$

Let’s convert from line to a right triangle.


Suppose we chose to use the above for-loop to write a line of n dollar-signs ($). Next, we want to write k
lines of 1, 2, …, k dollar-signs successively so they look like a right triangle. The output when k is 5 shown as
follows:
$
$$
$$$
$$$$
$$$$$

We can use a counting while-loop that repeats the above for-loop with the counter n running from 1 to k.
Suppose k is 5. Thus, the program can be defined as follows:
k = 5 # prints a right triangle with the base of length k
n = 1
while n <= k:
for i in range(n):
print('$', end='')
print()
n = n+1

Note that, the empty print() is added to make the next print() start at a new line.

Now, let’s convert from right triangles to a saw. Here, as shown above, we have already got a program that
writes a right triangle with the base of k dollar-signs, where k is a given positive integer.

Next, we want to write m right triangles, each with the base of k dollar signs so they look like a saw of m teeth,
where m is a given positive integer. Thus, the output when m is 3 and k is 5 shown as follows:

01204111 Computers and Programming, 157


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
$
$$
$$$
$$$$
$$$$$
$
$$
$$$
$$$$
$$$$$
$
$$
$$$
$$$$
$$$$$

k = 5 # prints a right triangle with the base of length k


n = 1
while n <= k:
for i in range(n):
print('$', end='')
print()
n = n+1

Again, from the code that prints a right triangle with the base of length k as shown above, we can use a
simple for-loop that repeats the above code m times. Suppose m is 4, so now we've got a program that writes
a saw of m teeth, where m is a given positive integer as follows.

1: m = 4
2: for j in range(m):
3: k = 5 # prints a right triangle with the base of length k
4: n = 1
5: while n <= k:
6: for i in range(n):
7: print('$', end='')
8: print()
9: n = n+1

The output when m is 4 shown as follows.

01204111 Computers and Programming, 158


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
$
$$
$$$
$$$$
$$$$$
$
$$
$$$
$$$$
$$$$$
$
$$
$$$
$$$$
$$$$$
$
$$
$$$
$$$$
$$$$$

Now, let’s encapsulate our saw's code into a function saw() that has three parameters:
• nteeth – the number of saw teeth.
• baselength – the number of symbols at the base of each tooth.
• symbol – the symbol used to build the saw.

In the program m is renamed to nteeth, k is renamed to baselength, '$' is replaced by symbol. Thus, the
complete code is modified as follows:

1: def saw(nteeth, baselength, symbol):


2: for j in range(nteeth):
3: n = 1
4: while n <= baselength:
5: for i in range(n):
print(symbol, end='')
6:
print()
7: n = n + 1
8:

Testing the function saw().

01204111 Computers and Programming, 159


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
def saw(nteeth, baselength, symbol): # version 1
for j in range(nteeth):

n = 1
while n <= baselength:
for i in range(n):
print(symbol, end='')
print()
n = n + 1

The counting while-loop inside the dashed line square in the version 1 of function saw() can be replaced by
a for-loop to become the version 2 of function saw() as follows.

01204111 Computers and Programming, 160


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
def saw(nteeth, baselength, symbol): #version 2
for j in range(nteeth):

for n in range(1, baselength+1):

for i in range(n):
print(symbol, end='')
print()
s

The innermost for-loop and a print() inside the dotted line square that prints a line can be replaced by a
single print() to become the version 3 of function saw() as follows.

def saw(nteeth, baselength, symbol): #version 3


for j in range(nteeth):

for n in range(1, baselength+1):

print(n*symbol)

The inner for-loop inside the dashed line square in the version 3 of function saw() that prints a saw tooth
can be factored out to become a function print_a_tooth(). Thus, the function saw() in this new version 4
has only a single loop that is much easier to understand than the nested-loop versions.

def print_a_tooth(size, symbol):


for n in range(1, size+1):
print(n*symbol)

def saw(nteeth, baselength, symbol): #version 4


for j in range(nteeth):

print_a_tooth(baselength, symbol)

This process of replacing part of a program by a subroutine call is called "refactoring", which may produce a
better program.

01204111 Computers and Programming, 161


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Task: Decimal-to-Binary Conversion
Write a program that repeatedly reads a decimal non-negative integer and converts it into its binary
equivalent. The program exits when the input is negative. The program runs like this:
Enter a nonnegative integer (or negative to quit): 6
Binary number is 110
Enter a nonnegative integer (or negative to quit): 233
Binary number is 11101001
Enter a nonnegative integer (or negative to quit): 0
Binary number is 0
Enter a nonnegative integer (or negative to quit): -3
Bye!

Algorithm of the main routine:


A sentinel loop via a forever loop with break.

while True:
Read n
if n is negative:
break
Convert n to binary and print the result
print 'Bye!'

Translate the above algorithm into Python code as follows:


1: while True:
2: n = int(input('Enter a nonnegative integer (or negative to quit): '))
3: if n < 0:
4: break
5: print('Binary number is', dec_to_bin(n))
6: print('Bye!')

The function dec_to_bin() will do the conversion from the decimal number into its binary equivalent.

Algorithm of dec_to_bin():
Let’s convert 13 to binary. These are the expressions for the conversion, step by step.

Step1: 13//2 = 6; 13%2 = 1 #13 divined by 2 is 6, and the remainder is 1


Step2: 6//2 = 3; 6%2 = 0 # 6 divined by 2 is 3, and the remainder is 0
Step3: 3//2 = 1; 3%2 = 1 # 3 divined by 2 is 1, and the remainder is 1
Step4: 1//2 = 0; 1%2 = 1 # 1 divined by 2 is 0, and the remainder is 1

01204111 Computers and Programming, 162


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Thus, 13 in decimal is converted to 1101 in binary (read the remainder from bottom to top). Notice that the
repeated division is done at least once for any input number.

Loop design:
Now, we are going to convert 6 in decimal to binary.

iteration n
quotient remainder binary updated next iteration?
n//2 n%2 n

Pre-loop 6 ""

1st 6 3 0 "0" 3 Yes

2nd 3 1 1 "10" 1 Yes

3rd 1 0 1 "110" 0 No

From the table, n is the given decimal number. In this example, 6 is given as an input. At the 1st iteration, 6 is
divided by 2 gives 3 as the answer(“quotient”) and 0 as the remainder, then we put that answer (3) into the
column “updated n”. After that, put that remainder (0) into the column “binary” as a string ("0"). Then,
check if “updated n” is 0 or not, and put the answer of “Yes” or “No” into the column of “next iteration?”
For the 2nd iteration, we start with n = 3 and do the same things as in the 1st iteration. At the 3rd iteration,
because “next iteration?” is “No”, so we end our calculation here. Finally, we can obtain “110” which is
written in the column of “binary” as our answer.
Note that, we can combine the string using the plus operator (+). For example, "1"+"0" is “10”. Then, we can
translate the mentioned steps to python code as follows:

1: # n is given as a parameter
2: binary = ''
3: while True:
4:
5: quotient = n // 2
6: remainder = n % 2
7: binary = str(remainder) + binary
8: n = quotient
9:
10: if n == 0 :
11: break

01204111 Computers and Programming, 163


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Since the loop body will be executed at least once, a suitable loop pattern for this task is a forever loop with
a check for break at the bottom. Note that, the built-in function str() converts a number into a string (line
7). After assignments, the variables quotient and remainder are referenced only once (in a dashed line
square), so we can do away with them to make the code simpler.

1: # n is given as a parameter
2: binary = ''
3: while True:
4:
5: binary = str(n % 2) + binary
6: n = n // 2;
7:
8: if n == 0 :
9: break

Encapsulate it into the function dec_to_bin(n) as follows:


1: def dec_to_bin(n):
2: """returns the binary representation of integer n
3: """
4: binary = ''
5: while True:
6: binary = str(n % 2) + binary
7: n = n // 2
8: if n == 0:
9: break
10: return binary

Once the loop exits, the variable binary (in line 10) is the result of the conversion. The main program added
to finish the program as follows:
1: def dec_to_bin(n):
2: """returns the binary representation of integer n
3: """
4: binary = ''
5: while True:
6: binary = str(n % 2) + binary
7: n = n // 2
8: if n == 0:
9: break
10: return binary
11:
12: # ---- main ---- #
13: while True:
14: n = int(input('Enter a nonnegative integer (or negative to quit): '))
15: if n < 0:
16: break
17: print('Binary number is', dec_to_bin(n))
18: print('Bye!')

01204111 Computers and Programming, 164


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Test run result:

9.4 Exercises
1) Fill in the blank (A) to complete the following program so that the loop stops when it has found
the smallest positive integer greater than 1000 that is divisible by both 33 and 273.
n = 1001

while True:
_____________
_____(A)_____

print(f"The value of n is {n}")

Output:
The value of n is 3003

2) Fill in the blank (A) and (B) to complete the code so that it gives the output as shown.

for i in _____(A)_____ :
print(f"i = {i}")
for j in _____(B)_____ :
print(f" j = {j}")

Output:
i = 5
j = 1
j = 2
i = 6
j = 1
j = 2
i = 7
j = 1
j = 2
i = 8
j = 1

01204111 Computers and Programming, 165


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
j = 2
i = 9
j = 1
j = 2

3) Fill in the blank (A) (B) (B) to complete the code so that it gives the output as shown.
for i in range(3):
for j in _____(A)_____ :
nspaces = _____(B)_____
nstars = _____(C)_____
print((' ' * nspaces) + ('*' * nstars))

Output:
*
***
*****
*******
*
***
*****
*******
*
***
*****
*******

4) Write a Python program to show the multiplication table of N from N x 1 to N x 12. The program
will continue to ask for another value N until the user presses ENTER without giving any value.

Example Output:
Input value of N (or just ENTER to quit): 12↵
12 x 1 = 12
12 x 2 = 24
12 x 3 = 36
12 x 4 = 48
12 x 5 = 60
12 x 6 = 72
12 x 7 = 84
12 x 8 = 96
12 x 9 = 108
12 x 10 = 120
12 x 11 = 132
12 x 12 = 144
Input value of N (or just ENTER to quit): ↵

*********

01204111 Computers and Programming, 166


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
5) Create a program to generate random numbers between 0-99. After the user enters the number
he/she wants to guess, the program shows "too LOW" when the guess number is lower than a
random number, and shows "too HIGHT" when the guess number is higher than a random
number. And it shows "correct" when the guess number is a random number. Besides, the
program allows incorrect guess number up to only 7 times.

Note: Import the random function as follows to generate a random number (in this exercise use
integer number).
>>> import random
>>> number = random.randint(0,99)
>>> number
67

Example Output 1:
Round [1] >> Enter the number (0-99): 20
too LOW
Round [2] >> Enter the number (0-99): 50
too HIGHT
Round [3] >> Enter the number (0-99): 30
too LOW
Round [4] >> Enter the number (0-99): 40
too HIGHT
Round [5] >> Enter the number (0-99): 35
CORRECT

Example Output 2:
Round [1] >> Enter the number (0-99): 99
too HIGHT
Round [2] >> Enter the number (0-99): 1
too LOW
Round [3] >> Enter the number (0-99): 60
too LOW
Round [4] >> Enter the number (0-99): 80
too HIGHT
Round [5] >> Enter the number (0-99): 62
too LOW
Round [6] >> Enter the number (0-99): 68
too LOW
Round [7] >> Maximum attempts exceeded.

01204111 Computers and Programming, 167


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
10. List

Outline:

10.1 Processing collection of data using lists


10.2 List creation and manipulation
10.3 Various functions on lists
10.4 Exercise

10.1 Processing collection of data using lists

10.1.1 Storing Collection of Data


Python provides many built-in data types to store a group of data
• list – an ordered collection of objects.
• tuple – immutable version of list.
• dict – a collection of key-value mapping.
• set – an unordered collection of distinct objects.
And a lot more in the standard collection’s module. But this course will focus only on list.

Quick Task: Find Average


Find the average score of students. The program behaves as follows:
Enter student score (or ENTER to finish): 24
Enter student score (or ENTER to finish): 26
Enter student score (or ENTER to finish): 28
Enter student score (or ENTER to finish): 32
Enter student score (or ENTER to finish):
Average score is 27.5

The program should be straightforward as follows:

01204111 Computers and Programming, 168


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: sum = 0
2: count = 0
3: while True:
4: ans = input("Enter student score (or ENTER to finish): ")
5: if ans == "":
6: break
7: score = float(ans)
8: sum = sum + score
9: count = count + 1
10: avg = sum/count
11: print(f"Average score is {avg}")

From the program, while loop is used to receive numbers from user. After the user inputs a number in each
iteration (line 4), the program checks the condition if that input (ans) is empty string or not (line 5). If the
condition is true, loop will stop by break (line 6). Otherwise, that input (ans) is converted to float and
assigned to a variable score, then accumulated into a variable sum. Variable count is used to count a number
of the input. Finally, the average(avg) is calculated (line 10).

Task: Find Below Average


Similar to Find Average, but also list the scores that are below the average. The program behaves as follows:
Enter student score (or ENTER to finish): 24
Enter student score (or ENTER to finish): 26
Enter student score (or ENTER to finish): 28
Enter student score (or ENTER to finish): 32
Enter student score (or ENTER to finish):
Average score is 27.5
Scores below average:
24
26

Ideas: We need to keep track of every single score. Thus, writing a program by declaring one variable for one
score is very inflexible. We cannot even control how many times to read scores.
s1 = float(input("Enter student score: "))
s2 = float(input("Enter student score: "))
s3 = float(input("Enter student score: "))
:

Storing a list of data


Python provides the list data type to store a list of objects

01204111 Computers and Programming, 169


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: scores = []
2: while True:
3: score = input("Enter score (or ENTER to finish): ")
4: if score == "":
5: break
6: score = int(score)
7: scores.append(score)
8: print("Scores are:", scores)

Line 1 is the statement that creates an empty list. Then a new element is appended to that list at line 7.

10.2 List creation and manipulation

10.2.1 List Creation


• Create an empty list
list1 = []

• Create a list containing 4 integers: 20, 12, 8, 6


list2 = [20, 12, 8, 6]

• Create a list containing 3 floats: 1.2, 3.1, 8.0


list3 = [1.2, 3.1, 8.0]

• Create a list containing 2 strings: "Hello", "Goodbye"


list4 = ["Hello", "Goodbye"]

• Create a list with mixed data types


list5 = ["Hello", 9, 3.8]

10.2.2 List Member Access


Members in a list can be accessed using the [] operator with an index (similar to strings) as follows:
>>> lst = [8,3,2,5,3,1,6]
>>> lst[0]
8
>>> lst[1]
3
>>> lst[-1]
6
Reminder: index starts from 0

01204111 Computers and Programming, 170


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Lists Are Mutable
Unlike strings, list's contents can be changed.
>>> lst = [8,3,9,5,3,1,6]
>>> lst
[8, 3, 9, 5, 3, 1, 6]
>>> lst[2] = 38
>>> lst
[8, 3, 38, 5, 3, 1, 6]

A new element can be added by using the list.append() method (a method is a function bound to an
object).
>>> lst
[8, 3, 38, 5, 3, 1, 6]
>>> lst.append(72)
>>> lst
[8, 3, 38, 5, 3, 1, 6, 72]

10.2.3 List's Length and List Traversal


The function len() returns the length of a list. A list can be used as a sequence of a for loop.

>>> lst = [8,3,2,5,3,1,6]


>>> len(lst)
7
>>> for x in lst:
print(x)

8
3
2
5
3
1
6

Revisit the task to Find Below Average.


Ideas: We will divide the task into smaller subtasks.
• read_scores() – reads and returns scores as a list.
• compute_average(scores) – computes the average from a list of scores
• print_below(scores,value) – prints only scores that are below the given value
We will then write a subroutine for each of these subtasks.

01204111 Computers and Programming, 171


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Flow charts of each subtask:

Flow chart of the Main program is shown as follows.

START

scores  read all scores

average  average of scores

display average

print all values in scores that are below average

END

Flow chart of subroutine read_scores() shown as follows.

01204111 Computers and Programming, 172


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
read all scores

scores  empty list

False
more score?

True

append score to scores

return scores

Flow chart of subroutine compute_average(scores) shown as follows.

compute average of scores

total  sum of all scores

count  number of scores

average  total/count

return average

01204111 Computers and Programming, 173


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Flow chart of subroutine print_below(scores,value) shown as follows.

print all values in scores


that are below value

False
more item in scores? return

True

read next score from scores

False
score less than value?

True

print score

Python code of each subroutine:


1: def read_scores():
2: scores = []
3: while True:
4: ans = input("Enter student score (or ENTER to finish): ")
5: if ans == "":
6: break
7: scores.append(int(ans))
8: return scores

1: def compute_average(scores):
2: sum = 0
3: for s in scores:
4: sum = sum + s
5: return sum/len(scores)

01204111 Computers and Programming, 174


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: def print_below(scores,value):
2: for s in scores:
3: if s < value:
4: print(s)

Built-in Function: sum()


sum(lst) returns the summation of all the items in the list lst

>>> sum([1,2,3,4])
10
>>> sum([10,50,21,27])
108
>>> sum(range(101))
5050

Therefore, compute_average() can be rewritten as;


1: def compute_average(scores):
2: return sum(scores)/len(scores)

Testing:
Once we have defined all subroutines, let us test them one by one
• Testing read_scores()

• Testing compute_average()

01204111 Computers and Programming, 175


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
• Testing print_below()

Once we have tested all subroutines, let us write the main program as follows:

1: scores = read_scores()
2: avg = compute_average(scores)
3: print(f"Average score is {avg}")
4: print("Scores below average:")
5: print_below(scores,avg)

Test run result.

10.3 Various operations on lists

10.3.1 Finding Min and Max


In addition to sum(), Python also provides min() and max() functions
• min(lst) returns the minimum value in the list lst
• max(lst) returns the maximum value in the list lst

01204111 Computers and Programming, 176


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
>>> nums = [6,2,4,8,1,2]
>>> min(nums)
1
>>> max(nums)
8

Task: Score Statistics


Read a list of scores and report the summary table, along with average, minimum, and maximum scores. The
program behaves as follows.
Enter student score (or ENTER to finish): 24
Enter student score (or ENTER to finish): 26
Enter student score (or ENTER to finish): 28
Enter student score (or ENTER to finish): 32
Enter student score (or ENTER to finish):
Student #1 score: 24
Student #2 score: 26
Student #3 score: 28
Student #4 score: 32
Average score is 27.5
Minimum score is 24
Maximum score is 32

Ideas:
Most subroutines from the previous example can be reused (read_scores, compute_average). Min and max
can be computed using the built-in functions. The only challenge is the summary table part which is defined
as show_score_summary(scores) (in line 2) in the following code.
1: scores = read_scores()
2: show_score_summary(scores)
3: avg_score = compute_average(scores)
4: min_score = min(scores)
5: max_score = max(scores)
6: print(f"Average score is {avg_score}")
7: print(f"Minimum score is {min_score}")
8: print(f"Maximum score is {max_score}")

The summary needs to display the order of each student's score as shown in the test run result in the
following dotted line square. Thus, a for loop with a combination of len() and range() can help.

01204111 Computers and Programming, 177


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Enter student score (or ENTER to finish): 24
Enter student score (or ENTER to finish): 26
Enter student score (or ENTER to finish): 28
Enter student score (or ENTER to finish): 32
Enter student score (or ENTER to finish):
Student #1 score: 24
Student #2 score: 26
Student #3 score: 28
Student #4 score: 32
Average score is 27.5
Minimum score is 24
Maximum score is 32

Newly defined show_score_summary() and Main program are shown as follows.


1: scores = read_scores() # Main program
2: show_score_summary(scores)
3: avg_score = compute_average(scores)
4: min_score = min(scores)
5: max_score = max(scores)
6: print(f"Average score is {avg_score}")
7: print(f"Minimum score is {min_score}")
8: print(f"Maximum score is {max_score}")
9:
10:
11: def show_score_summary(scores):
12: for i in range(len(scores)):
13: print(f"Student #{i+1} score: {scores[i]}")

Let's test the program.


>>> show_score_summary([31,56,73,48])
Student #1 score: 31
Student #2 score: 56
Student #3 score: 73
Student #4 score: 48

10.3.2 List vs. String


Lists and strings share many similarities.
• Member access with []
• The len() function
• Their use with for loop
The main difference is lists are mutable but strings are immutable.

01204111 Computers and Programming, 178


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Example which shows that list is mutable.
>>> L = [1,2,3,4,5]
>>> L[3] = 8
>>> L
[1, 2, 3, 8, 5]

From the above example, instead of 4, a new value of 8 was assigned to the place of Index number 3.

Example which shows that string is immutable.


>>> s = 'Hello'
>>> s[3] = 'c'
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
s[3] = 'c'
TypeError: 'str' object does not support item assignment

From the above example, it shows that we cannot change any character in the string.

Caveats – Lists are mutable


Assigning two or more names to the same list may have undesired effect
>>> nums1 = [1,2,4,8]
>>> nums2 = nums1 nums1 1 2 20 8
>>> nums2[2] = 20
>>> nums1
[1, 2, 20, 8] nums2

From the above example, after creating a list of numbers (in the first line), nums1 is then assigned to nums2 by
equal (=) operator (in the second line). That means both variables nums1 and nums2 are associated/assigned
with the same list of numbers. Thus, when some member in one variable has been changed ( nums2[2]=20
in the example), the member at the same index number of the other variable (nums1[2]) will be also
changed accordingly. To prevent this behavior, making a copy of a list by using list() function instead is
recommended.
>>> nums1 = [1,2,4,8]
>>> nums2 = list(nums1)
>>> nums2[2] = 20 nums1 1 2 4 8
>>> nums1
[1, 2, 4, 8]
>>> nums2 nums2 1 2 20 8
[1, 2, 20, 8]

01204111 Computers and Programming, 179


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
From the above example, by the second statement nums2=list(nums1), list of numbers of nums1 is copied to
nums2. This means that the variables nums1 and nums2 are not associated with the same list of number, but

they are independent of each other. Therefore, even a member of one variable is changed (nums2[2]=20 in
the example), the member of the other variable are not affected at all.

10.3.2 Other operators using with list.

Membership Test
Using the in operator to check if a specified value exists in a sequence (list or string) or not.
>>> numbers = [5,1,8,2,7]
>>> 5 in numbers
True
>>> 9 in numbers
False

The in operator also works with strings


>>> s = "Hello"
>>> "e" in s
True
>>> "L" in s
False
>>> "lo" in s
True

Membership Test – Example


The following code counts the number of vowels (a,e,i,o,u) in the given text
text = input("Enter a text: ")
count = 0
for c in text:
if c in "AEIOUaeiou":
count = count + 1
print(f"Found {count} vowel(s)")

Test run result.


Enter a text: Hello
Found 2 vowel(s)

Enter a text: Good morning


Found 4 vowel(s)

01204111 Computers and Programming, 180


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
List Slicing
Slicing creates a new list as a subset of an existing list.

Slicing syntax for a list L:


L[start:stop:step]

The newly created list is:


[L[start],L[start+step],L[start+2step],…]

• The last member DOES NOT include L[stop]


• start can be omitted, implying 0
• stop can be omitted, implying list's length
• step can be omitted, implying 1

Examples – List Slicing


Specifying start and stop.
>>> L = [1,4,9,16,25,36,49]
>>> L[2:4]
[9, 16]

Specifying only start.


L[1:]
[4, 9, 16, 25, 36, 49]

Specifying only stop


>>> L[:5]
[1, 4, 9, 16, 25]

Specifying start, stop, and step


>>> L[1:6:2]
[4, 16, 36]

01204111 Computers and Programming, 181


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Specifying a negative step
>>> L[::-1]
[49, 36, 25, 16, 9, 4, 1]

Specifying nothing (copying list)


>>> L[:]
[1, 4, 9, 16, 25, 36, 49]

The following code slices a list of month names into four quarters.
1: months = [
2: 'Jan','Feb','Mar','Apr','May','Jun',
3: 'Jul','Aug','Sep','Oct','Nov','Dec'
4: ]
5:
6: q1 = months[0:3]
7: q2 = months[3:6]
8: q3 = months[6:9]
9: q4 = months[9:12]
10: print("Quarter 1:", q1)
11: print("Quarter 2:", q2)
12: print("Quarter 3:", q3)
13: print("Quarter 4:", q4)

Test run result:

01204111 Computers and Programming, 182


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
10.4 Exercises

1) Fill in the blank (A) so that it gives the output in the shell as shown.
>>> nums = _____(A)_____
>>> len(nums)
5
>>> min(nums)
3
>>> max(nums)
10
>>> sum(nums)
34

2) Fill the blank (A) to complete the code so that it prints out every third member of the list seq in the
order from first to last, starting from the second member. Your code must also work with any
contents of seq.
seq = [2,3,5,7,11,13,17,19]
for i in _____(A)_____:
print(seq[i])

Output:
3
11
19

If seq is [1,2,3,4,5,6,7] instead, the output will be:


2
5

3) Fill in the blank (A) to complete the code so that it prints out all members of the list seq in the
order from last to first. Your code must also work with any contents of seq.
seq = [2,3,5,7,11,13,17,19]
for i in _____(A)_____:
print(seq[i])

Output:
19
17
13
11

01204111 Computers and Programming, 183


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
7
5
3
2

If seq is [1,2,3,4,5,6,7] instead, the output will be:


7
6
5
4
3
2
1

4) Write a Python program that asks user to enter a sequence of scores with an empty input to indicate
the end of the score sequence. The program then prints out all the scores ranked from the highest
to the lowest.

Example Output 1:
Enter student score (or ENTER to finish): 13↵
Enter student score (or ENTER to finish): 19↵
Enter student score (or ENTER to finish): 10↵
Enter student score (or ENTER to finish): ↵
Rank #1: 19
Rank #2: 13
Rank #3: 10

Example Output 2:
Enter student score (or ENTER to finish): 87↵
Enter student score (or ENTER to finish): 56↵
Enter student score (or ENTER to finish): 73↵
Enter student score (or ENTER to finish): 59↵
Enter student score (or ENTER to finish): 90↵
Enter student score (or ENTER to finish): 72↵
Enter student score (or ENTER to finish): ↵
Rank #1: 90
Rank #2: 87
Rank #3: 73
Rank #4: 72
Rank #5: 59
Rank #6: 56

01204111 Computers and Programming, 184


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
11. More Lists, File Input and Text Processing

Outline:

11.1 Reading text files


11.2 Creating lists from other sequences using list comprehensions
11.3 Tabular data and nested lists
11.4 Exercise

11.1 Reading text files

11.1.1 Creating a Text File


A text file can be created using any text editor such as Notepad in Microsoft Window or TextEdit in Mac OS.
IDLE is also a text editor, follow these steps to create a text file.
• Choose menu File  New File and start writing content.

• Save a file with .txt extension, not .py

11.1.2 Reading File with Python


Reading file's contents as a single string can be done by combining open() function with file.read()
method as follows. Note that open() returns a file object, and file.read() returns a string.
open(filename).read()

01204111 Computers and Programming, 185


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Test run result with a file named data.txt that contains two lines:

data.txt

Hello
Good morning

>>> s = open("data.txt").read()
>>> s
'Hello\nGood morning\n'

Reading file's contents as a list of strings, one per line can be done as follows. Note that method
str.splitlines() returns a list.

open(filename).read().splitlines()

Test run result with the same file named data.txt .


>>> lines = open("data.txt").read().splitlines()
>>> lines
['Hello', 'Good morning']

Functions vs. Methods


A method is a function bound to an object.
Functions are called by just their names (e.g., len(), sum())
>>> len
<built-in function len>
>>> len("abc")
3

Methods are called with their names and objects they are bound to (e.g., str.split(), where str is replaced
by a string)
>>> s = "Hello, World"
>>> s.split
<built-in method split of str object at 0x109665e70>
>>> s.split(",")
['Hello', ' World']

Text File Reader – Program


We want a program that reads lines from a specified text file and displays them along with their line
numbers.

01204111 Computers and Programming, 186


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Ideas:
Create a program that reads a text file as a list of strings, then traverses the list to print out each line.

Text file
data.txt

Hello
Good morning

Program:
filename = input("Enter file name: ")
lines = open(filename).read().splitlines()
for i in range(len(lines)):
print(f"Line {i+1}: {lines[i]}")

Test run result.


Enter file name: data.txt
Line 1: Hello
Line 2: Good morning

File Location Matters


If the text file is located in the same folder as the program just type the file name, i.e., data.txt. If not, the
entire path name of the file must be used, e.g., C:\Users\user\Desktop\data.txt

For Windows:
• Click a file icon in Explorer
• Press <Ctrl-C> to copy the entire path name of the file.

• Back to IDLE shell and press <Ctrl-V> to paste the entire path name of the file as follows:

01204111 Computers and Programming, 187


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
For macOS:
• Click a file icon in Finder
• Press <Alt-Command-C> to copy the entire path name of the file.
• Back to IDLE shell and press <Command-V> to paste the entire path name of the file

Files should be closed


Opened files should be properly closed. The files in the examples are closed automatically in most Python
environments. In real applications, you should explicitly close a file. There are two common methods as
follows.
• Using the with statement. A file is closed automatically when exiting the with block.
with open("file.txt") as f:
for line in f.readlines():
# process the lines

• The close() method. A file is closed manually when this statement is executed.
f = open("file.txt")
for line in f.readlines():
# process the lines
f.close()

Note that, we won't use both of them in this course.

Task: Score Ranking


Read a text file containing a list of scores. Then sort the scores from highest to lowest and print out the
ranking.

Text file
scores.txt
87.3
75.6
63.0
97.5
37.6

01204111 Computers and Programming, 188


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Test run result.
Enter score file: scores.txt
Rank #1: 97.5
Rank #2: 87.3
Rank #3: 75.6
Rank #4: 63.0
Rank #5: 37.6

Ideas:
Scores must be read as a list of numbers, not strings. Thus, each string member must get converted into a
number (float).

lines
“87.3” “75.6” “63.0” “97.5” “37.6”

float()

scores 87.3 75.6 63.0 97.5 37.6

Straightforward code with a for loop:


:
lines = open(filename).read().splitlines()
scores = []
for x in lines:
scores.append(float(x))
:

First, we read the file's contents as a list of strings, one per line, and name that list as lines. Then we create
an empty list named scores and use for loop to convert each member in the list lines from string to float
number and append the converted number to list scores.

11.2 Creating lists from other sequences using list comprehensions

11.2.1 List Comprehensions


List comprehensions are a powerful and concise way to create new lists from other sequences.
Syntax:

list2 = [ expression for item in list1 ]

01204111 Computers and Programming, 189


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Similar to a set notation in mathematics, e.g.,
𝑆𝑆 = {2𝑥𝑥 | 𝑥𝑥 = 1,2,3}

It behaves exactly like

list2 = []
for item in list1:
list2.append(expression)

list1 x0 x1 x2 x3 x4

expression

list2 y0 y1 y2 y3 y4

Examples:
Create a new list with all values doubled from another list.
>>> L1 = [5,1,2,8,9,12,16]
>>> L2 = [2*x for x in L1]
>>> L2
[10, 2, 4, 16, 18, 24, 32]

Create a list of squares of n, where n = 1,2,…,10. Note that, a range object can be used directly inside a list
comprehension.
>>> [i**2 for i in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Compute the sum of squares of n, where n = 1,2,…,10


>>> sum([i**2 for i in range(1,11)])
385

Back to the task Score Ranking - Ideas


With a list comprehension, the following code
scores = []
for x in lines:
scores.append(float(x))

01204111 Computers and Programming, 190


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
can be replaced by a much more concise statement as follows:
scores = [float(x) for x in lines]

Score Ranking - Complete Program


1: filename = input("Enter score file: ") # version 1
2: lines = open(filename).read().splitlines()
3: scores = [float(x) for x in lines]
4: scores.sort(reverse=True)
5: for i in range(len(scores)):
6: print(f"Rank #{i+1}: {scores[i]}")

From the above program, note that line 4 is the statement that sorts the scores from highest to lowest.

Input text file: scores.txt

scores.txt

87.3
75.6
63.0
97.5
37.6

Test run result is shown as follows:

Empty Lines in File


Suppose that we have a file named scores.txt which contains numbers and an empty line as follows:

scores.txt

87.3
75.6

63.0
97.5
37.6

01204111 Computers and Programming, 191


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Empty lines in the input file will break the program like this.

Thus, we must filter out those empty line(s) before converting them to floats.

11.2.2 Conditional List Comprehensions


Only certain members in the original list are selected to be included in the new list using if keyword.

list2 = [ expression for item in list1 if condition]

The above is similar to

list2 = []
for item in list1:
if condition:
list2.append(expression)

Examples of Conditional List Comprehensions:


Split numbers into odd and even sets of numbers.
>>> L = [5,1,2,8,9,12,16]
>>> odd = [x for x in L if x%2 == 1]
>>> even = [x for x in L if x%2 == 0]
>>> odd
[5, 1, 9]
>>> even
[2, 8, 12, 16]

Create a list of positive integers less than 100 that are divisible by 8 but not divisible by 6.
>>> [x for x in range(1,100) if x%8 == 0 and x%6 != 0]
[8, 16, 32, 40, 56, 64, 80, 88]

01204111 Computers and Programming, 192


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Score Ranking – Revised version
Back to the task Score Ranking (#version 1). The following modified version (#version 2) can skip the empty
line(s) in the input file by using if condition in the list comprehension (line 3).

1: filename = input("Enter score file: ") #version 2


2: lines = open(filename).read().splitlines()
3: scores = [float(x) for x in lines if x != ""]
4: scores.sort(reverse=True)
5: for i in range(len(scores)):
6: print(f"Rank #{i+1}: {scores[i]}")

11.3 Tabular data and nested lists

11.3.1 Tabular data


Most real-world data are often available in tabular form. For example, this is a snapshot of household income
statistics by year available at http://data.go.th

11.3.2 CSV File


Comma-Separated Values (CSV) file is commonly used to store tabular data as a text file.
• Each line is a row.
• Columns in each line (row) are separated by commas.
• CSV files can be opened directly in spreadsheet software such as Microsoft Excel.

01204111 Computers and Programming, 193


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
grades.txt

01175112,1,B+
01204111,3,A
row 01417167,3,B

columns

Task: GPA Calculator


Read a CSV file containing a list of subject codes, their credits, and the grades received. Then, display
grade summary, total credits, and GPA. As an input, we use a file named grades.txt which stores data in

the structure of CSV file as follows.

grades.txt

01175112,1,B+
01204111,3,A
01355112,3,C+
01417167,3,B

The result is as follows:


Enter grade data file: grades.txt
-----------------------------------
Subject Credits Grade Point
-----------------------------------
01175112 1 B+ 3.5
01204111 3 A 4.0
01355112 3 C+ 2.5
01417167 3 B 3.0
-----------------------------------
Total credits = 10
GPA = 3.20

Ideas: GPA Calculator Program


How to store tabular data in Python?
• A table is a list of rows; each row is a list of columns.

table

1 2 3

4 5 6

01204111 Computers and Programming, 194


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Thus, we need a list of lists, also known as a nested list.
>>> table = [[1,2,3],[4,5,6]]
>>> len(table)
2

Access row#1 (2nd row)


>>> table[1]
[4, 5, 6]

Access column#2 (3rd column) in row#1 (2nd row)


>>> table[1][2]
6

Steps: GPA Calculator Program


Divide the whole task into three major steps.
Step 1: Read grade table data from the file as a nested list.
Step 2: Display the grade table.
Step 3: Calculate total credits and GPA.

11.3.3 Breaking Lines into Columns


Python provides str.split(separator) method to split a string into a list. You can specify the separator, the
default separator is any whitespace. The following shows an example of using comma (“,”) as the separator.
>>> line = "01204111,3,A"
>>> line.split(",")
['01204111', '3', 'A']

Let us try using it inside a list comprehension


>>> lines = open("grades.txt").read().splitlines()
>>> lines
['01175112,1,B+', '01204111,3,A', '01355112,3,C+', '01417167,3,B']
>>> table = [x.split(",") for x in lines]
>>> table
[['01175112', '1', 'B+'], ['01204111', '3', 'A'], ['01355112', '3', 'C+'],
['01417167', '3', 'B']]

Now, we got a nested list as shown above.

01204111 Computers and Programming, 195


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Back to the task GPA Calculator.
We divide the whole task into three major steps.
Step 1: Read grade table data from the file as a nested list.
Step 2: Display the grade table.
Step 3: Calculate total credits and GPA.

Step 1: Read grade table data from the file as a nested list.
We will define read_table() function as follows:
def read_table(filename):
lines = open(filename).read().splitlines()
table = [x.split(",") for x in lines if x != ""]
return table

input file
Let's test it. grades.txt

>>> read_table("grades.txt") 01175112,1,B+


01204111,3,A
[['01175112', '1', 'B+'], ['01204111', '3', 'A'], 01355112,3,C+
['01355112', '3', 'C+'], ['01417167', '3', 'B']] 01417167,3,B

As you can see from the above output, the resulting table is not complete yet.

The complete output that we expect shown as follows.


Enter grade data file: grades.txt
-----------------------------------
Subject Credits Grade Point
-----------------------------------
01175112 1 B+ 3.5
01204111 3 A 4.0
01355112 3 C+ 2.5
01417167 3 B 3.0
-----------------------------------
Total credits = 10
GPA = 3.20

• The credits column (in a dotted line square) should store integers, not strings, for later calculation.
• The point column (in a dashed line square) is still missing.

We will traverse the table list to perform an adjustment on each row. Thus, we have to also define the
grade_point() function to map grades to points.

01204111 Computers and Programming, 196


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: def grade_point(grade):
2: if grade == "A":
3: return 4.0
4: elif grade == "B+":
5: return 3.5
6: elif grade == "B":
7: return 3.0
8: elif grade == "C+":
9: return 2.5
10: elif grade == "C":
11: return 2.0
12: elif grade == "D+":
13: return 1.5
14: elif grade == "D":
15: return 1.0
16: elif grade == "F":
17: return 0.0
18:
19: def read_table(filename):
20: lines = open(filename).read().splitlines()
21: table = [x.split(",") for x in lines if x != ""]
22: for row in table:
23: # convert credits to integers
24: row[1] = int(row[1])
25: # add a new column for grade point
26: row.append(grade_point(row[2]))
27: return table
28:

Line 26 is a calling of function grade_point() by sending a grade as an argument. Then the function
grade_point() converts the grade to the corresponding grade point and returns. Finally, the returned grade

point is appended to row as a last column. The test run result of the function read_table() is shown as
follows:
>>> table = read_table("grades.txt")
>>> table
[['01175112', 1, 'B+', 3.5], ['01204111', 3, 'A', 4.0],
['01355112', 3, 'C+', 2.5], ['01417167', 3, 'B', 3.0]]

Step 2: Display the grade table.


This can be done by traversing the table list and print out each row.

29: def print_table(table):


30: print("-----------------------------------")
31: print(" Subject Credits Grade Point")
32: print("-----------------------------------")
33: for row in table:
34: print(f" {row[0]:8} {row[1]:5} {row[2]:<5} {row[3]:.1f}")
35: print("-----------------------------------")
36:

01204111 Computers and Programming, 197


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
It is not so difficult but needs a lot of tweaking to get a nice-looking table. Line 34 is to adjust the space
between each variable. The test run result of the function print_table() is shown as follows:
>>> print_table(table) # table from previous step
-----------------------------------
Subject Credits Grade Point
-----------------------------------
01175112 1 B+ 3.5
01204111 3 A 4.0
01355112 3 C+ 2.5
01417167 3 B 3.0
-----------------------------------

Step 3: Calculate total credits and GPA.


The total of credits is computed from the summation of column#1 in all rows as shown in the following
statement.
total_credits = sum([row[1] for row in table])

GPA is computed from the summation of credits*point of all subjects, divided by the total credits. Note
that, credits is in column#1 and point is in column#3.
sum_credits_point = sum([row[1]*row[3] for row in table])
gpa = sum_credits_point/total_credits

Finally, we can write the main program as follows:


37: filename = input("Enter grade data file: ")
38: table = read_table(filename)
39: print_table(table)
40: total_credits = sum([row[1] for row in table])
41: sum_credits_point = sum([row[1]*row[3] for row in table])
42: gpa = sum_credits_point/total_credits
43: print(f"Total credits = {total_credits}")
44: print(f"GPA = {gpa:.2f}")

The program starts the execution form this main method. Line 37 is the statement that gets the file name
from the user. The next line is a calling of function read_table() to process data as explained in step 1. Line
39 is a calling of function print_table() to display the grade table as explained in step 2. Then lines 40, 41
and 42 are for the calculation of total credit and GPA as explained in step3. Finally, the last two lines are
showing the outputs of total credit and GPA. Test run result then shown as follows.

01204111 Computers and Programming, 198


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
11.4 Exercise
1) Fill in the blank (A) to use a list comprehension to create a list of all odd numbers not divisible by 5
between 1 and N, inclusive, where N is any positive integer.
>>> N = 20
>>> s = _____(A)_____
>>> s
[1, 3, 7, 9, 11, 13, 17, 19]

If N above is changed to 23, the result will be:


[1, 3, 7, 9, 11, 13, 17, 19, 21, 23]

2) Create a file named planets.txt with the following contents:

planets.txt
Mercury
Venus

Earth

Mars
Jupiter
Saturn
Uranus
Neptune

Fill in the blank (A) to complete the code below so that it opens planets.txt in the same folder
and reads out all of its lines into a list, including empty lines.
>>> lines = _____(A)_____
>>> lines
['Mercury', 'Venus', '', 'Earth', '', 'Mars', 'Jupiter', 'Saturn', 'Uranus',
'Neptune']

01204111 Computers and Programming, 199


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
3) Using the file planets.txt above, complete the code below so that it opens planets.txt in the
same folder and reads out all of its lines into a list, without empty lines.
>>> lines = _____(A)_____
>>> lines_noempty = _____(B)_____
>>> lines_noempty
['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']

4) Given a nested list representing a table, fill in the blank (A) to write a list comprehension that creates
a list of only the rows whose last columns are even numbers.
>>> table = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
>>> new_table = _____(A)_____
>>> new_table
[[4, 5, 6], [10, 11, 12]]

If the table list above is changed to


>>> table = [[2,4],[9,6],[5,3],[7,10],[1,9]]

then the same list comprehension must result in


>>> new_table
[[2, 4], [9, 6], [7, 10]]

5) Write a Python program that reads a CSV file containing a list of people and their ages. The program
then reports the name(s) of the oldest person(s) in the list.

Notes: if there is more than one person with the same oldest age, the program must print out these
names in the same order as listed in the input file.

Examples 1: Suppose the file age1.txt contains the following:

age1.txt
Somchai,58
Somying,50
Somsak,62

01204111 Computers and Programming, 200


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The output of the program when specifying age1.txt as input is:
Enter age file: age1.txt
Oldest person(s) with the age of 62:
- Somsak

Examples 2: In case there is more than one person with the oldest age, the program must report all
those people's names. Suppose the file age2.txt contains the following:

age2.txt
Sophia,95
Jackson,56
Emma,95
Aiden,42
Olivia,68
Lucas,75
Ava,86
Liam,92

The output of the program when specifying age2.txt as input is:


Enter age file: age2.txt
Oldest person(s) with the age of 95:
- Sophia
- Emma

01204111 Computers and Programming, 201


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
12. Numerical Processing and Basic Data Visualization

Outline:

12.1 Numerical processing using NumPy library


12.2 Basic data visualization using Matplotlib library
12.3 Exercise

12.1 Numerical processing using NumPy library

12.1.1 NumPy Library


NumPy library provides
• Data types such as array and matrix specifically designed for processing a large amount of numerical
data.
• A large collection of mathematical operations and functions, especially for linear algebra.
• A foundation to many other scientific libraries for Python.
NumPy is not part of standard Python, but is included in scientific Python distributions such as Anaconda.

Using NumPy
NumPy library is named numpy and can be imported using the import keyword, e.g.,
import numpy
a = numpy.array([1,2,3])

By convention, the name numpy is renamed to np for convenience using the as keyword, e.g.,
import numpy as np
a = np.array([1,2,3])

From now on we will simply refer to numpy module as np.

01204111 Computers and Programming, 202


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
12.1.2 Arrays vs. Lists

Similarities of NumPy's arrays and regular Python's lists.


NumPy's arrays and regular Python's lists share many similarities.
• Array members are accessed using [] operator.
• Arrays are mutable.
• Arrays can be used as a sequence for a list comprehensions or a for loop.
Examples are shown as follows.
>>> import numpy as np
>>> a = np.array([1,2,3,4,5])
>>> a
array([1, 2, 3, 4, 5])
>>> a[2]
3
>>> a[3] = 8
>>> a
array([1, 2, 3, 8, 5])
>>> for x in a:
print(x)
1
2
3
8
5

• Arrays can be two-dimensional, similar to nested lists. Examples are shown as follows.
>>> import numpy as np
>>> table = np.array([[1,2,3],[4,5,6]])
>>> table
array([[1, 2, 3],
[4, 5, 6]])
>>> table[0] # one-index access gives a single row
array([1, 2, 3])
>>> table[1]
array([4, 5, 6])
>>> table[0][1] # two-index access gives a single element
2
>>> table[1][2]
6

Differences between Arrays and Lists.


An array can be used directly in a mathematical expression, resulting in another array.
• They work like vectors in mathematics.

01204111 Computers and Programming, 203


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
• Math operators such as +,-,*,/,** work with arrays right away.
• Arrays in the same expression must have the same size.
Examples are shown as follows.

>>> import numpy as np


>>> a = np.array([1,2,3,4,5])
>>> b = np.array([6,7,8,9,10])
>>> a-3
array([-2, -1, 0, 1, 2])
>>> a+b
array([ 7, 9, 11, 13, 15])
>>> (2*a + 3*b)/10
array([ 2. , 2.5, 3. , 3.5, 4. ])

Math Functions over Arrays.


Math functions can be performed over arrays. However, those math functions must be vectorized. NumPy
provides vectorized versions of all functions in the math module.
>>> import math
>>> import numpy as np
>>> a = np.array([1,2,3,4,5])
>>> math.sqrt(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: only length-1 arrays can be converted to Python scalars

In the above example, an error occurred because math.sqrt only works with scalars.
>>> np.sqrt(a)
array([ 1. , 1.41421356, 1.73205081, 2. , 2.23606798])

Thus, instead of math.sqrt, we have to use a vectorized version of sqrt which is provided by NumPy as
shown in the above example.

Task: Degree Conversion


Read a file containing a list of temperature values in degrees Celsius. Then, print out all corresponding values
in degrees Fahrenheit. File degrees.txt contains numbers as follows.

01204111 Computers and Programming, 204


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
degrees.txt

0
10
37
50
68
100

The program behaves as follows.


Enter file name: degrees.txt
32.0
50.0
98.6
122.0
154.4
212.0

Ideas:
Although techniques from previous chapters could be used, we will solve this problem using arrays by these
steps.
Step 1: Read all values in the input file into an array.
Step 2: Apply the conversion formula directly to the array.

9
F= C + 32
5

Step 3: Print out the resulting array.

12.1.3 Reading Data File using NumPy


NumPy provides function loadtxt() that:
• Reads a text file containing a list of numbers.
• Converts number-like strings to floats by default.
• Skips all empty lines automatically.
• Returns all values as an array.
>>> import numpy as np
>>> c_array = np.loadtxt("degrees.txt")
>>> c_array
array([ 0., 10., 37., 50., 68., 100.])

01204111 Computers and Programming, 205


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
All the above are done within one function call. Thus, you don’t need to use puzzling “list comprehension”
anymore.

Back to Task Degree Conversion.


By using function loadtxt(), the Degree Conversion program can be defined as follows.

Program:
1: import numpy as np
2:
3: filename = input("Enter file name: ")
4: c_array = np.loadtxt(filename)
5: f_array = 9/5*c_array + 32
6: for fah in f_array:
7: print(f"{fah:.1f}")

After received the file name from the user (in line 3), the program uses function loadtxt() to read numbers
in that text file and converts to an array of float numbers (in line 4). Then the program converts each number
in that array (which is degree Celsius) to Fahrenheit (in line 5). Finally, the program shows the output by using
for loop (in line 6-7). Note that :.1f inside print() (in line 7) is to specify to display 1 decimal points.
The test run result shown as follows.

Task: Data Set Statistics


Read a specified data set file containing a list of values. Then, compute and report their mean and standard
deviation. File values.txt contains numbers as follows.

01204111 Computers and Programming, 206


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
values.txt

68.70
31.53
16.94
9.95
52.55
29.65
64.01
69.52
30.08
21.77

The program behaves as follows.

Enter file name: values.txt


Mean of the values is 39.47
Standard deviation of the values is 22.29

Ideas:
From statistics, the mean of the data set (x1, x2,…, xn) is
n
1
x� = � xi
n
i=1

That’s mean:

X = # <data set in NumPy array>


n = len(X)
mean = sum(X)/n

And its standard deviation is


𝑛𝑛
1
𝜎𝜎 = � �(𝑥𝑥𝑖𝑖 − 𝑥𝑥̅ )2
𝑛𝑛 − 1
𝑖𝑖=1

In the above equation, ∑ni=1(xi − x�)2 is


sum((X-mean)**2)

Thus, the standard deviation can be written in the following code.

stdev = np.sqrt(
sum((X-mean)**2) / (n-1)
)

01204111 Computers and Programming, 207


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program:
1: import numpy as np
2:
3: filename = input("Enter file name: ")
4: X = np.loadtxt(filename)
5: n = len(X)
6: mean = sum(X)/n
7: stdev = np.sqrt( sum((X-mean)**2) / (n-1) )
8: print(f"Mean of the values is {mean:.2f}")
9: print(f"Standard deviation of the values is {stdev:.2f}")

After receive file name from the user (in line 3), the program uses function loadtxt() to read numbers in that
text file and converts to array X (in line 4). Then, the program calculates mean and assign to variable mean (in
line 6). After that, it calculates standard deviation as explained in the Ideas above (in line 7). Finally, the
program shows the output of mean and standard deviation (in line 8-9). The test run result is shown as
follows.

12.1.4 Computing with 2D Arrays


Processing numerical tabular data using 2D arrays offers several benefits over regular Python nested lists.
Some benefits are:
• Convenient text file reading and writing, including CSV files.
• Math operations/functions are done in a vectorized style.
• Much faster speed with large data sets.

Task: Score Query


Read a score table from the CSV file, named scores.txt, then show the numbers of students and subjects
found in the input file. After that, ask the user to query for a specified student's score in a specified subject.

01204111 Computers and Programming, 208


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The scores table. CSV file named scores.txt
Subject
Student scores.txt
#1 #2 #3 #4
75,34,64,82
#1 75 34 64 82 67,79,45,71
58,74,79,63
#2 67 79 45 71
#3 58 74 79 63

The program behaves like this.


Reading data from scores.txt
Found scores of 3 student(s) on 4 subject(s)
Enter student no.: 2
Enter subject no.: 1
Student #2's score on subject #1 is 67.0

Reading CSV Files with NumPy


The loadtxt() function also works with CSV files. The parameter delimiter="," must be given.
>>> import numpy as np
>>> table = np.loadtxt("scores.txt",delimiter=",")
>>> table
array([[ 75., 34., 64., 82.],
[ 67., 79., 45., 71.],
[ 58., 74., 79., 63.]])

Checking Array's Properties


Arrays have several properties to describe their sizes, shapes, and arrangements.
As shown in the following example, there is no need to use () because they are not the function.
>>> table
array([[ 75., 34., 64., 82.],
[ 67., 79., 45., 71.],
[ 58., 74., 79., 63.]])
>>> table.ndim # give the number of array's dimension
2
>>> table.shape # give the lengths in all dimensions
(3, 4)
>>> table.size # give the total size
12

01204111 Computers and Programming, 209


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
One-Row Data File (Caveats)
If input file contains only one row of data, loadtxt() will return a 1 dimension array. To force 2 dimension
array reading, call loadtxt() with the parameter ndmin=2.
For example, suppose that we have a text file, named 1row.txt.

1row.txt

75,34,64,82

Initially, import module numpy and use function loadtxt() to create array, named table as follows.
>>> import numpy as np
>>> table = np.loadtxt("1row.txt",delimiter=",")
>>> table
array([ 75., 34., 64., 82.])

Try to use properties ndim and shape to find array dimension and lengths in all dimensions, respectively.
>>> table.ndim
1
>>> table.shape
(4,)

As you can see from the output result, array table has 1 dimension with 4 members (has length of 4).

Here, add parameter ndim=2 to force the number of dimensions to 2.


>>> table = np.loadtxt("1row.txt",delimiter=",", ndmin=2)
>>> table
array([[ 75., 34., 64., 82.]])

Again, try to use properties ndim and shape to find array dimension(s) and length(s) in all dimension(s),
respectively. Now, you can confirm that array table has 2 dimensions, and each dimension has length of 1
and 4, respectively.
>>> table.ndim
2
>>> table.shape
(1, 4)

Back to Task Score Query. The program of Task Score Query can be defined as follows.

01204111 Computers and Programming, 210


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program:
1: import numpy as np
2:
3: FILENAME = "scores.txt"
4: print(f"Reading data from {FILENAME}")
5: table = np.loadtxt(FILENAME, delimiter=",", ndmin=2)
6: nrows,ncols = table.shape
7: print(f"Found scores of {nrows} student(s) on {ncols} subject(s)")
8: student_no = int(input("Enter student no.: "))
9: subject_no = int(input("Enter subject no.: "))
10: score = table[student_no-1][subject_no-1]
11: print(f"Student #{student_no}'s score on subject #{subject_no} is {score}")

After import a module numpy (in line 1), the program gets data from a file named scores.txt, and creates
array named table (lines 3-5). Then, it gets a table size and displays as the number of students and the
number of subjects (in line 6-7), respectively. Then, it asks the user to input which number of the student
(student_no) and also which number of the subject (subject_no) to be displayed (in line 8-9). Note that, to
specify the correct index number to array table, we have to subtract 1 from both student_no and
subject_no because the index number of array starts from 0 (in line 10). Finally, the output is shown (in line

11). The test run result shown as follows.

The score table. CSV file named scores.txt


Subject
Student scores.txt
#1 #2 #3 #4
75,34,64,82
#1 75 34 64 82 67,79,45,71
58,74,79,63
#2 67 79 45 71
#3 58 74 79 63

01204111 Computers and Programming, 211


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Task: Who Fails
Read a score table from the CSV file scores.txt, then report who fails which subject. Use the score table
from the previous task. The scores.txt is as follows:

scores.txt

75,34,64,82
67,79,45,71
58,74,79,63

The program behaves like this.


Reading data from scores.txt
Found scores of 3 student(s) on 4 subject(s)
Student #1 fails subject #2 with score 34.0
Student #2 fails subject #3 with score 45.0

Ideas:
Find the student who fails the exam (score < 50). Scan through all scores and check one by one.

Steps:
For each student (each row), go from the first to the last subject (columns). Check whether the score is below
50 or not. If so, print out the student number, subject number, and the score.

Program:
1: import numpy as np
2:
3: FILENAME = "scores.txt"
4: print(f"Reading data from {FILENAME}")
5: table = np.loadtxt(FILENAME, delimiter=",", ndmin=2)
6: nrows,ncols = table.shape
7: print(f"Found scores of {nrows} student(s) on {ncols} subject(s)")
8:
9: for r in range(nrows):
10: for c in range(ncols):
11: score = table[r][c]
12: if score < 50:
13: print(f"Student #{r+1} fails subject #{c+1} with score {score}")

01204111 Computers and Programming, 212


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
This program added some changes from the previous task. We added nested loop from line 9. The loop
traverses from the first row which has index number 0 (assigned to r), starting with the column which has
index number 0 (assigned to c) to the last one in the specified range (from the above example, ncols is 4,
that mean range(ncols) ends with 3). Line 12 checks whether the score is less than 50 or not. If so, report
on the screen. The test run result is shown as follows.

Task: Score Sheet Summary


Read a score table from the CSV file scores.txt from the previous task. Then, display the total score for
each student and the average for each subject.

The score table. CSV file named scores.txt


Subject
Student scores.txt
#1 #2 #3 #4
75,34,64,82
#1 75 34 64 82 67,79,45,71
58,74,79,63
#2 67 79 45 71
#3 58 74 79 63

The program behaves like this.


Reading data from scores.txt
Found scores of 3 student(s) on 4 subject(s)
Student Summary
===============
Total score for student #1: 255
Total score for student #2: 262
Total score for student #3: 274
Subject Summary
===============
Average score for subject #1: 66.67
Average score for subject #2: 62.33
Average score for subject #3: 62.67
Average score for subject #4: 72.00

01204111 Computers and Programming, 213


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Ideas:
The array read from the file can be seen as a list of rows. We can traverse all the rows (i.e., students) with a
for loop. Then compute summation on each row.

>>> import numpy as np


>>> table =
np.loadtxt("scores.txt",delimiter=",",ndmin=2)
>>> table
array([[ 75., 34., 64., 82.],  Row 0
[ 67., 79., 45., 71.],  Row 1
[ 58., 74., 79., 63.]])  Row 2
>>> table[0]
array([ 75., 34., 64., 82.])

However, how to traverse all the columns (i.e., subjects) by for loop?

Array Transpose
NumPy's arrays have the array.T property for viewing the transposed version of the arrays. This allows 2D
array traversal by columns. The transpose provides a different view to an array, not a copy of it. See an
example using the same table from the above.

>>> table
array([[ 75., 34., 64., 82.],  Row 0
[ 67., 79., 45., 71.],  Row 1
[ 58., 74., 79., 63.]])  Row 2
>>> table.T
array([[ 75., 67., 58.],  Column 0
[ 34., 79., 74.],  Column 1
[ 64., 45., 79.],  Column 2
[ 82., 71., 63.]])  Column 3
>>> table.T[0]
array([ 75., 67., 58.])

Thus, by using array.T property, the program of the task Score Sheet Summary can be defined as follows.

01204111 Computers and Programming, 214


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program:
1: import numpy as np
2:
3: FILENAME = "scores.txt"
4: print(f"Reading data from {FILENAME}")
5: table = np.loadtxt(FILENAME, delimiter=",", ndmin=2)
6: nrows,ncols = table.shape
7: print(f"Found scores of {nrows} student(s) on {ncols} subject(s)")
8: print()
9: print("Student Summary")
10: print("===============")
11: for r in range(nrows):
12: print(f"Total score for student #{r+1}: {sum(table[r]):.0f}")
13: print()
14: print("Subject Summary")
15: print("===============")
16: for c in range(ncols):
17: avg = sum(table.T[c])/len(table.T[c])
18: print(f"Average score for subject #{c+1}: {avg:.2f}")

This program also modified from the previous task. The first for loop in line 11-12 accesses each row of table
and calculates the summation of each rows. Then, it shows total score of each student in line 12. The second
for loop in line 16-18 calculates average score of each subject (average score of each column) by using the
transpose of table. Concretely, the average of each subject is calculated by dividing the summation of
transposed row (which is scores of students) by the length of that transposed row (which is the number of
students). Then, it shows the average score for each subject in line 18. The test run result is shown as
follows.

2D Array Member Access


To access the element at row#i, column#j in 2D array, NumPy supports both [i][j] and [i,j] forms
• The [i,j] form does not work with nested lists
• The [i,j] form is often found in other programming languages such as MATLAB

01204111 Computers and Programming, 215


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
>>> import numpy as np
>>> a = np.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
[4, 5, 6]])
>>> a[0][2]
3
>>> a[0,2]
3

Matrix Processing (Bonus)


NumPy provides matrix() function for matrix creation. Certain operations, such as multiplication, have a
different meaning with matrices.
• Element-wise multiplication
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> a
array([[1, 2],
[3, 4]])
>>> b
array([[5, 6],
[7, 8]])
>>> a*b
array([[ 5, 12],
[21, 32]])
>>> b*a
array([[ 5, 12],
[21, 32]])

• Matrix-style multiplication
>>> import numpy as np
>>> a = np.matrix([[1,2],[3,4]])
>>> b = np.matrix([[5,6],[7,8]])
>>> a
matrix([[1, 2],
[3, 4]])
>>> b
matrix([[5, 6],
[7, 8]])
>>> a*b
matrix([[19, 22],
[43, 50]])
>>> b*a
matrix([[23, 34],
[31, 46]])

01204111 Computers and Programming, 216


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
12.2 Basic data visualization using Matplotlib library (Bonus Material)
Matplotlib Library

Matplotlib provides a rich set of data visualization tools like NumPy. Matplotlib is not part of standard Python.
Anaconda and other scientific Python distributions come with it.

Images from: http://matplotlib.org

12.2.1 Line plots

Matplotlib library has many submodules, but the most commonly used submodule is pyplot. It provides
functions similar to that of MATLAB. Pyplot can be imported using the import keyword, e.g.,
import matplotlib.pyplot
matplotlib.pyplot.plot([1,2,3],[4,5,6])
matplotlib.pyplot.show()

By convention, the lengthy module name is renamed to plt , e.g.,

import matplotlib.pyplot as plt


plt.plot([1,2,3],[4,5,6])
plt.show()

Task: Function Grapher


Create a chart with two-line plots representing two relations, 𝑦𝑦1 = sin �𝜋𝜋𝜋𝜋2� and 𝑦𝑦2 = 12 cos �𝜋𝜋𝜋𝜋3�, for 0 ≤ 𝑥𝑥 ≤ 5
The output image of the graph is shown as follows.

01204111 Computers and Programming, 217


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Creating Line Plots
Pyplot provides plot() function to create a line plot. The plot() function is very flexible for taking
parameters. We will use the form plot(x,y) where x and y are sequences (lists or arrays) for the x-axis and y-
axis coordinates, respectively. Call the show() function to show all the plot(s) created.
import matplotlib.pyplot as plt
plt.plot([1,2,3],[4,3,6])
plt.plot([1,2,3],[2,4,5])
plt.show()

The output result of the above code is shown as follows.

01204111 Computers and Programming, 218


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Thus, we can solve the task to create a chart with two-line plots representing two relations,
𝜋𝜋𝜋𝜋 1 𝜋𝜋𝜋𝜋
𝑦𝑦1 = sin � � and 𝑦𝑦2 = cos � �, for 0 ≤ 𝑥𝑥 ≤ 5, as follows.
2 2 3

Ideas:
• Create an array for the values of x, 0 ≤ 𝑥𝑥 ≤ 5
• Compute two other arrays for y1 and y2

• Create plots for x vs. y1 and x vs. y2

Python program is shown as follows:


1: import numpy as np
2: import matplotlib.pyplot as plt
3: x = np.array([0,1,2,3,4,5])
4: y1 = np.sin(np.pi*x/2)
5: y2 = 1/2*np.cos(np.pi*x/3)
6: plt.plot(x,y1)
7: plt.plot(x,y2)
8: plt.show()

The program imports numpy and matplotlib module (in line 1 and 2). Line 3 creates an array that contains
the values of x which are [0,1,2,3,4,5], and line 4-5 create an array for y1 and y2. Then, the program
plots a graph by using plot() function for x vs. y1 and x vs. y2, in line 6-7. Finally, show() function is used to
show the graph. The output result is shown as follows.

01204111 Computers and Programming, 219


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Refining the Range
Previous plots look very rough because using only [0,1,2,3,4,5] for the values of x is too coarse. NumPy
provides two functions to make finer sequences.
• arange(start,stop,step) - like range() but accepts fractional step size and returns an array (stop is
excluded)
>>> import numpy as np
>>> np.arange(0,5,0.5)
array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5])

• linspace(start,stop,length) makes an array of length values from start to stop (including stop
itself)
>>> np.linspace(0,5,11)
array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5, 5. ])

In the task Function Grapher, we will use the linspace() function to create a finer sequence of x. Create 100
points from 0 to 5 to make smoother curves. We can modify line 3 as follows:
1: import numpy as np
2: import matplotlib.pyplot as plt
3: x = np.linspace(0,5,100) # 100 points from 0 to 5
4: y1 = np.sin(np.pi*x/2)
5: y2 = 1/2*np.cos(np.pi*x/3)
6: plt.plot(x,y1)
7: plt.plot(x,y2)
8: plt.show()

The output result is shown as follows.

01204111 Computers and Programming, 220


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Decorating the Chart
• Call plot(…,label=s) to assign a legend label for the plot
• Call legend() to collect all plots' labels and create a legend box
• Call xlabel(s) and ylabel(s) to create labels for x-axis and y-axis, respectively
• Call grid(True) to display grid lines
grid lines
legend box

y label

x label

Thus, the modified version of the task will be as follows.


1: import numpy as np
2: import matplotlib.pyplot as plt
3:
4: x = np.linspace(0,5,100)
5: y1 = np.sin(np.pi*x/2)
6: y2 = 1/2*np.cos(np.pi*x/3)
7: plt.plot(x,y1,label="y1")
8: plt.plot(x,y2,label="y2")
9:
10: # decorate the figure
11: plt.grid(True)
12: plt.xlabel("x")
13: plt.ylabel("y")
14: plt.legend()
15:
16: plt.show()

01204111 Computers and Programming, 221


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The output result is shown as follows.

Task: Cannon Ball


Plot the trajectory of a cannon ball when it's fired at four different angles: 30o, 45o, 60o, and 75o. Only show
the trajectory in the first 10 seconds only. Suppose the initial speed of the cannon ball is 100 m/s.

Ideas:
We simply use the projectile-motion formulas from high-school physics:
𝑥𝑥(𝑡𝑡) = 𝑢𝑢 cos(𝜃𝜃) × 𝑡𝑡,
1
𝑦𝑦(𝑡𝑡) = 𝑢𝑢 sin(𝜃𝜃) × 𝑡𝑡 − 𝑔𝑔𝑡𝑡 2
2

where u is the initial speed (in m/s) and g is the Earth's gravitational acceleration, which is 9.81 m/s2

Steps:
The program will roughly work in the following steps.

01204111 Computers and Programming, 222


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Step 1: Prepare an array of time values, t, from 0 to 10 using linspace() function
Step 2: For each angle, θ
2.1: Compute an array of distances, x, at time t
2.2: Compute an array of heights, y, at time t
2.3: Create a line plot using the arrays x and y, along with the label
Step 3: Decorate and show the chart

Program:
1: import numpy as np
2: import matplotlib.pyplot as plt
3:
4: g = 9.81 # Earth's gravity in m/s^2
5: u = 100 # initial speed in m/s
6: t = np.linspace(0,10,100)
7: angles = [30,45,60,75]
8: for theta in angles:
9: x = u*np.cos(np.radians(theta))*t
10: y = u*np.sin(np.radians(theta))*t - 1/2*g*(t**2)
11: plt.plot(x,y,label=f"angle = {theta}")
12:
13: # decorate the figure
14: plt.xlabel("distance (m)")
15: plt.ylabel("height (m)")
16: plt.legend()
17: plt.grid(True)
18: plt.show()

Please note that for loop is used because we need to calculate x and y then plot the graph for each angle.
The output result is shown as follows.

01204111 Computers and Programming, 223


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
12.2.2 Scatter Plots

Task: BMI Scatter Plot


Read pairs of weights (in kg) and heights (in cm) from a CSV file. Compute the BMI value for each (weight,
height) pair. Display a scatter plot using weights as the x values, and heights as the y values. Use a different
color for each point, based on the BMI value. Besides, also display a color bar.

body.txt

65.6,174.0
71.8,175.3
80.7,193.5
72.6,186.5
:

Download full data file from https://elab.cpe.ku.ac.th/data/body.txt


The output image of the program is shown as follows.

Creating a Scatter Plot


Pyplot prepares the scatter() function for tasks like this, at least two parameters, x and y, must be specified.
The following example creates a scatter plot with points (1,4), (2,3), and (3,6)
import matplotlib.pyplot as plt
x = [1,2,3]
y = [4,3,6]
plt.scatter(x,y)
plt.show()

01204111 Computers and Programming, 224


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Output result when using scatter plot function is shown as follows.

Visualizing 3rd Variable


A basic scatter plot only displays two variables using coordinates (x,y). A third variable can be color-coded
into the plot by calling scatter(x,y,c=var3) where var3 is a sequence for the third variable.
import matplotlib.pyplot as plt
x = [1,2,3]
y = [4,3,6]
z = [10,20,30]
plt.scatter(x,y,c=z)
plt.show()

The output result when using scatter plot function with three variables is shown as follows.

Adding Color Bar


A color bar indicates the values of the color codes. Call colorbar() to add a color bar to the plot. Use the
returned value to set the color bar's title via its colorbar.ax.set_title() method.

01204111 Computers and Programming, 225


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
import matplotlib.pyplot as plt
x = [1,2,3]
y = [4,3,6]
z = [10,20,30]
plt.scatter(x,y,c=z)
cbar = plt.colorbar()
cbar.ax.set_title("z value")
plt.show()

The output result when using scatter plot function adding a color bar is shown as follows.

Changing Color Map


If you don't like the default color map, you can always choose a different one using the set_cmap(name)
function, where name is the colormap's name. Refer to https://matplotlib.org/examples/color/
colormaps_reference.html for a complete list.
import matplotlib.pyplot as plt
x = [1,2,3]
y = [4,3,6]
z = [10,20,30]
plt.scatter(x,y,c=z)
cbar = plt.colorbar()
cbar.ax.set_title("z value")
plt.set_cmap("jet")
plt.show()

The output result when using scatter plot function adding a color bar that changed the color map to “jet” is
shown as follows.

01204111 Computers and Programming, 226


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Now, let’s complete the task BMI Scatter Plot.

Ideas:
We will create a scatter plot with three variables:
weights as x values
heights as y values
BMI as color codes
BMI is computed from weights and heights using the formula:
weight kg
BMI =
(height m )2

The calculation can be done directly over NumPy's arrays.

Program:
Please download the full body.txt file from https://elab.cpe.ku.ac.th/data/body.txt

body.txt

65.6,174.0
71.8,175.3
80.7,193.5
72.6,186.5
:

01204111 Computers and Programming, 227


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
1: import numpy as np
2: import matplotlib.pyplot as plt
3:
4: table = np.loadtxt("body.txt",delimiter=",",ndmin=2)
5: weight = table.T[0] # extract weights from column#0
6: height = table.T[1] # extract heights from column#1
7: bmi = weight/((height/100)**2)
8: plt.scatter(weight,height,c=bmi)
9:
10: # decorating the chart
11: plt.xlabel("Weight (kg)")
12: plt.ylabel("Height (cm)")
13: plt.grid(True)
14: cbar = plt.colorbar()
15: cbar.ax.set_title("BMI")
16: plt.set_cmap("jet")
17:
18: plt.show()

Note that, according to the file body.txt, weight and height are separated into 2 columns in each row.
Therefore, we need to transpose them (as shown in line 5 and 6), to get the row of weight and the row of
height, respectively. The output of the program then shown as follows.

12.2.3 Heat Map


A heat map is a representation of 2D data in forms of color coding. Pyplot provides the imshow() function
that conveniently generates a heat map from data in a 2D array (or a nested list).

01204111 Computers and Programming, 228


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Program:

temperature.txt

18,18,18,19,20,...
19,19,19,20,21,...
19,19,19,21,21,...
: : : : :

Please download full temperature.txt file from https://elab.cpe.ku.ac.th/data/temperature.txt

import numpy as np
import matplotlib.pyplot as plt

data = np.loadtxt("temperature.txt",delimiter=",")
plt.imshow(data)

# decorate the figure


bar = plt.colorbar()
bar.ax.set_title("Degrees C")
plt.set_cmap("jet")

plt.show()

The output result is shown as follows.

01204111 Computers and Programming, 229


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
12.3 Exercise

1) Fill in the blanks (A) and (B) to get the output as shown.
>>> import numpy as np
>>> x = _____(A)_____
>>> x*2
array([ 4, 6, 10, 14, 22, 26])
>>> y = _____(B)_____
>>> x*2 + y
array([ 5, 6, 11, 14, 23, 26])

2) Enter an expression in the blank (A) so that it correctly computes the root mean square (RMS) of the
values in the array x. The RMS of (x1,x2,…,xn) is defined as:

1
𝑥𝑥𝑟𝑟𝑟𝑟𝑟𝑟 = � (𝑥𝑥12 + 𝑥𝑥22 +. . . +𝑥𝑥𝑛𝑛2 )
𝑛𝑛

The expression must work with any sequence, not only the one in the example.
>>> import numpy as np
>>> x = np.array([2,3,5,7,11,13])
>>> x_rms = _____(A)_____
>>> print(f"{x_rms:.2f}")
7.93

3) Fill in the blanks (A)~(F) so that it gives the output as shown.


>>> import numpy as np
>>> a = np.array([[5,6,7],[3,2,1]])
>>> a[__(A)__][__(B)__]
1
>>> a[__(C)__][__(D)__]
6
>>> a[__(E)__][__(F)__]
5

4) Suppose the file table.txt contains:

table.txt
3,5,0,5,9,1
4,2,6,5,1,8
7,10,9,4,6,5

01204111 Computers and Programming, 230


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
Fill in the blank (A) so that the code reads tabular data from the file as a 2D array and assign the
variable table to it.
>>> import numpy as np
>>> table = np.loadtxt(_____(A)_____)
>>> table
array([[ 3., 5., 0., 5., 9., 1.],
[ 4., 2., 6., 5., 1., 8.],
[ 7., 10., 9., 4., 6., 5.]])

5) Write a Python program that reads a list of values from the file specified. The program then reports
the following:
• The number of values (i.e., the data size) in the file
• The minimum value, with two decimal places
• The maximum value, with two decimal places
• The mean of the values, with two decimal places
• The standard deviation of the values, with two decimal places
Note that the mean of the data set X = (x1,x2,…,xn) is:
𝑁𝑁
1
𝑥𝑥̅ = � 𝑥𝑥𝑖𝑖
𝑛𝑛
𝑖𝑖=1

And the standard deviation is:

𝑁𝑁
1
𝜎𝜎 = � �(𝑥𝑥𝑖𝑖 − 𝑥𝑥̅ )2
𝑁𝑁 − 1
𝑖𝑖=1

Example 1:
Suppose the file values1.txt contains the following:

values1.txt

10
13
19

01204111 Computers and Programming, 231


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
The output of the program when specifying values1.txt as input is:
Enter file name: values1.txt
Size of the data set is 3
Minimum is 10.00
Maximum is 19.00
Mean is 14.00
Standard deviation is 4.58

Example 2:
Suppose the file values2.txt contains the following:

values2.txt

68.70
31.53
16.94
9.95
52.55
29.65
64.01
69.52
30.08
21.77

The output of the program when specifying values2.txt as input is:

Enter file name: values2.txt


Size of the data set is 10
Minimum is 9.95
Maximum is 69.52
Mean is 39.47
Standard deviation is 22.29

01204111 Computers and Programming, 232


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved
บรรณานุกรม
1. Allen Downey. "Think Python, How to Think Like a Computer Scientist" (2nd Edition), O'Reilly Media, 2015.
http://greenteapress.com/thinkpython2/thinkpython2.pdf
2. “หนังสือเรียนรายวิชาเพิ่มเติม เทคโนโลยีสารสนเทศและการสื่อสาร วิชาภาษาไพทอน (Python)”, สสวท
http://oho.ipst.ac.th/python-book/
3. บัญชา ปาสีละเตสัง, “การเขียนโปรแกรมดวย Python สำหรับผูเริม่ ตน”, บริษัท ซีเอ็ดยูเคชั่น จำกัด (มหาชน), 2019
4. ประยงค อูประสิทธิ์วงศ, “พื้นฐานการเขียนโปรแกรมดวยภาษา Python”, บริษัท ส.เอเซียเพรส (1989) จำกัด, 2019
5. เว็บไซต python.org https://www.python.org/
6. เว็บไซต Python version 3 documentation https://docs.python.org/3/
7. เว็บไซต WikiPython, https://wiki.python.org/moin/BeginnersGuide/NonProgrammers
8. เว็บไซต InteractivePython, http://interactivepython.org/runestone/static/thinkcspy/index.html
9. เว็ปไซต Wikipedia, https://en.wikipedia.org/wiki/History_of_computing
10. เว็ปไซต Computer Histpry, http://www.computerhistory.org/timeline/computers/
11. เว็ปไซต Code.org, http://www.code.org
12. เว็ปไซต Think Python, http://greenteapress.com/thinkpython2/thinkpython2.pdf
13. เว็ปไซต Digitalocean, https://www.digitalocean.com/community/tutorials/how-to-use-variables-in-python-
3#understanding-variables
14. เว็ปไซต TutorialsPoint.com, https://www.tutorialspoint.com/python/python_variable_types.htm
15. เว็ปไซต Python standard library, https://docs.python.org/3/library/index.html
16. เว็ปไซต Programiz.com, https://www.programiz.com/python-programming/if-elif-else

01204111 Computers and Programming, 233


Asst.Prof.Dr.Pattara Leelaprute, Department of Computer Engineering, Faculty of Engineering, Kasetsart University. All Right Reserved

You might also like