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…) forloops using collections, e.g.string,list, andrangeswhileloops (and the conversion betweenforloops andwhileloops)- conditional statements (
if,elif,else) return(andprintvs.return)
- Function definitions (
- Types
intfloatboolstrlist
- 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
inputfunctionprintfunction
- 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,randyafter the code executes?s = 5 r = 3 def bar(s): r = len(s) return r def foo(s): r = 1 for i in range(len(s)): bar(s[i:]) r = r * (-bar(s[i:])) return r y = foo("test")Show a solutionRecall that function parameters and local variables are in a separate scope. Thus the values of
sandrare unchanged, and still 5 and 3, respectively. Similaryrandswithinfoois distinct fromrandsinbar. We could simplify the code abovedef foo(s): r = 1 for i in range(len(s)): r = r * (-len(s[i:])) # The same as r = r * -(len(s)-i) return r y = foo("test")Thus
ywill be1 * -4 * -3 * -2 * -1or 24.Write a function named
random_testthat takes three integer parameters:max,thresholdandnum. The function should generatenumrandom 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): count = 0 for i in range(num): r = randint(0, max) if r <= threshold: count += 1 return countWhat would the following function return if we invoked it with 4 as the argument?.
def mystery(x): count = 1 total = 0 while count <= x: total += count * count return totalShow a solutionThe function would not return.
countis never modified and so this is an infinite loop.For each of the following tasks, indicate with would be most appropriate, a
forloop, awhileloop, or both a equally appropriate:Transform each letter in a string:
Show a solutionA
forloop 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
whileloop 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
whileloop 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
forloop (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
forloop to iterate through every character and a conditional to identify “a” characters, or awhileloop along with thefindmethod 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:index = string.find("a"): while index != -1: # Do something for string[index] # Find next "a", by starting search after previous "a" index = string.find("a", index+1)
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(): answer = input("Enter a number: ") below = 0 while answer != "": if answer < 0: below += 1 print("Below: " + below)Show a solutionFixed version:
# Fixed neg_count def neg_count(): answer = input("Enter a number: ") below = 0 while answer != "": # Runtime error: Need to convert string to float if float(answer) < 0: below += 1 # Logical error: Need to obtain subsequent inputs in each iteration of the loop answer = input("Enter a number:") # 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 xwe could just writex.Rewrite:
# x contains some bool value True and xShow a solutionCan be rewritten as:
xRewrite:
# x contains some bool value False or xShow a solutionCan be rewritten as:
xRewrite:
y > 0 and y < 10Show a solutionCan be rewritten as:
0 < y < 10Rewrite:
(y > 0 and z == 1) or (y > 0 and z == 2)Show a solutionCan be rewritten as:
y > 0 and (z == 1 or z == 2)Rewrite:
(y > 0 and y < 10) and (y > 0 and y < 20)Show a solutionCan be rewritten as:
y > 0 and y < 10or even more concisely as
0 < y < 10, as shown above.The expression
y > 0 and y < 10is a subset ofy > 0 and y < 20and 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:
(y > 0 and y < 10) and (y <= 0 or y >= 10)Show a solutionCan be rewritten as:
FalseThe expression
y > 0 and y < 10is the same asnot (y <= 0 or y >= 10)and such both operands can’t beTrueat the same time, thus the overall expression must beFalse.
The function below has two integer parameters
aandb. 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 FalseShow a solutionIf we think about this as 2-D space, we observe that the function returns
Truewhena > 4 and b >= -10andFalseotherwise. We cansimplify the function to return that expression directly, e.g.,def better(a, b): return a > 4 and b >= -10We noted that Python performs lexicographic comparison of two sequences. Write a function named
lessthanwith two arguments,seq1andseq2, 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"]) FalseShow 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): shorter = len(seq1) else: shorter = len(seq2) # 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() goto(x + length, y) for i in range(10): draw_something(0, i*5, i*5) done()Show a solutionThe above will draw horizontal lines of increasing length at increasing vertical coordinates.
Write a function named
intersectionthat 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): result = seq1[:0] # Create empty sequence the same type as seq1 for i in range(len(seq1)): if seq1[i] in seq2: result = result + seq1[i:i+1] # Concatenate seqeunce with single item return resultImagine you are given a list of column positions in a building (in sorted ascending order). Write a function name
spanthat 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): max_beam = -1 # Beam lengths can't be negative for i in range(1, len(columns)) beam = columns[i] - columns[i-1] if beam > max_beam: max_beam = beam return max_beam