Unit 1 - Python Bootcamp
This course uses object-oriented Python to explore advanced topics in computer science. If you're coming into this class from a previous Computer Science course at Poly, you have either:
- experience using object-oriented principles in a Java class, or
- experience using Python in a non-object-oriented course.
Either way, you're going to need develop a strong, working knowledge of object-oriented programming in Python before we can move on to the topics in this course.
Let's get started!
1.0. Overview
We're going to spend a few days covering the essentials of computing in Python:
- General information
- Output
- Comments and Code Blocks
- Identifiers and Data Types
- Data types: Numbers
- Input
- Modules, Functions, Parameters and Return Values
- Conditionals
- Loops
- Data Types: Strings
- Tuples and Lists
- Dictionaries
- Object-Oriented Python
There are some strong similarities between Java and Python, but some interesting differences as well. Once you've learned one programming language, you have an enormous advantage in learning additional languages: you already know how basic data structures and control structures work. All you have to do is learn a new syntax.
1.1. General Information
1.1.0. Getting Python on your machine
Some computers come with a version of Python pre-installed. In here, however, we're going to be using Python 3, installed via Miniconda. Download the correct package for your computer and install it following the instructions.
1.1.1. Python2 vs. Python3
There are two different versions of Python commonly used now. We'll be using Python3 in here, the "modern" version, but you should know that if you look at some textbooks/websites for examples or help, their Python2 examples may not work for you.
In this bootcamp, we'll point out two significant differences that you'll need to know.
(Note that Python2 comes pre-installed on Apple computers. Cool! But it's Python2, which is the reason you need to install Miniconda.)
1.1.2. Running Python
There are two ways that you can run Python. Interactive mode is perfect for testing small snippets of code to see how they work. Program mode is useful for running programs.
1.1.2.0. Interactive mode
To start the Python interpreter, type python at the command line and hit the [Enter] key:
$ python [Enter] Python 3.5.1 |Continuum Analytics, Inc.| (default, Dec 7 2015, 11:24:55) [GCC 4.2.1 (Apple Inc. build 5577)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
The >>>
prompt let's you know that Python is waiting for you to enter an instruction.
First Python statements
Try entering the statement here, press the [Enter] key to execute it, and see what happens:
>>> print(“Hello, world!”)
Then try a few other statements in the interpreter to see what happens:
- print(Hello, world!)
- print(3+4)
- print(“3+4”)
- print(3,4)
- print(34)
- print(3 4)
Python 3 vs Python 2: print()
statements
In Python 2, the print
statement allowed you to print things.
>>> print "Hello, World!" # only works in Python 2
In Python 3, the print
statement is a function that takes a parameter:
>>> print("Hello, World!") # works in Python 3 or Python 2
Because we're using Python3, make sure to include parentheses with your print
statements.
Once you're done with your interactive session, exit by typing "exit()", or holding down the ctrl key while pressing d.
>>> ^D
Executing instructions like this one at a time in the interpreter is kind of cool, especially when you're trying to figure out a command that's new to you, or if you want to experiment real quickly with an idea.
There's one big disadvantage, though: if you want to execute your instructions again, you have to type them in again. Usually, it's much better to write a program.
1.1.3. Writing a Python program
Before Python can compile and run the program, you have to write the program, for which you need a text editor.
Write "Hello, World!" in Python
Do this:
- In the Terminal, cd to your Desktop
- Launch nano or another text editor to create the program hello_world.py.
$ nano hello_world.py
- This program will just have three lines in it: one line will print out the message "Hello, world!" when it runs, the next line will print the sum of the numbers 1-10, and the last line will print a personalized goodbye message to you. Once you think the program is done, save it, and try running the program.
1.1.4. Running a Python program
As a developer you'll usually use two separate windows, one in which you're working on your program with a text editor or IDE, and one a terminal window that you're using to run your program.
Run the hello_world.py
program
Do this:
- In a Terminal window, enter
$ python hello_world.py
to run the program - If the program doesn't work as you expected, or you get a message saying that the program had an error, it's not big deal. The debugging begins!
- Move to the text editor window to try to fix the program, then move back to your test window to try to run the program again.
print("Hello, world!") print(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10) print("Goodbye, Richard!")
1.2. Output
We've already seen the print
statement that is used to print out values.
>>> print("Hello, world!") Hello, world!
Let's see some other ways to create output.
1.2.0. Printing multiple values on a single line
The print()
statement can be used to print multiple values by separating them with a comma.
>>> print("Hello,","world!") Hello, world!
Note that the comma inside the quotes got printed, and the comma outside the quotes didn't. Note, also, that Python inserts a space between comma-separated values when it prints them out. You can avoid this by concatenating values with a +
sign:
>>> print("Hello" + "world" + "!") Helloworld!
1.2.1. Printing multiple lines with a single print
statement
A single print()
statement can print on multiple lines by using the \n
(newline) character.
>>> print("Hello,\nWorld!") Hello, World!
1.2.2. Using multiple print statements to output a single line
A print()
statement typically displays the information indicated and then places cursor on the next line for subsequent print statements. If you want to have multiple print()
statements output information on the same line, use the end=''
modifier:
print("Hello, ",end='') print("world!") Output: Hello, world!
1.2.3 Print formatting
For specialized output needs—controlling spaces, justifying text, indicating how many decimal places should be printed—you can use Python's .format()
method.
Formatting Output
The basic way to format output in Python3 is as follows:
print("{0} is the {1}".format(value0, value1))
Thus:
>>> print("{0} is the {1}".format("Richard", "best")) Richard is the best
Or:
>>> print("The value of {0} is {1:.4f}".format("pi", math.pi)) The value of pi is 3.1416
What's happening here? A print()
statement includes the string to be formatted—with curly braces enclosing the formatting instructions—followed by a call to the .format()
method, which includes references to the values that are going to be formatted.
The formatting instructions in the curly braces include a reference to which value is being formatted (0, 1, etc.), and an optional formatting rule (following a colon) that should be followed in displaying that value.
{0}
causes the first value to be displayed with no spaces before or after the value.4f
causes a numeric value to be displayed as a float with 4 places after the decimal point10s
causes a string to be displayed in a width of 10 characters, with extra spaces padded at the back as necessary to make a total of 10 characters.
Note that there are a much wider variety of format possibilities available than what is listed here. For example, this snippet produces a very nicely formatted table:
print("{0:>8s} | {1:>8s} | {2:>8s}".format("number","square","root"))
for i in range(10):
print("{0:8d} | {1:8d} | {2:8.3f}".format(i, i*i, i**0.5))
number | square | root
0 | 0 | 0.000
1 | 1 | 1.000
2 | 4 | 1.414
3 | 9 | 1.732
4 | 16 | 2.000
5 | 25 | 2.236
6 | 36 | 2.449
7 | 49 | 2.646
8 | 64 | 2.828
9 | 81 | 3.000
See the Python3 documentation for further information on how to use print formatting.
1.3. Comments and Code Blocks
1.3.0. Comments
Python supports inline and multiline commenting.
- Inline commenting begins after a
#
.c = gcd(18,12) # gets the greatest common divisor
- Multiline comments in the middle of a program are typically surrounded by triple-single quotes:
''' This next section of code goes through the letters in the body of the text and either: a. increments the dictionary count of that letter, or b. creates a dictionary entry (with a count of 1) if this is the first time that we've seen this letter '''
- Multiline comments surrounded by triple-double quotes are used to identify docstrings that, when placed immediately after a function header, are used as official documentation text. (See below for example).
#!/usr/bin/env python3 """ hello_world.py The classic introductory "Hello, World" program, Python-style. """ print(“Hello, world!”) print(1+2+3+4+5+6+7+8+9+10) print("Goodbye, Richard")
1.3.1. Magic Methods (Double-underscore variables, or dunders)
Magic methods are special methods pre-defined in Python and called in certain situations. The double-underscore that precedes and follows the method name is intended to distinguish these special methods from others that you might define yourself.
If you've written your own class, you know that writing the method __init__(self)
is required. Python needs to know how it should go about constructing an object for your class type when it is created, and the "dunder-init-dunder" method does that.
You probably haven't used it directly but the __add__
dunder-method is called whenever a plus-sign ( +
) is used in an expression. That method, defined for numbers, will add them numerically. The same method defined for strings will instead concatenate them.
There are many other examples of dunder-methods, and we'll have occasion to use some of them in this course later on.
1.3.2. Code blocks, or Suites
Most programing languages consist of logical sections of code which are grouped together. The body of a function, perhaps, or the body of a loop. In Java, these logical sections of code are enclosed in { }
, and the end of an instruction is indicated with a ;
(semicolon).
In Python, these logical sections of code are called suites.
Suites, or code blocks
A suite in Python is a logical block of code, identified at the beginning by a colon (:), with each instruction on its own line, and all lines indented exactly 4 spaces from the previous line.
NOTE: Do not use [tab]s to create your spacing unless you have configured your text editor to replace tabs with spaces. Four spaces may look the same as a [tab], but Python won't be able to run your program correctly. Also, although the "4 spaces" rule is not required by Python—you can actually use any spaced-indent for a suite, as long as the same indent is used consistently throughout the program—in here we'll be using 4-spaces, which is standard Python "best practice."
Let's begin right away with setting up a suite that you'll use in practically every program that you write in the class: a main function that comprises the body of your program.
A main()
function
The following program uses a main function to organize the instructions:
#!/usr/bin/env python3 """ Hello, World! program """ def main(): print(“Hello, world!”) print(1+2+3+4+5+6+7+8+9+10) print("Goodbye, Richard") if __name__ == "__main__": main()
Here, the def
instruction in Python defines a function called "main", which contains a bit of code that won't be run until the name is used later on in the program.
Down below, then, we "call the function" by writing main()
, which tells the interpreter to execute the instructions that we'd described earlier on in the function definition.
1.4. Identifiers and Data Types
Computers need to store data in variables, which are indicated by identifiers.
Definition: Identifier
An identifier is a label used to refer to a specific storage location in the computer's memory.
Examples of identifiers that might store data in a Python program include:
username2
is_even
PI
Triangle
DAYS
i
In Python, an identifier may consist of letters, numbers, and underscores ("_"), but it can't begin with a number.
Multi-word variable names are usually written with underscores rather than camelCase—is_not_prime
rather than isNotPrime
, for example. Constants are written in all capital letters, however, with underscores used to separate words as required. Regular variable names should begin with a lowercase letter (my_triangle
, for example), while class names should begin with an uppercase letter (Triangle
).
Java is a strongly-typed language in that each variable that you use has to be declared to be of a specific data type (int
, double
, String
, boolean
, etc.).
Python is a weakly-typed language in that the type of value stored in a variable doesn't have to be declared in advance, or even at all. If you put an int
into the variable n
, then n
is storing an integer. And there's no rule against then storing a string
value in there. You're free to do so.
This freedom comes at a price, however. It means you have to work a little harder to make sure that you don't mess things up...
Data types in Python include:
int
(integers)float
numbers (floating point, or decimals)str
(Strings, of text)list
(the Python equivalent of Java'sArray
s andArrayList
)tuple
(kind of like lists, but immutable)dictionary
(key-value pairs, not covered in most introductory Java courses)...
Python also fully supports objects, which we'll be discussing a little later.
1.5. Data Types: Numbers
1.5.0. Numeric Data Types—Integers and Floating Point numbers
It's far easier for computers to deal with integers, and therefore far faster for them to perform operations with integers. Differences in speed won't be apparent in most programs that we write, but for any program that performs the same operation thousands, million, or billions of times, working with integers where possible produces a significant increase in speed.
Integers
Plain integers are simply that: integers, i.e. numerical values without a decimal point. You can confirm the type of a number by using the type() function in interactive mode:
>>> type(3) <type 'int'>
Integers have 32 bits of precision. If you need more than that, you'll need to use the longint
data type, which has unlimited precision. longint
values are indicated with an "L" at the end of the number, i.e. 3L
.
Floats
Floats are floating point numbers, i.e. numerical values that do have a decimal point.
>>> type(3.0) <type 'float'>
Start up the Python interpreter and try out each of the examples here. Can you predict what the output of each will be?
>>> 5 + 2
>>> 5.0 + 2
>>> 5.0 / 2
>>> 5 / 2
>>> 5 // 2 # how is this different?
>>> 5 % 2 # this is related to the last one
>>> 5 * 2
>>> 5 * 2.0
>>> 5 ** 2
>>> 2. ** 0.5
Note that the //
operator allows for "whole number" division—it returns the integer result of the division without a decimal and without any remainder.
The %
operator gives you that remainder.
These two division strategies turn out to be enormously useful to us.
Python3 vs. Python2
In Python 3, the division operator /
works just as you'd expect it would:
print(5 / 2) # produces result 2.5 in Python 3
In Python 2, the division operator, working on integers, produces an integer result only:
print(5 / 2) # produces result "2" in Python 2
You can use Python's built-in functions to convert from one data type to another:
>>> print(float(3)) 3.0
>>> print(int(3.7)) 3
>>> print(round(3.7)) 4
1.5.1. The math
module
Modules
A module in Python is a program that someone has written that can be used in a larger program. Collections of modules that can be used by programmers are called libraries.
One of the tremendous powers of Python is this ability to leverage the work that other people have already done, and the way one does that in Python is by importing modules.
The import
command
To import a module that someone has already written so that you can use it in your own program, simply include the statement import <modulename>
at the beginning of your program, just after your opening comments.
One important module is the math
module, which includes lots of methods for handling more sophisticated math functions.
Start the Python interpreter, try out the following statements:
Let's see how to use the math module to perform calculations. Enter the following code in the Python interpreter.
>>> import math # Gets the entire math library >>> r = 3 >>> circumference = 2 * math.pi * r # use pi from library >>> print(circumference)
What if you wish to calculate the square root of a number? There are a couple of ways to do that:
>>> print(11**(0.5)) 3.31662479036 >>> print(math.sqrt(11)) 3.31662479036
The operation **
indicates an exponent, raising some value to the power indicated.
What do you think this code might print?
>>> print(math.sin(math.radians(90)))
Other functions contained in the math module include:
- e, log(x), exp(x)
- sin(x), cos(x), tan(x), asin(x), acos(x), atan(x)
- radians(x), degrees(x)
Python's trig functions require that the value given be in radians. So, to calculate the horizontal component of velocity for a jet traveling 200 meters/second at 30 degrees above the horizontal:
>>> import math >>> horz_vel = 200 * math.cos(math.radians(30)) >>> print(horz_vel) 173.205080757
Note that if you forget to import the math module, you'll get an error.
For a more complete list of methods available in the math module, use help(math) after importing the module.
1.5.2. Different ways to import a module
Modules obviously provide a convenient way of expanding Python's capabilities beyond the built-in functions that are available any time Python executes a program.
We've already seen the traditional way of importing a module. Note that we have to indicate the module name (math
before we indicate the method we want to used from that module (.pi).
>>> import math # Gets the entire math library >>> circumference = 2 * math.pi * r # use pi from library
This technique, at the start, is the recommended way to use a method from an imported module.
Another option, though, if you really only need the pi function, is this:
>>> from math import pi # Gets just the pi function >>> circumference = 2 * pi * r # calculates using pi
The advantage here is that you can just use the identifier pi all by itself, without having to also specify the module name. The disadvantage is that there is some potential for confusion between the pi that you've imported and any other pi variable that you might be using in your program. The likelihood of this happening in a small program is pretty low, but as your programs become more complex, clearly distinguishing between your local variables and those imported from modules will be important.
The previous example gets only the pi function. If you wanted to get all the functions from math, you would do this:
>>> from math import * # Gets all math functions >>> print(pi, sin(pi/2)) # use any function directly
1.6. Input
To assign values to a variable, there are two common options: programmer-assigned values and user-assigned values.
1.6.0. Programmer-assigned values in variables
Programmer-assigned value to a variable
To assign a value to a variable in a program:
<variable> = <expression>
Take a look at this code snippet to make sure you understand how it works.
height_in_feet = 5.8 height_in_inches = 12 * height_in_feet height_in_inches = height_in_inches + 0.5 # she grew! print("The height in inches is now", height_in_inches)
Note that we're using self-documenting identifiers here, and rather than using CamelCase to identify the words, we're using underscores between words. This is a Python convention that you should follow.
Problem: Area and Circumference of a Circle
Write a program that uses the math
module to calculate the area and circumference of a circle with a radius of 2.7 meters.
Expected results:
Area: 22.902210444669592 meters-squared Circumference: 16.964600329384883 meters
#!/usr/bin/env python3 """ circle_calculator.py Calculates the area and circumference of a circle with radius 2.7 meters """ import math def main(): radius = 2.7 print("Area:", math.pi * radius * radius, "meters-squared") print("Circumference:", 2 * math.pi * radius, "meters") if __name__ == "__main__": main()
1.6.1. User-assigned values in variables
We wouldn't want to have to rewrite our program for every user that has a different height, however. If we want the user to be able to assign a value at run-time, we can use the input statement.
User-assigned value to a variable
To allow a user to enter a value while the program is running:
<variable> = input(<prompt>) # for entering strings
<variable> = int(input(<prompt>)) # for entering integer numbers
<variable> = float(input(<prompt>)) # for entering decimal numbers
Example:
guests = int(input("How many are coming to the party? "))
height_in_feet = float(input("Enter the height in feet: ")) height_in_inches = 12 * height_in_feet print("The height in inches is", height_in_inches)
The input()
statement is the other major difference that you need to think about when it comes to Python 3.
Python3 vs. Python2: input
statements
In Python 3, the input
statement allows the user to enter a str
value. If that string, say "34", needs to be evaluated as a number, then the float()
function needs to be called, as we've seen.
In Python 2, the input
statement is only used for numbers. If you want to have a user enter a string value, the raw_input()
function is used.
name = raw_input("Enter your name: ") # only works in Python 2
Temperature conversion
Write a Python program that has the user enter a temperature in Fahrenheit and then print out the corresponding temperature in Celsius.
Test cases:
Input --> Output 32 --> 0 212 --> 100 98.6 --> 37
#!/usr/bin/env python3 """ tempconverter.py Converts temperature in Fahrenheit to temperature in Celsius """ def main(): degreesF = float(input("Enter temperature in degrees Fahrenheit: ")) degreesC = (5 / 9) * (degreesF - 32) print("The equivalent temperature is", degreesC, "degrees Celsius.") if __name__ == "__main__": main()
1.7. Functions, Parameters, and Return Values
Functions are an important tool for any programmer. They allow us to organize and re-use code, and they have their own scope. Let's see how they work in Python.
1.7.1. Definition and Uses of Functions
Functions
A function is a small program inside a larger one, whose purpose is to:
- organize your program into logical blocks of code
- reduce duplicated code (shortening and simplifying your program)
- make your program easier to maintain (by keeping your code better organized)
You should include functions in your program if:
- You find that you're repeating code
- Your program takes up more than "one screen" of space
Functions
A function is a small program inside a larger one, whose purpose is to:
- organize your program into logical blocks of code
- reduce duplicated code (shortening and simplifying your program)
- make your program easier to maintain (by keeping your code better organized)
You should include functions in your program if:
- You find that you're repeating code
- Your program takes up more than "one screen" of space
How do you actually do that?
Defining a Function
Just as we've used def main():
to define a main block of code that runs, we can define other functions with blocks of code that will execute when we "call" the function.
def <function_name>(<optional function parameters>): <statement> <statement> <statement> <optional return value>
As an example, here's a short function to say "Hello" to somebody:
def say_hello(name): print("Hello,", name, "!")
These lines just define the function, but the code doesn't actually execute in our program until we call it:
def main(): say_hello("Jon Snow")
At this point, the "Hello, Jon Snow !" message is displayed.
The entire program looks like this:
#!/usr/bin/env python3 """ Simple program demonstrating the definition and use of a function """ def say_hello(name): print("Hello,", name, "!") def main(): say_hello("Jon Snow") if __name__ == "__main__": main()
1.7.2. Parameters and Scope
We can write functions that can be used in three different ways:
- stand-alone functions
- functions that need to get information from the main program
- functions that need to return information to the main program
Let's see how to write each type of function with a few examples.
1.7.2.0. Stand-alone functions
A stand-alone function doesn't need to interact with the main program in any serious way; it doesn't require any information from the main program, and it doesn't need to return any information to the main program. In this case, the function's sole purpose is to keep your code organized so that it's easier to read and manage.
Let's say that you're writing a program that allows the user to play Blackjack on the computer. If you want to print out the instructions for the user, you could certainly put a bunch of print()
statements in the main()
body of your program.
But it's better to move that block of print statements to someplace else—to a function—and then we'll just call that function if needed.
In most cases, the function definition is placed before the main()
defintion. The code, then, looks like this:
def give_instructions(): advice = input("Need instructions? (y/n)") if advice[0].lower() == "y": print("""Here's how you play Blackjack. Play begins with 2 cards dealt to each player... """) def main(): give_instructions() . . if __name__ == "__main__": main()
When Python executes this code, it:
- takes note of the
print_instructions
function definition and checks it for syntax, but doesn't actually execute that code yet. - takes note of the
main()
function definition and checks it for syntax, but doesn't actually execute that code yet. - falls through to the bottom of the code to see what it should do. If we're running this program from the command line, then __name__ == "__main__" so the
main()
function (program) is executed line by line. - encounters the
print_instructions()
line, causing execution to jump up to that function, and lines there are executed until the function is done. - returns to the line after the function was called in the
main()
where it continues to execute instructions.
Notice that the main()
program now is much less cluttered and easier to read now that I'm using it to call other functions.
1.7.2.1. Sending in information with parameters
In the last example, we didn't need to pass any information back and forth between the main program and the function, but most programs DO need some way of doing that. How do you pass information into the function so that it can actually do something useful? You use parameters.
Parameters
A parameter is information that is passed into a function.
A formal parameter is included in parentheses as part of the function definition. The actual parameter, either a variable or a value, is included in parentheses when the function is called.
Let's take a look at a complete program that actually uses parameters.
"""Calculator Program, by Richard White This program takes two numbers entered by the user and performs a mathematical operation on them. """ def add_them(number1, number2): print("The sum of",number1,"and",number2) print("is",number1+number2) def main(): n1 = float(input("Enter a number: ")) n2 = float(input("Enter a second number: ")) add_them(n1, n2) if __name__ == "__main__": main()
You can probably guess exactly how this program works. At run time, the main program is called, which asks the user to input two numbers, after which the add_them procedure is called, with those two variables as parameters. In the add_them function, the formal parameters (variables) number1 and number2 refer to the actual parameters n1 and n2. Printing number1 refers to whatever value was referred to when the function was called... and that was n1. The function takes n1 and n2 and prints their sum.
Well, let's try writing a small program to practice using a simple function with parameters.
Problem: Old MacDonald Had a Farm
Write a short program to print the lyrics to the song "Old MacDonald Had a Farm." The program should use a single function "print_lyrics," that takes two parameters—animals
and noise
—and uses them to print a verse to the song. The main program should then call that function with appropriate parameters ("horses", "neigh", or "ducks" and "quack", etc.) so that the lyrics to the song are printed.
#!/usr/bin/env python3 """ oldmacdonald.py Prints out lyrics to the song "Old MacDonald Had a Farm" based on animals and noises """ def print_lyrics(animals, noise): print("Old MacDonald had a farm, ee-yi-ee-yi-oh") print("And on that farm he had some",animals,", ee-yi-ee-yi-oh") print("With a",noise, noise, "here, and a", noise, noise, "there") print("Here a", noise," there a", noise, ", everywhere a", noise, noise) print("Old MacDonald had a farm, ee-yi-ee-yi-oh") print() # blank line to end verse def main(): print_lyrics("cows", "moo") print_lyrics("ducks", "quack") print_lyrics("horse", "neigh") print_lyrics("dog", "bark") if __name__ == "__main__": main()
Note that there are some minor formatting issues with these lyrics, with some extra spaces inserted into the lyrics at odd places. As an extension, consider using print formatting (see notes above) to clean up the text? :)
1.7.2.2. Scope
In our calculator program above, we used a function to add two numbers and print the result. It turns out that adding two numbers is fine thing to do in a function, but you don't usually want to print anything in the function. Instead, you should get the answer and return
it to the calling function which will decide what to do with the answer.
To understand this process, we need to talk about scope.
Scope
Scope refers to the area in a program where a particular variable may be used.
Local scope variables may be used "locally" (in the current function), but don't have any value outside the function.
Global scope variables have value outside a given function, and may be referred to inside a function, but they typically can't be changed by that function.
In our Calculator Program, n1
and n2
are local to main()
, and global to add_them
. number1
and number2
are local to add_them
, and undefined outside of that function.
Exercise: Scope
Examine the following function, and predict what the output of each of the statements will be. (This is not a useful function—it's just designed as an exercise to help you understand scope.)
def hello(a_name): print("Hello,",a_name) a_name = "Joe" # Careful! This may not print("Hi,",a_name) # do what you think! # Now let's see how the function works! def main(): my_name = "Sue" # set global variable hello(my_name) # call the function print(my_name) # did the function change # the value of myname? print(a_name) # will this even work?
- In the main program,
my_name
is set to the valueSue
- From the main program, the
hello
function is called with a reference to the stringSue
. - From the
hello
function,a_name
refers to the stringSue
- The
hello
function prints outHello, Sue
- The variable
a_name
is set to point to a different string,Joe
. Note that this doesn't change anything in themain()
program, wherea_name
still points to the stringSue
. - Still in the function,
print(a_name)
displays the value ofa_name
, which isJoe
. - The function finishes running, so control returns to the main program, where we
print(a_name)
, producing the outputSue
. - The instruction
print(a_name)
won't work, because the variablea_name
doesn't exist in this namespace.Traceback (most recent call last): File "hello.py", line 13, in
print(a_name) NameError: name 'a_name' is not defined
It should be clear from looking at even this small example that there's room for some confusion. Different variables have different values in different locations, if they have any value at all. What's the story with all of these parameters?
There are a series of rules that govern what values parameters will have, and under what conditions. The purpose of these rules is to make the code that you write stronger and easier to work with, once you understand the rules. You'll pretty quickly learn to track what value has been given to a function, and how to easily move data in and out of your functions.
1.7.2.3. Getting information back out of a function
We've learned that you can pass information into a function using parameters. But how do you get information back out?
return
statements
A return
statement in a function that returns operation of a program back to the point where the function was called. Any variables included as part of the return
statement are sent back to the function call as a result.
Example: This program takes the two values sent to it, adds them together, and returns the result to the calling function where it can be used in another calculation, printed, etc.
def add_them(a,b): return a + b # Calculate a+b # and sends result back # to function call def main(): x = 3 y = 8 answer = add_them(x, y) # Calls function and # puts result in answer print("The sum of",x,"and",y,"is",end='') print(answer)
Exercise. Roll an n-sided dice roll, but don't print the results
Define a function called dieroller
that will simulate rolling a die that has a number of sides specified as a parameter, and returns
(doesn't print) the result.
def dieroller(n): """ returns a value between 1 and n, inclusive assumes that random has already been imported """ return int(math.random() * n + 1)
Being able to return a result to a program rather than just printing out something on screen is the most common way of using functions. If there is any output to be delivered, it will be done so by the calling function.
Let's take a look at our calculator program again. What if we'd written this:
"""
Calculator Program that won't work.
"""
def add_them(number1,number2):
answer = number1 + number2
def main():
n1 = float(input("Enter a number: "))
n2 = float(input("Enter a second number: "))
add_them(n1, n2)
print(answer) # This won't work
if __name__ == "__main__":
main()
This program won't work as we need it to, because the variable answer is "local to add_them
", and undefined in our main
program. We need to get the answer back out of the function somehow.
Our programming solution is to return
a value.
Here's a version of our program, then, that does work:
"""
Calculator Program that works!
"""
def add_them(number1, number2):
return number1 + number2
def main():
n1 = float(input("Enter a number: "))
n2 = float(input("Enter a second number: "))
answer = add_them(n1, n2)
print(answer)
if __name__ == "__main__":
main()
One common use for functions is to gather user input. Writing separate functions for "initializing" a program (setting initial values for data) and actually processing that data is very common.
Returning multiple values in Python
Often our function will need to return multiple values. In Java, methods can only send back a single value, unless you create, say, a User_Information
object to contain many values, and then send one of those back.
Python allows you to return objects back, certainly, but we can also just return multiple values, separated by commas. Take a look at the problem below, and use the solution to see how that would work.
Functions for input
Write a small program that includes a function to get the user's name and age. The function should pass this information back to the main program.
def get_input(): name = input("Enter your name: ") age = float(input("Enter your age: ")) return name, age def main(): user, age = get_input() # Call the function print(user, ", you are", age, "years old.")
Now try this one:
Functions for input and calculation
Write a small program that includes two functions: one to get the dimensions of a quadrilateral (and return those dimensions to the main()), and one that uses the information from the first function to calculate the area and perimeter of that quadrilateral and return those to the main(). The main program should then print out the results of the analysis.
def get_dimensions(): length = float(input("Enter length of quadrilateral: ")) width = float(input("Now enter width:")) return length, width def calc_area_perimeter(length, width): area = length * width perimeter = 2 * length + 2 * width return area, perimeter def main(): l, w = get_dimensions() a, p = calc_area_perimeter(l,w) print("The area and perimeter of your") print("quadrilateral are", a,"and", p)
1.8. Conditionals (if, if-else, if-elif-else
The if
statement in Python works very much as it does in Java, with some minor differences.
1.8.1. The if
statement
The if
statement
Python's branching structure is the if
statement. In its most basic form, it looks like this:
if <Boolean condition>: <statement> <statement> <statement> <Statement that is NOT part of the suite>
The Boolean condition has a value that is True
or False
. If the condition is True
, the 3 statements in the indented suite will be executed, and then the statement following that suite will be executed. If the condition is False
, the 3 statements are skipped, and only the statement following the suite is executed. (Note that the suite has been indented 4 spaces, the standard in Python.
1.8.1.0 Boolean expressions
Boolean expressions
Boolean expressions evaluate as "True" or "False". One way to create such an expression is simply to assign a variable the value True
or False
.
Examples:
user_greater_than_18 = False
item_found = True
Another way to create a Boolean expression is to compare two values.
Examples:
user_age < 18
# will be True if the user_age is less than 18lottery_ticket_number == winning_number
# will be True if the numbers are equal
Boolean operations include:
== | means "is equal to" |
!= | means "is NOT equal to" |
< | means "is less than" |
> | means "is greater than |
<= | means "is less than or equal to" |
>= | means "is greater than or equal to" |
expr1 and expr2 | returns True if both expr1 and expr2 are True |
expr1 or expr2 | returns True if either expr1 or expr2 are True |
not expr1 | returns True if expr1 is False, and False if expr1 is True |
1.8.1.1. Boolean expressions in branching statements
Let's take a look at how boolean expressions might be used in actual statements.
Predict the result
Examine each of these examples and predict what you think the output will be. Then write each program and confirm your analysis:
user_name = input("Enter your name: ") if user_name == "Joe": print("Hi,", user_name)
age = float(input("Enter your age: )) if age >= 18: print("You're eligible to vote!")
gender = "Female" if gender != "Female": print("No Boys Allowed")
name = "Richard" if name == "Richard": print("I know you!") print("You're Richard!") print("Thank you!")
1.8.1.2. Additional if
statements
There are additional forms of the if
statement that often come in handy:
if-else
statements
If you want to manage a 2-way condition (either do this, or that), use the if-else
statement:
if <Boolean condition>: <statement> <statement> else: <statement> <statement> <Statement that is continuation of program>
Note that the if
and else
suites are indented 4 spaces, which helps us visualize that they are the two different options in this part of the program.
Thus, we can correctly analyze whether or not our 21-year-old can be president with the following code:
age = 21 if age < 35: print("You're not old enough to be President of the U.S.") else: print("You are old enough to be President of the U.S.")
Only one of the two statements will be executed, depending on the value of the variable age.
Let's try writing a new program.
Try this
A restaurant serves breakfast and lunch until 4pm (1600 hours on a 24-hour time clock), at which time it starts serving dinner. Write a program that has the user enter a 24-hour time, and then indicates whether the restaurant is serving lunch or dinner at that time.
#!/usr/bin/env python3 """ Restaurant lunch or dinner exercise Richard White, 2012-01-30 """ def main(): the_time = float(input("What time is it right now (enter time as hhmm in 24 hour clock): ")) if (the_time < 1600): print("The restaurant is serving lunch right now.") else: print("The restaurant is serving dinner right now.") if __name__ == "__main__": main()
Some problems require that there be more than a single option considered. For these cases, you basically have two possible ways two write the code:
- Organize your logical solution so that a series of
if-else
statements can be nested, allowing the program's logic to drill down to find the appropriate action, or - if the actions can all be considered simultaneously, use an
if-elif-else
statement.
Usually one strategy will recommend itself over the other. The next two examples show how each of the strategies can be used to solve the problem of calculating the roots of a quadratic equation.
nested if-else
Quadratic Eqn solver
Example of using a nested if-else
statement to solve a quadratic equation:
a, b, c, = float(input("Enter coefficients a, b, and c: ")) discrim = b**2 - 4 * a * c # "**" = exponent if (discrim < 0): print("There are no real roots! Sorry!") else: print("You have roots. Now calculating...") if (discrim == 0): # Here's our nested if root = -b / (2 * a) print("You have a double root: ",root) else: root1 = (-b + discrim ** 0.5) / (2 * a) root2 = (-b – discrim ** 0.5) / (2 * a) print("The roots are:",root1,"and",root2) print("Program terminating.")
if-elif-else
Quadratic Eqn solver
Example of using an if-elif-else
statement to solve a quadratic equation:
a, b, c, = float(input("Enter coefficients a, b, and c: ")) discrim = b**2 - 4 * a * c # "**" = exponent if discrim < 0: print("There are no real roots! Sorry!") elif discrim == 0: # "elif" means "else-if" root = -b / (2 * a) print("You have a double root: ",root) else: # if first 2 options passed... root1 = (-b + discrim ** 0.5) / (2 * a) root2 = (-b – discrim ** 0.5) / (2 * a) print("The roots are:",root1,"and",root2) print("Program terminating.")
Let's try a simple exercise to put some of these pieces together:
Exercise: Restaurant Hours
A restaurant is open for breakfast until 1100 hours, for lunch until 1600 hours, and for dinner until 2300 hours. Write a program that has the user enter the time (in 24-hour form), and then prints out meal the restaurant is serving at that time. Include an additional print statement for each meal that recommends a beverage suitable for that meal. Regardless of the hour, print out the message "Thank you for choosing our restaurant."
Exercise: Letter Grades
Write a main program grade_reporter.py
that takes a grade percentage as input (0 - 100), and then sends that information via a parameter to a function called evaluate_grade
. That function should return a string value of A, B, C, D, or F, depending on the value of the parameter.
Test cases:
Input --> Output 100 A 99 A 90 A 82 B 75 C 64 D 59 F 105 A -1 F
1.9. Loops
As in Java, there are two common forms of loops in Python: the while
loop and the for
loop.
1.9.0. The while
loop
The while
loop is typically used when you have a loop that needs to repeat some number of times, based on a condition:
- "While we haven't finished counting from 1 to 10, keep counting."
- "While we haven't gotten to the end of the sentence yet, keep looking at each letter."
- "While we haven't finished adding up this list of numbers, keep adding."
- "While the user hasn't entered an appropriate input, give them an error message and ask again."
- "While we haven't processed each item in this array, keep processing."
Here are some quick examples of common while
loops.
1.9.0.0. Counting loops
i = 0 while i < 10: print(i) i += 1
1.9.0.1. Interactive loops
The interactive loop allows the user to approve a repeated process.
# Program to find the average of numbers
# using an interactive loop
sum = 0.0 # Make sure sum is real
count = 0
keep_going = "Y"
while (keep_going == "Y"):
num = float(input("Enter a number: "))
sum = sum + num
count = count + 1
keep_going = input("Keep going (Y/N)?")
print("You entered",count,"numbers")
print("which have a mean of",sum/count)
This loop works pretty well, but one of the problems is that it's annoying for a user to have to approve every iteration.
1.9.0.2. Sentinel loops
One way of solving the problem of having to have a user repeatedly indicate that he/she wants to continue is by using a sentinel value. This value, when entered with the other numbers, will indicate to the loop that it should stop running.
# Program to find the average of numbers # using a sentinel loop sum = 0.0 # Make sure sum is real count = 0 num = float(input("Enter a number (<0 to quit): ")) while (num >= 0): sum = sum + num count = count + 1 num = float(input("Enter a number (<0 to quit): ")) print("You entered",count,"numbers") print("which have a mean of",sum/count)
This loop works much more nicely... but it introduces a new problem: What if one of the numbers that I want to find an average of is negative?
Here's a new trick: have the user enter each number as a string:
# Program to find the average of numbers # using a sentinel loop sum = 0.0 # Make sure sum is real count = 0 num = input("Enter a number, <Enter> quits: ") while (num != ""): sum = sum + float(num) # eval function converts # a string to a number count = count + 1 num = input("Enter a number, <Enter> quits: ") print("You entered",count,"numbers") print("which have a mean of",sum/count)
This is the best version of this program yet.
1.9.0.3. Using while
loops to validate input
Here are three quick examples of how you can use a while
loop to validate a user's input.
# Program to validate input >0 positive_number = float(input("Enter a number >0: ")) while (positive_number <= 0): print("Error: please enter a positive number.") positive_number = float(input("Enter a number >0: ")) print("Thanks for entering",positive_number,"!")
Here's a slightly different way of doing the same thing, but using an initial "seed" value.
# Program to validate input >0 positive_number = -1 # This is a "pre-seed" while (positive_number <= 0): positive_number = float(input("Enter a number >0: ")) print("Thanks for entering",positive_number,"!")
Poor Programming Style: while
loop
This next version of the program uses a loop that would repeat infinitely, except for the fact that—once we get the positive number that we're looking for—we use the break
statement to break out of the loop.
# Program to validate input >0
while True: # This would be an infinite loop, but...
positive_number = float(input("Enter a number >0: "))
if positive_number > 0:
break # Exits the loop
print("Thanks for entering",positive_number,"!")
This loop operates just fine, but it's considered by most people to demonstrate poor style. Why? For a programmer reading through this code, the instruction while True:
is practically useless. The programmer understands that a loop is being entered, but it's unclear what the purpose of that loop is, at least not until later on in the body of the loop. It's far better to use the first versions of these two loops.
1.9.1. The for
loop
It's often the case that a loop needs to count through a series of values. A while
loop may be written for this purpose, but a for
loop is a quick, easy way of accomplishing the same thing.
The for loop
The for
loop has the following syntax:
for <variable> in <sequence>: <statement> <statement> <statement>
The <sequence> may be:
- an actual sequence of values, like
[1,3,5,7,9]
- something like
range(10)
, which begins at 0 and goes up to one less than 10 - something like
range(1,10)
, which starts at 1 and goes until the number before 10 - something like
range(1,10,2)
, which begins at 1 and goes up by 2 until just before 10 - some other sequence of values, like
['alice', 'bob', 'charlie', 'dave']
, which goes through the loop for times, with each name assigned in turn to the variable
Some examples:
for i in range(10): print(i)
for i in range(1,10): print(i)
for i in (1,10): print(i)
for i in range(1,10,2): print(i)
Use the explanation of the for
loop syntax in the green box above to analyze each of the following loops.
Predict the output
Predict what you think will be outputted by each of these loops. Then enter them into a program or the Python interpreter, and see what happens.
>>> for i in range(10): ... print(i+1)
>>> for i in range(0,20,3): ... print(i)
>>> for j in range(10,0,-1): ... print(j)
>>> for j in (10,0,-1): ... print(j)
>>> for i in (“Hello, world!”): ... print(i)
>>> for n in ("Anne","Bob","Coraline"): ... print(n)
Problem: 99 bottles of beer on the wall
Write a short program to print all the lyrics to the song "99 bottles of beer on the wall." The program should use a single function "print_lyrics," that takes a single integer parameter to print out a verse of the song. The main program should then call that function from inside a loop.
""" 99 Bottles of beer on the Wall, by Richard White This program prints out all the lyrics to the song using a function called from within a loop. Future improvements include: * When only one bottle, don't say 'bottles.' * At end, instead of 0, say 'No more...' """ def print_lyrics(num): print(num,"bottles of beer on the wall,") print(num,"bottles of beer.") print("Take one down and pass it around.") print(num - 1,"bottles of beer on the wall.") print() def main(): for i in range(99,0,-1): print_lyrics(i) if __name__ == "__main__": main()
1.10. Data Types: Strings
Java has the char
data type, identified by single quotes ('), and the String
type, identified with double quotes ("). In Python, there is just the str
("string") class. A string in Python can be identified by enclosing double-quotes ("I'm a string"
) or enclosing single-quotes ('He said "Help!"'
).
If you want to print a double-quote mark while you're using double-quotes to indicate a string, but a backslash \
in front of it:
print("So then he said, \"Help!\" ") # Produces the output So then he said, "Help!"
1.10.0. Basic Strings and Slicing
The str
data type
The str
(string) data type is used to work with alphanumeric text.
A string consists of a series of characters, designated as a string by surrounding them with either single quotes (') or double quotes (").
>>> print("Hello, world!")
>>> username = input("Please enter your name: ")
A string is simply a sequence of zero or more characters, and we can easily refer to individual characters by their index, or position in the string.
Slicing
Accessing a string via its indices is called slicing. The indices are referred to by enclosing them in square brackets ([ ]).
Note that the indices for the characters in a string start at 0, not 1. Thus, if password
= "secret", password[1]
is "e", not "s".
Try these
Predict what will be produced by each of the following statements.
greet = "Hello, world!" print(greet[1]) print(greet[0], greet[12]) print(greet[7:12]) print(greet[-1]) print(greet[0:4]) print(greet[7:]) print(greet[:5]) print(greet[1:-1])
greet = "Hello, world!" print(greet[1]) # --> e print(greet[0], greet[12]) # --> H! print(greet[7:12]) # --> world! print(greet[-1]) # --> ! (1 character, starting counting from back) print(greet[0:4]) # --> Hell (counts up to the position one before 4) print(greet[7:]) # --> world! (no value after colon defaults to end of string) print(greet[:5]) # --> Hello (no value before color defaults to beginning of string) print(greet[1:-1]) # --> ello, world (from character at position 1 to one before last character)
1.10.1. Additional string operations
In addition to slicing, there are a number of string operations that may be useful:
More string functions
Predict what will be produced by each of the following statements.
a_string = "Hello" b_string = "world" print(a_string + b_string) # concatenation print(1 + b_string) # careful! print(3 * b_string) # repetition print(len(b_string))
a_string = "Hello" b_string = "world" print(a_string + b_string) # --> hello_world print(1 + b_string) # --> Unsupported operand print(3 * b_string) # --> worldworldworld print(len(b_string)) # --> 5
1.10.2. String Methods
Just as in Java, Python includes the concept of an object. In Python, just about everything is an "object." The objects "Richard", "Fletch", and "Ms. Bush" are all objects of the class string. The function main() is an object of the class function. The values 3, 17, and -204 are all objects of the class integer.
Because we're looking at strings right now, let's take a look at some string methods that you can use to manipulate the string in question.
How to use a Method
You use a method by indicating the object being used, a period (.), and the method name followed by a pair of parentheses. Depending on the method you're using, there may be arguments that you'll need to include in the parentheses.
Example: "Mississippi".count("s")
uses the string method "count" to count the number of "s"s in the string "Mississippi" and gives us a value of 4.
Here are some other string methods that you may find useful at some point.
Predict the Output: String methods
Predict what will be produced by each of the following statements, and try them out in the Python interpreter to get some familiarity with them.
name = "jules verne" print(name.capitalize()) print(name.title()) print("DON'T SHOUT!".lower()) print(name.upper()) print(name.replace("jules","phileas")) print(name.split()) # splits into a list, default separator is a space " " print("Wow. That's cool. Right?".split(".")) print(name.find("verne")) print(name.count("e")) print(" ".join(["i","love","you"])) # Joins a list of items into a string separated by " "
name = "jules verne" print(name.capitalize()) # --> Jules verne print(name.title()) # --> Jules Verne print("DON'T SHOUT!".lower()) # --> don't shout! print(name.upper()) # --> JULES VERNE print(name.replace("jules","phileas")) # --> phileas verne print(name.split()) # splits into a list, default separator is a space " " # --> ['jules', 'verne'] print("Wow. That's cool. Right?".split(".")) #--> ['Wow', " That's cool", ' Right?'] print(name.find("verne")) # --> 6 print(name.count("e")) # --> 3 print(" ".join(["i","love","you"])) # --> "i love you"
Problem: Censorship
Write a main program that takes a line of text input from user, and then passes that input to a function called censor
. That function takes the original string, searches it for the word "hell", and returns a copy of the original string with all instances of the word "hell" replaced by four asterisks ("****").
Problem: Guess the Game
Write a function that takes a string and returns the number of vowels in the string. Then write a main program that asks the user to enter two words. If the number of vowels in the two words is the same, the user loses the game; otherwise, they can keep playing, entering two more words. Can the user guess the rules of the game?
1.11. Data Types: Lists and Tuples
In Java there are a number of types of data that can store a sequence of objects, including Array
s and ArrayList
s. In Python, the list
type is used.
1.11.1. Intro to lists
and tuples
The list data structure
A list
is a sequence of data values. Lists may be made up of any type of value: strings, ints, floats, even other lists. Lists are indicated with square brackets enclosing the items in the list, which are separated by commas.
my_data = ['Richard','White','626-845-1235',50]
my_fingers = [1,2,3,4,5,6,7,8,9,10]
friend_list = ["Kathy","Dana","Gary"]
Individual items in a list can be referenced by their index enclosed in square brackets, or by using an "enhanced"-style for
loop.
my_phone_number = my_data[2]
for i in range(len(friend_list)): print(friend_list[i])
for friend in friend_list: print(friend)
Try these
What do you think this code will produce as output?
mylist = ["A","B","C","D","F"] print(mylist[2]) print(mylist[3:4]) # careful! print(len(mylist)) print(mylist[:]) print(mylist[::-1])
print(mylist[2]) # --> C print(mylist[3:4]) # --> D print(len(mylist)) # --> 5 print(mylist[:]) # --> ["A", "B", "C", "D", "F"] print(mylist[::-1]) # --> ["F", "D", "C", "B", "A"]
You can see that we can use some of the same strategies on lists
that we used on strings.
The tuple
data structure
The tuple
is another type of sequence of data values, very similar to a list. A tuple is indicated by the values, separated by commas, and surrounded by parentheses.
friend_tuple = ("Jill","Brad","Brian")
student_scores = (98, 45, 12, 103, 55)
You can reference the items in a tuple
the same exact way that you access it if it were a list of items:
for i in range(len(friend_tuple)): print(friend_tuple[i])
for friend in friend_tuple: print(friend)
The difference between the list
and the tuple
is that lists are mutable—we can change the list by adding and removing values or altering the values themselves—while a tuple
is immutable. Once it has been created, the series of values can't be changed.
Why you would want to have a series of items that can change when you could just as easily have a series that offers more flexibility is a bit beyond the scope of this class. :)
So, Lists and tuples both store ordered collections of data, referenced in the same way: friend_tuple[1]
or student_scores[2]
. The difference between a list
and a tuple
is that a list
is mutable (changeable) whereas a tuple
is immutable (unchangeable).
So I can add and remove friends from my list
of friends:
friend_list.append("Owen") friend_list.remove("Gary") friend_list.pop() # by default, removes the last item in the list friend_list.pop(0)
If I try to do any of those things with my friend_tuple
, I get error messages. The .append()
, .remove()
, and .pop()
methods don't exist for tuples.
1.11.2. Using lists
1.11.2.0. Iterating through a list
How are lists so powerful? Just as we've used a for
loop to run through a range of numbers, we can easily set up a loop to run through a series of items in a list.
As in Java, there are two strategies for going through a list. Which way you'll choose to write your list iteration depends on what you need to do.
Looping through a list with an index variable
You could run through the items in the list this way:
CODE: shopping_list = ["apples", "oranges", "bananas"] for i in range(len(shopping_list)): print("I need to buy",shopping_list[i]) OUTPUT: I need to buy apples I need to buy oranges I need to buy bananas
Here, the index i
changes as we go through the list, so each time we refer to shopping_list[i]
, we get a new value. This is the loop to use if you want to remember the location(s) of specific value(s) in your list as part of the program you're writing.
Looping through the list with an iterator
You can also go through all the items in the list this way, using iteration:
CODE: for item in shopping_list: print("I need to buy",item) OUTPUT: I need to buy apples I need to buy oranges I need to buy banana
Just as in a for
loop with numbers, this loop will repeat: the first time through, item
will represent the first piece of data in the list shopping_list
("apples"), the second time through it will be "oranges", and the third time through, "bananas".
The advantage to this loop is that you don't need an index variable like i
to refer to each item in the list. The disadvantage is that this loop runs through each item once, from beginning to end. If you need more flexibility in your program, you'll need to use the index-strategy mentioned above to go through the loop.
1.11.2.1. Some list operations
Useful list operations
Some of the more useful operations that can be performed with lists include:
shopping_list = [] # initializes an empty list that can be used to store items list_A + list_b # concatenates two lists into one list_A * <integer> # repeats a list a number of times list_A[n] # gets the item located at position n list_A[i:j] # slices a subset of list, starting at index i and ending at j-1 len(list_A) # determines the length of a list for j in list_A: # iterate through the list if (j in list_A): # boolean, checks to see if an item is in the list
1.11.2.2. Problems
Maximum of 7 values in a list
Write a program that puts the numbers 2, 6, 4, 12, 90, 15, 13 into a list, and then write a loop that goes through the list one by one to find the largest number in the list.
Here are a couple of ways to do that. This first way goes through the list using an index variable.
numberList = [2, 6, 4, 12, 90, 15, 13] position_of_max = 0 # First number is the biggest we've seen for i in range(1,len(numberList)): if numberList[i] > numberList[position_of_max]: position_of_max = i # And now that we've gone through the whole list... print(numberList[position_of_max])
This second way iterates through the list without an index variable:
numberList = [2, 6, 4, 12, 90, 15, 13] maxValue = numberList[0] # First number is the biggest we've seen for number in numberList: if number > maxValue: maxValue = number # And now that we've gone through the whole list... print(maxValue)
Sometimes it's useful to be able to make a short list of items and then use that list of items to help solve a larger problem.
In this next problem, we're going to use a list of the vowels (not including 'y'): vowels = ['a','e','i','o','u']
. We're also going to use a powerful boolean operator in
to identify when a letter is in that list:
vowels = ['a','e','i','o','u'] my_letter = "j" if my_letter in vowels: print("We found a vowel!")
Finding vowels
Write a program that asks the user to enter a word, and then tells them how many vowels there are in the word. The program should use a list called vowels
which stores the 5 vowels in it. When the program runs through the word entered by the user, it will check each character in the input word to see if that character is in the list of vowels, and increment a counter when one is found. After going through the word, print out the number of vowels found.
Here's one solution:
user_word = input('Please enter a word: ') vowel_count = 0 vowels = ['a','e','i','o','u'] print("The vowels in your word are: ", end='') for letter in user_word: if letter in vowels: print(letter, " ", end='') vowel_count += 1 print("There were",vowel_count,"vowels.") print("I'm terribly sorry if I missed any 'y's.")
Can you see how to improve the program to look for the occurrence of y's, but perhaps only count them if no other vowels have been found?
userWord = input('Please enter a word: ') vowel_count = 0 y_count = 0 print("The vowels in your word are: ", end='') for letter in user_word: if letter in ['a','e','i','o','u']: print(letter, " ", end='') vowel_count += 1 elif letter == 'y': y_count += 1 if vowel_count == 0: if y_count > 0: print(y_count * 'y ') # Prints out y letters else: print("non-existent.") print("I don't think you entered a real word.")
Problem: Censorship, part 2
Write a main program that takes a line of text input from user, and then passes that input to a function called censor
. That function takes the original string, searches it for any of the bad_words
"hell", "darn", "fart", and "dummy," and returns a censored copy of the original string. Each letter of the bad word should be replaced by an asterisk in the censored version (ie. "darn" will be replace by "****" and "dummy" will be replaced by "*****".)
1.11.2.3. List methods
Most programs that involve lists will need to manage them dynamically, adding items, deleting items, or reordering the items.
List methods
List methods that you may find helpful include:
list_A.append(x) # add an element to end of list_A list_A.sort() # sort list_A list_A.reverse() # reverse list_A list_A.index(x) # find the first location of x in list_A list_A.insert(i, x) # insert x into list_A at index i list_A.count(x) # count how many occurrences of x in list_A list_A.remove(x) # remove the first occurrence of x from list_A list_A.pop(i) # returns element i from list_A, and removes it from list list_A.pop() # acts on the last item of the list.
Make a list
A common need is to have a program make a list of items. Write a short program that initializes an empty list shopping_list
, and then uses a while
loop to repeatedly ask the user to enter items that s/he need to pick up at the store. The loop will add each item to shopping_list
until the user enters nothing (""). The entire shopping list should then be printed out.
print("Enter a list of items to get at the store.") shopping_list = [] more_items = True while more_items: an_item = input("Enter an item (<Enter> to stop)") if an_item != '' shopping_list.append(an_item) else: more_items = False print("When you go to the store, you need to get: ") for item in shopping_list: print(item)
You may find it useful to convert from strings to lists, or vice versa.
Converting between strings and lists
.join()
takes the elements from a list and assembles them into a string, with each element separated by the indicated separator.
my_friends = ["Kathy","Dana","Gary"] print(','.join(my_friends)) Kathy,Gary,Dana
To just convert the list to a string without any separators, use''.join(myList)
.split()
takes a string and splits it up into a list, with the specified separator (a space in the example below) used to separate elements of the list.
words = "I love you dearly!".split(" ") print(words) ['I', 'love', 'you', 'dearly!'] for word in words: print(word) I love you dearly!
A list of primes
Write a program that creates a table of the first thousand primes. Recall that a prime number is an integer greater than 1 that is evenly divisible only by itself and 1.
Your prime numbers should be stored in a list called "primes," and your strategy should consist of:
- identifying the number you are about to check for "primeness"
- going through the list of previous primes and seeing if any of them divide into the number evenly. If a prime number does divide evenly into the number we're checking, it's not prime and we can stop looking.
- if none of our prime numbers divide into the number we're checking, then this number must be prime, so add it to the list of prime numbers.
- loop back up to get the next number to check for primeness
Prime # Prime Value 1 2 2 3 3 5 4 7
1.11.2.4. Nested lists → a list inside a list
Just as we can nest if-else
statements inside other if-else
statements to work on multiple levels of a problem, we can nest loops inside other loops.
1.11.6.0. Nested counting loops
This demonstrates an odometer effect.
odometer.py
Enter this program and run it to see what effect is produced.
#!/usr/bin/env python3 """ odometer.py Demonstrates an odomter using nested loops with print formatting and clear screen function. """ import os # needed to clear the screen import time # needed to slow down the counter def main(): for i in range(10): for j in range(10): for k in range(10): print("{0:1d}{1:1d}{2:1d}".format(i,j,k)) time.sleep(0.1) os.system("clear") # may need to be altered for your system if __name__ == "__main__": main()
1.11.2.5. Nested loops for traversing a grid
One very common type of loop pattern involves using two loops to work through a 2-dimensional grid or table.
What does this nested loop do?
print(" | 0 1 2 3 4 5 6 7 8 9") print("--+------------------------------") for row in range(10): print(row,"|",end='') for col in range(10): print("{0:3d}".format(row * col), end='') print()
This program, after printing out a couple of header lines, has a row
loop that runs from 0 to 9. Inside that loop is a second col
loop that takes on the values 0 to 9. The print
statement uses formatting to print out the product row * col
in a space that's 3 characters wide. The effect:
| 0 1 2 3 4 5 6 7 8 9 --+------------------------------ 0 | 0 0 0 0 0 0 0 0 0 0 1 | 0 1 2 3 4 5 6 7 8 9 2 | 0 2 4 6 8 10 12 14 16 18 3 | 0 3 6 9 12 15 18 21 24 27 4 | 0 4 8 12 16 20 24 28 32 36 5 | 0 5 10 15 20 25 30 35 40 45 6 | 0 6 12 18 24 30 36 42 48 54 7 | 0 7 14 21 28 35 42 49 56 63 8 | 0 8 16 24 32 40 48 56 64 72 9 | 0 9 18 27 36 45 54 63 72 81
It's a multiplication table!
Let's try writing another nested loop and using it to print something.
The drawboxes
program
Write a program called drawboxes
that asks the user to enter a number. The program then uses that number as a parameter in a function called Boxy
which prints out a large box composed of that many "square-bracket boxes" printed on the screen.
If the user enters 3, for example, the program will need to call the function Boxy(3)
, which will then produce the output:
[][][] [][][] [][][]
Just as above, we need to print a box composed of rows of square brackets, with each row consisting of columns of square brackets.
def Boxy(n): for i in range(n): for j in range(n): print("[]",end = '') print() # go down to the next line
Once you've master the basic Boxy function, try this one:
The drawrectangles
program
Modify the previous program so that it draws rectangles. The user enters a width and a height in the main program, and a modified version of your Boxy
function takes that information and uses it to print an appropriate figure composed of "[]" as before.
One of the challenges of this assignment is getting the length and width of the rectangle to display correctly on the screen.
1.11.3. Working with External Files
Let's get some practice working with a real-life data set: sowpods.txt a 2.7MB text file that lists the legal words that can be used in the game of Scrabble.
Download a copy of that file on your computer, and use it to solve the following problems.
How To: Read a text file into a list
To use this text file, you need to get all of the items in the file into a list
in your program.
#!/usr/bin/env python3 """ Read a text file into a program; put each line of the file into a list. """ filename = "sowpods.txt" # must be in same directory as # program, or have correct path infile = open(filename, "r") # sets up a file object that we # can read lines from wordlist = infile.readlines() # brings the lines into a list # called 'wordlist' infile.close() # properly close the file # Each file is read as a line with a \n newline character at the end. # We need to strip those off, and maybe convert them to lowercase? for i in range(len(wordlist)): wordlist[i] = wordlist[i].lower().rstrip() # convert to lowercase # and strip off the # newline character # show that we got the list of words for word in wordlist: print(word)
Note that some of these commands can be combined and streamlined by using "Pythonic" strategies, such as this one-line command that reads the same file and stores the words in a list.
wordlist = [line.lower().strip() for line in open("sowpods.txt")]
Identify words that start with 'x'
Write a short program that produces a new list of only the words that begin with the letter 'x'.
Assuming that you've already read all the words into a list called wordlist
:
x_words = [] for word in wordlist: # "enhanced" for-loop if word[0] == "x": x_words.append(word) print(x_words) # Could also be written as an indexed for-loop for i in range(len(wordlist)): if wordlist[i][0] == "x": x_words.append(wordlist[i])
Identify words that only have vowels in them
Write a short program that produces a new list of the words that consist exclusively of vowels: a, e, i, o, u, and y.
Assuming that you've already read all the words into a list called words
:
vowels = ('a','e','i','o','u','y') vowel_words = [] for word in words: all_vowels = True for i in range(len(word)): if word[i] not in vowels: all_vowels = False break if all_vowels: vowel_words.append(word) print(vowel_words)
How To: Write a list to an external text file
You may wish to write the contents of a list to an external text file. This uses a process similar to the one we used to read a file. Note that if the filename we're writing to already exists, it will be overwritten by this new version of the file.
# Write the contents of the x_words list to a file filename = "x_word_file.txt" # the name of the external file outfile = open(filename,"w") # "w" indicates that we'll be writing for word in x_words: outfile.write(word + "\n") # Note that we're writing the text and # putting the newline character back in outfile.close() # properly close the file
1.11.4. List Comprehension
One of the uniquely Python features of working with lists is list comprehension, which is simply a shorthand strategy for creating lists from other lists.
1.12. Dictionaries
One of the most important data types that we haven't yet discussed is the dict
, for "dictionary." Dictionaries are used for manipulating unordered key-value pairs of information.
Let's see what that means.
1.12.1. Definition of a dictionary
Definition: Dictionary
A dictionary is a data type in Python that is unordered collection of key-value pairs, what most programming languages refer to as a hash.
An example of a simple dictionary might be this one, which tracks point-values for Scrabble letters:
scores = {"a": 1, "c": 3, "b": 3, "e": 1, "d": 2, "g": 2, "f": 4, "i": 1, "h": 4, "k": 5, "j": 8, "m": 3, "l": 1, "o": 1, "n": 1, "q": 10, "p": 3, "s": 1, "r": 1, "u": 1, "t": 1, "w": 4, "v": 4, "y": 4, "x": 8, "z": 10}
Each value before a colon above is called the "key" a unique value that cannot be shared with any other keys. The value after each colon is the "value" associated with that key—values do not have to be unique.
Once the dictionary scores
has been created, we can identify the value of any letter as follows:
>>> print(scores["j"]) 8 >>>
Note that the dict
data type stores its key-value pairs in an unordered format:
>>> print(scores) {'w': 4, 'i': 1, 'c': 3, 't': 1, 'x': 8, 'j': 8, 'a': 1, 'p': 3, 'f': 4, 'g': 2, 'h': 4, 'v': 4, 'r': 1, 'k': 5, 'l': 1, 'm': 3, 'b': 3, 'z': 10, 'o': 1, 'u': 1, 'e': 1, 'q': 10, 'd': 2, 's': 1, 'y': 4, 'n': 1} >>>
The only way to reference the "value" is by using its associated, unique key.
>>> word_sum = 0 >>> for letter in word: ... sum = sum + scores[letter] ... print("The value of the word is", sum)
1.12.2. Dictionary Methods
There are a number of dict
methods that can come in handy:
len(d) # Number of elements in d d[k] # Item in d with key k d[k] = v # Set item in d with key k to v del d[k] # Delete item k from dictionary d d.clear() # Remove all items from dictionary d d.has_key(k) # Return 1 if d has key k, 0 otherwise d.items() # Return a list of (key, value) pairs d.keys() # Return a list of keys in d d.values() # Return a list of values in d d.get(k) # Same as d[k]
1.12.3. Common Use of Dictionaries
A common use of a dictionary is to tabulate freqencies for a series of values.
Trace through this code or try it out on the computer and see how it works.
#!/usr/bin/env python3 """ letter_frequencies.py """ # Get an input string from the user sentence = input("Enter a sentence: ") # Split string up into a list of letters letters = [] for letter in sentence: letters.append(letter.lower()) # Put the letters into a dictonary by frequency count letter_counts = {} for letter in letters: letter_counts[letter] = letter_counts.get(letter, 0) + 1 # Print out the results for letter in sorted(letter_counts.keys()): print("{0:15s}|{1:3d}".format(letter, letter_counts[letter]))
1.13. List Comprehension, External Files
""" quick_dirty_reader.py This program demonstrates how you can quickly import a text file into a Python program where you can split it up into tokens and do analysis on it. """ __author__ = "Richard White" __version__ = "2022-11-30" # read all of the lines into memory with open('data.txt',encoding='utf-8') as infile: # use list comprehension # rstrip() cleans off the newline character on each line lines = [line.rstrip() for line in infile] # Now we can... # 1. print each line for line in lines: print(line) # 2. or take a line and separate it into commas-separated values for word in lines[0].split(','): print(word) # 3. or maybe they're numbers instead? Go through and make a list # of the numbers nums = [] for word in lines[0].split(','): nums.append(int(word)) # 4. Now do something with the numbers print("Adding up all the numbers!") total = 0 for i in range(len(nums)): total += nums[i] print(total)
1.14. Object-Oriented Python
Most people first learning Python don't get a chance to dig into object-oriented programming very deeply, if at all.
We're going to fix that, starting now.
1.14.1. Object-Oriented Principles
You've already been exposed to the principles of Object-Oriented Programming: similar types of objects are organized as classes, with each class describing the instance variables that describe an object, and the methods that can be used to interact with the object.
If you understand this description, the following examples will introduce you to the syntax of objects as they are treated in Python.
And if you're a little hazy on object-oriented principles, looking at this code is a great way to re-introduce yourself to the subject.
1.14.2. The Die
class
The Die
class is a great place to start learning about simple objects. Take a look at the code below and see if you can figure out what's going on.
#!/usr/bin/env python3 """ die.py The Die class is used to create Die objects. This class and its accompanying tester program in the main() below is to give a simple example of 1. writing a class 2. writing a constructor 3. creating instance variables 4. writing an accessor method 5. writing a mutator method 6. using the class in a program """ import random class Die(object): """ The Die class represents a Die object of an arbitrary number of sides. """ def __init__(self, number_of_sides): """This is Python's constructor syntax, which is used when an instance of a Die object is created. """ self.number_of_sides = number_of_sides self.roll() # Give the die an initial value def roll(self): """Rolls the die to get a new result, and returns that result. """ self.result = random.randrange(self.number_of_sides) + 1 return self.result def view_result(self): """Allows the client program to look at the current roll result. """ return self.result def cheat(self): """Change the result upward by one, if that won't make it too high. """ if random.randrange(5) > 0: # 80% chance of increasing value cheat_amount = random.randrange(1,3) # 1-2 inclusive if self.result + cheat_amount <= self.number_of_sides: self.result += cheat_amount def main(): d1 = Die(6) print(d1.view_result()) print(d1.roll()) print(d1.view_result()) d1.cheat() print(d1.view_result()) if __name__ == "__main__": main()
1.14.3. The Fraction
class
The Fraction
class is a great place to start learning about the writing of non-trivial classes.
It's also a great way to learn a little more about Python syntax, and how we can use overriding to make better use of the classes we're writing.
The Fraction
class is described in some detail in our book. The instructor will share some detail on how to develop Fraction
in class. You may also want to look at this fraction_tester.py that you can use to test the progress of your own class as you write it.
1.13.4. Inheritance
One of the most important aspects of object-oriented programming is the idea of inheritance, in which superclasses—and their accompanying instance variables and methods—can be extended, and leveraged by subclasses which inherit their capabilities.
1.13.4.1. Example of Inheritance
Once you've created a class, it's possible to make sub-classes that inherit the properties of the super-class, but also expand on those properties.
Take a look at this minimal example showcasing the interactions between classes.
#!/usr/bin/env python3 """ persons.py Demonstrates the use of classes, subclasses, arrays of objects, and the instanceof() function. """ __author__ = "Richard White" __version__ = "2019-02-07" class Person(object): """Describes a person in terms of their name.""" def __init__(self,name): """Used to construct a Person object""" self.name = name def get_name(self): """Returns the name of the Person""" return self.name def __repr__(self): """Returns a representation of the Person that can be printed""" return "Person[name=" + self.name + "]" class Student(Person): """Describes a Student subclass that inherits from the Person superclass""" def __init__(self, name, gpa): """Constructs a Student object. The name parameter *must* be sent to the super class using the instruction super().__init__(parameters) This initializes the inherited instance variables """ super().__init__(name) self.gpa = gpa # initializes the local variables def get_gpa(self): return self.gpa def __repr__(self): """Returns a representation of the Student class. Notice how it references the superclass's __repr__ method. """ return "Student[" + super().__repr__() + ",gpa=" + str(self.gpa) + "]" class Teacher(Person): def __init__(self, name, salary): super().__init__(name) self.salary = salary def get_salary(self): return self.salary def __repr__(self): return "Teacher[" + super().__repr__() + ",salary=" + str(self.salary) + "]" def main(): p = Person("Joe") print(p.getName()) print(p) s = Student("Mary",3.7) print(s) t = Teacher("Mr. White",50000) print(t) school_population = [] school_population.append(p) school_population.append(t) school_population.append(s) print("----------------------") for member in school_population: print(member.get_name()) if isinstance(member,Teacher): print(member.get_salary()) if __name__ == "__main__": main()
1.14.4.2. The Clothing
class
Consider a Clothing
class which is going to describe an article of clothing. For out initial consideration of this class, we'll define any clothing object in terms of three values (instance variables):
- its name ("t-shirt", "sweater", "favorite pants", "jeans", etc.)
- its color("white", "blue", "khaki", etc.)
- whether it's clean (
True
if it's clean,False
otherwise)
There are plenty of other characteristics that you could use to describe an article of clothing, but let's begin with these in the interest of keeping things manageable.
What kind of methods do you think you would need to interact with a Clothing
object?
Think about it for a moment, and then watch this video.
Object-Oriented Programming in Python, part 11.14.4.3. The Shirt
class
Now that we've figured out what the Clothing
class is all about, let's think about a subclass called Shirt
that extends the Clothing
class, and inherits from it.
Watch this video to get some idea of how you write a subclass in Python.
Object-Oriented Programming in Python, part 21.14.4.4. The Wardrobe Project
Now, you're ready for the Wardrobe project.