Midterm 1 Review
Midterm 1 practice problems
Midterm Logistics
- When and where
- Thursday, October 10, 7:30 - 10:00 PM in 75SHS 102 (although the exam is intended to take less than 2 hours)
- What can I bring?
- One piece of letter-sized paper with notes on both sides (I will provide copies of the cheat sheet)
- What can’t I bring?
- Anything else, e.g., book, computer, other notes, etc.
- I have a scheduling conflict, can I take the midterm at an alternate time?
- Yes. Hopefully you already responded to the Google form, to let me know. You can pick up the exam from me in my office on Thursday (or whatever time we agreed upon).
What will the exam cover?
The exam will cover up through loops (for
and while
) but not include file reading. It will specifically focus on the first 8 exam topics, one question per topic. Those questions will or can involve the following:
- Evaluating expressions (order of evaluation in parentheses, method chaining, etc.)
- Statements
- Function definitions (
def
…) for
loops using collections, e.g.string
,list
, andrange
swhile
loops (and the conversion betweenfor
loops andwhile
loops)- conditional statements (
if
,elif
,else
) return
(andprint
vs.return
)
- Function definitions (
- Types
int
float
bool
str
list
- Strings and Lists
- Indexing and slicing
- Iterating
- Functions that take collection as arguments, e.g.
len
- Methods
- Operators on type
- Operators
+
,-
,*
,/
,//
,%
,**
=
,+=
,-=
,*=
- Boolean and relational operators
and
,or
,not
(and their precedence)<
,<=
,>
,>=
,==
,!=
- Using modules
- Different import approaches
from <module> import <material>
import <module> [as <prefix>]
- random module
- math module
- turtle module
- Different import approaches
- Input and output
input
functionprint
function
- Commenting (including block/inline comments and docstrings)
- Good coding style
The exam will NOT include material that was in the book(s) but that we did not discuss in class, or use in our programming assignments, or practice on PrairieLearn. The exam will NOT include file reading.
Types of questions
- Determine the output of code, e.g. value of variables, printing, turtle drawing
- Rewrite code with better style
- Identify bugs in code
- Reassemble jumbled Python statements into a viable function
- Write code to solve problem.
- Short answer
How do you suggest I prepare?
- Review the relevant exam topics and identify the key ideas and techniques associated with each topic. Do you understand that key idea?
- Practice, practice, practice! Complete the previous exams, (re)-solve the practice problems and the in-class problems (available as “in-class questions” on course webpage).
- Review the class notes. Treat the examples in the notes as practice problems, i.e., can you predict the result/solution before you look at it?
What do you suggest I put on my notes page?
Here are some (non-exhaustive) suggestions:
- Common code snippets, e.g., building up a string, determining even/odd, maintaining a count, determining min/max, etc.
- Common slicing patterns, e.g., every third value in a sequence, all but the first value in a sequence, etc.
- Common kinds of errors, e.g., mismatched type, off-by-one, missing colons, missing/invalid keywords, incorrect indent, etc.
Review questions:
Consider the following Python code. What are the values of
s
,r
andy
after the code executes?= 5 s = 3 r def bar(s): = len(s) r return r def foo(s): = 1 r for i in range(len(s)): bar(s[i:])= r * (-bar(s[i:])) r return r = foo("test") y
Show a solutionRecall that function parameters and local variables are in a separate scope. Thus the values of
s
andr
are unchanged, and still 5 and 3, respectively. Similaryr
ands
withinfoo
is distinct fromr
ands
inbar
. We could simplify the code abovedef foo(s): = 1 r for i in range(len(s)): = r * (-len(s[i:])) # The same as r = r * -(len(s)-i) r return r = foo("test") y
Thus
y
will be1 * -4 * -3 * -2 * -1
or 24.Write a function named
random_test
that takes three integer parameters:max
,threshold
andnum
. The function should generatenum
random integers between 0 and max (inclusive) and return the number of these values that were less or equal to the threshold.Show a solutionfrom random import randint def random_test(max, threshold, num): = 0 count for i in range(num): = randint(0, max) r if r <= threshold: += 1 count return count
What would the following function return if we invoked it with 4 as the argument?.
def mystery(x): = 1 count = 0 total while count <= x: += count * count total return total
Show a solutionThe function would not return.
count
is never modified and so this is an infinite loop.For each of the following tasks, indicate with would be most appropriate, a
for
loop, awhile
loop, or both a equally appropriate:Transform each letter in a string:
Show a solutionA
for
loop is most appropriate, since we know the length of the string (the number of iterations) at the beginning of the loop.Count the number of coin flips rolls to get 10 heads:
Show a solutionSince we don’t know how many flips would be required, a
while
loop is most appropriate.Solicit a valid password from a user:
Show a solutionSince we don’t know how many attempts the user will need to provide a valid password, a
while
loop is most appropriate.Perform an operation on every point in a 3-D grid of known size:
Show a solutionSince we know the size of the grid, a
for
loop (and likely nested for loops) are mos appropriate.Perform an operation on every “a” in a string:
Show a solutionEither loop could be appropriate here. We could use a
for
loop to iterate through every character and a conditional to identify “a” characters, or awhile
loop along with thefind
method to search for “a”s, until no more are found. Neither approach is necessarily better than the other. An example of the latter could be:= string.find("a"): index while index != -1: # Do something for string[index] # Find next "a", by starting search after previous "a" = string.find("a", index+1) index
The following function is supposed to prompt the user for numbers until they enter a blank line, then it tells the user how many of the numbers were less than zero. Unfortunately, the function has a few problems and doesn’t work correctly. Identify and fix the problems.
def neg_count(): = input("Enter a number: ") answer = 0 below while answer != "": if answer < 0: += 1 below print("Below: " + below)
Show a solutionFixed version:
# Fixed neg_count def neg_count(): = input("Enter a number: ") answer = 0 below while answer != "": # Runtime error: Need to convert string to float if float(answer) < 0: += 1 below # Logical error: Need to obtain subsequent inputs in each iteration of the loop = input("Enter a number:") answer # Runtime error: Need to convert below to string before concatenation print("Below: " + str(below))
It can be trick to just “see” the errors. Instead I suggest you approach the problem just like Python, “executing” the code and looking for various errors. Try multiple passes:
- Look for syntax errors,
- “Step” through execution looking for runtime errors (like examples above),
- Is the output correct for different inputs (i.e., are there logical errors)?
Rewrite each of the boolean expressions below more compactly. For example, rather than writing
x and x
we could just writex
.Rewrite:
# x contains some bool value True and x
Show a solutionCan be rewritten as:
x
Rewrite:
# x contains some bool value False or x
Show a solutionCan be rewritten as:
x
Rewrite:
> 0 and y < 10 y
Show a solutionCan be rewritten as:
0 < y < 10
Rewrite:
> 0 and z == 1) or (y > 0 and z == 2) (y
Show a solutionCan be rewritten as:
> 0 and (z == 1 or z == 2) y
Rewrite:
> 0 and y < 10) and (y > 0 and y < 20) (y
Show a solutionCan be rewritten as:
> 0 and y < 10 y
or even more concisely as
0 < y < 10
, as shown above.The expression
y > 0 and y < 10
is a subset ofy > 0 and y < 20
and so if that first expression isTrue
, then the second expression must beTrue
. Thus the overall expression will true if and only if the first expression isTrue
.Rewrite:
> 0 and y < 10) and (y <= 0 or y >= 10) (y
Show a solutionCan be rewritten as:
False
The expression
y > 0 and y < 10
is the same asnot (y <= 0 or y >= 10)
and such both operands can’t beTrue
at the same time, thus the overall expression must beFalse
.
The function below has two integer parameters
a
andb
. The function works as desired, however, it is very verbose. Rewrite the function to have identical behavior (i.e., for all possible values of a and b return the same value), but to be as concise as possible.def could_be_better(a, b): if a > 4: if b > 15: return True elif b < -10: return False else return True else: return False
Show a solutionIf we think about this as 2-D space, we observe that the function returns
True
whena > 4 and b >= -10
andFalse
otherwise. We cansimplify the function to return that expression directly, e.g.,def better(a, b): return a > 4 and b >= -10
We noted that Python performs lexicographic comparison of two sequences. Write a function named
lessthan
with two arguments,seq1
andseq2
, and performs lexicographic less than of those sequences. You should only compare individual elements of the sequences.:>>> lessthan(["a", "b"], ["a", "b", "c"]) True >>> lessthan(["a", "c"], ["a", "b", "c"]) False >>> lessthan(["a", "b", "c"], ["a", "b", "c"]) False
Show a solutiondef lessthan(seq1, seq2): # Find the length of the shorter sequence so we don't attempt to access elements # beyond the end of sequence if len(seq1) < len(seq2): = len(seq1) shorter else: = len(seq2) shorter # Iterate by index so we can access corresponding elements of the same sequence for i in range(shorter): if seq1[i] < seq2[i]: return True # Return as soon as we know the result elif seq1[i] > seq2[i]: return False # If we get here, the prefixes of the sequences are the same, return True if # seq1 is the shorter sequence return len(seq1) < len(seq2)
Draw below what the following program would draw on the screen:
from turtle import * def draw_something(x, y, length): pu() goto(x, y) pd()+ length, y) goto(x for i in range(10): 0, i*5, i*5) draw_something( done()
Show a solutionThe above will draw horizontal lines of increasing length at increasing vertical coordinates.
Write a function named
intersection
that has two sequences as parameters and returns a copy of its first argument containing just those items in the first sequence present in the second. It should work for any combination of list and string arguments. As a hint, slicing evaluates to a sequence of the same type and equality operators can be applied to values of different types. For example:>>> intersection(["a", "b"], "aac") ["a"]
Show a solutionHere we take advantage of slicing to create a sequence of the same type, with either zero or 1 items. Recall that
len
,+
and slicing are defined for all sequence types.def intersection(seq1, seq2): = seq1[:0] # Create empty sequence the same type as seq1 result for i in range(len(seq1)): if seq1[i] in seq2: = result + seq1[i:i+1] # Concatenate seqeunce with single item result return result
Imagine you are given a list of column positions in a building (in sorted ascending order). Write a function name
span
that takes the list as argument and returns the longest beam you will need to span between the columns, i.e., the maximum distance between any two adjacent columns. You can assume there are at least two columns.Show a solutiondef span(columns): = -1 # Beam lengths can't be negative max_beam for i in range(1, len(columns)) = columns[i] - columns[i-1] beam if beam > max_beam: = beam max_beam return max_beam