Lecture: Midterm Review & Exam
Lecture script · about 15–20 minutes spoken · Week 8
Opening
Picture a nursing student checking a dose calculator before a shift, or a business major double-checking the formula behind a sales report. Neither of them trusts the number until they know what the code will do. They predict, they read for the usual mistakes, and then they run it.
That's the habit this week builds. In Week 1 you learned to predict what a line prints and to read an error from its last line. Weeks 2 and 3 gave you values, types, arithmetic, strings, and slices. Week 4 gave you conditions and the if statement. Weeks 5 and 6 gave you the while loop, the for loop, and range. Week 7 gave you functions, return, and scope.
This week we look back at all seven, one short program per topic, and we add one new tool, a checklist of six classic slips. Then comes the midterm. After it, Week 9 opens the second half of the course with lists, where one name holds a whole pile of values and the checklist earns its keep.
Here's the plan for this lecture. We'll review the predict-then-run method, then values, then decisions, then loops, then functions. Then we'll build the checklist, check a chatbot with a run, and talk about what the midterm asks.
1. Predict, then run: the review method
Think about a weather forecaster. A forecast written after the rain has already fallen teaches nothing. The forecaster writes it down first, and then the day decides whether it was right.
Your review works the same way. The habit has a name in this course: predict, then run. It is the habit of writing down exactly what a program will print before running it, then running it and comparing, so that any gap between the prediction and the output shows which rule needs another look.
Here's the first program from Week 1. It prints two plus three times four. Python follows operator precedence, the rule that decides which operator Python works out first when an expression has several, such as multiplication before addition, with parentheses always going first. So three times four comes first, which is 12, and then two plus 12 is 14. The line prints 14, not 20.
The second program is one line that prints a name called total, and nothing in the program ever gave total a value. It prints nothing. It stops with an error, and the last line of that error names the type: NameError. That's a runtime exception, which means the program started, ran, and raised. A SyntaxError is different. With a SyntaxError, the parser refuses the text, and no line runs at all.
Pause and try this. If someone runs the line that prints two plus three times four and expects 20, which rule did they skip?
Say the rule to yourself before you go on.
Here's the answer. They skipped operator precedence. Multiplication goes before addition, so three times four is 12 first, and two plus 12 is 14.
A red error isn't a verdict. Its last line is a map to the bug.
2. Name the type: division, remainders, and slices
Imagine a cashier splitting a 10-dollar bill between two people. The cashier hands back two 5-dollar bills. Ask Python the same question with a single slash, and it hands back 5.0. Same amount, different kind of value.
That's true division: division with a single slash, which always gives a float, even when the two numbers divide evenly. So 10 divided by two prints 5.0, with a decimal point, every time.
Now the double slash and the percent sign. Floor division with the double slash keeps the whole number of times one number fits into another, and the remainder operator, the percent sign, keeps what's left over. The Week 2 program prints seven floor-divided by two, then seven remainder two, on one line. Two fits into seven three times, because three times two is six. Seven minus six leaves one. So the line prints 3, then 1.
The last value type in this section is the slice. A slice is a piece cut from a string with square brackets and a colon, which keeps the characters from the start index up to, but not including, the stop index. The Week 3 program stores the word PYTHON in capital letters and prints the slice from 1 to 4. Count from zero: P is at index zero, Y at 1, T at 2, H at 3. The slice stops before 4, so it prints Y, T, H.
Pause and try this. The slice from 1 to 4 printed three letters. Which letter sits at index 4 of PYTHON, and why did it not print?
Count from zero, one letter at a time.
Here's the answer. Index 4 holds the letter O. It didn't print because a slice stops before its stop index, so index 4 is the first character left out.
Before you say what a line prints, name the type it makes.
3. Find the branch that runs: logic and if statements
Picture a theater usher checking tickets. Is it a box seat? If not, is it a balcony seat? If not, it's the main floor. The usher stops at the first yes and never checks the rest.
The Week 4 program prints True or False and False, all on one line. If you read left to right, you'd get the wrong value. Python works out not, then and, then or. So False and False goes first, and that's False. Then True or False is True. The line prints True.
Then the if statement. A branch is one of the alternative blocks of code in an if statement, and Python runs at most one branch each time the statement runs. The Week 4 program sets x to 7. The first test asks whether x is greater than 10. That's False, so Python skips that branch. The elif asks whether x is greater than 5. That's True, so the program prints the word medium, and then it skips everything below, including the else. Only the first true branch runs.
That's why the order of the tests is part of the program. Put a looser test above a stricter one, and the stricter branch never gets its turn. The program runs with no error and prints the wrong thing, which is a logic error.
Pause and try this. In the program where x is 7, the else branch would print small. Why doesn't it run, even though it sits at the bottom of the chain?
Find the first test that comes out True.
Here's the answer. The elif test, x greater than 5, came out True first, so Python ran that branch and skipped the rest of the chain. An else runs only when every test above it is False.
And before or; the first yes wins.
4. Count the passes: counters and ranges
Think about a swimmer counting laps out loud. She touches the wall after lap 5 and says the next number, 6, even though she's done. A loop counter does exactly that.
The Week 5 program starts count at 1. The loop runs while count is less than or equal to 5, and the body adds 1 to count. After the loop, the program prints count. When count is 5, the test is still True, because 5 is less than or equal to 5. So the body runs once more, and count becomes 6. Now the test is False, and the loop ends. The program prints 6. The counter ends one past the last value that passed.
The Week 6 program is a for loop over the range from 1 to 5, printing each number with a space after it. The exclusive stop is the rule that the stop number of a range is never one of the numbers it produces, so the range from 1 to 5 gives 1, 2, 3, and 4 but not 5. The loop prints 1, 2, 3, 4 on one line. Five minus 1 is 4, so there are four values.
Notice how the slice and the range agree. Both stop before their stop. Once you see that rule in one place, you'll recognize it in the other.
Pause and try this. The while loop's body ran while count was 1, 2, 3, 4, and 5. Which value of count was the first to fail the test?
Ask which value makes "less than or equal to 5" come out False.
Here's the answer. The value 6 was the first to fail, because 6 isn't less than or equal to 5. That's why the program prints 6 and not 5.
The counter ends on the first value that fails.
5. Ask what a call hands back: return, None, and local names
Picture a parking-garage ticket machine. It can flash a price on its screen, or it can print a ticket that you carry away and use later. Flashing the price is print. Handing you the ticket is return.
Your reading log's Week 7 function, pages_left, takes a goal and the pages read and returns the goal minus the pages read. The call with 300 and 45 returns 300 minus 45, which is 255, and the print around the call displays 255. A return value is the value a function call hands back to the code that called it, so the line that called it can print it, store it, or use it.
Now the Week 7 trap. A function called show takes x and prints x times two. It has no return line. The program prints the call show of 4. Inside the call, four times two is 8, and that prints. Then the call hands back None, Python's special value meaning no value at all. The outer print displays None. So the output is 8, then None, on two lines.
One more. The program sets n to 5 at the top. A function called change sets n to 99 inside its body. The program calls change and then prints n. It prints 5. The assignment inside the function made a new local n, which disappeared when the call ended. The global n never moved.
Pause and try this. The show function printed 8 during the call. Why did the outer print display None instead of 8?
Look for a return line inside show.
Here's the answer. The show function has no return line, so the call hands back None. Printing 8 displayed the value to you; it didn't hand the value back to the line that called it.
Print shows; return hands back.
6. Read for the six classic slips: the checklist
Think about a proofreader. She doesn't read a page once for everything. She reads it hunting for one kind of slip at a time: a doubled word, then a missing period, then a wrong name. A short list of familiar slips catches more than one long, careful read.
That's the new tool. The classic-bug checklist is six slips a reader looks for before running a program. I'll walk through them one at a time, each with a program you've already met.
Slip one is a single equals sign where a double one belongs. The program sets x to 5 and then says if x equals 5 with a single equals sign. That's a SyntaxError, and not one line runs, not even the line that set x. With a double equals sign, the program prints yes.
Slip two is a stop left out. The loop over the range from 1 to 5 printed 1 through 4. If you mean 1 to 5, write a stop of 6, and it prints 1, 2, 3, 4, 5. That's the off-by-one error.
Slip three is the single slash. Ten divided by two prints 5.0. If you need a whole number, the double slash prints 5.
Slip four is two strings joined. The string "2" plus the string "3" prints 23, because quotation marks make them text and plus joins text end to end.
Slip five is a missing return. The show function printed 8 and handed back None. With return in place of print, the outer print displays 8 once.
Slip six is a while loop with no update. Start count at 1, loop while count is less than or equal to 5, and only print count in the body. It prints 1, and 1, and 1, and it never stops, because nothing moves count. That's an infinite loop. Add the line that adds 1 to count, and it prints 1 through 5 and then 6.
Pause and try this. Only one of the six slips stops the program with an error message. Which one is it, and what do the other five do instead?
Ask which slips still let the program run.
Here's the answer. The single equals sign in an if line, which the parser refuses as a SyntaxError. The other five run without an error message. The stop left out, the single slash, and the joined strings each print the wrong thing, which makes each a logic error. A missing return quietly hands back None, and a while loop with no update never stops. Only reading for them catches them.
Six slips, one read each, then run.
7. Check a chatbot, then get ready for the midterm
A friend tells you a shop closes at 9. Before you cross town, you check the sign on the door. A chatbot's prediction about code deserves the same check, and the run is the sign on the door.
Suppose you ask a chatbot what the line that prints show of 4 displays. It tells you the line prints 8 twice, because the function shows 8 and returns it. Run it. The output is 8, then None. The chatbot treated a printing function as if it returned the printed value, which is slip five on your checklist. A chatbot predicts likely text. It doesn't run your program. So you paste the code into your runner, compare, and trust the run.
Now the midterm. It covers Objectives 1 to 5, as taught in Weeks 1 to 7, and AI is not permitted on it. That's the point: it confirms that you, on your own, can read code, predict what it prints, and find a defect. Each item shows a short program and asks what it prints, which branch runs, how many passes a loop makes, or which error type it raises. Collections, files, algorithms, recursion, and classes come after the midterm and belong to the final.
The best review is the one this lecture modeled. Cover the output of a worked example, write your prediction, read for the six slips, and only then check.
Pause and try this. A chatbot tells you the loop over the range from 1 to 5 prints 1 through 5. Which slip did it make, and what does the run display?
Picture the stop of that range before you decide.
Here's the answer. It made slip two, the stop left out. The run displays 1, 2, 3, 4, because the range never produces its stop of 5.
Trust the run, not the explanation.
Closing
Let's pull it together. Predict, then run, and read an error from its last line. Name the type before the value: a single slash gives a float, and a slice stops before its stop. In an if statement, and goes before or, and only the first true branch runs. A while counter ends one past the last value that passed, and a range never produces its stop. A function with no return hands back None, and an assignment inside a function makes a new local. Then the new habit: read for the six classic slips before you run.
Next in this module come the Readings and Resources page, the practice set, the discussion, and the midterm. After that, Week 9 brings lists, one name for a whole pile of values, read with the same indexes and stops you reviewed here.
Built with The Course Maker · samples.thecoursemaker.com