IT 116: Introduction to Scripting
Class 13
Today's Topics
Review
New Material
Homework 7
I have posted homework 7 here.
It is not due this coming Sunday.
Instead is due on the Sunday of the following week, October 27th.
This is to allow you time this weekend to study for the mid-term.
Today's New Material Not on Mid-term
The new material in today's class will not appear on the Mid-term.
You will only be responsible for the material in the Class Notes for the next class.
They will cover Class Notes 2 through 12.
Tips and Examples
Review
Local Variables
- Any time you create a variable inside a function you are creating a
local variable
- A local variable created inside a function can only be used inside that function
- The variable only exists while the function runs
- This means the variable is invisible outside the function
- Outside the function, the local variable does not exist
- Local variables defined in one function are invisible to other functions
- This means we can use the same variable name in more than one function
- Another way of saying this is that the
scope
of a local variable is the function in which it is defined
Parameters
- Parameters
are a special kind of local variable
- They are defined in the
function header
inside the parentheses
- They get their value from the corresponding argument in the
function call
- Like other local variables, they disappear after the function ends
New Material
Default Values for Parameters
- A function with many parameter needs a value for each one
- This is particularly annoying when some parameter normally has the same value
- Here is a function for converting feet and inches
into either total inches or total centimeters
# converts feet and inches to inches or centimeters
def convert(feet, inches, units):
total_inches = 12 * feet + inches
if units == "inches":
print(total_inches)
else:
print(total_inches * 2.54)
- When we call this function we must supply three arguments
>>> convert(6, 5, 'inches')
77
- America is the only major country in the world that does not use the metric system
- In this country the third argument would almost always be 'inches'
- Having to enter a third argument which is almost always the same is very annoying
- Fortunately, Python gives you an alternative
- Python lets you define a function with a
default value
- A default value is a value that is supplied automatically if it is left out
- The format for writing a function with default values is
def FUNCTION_NAME([PARAMETER, ...], PARAMETER_NAME=DEFAULT_VALUE [, PARAMETER_NAME=DEFAULT_VALUE]):
STATEMENT
...
- Notice that the default values must come at the end of the parameter list
- You can have as many defaults as you want
- But defaults must come after the parameters that do not have defaults
- Let's rewrite the previous function to use a default value
# converts feet and inches to inches or centimeters
def convert(feet, inches, units='inches'):
total_inches = 12 * feet + inches
if units == "inches":
print(total_inches)
else:
print(total_inches * 2.54)
- Most of the time only two arguments will be given
>>> convert(6, 5)
77
- But we can also supply the third argument when we need it
>>> convert(6, 5, 'cm')
195.58
- With this particular function we can go a step further
- What if the measure had no inches
- You would still have to provide a second value
>>> convert(6, 0)
72
- Why not give the second argument a default value of 0?
def convert(feet, inches=0, units='inches'):
total_inches = 12 * feet + inches
if units == "inches":
print(total_inches)
else:
print(total_inches * 2.54)
- Now we can call the function with only one argument
>>> convert(6)
72
Named Arguments
- The latest version of the conversion function has two default values
- But what if we wanted to change the second default value
- But not the first?
- Would we have to supply all three arguments?
>>> convert(7, 0, 'cm')
213.36
- Python gives us another option called
named arguments
- The textbook calls this feature keyword arguments
- You do this by writing the name of the parameter followed by the assignment operator,
= followed by the value for that parameter
>>> convert(6, units='cm')
182.88
- Named parameters lets you give a value to any parameter in any order
- You don't have to use the order specified in the function header
- We used named parameters when we changed the default values of the
print
parameters end and sep
Global Variables
- Parameters and variables declared inside a function are local variables
- Local variables cannot be seen outside the function
- But what about the variables declared outside any function?
- These variables live in the outermost memory space
- This gives them special properties
- Variable declared outside of functions can be seen inside any function
- These variables are called
global variables
- Here is an example
def cheer():
print('Go ' + team) + '!')
team = 'Red Sox'
cheer()
- In this example, team is a global variable
- You can think of functions as looking at the program memory through a one way mirror
- Functions can see the variables declared in the body of the program
- But the body of the program cannot see variables declared inside the function
- What if a local variable has the same name as a global variable
- In that case the Python interpreter will use the value of the local variable
>>> def cheer_2():
... team = 'Red Sox'
... print('Go', team, end="!\n')
...
>>> team = 'Pats'
>>> cheer_2()
Go Red Sox!
- This is called
variable shadowing
- If I try to run the first version of cheer without having
defined team outside the function
I will get an error
>>> cheer()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in cheer
NameError: name 'team' is not defined
- For this reason, it is not a good idea to use global variables inside functions
- If you forget to define the global variable the function will not work
- Also, useful function are often put into
modules
- They can then be imported into any program as needed
- If functions in a module cannot depended on global variables in the script
- That would make them hard to use
- Don't use global variables in a function unless you have a good reason
Global Constants
- Some things in life, and in programming, never change
- The number of days in the week
- The number of months in a year
- The first date of the year
- The ratio of the circumference of a circle to its diameter (π)
- For this reason, some languages have special variables called
constants
- A constant is a variable whose value cannot be changed
- Python does not have constants
- But you can use a global variable for this purpose
- You just give it value and don't change it
- Global variables in Python can be changed inside a function
- But you need a special construction
- It is customary to write the names of constants in ALL_CAPITALS
- This serves as a reminder never to change their values
- Global variables used as constants should be declared once at the top of the program
- You will sometime find globals in modules
Pausing Execution of a Script
Functions that Return Values
- Functions that return values can be used in assignment statements
>>> result = round(8.765)
>>> result
9
- To return a value, a function must use
return statement
is a Python statement that uses the
return
- Return statements have the form
return EXPRESSION
- Remember, an expression
is anything that the Python interpreter can turn into a value
- A
return
statement does two things
- It ends the execution of the function
- It sends a value back to the function call
- A
return
statement always causes the function to quit
- So any code after the
return
statement will never be executed
- Here is a new version of the cheer function that returns a value
>>> def cheer(team):
... return 'Go ' + team + '!'
- To see the output we have to put a call to the function inside a call to
print
>>> print(cheer('Red Sox'))
Go Red Sox!
- Since this version of cheer returns a value, it is an expression
- So we can always use the function call as the argument to a
print
Returning Multiple Values
- A Python
return
statement can return more than one value
- All you have to do is follow the
return
keyword with a comma separated list of expressions
return EXPRESION, EXPRESSION [, EXPRESSION, ...]
- Using this feature I can write a function to get both the first and last name
>>> def get_full_name():
... first_name = input("Please enter your first name: ")
... last_name = input("Please enter your last name: ")
... return first_name, last_name
...
- When this function is called it will ask for two values
- And return each to a separate variable
>>> fname, lname = get_full_name()
Please enter your first name: Glenn
Please enter your last name: Hoffman
- You have to be careful when calling a function that return more than one value
- You must have a variable ready to receive each value
- On the left hand side of the assignment statement
- Assigning more that one variable a value with a single assignment statement is called
multiple assignment
Standard Library
Creating Random Numbers
- Many things in nature are random
- The number of dust particles in a room
- Whether a coin comes up heads or tails
- The number of leaves in my yard
- The number of water droplets in a cloud
- Random events are things that cannot be exactly predicted
- In other word, events with no patterns
- When writing programs, we often need random numbers
- We need them in writing
- Would a game of solitaire be any fun if the cards always appeared in the same order?
- Simulations are extremely important in many sciences
- Astronomers use simulations to study the evolution of galaxies
- Climate scientists use simulations to see what global warming will bring
- For both games and simulations we need random numbers
- But we have a problem
- Nothing that a computer does is random
- If you give a program the same input .you will always get the same output
- In other words, the output of a program is completely determined
- There is nothing random about it
- But the need for random numbers in computing is very great
- So mathematicians have developed algorithms that create
pseudorandom numbers
- These algorithms create a sequence of numbers
- In a truly random sequence, the numbers would never repeat
- In a pseudorandom sequence the numbers eventually repeat
- But the interval between repeats is so long that they are "random" enough for most purposes
- The functions that create these pseudorandom sequences are called
pseudorandom number generators
- Sometimes they are simply called random number generators, although that term in not really accurate
The random Module
- One of the modules in the standard library is random
- It contains several several functions that create pseudorandom numbers
- The function randint takes two integers as arguments
- And returns a pseudorandom integer
- The two numbers specify the minimum and the maximum numbers created
- We can call this function several times and each time it will return a different number
$ cat random_1.py
# demonstrates the use of the randint function of the random module
import random
for i in range(10):
print(random.randint(1,100))
$ python3 random_1.py
89
98
93
73
32
40
63
100
76
80
$ python3 random_1.py
66
49
1
29
63
17
91
3
70
5
- We can use randint to simulate throwing dice
$ cat dice.py
# this program emulates a throw of two dice
import random
die_1 = random.randint(1,6)
die_2 = random.randint(1,6)
print("You rolled", str(die_1), "and", str(die_2), "for a total of", str(die_1 + die_2))
$ python3 dice.py
You rolled 4 and 3 for a total of 7
$ python3 dice.py
You rolled 7 and 1 for a total of 8
$ python3 dice.py
You rolled 5 and 3 for a total of 8
- If we kept calling randint long enough it would eventually repeat
- But we would have to call it a very large number of times
Other random Functions
- The random module has other pseudorandom functions
- Each of them has advantages in different situations
- The randrange function also returns an integer
- But it gives you more options when specifying the range
- While randint takes two arguments
- The arguments to the randrange function
work just like the arguments to the
range
function
- When run with one argument randrange creates a sequence starting at 0
- And ending with one less than the argument
$ cat random_2.py
# demonstrates the use of the randrange function of the random module
# with one argument
import random
for i in range(10):
print(random.randrange(5))
$ python3 random_2.py
1
3
2
0
1
1
2
2
0
4
- Notice that all the numbers are between 0 and 4
- When called with two arguments the first argument specifies the start of the range
- And the second number specifies one more than the end of the range
$ cat random_3.py
# demonstrates the use of the randrange function of the random module
# with two arguments
import random
for i in range(10):
print(random.randrange(1, 6))
$ python3 random_3.py
1
3
1
2
5
5
2
3
1
1
- Here all the numbers fall between 1 and 5
- When called with 3 arguments the third argument specifies the difference between any two values
$ cat random_4.py
# demonstrates the use of the randrange function of the random module
# with three arguments
import random
for i in range(10):
print(random.randrange(2, 11, 2))
$ python3 random_4.py
6
6
4
6
8
10
10
4
8
2
- The values are all even numbers between 2 and 10
- Both randint and randrange return integers
- If you want a decimal number, use random
- It generates a random number between 0.0 and 1.0
$ cat random_5.py
# demonstrates the use of the random function of the random module
import random
for i in range(10):
print(random.random())
$ python3 random_5.py
0.3366683809865726
0.6243291094221154
0.47182435685723234
0.3079697111617222
0.5048399470937616
0.11682962682702247
0.08597187089498437
0.10398098486344709
0.8667164814826076
0.15337564523669833
- uniform takes two arguments and creates decimal numbers
- The numbers lie between the two arguments which specify the range
$ cat random_6.py
# demonstrates the use of the uniform function of the random module
import random
for i in range(10):
print(random.uniform(1, 5))
$ python3 random_6.py
3.987702460027857
2.776217942732739
2.890534381287354
1.5377836190792888
3.1461905324732022
1.010886780905638
1.4452549292653458
4.558908792372804
4.934363837349949
2.1135109420482228
Random Number Seeds
- The numbers generated by the functions in the random module
are not truly random
- They use algorithms that need a starting value to work
- The starting value is called a seed
- If the seed is the same the numbers created by the random functions will be the same
- To prevent this from happening the functions in random use a trick
- Instead of choosing the same seed value each time they run they use the system time instead
- Every computer keeps track of the time and date in a variable called the system time
- The system time counts seconds and is a very large integer that keeps changing
- This means the random functions will create different
number sequences each time they are run
- But what if we wanted the sequence of numbers to be the same?
- Let's say that you were writing a simulation of a complicated system
- Say the weather over a continent
- You run the simulation once and get a result
- Then you want to know what would change if you added another variable to the simulation
- Say you added calculations to take account of the presence of dust in the atmosphere
- Dust helps rain clouds form
- We would want to test this new simulation when the same sequence of numbers used before
- We can do this using the seed function
- The seed function assigns a specific value to the seed
- If we use the seed function to set the seed value to the same number
- each time the program is run, we will get the same number sequence
$ cat random_6.py
# demonstrates the use of the seed function in the random module
# to generate the same series of numbers each time the program is run
import random
random.seed(67)
for i in range(10):
print(random.randint(1, 100))
$ python3 random_6.py
10
15
99
53
60
54
35
77
55
63
$ python3 random_6.py
10
15
99
53
60
54
35
77
55
63