def
…)for
loops using collections, e.g. string
, list
, and range
swhile
loops (and the conversion between for
loops and while
loops)if
, elif
, else
)return
(and print
vs. return
)int
float
bool
str
list
len
+
, -
, *
, /
, //
, %
, **
=
, +=
, -=
, *=
and
, or
, not
(and their precedence)<
, <=
, >
, >=
, ==
, !=
from <module> import <material>
import <module> [as <prefix>]
input
functionprint
functionwith
blockThe exam will NOT include material that was in the book(s) but that we did not discuss in class, or use in our labs, or practice in the problem sets. The exam will NOT include material in class 15+ (i.e., no references).
Here are some (non-exhaustive) suggestions:
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. Show answer.
def neg_count():
answer = input("Enter a number: ")
below = 0
while answer != "":
if answer < 0:
below += 1
print("Below: " + below)
Can be fixed as:
# 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))
Write a function called my_startswith
that takes two strings as parameters
and returns True
if the first string starts with the second string. You
may NOT use the built-in startswith
method. You may assume that the
second string is shorter than the first. Show answer.
def my_startswith(s1, s2):
n = len(s2)
return s1[:n] == s2
The above would also work if s2
was longer than s1
because while we can’t access individual indices past the end of the sequence, we can slice past the end (it just evaluates to the original sequence). We could make the computation more explicit with:
def my_startswith(s1, s2):
n = len(s2)
return n <= len(s1) and s1[:n] == s2
Rewrite each of the boolean expressions below more compactly. For example,
rather than writing x and x
we could just write x
.
# x contains some bool value
True and x
Can be rewritten as:
x
# x contains some bool value
False or x
Can be rewritten as:
x
y > 0 and y < 10
Can be rewritten as:
0 < y < 10
(y > 0 and z == 1) or (y > 0 and z == 2)
Can be rewritten as:
y > 0 and (z == 1 or z == 2)
(y > 0 and y < 10) and (y > 0 and y < 20)
Can be rewritten as:
y > 0 and y < 10
The expression y > 0 and y < 10
is a subset of y > 0 and y < 20
and
so if that first expression is True
, then the second expression must be
True
. Thus the overall expression will true if and only if the first
expression is True
.
(y > 0 and y < 10) and (y <= 0 or y >= 10)
Can be rewritten as:
False
The expression y > 0 and y < 10
is the same as not (y <= 0 or y >=
10)
and such both operands can’t be True
at the same time, thus the
overall expression must be False
.
Draw below what the following program would draw on the screen (Show answer):
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()
The above will draw horizontal lines of increasing length at increasing vertical coordinates.
For each of the statements below state whether an error would occur OR state what would be printed out. Make sure to make it clear whether you have printed an integer, a float or a string.
print(2 + 5.5)
>>> print(2 + 5.5)
7.5
print(15 / 2)
>>> print(15 / 2)
7.5
print(float(15 // 2))
>>> print(float(15 // 2))
7.0
print(2 + '3')
>>> print(2 + '3')
TypeError: unsupported operand type(s) for +: 'int' and 'str'
print(str(2) + '3')
>>> print(str(2) + '3')
"23"
Write a function called random_test
that takes three integer parameters:
max
, threshold
and num
. The function should generate num
random integers
between 0 and max (inclusive) and return the number of these values that
were less or equal to the threshold. Show answer.
from 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 count
If I have a file called “data.txt” that has the following data in it:
A 0
B 1
C 2
D 3
E 4
What would the following program print out? Show answer.
def process_file(filename):
a = []
b = []
with open(filename, "r") as file:
for line in file:
data = line.split()
a.append(data[0])
b.append(int(data[1]))
for i in range(len(a)):
print(a[i] * b[i])
process_file("data.txt")
The program would print the following. Note the initial blank line.
B
CC
DDD
EEEE
What would the following function return if we invoked it with 4 as the argument? Show answer.
def mystery(x):
count = 1
total = 0
while count <= x:
total += count * count
return total
No return. count
is never modified and so this is an infinite loop.
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 answer.
def span(columns):
max_beam = 0 # Since columns are in sorted ascending order, the beam length must always be >= 0
for i in range(1, len(columns))
beam = columns[i] - columns[i-1]
if beam > max_beam:
max_beam = beam
return max_beam
What does the following expression evaluate to? Show answer.
len(("Mississippi" + "!").upper().replace("ss","a"))
12. The len
argument evaluates as
"Mississippi!".upper().replace("ss","a")
. Since upper
converts the
string to MISSISSIPPI!
, nothing is replaced. Thus we are evaluating
len("MISSISSIPPI!")
, which results in 12.
Write a function named intersection
that has two lists as parameters and
prints out every item in the first list that is present in the second list.
It should only print each item once, even if it appears in the second list
multiple times. Do not use a set. For example: Show answer.
>>> intersection(["a", "b"], ["a", "a", "c"])
a
The simplest approach uses the in
operator on lists.
def intersection(list1, list2):
for item in list1:
if item in list2:
print(item)
If we do not use that operator, we can create the equivalent code with a nested for loop.
def intersection(list1, list2):
for item in list1:
for match in list2:
if item == match:
print(item)
break
Here we use the break
statement to terminate the inner loop once we have
a match so that we don’t print item
multiple times. We have previously
used break
with while
loops, it can also be used with for
loops. In
the context of nested loops, break
only terminates the current loop (not
all loops). Alternately we can use a helper function to only match an item
in list2
once. For example:
def match_once(item, list2):
for match in list2:
if item == match:
return True
return False
def intersection(list1, list2):
for item in list1:
if match_once(item, list2):
print(item)
In match_once
we return True
immediately if there is a match (once we
know the answer, no reason to continue the computation) and False
only if
there is no match (if we complete the loop there must not have been a
match). Thus we will only print matching items once.