0% found this document useful (0 votes)
6 views206 pages

Python New

Uploaded by

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

Python New

Uploaded by

raaz ftb
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 206

A Practical Introduction to

Python Programming

1
2
Contents

Contents

Chapter 1 ......................................................................................................................................... 9
1.1 Installing Python ............................................................................................................... 9
1.2 IDLE ................................................................................................................................ 9
1.3 Data analysis and machine learning .................................................................................... 10
1.4 A first program ............................................................................................................. 10
1.5 Typing things in ............................................................................................................ 11
1.6 Getting input ................................................................................................................. 11
1.7 Printing ......................................................................................................................... 12
1.8 Variables ...................................................................................................................... 13
1.9 Variable names .................................................................................................................... 14
Exercises .................................................................................................................................... 15
Chapter 2 ....................................................................................................................................... 16
2.1 Examples ....................................................................................................................... 16
2.2 The loop variable .......................................................................................................... 17
2.3 The range function ........................................................................................................ 18
2.4 A Trickier Example ...................................................................................................... 19
2.5 Exercises ........................................................................................................................ 20
Chapter 3 ....................................................................................................................................... 21
3.1 Integers and Decimal Numbers .................................................................................... 21
3.2 Math Operators ............................................................................................................ 21
3.3 Order of operations ...................................................................................................... 22
3.4 Random numbers ......................................................................................................... 22
3.5 Math functions .............................................................................................................. 23
3.6 Getting help from Python ............................................................................................. 25
3.7 Using the Shell as a Calculator ..................................................................................... 26
3.8 Date and Time Functions in Python .................................................................................... 27
3.9 Exercises ........................................................................................................................ 31

3
Chapter 4 ....................................................................................................................................... 32
4.1 A Simple Example......................................................................................................... 32
4.2 Conditional operators ................................................................................................... 32
4.3 Common Mistakes ........................................................................................................ 33
4.4 elif .................................................................................................................................. 34
4.5 Exercises ........................................................................................................................ 35
Chapter 5 ....................................................................................................................................... 37
5.1 Counting ........................................................................................................................ 37
5.2 Summing ....................................................................................................................... 38
5.3 Swapping ....................................................................................................................... 39
5.4 Flag variables ................................................................................................................ 39
5.5 Maxes and mins ............................................................................................................ 40
5.6 Comments ..................................................................................................................... 41
5.7 Simple debugging .......................................................................................................... 41
5.8 Example programs ........................................................................................................ 42
5.9 Indentation matters ............................................................................................................. 44
Chapter 6 ....................................................................................................................................... 46
6.1 Basics ............................................................................................................................. 46
6.2 Concatenation and repetition ....................................................................................... 47
6.3 The in operator ............................................................................................................. 47
6.4 Indexing ........................................................................................................................ 48
6.5 Slices .............................................................................................................................. 48
6.6 Changing individual characters of a string .................................................................. 49
6.7 Looping ......................................................................................................................... 50
6.8 String Functions in Python ........................................................................................... 50
6.9 Escape characters ......................................................................................................... 55
6.10 Examples ....................................................................................................................... 56
6.11 Exercises ........................................................................................................................ 59
Chapter 7 ....................................................................................................................................... 60
7.1 Basics ............................................................................................................................. 60
7.2 List Operations .................................................................................................................... 61
7.3 Similarities to strings .................................................................................................... 62
7.4 Built-in functions .......................................................................................................... 63
7.5 List methods .................................................................................................................. 63
7.6 Miscellaneous ................................................................................................................ 64

4
7.7 Examples ....................................................................................................................... 65
7.8 Exercises ........................................................................................................................ 68
Chapter 8 ....................................................................................................................................... 69
8.1 Lists and the random module ....................................................................................... 69
8.2 Split ............................................................................................................................... 70
8.3 Join ................................................................................................................................ 71
8.4 List Comprehensions .................................................................................................... 72
8.5 Using list comprehensions ............................................................................................ 74
8.6 Two-Dimensional Lists ................................................................................................. 75
8.7 Exercises ........................................................................................................................ 78
Chapter 9 ....................................................................................................................................... 79
9.1 Examples ....................................................................................................................... 79
9.2 Infinite loops ................................................................................................................. 83
9.3 The break statement ..................................................................................................... 83
9.4 The else statement ......................................................................................................... 84
9.5 The guessing game, more nicely done .......................................................................... 85
9.6 Exercises ........................................................................................................................ 90
Chapter 10 ..................................................................................................................................... 91
10.1 str, int, float, and list ..................................................................................................... 91
10.2 Examples ............................................................................................................................ 92
10.3 Booleans ........................................................................................................................ 93
10.4 Shortcuts ....................................................................................................................... 94
10.5 Continuation ................................................................................................................. 95
10.6 pass ................................................................................................................................ 96
10.7 String formatting .......................................................................................................... 96
10.8 Nested loops .................................................................................................................. 98
10.9 Exercises ...................................................................................................................... 100
Chapter 11 ................................................................................................................................... 101
11.1 Basics ........................................................................................................................... 101
11.2 Dictionary examples ................................................................................................... 102
11.3 Working with dictionaries .......................................................................................... 104
11.4 Counting words ........................................................................................................... 106
11.5 Tuple in Python ................................................................................................................ 108
11.6 Creating a Tuple .............................................................................................................. 108
11.7 Tuple Operations ............................................................................................................. 108

5
11.8 Set in Python ............................................................................................................. 109
Creating a Set ........................................................................................................................ 109
Set Properties: ...................................................................................................................... 110
Set Operations ...................................................................................................................... 110
11.9 Differences Among List, Tuple, Set, and Dictionary....................................................... 111
11.10 When to Use Which? ...................................................................................................... 111
11.11 Exercises ................................................................................................................. 112
Chapter 12 ................................................................................................................................... 113
12.1 Reading from files ....................................................................................................... 113
12.2 Writing to files ............................................................................................................ 114
12.3 Examples ..................................................................................................................... 114
12.4 Wordplay .................................................................................................................... 115
12.5 Exercises ...................................................................................................................... 117
Chapter 13 ................................................................................................................................... 119
13.1 Basics ........................................................................................................................... 119
13.2 Arguments ................................................................................................................... 120
13.3 Returning values ......................................................................................................... 121
13.4 Default arguments and keyword arguments .............................................................. 123
13.5 Local variables ............................................................................................................ 124
13.6 Exercises ...................................................................................................................... 126
Chapter 14 ................................................................................................................................... 127
14.1 Python is objected-oriented ........................................................................................ 127
14.2 Creating your own classes .......................................................................................... 128
14.3 Inheritance .................................................................................................................. 130
14.4 A playing-card example .............................................................................................. 132
14.5 A Tic-tac-toe example ................................................................................................. 135
Part II .......................................................................................................................................... 140
Chapter 15 ................................................................................................................................... 141
15.1 Basics ........................................................................................................................... 141
15.2 Creating a Simple Tkinter Window ........................................................................... 141
15.3 Code Explanation ....................................................................................................... 142
15.4 Labels .......................................................................................................................... 145
15.5 Grid ............................................................................................................................. 146
15.6 Entry boxes ................................................................................................................. 147
15.7 Buttons ........................................................................................................................ 149

6
15.8 Using Frames and Layouts (Pack, Grid, Place) ........................................................ 151
15.9 Global variables .......................................................................................................... 151
15.10 Tic-tac-toe .................................................................................................................. 152
Chapter 16 ................................................................................................................................... 158
16.1 Frames......................................................................................................................... 158
16.2 Colors .......................................................................................................................... 160
16.3 Images ......................................................................................................................... 160
16.4 Canvases ...................................................................................................................... 161
16.5 Check buttons and Radio buttons .............................................................................. 163
16.6 Text widget .................................................................................................................. 164
16.7 Scale widget ................................................................................................................. 165
16.8 GUI Events .................................................................................................................. 166
16.9 Event Examples .......................................................................................................... 168
Example 1 Key Event ................................................................................................... 168
Example 2 Mouse Event Example................................................................................ 169
Example 3 To-Do List....................................................................................................... 173
Example 4 Digital Clock ............................................................................................... 175
Example 5 Login Form................................................................................................. 176
Example 6 Countdown Timer ...................................................................................... 178
Chapter 17 ................................................................................................................................... 181
17.1 Title bar....................................................................................................................... 181
17.2 Disabling things .......................................................................................................... 181
17.3 Getting the state of a widget ....................................................................................... 181
17.4 Message boxes ............................................................................................................. 182
17.5 Destroying things ........................................................................................................ 183
17.6 Updating ...................................................................................................................... 184
17.7 Dialogs ......................................................................................................................... 185
17.8 Menu bars ................................................................................................................... 186
17.9 New windows .............................................................................................................. 187
17.10 pack ............................................................................................................................. 187
17.11 StringVar .................................................................................................................... 188
Chapter 18 ................................................................................................................................... 190
18.1 To install MySQL on Windows, you can: .................................................................. 190
18.2 Features of this Application........................................................................................ 191
18.3 Steps to Set Up ............................................................................................................ 191

7
Install Required Modules .................................................................................................... 191
18.4 Tkinter + MySQL CRUD Application ............................................................................ 192
Create MySQL Database and Table ................................................................................... 192
Create Python Program....................................................................................................... 192
18.5 Multiple Document Interface(MDI) Project .............................................................. 197
1️. Create MySQL Tables ..................................................................................................... 198
2️. Tkinter Login Form (Authentication) ............................................................................. 199
3️. MDI Parent Window (Main Menu) ................................................................................. 200
4️. CRUD Forms ................................................................................................................... 201
5️. Reports Form (Display All Records) ............................................................................... 204
🔹 Summary .............................................................................................................................. 206

8
Chapter 1

This chapter will get you up and running with Python, from downloading it to writing simple
programs.

1.1 Installing Python

Go to www.python.org and download the latest version of Python (version 3.5 as of this writing).
It should be painless to install. If you have a Mac or Linux, you may already have Python on
your computer, though it may be an older version. If it is version 2.7 or earlier, then you should
install the latest version, as many of the programs in this book will not work correctly on older
versions.

1.2 IDLE

IDLE is a simple integrated development environment (IDE) that comes with Python. It’s a pro-
gram that allows you to type in your programs and run them. There are other IDEs for Python,
but for now I would suggest sticking with IDLE as it is simple to use. You can find IDLE in the
Python 3.4 folder on your computer.

When you first start IDLE, it starts up in the shell, which is an interactive window where you can
type in Python code and see the output in the same window. I often use the shell in place of my
calculator or to try out small pieces of code. But most of the time you will want to open up a
new window and type the program in there.

Keyboard shortcuts The following keystrokes work in IDLE and can really speed up your work.

Keystroke Result
CTRL+C Copy selected text
CTRL+X Cut selected text
CTRL+V Paste
CTRL+Z Undo the last keystroke or group of keystrokes
CTRL+SHIFT+Z Redo the last keystroke or group of keystrokes
F5 Run module

9
1.3 Data analysis and machine learning
Python has become a staple in data science, allowing data analysts and other professionals to
use the language to conduct complex statistical calculations, create data visualisations, build
machine learning algorithms, manipulate and analyse data, and complete other data-related
tasks.

1.4 A first program


Start IDLE and open up a new window (choose New Window under the File Menu). Type in the
following program.
temp = eval(input('Enter a temperature in Celsius: '))
print('In Fahrenheit, that is', 9/5*temp+32)

Then, under the Run menu, choose Run Module (or press F5). IDLE will ask you to save the
file, and you should do so. Be sure to append .py to the filename as IDLE will not automatically
append it. This will tell IDLE to use colors to make your program easier to read.

Once you’ve saved the program, it will run in the shell window. The program will ask you for a
temperature. Type in 20 and press enter. The program’s output looks something like this:

Output: Enter a temperature in Celsius: 20


In Fahrenheit, that is 68.0

Let’s examine how the program does what it does. The first line asks the user to enter a
tempera-ture. The input function’s job is to ask the user to type something in and to capture
what the user types. The part in quotes is the prompt that the user sees. It is called a string and
it will appear to the program’s user exactly as it appears in the code itself. The eval function is
something we use here, but it won’t be clear exactly why until later. So for now, just remember
that we use it when we’re getting numerical input.
We need to give a name to the value that the user enters so that the program can remember it
and use it in the second line. The name we use is temp and we use the equals sign to assign
the user’s value to temp.
The second line uses the print function to print out the conversion. The part in quotes is another
string and will appear to your program’s user exactly as it appears in quotes here. The second
argument to the print function is the calculation. Python will do the calculation and print out the
numerical result.
This program may seem too short and simple to be of much use, but there are many websites
that have little utilities that do similar conversions, and their code is not much more complicated
than the code here.
A second program Here is a program that computes the average of two numbers that the user
enters:
num1 = eval(input('Enter the first number: '))
num2 = eval(input('Enter the second number: '))
print('The average of the numbers you entered is', (num1+num2)/2)

10
For this program we need to get two numbers from the user. There are ways to do that in one line,
but for now we’ll keep things simple. We get the numbers one at a time and give each number its
own name. The only other thing to note is the parentheses in the average calculation. This is
because of the order of operations. All multiplications and divisions are performed before any
additions and subtractions, so we have to use parentheses to get Python to do the addition first.

1.5 Typing things in


Case Case matters. To Python, print, Print, and PRINT are all different things. For now, stick
with lowercase as most Python statements are in lowercase.
Spaces Spaces matter at the beginning of lines, but not elsewhere. For example, the code
below will not work.

temp = eval(input('Enter a temperature in Celsius: '))

print('In Fahrenheit, that is', 9/5*temp+32)

Python uses indentation of lines for things we’ll learn about soon. On the other hand, spaces
in most other places don’t matter. For instance, the following lines have the same effect:

print('Hello world! ')

print ('Hello world! ')

print( 'Hello world! ' )

Basically, computers will only do what you tell them, and they often take things very literally.
Python itself totally relies on things like the placement of commas and parentheses so it knows
what’s what. It is not very good at figuring out what you mean, so you have to be precise. It will
be very frustrating at first, trying to get all of the parentheses and commas in the right places,
but after a while it will become more natural. Still, even after you’ve programmed for a long
time, you will still miss something. Fortunately, the Python interpreter is pretty good about
helping you find your mistakes.

1.6 Getting input


The input function is a simple way for your program to get information from people using your
program. Here is an example:
name = input('Enter your name: ')
print('Hello, ', name)
The basic structure is
variable name = input(message to user)

The above works for getting text from the user. To get numbers from the user to use in
calculations, we need to do something extra. Here is an example:
num = eval(input('Enter a number: '))
print(' Your number squared:', num*num)

11
The eval function converts the text entered by the user into a number. One nice feature of this
is you can enter expressions, like 3*12+5, and eval will compute them for you.

Note If you run your program and nothing seems to be happening, try pressing enter. There is
a bit of a glitch in IDLE that occasionally happens with input statements.

1.7 Printing
Here is a simple example:
print('Hi there')

The print function requires parenthesis around its arguments. In the program above, its only
argument is the string 'Hi there'. Anything inside quotes will (with a few exceptions) be printed
exactly as it appears. In the following, the first statement will output 3+4, while the second will
output 7.
print('3+4')
print(3+4)

To print several things at once, separate them by commas. Python will automatically insert
spaces between them. Below is an example and the output it produces.
print('The value of 3+4 is', 3+4)
print('A', 1, 'XYZ', 2)

Output:
The value of 3+4 is 7
A1XYZ2

Optional arguments
There are two optional arguments to the print function. They are not overly important at this
stage of the game, so you can safely skip over this section, but they are useful for making your
output look nice.

sep Python will insert a space between each of the arguments of the print function. There is an
optional argument called sep, short for separator, that you can use to change that space to some-
thing else. For example, using sep=':' would separate the arguments by a colon and sep='##' would
separate the arguments by two pound signs.

One particularly useful possibility is to have nothing inside the quotes, as in sep=''. This says to
put no separation between the arguments. Here is an example where sep is useful for getting
the output to look nice:
print ('The value of 3+4 is', 3+4, '.')
print ('The value of 3+4 is ', 3+4, '.', sep='')

Output:
The value of 3+4 is 7 .

12
The value of 3+4 is 7.
end The print function will automatically advance to the next line. For instance, the following will
print on two lines:
print('On the first line')
print('On the second line')

Output:
On the first line
On the second line
There is an optional argument called end that you can use to keep the print function from
advancing to the next line. Here is an example: print('On the first line', end='')
print('On the second line')
Output:
On the first lineOn the second line
Of course, this could be accomplished better with a single print, but we will see later that there
are interesting uses for the end argument.

1.8 Variables
Looking back at our first program, we see the use of a variable called temp:

temp = eval(input('Enter a temperature in Celsius: '))


print('In Fahrenheit, that is', 9/5*temp+32)

One of the major purposes of a variable is to remember a value from one part of a program so
that it can be used in another part of the program. In the case above, the variable temp stores
the value that the user enters so that we can do a calculation with it in the next line.
In the example below, we perform a calculation and need to use the result of the calculation in
several places in the program. If we save the result of the calculation in a variable, then we only
need to do the calculation once. This also helps to make the program more readable.
temp = eval(input('Enter a temperature in Celsius: '))
f_temp = 9/5*temp+32

print(' In Fahrenheit, that is', f_temp)


if f_temp > 212:
print('That temperature is above the boiling point.')
if f_temp < 32:
print('That temperature is below the freezing point.')
We haven’t discussed if statements yet, but they do exactly what you think they do.
A second example Here is another example with variables. Before reading on, try to figure out
what the values of x and y will be after the code is executed.
x=3
y=4
z=x+y
z=z+1
13
x=y
y=5
After these four lines of code are executed, x is 4, y is 5 and z is 8. One way to understand something
like this is to take it one line at a time. This is an especially useful technique for trying to understand
more complicated chunks of code. Here is a description of what happens in the code above:

1. x starts with the value 3 and y starts with the value 4.


2. In line 3, a variable z is created to equal x+y, which is 7.
3. Then the value of z is changed to equal one more than it currently equals, changing it
from 7 to 8.
4. Next, x is changed to the current value of y, which is 4.

5. Finally, y is changed to 5. Note that this does not affect x.


6. So at the end, x is 4, y is 5, and z is 8.

1.9 Variable names


There are just a couple of rules to follow when naming your variables.
• Variable names can contain letters, numbers, and the underscore.
• Variable names cannot contain spaces.
• Variable names cannot start with a number.
• Case matters—for instance, temp and Temp are different.

It helps make your program more understandable if you choose names that are descriptive,
but not so long that they clutter up your program.

14
Exercises
1. Print a box like the one below.

*******************
*******************
*******************

2. Print a triangle like the one below.

*
**
***
****

3. Ask the user to enter a number. Print out the square of the number, but use the sep
optional argument to print it out in a full sentence that ends in a period. Sample output
is shown below.

Enter a number: 5
The square of 5 is 25.

15
Chapter 2

For loops
Probably the most powerful thing about computers is that they can repeat things over and over
very quickly. There are several ways to repeat things in Python, the most common of which is
the for loop.

2.1 Examples
Example 1 The following program will print Hello ten times:
for i in range(10):
print('Hello')
The structure of a for loop is as follows:
for variable name in range( number of times to repeat ):
statements to be repeated
The syntax is important here. The word for must be in lowercase, the first line must end with a
colon, and the statements to be repeated must be indented. Indentation is used to tell Python
which statements will be repeated.
Example 2 The program below asks the user for a number and prints its square, then asks for
another number and prints its square, etc. It does this three times and then prints that the loop
is done.
for i in range(3):
num = eval(input('Enter a number: '))
print ('The square of your number is ', num*num)

print('The loop is now done.')


Output:
Enter a number: 3

The square of your number is 9

Enter a number: 5

The square of your number is 25

Enter a number: 23

The square of your number is 529

The loop is now done.

Since the second and third lines are indented, Python knows that these are the statements to
be repeated. The fourth line is not indented, so it is not part of the loop and only gets executed
once, after the loop has completed.

16
Looking at the above example, we see where the term for loop comes from: we can picture the
execution of the code as starting at the for statement, proceeding to the second and third lines,
then looping back up to the for statement.
Example 3 The program below will print A, then B, then it will alternate C’s and D’s five times
and then finish with the letter E once.
print('A')
print('B')
for i in range(5):
print('C')
print('D')
print('E')
The first two print statements get executed once, printing an A followed by a B. Next, the C’s
and D’s alternate five times. Note that we don’t get five C’s followed by five D’s. The way the
loop works is we print a C, then a D, then loop back to the start of the loop and print a C and
another D, etc. Once the program is done looping with the C’s and D’s, it prints one E.
Example 4 If we wanted the above program to print five C’s followed by five D’s, instead of
alternating C’s and D’s, we could do the following:
print('A')
print('B')
for i in range(5):
print('C')
for i in range(5):
print('D')
print('E')

2.2 The loop variable

There is one part of a for loop that is a little tricky, and that is the loop variable. In the example
below, the loop variable is the variable i. The output of this program will be the numbers 0, 1, .
. . , 99, each printed on its own line.
for i in range(100):
print(i)
When the loop first starts, Python sets the variable i to 0. Each time we loop back up, Python
increases the value of i by 1. The program loops 100 times, each time increasing the value of i
by 1, until we have looped 100 times. At this point the value of i is 99.
You may be wondering why i starts with 0 instead of 1. Well, there doesn’t seem to be any really
good reason why other than that starting at 0 was useful in the early days of computing and it
has stuck with us. In fact most things in computer programming start at 0 instead of 1. This
does take some getting used to.
Since the loop variable, i, gets increased by 1 each time through the loop, it can be used to
keep track of where we are in the looping process. Consider the example below:

17
for i in range(3):
print(i+1, '-- Hello')
Output:
1 -- Hello
2 -- Hello
3 -- Hello

Names There’s nothing too special about the name i for our variable. The programs below will
have the exact same result.

for i in range(100): for wacky_name in


range(100):

print(i)
print(wacky_name)

It’s a convention in programming to use the letters i, j, and k for loop variables, unless there’s
a good reason to give the variable a more descriptive name.

2.3 The range function

The value we put in the range function determines how many times we will loop. The way range
works is it produces a list of numbers from zero to the value minus one. For instance, range(5)
produces five values: 0, 1, 2, 3, and 4.
If we want the list of values to start at a value other than 0, we can do that by specifying the
starting value. The statement range(1,5) will produce the list 1, 2, 3, 4. This brings up one quirk
of the range function—it stops one short of where we think it should. If we wanted the list to contain
the numbers 1 through 5 (including 5), then we would have to do range(1,6).

Another thing we can do is to get the list of values to go up by more than one at a time. To do
this, we can specify an optional step as the third argument. The statement range(1,10,2) will
step through the list by twos, producing 1, 3, 5, 7, 9.
To get the list of values to go backwards, we can use a step of -1. For instance, range(5,1,-1)
will produce the values 5, 4, 3, 2, in that order. (Note that the range function stops one short of
the ending value 1). Here are a few more examples:

Statement Values generated


range(10) 0,1,2,3,4,5,6,7,8,9
range(1,10) 1,2,3,4,5,6,7,8,9
range(3,7) 3,4,5,6
range(2,15,3) 2,5,8,11,14
range(9,2,-1) 9,8,7,6,5,4,3

18
Here is an example program that counts down from 5 and then prints a message.
for i in range(5,0,-1):
print(i, end=' ')

print('Blast off!! ')

Output:
5 4 3 2 1 Blast off!!!
The end=' ' just keeps everything on the same line.

2.4 A Trickier Example

Let’s look at a problem where we will make use of the loop variable. The program below prints
a rectangle of stars that is 4 rows tall and 6 rows wide.

for i in range(4):
print('*'*6)

Output:
It just repeats the asterisk character six times.

******
******
******
******

Suppose we want to make a triangle instead. We can accomplish this with a very small change
to the rectangle program. Looking at the program, we can see that the for loop will repeat the
print statement four times, making the shape four rows tall. It’s the 6 that will need to change.

The key is to change the 6 to i+1. Each time through the loop the program will now print i+1
stars instead of 6 stars. The loop counter variable i runs through the values 0, 1, 2, and 3. Using
it allows us to vary the number of stars. Here is triangle program:
for i in range(4):
print('*'*(i+1))

Output:
*
**
***
****

19
2.5 Exercises

1. Write a program that prints your name 100 times.

2. Write a program to fill the screen horizontally and vertically with your name. [Hint: add
the option end='' into the print function to fill the screen horizontally.]

3. Write a program that outputs 100 lines, numbered 1 to 100, each with your name on it.
The output should look like the output below.

1 Your name
2 Your name
3 Your name
4 Your name
...
100 Your name

4. Write a program that prints out a list of the integers from 1 to 20 and their squares. The
output should look like this:

1 --- 1
2 --- 4
3 --- 9
...
20 --- 400

5. Write a program that uses a for loop to print the numbers 8, 11, 14, 17, 20, . . . , 83, 86, 89.

6. Write a program that uses a for loop to print the numbers 100, 98, 96, . . . , 4, 2.

7. Write a program that uses exactly four for loops to print the sequence of letters below.

AAAAAAAAAABBBBBBBCDCDCDCDEFFFFFFG

8. Write a program that asks the user for their name and how many times to print it. The
program should print out the user’s name the specified number of times.

20
Chapter 3

Numbers
This chapter focuses on numbers and simple mathematics in Python.

3.1 Integers and Decimal Numbers

Because of the way computer chips are designed, integers and decimal numbers are
represented differently on computers. Decimal numbers are represented by what are called
floating point num-bers. The important thing to remember about them is you typically only get
about 15 or so digits of precision. It would be nice if there were no limit to the precision, but
calculations run a lot more quickly if you cut off the numbers at some point.
On the other hand, integers in Python have no restrictions. They can be arbitrarily large.
For decimal numbers, the last digit is sometimes slightly off due to the fact that computers work
in binary (base 2) whereas our human number system is base 10. As an example,
mathematically, we know that the decimal expansion of 7=3 is 2.333 , with the threes repeating
forever. But when we type 7/3 into the Python shell, we get 2.3333333333333335. This is called
roundoff error. For most practical purposes this is not too big of a deal, but it actually can cause
problems for some mathematical and scientific calculations.

3.2 Math Operators

Here is a list of the common operators in Python:

Operator Description

+ Addition

- Subtraction

* Multiplication

/ Divison

% Modulo (remainder)

// Integer division

** Exponentiation

21
Exponentiation Python uses ** for exponentiation. The caret, ^, is used for something else.

Integer division The integer division operator, //, requires some explanation. Basically, for pos-
itive numbers it behaves like ordinary division except that it throws away the decimal part of the
result. For instance, while 8/5 is 1.6, we have 8//5 equal to 1. We will see uses for this operator
later. Note that in many other programming languages and in older versions of Python, the
usual division operator / actually does integer division on integers.
Modulo The modulo operator, %, returns the remainder from a division. For instance, the result
of 18%7 is 4 because 4 is the remainder when 18 is divided by 7. This operation is surprisingly
useful. For instance, a number is divisible by n precisely when it leaves a remainder of 0 when
divided by n. Thus to check if a number, n, is even, see if n%2 is equal to 0. To check if n is
divisible by 3, see if n%3 is 0.
One use of this is if you want to schedule something in a loop to happen only every other time
through the loop, you could check to see if the loop variable modulo 2 is equal to 0, and if it is,
then do that something.
The modulo operator shows up surprisingly often in formulas. If you need to “wrap around” and
come back to the start, the modulo is useful. For example, think of a clock. If you go six hours
past 8 o’clock, the result is 2 o’clock. Mathematically, this can be accomplished by doing a
modulo by 12. That is, (8+6)%12 is equal to 2.

3.3 Order of operations

Exponentiation gets done first, followed by multiplication and division (including // and %), and
addition and subtraction come last. The classic math class mnemonic, PEMDAS (Please
Excuse My Dear Aunt Sally), might be helpful.

This comes into play in calculating an average. Say you have three variables x, y, and z, and
you want to calculate the average of their values. To expression x+y+z/3 would not work.
𝑍
Because division comes before addition, you would actually be calculating 𝑥 + 𝑦 + 3 instead of
𝑥+𝑦+𝑧
3
.

This is easily fixed by using parentheses: (x+y+z)/3.


In general, if you’re not sure about something, adding parentheses might help and usually
doesn’t do any harm.

3.4 Random numbers

To make an interesting computer game, it’s good to introduce some randomness into it. Python
comes with a module, called random, that allows us to use random numbers in our programs.
Before we get to random numbers, we should first explain what a module is. The core part of
the Python language consists of things like for loops, if statements, math operators, and some
functions, like print and input. Everything else is contained in modules, and if we want to use
something from a module we have to first import it—that is, tell Python that we want to use it.
22
At this point, there is only one function, called randint, that we will need from the random mod-
ule. To load this function, we use the following statement:

from random import randint

Using randint is simple: randint(a,b) will return a random integer between a and b including both
a and b. (Note that randint includes the right endpoint b unlike the range function). Here is a
short example:

from random import randint

x = randint(1,10)

print('A random number between 1 and 10: ', x)

Output:

A random number between 1 and 10: 7

The random number will be different every time we run the program.

3.5 Math functions

The math module Python has a module called math that contains familiar math functions, in-
cluding sin, cos, tan, exp, log, log10, factorial, sqrt, floor, and ceil. There are also the inverse trig
functions, hyperbolic functions, and the constants pi and e. Here is a short example:
from math import sin, pi

print('Pi is roughly', pi)

print(' sin(0) =', sin(0))

Output:

Pi is roughly 3.14159265359
sin(0) = 0.0
Built-in math functions There are two built in math functions, abs (absolute value) and
round that are available without importing the math module. Here are some examples:

print(abs(-4.3))

print(round(3.336, 2))

print(round(345.2, -1))

23
Output:

4.3
3.34
350.0

The round function takes two arguments: the first is the number to be rounded and the
second is the number of decimal places to round to. The second argument can be negative.

1 math.sqrt() - Square Root

Finds the square root of a number.


Example:
import math
print(math.sqrt(25))

Output:
5.0

2 math.pow() - Power Function

Raises a number to a power.


Example:
print(math.pow(2, 3)) # 2 raised to the power 3

Output:
8.0

3 math.ceil() and math.floor() - Rounding

 ceil() rounds up to the nearest integer.

 floor() rounds down to the nearest integer.

Example:
print(math.ceil(4.2)) # Round up
print(math.floor(4.8)) # Round down

Output:
5
4

24
4 math.factorial() - Factorial

Finds the factorial of a number.


Example:
print(math.factorial(5)) # 5! = 5 × 4 × 3 × 2 × 1

Output:

120

5 math.pi and math.e - Constants

 math.pi gives the value of π.

 math.e gives Euler’s number.

Example:
print(math.pi)
print(math.e)

Output:
3.141592653589793
2.718281828459045

6 math.sin(), math.cos(), math.tan() - Trigonometry

Returns sine, cosine, and tangent values (in radians).


Example:
print(math.sin(math.radians(30))) # Convert degrees to radians
print(math.cos(math.radians(60)))
print(math.tan(math.radians(45)))

Output:
0.5
0.5
1.0

3.6 Getting help from Python

25
There is documentation built into Python. To get help on the math module, for example, go to the

Python shell and type the following two lines:

>>> import math

>>> dir(math)

Output

:['__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin',

'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos',


'cosh', 'degrees', 'e', 'exp', 'fabs', 'factorial', 'floor',
'fmod', 'frexp', 'fsum', 'hypot', 'isinf', 'isnan', 'ldexp',
'log', 'log10', 'log1p', 'modf', 'pi', 'pow ', 'radians', 'sin',
'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

This gives a list of all the functions and variables in the math module. You can ignore all of the
ones that start with underscores. To get help on a specific function, say the floor function, you
can type help(math.floor). Typing help(math) will give you help for everything in the math module.

3.7 Using the Shell as a Calculator

The Python shell can be used as a very handy and powerful calculator. Here is an example session:

>>> 23**2
529

>>> s = 0
>>> for n in range(1,10001): s = s +
1/n**2

>>> s

1.6448340718480652
>>> from math import *
>>> factorial(10)

26
3628800

The second example here sums the numbers 1 + 1=4 + 1=9 + + 1=100002. The result is stored in the
variable s. To inspect the value of that variable, just type its name and press enter. Inspecting
variables is useful for debugging your programs. If a program is not working properly, you can type
your variable names into the shell after the program has finished to see what their values are.

The statement from math import* imports every function from the math module, which can
make the shell a lot like a scientific calculator.

Note Under the Shell menu, select Restart shell if you want to clear the values of all the
variables.

3.8 Date and Time Functions in Python

Python provides the datetime module for handling date and time.

>>>dir(datetime)

Displays all the function in datetime module.


Output:

['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',


'__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__',
'__le__', '__lt__', '__ne__', '__new__', '__radd__', '__reduce__', '__reduce_ex__',
'__repr__', '__rsub__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__',
'astimezone', 'combine', 'ctime', 'date', 'day', 'dst', 'fold', 'fromisocalendar', 'fromisoformat',
'fromordinal', 'fromtimestamp', 'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max',
'microsecond', 'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second', 'strftime',
'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today', 'toordinal', 'tzinfo', 'tzname',
'utcfromtimestamp', 'utcnow', 'utcoffset', 'utctimetuple', 'weekday', 'year']

First, Import the datetime Module

from datetime import *

1 datetime.now() - Current Date and Time

Gets the current system date and time.


Example:
now = datetime.now()
print(now)
27
Output:
2025-03-17 14:30:45.123456

(Output will vary based on the current date and time.)


2 date.today() - Get Today’s Date

Gets the current system date.


Example:
today = date.today()
print(today)

Output:
2025-03-17

3 strftime() - Format Date and Time

Formats date and time into a readable string.


Example:
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))

Output:
2025-03-17 14:30:45

4 timedelta() - Date Arithmetic

Adds or subtracts days from a date.


Example:
today = date.today()
print(today)
future_date = today + timedelta(days=10)
print(future_date)

Output:
2025-03-27

5 datetime.strptime() - Convert String to Date

Parses a string into a datetime object.


Example:
date_string = "2025-03-17 14:30:45"
dt = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
print(dt)
28
Output:
2025-03-17 14:30:45

6. Create a date object


import datetime

x = datetime.datetime(2020, 5, 17)

print(x)

Display the name of the month:


print(x.strftime("%B"))

Output:
2020-05-17 00:00:00
May
A reference of all the legal format codes:

Directive Description Example

%a Weekday, short version Wed

%A Weekday, full version Wednesday

%w Weekday as a number 0-6, 0 is Sunday 3

%d Day of month 01-31 31

%b Month name, short version Dec

%B Month name, full version December

%m Month as a number 01-12 12

%y Year, short version, without century 18

%Y Year, full version 2018

%H Hour 00-23 17

%I Hour 00-12 05

%p AM/PM PM

29
%M Minute 00-59 41

%S Second 00-59 08

%f Microsecond 000000-999999 548513

%z UTC offset +0100

%Z Timezone CST

%j Day number of year 001-366 365

%U Week number of year, Sunday as the first day 52


of week, 00-53

%W Week number of year, Monday as the first 52


day of week, 00-53

%c Local version of date and time Mon Dec 31 17:41:00 2018

%C Century 20

%x Local version of date 12/31/18

%X Local version of time 17:41:00

%% A % character %

%G ISO 8601 year 2018

%u ISO 8601 weekday (1-7) 1

%V ISO 8601 weeknumber (01-53) 01

30
3.9 Exercises

1. Write a program that generates and prints 50 random integers, each between 3 and 6.

2. Write a program that generates a random number, x, between 1 and 50, a random
number y between 2 and 5, and computes x y .

3. Write a program that generates a random number between 1 and 10 and prints your
name that many times.

4. Write a program that generates a random decimal number between 1 and 10 with two
decimal places of accuracy. Examples are 1.23, 3.45, 9.80, and 5.00.

5. Write a program that generates 50 random numbers such that the first number is between
1 and 2, the second is between 1 and 3, the third is between 1 and 4, . . . , and the last is
between 1 and 51.

31
Chapter 4

If statements
Quite often in programs we only want to do something provided something else is true. Python’s
if statement is what we need.

4.1 A Simple Example

Let’s try a guess-a-number program. The computer picks a random number, the player tries to
guess, and the program tells them if they are correct. To see if the player’s guess is correct, we
need something new, called an if statement.
from random import randint
num = randint(1,10)
guess = eval(input('Enter your guess: '))
if guess==num:
print('You got it! ')

The syntax of the if statement is a lot like the for statement in that there is a colon at the end of
the if condition and the following line or lines are indented. The lines that are indented will be
executed only if the condition is true. Once the indentation is done with, the if block is concluded.

The guess-a-number game works, but it is pretty simple. If the player guesses wrong, nothing
happens. We can add to the if statement as follows:

if guess==num:
print('You got it! ')
else:
print('Sorry. The number is ', num)

We have added an else statement, which is like an “otherwise.”

4.2 Conditional operators

The comparison operators are ==, >, <, >=, <=, and !=. That last one is for not equals. Here are
a few examples:

32
Expression Description
if x>3: if x is greater than 3
if x>=3: if x is greater than or equal to 3
if x==3: if x is 3
if x!=3: if x is not 3

There are three additional operators used to construct more complicated conditions: and, or,
and not. Here are some examples:

if grade>=80 and grade<90:


print('Your grade is a B.')

if score>1000 or time>20:
print('Game over.')

if not (score>1000 or time>20):


print('Game continues.')

Order of operations In terms of order of operations, and is done before or, so if you have a
complicated condition that contains both, you may need parentheses around the or condition.
Think of and as being like multiplication and or as being like addition. Here is an example:

if (score<1000 or time>20) and turns_remaining==0:


print('Game over.')

4.3 Common Mistakes

Mistake 1 The operator for equality consists of two equals signs. It is a really common error
to forget one of the equals signs.

Incorrect Correct
if x=1: if x==1:

Mistake 2 A common mistake is to use and where or is needed or vice-versa. Consider the
following if statements:
if x>1 and x<100:
if x>1 or x<100:

33
The first statement is the correct one. If x is any value between 1 and 100, then the statement
will be true. The idea is that x has to be both greater than 1 and less than 100. On the other
hand, the second statement is not what we want because for it to be true, either x has to be
greater than 1 or x has to be less than 100. But every number satisfies this. The lesson here is if
your program is not working correctly, check your and’s and or’s.

Mistake 3 Another very common mistake is to write something like below:


if grade>=80 and <90:

This will lead to a syntax error. We have to be explicit. The correct statement is

if grade>=80 and grade<90:

On the other hand, there is a nice shortcut that does work in Python (though not in many other
programming languages):

if 80<=grade<90:

4.4 elif

A simple use of an if statement is to assign letter grades. Suppose that scores 90 and above
are A’s, scores in the 80s are B’s, 70s are C’s, 60s are D’s, and anything below 60 is an F.
Here is one way to do this:

grade = eval(input('Enter your score: '))

if grade>=90:
print('A')
if grade>=80 and grade<90:
print('B')
if grade>=70 and grade<80:
print('C')
if grade>=60 and grade<70:
print('D')
if grade<60:
print('F')

The code above is pretty straightforward and it works. However, a more elegant way to do it is
shown below.

34
grade = eval(input('Enter your score: '))

if grade>=90:

print('A')
elif grade>=80:

print('B')
elif grade>=70:

print('C')
elif grade>=60:

print('D')
else:
print('F')

With the separate if statements, each condition is checked regardless of whether it really needs
to be. That is, if the score is a 95, the first program will print an A but then continue on and
check to see if the score is a B, C, etc., which is a bit of a waste. Using elif, as soon as we find
where the score matches, we stop checking conditions and skip all the way to the end of the
whole block of statements. An added benefit of this is that the conditions we use in the elif
statements are simpler than in their if counterparts. For instance, when using elif, the second
part of the second if statement condition, grade<90, becomes unnecessary because the
corresponding elif does not have to worry about a score of 90 or above, as such a score would
have already been caught by the first if statement.
You can get along just fine without elif, but it can often make your code simpler.

4.5 Exercises

1. Write a program that asks the user to enter a length in centimeters. If the user enters a
negative length, the program should tell the user that the entry is invalid. Otherwise, the
program should convert the length to inches and print out the result. There are 2.54
centimeters in an inch.

2. Ask the user for a temperature. Then ask them what units, Celsius or Fahrenheit, the temper-
ature is in. Your program should convert the temperature to the other unit. The conversions

a. are F = 9/ 5 C + 32 and C = 5/ 9 (F-32).

3. Ask the user to enter a temperature in Celsius. The program should print a message
based on the temperature:

35
a. If the temperature is less than -273.15, print that the temperature is invalid because
it is below absolute zero.

b. If it is exactly -273.15, print that the temperature is absolute 0.

c. If the temperature is between -273.15 and 0, print that the temperature is below freezing.

d. If it is 0, print that the temperature is at the freezing point.

e. If it is between 0 and 100, print that the temperature is in the normal range.

f. If it is 100, print that the temperature is at the boiling point.

g. If it is above 100, print that the temperature is above the boiling point.

4. Generate a random number between 1 and 10. Ask the user to guess the number and
print a message based on whether they get it right or not.

5. A store charges $12 per item if you buy less than 10 items. If you buy between 10 and 99
items, the cost is $10 per item. If you buy 100 or more items, the cost is $7 per item. Write
a program that asks the user how many items they are buying and prints the total cost.

36
Chapter 5

Miscellaneous Topics I
This chapter consists of a several common techniques and some other useful information.

5.1 Counting

Very often we want our programs to count how many times something happens. For instance,
a video game may need to keep track of how many turns a player has used, or a math program
may want to count how many numbers have a special property. The key to counting is to use
a variable to keep the count.

Example 1 This program gets 10 numbers from the user and counts how many of those
numbers are greater than 10.

count = 0
for i in range(10):
num = eval(input('Enter a number: '))

if num>10:
count=count+1
print('There are', count, ' numbers greater than 10.')

Think of the count variable as if we are keeping a tally on a piece of paper. Every time we get
a number larger than 10, we add 1 to our tally. In the program, this is accomplished by the line
count=count+1. The first line of the program, count=0, is important. Without it, the Python interpreter
would get to the count=count+1 line and spit out an error saying something about not knowing what
count is. This is because the first time the program gets to this line, it tries to do what it says: take
the old value of count, add 1 to it, and store the result in count. But the first time the program gets
there, there is no old value of count to use, so the Python interpreter doesn’t know what to do. To
avoid the error, we need to define count, and that is what the first line does. We set it to 0 to indicate
that at the start of the program no numbers greater than 10 have been found.

Counting is an extremely common thing. The two things involved are:


1. count=0 — Start the count at 0.
2. count=count+1 — Increase the count by 1.

37
Example 2 This modification of the previous example counts how many of the numbers the
user enters are greater than 10 and also how many are equal to 0. To count two things we use
two count variables.

count1 = 0
count2 = 0
for i in range(10):
num = eval(input('Enter a number: '))

if num>10:
count1=count1+1

if num==0:
count2=count2+1
print('There are', count1, ' numbers greater than 10.')
print('There are', count2, 'zeroes.')

Example 3 Next we have a slightly trickier example. This program counts how many of the
squares from 12 to 1002 end in a 4.

count = 0
for i in range(1,101):
if (i**2)%10==4:

count = count + 1
print(count)

A few notes here: First, because of the aforementioned quirk of the range function, we need to
use range(1,101) to loop through the numbers 1 through 100. The looping variable i takes on those
values, so the squares from 12 to 1002 are represented by i**2. Next, to check if a number ends in
4, a nice mathematical trick is to check if it leaves a remainder of 4 when divided by 10. The modulo
operator, %, is used to get the remainder.

5.2 Summing

Closely related to counting is summing, where we want to add up a bunch of numbers.

Example 1 This program will add up the numbers from 1 to 100. The way this works is that
each time we encounter a new number, we add it to our running total, s.
s=0
for i in range(1,101):
s=s+i

print('The sum is', s)


38
Example 2 This program that will ask the user for 10 numbers and then computes their average.

s=0
for i in range(10):
num = eval(input('Enter a number: '))
s = s + num
print('The average is', s/10)

Example 3 A common use for summing is keeping score in a game. Near the beginning of the
game we would set the score variable equal to 0. Then when we want to add to the score we
would do something like below:

score = score + 10

5.3 Swapping

Quite often we will want to swap the values of two variables, x and y. It would be tempting to try
the following:
x=y
y=x

But this will not work. Suppose x is 3 and y is 5. The first line will set x to 5, which is good, but
then the second line will set y to 5 also because x is now 5. The trick is to use a third variable
to save the value of x:
hold = x

x=y

y = hold

In many programming languages, this is the usual way to swap variables. Python, however,
pro-vides a nice shortcut:
x,y = y,x
We will learn later exactly why this works. For now, feel free to use whichever method you prefer.
The latter method, however, has the advantage of being shorter and easier to understand.

5.4 Flag variables

A flag variable can be used to let one part of your program know when something happens in
another part of the program. Here is an example that determines if a number is prime.

39
num = eval(input('Enter number: '))
flag = 0
for i in range(2,num):
if num%i==0:
flag = 1

if flag==1:
print('Not prime')
else:
print('Prime')

Recall that a number is prime if it has no divisors other than 1 and itself. The way the program
above works is flag starts off at 0. We then loop from 2 to num-1. If one of those values turns
out to be a divisor, then flag gets set to 1. Once the loop is finished, we check to see if the flag
got set or not. If it did, we know there was a divisor, and num isn’t prime. Otherwise, the number
must be prime.

5.5 Maxes and mins

A common programming task is to find the largest or smallest value in a series of values. Here is an
example where we ask the user to enter ten positive numbers and then we print the largest one.

largest = eval(input('Enter a positive number: '))


for i in range(9):
num = eval(input('Enter a positive number: '))

if num>largest:
largest=num
print('Largest number:', largest)

The key here is the variable largest that keeps track of the largest number found so far. We
start by setting it equal to the user’s first number. Then, every time we get a new number from
the user, we check to see if the user’s number is larger than the current largest value (which is
stored in largest). If it is, then we set largest equal to the user’s number.

If, instead, we want the smallest value, the only change necessary is that > becomes <, though
it would also be good to rename the variable largest to smallest.

Later on, when we get to lists, we will see a shorter way to find the largest and smallest values,
but the technique above is useful to know since you may occasionally run into situations where
the list way won’t do everything you need it to do.

40
5.6 Comments

A comment is a message to someone reading your program. Comments are often used to
describe what a section of code does or how it works, especially with tricky sections of code.
Comments have no effect on your program.
Single-line comments For a single-line comment, use the # character.

# a slightly sneaky way to get two values at once

num1, num2 = eval(input('Enter two numbers separated by commas: '))

You can also put comments at the end of a line:

count = count + 2 # each divisor contributes two the count

Multi-line comments For comments that span several lines, you can use triple quotes.

""" Program name: Hello world


Author: Brian Heinold
Date: 1/9/11 """

print('Hello world')

One nice use for the triple quotes is to comment out parts of your code. Often you will want to
modify your program but don’t want to delete your old code in case your changes don’t work.
You could comment out the old code so that it is still there if you need it, and it will be ignored
when your new program is run. Here is a simple example:

"""

print('This line and the next are inside a comment.')

print('These lines will not get executed.')

"""

print('This line is not in a comment and it will be executed. ')

5.7 Simple debugging

Here are two simple techniques for figuring out why a program is not working:

41
1. Use the Python shell. After your program has run, you can type in the names of your pro-
gram’s variables to inspect their values and see which ones have the values you expect
them to have and which don’t. You can also use the Shell to type in small sections of your
program and see if they are working.

2. Add print statements to your program. You can add these at any point in your program to see
what the values of your variables are. You can also add a print statement to see if a point in
your code is even being reached. For instance, if you think you might have an error in a
condition of an if statement, you can put a print statement into the if block to see if the
condition is being triggered.

Here is an example from the part of the primes program from earlier in this chapter. We
put a print statement into the for loop to see exactly when the flag variable is being set:
flag = 0
num = eval(input('Enter number: '))
for i in range(2,num):
if num%i==0:
flag = 1

print(i, flag)
3. An empty input statement, like below, can be used to pause your program at a specific
point: input()

5.8 Example programs

It is a valuable skill is to be able to read code. In this section we will look in depth at some
simple programs and try to understand how they work.

Example 1 The following program prints Hello a random number of times between 5 and 25.

from random import randint


rand_num = randint(5,25)
for i in range(rand_num):

print('Hello')

The first line in the program is the import statement. This just needs to appear once, usually near
the beginning of your program. The next line generates a random number between 5 and 25. Then,
remember that to repeat something a specified number of times, we use a for loop. To repeat some-
thing 50 times, we would use range(50) in our for loop. To repeat something 100 times, we would
use range(100). To repeat something a random number of times, we can use range(rand_num),
where rand_num is a variable holding a random number. Although if we want, we can skip the
variable and put the randint statement directly in the range function, as shown below.

42
from random import randint
for i in range(randint(5,25)):
print('Hello')

Example 2 Compare the following two programs.

from random import randint from random import randint

rand_num = randint(1,5) for i in range(6):


for i in range(6): rand_num = randint(1,5)

print('Hello'*rand_num) print('Hello'*rand_num)

Hello Hello Hello Hello Hello


Hello Hello Hello
Hello Hello Hello Hello Hello Hello
Hello Hello Hello Hello Hello
Hello Hello Hello Hello
Hello Hello Hello

The only difference between the programs is in the placement of the rand_num statement. In
the first program, it is located outside of the for loop, and this means that rand_num is set once
at the beginning of the program and retains that same value for the life of the program. Thus
every print statement will print Hello the same number of times. In the second program, the
rand_num statement is within the loop. Right before each print statement, rand_num is assigned a
new random number, and so the number of times Hello is printed will vary from line to line.

Example 3 Let us write a program that generates 10000 random numbers between 1 and 100
and counts how many of them are multiples of 12. Here are the things we will need:

• Because we are using random numbers, the first line of the program should import the
random module.

• We will require a for loop to run 10000 times.

• Inside the loop, we will need to generate a random number, check to see if it is divisible
by 12, and if so, add 1 to the count.

• Since we are counting, we will also need to set the count equal to 0 before we start
counting.

• To check divisibility by 12, we use the modulo, %, operator.


43
When we put this all together, we get the following:
from random import randint
count = 0
for i in range(10000):
num = randint(1, 100)

if num%12==0:
count=count+1
print('Number of multiples of 12:', count)

5.9 Indentation matters

A common mistake is incorrect indentation. Suppose we take the above and indent the last line.
The program will still run, but it won’t run as expected.

from random import randint


count = 0
for i in range(10000):
num = randint(1, 100)

if num%12==0:
count=count+1

print('Number of multiples of 12:', count)

When we run it, it outputs a whole bunch of numbers. The reason for this is that by indenting
the print statement, we have made it a part of the for loop, so the print statement will be
executed 10,000 times.
Suppose we indent the print statement one step further, like below.

from random import randint


count = 0
for i in range(10000):
num = randint(1, 100)

if num%12==0:
count=count+1

print('Number of multiples of 12:', count)


Now, not only is it part of the for loop, but it is also part of the if statement. What will happen is
every time we find a new multiple of 12, we will print the count. Neither this, nor the previous

44
example, is what we want. We just want to print the count once at the end of the program, so
we don’t want the print statement indented at all.

5.10 Exercises

1. Write a program that counts how many of the squares of the numbers from 1 to 100 end
in a 1.

2. Write a program that counts how many of the squares of the numbers from 1 to 100 end
in a 4 and how many end in a 9.

3. Write a program that asks the user to enter a value n, and then computes (1 + 12 + 13
+ + 1n ) ln(n). The ln function is log in the math module.

4. Write a program to compute the sum 1 2+3 4+ + 1999 2000.

45
Chapter 6

Strings
Strings are a data type in Python for dealing with text. Python has a number of powerful
features for manipulating strings.

6.1 Basics

Creating a string A string is created by enclosing text in quotes. You can use either single quotes,
', or double quotes, ". A triple-quote can be used for multi-line strings. Here are some examples:

s = 'Hello'
t = "Hello"

m = """This is a long string that is spread


across two lines."""

Input Recall from Chapter 1 that when getting numerical input we use an eval statement with
the input statement, but when getting text, we do not use eval. The difference is illustrated
below:
num = eval(input('Enter a number: '))

string = input('Enter a string: ')

Empty string The empty string '' is the string equivalent of the number 0. It is a string with
nothing in it. We have seen it before, in the print statement’s optional argument, sep=''.
Length To get the length of a string (how many characters it has), use the built-in function len.

For example,
len('Hello') is 5.

46
6.2 Concatenation and repetition

The operators + and * can be used on strings. The + operator combines two strings. This operation is
called concatenation. The * repeats a string a certain number of times. Here are some examples.

Expression Result

'AB'+'cd' 'ABcd'

'A'+'7'+'B' 'A7B'

'Hi'*4 'HiHiHiHi'

Example 1 If we want to print a long row of dashes, we can do the following

print('-'*75)

Example 2 The + operator can be used to build up a string, piece by piece, analogously to the way we
built up counts and sums in Sections 5.1 and 5.2. Here is an example that repeatedly asks the user to
enter a letter and builds up a string consisting of only the vowels that the user entered.

s = ''
for i in range(10):
t = input('Enter a letter: ')

if t=='a' or t=='e' or t=='i' or t=='o' or t=='u':


s=s+t
print(s)
This technique is very useful.

6.3 The in operator

The in operator is used to tell if a string contains something. For example:


if 'a' in string:
print('Your string contains the letter a.')

You can combine in with the not operator to tell if a string does not contain something:
if ';' not in string:
print('Your string does not contain any semicolons.')

47
Example In the previous section we had the long if condition
if t=='a' or t=='e' or t=='i' or t=='o' or t=='u':

Using the in operator, we can replace that statement with the following:
if t in 'aeiou':

6.4 Indexing

We will often want to pick out individual characters from a string. Python uses square brackets to
do this. The table below gives some examples of indexing the string s='Python'.

Statement Result Description


s[0] P first character of s
s[1] y second character of s
s[-1] n last character of s
s[-2] o second-to-last character of s

• The first character of s is s[0], not s[1]. Remember that in programming, counting usually
starts at 0, not 1.

• Negative indices count backwards from the end of the string.

A common error Suppose s='Python' and we try to do s[12]. There are only six characters in the
string and Python will raise the following error message:

IndexError: string index out of range

You will see this message again. Remember that it happens when you try to read past the end of
a string.

6.5 Slices

A slice is used to pick out part of a string. It behaves like a combination of indexing and the range
function. Below we have some examples with the string s='abcdefghij'.

48
index: 0 12 3 4 5 6 7 8 9
letters: abcdefghI j

Code Result Description

s[2:5] Cde characters at indices 2, 3, 4

s[ :5] Abcde first five characters

s[5: ] Fghij characters from index 5 to the end

s[-2: ] ij last two characters

s[ : ] abcdefghij entire string

s[1:7:2] Bdf characters from index 1 to 6, by twos

s[ : :-1] jihgfedcba a negative step reverses the string

• The basic structure is

string name[starting location : ending location+1]

Slices have the same quirk as the range function in that they do not include the ending
location. For instance, in the example above, s[2:5] gives the characters in indices 2, 3, and
4, but not the character in index 5.

• We can leave either the starting or ending locations blank. If we leave the starting location
blank, it defaults to the start of the string. So s[:5] gives the first five characters of s. If we
leave the ending location blank, it defaults to the end of the string. So s[5:] will give all the
characters from index 5 to the end. If we use negative indices, we can get the ending
characters of the string. For instance, s[-2:] gives the last two characters.

• There is an optional third argument, just like in the range statement, that can specify the step.
For example, s[1:7:2] steps through the string by twos, selecting the characters at indices 1,
3, and 5 (but not 7, because of the aforementioned quirk). The most useful step is -1, which
steps backwards through the string, reversing the order of the characters.

6.6 Changing individual characters of a string

Suppose we have a string called s and we want to change the character at index 4 of s to 'X'. It is
tempting to try s[4]='X', but that unfortunately will not work. Python strings are immutable, which
means we can’t modify any part of them.
s = s[:4] + 'X' + s[5:]

49
The idea of this is we take all the characters up to index 4, then X, and then all of the characters
after index 4.

6.7 Looping

Very often we will want to scan through a string one character at a time. A for loop like the one
below can be used to do that. It loops through a string called s, printing the string, character by
character, each on a separate line:

for i in range(len(s)):

print (s[i])

In the range statement we have len(s) that returns how long s is. So, if s were 5 characters long,
this would be like having range(5) and the loop variable i would run from 0 to 4. This means that s[i]
will run through the characters of s. This way of looping is useful if we need to keep track of our
location in the string during the loop.
If we don’t need to keep track of our location, then there is a simpler type of loop we can use:
for c in s:
print(c)

This loop will step through s, character by character, with c holding the current character. You can
almost read this like an English sentence, “For every character c in s, print that character.”

6.8 String Functions in Python

Python provides multiple built-in string functions that allow manipulation of strings. Some
important string functions are:
1 len() - Find the Length of a String

Returns the total number of characters in a string.


Example:
text = "Hello, Python!"
print(len(text))

Output:
14

50
2 upper() - Convert to Uppercase

Converts all lowercase letters in a string to uppercase.


Example:
text = "hello world"
print(text.upper())

Output:
HELLO WORLD

3 lower() - Convert to Lowercase

Converts all uppercase letters in a string to lowercase.


Example:
text = "Hello WORLD"
print(text.lower())

Output: hello world

4 title() - Convert to Title Case

Converts the first character to upper case and rest to lower case
Example:
text = "Hello WORLD"
print(text.title())

Output: Hello World

5 swapcase() - Convert to Title Case

Swaps the case of all characters in the string

ie. upper case character to lowercase and viceversa


Example:
text = "Hello WORLD"
print(text.title())

Output: hELLO world

51
6 capitalize() - Convert to Title Case

Convert the first character of a string to uppercase


Example:
text = "Hello WORLD"
print(text. capitalize())

Output:

Hello world

7 strip() - Remove Whitespace

Removes leading and trailing whitespace.


Example:
text = " Python Programming "
print(text.strip())

Output:
Python Programming

8 replace() - Replace Substring

Replaces a specified substring with another substring.


Example:
text = "I like Python"
print(text.replace("like", "love"))

Output:
I love Python

9 split() - Split a String into a List

Splits a string into a list based on a delimiter.


Example:
text = "apple,banana,cherry"

52
print(text.split(","))

Output:
['apple', 'banana', 'cherry']

10 join() - Join Elements of a List into a String

Joins list elements into a single string with a specified separator.


Example:
words = ["Hello", "Python", "World"]
print(" ".join(words))

Output:
Hello Python World

11 find() - Find Substring Index

Finds the first occurrence of a substring. Returns -1 if not found.


Example:
text = "Python is amazing"
print(text.find("is"))

Output:
7

12 startswith() and endswith() - Check Start and End

Checks if a string starts or ends with a specific substring.


Example:
text = "Hello, Python!"
print(text.startswith("Hello"))
print(text.endswith("!"))

Output:
True
True

53
13 isalpha()
The isalpha() method checks if all characters in a given string are alphabetic. It returns True if
every character in the string is a letter and False if the string contains any numbers, spaces, or
special characters.
Example:

s1 = "HelloWorld"
res1 = s1.isalpha()
print(res1)
s2 = "Hello123"

res2 = s2.isalpha()
print(res2)

Output:
True
False

14 isdigit()

Python String isdigit() function returns True if all the characters in the string are digits, otherwise
False.
Example:
s1 = “23432”
res1 = s1.isdigit()
print(res1)
s2 = "12f3"
res2 = s2.isdigit()
print(res2)

Output:
True
False

54
15 isupper(), islower() and istitle()

Python String islower() returns True if all cased characters in the string are lowercase
islower()
and there is at least one cased character, otherwise it returns False.

isupper() Python String isupper() function returns True if all the cased characters are in Uppercase.

istitle() Python String istitle() returns True if the string is title cased and not empty, otherwise it returns False.

6.9 Escape characters

The backslash, \, is used to get certain special characters, called escape characters, into your string.

There are a variety of escape characters, and here are the most useful ones:
• \n the newline character. It is used to advance to the next line. Here is an example:
print('Hi\n\nthere! ')

Hi
There!

• \' for inserting apostrophes into strings. Say you have the following string: s = 'I
can't go'

This will produce an error because the apostrophe will actually end the string. You can use
\' to get around this:
s = 'I can\'t go'

Another option is to use double quotes for the string:


"s = I can't go"

• \" analogous to \'.


• \\ This is used to get the backslash itself. For example:
filename = 'c:\\programs\\file.py'

55
• \t the tab character

6.10 Examples

Example 1 An easy way to print a blank line is print(). However, if we want to print ten blank lines,
a quick way to do that is the following:

print('\n'*9)

Note that we get one of the ten lines from the print function itself.
Example 2 Write a program that asks the user for a string and prints out the location of each 'a' in
the string.
s = input('Enter some text: ')
for i in range(len(s)):
if s[i]=='a':
print(i)
We use a loop to scan through the string one character at a time. The loop variable i keeps track
of our location in the string, and s[i] gives the character at that location. Thus, the third line checks
each character to see if it is an 'a', and if so, it will print out i, the location of that 'a'.

Example 3 Write a program that asks the user for a string and creates a new string that doubles
each character of the original string. For instance, if the user enters Hello, the output should be
HHeelllloo.

s = input('Enter some text: ')


doubled_s = ''
for c in s:
doubled_s = doubled_s + c *2

Here we can use the second type of loop from Section 6.7. The variable c will run through the
characters of s. We use the repetition operator, *, to double each character. We build up the string
s in the way described at the end of Section 6.2.

Example 4 Write a program that asks a user for their name and prints it in the following funny
pattern:

E El Elv Elvi Elvis

56
We will require a loop because we have to repeatedly print sections of the string, and to print the
sections of the string, we will use a slice:

name = input('Enter your name: ')


for i in range(len(name)):
print(name[:i+1], end=' ')

The one trick is to use the loop variable i in the slice. Since the number of characters we need to
print is changing, we need a variable amount in the slice. This is reminiscent of the triangle program
from Section 2.4. We want to print one character of the name the first time through the loop, two
characters the second time, etc. The loop variable, i, starts at 0 the first time through the loop, then
increases to 1 the second time through the loop, etc. Thus we use name[:i+1] to print the first i+1
characters of the name. Finally, to get all the slices to print on the same line, we use the print
function’s optional argument end=''.
Exmple 5 Write a program that removes all capitalization and common punctuation from a string s.

s = s.lower()
for c in ',.;:-?!()\'"':
s = s.replace(c, '')

The way this works is for every character in the string of punctuation, we replace every occurrence of it
in s with the empty string, ''. One technical note here: We need the ' character in a string. As described
in the previous section, we get it into the string by using the escape character \'.

Example 6 Write a program that, given a string that contains a decimal number, prints out the
decimal part of the number. For instance, if given 3.14159, the program should print out .14159.
s = input('Enter your decimal number: ')
print(s[s.index('.'):])

The key here is the index method will find where the decimal point is. The decimal part of the
number starts there and runs to the end of the string, so we use a slice that starts at s.index('.').

Here is another, more mathematical way, to do this:


from math import floor
num = eval(input('Enter your decimal number: ')
print(num - floor(num))

One difference between the two methods is the first produces a string, whereas the second
produces a number.

57
Example 7 A simple and very old method of sending secret messages is the substitution cipher.
Basically, each letter of the alphabet gets replaced by another letter of the alphabet, say every a
gets replaced with an x, and every b gets replaced by a z, etc. Write a program to implement this.

alphabet = 'abcdefghijklmnopqrstuvwxyz'
key = ' xznlwebgjhqdyvtkfuompciasr'

secret_message = input('Enter your message: ')


secret_message = secret_message.lower()

for c in secret_message:
if c.isalpha():

print(key[alphabet.index(c)],end='')

else:

print(c, end='')

The string key is a random reordering of the alphabet.

The only tricky part of the program is the for loop. What it does is go through the message one
character at a time, and, for every letter it finds, it replaces it with the corresponding letter from the
key. This is accomplished by using the index method to find the position in the alphabet of the
current letter and replacing that letter with the letter from the key at that position. All non-letter
characters are copied as is. The program uses the isalpha method to tell whether the current
character is a letter or not.

58
6.11 Exercises

1. Write a program that asks the user to enter a string. The program should then print the
following:
(a) The total number of characters in the string
(b) The string repeated 10 times
(c) The first character of the string (remember that string indices start at 0)
(d) The first three characters of the string
(e) The last three characters of the string
(f) The string backwards
(g) The seventh character of the string if the string is long enough and a message otherwise
(h) The string with its first and last characters removed
(i) The string in all caps
(j) The string with every a replaced with an e
(k) The string with every letter replaced by a space

2. A simple way to estimate the number of words in a string is to count the number of spaces in
the string. Write a program that asks the user for a string and returns an estimate of how
many words are in the string.

3. People often forget closing parentheses when entering formulas. Write a program that asks
the user to enter a formula and prints out whether the formula has the same number of open-
ing and closing parentheses.

4. Write a program that asks the user to enter a word and prints out whether that word
contains any vowels.

59
Chapter 7

Lists
Say we need to get thirty test scores from a user and do something with them, like put them in order.
We could create thirty variables, score1, score2, . . . , score30, but that would be very tedious. To then
put the scores in order would be extremely difficult. The solution is to use lists.

A list is an ordered, mutable (changeable), and indexed collection of elements. It allows duplicates
and can store different data types.

Creating a List

my_list = [10, 20, 30, "Python", 40.5]


print(my_list)

Output:

[10, 20, 30, 'Python', 40.5]

List Properties:

 Ordered ✅

 Mutable (Changeable) ✅
 Allows Duplicates ✅
 Uses Indexing ✅

7.1 Basics

Creating lists Here is a simple list:


L = [1,2,3]

60
Use square brackets to indicate the start and end of the list, and separate the items by commas.

The empty list The empty list is []. It is the list equivalent of 0 or ''.

Long lists If you have a long list to enter, you can split it across several lines, like below:

nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]

7.2 List Operations

my_list = [10, 20, 30, "Python", 40.5]

1 Accessing Elements

print(my_list[0]) # First element


print(my_list[-1]) # Last element

Output:
10
40.5

2 Modifying Elements

my_list[1] = 50
print(my_list)

Output:
[10, 50, 30, 'Python', 40.5]

3 Adding Elements

my_list.append(60) # Add at end


print(my_list)

Output:
[10, 50, 30, 'Python', 40.5, 60]

61
4 Removing Elements
my_list.remove(30) # Remove specific value
print(my_list)

Output:
[10, 50, 'Python', 40.5, 60]
Input We can use eval(input()) to allow the user to enter a list. Here is an example:

L = eval(input('Enter a list: ')) print('The first


element is ', L[0])

Enter a list: [5,7,9]


The first element is 5

Printing lists You can use the print function to print the entire contents of a list.

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

[1, 2, 3]
Data types Lists can contain all kinds of things, even other lists. For example, the following is a
valid list:

[1, 2.718, 'abc', [5,6,7]]

7.3 Similarities to strings

There are a number of things which work the same way for lists as for strings.
• len — The number of items in L is given by len(L).
• in — The in operator tells you if a list contains something. Here are some examples:
if 2 in L:
print('Your list contains the number 2.')

if 0 not in L:

print('Your list has no zeroes.')

• Indexing and slicing — These work exactly as with strings. For example, L[0] is the first item
of the list L and L[:3] gives the first three items.
• index and count — These methods work the same as they do for strings.

62
• + and * — The + operator adds one list to the end of another. The * operator repeats a list.
Here are some examples:

Expression Result

[7,8]+[3,4,5] [7,8,3,4,5]
[7,8,7,8,7,8]
[7,8]*3
[0,0,0,0,0]
[0]*5

The last example is particularly useful for quickly creating a list of zeroes.

• Looping — The same two types of loops that work for strings also work for lists. Both of the
following examples print out the items of a list, one-by-one, on separate lines.

for i in range(len(L)): for item in L:


print(L[i]) print(item)

The left loop is useful for problems where you need to use the loop variable i to keep track of
where you are in the loop. If that is not needed, then use the right loop, as it is a little simpler.

7.4 Built-in functions

There are several built-in functions that operate on lists. Here are some useful ones:

Function Description
len returns the number of items in the list
sum returns the sum of the items in the list
min returns the minimum of the items in the list
max returns the maximum of the items in the list

For example, the following computes the average of the values in a list L:
average = sum(L)/len(L)

7.5 List methods

Here are some list methods:

63
Method Description
append(x) adds x to the end of the list
sort() sorts the list
count(x) returns the number of times x occurs in the list
index(x) returns the location of the first occurrence of x
reverse() reverses the list
remove(x) removes first occurrence of x from the list
pop(p) removes the item at index p and returns its value
insert(p,x) inserts x at index p of the list

Important note There is a big difference between list methods and string methods: String meth-
ods do not change the original string, but list methods do change the original list. To sort a list L,
just use L.sort() and not L=L.sort(). In fact, the latter will not work at all.

wrong Right
s.replace('X','x') s = s.replace('X','x')
L = L.sort() L.sort()

Other list methods There are a few others list methods. Type help(list) in the Python shell to
see some documentation for them.

7.6 Miscellaneous

Making copies of lists Making copies of lists is a little tricky due to the way Python handles lists.
Say we have a list L and we want to make a copy of the list and call it M. The expression M=L will
not work for reasons covered in Section 19.1. For now, do the following in place of M=L:

M = L[:]

Changing lists Changing a specific item in a list is easier than with strings. To change the value
in location 2 of L to 100, we simply say L[2]=100. If we want to insert the value 100 into location 2
without overwriting what is currently there, we can use the insert method. To delete an entry from
a list, we can use the del operator. Some examples are shown below. Assume L=[6,7,8] for each
operation.

64
Operation New L Description
L[1]= 9 [6,9, 8] replace item at index 1 with 9
L.insert(1,9) [6,9, 7, 8] insert a 9 at index 1 without replacing
del L[1] [6,8] delete second item
del L[:2] [8] delete first two items

7.7 Examples

Example 1 Write a program that generates a list L of 50 random numbers between 1 and 100.
from random import randint
L=[]
for i in range(50):
L.append(randint(1,100))
We use the append method to build up the list one item at a time starting with the empty list, [].

An alternative to append is to use the following:

L = L + [randint(1,100)]

Example 2 Replace each element in a list L with its square.

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

Example 3 Count how many items in a list L are greater than 50. count = 0
for item in L:
if item>50:
count=count+1

Example 4 Given a list L that contains numbers between 1 and 100, create a new list whose first
element is how many ones are in L, whose second element is how many twos are in L, etc.

frequencies = []
for i in range(1,101):
frequences.append(L.count(i))

The key is the list method count that tells how many times a something occurs in a list.

65
Example 5 Write a program that prints out the two largest and two smallest elements of a list
called scores.

scores.sort()
print('Two smallest: ', scores[0], scores[1])
print('Two largest: ', scores[-1], scores[-2])

Once we sort the list, the smallest values are at the beginning and the largest are at the end.

Example 6 Here is a program to play a simple quiz game.

num_right = 0
# Question 1

print('What is the capital of France?', end=' ')

guess = input()
if guess.lower()=='paris':

print('Correct! ')
num_right+=1

else:

print('Wrong. The answer is Paris.')


print('You have', num_right, 'out of 1 right')

#Question 2

print('Which state has only one neighbor?', end=' ')

guess = input()
if guess.lower()=='maine':

print('Correct! ')
num_right+=1

else:
print('Wrong. The answer is Maine.')
print('You have', num_right, 'out of 2 right,')

66
The code works, but it is very tedious. If we want to add more questions, we have to copy and
paste one of these blocks of code and then change a bunch of things. If we decide to change
one of the questions or the order of the questions, then there is a fair amount of rewriting
involved. If we decide to change the design of the game, like not telling the user the correct
answer, then every single block of code has to be rewritten. Tedious code like this can often be
greatly simplified with lists and loops:

questions = ['What is the capital of France?',


'Which state has only one neighbor? ']
answers = ['Paris','Maine']

num_right = 0
for i in range(len(questions)):
guess = input(questions[i])

if guess.lower()==answers[i].lower():

print('Correct')
num_right=num_right+1

else:
print('Wrong. The answer is', answers[i])

print('You have', num_right, 'out of', i+1, 'right.')

If you look carefully at this code, you will see that the code in the loop is the nearly the same
as the code of one of the blocks in the previous program, except that in the statements where
we print the questions and answers, we use questions[i] and answers[i] in place of the actual
text of the questions themselves.

This illustrates the general technique: If you find yourself repeating the same code over and
over, try lists and a for loop. The few parts of your repetitious code that are varying are where
the list code will go.

The benefits of this are that to change a question, add a question, or change the order, only
the questions and answers lists need to be changed. Also, if you want to make a change to the
program, like not telling the user the correct answer, then all you have to do is modify a single line,
instead of twenty copies of that line spread throughout the program.

67
7.8 Exercises

1. Write a program that asks the user to enter a list of integers. Do the following:

(a) Print the total number of items in the list.


(b) Print the last item in the list.
(c) Print the list in reverse order.
(d) Print Yes if the list contains a 5 and No otherwise.
(e) Print the number of fives in the list.

(f) Remove the first and last items from the list, sort the remaining items, and print the
result.
(g) Print how many integers in the list are less than 5.

2. Write a program that generates a list of 20 random numbers between 1 and 100.

(a) Print the list.


(b) Print the average of the elements in the list.
(c) Print the largest and smallest values in the list.
(d) Print the second largest and second smallest entries in the list
(e) Print how many even numbers are in the list.

3. Start with the list [8,9,10]. Do the following:

(a) Set the second entry (index 1) to 17


(b) Add 4, 5, and 6 to the end of the list
(c) Remove the first entry from the list
(d) Sort the list
(e) Double the list
(f) Insert 25 at index 3

The final list should equal [4,5,6,25,10,17,4,5,6,10,17]

4. Ask the user to enter a list containing numbers between 1 and 12. Then replace all of
the entries in the list that are greater than 10 with 10.
5. Ask the user to enter a list of strings. Create a new list that consists of those strings with
their first characters removed.
6. Create the following lists using a for loop.

(a) A list consisting of the integers 0 through 49


(b) A list containing the squares of the integers 1 through 50.

68
Chapter 8

More with Lists

8.1 Lists and the random module

There are some nice functions in the random module that work on lists.

Function Description
choice(L) picks a random item from L
sample(L,n) picks a group of n random items from L
shuffle(L) Shuffles the items of L

Note The shuffle function modifies the original list, so if you don’t want your list changed, you’ll
need to make a copy of it.
Example 1 We can use choice to pick a name from a list of names.

from random import choice


names = ['Joe', 'Bob', 'Sue', 'Sally']
current_player = choice(names)

Example 2 The sample function is similar to choice. Whereas choice picks one item from a list,
sample can be used to pick several.

from random import sample


names = ['Joe', 'Bob', 'Sue', 'Sally']
team = sample(names, 2)

69
Example 3 The choice function also works with strings, picking a random character from a string.
Here is an example that uses choice to fill the screen with a bunch of random characters.

from random import choice

s='abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()'
for i in range(10000):
print(choice(s), end='')

Example 4 Here is a nice use of shuffle to pick a random ordering of players in a game.

from random import shuffle


players = ['Joe', 'Bob', 'Sue', 'Sally']
shuffle(players)
for p in players:
print(p, ' it is your turn.')
# code to play the game goes here...

Example 5 Here we use shuffle divide a group of people into teams of two. Assume we are given
a list called names.

shuffle(names)
teams = []

for i in range(0,len(names),2):
teams.append([names[i], names[i+1]])

Each item in teams is a list of two names. The way the code works is we shuffle the names so they
are in a random order. The first two names in the shuffled list become the first team, the next two
names become the second team, etc. Notice that we use the optional third argument to range to
skip ahead by two through the list of names.

8.2 Split

The split method returns a list of the words of a string. The method assumes that words are sep-arated
by whitespace, which can be either spaces, tabs or newline characters. Here is an example:

s = 'Hi! This is a test.'


print(s.split())

70
['Hi!', 'This', 'is', 'a', 'test.']

As we can see, since split breaks up the string at spaces, the punctuation will be part of the words.
There is a module called string that contains, among other things, a string variable called
punctuation that contains common punctuation. We can remove the punctuation from a string s with the
following code:
from string import punctuation
for c in punctuation:
s = s.replace(c, '')

Example Here is a program that counts how many times a certain word occurs in a string.

from string import punctuation


s = input('Enter a string: ')
for c in punctuation:
s = s.replace(c, '')
s = s.lower()
L = s.split()

word = input('Enter a word: ')


print(word, 'appears', L.count(word), 'times.')

Optional argument The split method takes an optional argument that allows it to break the string
at places other than spaces. Here is an example:

s = '1-800-271-8281'
print(s.split('-'))

['1', '800', '271', '8281']

8.3 Join

The join method is in some sense the opposite of split. It is a string method that takes a list of
strings and joins them together into a single string. Here are some examples, using the list
L = ['A','B','C']

71
Operation Result
' '.join(L) ABC
''.join(L) ABC
', '.join(L) A,B,C
A
'***'.join(L) ***B***C

Example Write a program that creates an anagram of a given word. An anagram of a word uses the
same letters as the word but in a different order. For instance, two anagrams of the word there are
three and ether. Don’t worry about whether the anagram is a real word or not.
This sounds like something we could use shuffle for, but shuffle only works with lists. What we need
to do is convert our string into a list, use shuffle on it, and then convert the list back into a string.
To turn a string s into a list, we can use list(s). (See Section 10.1.) To turn the list back into a string,
we will use join.

from random import shuffle


word = input('Enter a word: ')

letter_list = list(word)
shuffle(letter_list)
anagram = ''.join(letter_list)

print(anagram)

8.4 List Comprehensions

List comprehensions are a powerful way to create lists. Here is a simple example:

L = [i for i in range(5)]

This creates the list [0,1,2,3,4]. Notice that the syntax of a list comprehension is somewhat rem-
iniscent of set notation in mathematics. Here are a couple more examples of list comprehensions.
For these examples, assume the following:

string = 'Hello'

L = [1,14,5,9,12]

M = ['one', 'two', 'three', 'four', 'five', 'six']

72
List comprehension Resulting list
[0 for i in range(10)] [0,0,0,0,0,0,0,0,0,0]

[i**2 for i in range(1,8)] [1,4,9,16,25,36,49]

[i*10 for i in L] [10,140,50,90,120]

[c*2 for c in string] ['HH','ee','ll','ll','oo']


[m[0] for m in M] ['o','t','t','f','f','s']
[i for i in L if i<10] [1,5,9]
[m[0] for m in M if len(m)==3] ['o','t','s']

As we see in the last two examples, we can add an if to a list comprehension. Compare the last
example with the long way of building the list:

L=[]

for m in M:

if len(m)==3:
L.append(m)

Multiple fors You can use more than one for in a list comprehension:
L = [[i,j] for i in range(2) for j in range(2)]

[[0, 0], [0, 1], [1, 0], [1, 1]]

This is the equivalent of the following code:

L=[]

for i in range(2):

for j in range(2):
L.append([i,j])

Here is another example:

[[i,j] for i in range(4) for j in range(i)]

[[1, 0], [2, 0], [2, 1], [3, 0], [3, 1], [3, 2]]

73
8.5 Using list comprehensions

To further demonstrate the power of list comprehensions, we will do the first four examples of
Section 7.6 in one line apiece using list comprehensions.

Example 1 Write a program that generates a list L of 50 random numbers between 1 and 100.

L = [randint(1,100) for i in range(50)]

Example 2 Replace each element in a list L with its square.

L = [i**2 for i in L]

Example 3 Count how many items in a list L are greater than 50.

len([i for i in L if i>50])

Example 4 Given a list L that contains numbers between 1 and 100, create a new list whose first
element is how many ones are in L, whose second element is how many twos are in L, etc.

frequencies = [L.count(i) for i in range(1,101)]

Another example The join method can often be used with list comprehensions to quickly build up
a string. Here we create a string that contains a random assortment of 1000 letters.

from random import choice


alphabet = 'abcdefghijklmnopqrstuvwxyz'
s = ''.join([choice(alphabet) for i in range(1000)])

One more example Suppose we have a list whose elements are lists of size 2, like below:
L = [[1,2], [3,4], [5,6]]

If we want to flip the order of the entries in the lists, we can use the following list comprehension:
M = [[y,x] for x,y in L]

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

74
Note You can certainly get away without using list comprehensions, but once you get the hang of
them, you’ll find they are both quicker to write and easier to read than the longer ways of creating
lists.

8.6 Two-Dimensional Lists

There are a number of common things that can be represented by two-dimensional lists, like a Tic-
tac-toe board or the pixels on a computer screen. In Python, one way to create a two-dimensional
list is to create a list whose items are themselves lists. Here is an example:

L = [[1,2,3],

[4,5,6],

[7,8,9]]

Indexing We use two indices to access individual items. To get the entry in row r, column c, use
the following:

L[r][c]

Printing a two-dimensional list To print a two-dimensional list, you can use nested for loops.

The following example prints a 10 5 list:

for r in range(10):
for c in range(5):

print(L[r][c], end=" ")

print()

Another option is to use the pprint function of the pprint module. This function is used to “pretty-
print” its argument. Here is an example to print a list L:

from pprint import pprint

pprint(L)

The pprint function can be used to nicely print ordinary lists and other objects in Python.

75
Working with two-dimensional lists Nested for loops, like the ones used in printing a two-
dimensional list, can also be used to process the items in a two-dimensional list. Here is an example
that counts how many entries in a 10 5 list are even.
count = 0

for r in range(10):

for c in range(5):

if L[r][c]%2==0:
count = count + 1

This can also be done with a list comprehension:

count = sum([1 for r in range(10) for c in range(5) if L[r][c]%2==0])

Creating large two-dimensional lists To create a larger list, you can use a list comprehension
like below:

L = [[0]*50 for i in range(100)]

This creates a list of zeroes with 100 rows and 50 columns.

Picking out rows and columns To get the row r of L (starting at row r = 0), use the following:
L[r]

To get the column c of L (starting at column c = 0), use a list comprehension:

[L[i][c] for i in range(len(L))]

Flattening a list To flatten a two-dimensional list, that is, return a one-dimensional list of its
elements, use the following:

[j for row in L for j in row]

For instance, suppose we have the following list:

L = [[1,2,3],

[4,5,6],

[7,8,9]]

76
The flattened list will be:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

Higher dimensions Creating and using 3-dimensional and higher lists is similar. Here we create
a 5 5 5 list:

L = [[[0]*5 for i in range(5)] for j in range(5)]

It is a list whose items are lists of lists. The first entry in the list is

L[0][0][0]

77
8.7 Exercises

1. Write a program that asks the user to enter some text and then counts how many articles are
in the text. Articles are the words 'a', 'an', and 'the'.

2. Write a program that allows the user to enter five numbers (read as strings). Create a string
that consists of the user’s numbers separated by plus signs. For instance, if the user enters 2,
5, 11, 33, and 55, then the string should be '2+5+11+33+55'.

(a) Ask the user to enter a sentence and print out the third word of the sentence.
(b) Ask the user to enter a sentence and print out every third word of the sentence.

3. Write a program that asks the user to enter a sentence and then randomly rearranges the words of
the sentence. Don’t worry about getting punctuation or capitalization correct.

(a) Do the above problem, but now make sure that the sentence starts with a capital, that
the original first word is not capitalized if it comes in the middle of the sentence, and
that the period is in the right place.

4. Write a simple quote-of-the-day program. The program should contain a list of quotes, and
when the user runs the program, a randomly selected quote should be printed.

5. Write a simple lottery drawing program. The lottery drawing should consist of six different
numbers between 1 and 48.

6. Write a program that estimates the average number of drawings it takes before the user’s
numbers are picked in a lottery that consists of correctly picking six different numbers that are
between 1 and 10. To do this, run a loop 1000 times that randomly generates a set of user
numbers and simulates drawings until the user’s numbers are drawn. Find the average number
of drawings needed over the 1000 times the loop runs.

7. Write a program that simulates drawing names out of a hat. In this drawing, the number of hat
entries each person gets may vary. Allow the user to input a list of names and a list of how
many entries each person has in the drawing, and print out who wins the drawing.

8. Write a simple quiz game that has a list of ten questions and a list of answers to those ques-
tions. The game should give the player four randomly selected questions to answer. It should
ask the questions one-by-one, and tell the player whether they got the question right or wrong.
At the end it should print out how many out of four they got right.

9. Use a list comprehension to produce a list that consists of all palindromic numbers between
100 and 1000.

78
Chapter 9

While loops
We have already learned about for loops, which allow us to repeat things a specified number of
times. Sometimes, though, we need to repeat something, but we don’t know ahead of time exactly
how many times it has to be repeated. For instance, a game of Tic-tac-toe keeps going until
someone wins or there are no more moves to be made, so the number of turns will vary from game
to game. This is a situation that would call for a while loop.

9.1 Examples

Example 1 Let’s go back to the first program we wrote back in Section 1.3, the temperature con-
verter. One annoying thing about it is that the user has to restart the program for every new tem-
perature. A while loop will allow the user to repeatedly enter temperatures. A simple way for the
user to indicate that they are done is to have them enter a nonsense temperature like 1000 (which
is below absolute 0). This is done below:

temp = 0
while temp!=-1000:
temp = eval(input('Enter a temperature (-1000 to quit): '))
print('In Fahrenheit that is ', 9/5*temp+32)

Look at the while statement first. It says that we will keep looping, that is, keep getting and
converting temperatures, as long as the temperature entered is not 1000. As soon as 1000 is
entered, the while loop stops. Tracing through, the program first compares temp to 1000. If temp is
not 1000, then the program asks for a temperature and converts it. The program then loops back
up and again compares temp to 1000. If temp is not 1000, the program will ask for another
temperature, convert it, and then loop back up again and do another comparison. It continues this
process until the user enters 1000.

We need the line temp=0 at the start, as without it, we would get a name error. The program would
get to the while statement, try to see if temp is not equal to 1000 and run into a problem because
temp doesn’t yet exist. To take care of this, we just declare temp equal to 0. There is nothing special

79
about the value 0 here. We could set it to anything except 1000. (Setting it to 1000 would cause
the condition on the while loop to be false right from the start and the loop would never run.)

Note that is natural to think of the while loop as continuing looping until the user enters -1000.
However, when we construct the condition, instead of thinking about when to stop looping, we
instead need to think in terms of what has to be true in order to keep going.

A while loop is a lot like an if statement. The difference is that the indented statements in an if block
will only be executed once, whereas the indented statements in a while loop are repeatedly
executed.

Example 2 One problem with the previous program is that when the user enters in 1000 to quit, the
program still converts the value 1000 and doesn’t give any message to indicate that the program
has ended. A nicer way to do the program is shown below.

temp = 0
while temp!=-1000:
temp = eval(input('Enter a temperature (-1000 to quit): '))

if temp!=-1000:

print('In Fahrenheit that is', 9/5*temp+32)

else:

print('Bye! ')

Example 3 When first met if statements in Section 4.1, we wrote a program that played a simple
random number guessing game. The problem with that program is that the player only gets one
guess. We can, in a sense, replace the if statement in that program with a while loop to create a
program that allows the user to keep guessing until they get it right.

from random import randint


secret_num = randint(1,10)
guess = 0
while guess != secret_num:
guess = eval(input('Guess the secret number: '))
print('You finally got it! ')

80
The condition guess!=secret_num says that as long as the current guess is not correct, we will keep
looping. In this case, the loop consists of one statement, the input statement, and so the pro-gram
will keep asking the user for a guess until their guess is correct. We require the line guess=0 prior
to the while loop so that the first time the program reaches the loop, there is something in guess for
the program to use in the comparison. The exact value of guess doesn’t really matter at this point. We
just want something that is guaranteed to be different than secret_num. When the user finally guesses
the right answer, the loop ends and program control moves to the print statement after the loop, which
prints a congratulatory message to the player.

Example 4 We can use a while loop to mimic a for loop, as shown below. Both loops have the
exact same effect.

for i in range(10): i=0


print(i) while i<10:
print(i)

i=i+1

Remember that the for loop starts with the loop variable i equal to 0 and ends with it equal to 9. To
use a while loop to mimic the for loop, we have to manually create our own loop variable i. We start
by setting it to 0. In the while loop we have the same print statement as in the for loop, but we have
another statement, i=i+1, to manually increase the loop variable, something that the for loop does
automatically.

Example 5 Below is our old friend that converts from Fahrenheit to Celsius.

temp = eval(input('Enter a temperature in Celsius: '))


print('In Fahrenheit, that is', 9/5*temp+32)

A program that gets input from a user may want to check to see that the user has entered valid
data. The smallest possible temperature is absolute zero, -273.15 C. The program below takes
absolute zero into account:

temp = eval(input('Enter a temperature in Celsius: '))


if temp<-273.15:

print('That temperature is not possible.'))


else:
print('In Fahrenheit, that is ', 9/5*temp+32)

81
One way to improve this is to allow the user to keep reentering the temperature until they enter a
valid one. You may have experienced something similar using an online form to enter a phone
number or a credit card number. If you enter an invalid number, you are told to reenter it. In the
code below, the while loop acts very similarly to the if statement in the previous example.

temp = eval(input('Enter a temperature in Celsius: '))


while temp<-273.15:
temp = eval(input(' Impossible.Enter a valid temperature: ' ))
print('In Fahrenheit, that is', 9/5*temp+32)

Note that we do not need an else statement here, like we had with the if statement.. The condition
on the while loop guarantees that we will only get to the print statement once the user enters a
valid temperature. Until that point, the program will be stuck in the loop, continually asking the user
for a new temperature.

Example 6 As mentioned before, it is a valuable skill is to be able to read code. One way to do so
is to pretend to be the Python interpreter and go through the code line by line. Let’s try it with the
code below.
i=0
while i<50:
print(i)
i=i+2

print('Bye! ')

The variable i gets set to 0 to start. Next, the program tests the condition on the while loop. Because
i is 0, which is less than 50, the code indented under the while statement will get executed. This code
prints the current value of i and then executes the statement i=i+2 which adds 2 to i.

The variable i is now 2 and the program loops back to the while statement. It checks to see if i is
less than 50, and since i is 2, which is less than 50, the indented code should be executed again.
So we print i again, add 2 to it, and then loop back to check the while loop condition again. We
keep doing this until finally i gets to 50.

At this point, the while condition will finally not be true anymore and the program jumps down to
the first statement after the while, which prints Bye! . The end result of the program is the numbers
0, 2, 4, . . . , 48 followed by the message, Bye! .

82
9.2 Infinite loops

When working with while loops, sooner or later you will accidentally send Python into a never-
ending loop. Here is an example:

i=0
while i<10:
print(i)

In this program, the value of i never changes and so the condition i<10 is always true. Python will
continuously print zeroes. To stop a program caught in a never-ending loop, use Restart Shell under
the Shell menu. You can use this to stop a Python program before it is finished executing.

Sometimes a never-ending loop is what you want. A simple way to create one is shown below:

while True:
# statements to be repeated go here

9.3 The break statement

The break statement can be used to break out of a for or while loop before the loop is finished.
Example 1 Here is a program that allows the user to enter up to 10 numbers. The user can stop
early by entering a negative number.

for i in range(10):
num = eval(input('Enter number: '))

if num<0:

break
This could also be accomplished with a while loop.

i=0
num=1
while i<10 and num>0:
num = eval(input('Enter a number: '))

83
Either method is ok. In many cases the break statement can help make your code easier to under-
stand and less clumsy.

Example 2 Earlier in the chapter, we used a while loop to allow the user to repeatedly enter
temperatures to be converted. Here is, more or less, the original version on the left compared with
a different approach using the break statement.

temp = 0 while True:


while temp!=-1000: temp = eval(input(': '))
temp = eval(input(': ')) if temp==-1000:
if temp!=-1000: print('Bye')

print(9/5*temp+32) break
else: print(9/5*temp+32)

print('Bye! ')

9.4 The else statement

There is an optional else that you can use with break statements. The code indented under the
else gets executed only if the loop completes without a break happening.

Example 1 This is a simple example based off of Example 1 of the previous section.

for i in range(10):
num = eval(input('Enter number: '))

if num<0:

print('Stopped early')

break

else:

print('User entered all ten values')

84
The program allows the user to enter up to 10 numbers. If they enter a negative, then the program
prints Stopped early and asks for no more numbers. If the user enters no negatives, then the
program prints User entered all ten values.

Example 2 Here are two ways to check if an integer num is prime. A prime number is a number
whose only divisors are 1 and itself. The approach on the left uses a while loop, while the approach
on the right uses a for/break loop:

i=2 for i in range(2, num):

while i<num and num%i!=0: if num%i==0:


i=i+1 print('Not prime')
if i==num: break
print('Prime') else:
else: print('Prime')
print('Not prime')

The idea behind both approaches is to scan through all the integers between 2 and num-1, and if
any of them is a divisor, then we know num is not prime. To see if a value i is a divisor of num, we
just have to check to see if num%i is 0.

The idea of the while loop version is we continue looping as long as we haven’t found a divisor. If
we get all the way through the loop without finding a divisor, then i will equal num, and in that case
the number must be prime.

The idea of the for/break version is we loop through all the potential divisors, and as soon as we
find one, we know the number is not prime and we print Not prime and stop looping. If we get all
the way through the loop without breaking, then we have not found a divisor. In that case the else
block will execute and print that the number is prime.

9.5 The guessing game, more nicely done

It is worth going through step-by-step how to develop a program. We will modify the guessing game
program from Section 9.1 to do the following:

• The player only gets five turns.

• The program tells the player after each guess if the number is higher or lower.

85
• The program prints appropriate messages for when the player wins and loses.

Below is what we want the program to look like:

Enter your guess (1-100): 50


LOWER. 4 guesses left.
Enter your guess (1-100): 25
LOWER. 3 guesses left.

Enter your guess (1-100): 12


LOWER. 2 guesses left.

Enter your guess (1-100): 6


HIGHER. 1 guesses left.

Enter your guess (1-100): 9


LOWER. 0 guesses left.

You lose. The correct number is 8

First, think about what we will need in the program:

• We need random numbers, so there will be an import statement at the beginning of the pro-
gram and a randint function somewhere else.

• To allow the user to guess until they either guess right or run out of turns, one solution is to
use while loop with a condition that takes care of both of these possibilities.

• There will be an input statement to get the user’s guess. As this is something that is
repeatedly done, it will go inside the loop.

• There will be an if statement to take care of the higher/lower thing. As this comparison will be
done repeatedly and will depend on the user’s guesses, it will go in the loop after the input
statement.

86
• There will be a counting variable to keep track of how many turns the player has taken. Each
time the user makes a guess, the count will go up by one, so this statement will also go inside
the loop.

Next start coding those things that are easy to do:

from random import randint

secret_num = randint(1,100)

num_guesses = 0

while #some condition goes here#

guess = eval(input('Enter your guess (1-100): '))


num_guesses = num_guesses + 1

# higher/lower if statement goes here

For the while loop, we want to continue looping as long as the user has not guessed the secret
number and as long as the player has not used up all of their guesses:

while guess != secret_num and num_guesses <= 4:

The higher
if guess < secret_num:

print('HIGHER.', 5-num_guesses, 'guesses left.\n')

elif guess > secret_num:

print('LOWER.', 5-num_guesses, 'guesses left.\n')

else:

print('You got it! ')

Finally, it would be nice to have a message for the player if they run out of turns. When they run
out of turns, the while loop will stop looping and program control will shift to whatever comes outside
of the loop. At this point we can print the message, but we only want to do so if the reason that the
loop stopped is because of the player running out of turns and not because they guessed correctly.
We can accomplish this with an if statement after the loop. This is shown below along with the rest
of the completed program.

87
from random import randint

secret_num = randint(1,100)

num_guesses = 0
guess = 0

while guess != secret_num and num_guesses <= 4:

guess = eval(input('Enter your guess (1-100): ')) num_guesses =


num_guesses + 1 if guess < secret_num:

print('HIGHER.', 5-num_guesses, 'guesses left.\n')

elif guess > secret_num:

print('LOWER.', 5-num_guesses, 'guesses left.\n')

else:

print('You got it! ')

if num_guesses==5 and guess != secret_num:

print('You lose. The correct number is', secret_num)

Here is an alternative solution using a for/break loop:

from random import randint

secret_num = randint(1,100)

for num_guesses in range(5):


guess = eval(input('Enter your guess (1-100): '))

if guess < secret_num:

print('HIGHER.', 5-num_guesses, 'guesses left.\n')

elif guess > secret_num:

print('LOWER.', 5-num_guesses, 'guesses left.\n')

else:

88
print('You got it! ')

break

else:
print('You lose. The correct number is', secret_num)

89
9.6 Exercises

1) The code below prints the numbers from 1 to 50. Rewrite the code using a while loop to
accomplish the same thing.

(a) for i in range(1,51):

(i) print(i)

2) Write a program that uses a while loop (not a for loop) to read through a string and print the
characters of the string one-by-one on separate lines.

a) Modify the program above to print out every second character of the string.

3) Write a program that asks the user for a string and a letter. Using a while loop, the program
should print the index of the first occurrence of that letter and a message if the string does not
contain the letter.

a) Write the above program using a for/break loop instead of a while loop.

4) The GCD (greatest common divisor) of two numbers is the largest number that both are di-
visible by. For instance, gcd(18, 42) is 6 because the largest number that both 18 and 42 are
divisible by is 6. Write a program that asks the user for two numbers and computes their gcd.
Shown below is a way to compute the GCD, called Euclid’s Algorithm.

a) First compute the remainder of dividing the larger number by the smaller number

b) Next, replace the larger number with the smaller number and the smaller number with the
remainder.

c) Repeat this process until the smaller number is 0. The GCD is the last value of the larger
number.

90
Chapter 10

Miscellaneous Topics II

In this chapter we will look at variety of useful things to know.

10.1 str, int, float, and list

The str, int, float, and list functions are used to convert one data type into another.

str Quite often we will want to convert a number to a string to take advantage of string methods to
break the number apart. The built-in function str is used to convert things into strings. Here are some
examples:

Statement Result

str(37) '37'

str(3.14) '3.14'

str([1,2,3]) '[1,2,3]'

int and float The int function converts something into an integer. The float function con-verts
something into a floating point number. Here are some examples.

Statement Result

int('37') 37

float('3.14') 3.14

91
int(3.14) 3

To convert a float to an integer, the int function drops everything after the decimal point.

list The list function takes something that can be converted into a list and makes into a list.

Here are two uses of it.

list(range(5)) [0,1,2,3,4]

list('abc') ['a','b','c']

10.2 Examples

Example 1 Here is an example that finds all the palindromic numbers between 1 and 10000. A
palindromic number is one that is the same backwards as forwards, like 1221 or 64546.

for i in range(1,10001):
s = str(i)

if s==s[::-1]:

print(s)

We use the str function here to turn the integer i into a string so we can use slices to reverse it.

Example 2 Here is an example that tells a person born on January 1, 1991 how old they are in
2010.

birthday = 'January 1, 1991'


year = int(birthday[-4:])
print('You are', 2010-year, ' years old.')

The year is in the last four characters of birthday. We use int to convert those characters into
an integer so we can do math with the year.

Example 3 Write a program that takes a number num and adds its digits. For instance, given
the number 47, the program should return 11 (which is 4 + 7). Let us start with a 2-digit example.

digit = str(num)
92
answer = int(digit[0]) + int(digit[1])

The idea here is that we convert num to a string so that we can use indexing to get the two
digits separately. We then convert each back to an integer using the int function. Here is a
version that handles numbers with arbitrarily many digits:

digit = str(num)
answer = 0
for i in range(len(digit)):
answer = answer + int(digit[i])
We can do the above program in a single line using a list comprehension.

answer = sum([int(c) for c in str(num)])

Example 4 To break a decimal number, num, up into its integer and fractional parts, we can do
the following:

ipart = int(num)

dpart = num - int(num)

For example, if num is 12.345, then ipart is 12 and dpart is 12.345 12 = .345.

10.3 Booleans

Boolean variables in Python are variables that can take on two values, True and False. Here
are two examples of setting Boolean variables:

game_over = True

highlight_text = False

Booleans can help make your programs more readable. They are often used as flag variables
or to indicate options. Booleans are often used as conditions in if statements and while loops:

if game_over:

print('Bye! ')
Note the following equivalences:

if game_over: , if game_over==True:

while not game_over: , while game_over==False:

93
note Conditional expressions evaluate to booleans and you can even assign them to variables.

For instance, the following assigns True to x because 6==6 evaluates to True.

x = (6==6)

We have seen booleans before. The isalpha string method returns True if every character of the
string is a letter and False otherwise.

10.4 Shortcuts

• Shortcut operators Operations like count=count+1 occur so often that there is a


shorthand for them. Here are a couple of examples:

Statement Shorthand

count=count+1 count+=1

total=total-5 total-=5

prod=prod*2 prod*=2

There are also shortcut operators /=, %=, //=, and **=.

• An assignment shortcut

Look at the code below.

a=0

b=0

c=0

A nice shortcut is:

a=b=c=0

• Another assignment shortcut

94
Say we have a list L with three elements in it, and we want to assign those elements to
variable names. We could do the following:

x = L[0]

y = L[1]

z = L[2]

Instead, we can do this:

x,y,z = L

Similarly, we can assign three variables at a time like below:

x,y,z = 1,2,3

And, as we have seen once before, we can swap variables using this kind of assignment.

x,y,z = y,z,x

• Shortcuts with conditions

Here are some handy shortcuts:

Statement Shortcut

if a==0 and b==0 and c==0: if a==b==c==0:

if 1<a and a<b and b<5: if 1<a<b<5:

10.5 Continuation

Sometimes you’ll write a long line of code that would be more readable if it were split across
two lines. To do this, use a backslash \ character at the end of the line to indicate that the
statement continues onto the next line. Here is an example:

if 'a' in string or 'b' in string or 'c' in string \ or 'd' in string or 'e' in


string:

Make sure there are no extra spaces after the backslash or you will get an error message.

If you are entering a list, dictionary, or the arguments of a function, the backslash can be left out:

95
L = ['Joe', 'Bob', 'Sue', 'Jimmy', 'Todd', 'Frank', 'Mike', 'John', ' Amy',
'Edgar', 'Sam']

10.6 pass
The pass statement does nothing. Believe it or not, such a thing does have a few uses that
we will see later.

10.7 String formatting

Suppose we are writing a program that calculates a 25% tip on a bill of $23.60. When we
multiply, we get 5.9, but we would like to display the result as $5.90, not $5.9. Here is how to do
it:

a = 23.60 * .25
print('The tip is {:.2f}'.format(a))

This uses the format method of strings. Here is another example:

bill = 23.60

tip = 23.60*.25

print('Tip: ${:.2f}, Total: ${:.2f}'.format(tip, bill+tip))

The way the format method works is we put a pair of curly braces {} anywhere that we want a
formatted value. The arguments to the format function are the values we want formatted, with
the first argument matching up with the first set of braces, the second argument with the second
set of braces, etc. Inside each set of curly braces you can specify a formatting code to determine
how the corresponding argument will be formatted.
Formatting integers To format integers, the formatting code is {:d}. Putting a number in front
of the d allows us to right-justify integers. Here is an example:

print('{:3d}'.format(2))

print('{:3d}'.format(25))

print('{:3d}'.format(138))

2
25
138

96
The number 3 in these examples says that the value is allotted three spots. The value is placed
as far right in those three spots as possible and the rest of the slots will be filled by spaces.
This sort of thing is useful for nicely formatting tables.

To center integers instead of right-justifying, use the ^ character, and to left-justify, use the <
char-acter.

print('{:^5d}'.format(2))

print('{:^5d}'.format(222))

print('{:^5d}'.format(13834))

2
122
13834

Each of these allots five spaces for the integer and centers it within those five spaces.

Putting a comma into the formatting code will format the integer with commas. The example
below prints 1,000,000:

print('{:,d}'.format(1000000))

Formatting floats To format a floating point number, the formatting code is {:f}. To only display
the number to two decimal places, use {:.2f}. The 2 can be changed to change the number of
decimal places.

You can right-justify floats. For example, {:8.2f} will allot eight spots for its value—one of those
is for the decimal point and two are for the part of the value after the decimal point. If the value
is 6.42, then only four spots are needed and the remaining spots are filled by spaces, causing
the value to be right-justified.

The ^ and < characters center and left-justify floats.


Formatting strings To format strings, the formatting code is {:s}. Here is an example that
centers some text:

print('{:^10s}'.format('Hi'))

print('{:^10s}'.format('there! '))

Hi
there!

97
To right-justify a string, use the > character:

print('{:>6s}'.format('Hi'))

print('{:>6s}'.format('There'))

Hi
there!
There is a whole lot more that can be done with formatting. See the Python documentation [1].

10.8 Nested loops

You can put loops inside of other loops. A loop inside of another loop is said to be nested, and
you can, more or less, nest loops as deeply as you want.

Example 1 Print a 10X10 multiplication table.

for i in range(1,11):
for j in range(1,11):
print('{:3d}'.format(i*j), end=' ')

print()

A multiplication table is a two-dimensional object. To work with it, we use two for loops, one for
the horizontal direction and one for the vertical direction. The print statement right justifies the
products to make them look nice. The end='' allows us to print several things on each row. When
we are done printing a row, we use print() to advance things to the next line.

Example 2 A common math problem is to find the solutions to a system of equations.


Sometimes you want to find only the integer solutions, and this can be a little tricky
mathematically. However, we can write a program that does a brute force search for solutions.
Here we find all the integer solutions (x, y) to the system 2x + 3 y = 4, x y = 7, where x and y are
both between -50 and 50.

for x in range(-50,51):
for y in range(-50,51):
if 2* x+3* y==4 and x-y==7:

print(x,y)

98
Example 3 A Pythagorean triple is a triple of numbers (x, y, z) such that x2 + y2 = z2. For instance
(3, 4, 5) is a Pythagorean triple because 32 + 42 = 52. Pythagorean triples correspond to triangles
whose sides are all whole numbers (like a 3-4-5-triangle). Here is a program that finds all the
Pythagorean triples (x, y, z) where x, y, and z are positive and less than 100.

for x in range(1,100):
for y in range(1,100):

for z in range(1,100):

if x**2+y**2==z**2:

print(x,y,z)

If you run the program, you’ll notice that there are redundant solutions. For instance, (3, 4, 5)
and (4, 3, 5) are both listed. To get rid of these redundancies, change the second loop so that it runs
from x to 100. This way, when x is 4, for instance, the first value for y that will be searched is 4,
rather than 1, and so we won’t get the redundant (4, 3, 5). Also change the third loop so that it runs
from y to 100.

As you look through the solutions, you might also notice that there are many solutions that are
multiples of others, like (6, 8, 10), and (9, 12, 15) are multiples of (3, 4, 5). The following program
finds only primitive Pythagorean triples, those that aren’t multiples of another triple. The way it
does this is every time a new triple is found, it checks to make sure that x, y, and z are not all
divisible by the same number.

for x in range(1,100):
for y in range(x,100):

for z in range(y,100):
if x**2+y**2==z**2:

for i in range(2,x):

if x%i==0 and y%i==0 and z%i==0:

break

else:

print((x,y,z), end=' ')

Example 4 List comprehensions can contain nested for loops. The example below returns a
list of all the vowels in a list of words.

[char for item in L for char in item if char in 'aeiou']

99
10.9 Exercises

1. Write a program that uses list and range to create the list [3,6, 9, . . . , 99].

2. Write a program that asks the user for a weight in kilograms. The program should convert
the weight to kilograms, formatting the result to one decimal place.

3. Write a program that asks the user to enter a word. Rearrange all the letters of the word in
alphabetical order and print out the resulting word. For example, abracadabra should
become aaaaabbcdrr.

4. Write a program that takes a list of ten prices and ten products, applies an 11% discount
to each of the prices displays the output like below, right-justified and nicely formatted.

Apples $ 2.45

Oranges $ 18.02

...

Pears $120.03

5. Use the following two lists and the format method to create a list of card names in the
format card value of suit name (for example, 'Two of Clubs').

suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']

values = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack',
'Queen', 'King', 'Ace']

6. Write a program that uses a boolean flag variable in determining whether two lists have
any items in common.

7. Write a program that creates the list [1,11,111,1111,...,111...1], where the entries have an
ever increasing number of ones, with the last entry having 100 ones.

8. Write a program to find all numbers between 1 and 1000 that are divisible by 7 and end in
a 6.
9. Write a program to determine how many of the numbers between 1 and 10000 contain
the digit 3.

100
Chapter 11

Dictionaries
A dictionary is a more general version of a list. Here is a list that contains the number of days
in the months of the year:

days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

If we want the number of days in January, use days[0]. December is days[11] or days[-1].

Here is a dictionary of the days in the months of the year:

days = {'January':31, 'February':28, 'March':31, 'April':30,

'May':31, 'June':30, 'July':31, 'August':31,

'September':30, 'October':31, 'November':30, 'December':31}

To get the number of days in January, we use days['January']. One benefit of using dictionaries
here is the code is more readable, and we don’t have to figure out which index in the list a given
month is at. Dictionaries have a number of other uses, as well.

Dictionary Properties:

 Ordered ✅ (Since Python 3.7+)

 Mutable (Can Add/Remove Elements) ✅

 No Duplicates (Keys Must Be Unique) ❌


 Uses Key-Value Pair ✅

11.1 Basics

Creating dictionaries Here is a simple dictionary:

d = {'A':100, 'B':200}

101
To declare a dictionary we enclose it in curly braces, {}. Each entry consists of a pair separated
by a colon. The first part of the pair is called the key and the second is the value. The key acts
like an index. So in the first pair, 'A':100, the key is 'A', the value is 100, and d['A'] gives 100.
Keys are often strings, but they can be integers, floats, and many other things as well. You can
mix different types of keys in the same dictionary and different types of values, too.

Changing dictionaries Let’s start with this dictionary:

d = {'A':100, 'B':200}

• To change d['A'] to 400,


do d['A']=400

• To add a new entry to the dictionary, we can just assign it, like
below: d['C']=500

Note that this sort of thing does not work with lists. Doing L[2]=500 on a list with two
elements would produce an index out of range error. But it does work with dictionaries.

• To delete an entry from a dictionary, use the del


operator: del d['A']

Empty dictionary The empty dictionary is {}, which is the dictionary equivalent of [] for lists or

'' for strings.

Important note The order of items in a dictionary will not necessarily be the order in which put
them into the dictionary. Internally, Python rearranges things in a dictionary in order to optimize
performance.

11.2 Dictionary examples

Example 1 You can use a dictionary as an actual dictionary of definitions:

d = {'dog' : 'has a tail and goes woof! ', 'cat' : 'says


meow',
'mouse' : 'chased by cats'}

Here is an example of the dictionary in use:


102
word = input('Enter a word: ')

print('The definition is:', d[word])

Enter a word: mouse


The definition is: chased by cats

Example 2 The following dictionary is useful in a program that works with Roman numerals.

numerals = {' I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}

Example 3 In the game Scrabble, each letter has a point value associated with it. We can use
the following dictionary for the letter values:

points = {'A':1, 'B':3, 'C':3, 'D':2, 'E':1, 'F':4, 'G':2, 'H':4, 'I':1, 'J':8, 'K':5, 'L':1, 'M':3,
'N':1, 'O':1, 'P':3, 'Q':10, 'R':1, 'S':1, 'T':1, 'U':1, 'V':4, 'W ':4, 'X':8,
'Y':4, 'Z':10}

To score a word, we can do the following:

score = sum([points[c] for c in word])

Or, if you prefer the long way:

total = 0

for c in word:
total += points[c]

Example 4 A dictionary provides a nice way to represent a deck of cards:

deck = [{'value':i, 'suit':c}

for c in ['spades', 'clubs', 'hearts', 'diamonds']

for i in range(2,15)]

The deck is actually a list of 52 dictionaries. The shuffle method can be used to shuffle the deck:

103
shuffle(deck)

The first card in the deck is deck[0]. To get the value and the suit of the card, we would use the
following:

deck[0]['value']

deck[0]['suit']

11.3 Working with dictionaries

Copying dictionaries Just like for lists, making copies of dictionaries is a little tricky for reasons
we will cover later. To copy a dictionary, use its copy method. Here is an example:

d2 = d.copy()

in The in operator is used to tell if something is a key in the dictionary. For instance, say we have
the following dictionary:

d = {'A':100, 'B':200}

Referring to a key that is not in the dictionary will produce an error. For instance, print(d['C'])
will fail. To prevent this error, we can use the in operator to check first if a key is in the dictionary
before trying to use the key. Here is an example:

letter = input('Enter a letter: ')

if letter in d:

print('The value is', d[letter])

else:

print('Not in dictionary')

You can also use not in to see if a key is not in the dictionary.

Looping Looping through dictionaries is similar to looping through lists. Here is an example
that prints the keys in a dictionary:

for key in d:

104
print(key)

Here is an example that prints the values:

for key in d:

print(d[key])

Lists of keys and values The following table illustrates the ways to get lists of keys and values
from a dictionary. It uses the dictionary d={'A':1,'B':3}.

Statement Result Description


list(d) ['A','B'] keys of d
list(d.values()) [1,3] values of d
list(d.items()) [('A',1),('B',3)] (key,value) pairs of d

The pairs returned by d.items are called tuples.

Here is a use of d.items to find all the keys in a dictionary d that correspond to a value of 100:

d = {'A':100, 'B':200, 'C':100}

L = [x[0] for x in d.items() if x[1]==100]

['A', 'C']

dict The dict function is another way to create a dictionary. One use for it is kind of like the opposite
of the items method:

d = dict([('A',100),('B',300)])

This creates the dictionary {'A':100,'B':300}. This way of building a dictionary is useful if your
program needs to construct a dictionary while it is running.

Dictionary comprehensions Dictionary comprehensions work similarly to list


comprehensions. The following simple example creates a dictionary from a list of words, where
the values are the lengths of the words:
105
d = {s : len(s) for s in words}

11.4 Counting words

We can use dictionaries to count how frequently certain words appear in a text.

we will learn how to read from a text file. For now, here’s a line of code that reads the entire
contents of a file containing the text of Shakespeare’s Romeo and Juliet and stores the contents
in a string called text:

text = open('romeoandjuliet.txt').read()

To get at the individual words, we will use the split method to turn the string into a list of its
individual words. Also, because some words may be capitalized, we will convert the whole
string to lowercase. We also have to remove punctuation.

from string import punctuation

text = text.lower()

for p in punctuation:
text = text.replace(p, '')

words = text.split()

Next comes the dictionary code that does the counting. The dictionary keys will be the words
from the text and the values will be counts of how many time each word appears. We start with
an empty dictionary. Then for every word in the list of words, if we have seen the word before,
we add one to its count, and otherwise we set the count for that word equal to 1. Here is the
code:

d = {}

for w in words:

if w in d:
d[w] = d[w] + 1

else:
d[w] = 1

Once we have created the dictionary, we can use the following code to print the items in
alphabeti-cal order:

106
items = list(d.items())

items.sort()

for i in items:

print(i)

The way this works is a little tricky. Remember that d.items() returns a list of pairs (called tuples),
which are a lot like lists. When we sort a list of tuples, the sorting is done by the first entry,
which in this case is the word. So the sorting is done alphabetically.

If we instead want to order things by frequency, we can flip the order of the tuples and then sort:

items = list(d.items())

items = [(i[1], i[0]) for i in items]


items.sort()

for i in items:

print(i)

Here is the code all together:


from string import punctuation

# read from file, remove caps and punctuation, and split into words

text = open('romeoandjuliet.txt').read()

text = text.lower()
for p in punctuation:
text = text.replace(p, '')
words = text.split()

# build the dictionary of frequencies


d = {}
for w in words:
if w in d:
d[w] = d[w] + 1
else:

d[w] = 1

# print in alphabetical order


items = list(d.items())

107
items.sort()
for i in items:
print(i)

# print in order from least to most common


items = list(d.items())
items = [(i[1], i[0]) for i in items]
items.sort()
for i in items:

print(i)

11.5 Tuple in Python

A tuple is an ordered and immutable (unchangeable) collection of elements. It allows


duplicates and is indexed.

11.6 Creating a Tuple

my_tuple = (10, 20, 30, "Python", 40.5)


print(my_tuple)

Output:
(10, 20, 30, 'Python', 40.5)

Tuple Properties:

 Ordered ✅

 Immutable (Cannot be changed) ❌


 Allows Duplicates ✅

 Uses Indexing ✅

11.7 Tuple Operations

1. Accessing Elements

print(my_tuple[0]) # First element


print(my_tuple[-1]) # Last element

108
Output:
10
40.5

2. Trying to Modify a Tuple (Will Cause an Error)

my_tuple[1] = 50 # Error

Output:

TypeError: 'tuple' object does not support item assignment

3. Converting Tuple to List (To Modify Elements)

temp_list = list(my_tuple)
temp_list[1] = 50
my_tuple = tuple(temp_list)
print(my_tuple)

Output:

(10, 50, 30, 'Python', 40.5)

11.8 Set in Python

A set is an unordered, mutable, and unindexed collection of elements. It does not allow
duplicates.

Creating a Set

my_set = {10, 20, 30, "Python", 40.5, 10}


print(my_set)

Output:

{40.5, 'Python', 10, 20, 30}

(Notice that the duplicate 10 is removed automatically.)

109
Set Properties:

 Ordered ❌ (Unordered)

 Mutable (Can Add/Remove Elements) ✅


 Does Not Allow Duplicates ❌

 No Indexing ❌
Set Operations

1. Adding Elements

my_set.add(50)
print(my_set)

Output:

{40.5, 'Python', 10, 50, 20, 30}

2. Removing Elements

my_set.remove(20)
print(my_set)

Output:

{40.5, 'Python', 10, 50, 30}

3. Checking Membership

print(30 in my_set) # Check if 30 is in the set

Output:
True

110
11.9 Differences Among List, Tuple, Set, and Dictionary

Feature List ✅ Tuple ✅ Set ✅ Dictionary ✅

Ordered ✅ Yes ✅ Yes ❌ No ✅ Yes (Since Python 3.7+)

Mutable ✅ Yes ❌ No ✅ Yes ✅ Yes

Duplicates Allowed ✅ Yes ✅ Yes ❌ No ❌ No (Keys Must Be Unique)

Indexing ✅ Yes ✅ Yes ❌ No ❌ No (Uses Keys)

Unordered ❌ No ❌ No ✅ Yes ✅ Yes (Before Python 3.7)

Key-Value Pair ❌ No ❌ No ❌ No ✅ Yes

11.10 When to Use Which?

 List → When you need an ordered, mutable collection (e.g., storing student names).
 Tuple → When you need an ordered, immutable collection (e.g., coordinates (x, y)).
 Set → When you need an unordered collection with unique items (e.g., unique colors in an
image).
 Dictionary → When you need key-value pairs for quick lookups (e.g., storing user details).

111
11.11 Exercises

1) Write a program that repeatedly asks the user to enter product names and prices. Store all of these
in a dictionary whose keys are the product names and whose values are the prices. When the user
is done entering products and prices, allow them to repeatedly enter a product name and print the
corresponding price or a message if the product is not in the dictionary.

2) Using the dictionary created in the previous problem, allow the user to enter a dollar amount
and print out all the products whose price is less than that amount.

3) For this problem, use the dictionary from the beginning of this chapter whose keys are month
names and whose values are the number of days in the corresponding months.

a) Ask the user to enter a month name and use the dictionary to tell them how many days
are in the month.
b) Print out all of the keys in alphabetical order.
c) Print out all of the months with 31 days.
d) Print out the (key-value) pairs sorted by the number of days in each month.

e) Modify the program from part (a) and the dictionary so that the user does not have to know
how to spell the month name exactly. That is, all they have to do is spell the first three
letters of the month name correctly.

4) Write a program that uses a dictionary that contains ten user names and passwords. The
program should ask the user to enter their username and password. If the username is not in
the dictionary, the program should indicate that the person is not a valid user of the system. If
the username is in the dictionary, but the user does not enter the right password, the program
should say that the password is invalid. If the password is correct, then the program should tell
the user that they are now logged in to the system.

5) Write a program that converts Roman numerals into ordinary numbers. Here are the
conversions: M=1000, D=500, C=100, L=50, X=10, V=5 I=1. Don’t forget about things like IV
being 4 and XL being 40.

a) Write a program that converts ordinary numbers into Roman numerals.

112
Chapter 12

Text Files

There is a ton of interesting data to be found on the internet stored in text files. In this chapter
we will learn how to work with data stored in text files.

12.1 Reading from files

Suppose we have a text file called example.txt whose contents are shown below, and we want
to read its contents into Python. There are several ways to do so. We will look at two of them.

Hello.

This is a text file.

Bye!

1. The first way to read a text file uses a list comprehension to load the file line-by-line into
a list:

lines = [line.strip() for line in open('example.txt')] The list lines is now

['Hello.', 'This is a text file.', 'Bye! ']

The string method strip removes any whitespace characters from the beginning and end
of a string. If we had not used it, each line would contain a newline character at the end
of the line. This is usually not what we want.

Note: strip removes whitespace from both the beginning and end of the line. Use rstrip if
you need to preserve whitespace at the beginning of the line.

2. The second way of reading a text file loads the entire file into a string:

s = open('example.txt').read()
113
The string s is now

'Hello.\nThis is a text file.\nBye! '

Directories

Say your program opens a file, like below:

s = open('file.txt').read()

The file is assumed to be in the same directory as your program itself. If it is in a different
directory, then you need to specify that, like below:

s = open('c:/users/heinold/desktop/file.txt').read()

12.2 Writing to files

There are also several ways to write to files. We will look at one way here. We will be writing to
a file called writefile.txt.

f = open('writefile.txt', 'w')
print('This is line 1.', file=f)
print('This is line 2.', file=f)
f.close()

We first have to open the file. That is what the first line does, with the 'w' indicating that we want
to be able to write to the file. Python creates what is called a file object to represent the file, and
we give that object the name f. This is what we use to refer to the file. To write to the file, we
use the print statement with the optional file argument that specifies the file to write to. When
we are done writing, we should close the file to make sure all of our changes take. Be careful
here because if writefile.txt already exists, its contents will be overwritten.

12.3 Examples

Example 1 Write a program that reads a list of temperatures from a file called temps.txt, con-
verts those temperatures to Fahrenheit, and writes the results to a file called ftemps.txt.

114
file1 = open('ftemps.txt', 'w')
temperatures = [line.strip() for line in open('temps.txt')]
for t in temperatures:
print(t*9/5+32, file=file1)

file1.close()

Example 2 In Section 7.6 we wrote a simple quiz game. The questions and answers were both
contained in lists hard-coded into the program. Instead of that, we can store the questions and
answers in files. That way, if you decide to change the questions or answers, you just have to change
their files. Moreover, if you decide to give the program to someone else who doesn’t know

Python, they can easily create their own lists of questions and answers. To do this, we just
replace the lines that create the lists with the following:

questions = [line.strip() for line in open('questions.txt')] answers = [line.strip()


for line in open('answers.txt')]

12.4 Wordplay

If you like words, you can have a lot of fun with a wordlist, which is a text file where each line
contains a different word. A quick web search will turn up a variety of different wordlists, ranging
from lists of common English words to lists containing practically every English word.

Assuming the wordlist file is wordlist.txt, we can load the words into a list using the line below.
wordlist = [line.strip() for line in open('wordlist.txt')]

Example 1 Print all three letter words.

for word in wordlist:


if len(word)==3:

print(word)

Note that this and most of the upcoming examples can be done with list comprehensions:

print([word for word in wordlist if len(word)==3])

Example 2 Print all the words that start with gn or kn.

for word in wordlist:


if word[:2]=='gn' or word[:2]=='kn':

print(word)

115
Example 3 Determine what percentage of words start with a vowel.

count = 0
for word in wordlist:
if word[0] in 'aeiou':
count=count+1
print(100*count/len(wordlist))

Example 4 Print all 7-letter words that start with th and end in ly. Things like this are good for
cheating at crosswords.

for word in wordlist:


if len(word)==7 and word[:2]=='th' and word[-2:]==' ly':

print(word)

Example 5 Print the first ten words that start with q.

i=0
while wordlist[i][0]!='q':
i=i+1
print(wordlist[i:i+10]

Note this is not a very efficient way of doing things since we have to scan through most of the
list. A binary search would be more efficient, but the above approach still runs almost instantly
even for large files.

Example 6 Find the longest word that can be made using only the letters a, b, c, d, and e.

largest = 0
for word in wordlist:
for c in word:

if c not in 'abcde':

break

116
else:

if len(word)>largest:

largest=len(word)
largest_word=word

print(largest_word)

12.5 Exercises

1. You are given a file called class_scores.txt, where each line of the file contains a one-
word username and a test score separated by spaces, like below:.

GWashington 83

JAdams 86

Write code that scans through the file, adds 5 points to each test score, and outputs the
user-names and new test scores to a new file, scores2.txt.

2. You are given a file called grades.txt, where each line of the file contains a one-word stu-
dent username and three test scores separated by spaces, like below:.
GWashington 83 77 54

JAdams 86 69 90

Write code that scans through the file and determines how many students passed all
three tests.
3. Wordplay – Use the file wordlist.txt for this problem. Find the following:

(a) All words ending in ime


(b) All words whose second, third, and fourth letters are ave
(c) How many words contain at least one of the letters r, s, t, l, n, e
(d) The percentage of words that contain at least one of the letters r, s, t, l, n, e
(e) All words with no vowels
(f) All words that contain every vowel
(g) Whether there are more ten-letter words or seven-letter words
(h) The longest word in the list
(i) All palindromes
(j) All words that are words in reverse, like rat and tar.

117
(k) Same as above, but only print one word out of each pair.
(l) All words that contain double letters next each other like aardvark or book,
excluding words that end in lly
(m) All words that contain a q that isn’t followed by a u
(n) All words that contain zu anywhere in the word
(o) All words that contain ab in multiple places, like habitable
(p) All words with four or more vowels in a row
(q) All words that contain both a z and a w
(r) All words whose first letter is a, third letter is e and fifth letter is i
(s) All two-letter words
(t) All four-letter words that start and end with the same letter
(u) All words that contain at least nine vowels.
(v) All words that contain each of the letters a, b, c, d, e, and f in any order. There may
be other letters in the word. Two examples are backfield and feedback.
(w) All words whose first four and last four letters are the same
(x) All words of the form abcd*dcba, where * is arbitrarily long sequence of letters.
(y) All groups of 5 words, like pat pet pit pot put, where each word is 3 letters, all
words share the same first and last letters, and the middle letter runs through all 5
vowels.
(z) The word that has the most i’s.

4. Write a program to help with word games. The user enters a word and the program
uses the wordlist to determine if the user’s word is a real word or not.

118
Chapter 13

Functions

Functions are useful for breaking up a large program to make it easier to read and maintain.
They are also useful if you find yourself writing the same code at several different points in your
pro-gram. You can put that code in a function and call the function whenever you want to
execute that code. You can also use functions to create your own utilities, math functions, etc.

13.1 Basics

Functions are defined with the def statement. The statement ends with a colon, and the code
that is part of the function is indented below the def statement. Here we create a simple function
that just prints something.
Example:
def print_hello():
print('Hello! ')

print_hello()
print('1234567')
print_hello()

Output:
Hello!
1234567
Hello!

The first two lines define the function. In the last three lines we call the function twice.

Put the code into a function, and then whenever you need a box, just call the function rather
than typing several lines of redundant code. Here is the function.
119
Example:

def draw_square():
print('*' * 15)
print('*', ' '*11, '*')

print('*', ' '*11, '*')

print('*' * 15)

One benefit of this is that if you decide to change the size of the box, you just have to modify
the code in the function, whereas if you had copied and pasted the box-drawing code
everywhere you needed it, you would have to change all of them.

13.2 Arguments

We can pass values to functions. Here is an example:

Example:
def print_hello(n):

print('Hello ' * n)
print()

print_hello(3)
print_hello(5)

times = 2
print_hello(times)

Output:
Hello Hello Hello
Hello Hello Hello Hello Hello
Hello Hello

When we call the print_hello function with the value 3, that value gets stored in the variable n.

We can then refer to that variable n in our function’s code.

You can pass more than one value to a function:

120
Example:
def multiple_print(string, n):

print(string * n)
print()

multiple_print('Hello', 5)
multiple_print('A', 10)

Output:
HelloHelloHelloHelloHello
AAAAAAAAAA

13.3 Returning values

We can write functions that perform calculations and return a result.

Example 1 Here is a simple function that converts temperatures from Celsius to Fahrenheit.

def convert(t):
return t*9/5+32

print(convert(20))

Output:
68

The return statement is used to send the result of a function’s calculations back to the caller.

Notice that the function itself does not do any printing. The printing is done outside of the function.

That way, we can do math with the result, like below.

print(convert(20)+5)

If we had just printed the result in the function instead of returning it, the result would have been
printed to the screen and forgotten about, and we would never be able to do anything with it.

121
Example 2 As another example, the Python math module contains trig functions, but they only
work in radians. Let us write our own sine function that works in degrees.

from math import pi, sin

def deg_sin(x):
return sin(pi* x/180)

Example 3 A function can return multiple values as a list.

Say we want to write a function that solves the system of equations a x + b y = e and c x + d y =
f . It turns out that if there is a unique solution, then it is given by x = (d e b f )=(ad bc) and y = (a
f ce)=(ad bc). We need our function to return both the x and y solutions.

def solve(a,b,c,d,e,f):

x = (d* e-b*f)/(a*d-b*c)

y = (a* f-c* e)/(a*d-b*c)

return [x,y]

xsol, ysol = solve(2,3,4,1,2,5)


print('The solution is x = ', xsol, 'and y = ', ysol)

The solution is x = 1.3 and y = -0.2

Example 4 A return statement by itself can be used to end a function early.

def multiple_print(string, n, bad_words):

if string in bad_words:

return
print(string * n)
print()

The same effect can be achieved with an if/else statement, but in some cases, using return
can make your code simpler and more readable.

122
13.4 Default arguments and keyword arguments

You can specify a default value for an argument. This makes it optional, and if the caller
decides not to use it, then it takes the default value. Here is an example:

def multiple_print(string, n=1)


print(string * n)
print()

multiple_print('Hello', 5)
multiple_print('Hello')

Output:
HelloHelloHelloHelloHello
Hello

Default arguments need to come at the end of the function definition, after all of the non-
default arguments.

Keyword arguments A related concept to default arguments is keyword arguments. Say we


have the following function definition:

def fancy_print(text, color, background, style, justify):

Every time you call this function, you have to remember the correct order of the arguments.
Fortu-nately, Python allows you to name the arguments when calling the function, as shown
below:

fancy_print(text='Hi', color=' yellow', background='black', style='bold',


justify=' left')

fancy_print(text='Hi', style='bold', justify='left', background='black',


color='yellow')

As we can see, the order of the arguments does not matter when you use keyword arguments.

When defining the function, it would be a good idea to give defaults. For instance, most of the
time, the caller would want left justification, a white background, etc. Using these values as
defaults means the caller does not have to specify every single argument every time they call
the function. Here is a example:

123
def fancy_print(text, color='black', background='white',
style=' normal', justify=' left'):

# function code goes here

fancy_print('Hi', style='bold')
fancy_print('Hi', color='yellow', background='black')
fancy_print('Hi')

Note We have actually seen default and keyword arguments before—the sep, end and file
arguments of the print function.

13.5 Local variables

Let’s say we have two functions like the ones below that each use a variable i:

def func1():
for i in range(10):

print(i)

def func2():
i=100

func1()

print(i)

A problem that could arise here is that when we call func1, we might mess up the value of i in
func2. In a large program it would be a nightmare trying to make sure that we don’t repeat
variable names in different functions, and, fortunately, we don’t have to worry about this. When
a variable is defined inside a function, it is local to that function, which means it essentially does
not exist outside that function. This way each function can define its own variables and not have
to worry about if those variable names are used in other functions.

Global variables On the other hand, sometimes you actually do want the same variable to be
available to multiple functions. Such a variable is called a global variable. You have to be careful
using global variables, especially in larger programs, but a few global variables used judiciously
are fine in smaller programs. Here is a short example:

124
In this program we have a variable time_left that we would like multiple functions to have access
to. If a function wants to change the value of that variable, we need to tell the function that
time_left is a global variable. We use a global statement in the function to do this. On the other
hand, if we just want to use the value of the global variable, we do not need a global statement.
Arguments We finish the chapter with a bit of a technical detail. You can skip this section for
the time being if you don’t want to worry about details right now. Here are two simple functions:

def func1(x):
x=x+1

def func2(L):
L=L+[1]

Output:
a=3
M=[1,2,3]
func1(a)
func2(M)

When we call func1 with a and func2 with L, a question arises: do the functions change the
values of a and L? The answer may surprise you. The value of a is unchanged, but the value
of L is changed. The reason has to do with a difference in the way that Python handles numbers
and lists. Lists are said to be mutable objects, meaning they can be changed, whereas numbers
and strings are immutable, meaning they cannot be changed.
If we want to reverse the behavior of the above example so that a is modified and L is not, do
the following:

def func1(x):

x=x+1
return x

def func2(L):

copy = L[:]
copy = copy + [1]

Output:
a=3

M=[1,2,3]

a=func1(a) # note change on this line


func2(M)

125
13.6 Exercises

1. Write a function called rectangle that takes two integers m and n as arguments and
prints out an m n box consisting of asterisks. Shown below is the output of rectangle(2,4)

****

****

2. (a) Write a function called add_excitement that takes a list of strings and adds an excla-
mation point (! ) to the end of each string in the list. The program should modify the
original list and not return anything.

(b) Write the same function except that it should not modify the original list and should
instead return a new list.

3. Write a function called sum_digits that is given an integer num and returns the sum of
the digits of num.

4. The digital root of a number n is obtained as follows: Add up the digits n to get a new
number. Add up the digits of that to get another new number. Keep doing this until you
get a number that has only one digit. That number is the digital root.

For example, if n = 45893, we add up the digits to get 4 + 5 + 8 + 9 + 3 = 29. We then add
up the digits of 29 to get 2 + 9 = 11. We then add up the digits of 11 to get 1 + 1 = 2. Since
2 has only one digit, 2 is our digital root.

Write a function that returns the digital root of an integer n. [Note: there is a shortcut,
where the digital root is equal to n mod 9, but do not use that here.]

5. Write a function called first_diff that is given two strings and returns the first location in
which the strings differ. If the strings are identical, it should return -1.

126
Chapter 14

Object-Oriented Programming

About a year or so after I started programming, I decided to make a game to play Wheel of
Fortune. I wrote the program in the BASIC programming language and it got to be pretty large,
a couple thousand lines. It mostly worked, but whenever I tried to fix something, my fix would
break something in a completely different part of the program. I would then fix that and break
something else. Eventually I got the program working, but after a while I was afraid to even
touch it.

The problem with the program was that each part of the program had access to the variables
from the other parts. A change of a variable in one part would mess up things in the others.
One solu-tion to this type of problem is object-oriented programming. One of its chief benefits
is encapsulation, where you divide your program into pieces and each piece internally operates
independently of the others. The pieces interact with each other, but they don’t need to know
exactly how each one accomplishes its tasks. This requires some planning and set-up time
before you start your program, and so it is not always appropriate for short programs, like many
of the ones that we have written so far.

We will just cover the basics of object-oriented programming here. Object-oriented


programming is used extensively in software design and I would recommend picking up another
book on pro-gramming or software design to learn more about designing programs in an object-
oriented way.

14.1 Python is objected-oriented

Python is an object-oriented programming language, and we have in fact been using many
object-oriented concepts already. The key notion is that of an object. An object consists of two
things: data and functions (called methods) that work with that data. As an example, strings in
Python are objects. The data of the string object is the actual characters that make up that
string. The methods are things like lower, replace, and split. In Python, everything is an object.
That includes not only strings and lists, but also integers, floats, and even functions themselves.

127
14.2 Creating your own classes

A class is a template for objects. It contains the code for all the object’s methods.

A simple example Here is a simple example to demonstrate what a class looks like. It does not
do anything interesting.

class Example:
def __init__(self, a, b):
self.a = a

self.b = b

def add(self):

return self.a + self.b

Output:
e = Example(8, 6)
print(e.add())

• To create a class, we use the class statement. Class names usually start with a capital.

• Most classes will have a method called __init__. The underscores indicate that it is a special
kind of method. It is called a constructor, and it is automatically called when someone creates
a new object from your class. The constructor is usually used to set up the class’s variables.
In the above program, the constructor takes two values, a and b, and assigns the class
variables a and b to those values.

• The first argument to every method in your class is a special variable called self. Every time
your class refers to one of its variables or methods, it must precede them by self. The purpose
of self is to distinguish your class’s variables and methods from other variables and functions
in the program.

• To create a new object from the class, you call the class name along with any values that you
want to send to the constructor. You will usually want to assign it to a variable name. This is
what the line e=Example(8,6) does.

• To use the object’s methods, use the dot operator, as in e.addmod().

128
A more practical example Here is a class called Analyzer that performs some simple analysis on
a string. There are methods to return how many words are in the string, how many are of a given
length, and how many start with a given string.

from string import punctuation


class Analyzer:

def __init__(self, s):

for c in punctuation:

s = s.replace(c,'')

s = s.lower()

self.words = s.split()

def number_of_words(self):

return len(self.words)

def starts_with(self, s):

return len([w for w in self.words if w[:len(s)]==s])

def number_with_length(self, n):

return len([w for w in self.words if len(w)==n])

s = 'This is a test of the class.'

analyzer = Analyzer(s)

print(analyzer.words)

print('Number of words:', analyzer.number_of_words())


print('Number of words starting with "t":', analyzer.starts_with('t'))

print('Number of 2-letter words:', analyzer.number_with_length(2))

Output:
['this', 'is', 'a', 'test', 'of', 'the', 'class'] Number of words: 7
Number of words starting with "t": 3
Number of 2-letter words: 2

129
A few notes about this program:
• One reason why we would wrap this code up in a class is we can then use it a variety of
different programs. It is also good just for organizing things. If all our program is doing is just
analyzing some strings, then there’s not too much of a point of writing a class, but if this were
to be a part of a larger program, then using a class provides a nice way to separate the
Analyzer code from the rest of the code. It also means that if we were to change the internals of
the Analyzer class, the rest of the program would not be affected as long as the interface, the way
the rest of the program interacts with the class, does not change. Also, the Analyzer class can be
imported as-is in other programs.

• The following line accesses a class variable:

print(analyzer.words)

You can also change class variables. This is not always a good thing. In some cases this is con-
venient, but you have to be careful with it. Indiscriminate use of class variables goes against the
idea of encapsulation and can lead to programming errors that are hard to fix. Some other object-
oriented programming languages have a notion of public and private variables, public variables
being those that anyone can access and change, and private variables being only accessible to
methods within the class. In Python all variables are public, and it is up to the programmer to be
responsible with them. There is a convention where you name those vari-ables that you want to
be private with a starting underscore, like _var1. This serves to let others know that this variable is
internal to the class and shouldn’t be touched.

14.3 Inheritance

In object-oriented programming there is a concept called inheritance where you can create a class that
builds off of another class. When you do this, the new class gets all of the variables and methods of the
class it is inheriting from (called the base class). It can then define additional variables and methods that
are not present in the base class, and it can also override some of the methods of the base class. That
is, it can rewrite them to suit its own purposes. Here is a simple example:

class Parent:

def __init__(self, a):


self.a = a

def method1(self):

return self.a*2

def method2(self):
return self.a+'!!! '

130
class Child(Parent):

def __init__(self, a, b):


self.a = a

self.b = b

def method1(self):

return self.a*7

def method3(self):
return self.a + self.b

p = Parent(' hi')

c = Child(' hi', 'bye')


print('Parent method 1: ', p.method1())

print('Parent method 2: ', p.method2())


print()

print('Child method 1: ', c.method1())

print('Child method 2: ', c.method2())


print('Child method 3: ', c.method3())

Output:
Parent method 1: hihi
Parent method 2: hi!!!

Child method 1: hihihihihihihi


Child method 2: hi!!!
Child method 3: hibye

We see in the example above that the child has overridden the parent’s method1, causing it to now
repeat the string seven times. The child has inherited the parent’s method2, so it can use it without
having to define it. The child also adds some features to the parent class, namely a new variable b
and a new method, method3.

A note about syntax: when inheriting from a class, you indicate the parent class in parentheses in
the class statement.

131
If the child class adds some new variables, it can call the parent class’s constructor as
demonstrated below. Another use is if the child class just wants to add on to one of the parent’s
methods. In the example below, the child’s print_var method calls the parent’s print_var method
and adds an additional line.

class Parent:
def __init__(self, a):
self.a = a

def print_var(self):

print("The value of this class's variables are:")

print(self.a)

class Child(Parent):
def __init__(self, a, b):
Parent.__init__(self, a)

self.b = b

def print_var(self):
Parent.print_var(self)

print(self.b)

14.4 A playing-card example

In this section we will show how to design a program with classes. We will create a simple hi-
lo card game where the user is given a card and they have to say if the next card will be higher
or lower than it. This game could easily be done without classes, but we will create classes to
represent a card and a deck of cards, and these classes can be reused in other card games.

class Card:

def __init__(self, value, suit):


self.value = value

self.suit = suit

def __str__(self):
names = ['Jack', 'Queen', 'King', 'Ace']

if self.value <= 10:

return '{} of {}'.format(self.value, self.suit)

132
else:

return '{} of {}'.format(names[self.value-11], self.suit)

Next we have a class to represent a group of cards. Its data consists of a list of Card objects. It
has a number of methods: nextCard which removes the first card from the list and returns it;
hasCard which returns True or False depending on if there are any cards left in the list; size, which
returns how many cards are in the list; and shuffle, which shuffles the list.

import random
class Card_group:
def __init__(self, cards=[]):
self.cards = cards

def nextCard(self):

return self.cards.pop(0)

def hasCard(self):
return len(self.cards)>0

def size(self):

return len(self.cards)

def shuffle(self):
random.shuffle(self.cards)

We have one more class Standard_deck, which inherits from Card_group. The idea here is that
Card_group represents an arbitrary group of cards, and Standard_deck represents a specific group
of cards, namely the standard deck of 52 cards used in most card games.

class Standard_deck(Card_group):
def __init__(self):
self.cards = []

for s in ['Hearts', 'Diamonds', 'Clubs', 'Spades']:

for v in range(2,15):
self.cards.append(Card(v, s))

133
deck = Standard_deck()

deck.shuffle()

new_card = deck.nextCard()

print('\n', new_card)

choice = input("Higher (h) or lower (l): ")

streak = 0

while (choice==' h' or choice==' l'):

if not deck.hasCard():
deck = Standard_deck()

deck.shuffle()

old_card = new_card

new_card = deck.nextCard()

if (choice.lower()==' h' and new_card.value>old_card.value or\

choice.lower()=='l' and new_card.value<old_card.value):

streak = streak + 1

print("Right! That' s", streak, "in a row!")

elif (choice.lower()==' h' and new_card.value<old_card.value or\ choice.lower()==' l'


and new_card.value>old_card.value):

streak = 0

print('Wrong.')

print('\n', new_card)

choice = input("Higher (h) or lower (l): ")

134
Output:
King of Clubs
Higher (h) or lower (l): l
Right! That's 1 in a row!
2 of Spades
Higher (h) or lower (l): h

Right! That's 2 in a row!

14.5 A Tic-tac-toe example

In this section we create an object-oriented Tic-tac-toe game. We use a class to wrap up the
logic of the game. The class contains two variables, an integer representing the current player,
and a 3 3 list representing the board. The board variable consists of zeros, ones, and twos.
Zeros represent an open spot, while ones and twos represent spots marked by players 1 and
2, respectively. There are four methods:

• get_open_spots — returns a list of the places on the board that have not yet been marked by
players

• is_valid_move — takes a row and a column representing a potential move, and returns True
if move is allowed and False otherwise

• make_move — takes a row and a column representing a potential move, calls is_valid_move
to see if the move is okay, and if it is, sets the board array accordingly and changes the player

• check_for_winner — scans through the board list and returns 1 if player 1 has won, 2 if player
2 has won, 0 if there are no moves remaining and no winner, and -1 if the game should
continue

Here is the code for the class:

class tic_tac_toe:

def __init__(self):
self.B = [[0,0,0],
[0,0,0],
[0,0,0]]
self.player = 1

135
def get_open_spots(self):

return [[r,c] for r in range(3) for c in range(3)

if self.B[r][c]==0]

def is_valid_move(self,r,c):

if 0<=r<=2 and 0<=c<=2 and self.B[r][c]==0:

return True

return False

def make_move(self,r,c):

if self.is_valid_move(r,c):

self.B[r][c] = self.player

self.player = (self.player+2)%2 + 1

def check_for_winner(self):
for c in range(3):

if self.B[0][c]==self.B[1][c]==self.B[2][c]!=0:

return self.B[0][c]

for r in range(3):

if self.B[r][0]==self.B[r][1]==self.B[r][2]!=0:

return self.B[r][0]

if self.B[0][0]==self.B[1][1]==self.B[2][2]!=0:

return self.B[0][0]

if self.B[2][0]==self.B[1][1]==self.B[0][2]!=0:

return self.B[2][0]

if self.get_open_spots()==[]:

return 0
return -1
This class consists of the logic of the game. There is nothing in the class that is specific to the user
interface. Below we have a text-based interface using print and input statements. If we decide to use
a graphical interface, we can use the Tic_tac_toe class without having to change anything about it.
Note that the get_open_spots method is not used by this program. It is useful, however, if you want
136
to implement a computer player. A simple computer player would call that method and use
random.choice method to choose a random element from the returned list of spots.

def print_board():

chars = ['-', 'X', 'O']

for r in range(3):

for c in range(3):

print(chars[game.B[r][c]], end=' ')

print()
game = tic_tac_toe()

while game.check_for_winner()==-1:

print_board()
r,c = eval(input('Enter spot, player ' + str(game.player) + ': '))

game.make_move(r,c)

print_board()

x = game.check_for_winner()
if x==0:

print("It' s a draw.")
else:

print('Player', x, 'wins! ')

Here is what the first couple of turns look like:

---
---
---
Enter spot, player 1: 1,1
---
-X-
---
Enter spot, player 2: 0,2

- -O
- X-
- --

137
Enter spot, player 1:

14.7 Exercises

1. Write a class called Investment with fields called principal and interest. The construc-tor
should set the values of those fields. There should be a method called value_after that
returns the value of the investment after n years. The formula for this is p(1 + i)n, where p
is the principal, and i is the interest rate. It should also use the special method __str__ so
that printing the object will result in something like below:

Principal - $1000.00, Interest rate - 5.12%

2. Write a class called Product. The class should have fields called name, amount, and price,
holding the product’s name, the number of items of that product in stock, and the regular
price of the product. There should be a method get_price that receives the number of
items to be bought and returns a the cost of buying that many items, where the regular
price is charged for orders of less than 10 items, a 10% discount is applied for orders of
between 10 and 99 items, and a 20% discount is applied for orders of 100 or more items.
There should also be a method called make_purchase that receives the number of items
to be bought and decreases amount by that much.

3. Write a class called Password_manager. The class should have a list called old_passwords
that holds all of the user’s past passwords. The last item of the list is the user’s current
pass-word. There should be a method called get_password that returns the current
password and a method called set_password that sets the user’s password. The
set_password method should only change the password if the attempted password is
different from all the user’s past passwords. Finally, create a method called is_correct that
receives a string and returns a boolean True or False depending on whether the string is
equal to the current password or not.

4. Write a class called Wordplay. It should have a field that holds a list of words. The user of
the class should pass the list of words they want to use to the class. There should be the
following methods:

• words_with_length(length) — returns a list of all the words of length length

• starts_with(s) — returns a list of all the words that start with s

• ends_with(s) — returns a list of all the words that end with s

• palindromes() — returns a list of all the palindromes in the list

138
• only(L) — returns a list of the words that contain only those letters in L

• avoids(L) — returns a list of the words that contain none of the letters in L

5. Write a class called Converter. The user will pass a length and a unit when declaring an
object from the class—for example, c = Converter(9,'inches'). The possible units are
inches, feet, yards, miles, kilometers, meters, centimeters, and millimeters. For each of
these units there should be a method that returns the length converted into those units.
For exam-ple, using the Converter object created above, the user could call c.feet() and
should get 0.75 as the result.

139
Part II

Graphics

140
Chapter 15

GUI Programming with Tkinter

Up until now, the only way our programs have been able to interact with the user is through
keyboard input via the input statement. But most real programs use windows, buttons, scrollbars,
and various other things. These widgets are part of what is called a Graphical User Interface or
GUI. This chapter is about GUI programming in Python with Tkinter.

All of the widgets we will be looking at have far more options than we could possibly cover here.

An excellent reference is Fredrik Lundh’s Introduction to Tkinter [2].

15.1 Basics

Nearly every GUI program we will write will contain the following three lines:

from tkinter import *


root = Tk()

mainloop()

The first line imports all of the GUI stuff from the tkinter module. The second line creates a
window on the screen, which we call root. The third line puts the program into what is essentially
a long-running while loop called the event loop. This loop runs, waiting for keypresses, button
clicks, etc., and it exits when the user closes the window.

15.2 Creating a Simple Tkinter Window

Here’s a basic example of a Tkinter window:

from tkinter import Tk

root = Tk()

root.title("My First Tkinter Window")

141
root.geometry("300x200")

root.mainloop()

This creates a simple window titled "My First Tkinter Window".

Output:

15.3 Code Explanation

root.title("Tkinter Example")

 Sets the Window Title:

o The title() method changes the window’s title bar text to "Tkinter
Example".

root.geometry("300x200")

 Sets Window Size:


o geometry("widthxheight") sets the window’s dimensions to 300 pixels wide
and 200 pixels high.

label = Label(root, text="Click the button", font=("Arial", 14))

142
 Creates a Label Widget:
o tk.Label() creates a label inside root.

o text="Click the button" sets the default text.

o font=("Arial", 14) sets the font style to "Arial" and size 14.

label.pack(pady=10)

 Displays the Label (label.pack()):


o pack() arranges the label in the window.

o pady=10 adds 10 pixels of vertical spacing.

def say_hello():
label.config(text="Hello, Tkinter!")

 Function Definition (say_hello):

o When this function is called, it changes the text of the label widget to "Hello,
Tkinter!".

o .config(text="Hello, Tkinter!") updates the label’s text property.

button = tk.Button(root, text="Click Me", command=say_hello)

 Creates a Button Widget:


o tk.Button() creates a button inside root.

o text="Click Me" sets the button label.

o command=say_hello links the button click to the say_hello() function.

button.pack()

 Displays the Button (button.pack()):


o This places the button inside the window.

root.mainloop()

 Starts the Tkinter Event Loop:

143
o mainloop() keeps the window open and waits for user interactions (like button
clicks).
Expected Output

Before Clicking the Button: After Clicking the Button:

Here is a working GUI program that converts temperatures from Fahrenheit to Celsius.

from tkinter import *

def calculate():

temp = int(entry.get())
temp = 9/5*temp+32

output_label.configure(text = 'Converted: {:.1f}'.format(temp))

entry.delete(0,END)

root = Tk()
message_label = Label(text='Enter a temperature',
font=('Verdana', 16))
output_label = Label(font=('Verdana', 16))
entry = Entry(font=('Verdana', 16), width=4)
calc_button = Button(text='Ok', font=('Verdana', 16),
command=calculate)

message_label.grid(row=0, column=0)
entry.grid(row=0, column=1)
calc_button.grid(row=0, column=2)
output_label.grid(row=1, column=0, columnspan=3)

mainloop()

144
Output:

We now will examine the components of the program separately.

15.4 Labels

A label is a place for your program to place some text on the screen. The following code creates a
label and places it on the screen.

hello_label = Label(text=' hello')

hello_label.grid(row=0, column=0)

We call Label to create a new label. The capital L is required. Our label’s name is hello_label. Once
created, use the grid method to place the label on the screen. We will explain grid in the next section.

Options There are a number of options you can change including font size and color. Here are
some examples:

hello_label = Label(text=' hello', font=('Verdana', 24, 'bold'),

bg='blue', fg='white')

Note the use of keyword arguments. Here are a few common options:

• font — The basic structure is font= (font name, font size, style). You can leave out the font size or
the style. The choices for style are 'bold', 'italic', 'underline', ' overstrike', 'roman', and 'normal' (which
is the default). You can combine multiple styles like this: 'bold italic'.

• fg and bg — These stand for foreground and background. Many common color names can be
used, like 'blue', 'green', etc.

145
• width — This is how many characters long the label should be. If you leave this out, Tkinter will
base the width off of the text you put in the label. This can make for unpredictable results, so it is
good to decide ahead of time how long you want your label to be and set the width accordingly.

• height — This is how many rows high the label should be. You can use this for multi-line labels.
Use newline characters in the text to get it to span multiple lines. For example, text=' hi\nthere'.

There are dozens more options. The aforementioned Introduction to Tkinter [2] has a nice list of
the others and what they do.
Changing label properties Later in your program, after you’ve created a label, you may want to
change something about it. To do that, use its configure method. Here are two examples that
change the properties of a label called label:

label.configure(text='Bye')

label.configure(bg='white', fg='black')

Setting text to something using the configure method is kind of like the GUI equivalent of a print
statement. However, in calls to configure we cannot use commas to separate multiple things to print.
We instead need to use string formatting. Here is a print statement and its equiv-alent using the
configure method.

print('a =', a, 'and b =', b)

label.configure(text='a = {}, and b = {}'.format(a,b))

The configure method works with most of the other widgets we will see.

15.5 Grid

The grid method is used to place things on the screen. It lays out the screen as a rectangular grid
of rows and columns. The first few rows and columns are shown below.

(row=0, column=0) (row=0, column=1) (row=0, column=2)

(row=1, column=0) (row=1, column=1) (row=1, column=2)

(row=2, column=0) (row=2, column=1) (row=2, column=2)

146
Spanning multiple rows or columns There are optional arguments, rowspan and columnspan,
that allow a widget to take up more than one row or column. Here is an example of several grid
statements followed by what the layout will look like:

label1.grid(row=0, column=0)

label2.grid(row=0, column=1)

label3.grid(row=1, column=0, columnspan=2)

label4.grid(row=1, column=2)

label5.grid(row=2, column=2)

label1 label2

label 3 label4

label5

Spacing To add extra space between widgets, there are optional arguments padx and pady.

15.6 Entry boxes

Entry boxes are a way for your GUI to get text input. The following example creates a simple
entry box and places it on the screen.

entry = Entry()

entry.grid(row=0, column=0)

Most of the same options that work with labels work with entry boxes (and most of the other
widgets we will talk about). The width option is particularly helpful because the entry box will
often be wider than you need.

147
Example:

from tkinter import *

def show_name():

name = entry.get()

label.config(text=f"Hello, {name}!")

root = Tk()

root.title("User Input Example")

root.geometry("300x200")

entry = Entry(root)

entry.pack(pady=10)

button = Button(root, text="Submit", command=show_name)

button.pack()

label = Label(root, text="")

label.pack()

root.mainloop()

Output:

148
• Getting text To get the text from an entry box, use its get method. This will return a string.
If you need numerical data, use eval (or int or float) on the string. Here is a simple
example that gets text from an entry box named entry.

string_value = entry.get()

num_value = eval(entry.get())

• Deleting text To clear an entry box, use the


following: entry.delete(0,END)

• Inserting text To insert text into an entry box, use the


following: entry.insert(0, 'hello')

15.7 Buttons

The following example creates a simple button:


ok_button = Button(text='Ok')

To get the button to do something when clicked, use the command argument. It is set to the
name of a function, called a callback function. When the button is clicked, the callback function
is called. Here is an example:

from tkinter import *


def callback():
label.configure(text='Button clicked')

root = Tk()
label = Label(text='Not clicked')
button = Button(text='Click me', command=callback)

label.grid(row=0, column=0)
button.grid(row=1, column=0)

mainloop()

When the program starts, the label says Click me. When the button is clicked, the callback func-
tion callback is called, which changes the label to say Button clicked.

149
lambda trick Sometimes we will want to pass information to the callback function, like if we have
several buttons that use the same callback function and we want to give the function infor-mation
about which button is being clicked. Here is an example where we create 26 buttons, one for each
letter of the alphabet. Rather than use 26 separate Button() statements and 26 different functions,
we use a list and one function.

from tkinter import *


alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

def callback(x):

label.configure(text='Button {} clicked'.format(alphabet[x]))

root = Tk()

label = Label()

label.grid(row=1, column=0, columnspan=26)

buttons = [0]*26 # create a list to hold 26 buttons

for i in range(26):
buttons[i] = Button(text=alphabet[i],

command = lambda x=i: callback(x))

buttons[i].grid(row=0, column=i)

mainloop()

Output:

We note a few things about this program. First, we set buttons=[0]*26. This creates a list with
26 things in it. We don’t really care what thoset things are because they will be replaced with
buttons. An alternate way to create the list would be to set buttons=[] and use the append
method.

We only use one callback function and it has one argument, which indicates which button was
clicked. As far as the lambda trick goes, without getting into the details, command=callback(i)
does not work, and that is why we resort to the lambda trick.

150
15.8 Using Frames and Layouts (Pack, Grid, Place)

 Using pack() (Simple Layout)

label = tk.Label(frame, text="Inside a Frame")


label.pack()

 Using grid() (Table-like Layout)

label1 = tk.Label(root, text="Row 0, Column 0")


label1.grid(row=0, column=0)

label2 = tk.Label(root, text="Row 1, Column 1")


label2.grid(row=1, column=1)

 Using place() (Absolute Positioning)

label.place(x=50, y=100) # Position at (50,100)

15.9 Global variables

Let’s say we want to keep track of how many times a button is clicked. An easy way to do this
is to use a global variable as shown below.

from tkinter import *


def callback():
global num_clicks
num_clicks = num_clicks + 1

label.configure(text='Clicked {} times.'.format(num_clicks))

num_clicks = 0
root = Tk()
label = Label(text='Not clicked')
button = Button(text='Click me', command=callback)
label.grid(row=0, column=0)
button.grid(row=1, column=0)
mainloop()

151
Output:

We will be using a few global variables in our GUI programs. Using global variables
unnecessarily, especially in long programs, can cause difficult to find errors that make programs
hard to maintain,
but in the short programs that we will be writing, we should be okay. Object-oriented
programming provides an alternative to global variables.

15.10 Tic-tac-toe

Using Tkinter, in only about 20 lines we can make a working tic-tac-toe program:

from tkinter import *

def callback(r,c):

global player

if player == 'X':

b[r][c].configure(text = 'X')

player = 'O'

else:

b[r][c].configure(text = 'O')

player = 'X'

root = Tk()

b = [[0,0,0],

[0,0,0],

[0,0,0]]
152
for i in range(3):

for j in range(3):

b[i][j] = Button(font=('Verdana', 56), width=3, bg='yellow', command = lambda


r=i,c=j: callback(r,c))

b[i][j].grid(row = i, column = j)

player = 'X'
mainloop()

The program works, though it does have a few problems, like letting you change a cell that
already has something in it. We will fix this shortly. First, let’s look at how the program does
what it does. Starting at the bottom, we have a variable player that keeps track of whose turn it
is. Above that we create the board, which consists of nine buttons stored in a two-dimensional
list. We use the lambda trick to pass the row and column of the clicked button to the callback
function. In the callback function we write an X or an O into the button that was clicked and change
the value of the global variable player.

Correcting the problems To correct the problem about being able to change a cell that already
has something in it, we need to have a way of knowing which cells have X’s, which have O’s,
and which are empty. One way is to use a Button method to ask the button what its text is.
Another way, which we will do here is to create a new two-dimensional list, which we will call
states, that will keep track of things. Here is the code.

from tkinter import *

def callback(r,c):

global player

if player == 'X' and states[r][c] == 0:

153
b[r][c].configure(text='X')

states[r][c] = 'X'

player = 'O'

if player == 'O' and states[r][c] == 0:

b[r][c].configure(text='O')

states[r][c] = 'O'

player = 'X'
root = Tk()

states = [[0,0,0],

[0,0,0],

[0,0,0]]

b = [[0,0,0],

[0,0,0],

[0,0,0]]

for i in range(3):

for j in range(3):

b[i][j] = Button(font=('Verdana', 56), width=3, bg='yellow', command = lambda


r=i,c=j: callback(r,c))

b[i][j].grid(row = i, column = j)

player = 'X'

mainloop()

We have not added much to the program. Most of the new action happens in the callback function.
Every time someone clicks on a cell, we first check to see if it is empty (that the corresponding index
in states is 0), and if it is, we display an X or O on the screen and record the new value in states.
Many games have a variable like states that keeps track of what is on the board.

154
Checking for a winner We have a winner when there are three X’s or three O’s in a row, either
vertically, horizontally, or diagonally. To check if there are three in a row across the top row, we
can use the following if statement:

if states[0][0]==states[0][1]==states[0][2]!=0:

stop_game=True
b[0][0].configure(bg='grey')

b[0][1].configure(bg='grey')

b[0][2].configure(bg='grey')

Next, to check if there are three in a row across the middle row, change the first coordinate
from 0 to 1 in all three references, and to check if there are three in a row across the bottom,
change the 0’s to 2’s. Since we will have three very similar if statements that only differ in one
location, a for loop can be used to keep the code short:

for i in range(3):

if states[i][0]==states[i][1]==states[i][2]!=0:
b[i][0].configure(bg='grey')
b[i][1].configure(bg='grey')
b[i][2].configure(bg='grey')

stop_game = True

Next, checking for vertical winners is pretty much the same except we vary the second
coordinate instead of the first. Finally, we have two further if statements to take care of the
diagonals. The full program is at the end of this chapter. We have also added a few color options
to the configure statements to make the game look a little nicer.

Further improvements From here it would be easy to add a restart button. The callback
function for that variable should set stop_game back to false, it should set states back to all
zeroes, and it should configure all the buttons back to text='' and bg='yellow'.

To add a computer player would also not be too difficult, if you don’t mind it being a simple computer
player that moves randomly. That would take about 10 lines of code. To make an intelligent computer
player is not too difficult. Such a computer player should look for two O’s or X’s in a row in order to try
to win or block, as well avoid getting put into a no-win situation.

155
from tkinter import *

def callback(r,c):

global player

if player == 'X' and states[x][y] == 0 and stop_game==False:


b[r][c].configure(text='X', fg='blue', bg='white') states[r][c] = 'X'

player = 'O'

if player == 'O' and states[r][c] == 0 and stop_game==False:

b[r][c].configure(text='O', fg='orange', bg='black')

states[r][c] = 'O'

player = 'X'

check_for_winner()

def check_for_winner():

global stop_game

for i in range(3):

if states[i][0]==states[i][1]==states[i][2]!=0:
b[i][0].configure(bg='grey') b[i][1].configure(bg='grey')
b[i][2].configure(bg='grey')

stop_game = True
for i in range(3):

if states[0][i]==states[1][i]==states[2][i]!=0:
b[0][i].configure(bg='grey') b[1][i].configure(bg='grey')
b[2][i].configure(bg='grey')

stop_game = True

if states[0][0]==states[1][1]==states[2][2]!=0:
b[0][0].configure(bg='grey') b[1][1].configure(bg='grey')
b[2][2].configure(bg='grey')

stop_game = True

156
if states[2][0]==states[1][1]==states[0][2]!=0:
b[2][0].configure(bg='grey') b[1][1].configure(bg='grey')
b[0][2].configure(bg='grey')

stop_game = True

root = Tk()

b = [[0,0,0],

[0,0,0],
[0,0,0]]

states = [[0,0,0],
[0,0,0],

[0,0,0]]

for i in range(3):
for j in range(3):

b[i][j] = Button(font=('Verdana', 56), width=3, bg='yellow', command = lambda


r=i,c=j: callback(r,c))
b[i][j].grid(row = i, column = j)

player = 'X'
stop_game = False

mainloop()

157
Chapter 16

GUI Programming II

In this chapter we cover more basic GUI concepts.

16.1 Frames

Let’s say we want 26 small buttons across the top of the screen, and a big Ok button below
them, like below:

We try the following code:

from tkinter import *

root = Tk()

alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

buttons = [0]*26

for i in range(26):
buttons[i] = Button(text=alphabet[i])

buttons[i].grid(row=0, column=i)

158
ok_button = Button(text='Ok', font=('Verdana', 24))

ok_button.grid(row=1, column=0)

mainloop()

But we instead get the following unfortunate result:

The problem is with column 0. There are two widgets there, the A button and the Ok button,
and Tkinter will make that column big enough to handle the larger widget, the Ok button. One
solution to this problem is shown below:

ok_button.grid(row=1, column=0, columnspan=26)

Another solution to this problem is to use what is called a frame. The frame’s job is to hold other
widgets and essentially combine them into one large widget. In this case, we will create a frame
to group all of the letter buttons into one large widget. The code is shown below:

from tkinter import *


alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
root = Tk()

button_frame = Frame()
buttons = [0]*26

for i in range(26):
buttons[i] = Button(button_frame, text=alphabet[i])

buttons[i].grid(row=0, column=i)
ok_button = Button(text='Ok', font=('Verdana', 24))
button_frame.grid(row=0, column=0)
ok_button.grid(row=1, column=0)

mainloop()

To create a frame, we use Frame() and give it a name. Then, for any widgets we want include
in the frame, we include the name of the frame as the first argument in the widget’s declaration.

159
We still have to grid the widgets, but now the rows and columns will be relative to the frame.
Finally, we have to grid the frame itself.

16.2 Colors

Tkinter defines many common color names, like 'yellow' and 'red'. It also provides a way to get
access to millions of more colors. We first have to understand how colors are displayed on the
screen.

Each color is broken into three components—a red, a green, and a blue component. Each compo-
nent can have a value from 0 to 255, with 255 being the full amount of that color. Equal parts of red
and green create shades of yellow, equal parts of red and blue create shades of purple, and equal
parts of blue and green create shades of turquoise. Equal parts of all three create shades of
gray. Black is when all three components have values of 0 and white is when all three
components have values of 255.

Because the color component values run from 0 to 255, they will run from 0 to FF in hexadeci-
mal, and thus are described by two hex digits. A typical color in Tkinter is specified like this:
'#A202FF'. The color name is prefaced with a pound sign. Then the first two digits are the red
component (in this case A2, which is 162 in decimal). The next two digits specify the green compo-
nent (here 02, which is 2 in decimal), and the last two digits specify the blue component (here FF,
which is 255 in decimal). This color turns out to be a bluish violet. Here is an example of it in use:

label = Label(text='Hi', bg='#A202FF')

If you would rather not bother with hexadecimal, you can use the following function which will
convert percentages into the hex string that Tkinter uses.

def color_convert(r, g, b):

return '#{:02x}{:02x}{:02x}'.format(int(r*2.55),int(g*2.55), int(b*2.55))

Here is an example of it to create a background color that has 100% of the red component,
85% of green and 80% of blue.

label = Label(text='Hi', bg=color_convert(100, 85, 80))

16.3 Images

Labels and buttons (and other widgets) can display images instead of text.

160
To use an image requires a little set-up work. We first have to create a PhotoImage object and
give it a name. Here is an example:

cheetah_image = PhotoImage(file='cheetahs.gif')

Here are some examples of putting the image into widgets:

label = Label(image=cheetah_image)

button = Button(image=cheetah_image, command=cheetah_callback())

You can use the configure method to set or change an image:

label.configure(image=cheetah_image)

File types One unfortunate limitation of Tkinter is the only common image file type it can use
is GIF.

16.4 Canvases

A canvas is a widget on which you can draw things like lines, circles, rectangles. You can also
draw text, images, and other widgets on it. It is a very versatile widget, though we will only
describe the basics here.

Creating canvases The following line creates a canvas with a white background that is 200
200 pixels in size:

canvas = Canvas(width=200, height=200, bg='white')

Rectangles The following code draws a red rectangle to the canvas:

canvas.create_rectangle(20,100,30,150, fill='red')

See the image below on the left. The first four arguments specify the coordinates of where to
place the rectangle on the canvas. The upper left corner of the canvas is the origin, (0, 0). The
upper left of the rectangle is at (20, 100), and the lower right is at (30, 150). If were to leave off
fill='red', the result would be a rectangle with a black outline.

161
Ovals and lines Drawing ovals and lines is similar. The image above on the right is created
with the following code:
canvas.create_rectangle(20,100,70,180)

canvas.create_oval(20,100,70,180, fill='blue')

canvas.create_line(20,100,70,180, fill='green')

The rectangle is here to show that lines and ovals work similarly to rectangles. The first two
coor-dinates are the upper left and the second two are the lower right.

To get a circle with radius r and center (x,y), we can create the following function:

def create_circle(x,y,r):

canvas.create_oval(x-r,y-r,x+r,y+r)

Images We can add images to a canvas. Here is an example:

cheetah_image = PhotoImage(file='cheetahs.gif')

canvas.create_image(50,50, image=cheetah_image)

The two coordinates are where the center of the image should be.

Naming things, changing them, moving them, and deleting them We can give names to
the things we put on the canvas. We can then use the name to refer to the object in case we
want to move it or remove it from the canvas. Here is an example were we create a rectangle,
change its color, move it, and then delete it:

rect = canvas.create_rectangle(0,0,20,20)
162
canvas.itemconfigure(rect, fill='red')

canvas.coords(rect,40,40,60,60)

canvas.delete(rect)

The coords method is used to move or resize an object and the delete method is used to
delete it. If you want to delete everything from the canvas, use the following:

canvas.delete(ALL)

16.5 Check buttons and Radio buttons

In the image below, the top line shows a check button and the bottom line shows a radio button.

Check buttons The code for the above check button is:

show_totals = IntVar()

check = Checkbutton(text='Show totals', var=show_totals)

The one thing to note here is that we have to tie the check button to a variable, and it can’t be
just any variable, it has to be a special kind of Tkinter variable, called an IntVar. This variable,
show_totals, will be 0 when the check button is unchecked and 1 when it is checked. To access the
value of the variable, you need to use its get method, like this:

show_totals.get()

You can also set the value of the variable using its set method. This will automatically check or
uncheck the check button on the screen. For instance, if you want the above check button
checked at the start of the program, do the following:

show_totals = IntVar()

show_totals.set(1)
check = Checkbutton(text='Show totals', var=show_totals)
163
Radio buttons Radio buttons work similarly. The code for the radio buttons shown at the start
of the section is:

color = IntVar()

redbutton = Radiobutton(text='Red', var=color, value=1)

greenbutton = Radiobutton(text='Green', var=color, value=2)

bluebutton = Radiobutton(text='Blue', var=color, value=3)

The value of the IntVar object color will be 1, 2, or 3, depending on whether the left, middle, or
right button is selected. These values are controlled by the value option, specified when we
create the radio buttons.
Commands Both check buttons and radio buttons have a command option, where you can set
a callback function to run whenever the button is selected or unselected.

16.6 Text widget

The Text widget is a bigger, more powerful version of the Entry widget. Here is an example of
creating one:

textbox = Text(font=('Verdana', 16), height=6, width=40)

The widget will be 40 characters wide and 6 rows tall. You can still type past the sixth row; the
widget will just display only six rows at a time, and you can use the arrow keys to scroll.

If you want a scrollbar associated with the text box you can use the ScrolledText widget. Other
than the scrollbar, ScrolledText works more or less the same as Text. An example is of what it
looks like is shown below. To use the ScrolledText widget, you will need the following import:

from tkinter.scrolledtext import ScrolledText

Here are a few common commands:


164
Statement Description
textbox.get(1.0,END) returns the contents of the text box
textbox.delete(1.0,END) deletes everything in the text box
textbox.insert(END,'Hello') inserts text at the end of the text box

One nice option when declaring the Text widget is undo=True, which allows Ctrl+Z and Ctrl+Y
to undo and redo edits. There are a ton of other things you can do with the Text widget. It is
almost like a miniature word processor.

16.7 Scale widget

A Scale is a widget that you can slide back and forth to select different values. An example is
shown below, followed by the code that creates it.

scale = Scale(from_=1, to_=100, length=300, orient=' horizontal')

Here are some of the useful options of the Scale widget:

Option Description
from_ minimum value possible by dragging the scale
to_ maximum value possible by dragging the scale
Length how many pixels long the scale is
Label specify a label for the scale
showvalue='NO' gets rid of the number that displays above the scale
tickinterval=1 displays tickmarks at every unit (1 can be changed)

There are several ways for your program to interact with the scale. One way is to link it with an
IntVar just like with check buttons and radio buttons, using the variable option. Another option is to
use the scale’s get and set methods. A third way is to use the command option, which works just
like with buttons.
165
16.8 GUI Events

Often we will want our programs to do something if the user presses a certain key, drags something
on a canvas, uses the mouse wheel, etc. These things are called events.

A simple example The first GUI program we looked at back in Section 15.1 was a simple temper-
ature converter. Anytime we wanted to convert a temperature we would type in the temperature in
the entry box and click the Calculate button. It would be nice if the user could just press the enter
key after they type the temperature instead of having to click to Calculate button. We can
accomplish this by adding one line to the program:

entry.bind('<Return>', lambda dummy=0:calculate())

This line should go right after you declare the entry box. What it does is it takes the event that the
enter (return) key is pressed and binds it to the calculate function.

Well, sort of. The function you bind the event to is supposed to be able to receive a copy of an Event
object, but the calculate function that we had previously written takes no arguments. Rather than rewrite
the function, the line above uses lambda trick to essentially throw away the Event object.

Common events Here is a list of some common events:

Event Description
<Button-1> The left mouse button is clicked.
<Double-Button-1> The left mouse button is double-clicked.
<Button-Release-1> The left mouse button is released.
<B1-Motion> A click-and-drag with the left mouse button.
<MouseWheel> The mouse wheel is moved.
<Motion> The mouse is moved.
<Enter> The mouse is now over the widget.
<Leave> The mouse has now left the widget.
<Key> A key is pressed.
<key name> The key name key is pressed.

For all of the mouse button examples, the number 1 can be replaced with other numbers.
Button 2 is the middle button and button 3 is the right button.

The most useful attributes in the Event object are:

166
Attribute Description

keysym The name of the key that was pressed

x, y The coordinates of the mouse pointer

delta The value of the mouse wheel

Key events For key events, you can either have specific callbacks for different keys or catch
all keypresses and deal with them in the same callback. Here is an example of the latter:

from tkinter import *


def callback(event):
print(event.keysym)

root = Tk()
root.bind('<Key>', callback)

mainloop()

The above program prints out the names of the keys that were pressed. You can use those
names in if statements to handle several different keypresses in the callback function, like
below:

if event.keysym == 'percent':

# percent (shift+5) was pressed, do something about it...

elif event.keysym == 'a':

# lowercase a was pressed, do something about it...

Use the single callback method if you are catching a lot of keypresses and are doing something
similar with all of them. On the other hand, if you just want to catch a couple of specific
keypresses or if certain keys have very long and specific callbacks, you can catch keypresses
separately like below:

from tkinter import * def callback1(event):


print('You pressed the enter key.')

def callback2(event):
print('You pressed the up arrow.')

root = Tk()

167
root.bind('<Return>', callback1)
root.bind('<Up>', callback2)
mainloop()

The key names are the same as the names stored in the keysym attribute. You can use the
program from earlier in this section to find the names of all the keys. Here are the names for a
few common keys:
Most printable keys can be captured with their names, like below:

root.bind('a', callback)

root.bind('A', callback)

root.bind('-', callback)

The exceptions are the spacebar (<Space>) and the less than sign (<Less>). You can also catch
key combinations, such as <Shift-F5>, <Control-Next>, <Alt-2>, or <Control-Shift-F1>.
Note These examples all bind keypresses to root, which is our name for the main window. You
can also bind keypresses to specific widgets. For instance, if you only want the left arrow key
to work on a Canvas called canvas, you could use the following:

canvas.bind(<Left>, callback)

One trick here, though, is that the canvas won’t recognize the keypress unless it has the GUI’s focus.

This can be done as below:

canvas.focus_set()

16.9 Event Examples

Example 1 Key Event

Here is an example where the user can move a rectangle with the left or right arrow keys.

from tkinter import *

def callback(event):
global move
if event.keysym=='Right':

168
move += 1
elif event.keysym=='Left':
move -=1
canvas.coords(rect,50+move,50,100+move,100)
root = Tk()
root.bind('<Key>', callback)
canvas = Canvas(width=200,height=200)
canvas.grid(row=0,column=0)
rect = canvas.create_rectangle(50,50,100,100,fill='blue')
move = 0
mainloop()

Example 2 Mouse Event Example

import tkinter as tk

def draw(event):

x, y = event.x, event.y

canvas.create_oval(x, y, x+5, y+5, fill="red")

root = tk.Tk()

root.title("Simple Paint")

root.geometry("500x400")

canvas = tk.Canvas(root, bg="white", width=500, height=400)

canvas.pack()

canvas.bind("<B1-Motion>", draw)

root.mainloop()

169
Output:

Example 2 Here is an example program demonstrating mouse events. The program starts by
drawing a rectangle to the screen. The user can do the following:

• Drag the rectangle with the mouse (<B1_Motion>).

• Resize the rectangle with the mouse wheel (<MouseWheel>).

• Whenever the user left-clicks, the rectangle will change colors (<Button-1>).

• Anytime the mouse is moved, the current coordinates of the mouse are displayed in a
label (<Motion>).

Here is the code for the program:

from tkinter import * def mouse_motion_event(event):

label.configure(text='({}, {})'.format(event.x, event.y))

def wheel_event(event):

global x1, x2, y1, y2

if event.delta>0:

diff = 1

elif event.delta<0:

diff = -1

x1+=diff

170
x2-=diff

y1+=diff

y2-=diff

canvas.coords(rect,x1,y1,x2,y2)

def b1_event(event):

global color

if not b1_drag:

color = 'Red' if color=='Blue' else 'Blue'


canvas.itemconfigure(rect, fill=color)

def b1_motion_event(event):global b1_drag, x1, x2, y1, y2, mouse_x, mouse_y

x = event.x

y = event.y

if not b1_drag:

mouse_x = x

mouse_y = y

b1_drag = True

return

x1+=(x-mouse_x)

x2+=(x-mouse_x)

y1+=(y-mouse_y)

y2+=(y-mouse_y)

canvas.coords(rect,x1,y1,x2,y2)

mouse_x = x

mouse_y = y
def b1_release_event(event):
global b1_drag

b1_drag = False

171
root=Tk()

label = Label()

canvas = Canvas(width=200, height=200)

canvas.bind('<Motion>', mouse_motion_event)
canvas.bind('<ButtonPress-1>', b1_event)

canvas.bind('<B1-Motion>', b1_motion_event)
canvas.bind('<ButtonRelease-1>', b1_release_event)

canvas.bind('<MouseWheel>', wheel_event)
canvas.focus_set()

canvas.grid(row=0, column=0)

label.grid(row=1, column=0)

mouse_x = 0

mouse_y = 0
b1_drag = False

x1 = y1 = 50

x2 = y2 = 100
color = 'blue'

rect = canvas.create_rectangle(x1,y1,x2,y2,fill=color)

mainloop()

Here are a few notes about how the program works:

172
1. First, every time the mouse is moved over the canvas, the mouse_motion_event function
is called. This function prints the mouse’s current coordinates which are contained in the
Event attributes x and y.

2. The wheel_event function is called whenever the user uses the mouse (scrolling) wheel.
The Event attribute delta contains information about how quickly and in what direction the
wheel was moved. We just stretch or shrink the rectangle based on whether the wheel
was moved forward or backward.

3. The b1_event function is called whenever the user presses the left mouse button. The
func-tion changes the color of the rectangle whenever the rectangle is clicked. There is a
global variable here called b1_drag that is important. It is set to True whenever the user
is dragging the rectangle. When dragging is going on, the left mouse button is down and
the b1_event function is continuously being called. We don’t want to keep changing the
color of the rect-angle in that case, hence the if statement.

4. The dragging is accomplished mostly in the b1_motion_event function, which is called


whenever the left mouse button is down and the mouse is being moved. It uses global
vari-ables that keep track of what the mouse’s position was the last time the function was
called, and then moves the rectangle according to the difference between the new and
old position.
5. The focus_set method is needed because the canvas will not recognize the mouse
wheel events unless the focus is on the canvas.

6. One problem with this program is that the user can modify the rectangle by clicking
anywhere on the canvas, not just on rectangle itself. If we only want the changes to
happen when the mouse is over the rectangle, we could specifically bind the rectangle
instead of the whole canvas, like below:

canvas.tag_bind(rect, '<B1-Motion>', b1_motion_event)

7. Finally, the use of global variables here is a little messy. If this were part of a larger
project, it might make sense to wrap all of this up into a class.

Example 3 To-Do List

import tkinter as tk
from tkinter import messagebox
def add_task():

task = entry.get()

173
if task:
listbox.insert(tk.END, task)
entry.delete(0, tk.END)

else:
messagebox.showwarning("Warning", "Task cannot be empty!")

def remove_task():
try:

selected = listbox.curselection()[0]
listbox.delete(selected)
except IndexError:
messagebox.showwarning("Warning", "Select a task to delete!")

root = tk.Tk()

root.title("To-Do List")
root.geometry("300x350")

entry = tk.Entry(root, width=30)


entry.pack(pady=10)

entry.focus_set()
add_button = tk.Button(root, text="Add Task", command=add_task)
add_button.pack()
listbox = tk.Listbox(root, width=40, height=10)
listbox.pack()

remove_button = tk.Button(root, text="Remove Task", command=remove_task)


remove_button.pack(pady=5)
root.mainloop()

Output:
174
Explanation

 User types a task and clicks "Add Task".


 Task appears in the list.
 Clicking "Remove Task" deletes the selected task.
Expected Output

 A text entry box, Add Task button, and Remove Task button.
 Tasks appear in a listbox.

Example 4 Digital Clock

import tkinter as tk

from time import strftime

def update_time():

time_string = strftime('%H:%M:%S %p')

label.config(text=time_string)

label.after(1000, update_time)

175
root = tk.Tk()

root.title("Digital Clock")

root.geometry("300x150")

label = tk.Label(root, font=('Arial', 40), fg='red', bg='black')

label.pack(pady=20)

update_time()

root.mainloop()

Output:

Explanation

 Updates the current time every second.


Expected Output

 A digital clock displaying HH:MM:SS AM/PM.

Example 5 Login Form

import tkinter as tk

from tkinter import messagebox

176
def login():

user = entry_user.get()

password = entry_pass.get()

if user == "admin" and password == "1234":

messagebox.showinfo("Login Success", "Welcome!")

else:

messagebox.showerror("Error", "Invalid username or password!")

root = tk.Tk()

root.title("Login System")

root.geometry("300x200")

tk.Label(root, text="Username:").pack(pady=5)

entry_user = tk.Entry(root)

entry_user.pack()

tk.Label(root, text="Password:").pack(pady=5)

entry_pass = tk.Entry(root, show="*")

entry_pass.pack()

button = tk.Button(root, text="Login", command=login)

button.pack(pady=10)

root.mainloop()

Output:

177
Explanation

 Valid credentials show "Login Success!"


 Invalid credentials show "Error: Invalid username or password!"
Expected Output

 Username: admin, Password: 1234 → Login Success!


 Wrong input → Error message

Example 6 Countdown Timer

import tkinter as tk

def start_timer():

time_left = int(entry.get())

#print(time_left)

def countdown():

nonlocal time_left

if time_left > 0:

label.config(text=f"Time Left: {time_left}s")

time_left -= 1

root.after(1000, countdown)

else:

label.config(text="Time's up!")

countdown()
178
root = tk.Tk()

root.title("Countdown Timer")

root.geometry("300x200")

tk.Label(root, text="Enter Seconds:").pack()

entry = tk.Entry(root)

entry.pack()

button = tk.Button(root, text="Start", command=start_timer)

button.pack(pady=5)

label = tk.Label(root, text="")

label.pack()

root.mainloop()

Output:

179
Explanation

 User enters seconds and clicks Start.


 Counts down to 0.
Expected Output

 Input "10", timer shows:


o "Time Left: 10s"
o "Time Left: 9s"

o …
o "Time's up!"

180
Chapter 17

GUI Programming III


This chapter contains a few more GUI odds and ends.

17.1 Title bar

The GUI window that Tkinter creates says Tk by default. Here is how to change it:

root.title('Your title')

17.2 Disabling things

Sometimes you want to disable a button so it can’t be clicked. Buttons have an attribute state
that allows you to disable the widget. Use state=DISABLED to disable the button and
state=NORMAL to enable it. Here is an example that creates a button that starts out disabled
and then enables it:

button = Button(text='Hi', state=DISABLED, command=function)

button.configure(state=NORMAL)

You can use the state attribute to disable many other types of widgets, too.

17.3 Getting the state of a widget

Sometimes, you need to know things about a widget, like exactly what text is in it or what its
background color is. The cget method is used for this. For example, the following gets the text
of a label called label:

label.cget('text')
181
This can be used with buttons, canvases, etc., and it can be used with any of their properties,
like bg, fg, state, etc. As a shortcut, Tkinter overrides the [] operators, so that label['text']
accomplishes the same thing as the example above.

17.4 Message boxes

Message boxes are windows that pop up to ask you a question or say something and then go away.

To use them, we need an import statement:

from tkinter.messagebox import *

There are a variety of different types of message boxes. For each of them you can specify the
message the user will see as well as the title of the message box. Here are three types of
message boxes, followed by the code that generates them:

showinfo(title='Message for you', message='Hi There! ')

askquestion(title='Quit?', message='Do you really want to quit?')

showwarning(title='Warning', message='Unsupported format')

Below is a list of all the types of message boxes. Each displays a message in its own way.

Message Box Special properties


showinfo OK button
askokcancel OK and Cancel buttons
askquestion Yes and No buttons
askretrycancel Retry and a Cancel buttons
askyesnocancel Yes, No, and Cancel buttons
Showerror An error icon and an OK button
Showwarning A warning icon and an OK button

Each of these functions returns a value indicating what the user clicked. See the next section
for a simple example of using the return value. Here is a table of the return values:
182
Function Return value (based on what user clicks)

Showinfo Always returns 'ok'

Askokcancel OK—True Cancel or window closed—False

Askquestion Yes—'yes' No—'no'

Askretrycancel Retry—True Cancel or window closed—False

askyesnocancel Yes—True No—False anything else—None

Showerror Always returns 'ok'

Showwarning Always returns 'ok'

17.5 Destroying things

To get rid of a widget, use its destroy method. For instance, to get rid of a button called button,
do the following:

button.destroy()

To get rid of the entire GUI window, use the following:

root.destroy()

Stopping a window from being closed When your user tries to close the main window, you
may want to do something, like ask them if they really want to quit. Here is a way to do that:

from tkinter import *


from tkinter.messagebox import askquestion
def quitter_function():
answer = askquestion(title='Quit?', message='Really quit?' )

if answer==' yes':
root.destroy()

root = Tk()
root.protocol('WM_DELETE_WINDOW ', quitter_function)
mainloop()

183
The key is the following line, which cause quitter_function to be called whenever the user tries
to close the window.

root.protocol('WM_DELETE_WINDOW ', quitter_function)

17.6 Updating

Tkinter updates the screen every so often, but sometimes that is not often enough. For instance, in
a function triggered by a button press, Tkinter will not update the screen until the function is done.

If, in that function, you want to change something on the screen, pause for a short while, and
then change something else, you will need to tell Tkinter to update the screen before the pause.
To do that, just use this:
root.update()

If you only want to update a certain widget, and nothing else, you can use the update method
of that widget. For example,
canvas.update()

A related thing that is occasionally useful is to have something happen after a scheduled time
interval. For instance, you might have a timer in your program. For this, you can use the after method.
Its first argument is the time in milliseconds to wait before updating and the second argument is the
function to call when the time is right. Here is an example that implements a timer:

from time import time

from tkinter import *

def update_timer():

time_left = int(90 - (time()-start))


minutes = time_left // 60

seconds = time_left % 60

time_label.configure(text='{}:{:02d}'.format(minutes, seconds))

root.after(100, update_timer)

root = Tk()

time_label = Label()

time_label.grid(row=0, column=0)

start = time()

update_timer()
mainloop()

184
17.7 Dialogs

Many programs have dialog boxes that allow the user to pick a file to open or to save a file.
To use them in Tkinter, we need the following import statement:

from tkinter.filedialog import *

Tkinter dialogs usually look like the ones that are native to the operating system.

Here are the most useful dialogs:

Dialog Description
askopenfilename Opens a typical file chooser dialog
askopenfilenames Like previous, but user can pick more than one file
asksaveasfilename Opens a typical file save dialog
askdirectory Opens a directory chooser dialog

The return value of askopenfilename and asksaveasfilename is the name of the file selected.
There is no return value if the user does not pick a value. The return value of askopenfilenames
is a list of files, which is empty if no files are selected. The askdirectory function returns the
name of the directory chosen.
There are some options you can pass to these functions. You can set initialdir to the directory
you want the dialog to start in. You can also specify the file types. Here is an example:

filename=askopenfilename(initialdir='c:\\python31\\',

filetypes=[(' Image files', '.jpg .png .gif'),

('All files', '*')])

185
A short example Here is an example that opens a file dialog that allows you to select a text file.

The program then displays the contents of the file in a textbox.

from tkinter import *


from tkinter.filedialog import *

from tkinter.scrolledtext import ScrolledText

root = Tk()

textbox = ScrolledText()

textbox.grid()

filename=askopenfilename(initialdir='c:\\python31\\', filetypes=[('Text files',


'.txt'),

('All files', '*')])

s = open(filename).read()
textbox.insert(1.0, s)

mainloop()

17.8 Menu bars

We can create a menu bar, like the one below, across the top of a window.

Here is an example that uses some of the dialogs from the previous section:

from tkinter import *


from tkinter.filedialog import *

def open_callback():

filename = askopenfilename()
186
# add code here to do something with filename

def saveas_callback():

filename = asksaveasfilename()

# add code here to do something with filename

root = Tk()

menu = Menu()
root.config(menu=menu)

file_menu = Menu(menu, tearoff=0)

file_menu.add_command(label='Open', command=open_callback)

file_menu.add_command(label='Save as', command=saveas_callback)


file_menu.add_separator()

file_menu.add_command(label='Exit', command=root.destroy)

menu.add_cascade(label='File', menu=file_menu)

mainloop()

17.9 New windows

Creating a new window is easy. Use the Toplevel function:

window = Toplevel()

You can add widgets to the new window. The first argument when you create the widget needs
to be the name of the window, like below

new_window = Toplevel()

label = Label(new_window, text='Hi')

label.grid(row=0, column=0)

17.10 pack

187
There is an alternative to grid called pack. It is not as versatile as grid, but there are some places
where it is useful. It uses an argument called side, which allows you to specify four locations for
your widgets: TOP, BOTTOM, LEFT, and RIGHT. There are two useful optional arguments, fill
and expand. Here is an example.

button1=Button(text='Hi')

button1.pack(side=TOP, fill=X)

button2=Button(text='Hi')

button2.pack(side=BOTTOM)

The fill option causes the widget to fill up the available space given to it. It can be either X, Y or
BOTH. The expand option is used to allow the widget to expand when its window is resized. To
enable it, use expand=YES.

Note You can use pack for some frames, and grid for others; just don’t mix pack and grid within
the same frame, or Tkinter won’t know quite what to do.

17.11 StringVar

In Section 16.5 we saw how to tie a Tkinter variable, called an IntVar, to a check button or a
radio button. Tkinter has another type of variable called a StringVar that holds strings. This type
of variable can be used to change the text in a label or a button or in some other widgets. We
already know how to change text using the configure method, and a StringVar provides another
way to do it.
To tie a widget to a StringVar, use the textvariable option of the widget. A StringVar has get and
set methods, just like an IntVar, and whenever you set the variable, any widgets that are tied to it
are automatically updated.

Here is a simple example that ties two labels to the same StringVar. There is also a button that
when clicked will alternate the value of the StringVar (and hence the text in the labels).

from tkinter import *


def callback():

global count

s.set('Goodbye' if count%2==0 else 'Hello')

count +=1

188
root = Tk()

count = 0

s = StringVar()

s.set('Hello')

label1 = Label(textvariable = s, width=10)

label2 = Label(textvariable = s, width=10)


button = Button(text = 'Click me', command = callback)

label1.grid(row=0, column=0)

label2.grid(row=0, column=1)
button.grid(row=1, column=0)

mainloop()

189
Chapter 18

Database Connectivity in Python


Python being a high-level language provides support for various databases. We can connect
and run queries for a particular database using Python.
MySQL is a Relational Database Management System (RDBMS) whereas the structured
Query Language (SQL) is the language used for handling the RDBMS using CRUD commands
i.e Creating, Reading, Updating and Deleting the data from the databases.

18.1 To install MySQL on Windows, you can:

1. Go to the MySQL website


2. Click Downloads
3. Select MySQL Installer for Windows
4. Choose the installer and click Download
5. Open the installer
6. Click Yes when prompted for permission
7. Choose the setup type
8. Select the products to install
9. Click Next
10. Click Execute to download and install the products
11. Click Next again
12. Configure the products
13. Click Next again
14. Enter the root account password and click Check
15. Click Execute to apply the configuration
16. Click Finish

Let's create a Tkinter application that performs CRUD (Create, Read, Update, Delete)
operations using MySQL.

190
18.2 Features of this Application

✅ Create: Add new records to the database


✅ Read: Display all records from the database
✅ Update: Modify existing records
✅ Delete: Remove records

18.3 Steps to Set Up


Install Required Modules

Step 1 : Go to Command Prompt (cmd)


Step 2 : Run as Administrator
Step 3 : Go to Python Script path as shown below
C:\>cd C:\Users\rhyth\AppData\Local\Programs\Python\Python312\Scripts
Step 4 : Write the command
pip install mysql_connector

MySQL installed successfully.

191
18.4 Tkinter + MySQL CRUD Application

Create MySQL Database and Table

Before running the Python code, create a MySQL database and table.

CREATE DATABASE student_db;


USE student_db;

CREATE TABLE students (


id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
age INT,
course VARCHAR(100));

Create Python Program

import tkinter as tk
from tkinter import ttk, messagebox
import mysql.connector

# Database Connection
def connect_db():
return mysql.connector.connect(
host="localhost",
user="root", # Change if needed
password="", # Change if needed
database="student_db"
)

# Function to Fetch Records


def fetch_records():
conn = connect_db()
cursor = conn.cursor()
cursor.execute("SELECT * FROM students")
rows = cursor.fetchall()
192
conn.close()

tree.delete(*tree.get_children()) # Clear existing data


for row in rows:
tree.insert("", "end", values=row)

# Function to Add Student


def add_student():
name = entry_name.get()
age = entry_age.get()
course = entry_course.get()

if name and age and course:


conn = connect_db()
cursor = conn.cursor()
cursor.execute("INSERT INTO students (name, age, course) VALUES (%s, %s, %s)", (name,
age, course))
conn.commit()
conn.close()
fetch_records()
entry_name.delete(0, tk.END)
entry_age.delete(0, tk.END)
entry_course.delete(0, tk.END)
else:
messagebox.showwarning("Warning", "All fields are required!")

# Function to Update Student


def update_student():
selected = tree.selection()
if not selected:
messagebox.showwarning("Warning", "Select a record to update!")
return

item = tree.item(selected[0])
student_id = item['values'][0]
new_name = entry_name.get()
new_age = entry_age.get()
new_course = entry_course.get()
193
if new_name and new_age and new_course:
conn = connect_db()
cursor = conn.cursor()
cursor.execute("UPDATE students SET name=%s, age=%s, course=%s WHERE id=%s",
(new_name, new_age, new_course, student_id))
conn.commit()
conn.close()
fetch_records()
else:
messagebox.showwarning("Warning", "All fields are required!")

# Function to Delete Student


def delete_student():
selected = tree.selection()
if not selected:
messagebox.showwarning("Warning", "Select a record to delete!")
return

item = tree.item(selected[0])
student_id = item['values'][0]

conn = connect_db()
cursor = conn.cursor()
cursor.execute("DELETE FROM students WHERE id=%s", (student_id,))
conn.commit()
conn.close()
fetch_records()

# GUI Setup
root = tk.Tk()
root.title("Student Management System")
root.geometry("600x400")

# Input Fields
tk.Label(root, text="Name:").grid(row=0, column=0, padx=10, pady=5)
entry_name = tk.Entry(root)
entry_name.grid(row=0, column=1, padx=10, pady=5)
194
tk.Label(root, text="Age:").grid(row=1, column=0, padx=10, pady=5)
entry_age = tk.Entry(root)
entry_age.grid(row=1, column=1, padx=10, pady=5)

tk.Label(root, text="Course:").grid(row=2, column=0, padx=10, pady=5)


entry_course = tk.Entry(root)
entry_course.grid(row=2, column=1, padx=10, pady=5)

# Buttons
tk.Button(root, text="Add Student", command=add_student).grid(row=0, column=2, padx=10)
tk.Button(root, text="Update Student", command=update_student).grid(row=1, column=2, padx=10)
tk.Button(root, text="Delete Student", command=delete_student).grid(row=2, column=2, padx=10)

# Data Table
columns = ("ID", "Name", "Age", "Course")
tree = ttk.Treeview(root, columns=columns, show="headings")
for col in columns:
tree.heading(col, text=col)
tree.column(col, width=100)

tree.grid(row=3, column=0, columnspan=3, padx=10, pady=10)


fetch_records()

root.mainloop()

Explanation of above example

1️. Database Connection

The connect_db() function establishes a connection to the MySQL database.


2️. Fetch Records

The fetch_records() function retrieves all records from the students table and displays them in the
Treeview widget.
3️. Add Student

The add_student() function inserts a new record into the database.

195
4️. Update Student

The update_student() function updates an existing record selected in the Treeview.


5️. Delete Student

The delete_student() function removes a selected record.

6️. Tkinter UI

Uses Entry widgets for input fields.

Uses Treeview to display database records.

Expected Output

1. Initial Screen

An empty table with column headers: ID | Name | Age | Course.

After Adding a Student

Enter Name, Age, and Course → Click "Add Student" → The student appears in the table.

Updating a Student

Select a student, modify the fields, and click "Update Student".

Deleting a Student

Select a student and click "Delete Student".

196
18.5 Multiple Document Interface(MDI) Project

✅ Login system (validated from MySQL table)

✅ MDI Parent Form (Main Menu always visible)

✅ Multiple Forms for:

 Item Details
 Purchase
 Reports

✅ CRUD Operations (Data stored in different tables)

✅ Validations on all forms

Steps to Implement
1️. Create MySQL Tables
2️. Build Login Form
3️. Create MDI Parent Window (Main Menu always visible)
4️. Create Connected Forms for each module
5️. Implement Validation & CRUD Operations

197
1️. Create MySQL Tables

Before writing Python code, create these tables in MySQL:

CREATE DATABASE inventory_db;

USE inventory_db;

CREATE TABLE users (


id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE,
password VARCHAR(50)
);

CREATE TABLE items (


id INT AUTO_INCREMENT PRIMARY KEY,
item_name VARCHAR(100),
price DECIMAL(10,2),
stock INT
);

CREATE TABLE purchase (


id INT AUTO_INCREMENT PRIMARY KEY,
item_name VARCHAR(100),
quantity INT,
total_price DECIMAL(10,2),
);

198
2️. Tkinter Login Form (Authentication)

import tkinter as tk
from tkinter import messagebox
import mysql.connector

# Database Connection
def connect_db():
return mysql.connector.connect(
host="localhost",
user="root",
password="",
database="inventory_db"
)

# Function to validate login


def login():
username = entry_user.get()
password = entry_pass.get()

conn = connect_db()
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE username=%s AND password=%s", (username,
password))
user = cursor.fetchone()
conn.close()

if user:
root.destroy()
open_main_menu()
else:
messagebox.showerror("Error", "Invalid Username or Password")

# Login Form UI
root = tk.Tk()
root.title("Login")
root.geometry("300x200")
199
tk.Label(root, text="Username:").pack()
entry_user = tk.Entry(root)
entry_user.pack()

tk.Label(root, text="Password:").pack()
entry_pass = tk.Entry(root, show="*")
entry_pass.pack()

tk.Button(root, text="Login", command=login).pack()


root.mainloop()

Output:

3️. MDI Parent Window (Main Menu)

The menu remains open and loads child forms.

def open_main_menu():
menu = tk.Tk()
menu.title("Inventory Management System (MDI)")
menu.geometry("600x400")

def open_form(form_name):
if form_name == "item_details":
item_details()
elif form_name == "purchase":

200
purchase_form()
elif form_name == "reports":
reports_form()

# Menu Buttons
tk.Button(menu, text="Item Details", command=lambda: open_form("item_details")).pack()
tk.Button(menu, text="Purchase", command=lambda: open_form("purchase")).pack()
tk.Button(menu, text="Sale", command=lambda: open_form("sale")).pack()
tk.Button(menu, text="Payment", command=lambda: open_form("payment")).pack()
tk.Button(menu, text="Receive", command=lambda: open_form("receive")).pack()
tk.Button(menu, text="Reports", command=lambda: open_form("reports")).pack()

menu.mainloop()

Output:

4️. CRUD Forms

(A) Item Details Form

def item_details():
item_win = tk.Toplevel()
item_win.title("Item Details")

def add_item():
name = entry_name.get()
price = entry_price.get()
stock = entry_stock.get()

201
if name and price and stock:
conn = connect_db()
cursor = conn.cursor()
cursor.execute("INSERT INTO items (item_name, price, stock) VALUES (%s, %s, %s)",
(name, price, stock))
conn.commit()
conn.close()
messagebox.showinfo("Success", "Purchase added successfully!")
item_win.destroy()
else:
messagebox.showwarning("Warning", "All fields are required!")

tk.Label(item_win, text="Item Name:").pack()


entry_name = tk.Entry(item_win)
entry_name.pack()

tk.Label(item_win, text="Price:").pack()
entry_price = tk.Entry(item_win)
entry_price.pack()

tk.Label(item_win, text="Stock:").pack()
entry_stock = tk.Entry(item_win)
entry_stock.pack()

tk.Button(item_win, text="Add Item", command=add_item).pack()

Output:

202
(B) Purchase Form

def purchase_form():
purchase_win = tk.Toplevel()
purchase_win.title("Purchase Form")

tk.Label(purchase_win, text="Item Name:").pack()


entry_item_name = tk.Entry(purchase_win)
entry_item_name.pack()

tk.Label(purchase_win, text="Quantity:").pack()
entry_quantity = tk.Entry(purchase_win)
entry_quantity.pack()

def purchase_item():
item_name = entry_item_name.get()
quantity = entry_quantity.get()

if item_name and quantity:


conn = connect_db()
cursor = conn.cursor()
cursor.execute("INSERT INTO purchase (item_name, quantity, total_price) VALUES (%s, %s,
%s)", (item_name, quantity, 0)) # Total price can be calculated later
conn.commit()

203
conn.close()
messagebox.showinfo("Success", "Purchase added successfully!")
purchase_win.destroy()
else:
messagebox.showwarning("Warning", "All fields are required!")

tk.Button(purchase_win, text="Purchase", command=purchase_item).pack()

Output:

5️. Reports Form (Display All Records)

def reports_form():
report_win = tk.Toplevel()
report_win.title("Reports")

tree = ttk.Treeview(report_win, columns=("ID", "Item Name", "Price", "Stock"), show="headings")


for col in ("ID", "Item Name", "Price", "Stock"):
tree.heading(col, text=col)
tree.column(col, width=100)
tree.pack()

def load_data():

204
conn = connect_db()
cursor = conn.cursor()
cursor.execute("SELECT * FROM items")
rows = cursor.fetchall()
conn.close()

tree.delete(*tree.get_children())
for row in rows:
tree.insert("", "end", values=row)

tk.Button(report_win, text="Load Data", command=load_data).pack()

Output:

205
🔹 Summary

✅ Login Form → Authenticates user


✅ MDI Parent Form → Menu always visible
✅ CRUD Forms → Handles data entry
✅ Report Form → Displays stored data

206

You might also like