Programming Techniques#
Objectives#
To use control structures to clean and transform data in an automated way
To write basic functions to reduce redundancy
To interpret Python exceptions (error messages) in order to fix bugs
Introduction#
The Python language offers many other tools and techniques to make code more robust, reusable, and efficient. One way to think about these tools and techniques is that they help us write programs as opposed to writing code, a program being some code that is designed for use by different users in different contexts. Even if you are the only user of your code, applying these programming techniques can make your work more productive and your code more effective.
This notebook is intended for you to work through independently, in order to review and clarify the concepts introduced on Python Camp Day 2, and to lay the groundwork for the activities on Python Camp Day 3. However, feel free to collaborate with others in working through it. It is also intended to serve as a resource you can return to review as necessary.
How to Use this Notebook
Read the documentation above each cell containing code and run the cell (
Ctrl+Enter
orCmd+Return
) to view the output.Follow the prompts labeled
Try it out!
that ask you to write your own code in the provided blank cells.(Hidden) solutions to these exercises follow the blank cells; click the toggle bar to expand the solution to compare with your approach.
Some prompts include alternative exercises (Parsons Problems) that will be linked from the prompt. These alternatives may help clarify concepts (especially if you find yourself struggling to keep up with all the syntax).
Optional annotations (labeled
For the curious...
) provide additional explanation and/or context for those who want them. Feel free to skip these sections if you like. As a beginner, it’s important to maintain a balanced cognitive load: taking in too much information all at once can impede your progress toward understanding. This balance looks different for everyone, but we have tried to keep the main content focused on a few key concepts, tools, and techniques, while providing that additional context for those who might benefit from it.
I. Loops & lists#
I.1 Doing things with strings & lists#
The real power of lists enters when we can use them to automate repetitive tasks.
In “Modeling Code” and “Describing the Team” we used what’s called a for loop to adjust items in a list. Here we’ll work up to the same sort of task, step by step, but we’ll add a couple of enhancements.
For this example, we’ll start with a list of strings representing book prices.
book_prices = ['$55.99', '$119.95', '$13.95', '$250.67', '$99.99']
First, let’s just print each price from the list on its own line.
for price in book_prices:
print(price)
Notes
Our loop begins with the Python keyword
for
. This is not a function – likelen()
orprint()
– but part of the Python syntax itself (like the quotation marks around strings or the square brackets around lists).for
always goes within
; they make a pair.The variable
price
, immediately followingfor
, is being created here. (It was not previously defined in our code.) Its role is to hold – in sequence – each item in the collection followingin
.book_prices
was defined before the loop. The variable followingin
should always be some sort of collection type – a string, a list, a dictionary, etc. – or else a function that returns a collection. We cannot writefor x in 10
, for instance, because the integer10
is not a collection; it holds no items within itself. (For the same reason, we can’t take a slice of10
.)The first line of the
for
loop ends in a colon, and the line or lines underneath it are indented (separated from the left margin by the same number of tabs or spaces). We call these indented lines in Python a block.
Animation
To help you visualize what’s happening inside for
loop, here’s an animation of looping over a list of float values.
As this animation demonstrates, the loop variable, price
, holds the last value in the list once the loop has finished.
Try it out!
All of the prices follow the same format, beginning with the dollar sign. To calculate the sales tax, we need to multiply each price by a fixed percentage – let’s say 110%, or 1.1, to reflect a sales tax of 10% on the dollar.
But as we saw above, we can’t perform math with strings, and book_prices
is a list of strings. To convert our strings to numbers, we first need to remove the dollar sign from each price.
Modify the for
loop above so that it prints each price without the dollar sign. For a hint, consult the example from yesterday’s homework where we created the variable course_section
.
# Your code here
Now check your answer by expanding the hidden solution cell below.
Show code cell content
for price in book_prices:
print(price[1:])
Try it out!
Now that we have extracted the numeric part of the string (the part after the dollar sign), we can convert this string to a float in order to do math with it.
Modify the for loop again to do the following:
Assign the slice of the price (without the dollar sign) to a new variable called
price_num
.Use the
float()
function to convertprice_num
to a float, and multiply the result by1.1
.For instance, to convert the string
"1.5"
(notice the quotations marks!) to its float representation, we would writefloat("1.5")
.Assign the result of this calculation to
price_num
and print it.
If the foregoing feels intimidating, try this Parsons Problem first. It allows you to focus on the logical order of the actions to be performed, rather than on the syntax of the commands.
# Your code here
Now check your answer by expanding the hidden solution cell below.
Show code cell content
for price in book_prices:
price_num = price[1:]
price_num = float(price_num) * 1.1
print(price_num)
II.2 From one list to another#
If you didn’t get the intended answer, don’t worry! You’ll get the hang of it. The most important thing for now is to understand that we used a for loop because we wanted to repeat a certain set of actions for all the items in a list.
For now, let’s add one enhancement to our loop: instead of just printing the new price (with the added sales tax), we’ll store it in a separate list.
To do this, we need to use a method of Python lists called append()
. This method adds a new item to the end of a list.
Much like the split()
method we used on strings, the append()
method can be called from any Python list by writing the name of the list plus .append(item)
, where item
is the value we want to add to the list.
See the code below and the explanation that follows.
prices_with_tax = []
for price in book_prices:
price_num = price[1:]
price_num = float(price_num) * 1.1
prices_with_tax.append(price_num)
print(prices_with_tax)
Notes
This loop achieves the same thing as the previous, with this difference: the adjusted prices are now stored in the prices_with_tax
variable, which is another list. This is a fairly common Python pattern; when using this pattern, here are a few rules of thumb to keep in mind:
We need to create the new list outside of the loop. The line
prices_with_tax = []
creates a new variable that consists of an empty list.As before, we use the loop variable
price
to work with each item in thebook_prices
list.The variable
price_num
is temporary, in the sense that, like theprice
loop variable, it will change (be reassigned to a new value) with every iteration of the loop.The line
prices_with_tax.append(price_num)
stores the value inprice_num
to our list. Without this step, we could not “save” the results of our calculations. It’s like performing a series of steps on a calculator: if you don’t write down your answer before moving onto the next problem, you will lose all your hard work!Steps 2, 3, and 4 are all indented underneath the line that kicks off the for loop. Visually, this tells you that all of these steps happen on each iteration of the loop (once for every item in the
book_prices
lists.The line
print(prices_with_tax)
is not indented, meaning that it will be executed after the for loop completes. That’s because we only want to print our new list when it’s finished, not every time we add a new item to it.Note that our
book_prices
list still holds the original strings: our code made a new, second list.
print(book_prices)
Try it out!
We have a list of strings that represent courses, where each string (as in the example above) consists of a department code, a course number, and a section number:
courses = ['CHEM 1001 10', 'CHEM 1001 11' ...]
Using a for loop, transform this list into three separate lists:
one to hold the department codes,
one to hold the course numbers,
and one to hold the section numbers.
The cells below will get you started. For more help, check out this Parsons Problem.
courses = ['CHEM 1001 10', 'CHEM 1001 11', 'BISC 1111 10', 'BISC 2207 10', 'PSC 1001 10',
'PSC 1001 11', 'PSC 1001 12', 'ANTH 3808 10', 'AMST 2071 80']
depts = []
course_nums = []
sections = []
# Your code here
Now check your answer by expanding the hidden solution cell below.
Show code cell content
for course in courses:
course_info = course.split()
depts.append(course_info[0])
course_nums.append(course_info[1])
sections.append(course_info[2])
print(depts)
print(course_nums)
print(sections)
II. Writing Functions#
We’ve met a number of functions and methods so far on our journey through the Python language. See how many you can name before expanding the cell below.
Hint
print()
: Displays one or more values on the screen.type()
: Returns the data type of a value.len()
: Returns the length (as an integer) of a list or string.float()
: Converts a string or integer to a float.open()
: Opens a file for reading or writing.str.split()
: A string method, it returns a list of strings derived by separating a string on some character (white space by default).list.append()
: A list method, adds an element to the end of a list.json.load()
,json.dump()
: Methods defined in thejson
Python module, which format Python data types for storage in the JSON format.
Functions and methods may feel pretty inscrutable. Unlike lists and dictionaries, we can’t “look inside” them to see what they consist of, the way we examined bkst_data
to determine its structure. (We can read the source code for functions and methods, but unless you know what you’re looking for, that’s not always helpful.)
But in what follows, we’ll demystify functions a bit by writing our own.
A function (or a method) is just a way of encapsulating code. It’s like a shortcut on your computer (e.g., like hitting Ctrl+S
or Cmd+S
in order to save the current document, etc.). Functions make it easier to do the same thing multiple times without having to repeat yourself.
They can also help make your code more legible and easier to reason about.
II.1 Defining vs. calling functions#
Below is a simple Python function that prints a message to the screen.
def print_message():
print("Hello from my function!")
Notes
When you run the above cell, you shouldn’t see any output. That’s because defining a function and using the function are two separate operations.
Let’s unpack our function definition, piece by piece:
The
def
keyword tells Python that we’re defining a function.We have to give our function a name, following the same rules as for Python variable names (only letters, numbers, and underscores; must begin with a letter).
As with variables, our function names should be unique. We don’t want to give a function the same name as an existing Python function. For instance, calling this function
print
would overwrite the built-in Pythonprint()
function, which would mean that we could no longer use the latter.Immediately after the function name, we need parentheses. Here the parentheses are empty because this function takes no arguments. We’ll look at arguments later.
Then there’s a colon (
:
), followed by an indented block (as in the for loops you wrote today).The code in the indented block is the body of the function. The function body is what will be executed when we call the function
print_message()
In the cell above, we called the print_message()
function. Calling a function, like defining a function, requires the parentheses, even when there are no arguments. The presence of the parentheses lets Python know that it should execute the code within the body of the function.
II.2 Arguments and return values#
We write functions and methods in order to be able to re-use code in different contexts. Basically, it saves us from having to repeat ourselves.
But our print_message()
always prints the same message, which is not likely to be very useful.
Most functions are used to transform data in some way. Such functions take some input and return some (different) output. Examples you’ve seen so far include the following:
function name |
input |
output |
---|---|---|
|
a string or a list |
an integer |
|
the name of a file as a string |
a file handle (for working with the file’s contents) |
|
a string |
a float |
|
one or more values of any Python type |
those values, displayed on the screen |
The arguments in the function definition are variables that hold the input. These variables are used within the body of the function (in the block of code that comes after the def
line).
In order to produce output, a function will usually return a value, using the return
keyword. return
will usually start the last line of the function.
For instance, the function below calculates sales tax on a given price.
def add_sales_tax(price):
# Price should be a numeric value
# Returns the price + 10% for sales tax
price_with_tax = price * 1.1
return price_with_tax
Now we can use the add_sales_tax
function with any price (provided we give it a float or integer for the price
argument).
prices = [9.99, 11.99, 55.95, 100.19]
for p in prices:
print('Price is', p)
price_with_tax = add_sales_tax(p)
print('Price with tax is', price_with_tax)
Notes
In the code above, we called
add_sales_tax
inside a for loop, passing it the loop variablep
in parentheses.During the execution of the function, the value of
p
is copied into to theprice
variable (which is internal to the function).We are calling
add_sales_tax()
inside our loop, and assigning the result to theprice_with_tax
variable. Like the loop variablep
,price_with_tax
receives a new value on each iteration of the loop.
Try it out!
Write a function, dollars_to_float()
, to convert a string starting with a dollar sign to a float. You’ve used this code before – now encapsulate it in a function so that you can re-use it in the future without retyping it.
Don’t forget to return
something, otherwise your function will have no effect!
Once you’ve written your function, test it by calling it on the following strings:
'$10'
'$9.99'
'$200.00'
# Your code here
Show code cell content
def dollars_to_float(dollar_amt):
# Converts a string prefixed with a dollar sign to a float
amt = dollar_amt[1:]
return float(amt)
If you wrote the function as shown above (in the collapsed cell), you should be able to get the intended result for all three examples.
But an amount containing a comma should produce a ValueError
:
dollars_to_float('$10,000.00')
III. Errors & Exceptions#
Errors can be jarring. For many of us, error messages on the computer inspire frustration, even anger. They may even make us feel misunderstood, or else that we lack understanding, that we just don’t “get” it.
Learning to program (in virtually any language) involves learning how to deal with errors. There’s no such thing as a piece of software without “bugs,” if only because for any given piece of software, someone can find a way to use it for which it was not intended.
In the example above, we didn’t design the function specifically to work for strings with commas, and indeed, it doesn’t. The ValueError
– technically, this kind of error is called an exception – means simply that the Python interpreter encountered a kind of value it didn’t expect and doesn’t know what to do with.
Such errors/exceptions are valuable (no pun intended) to the programmer; they tell us where the bugs are (or might be) in our programs. Python even provides mechanisms for checking for errors proactively, so that our code doesn’t grind to a halt whenever it encounters one.
On Days 3 and 4, we’ll work more with errors and exceptions, and we’ll learn about an approach to writing code that uses errors to guide development.
For the curious
What’s the difference between an error and an exception?
Technically, even though they often have the word Error
in their name, most of the errors you’ll encounter when programming in Python are called exceptions. These describe situations where a line of code may or may not work, depending on other factors. These other factors include the rest of the code in the program, the input to the program, the environment in which the program is being run, etc.
The example above is an exception because the line return float(amt)
works except when amt
is a string that contains something besides numerals and a period.
Different from exceptions are syntax errors. A syntax error means that the line of code will never work because Python cannot parse it (i.e., interpret it correctly).
For example, the following line of code will produce a syntax error because I failed to close the quotation marks around the string argument to print()
:
print('Hello, cruel world!)
But in practice, this distinction doesn’t matter very much, so feel free to refer to both exceptions and syntax errors as errors!
Wrap up#
With for loops, we can automate actions that would otherwise be tedious, like calculating the sales tax of a (long) list of prices. And that’s one of the main reasons for learning to program: as the title of one popular book on Python puts it, “to automate the boring stuff”.
You wrote your first Python function, dollars_to_float
. You also encountered some Python error messages, which we’ll learn more about on Day 3.
You’ll use your dollars_to_float
function, as well as the skills covered in this homework, in the team exercises ahead.
By now, you have written Python code to solve various problems. Some problems could be solved in one or two lines; others (like finding the most expensive textbook in our dataset) required several lines of code.
Given all that you have learned so far, you could go on to solve many, many more problems using Python. In other words, we’ve covered the bare essentials; it’s one of the main advantages of Python (as a programming language) that these essentials can be covered in just a couple of days.