IT 116: Introduction to Scripting
Class 12
Tips and Examples
Review
New Material
Studying
Microphone
Homework 6
I have posted homework 6
here.
It is due this coming Sunday at 11:59 PM.
Quiz 4
Let's look at the answers to
Quiz 4.
Midterm
The Midterm exam for this course will be held on Tuesday,
October 22nd.
The exam will be given in this room.
It will consist of questions like those on the quizzes along with questions
asking you to write short segments of Python code.
60% of the points on this exam will consist of questions from the Weekly
Graded Quizzes.
There is a link to the answers to the graded quizze on the class web page.
There will be 15 of these questions, worth 4 points each.
The other 40% of points will come from four questions that ask you to write a short
segment of code.
There will be 4 of these questions worth 10 points each.
To study for the code questions you should be able to
- Write an
if
/elif
/else
statement
- Write a
while
loop
- Write a
for
loop using range
- Write a function that does not return a value
A good way to study for the code questions is to review the Class Exercises
and homework solutions.
The last class before the exam, Thursday, October 17th, will be a review session.
You will only be responsible for the material in the Class Notes for that class
on the exam.
You will find the Midterm review Class Notes
here.
If for some reason you cannot take the exam on the date mentioned above
you must contact me to make alternate arrangements.
The Midterm is given on paper.
I scan each exam paper and upload the scans to Gradescope.
I score the exam on Gradescope.
You will get an email from Gradescope with your score when I am done.
The Midterm is a closed book exam.
You are not allowed to use any resource other than what is in your head,
while taking the exam.
Cheating on the exam will result in a score of 0 and will be reported to the Administration.
Remember your Oath of Honesty.
To prevent cheating, certain rules
will be enforced during the exam.
Remember, the Midterm and Final determine 50% of your grade.
Questions
Are there any questions before I begin?
Tips and Examples
Studying for the Midterm with Flashcards
- 60% of the point on the Midterm come from Class Quiz Questions
- You can use the flashcards you created for these questions when
studying for the Midterm
- But not all Class Quiz Questions will appear on the Midterm
- If the flashcard question covers a topic not in the Midterm Review ...
- you do not have to study it for the exam
- You should remove these flashcards from your collection
Additional Rules for Homework Scripts Using Functions
- I have added some additional rule for homework assignments ...
- when the scripts contain functions
- Let's take a look at the
rules
The pass
Statement
- Python has a special statement used when defining functions
- The statement is
pass
- This statement does nothing
- But it is a legal Python statement
- It is used as a
placeholder
- Whenever you write a
function header
it must be followed by a
code block ...
- or you will get an error
- If you follow the header with the single statement
pass
...
- the Python interpreter will not complain
- Why does Python have this statement?
- Sometimes when you are writing code you know you will need a function
- You may not be ready at that point to write the function
- But you are writing code that calls this new function
- With
pass
you can write the function header ...
- and use
pass
as the only statement in the code block
- Now you can test the code you are working on ...
- with the call to the new function ...
- and Python will not give you an error
- You will need to use
pass
in this week's homework assignment ...
- if you follow my suggestions
Review
Calculation a Running Total
- A total that is updated as new numbers are encountered
is called a running total
- A good example of a running total is a bank balance
- Your bank balance is the running total
of all deposits and withdrawals from your account
- In programming, running totals are computed using two features
- A variable that holds the total, called the
accumulator ...
- and a loop in which new numbers are added to the accumulator
- Before you enter the loop, the accumulator must be set to 0
- Running totals are used when you calculate averages
$ cat average.py
# this program asks the user how many numbers
# they have to enter, then performs a running
# total and computes the average
entries = int(input("How many entries? "))
total = 0
for entry_no in range(entries):
number = int(input("number: "))
total += number
average = total / entries
print("Average", average)
$ python3 average.py
How many entries?
number: 10
number: 9
number: 8
number: 7
number: 6
number: 5
number: 4
number: 3
number: 2
number: 1
Average 5.5
The entries in blue are user input
Augmented Assignment Operators
- In programming, we often have to change the value of a variable by some amount
- If we wanted to add 1 to the variable number we
could write
number = number + 1
- Statements like this are quite common
- So most computer languages have a special operator ...
- that you can use for such situations
- Instead of writing the statement above we could write
number += 1
- This operator works as follows
- Get the current value of the variable on the left
- Get the current value of the expression on the right
- Add the two values
- Assign this new value to the variable
- Using this operator makes the code shorter
- Which reduces the risk of errors
- An operator like this is called an
augmented assignment operator
- Because it does more than assign a value to a variable
- Python has an augmented assignment operator for every arithmetic operator
Operator | Example | Equivalent To |
+= |
num += 5 |
num = num + 5 |
-= |
num -= 5 |
num = num - 5 |
*= |
num *= 5 |
num = num * 5 |
/= |
num /= 5 |
num = num / 5 |
//= |
num //= 5 |
num = num // 5 |
%= |
num %= 5 |
num = num % 5 |
**= |
num **= 5 |
num = num ** 5 |
Functions
- A function
is a group of statements that has a name ...
- and performs a specific task
- The Python interpreter has a number of functions that you can use ...
- without having to do anything special
- They are called
built-in functions
- They are defined inside the Python interpreter
- So you can use them at any time
- You can also define your own Python functions
- Most Python scripts contain a number of function definitions
- But some function are so useful you will want to use them in many scripts
- You should define such functions in separate Python files called
modules
- These files do not do anything by themselves
- They just contain functions that can be used in other scripts
- To use the module functions in a script ...
- you need a special Python statement the top
- It is an import statement and has the following form
import MODULE_NAME
- The module name is the filename without the .py extension
- This statement tell the interpreter to load the module functions into RAM ...
- so your script can use them
- You have to let the interpreter know where to find your modules
- On Mac and Unix you do this by setting the
PYTHONPATH system variable
- This variable tells the interpreter where to look for the modules you use
Two Types of Functions
- There are two types of functions
- Functions that return a value
- Functions that do not return a value
- The textbook calls the second type of function a
void function
- The conversion functions
str
, int
and
float
return a value
- But
print
does not
- It causes something to be printed
- But it does not return a value
Function Names
Defining a Function
Calling a Function
- To run a function run you write a
function call
- A function call has two parts
- The function name
- A list of arguments enclosed in parentheses
- You must follow the function name with parentheses ...
- even if the function takes no arguments
- The Python interpreter runs through a script statement by statement
- After a statement is processed, the interpreter forgets all about it
- Functions must be defined before they are used
- Otherwise the interpreter will not know what to do when they are called
- When the interpreter comes to function definition, it stores it ...
- in a special part of RAM
- It retrieves this definition when the function is called
- The function ends when the last statement in the code block is run
- Then the interpreter returns to the line in the script ...
- where the function was called
Attendance
New Material
How the Python Interpreter Runs a Script
- Here is a script that defines the function
print_umb_address ...
- and calls this function
$ cat -n umb.py
1 # this program contains a function that
2 # prints the address of our campus
3
4 # prints the address of UMB
5 def print_umb_address():
6 print("University of Massachusetts at Boston")
7 print("100 Morrissey Boulevard")
8 print("Boston, Massachusetts 02125-3393")
9
10 print("I teach at UMass/Boston")
11 print()
12 print_umb_address()
13 print()
14 print("I am the IT Program Director in the Computer Science Department")
$ python3 umb.py
I teach at UMass/Boston
University of Massachusetts at Boston
100 Morrissey Boulevard
Boston, Massachusetts 02125-3393
I am the IT Program Director in the Computer Science Department
- Let's look at what the Python interpreter does as it runs the script
- The first two lines begin with # which means they
are comments
- The interpreter ignores comments
- It skips the blank line to go down to the next
- This line is also a comment and is ignored
- Line 5 is the function header
- It gives the function a name and lists the parameters it needs
- The interpreter has to do something special ...
- when it comes to a function definition
- Remember, the interpreter processes a script statement by statement
- Once it has processed a statement it forgets all about it
- Functions can be called many times as the script runs
- So when the interpreters sees a function definition it has to store it
- It is stored inside a special place in the RAM given to the script
- This way it will know what to do when the function is called
- The interpreter will store each statement in the function body
in this special place in RAM
- Line 9 is another blank line and is skipped
- When the interpreter gets to line 10 it notices that the statement is
not indented
- This means that the function definition has ended
- The interpreter can can now execute each statement it reads ...
- and forget about it after it is done
- The interpreter executes the
print
statements on line 10 and 11
- Line 12 is a function call
- The interpreter jumps to the function it previously stored in RAM
- It runs each statement in the function body until it gets to the end
- Now it jumps back to the statement after the function call
- Line 13 and 14 are
print
statements
- When the interpreter run out of statements ...
- it quits
Layout Rules for Functions
- A layout is the arrangement of information in a document
- Python has two rules when defining a function
- The function definition must come before the code
that calls it
- The body of the function must be indented
- These are not arbitrary
- They are the way code must be laid out ...
- for the interpreter to do its job
- Function definitions must come before the code that calls it ...
- so it can be stored for future use
- The interpreter process the script statement by statement
- Once the interpreter has processed a statement it forgets about it
- The code block of a function is indented
- So the interpreter knows which statements belong to the function ...
- and which are part of the rest of the script
Functions in Scripts
- Most scripts are composed of two sections
- A section at the top consisting of function definitions
- Followed by code that makes the script do its work ...
- and calls the functions
- In the script below, this second part appears in red
# this program prints some information about me
# and prints the address of our campus
# prints the address of UMB
def print_umb_address():
print("University of Massachusetts at Boston")
print("100 Morrissey Boulevard")
print("Boston, Massachusetts 02125-3393")
# prints some information about me
def print_personal_info():
print("Glenn Hoffman")
print("Information Technology Program Director")
print("Computer Science Department")
print("University of Massachusetts at Boston")
print("Glenn.Hoffman@umb.edu")
print("McCormack 3-0201-22")
print("Some information about me")
print()
print_personal_info()
print()
print_umb_address()
- This second part is sometimes called the driver ...
- or the main body of the code
- Some programmers like to put this code inside a special function
called main
- This main function is highlighted in
red in the code below
- Since main is a function it must be called
- The call to main is the blue
statement at the end of the file
# this program prints some information about me
# and prints the address of our campus
# prints the address of UMB
def print_umb_address():
print("University of Massachusetts at Boston")
print("100 Morrissey Boulevard")
print("Boston, Massachusetts 02125-3393")
# prints some information about me
def print_personal_info():
print("Glenn Hoffman")
print("Information Technology Program Director")
print("Computer Science Department")
print("University of Massachusetts at Boston")
print("Glenn.Hoffman@umb.edu")
print("McCormack 3-0201-22")
def main():
print("Some information about me")
print()
print_personal_info()
print()
print_umb_address()
main()
- There is nothing wrong with this approach ...
- though I do not use it
- Notice that this script shows that one function can call another
Top Down Design
- The best way to work on a large project is to break it down ...
- into smaller tasks
- These smaller tasks can also be broken up ...
- until each task is a manageable size
- Programmers use this technique when writing large programs
- This technique is called top down design
- The basic approach is as follows
- Define the problem
- Break down the problem into smaller tasks
- Break down the smaller tasks into still smaller tasks
- Continue doing this until all tasks are as simple as possible
- Write functions for each of the smaller tasks
- Write a main program that calls all the functions
Example of Top Down Design
-
Suspension bridges
are very big construction projects
- Building such a bridge is a very big project
- But if we break it down into smaller tasks it becomes more manageable
- Out first attempt at breaking down the work might look like this
- Erect the towers
- Run the cables
- Lay down the roadway
- But each of these tasks could be broken down further
- Erecting the towers can be broken down into
- Build the foundations in the water
- Build the towers on top of the foundations
- Running the cables could be broken down into
- Create an anchorage
on each bank of the river
- Run the first line between the anchor points and the
towers
- Create the suspension cables
- Laying down the roadway can be broken down into
- Run
stringers
from the suspension cables down to the height of the roadway
- Erect a platform to hold the roadway suspended from the
stringers
- Put a paved surface on top the platform
- Each subtask can be broken down further
- For example building the foundation can be broken down into
- Erect a
coffer dam
- Pump out the water
- Clear the bottom of mud and rubble
- Build a wooden frame for the concrete
- Pour concrete into the frame
- With each breakdown we get closer and closer to a manageable task
- And each task can be given to a specific group of people
- Often these people can work in isolation from the rest of the project
The Advantages of Isolation
- If we are smart in how we break up the problem ...
- each task will be somewhat independent
- It will not depend too much on the work of other teams
- That means each team can do their job ...
- without being too concerned about the rest of the project
- One part of building a suspension bridge is constructing the anchors
- These are massive concrete structures that hold the suspension cables taught
- There is one on either side of the river
- The teams working on the anchors not have to worry about other parts of the
work ...
- like the construction of the towers in the river
- Things work best when each part of a job is independent of the other work
- If teams had to keep talking to one another as they worked ...
- it would slow things down considerably
- Isolating the work of one group allows that group to keep working ...
- even if other groups run into problems
Specifying the Work for a Function
- Before you write a function you should be clear what the function should do
- Sometimes you write this out as a formal specification
- More often it is a short description in a comment before the function
- Here are comments from some of the functions I have written for use in other
scripts
- converts a string into a decimal, if it can, otherwise
returns the empty string
- prints an error message, then quits
- adds spaces to a string until its length is equal to the
parameter given
- converts a string into an integer if it can, otherwise
prints an error and quits
Keep It Simple
- One of the best ideas in engineering goes by the acronym KISS
- It stands for Keep It Simple Stupid
- Which do you think will break first?
- A machine with 10 parts or one with 100?
- The simpler something is ...
- the less there is to go wrong
- The KISS principle says that a function should do one thing
- But do it well
- The more complicated you make a function ...
- the harder it is to get it to work
Running Programs and the Operating System
- There is a special part of the operating system that deals directly with hardware
- Things like the processor, RAM and discs
- This program is called the
kernel
- The kernel is always running in RAM
- Programs need to interact with the hardware
- They need to read from a file
- Or create directories
- They cannot do this by themselves
- Instead they have to ask the kernel to do it for them
- The Unix command line is created by a special kind of program
- It is called a
shell
- A shell allows you to talk to the kernel
- Only the kernel can start a program running
- It does this by setting aside some space in RAM ...
- and loading the code for the program into this space
- A running program is called a
process
- A process has its own chunk of memory in RAM
- No other program can use this memory
- This keeps programs from interfering with each other
- Each Python script runs in its own bit of RAM
How the Interpreter Uses Process Memory
- Every time you run a Python program a process is created
- And the interpreter is loaded into the RAM space given to the process
- The code of your Python script is also loaded into this space
- The interpreter goes through the lines of the script statement by statement
- When it comes across a function definition, it stores it for future use
- Variables are created in this process space
- When you call a function that function gets is own, separate, piece of RAM ...
- inside the process space
- This chuck of process RAM is used to store the function's variables
- Function memory disappears when the function finishes
- This means that the variables inside a function are not permanent
- This keeps the function isolated from other parts of the script
Parameters
- The script cheer_1_test.py has process memory
assigned to it
- The function has not been called, so there in no function memory
- When the function cheer_1 is called ...
- it gets its own piece of memory for its variables
- This chunk of memory is inside the process memory for the script
- The first thing the function does is create the variable
team
- Inside the function memory space
- team is a parameter
- So it gets it's value from the argument in the function call
- Here the value is "Red Sox"
- After the function finishes it's memory disappears
- So all its variables are gone
- Now let's test the same function ...
- with slightly different body code calling cheer_1
- The new body code sets the variable team ...
- inside the process memory for the script
- The state of memory looks like this
- When the body code calls cheer_1
- The function gets its own space inside process memory
- The first thing the function does is give the parameter
team its value
- This team is a new variable
- That lives inside the memory space for the function
- It just so happens that the variable has the same name and value ...
- as the other variable team
- Outside in the process memory space
- When the function finishes, it gives up its memory space
- But the original variable team is still around
- It will not disappear until the script ends
Local Variables
- When the function is called it gets its own chunk of RAM
- The function has no parameter, so it has no variables of its own yet
- The first line of the code block creates a local variable called
team
- Notice that we have two team variables with
different values
- When the function finishes it loses its memory space and all its variables
- Now we are only left with the original team variable
- The part of a program where a variable has meaning is called the
scope of the variable
- Local variables defined inside one function are invisible outside the function
- This means we can use the same variable name in more than one function
Parameters Are Local Variables
- Parameters only come into existence inside the memory space of the function
- That means that parameters are local variables
- But not all local variables are parameters
- What makes a variable local is where it is stored in memory
- If it is stored in the function's memory space it is local
- What makes a parameter different from other local variables is
how it gets its value
- A parameter gets this value from an argument in the function call
Studying
Class Exercise
Class Quiz