跳到主要内容

Semester 2, 2023 Exam

Question 1
What is stored in x after only the following code is executed by Python?

Pi = 3.14
x = 2 * 'Pi'

A. 6
B. 6.0
C. 6.18
D. 'PiPi'
E. None of the above

查看答案与解析

解析:

2 * 'Pi' 是字符串重复,不是数学乘法。

结果是 'PiPi'。

答案:D. 'PiPi'


Question 2
Which statement below is false?

A. We do not have to verify preconditions because it is the user's fault for breaking them.
B. Functions have a "local scope" which means we can use the same variable-name in different functions instead of having to use many unique variable-names.
C. A constant value in Python can be modified.
D. Python prohibits the modification of private variables and the only way to change one is with a getter.
E. None of the above

查看答案与解析

解析:

A 项错误。即使是用户破坏了前置条件,程序员也应当在代码中进行适当的校验。

B、C、D 虽然措辞有点问题,但只有 A 是明显错误。

答案:A. We do not have to verify preconditions because it is the user's fault for breaking them.


Question 3
What is stored in x after only the following code is executed by Python?

def foo(x: int, y: int) -> int:
if x > y:
z = x - y
elif x < y:
z = y - x
return z

x = foo(6, 6)

A. 0
B. 6
C. -6
D. Error
E. None of the above

查看答案与解析

解析:

x = 6, y = 6

既不满足 x > y,也不满足 x < y,所以 z 从未被赋值。

return z 时找不到 z,直接报错 UnboundLocalError。

答案:D. Error


Question 4
What does the following arithmetic expression evaluate to in Python?

2 ** 3 % 5 - 1

A. 0
B. 2
C. 4
D. 7
E. None of the above

查看答案与解析

解析:

运算顺序:

2 ** 3 = 8

8 % 5 = 3

3 - 1 = 2

答案:B. 2


Question 5
What is the value of xs after only the following is evaluated?

xs = (1, 2, 3)
ys = xs
ys[1] = 0

A. (0, 2, 3)
B. (1, 0, 3)
C. None
D. Error
E. None of the above

查看答案与解析

解析:

元组是不可变的(immutable)。

试图修改 ys[1] 会导致 TypeError。

答案:D. Error


Question 6
What is stored in x when only the following is executed by Python?

x = len("1\t2\t3")

A. 5
B. 7
C. 11
D. It depends on the number of spaces in a tab.
E. None of the above

查看答案与解析

解析:

字符串 "1\t2\t3" 实际有:数字 1、制表符\t、数字 2、制表符\t、数字 3

每个\t 算作 1 个字符,所以总长度是 5。

答案:A. 5


Question 7
What is the value of y after only the following has been executed?

y = 0
for x in range(5):
if x == 2 or 3 or 4 or 5:
y += 1

A. 2
B. 3
C. 4
D. 5
E. None of the above

查看答案与解析

解析:

if x == 2 or 3 or 4 or 5 实际理解为:(x == 2) or (3) or (4) or (5)

由于数字 3、4、5 在布尔上下文中为 True,所以条件永远为 True。

range(5)是 0 到 4,共 5 个数,全部满足条件,每次 y += 1。

所以最后 y = 5。

答案:D. 5


Question 8
How many of the following statements evaluate to True?

bool("False")
bool(" ") # 1 space
bool(False and True or True)

A. 0
B. 1
C. 2
D. 3
E. None of the above

查看答案与解析

解析:

分别判断:

bool("False"):非空字符串为 True ✅

bool(" "):空格字符串也是 True ✅

bool(False and True or True):False and True = False,然后 False or True = True ✅

三句都是 True。

答案:D. 3


Question 9
What is stored in y after only the following code is executed?

def foo(xs: str) -> str:
if xs:
return 2 * xs
y = foo("")

A. "" (empty string)
B. " " (one space)
C. " " (two spaces)
D. None
E. None of the above

查看答案与解析

解析:

传入 foo(""),xs 是空字符串,if xs: 条件不满足。

没有 return 语句,默认返回 None。

答案:D. None


Question 10
What is the appropriate type-hint for the following function, assuming the function contains valid code and can be called without generating an error?

def foo(x, y, z):
for z in y:
if x in z:
z.append(x)
return x * y[0] + z

A. foo(x: str, y: list[str], z: str) -> str
B. foo(x: int, y: list[list[int]], z: list[int]) -> list[int]
C. foo(x: int, y: list[str], z: str) -> None
D. foo(x: int, y: list[int], z: int) -> list[int]
E. None of the above

查看答案与解析

解析:

for z in y,说明 y 是可迭代的,每个元素 z 要能调用 append 方法。

只有 list 支持 append,所以 y 应该是 list[list[int]]。

x 在 z 里,x 应该是 int。

最后返回的是 list[int]。

答案:B. foo(x: int, y: list[list[int]], z: list[int]) -> list[int]


Question 11
Suppose we define a new class for hospital admissions. Which name is most appropriate for this class?

A. hospital_admissions
B. HOSPITAL_ADMISSIONS
C. HospitalAdmissions
D. hospital_admissions
E. None of the above

查看答案与解析

解析:

类名应采用驼峰命名法(PascalCase)。

HospitalAdmissions 符合类命名规范。

其他选项是变量命名风格或特殊方法命名风格。

答案:C. HospitalAdmissions


Question 12
What is the value of x after only the following code is run?

x = 0

def foo(x: int) -> int:
x = x + 1

foo(x)
foo(x)

A. 0
B. 1
C. 2
D. Error
E. None of the above

查看答案与解析

解析:

foo 函数修改的是局部变量 x,不会影响外部的全局变量 x。

所以调用 foo(x)两次后,外部的 x 仍然是初始值 0。

答案:A. 0


Question 13
The following is an incomplete recursive function that counts the number of times a given integer occurs in a given list.

def foo(xs: list[int], x: int) -> int:
""" >>> foo([10, 10, 20], 20)
1 >>> foo([10, 10, 20], 10)
2
"""
a, b = ?
if len(xs) == a:
return b
return (xs[0] == x) + foo(xs[1:])

What should be assigned to a, b at line 8 to make the function work?

A. 0, 0
B. 1, 1
C. 0, xs[0] == x
D. 1, xs[0] == x
E. None of the above

查看答案与解析

解析:

当列表长度为 0 时,应返回计数 0。

所以 (a, b) 应该是 (0, 0)。

注意:递归的 base case 是空列表。

答案:A. 0, 0


Question 14
What best describes the behaviour of the following function?

def foo(y, z):
for x in y:
if x > z:
return True
else:
return False
return False

A. Always returns True.
B. Always returns False.
C. Returns False only when there is no element of y that is strictly greater than z.
D. Returns True only when the first element of y is strictly greater than z.
E. None of the above

查看答案与解析

解析:

for 循环第一次迭代就会立即返回,无论 x > z 是否成立。

所以只取决于第一个元素是否大于 z。

答案:D. Returns True only when the first element of y is strictly greater than z.


Question 15
What is stored in x after running only the following code?

x = "drake is overrated".capitalize()

Given that capitalize() means:

  • Make the first character uppercase
  • Make the rest of the string lowercase

A. "Drake is overrated"
B. "Drake Is Overrated"
C. "DRAKE IS OVERRATED"
D. None
E. None of the above

查看答案与解析

解析:

.capitalize() 会使首字母大写,其余全部小写。

所以 "drake is overrated" 变为 "Drake is overrated"。

答案:A. "Drake is overrated"


Question 16
Suppose the following lines of Python have been executed.

letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
xs = letters[5:-5:1]

What is stored in xs?

A. ['F', 'E']
B. ['F', 'E', 'D']
C. []
D. Error
E. None of the above

查看答案与解析

解析:

切片 letters[5:-5:1],start=5,end=-5。

letters[5] 是 'F',letters[-5] 是 'C'。

因为 start > end,步长又是正的,所以返回空列表。

答案:C. []


Question 17
What type of error is thrown by executing the following code?

def foo(x: str, y: str) -> str:
""" >>> foo("Monty", "Python")
'MontyPython'
"""
return x + y

ans = foo(2, 1/3)

A. TypeError
B. NameError
C. ValueError
D. This is valid Python code.
E. None of the above

查看答案与解析

解析:

foo(2, 1/3):传入的是 int 和 float,而函数预期是 str。

在 return x + y 尝试字符串加法时,出现类型不匹配。

Python 抛出 TypeError。

答案:A. TypeError


Question 18
What is stored in x after only the following is executed?

x = (1) + (2) + (3)

A. (1, 2, 3)
B. (1, (2, 3))
C. ((1, 2), 3)
D. None of the above
E. None of the above

查看答案与解析

解析:

(1)、(2)、(3) 都是数字,不是元组。

(1) + (2) + (3) 实际是数值加法,1 + 2 + 3 = 6。

所以都不是给的选项。

答案:D. None of the above


Question 19
What is the behaviour of the following function, supposing it is called properly (i.e. preconditions are satisfied)?

def foo(xss: list[list[int]]) -> dict[list[int], int]:
""" Precondition: len(xss) > 0 """
ans = dict()
for xs in xss:
ans[xs] = sum(xs)
return ans

A. foo always returns None.
B. foo always raises an error.
C. foo returns a dictionary mapping lists to their sums.
D. foo has a logical error because many lists can have the same sum.
E. None of the above

查看答案与解析

解析:

列表(list)是不可哈希的,不能作为字典的 key。

ans[xs] = sum(xs) 会直接导致 TypeError。

答案:B. foo always raises an error.


Question 20
Which is not a Python naming convention/rule?

A. Class attributes that should not be changed by the user (i.e. private variables) start with an underscore _like_this.
B. Magic methods are surrounded by double underscore like_this.
C. Global constants are capitalized LIKE_THIS.
D. Class attributes are camel cased likeThis.
E. None of the above

查看答案与解析

解析:

A、B、C 都是正确的 Python 命名规则。

D 是错误的,类名用 PascalCase(LikeThis),而不是 camelCase(likeThis)。

答案:D. Class attributes are camel cased likeThis.


Question 21
What is the value of xs after executing the following?

ys = ["A", "B"]
xs = ["D"]
ys.extend(["C"])
xs.append(ys)

A. ["D", ["A", "B", "C"]]
B. ["D", "A", "B", "C"]
C. ["D", ["A", "B", ["C"]]]
D. Error
E. None of the above

查看答案与解析

解析:

ys = ["A", "B"]

ys.extend(["C"]) → ["A", "B", "C"]

xs = ["D"]

xs.append(ys) → 把整个 ys 作为一个元素添加到 xs,所以 ["D", ["A", "B", "C"]]

答案:A. ["D", ["A", "B", "C"]]


Question 22
What line of code should replace #sub in order to generate the window illustrated above?

import tkinter as tk
root = tk.Tk()
#sub
root.mainloop()

A. root.geometry("200x400")
B. root.geometry("200 x 400")
C. root.geometry("400x200")
D. root.geometry("400 x 200")
E. None of the above

查看答案与解析

解析:

tkinter.geometry()方法要求字符串格式 "宽 x 高",中间不能有空格。

"400x200"是合法的格式。

答案:C. root.geometry("400x200")


Question 23
Suppose we want to assign True to the name validate when a user has inputted only the single digit '1', '2', '3', or '4' (and False otherwise). Which proposition should replace #sub?

value = input("Enter a single digit: ")
validate = #sub

A. value == "1" or "2" or "3" or "4"
B. value in "1234"
C. "1" <= value <= "4"
D. int(value) in range(1, 5)
E. None of the above

查看答案与解析

解析:

A 错误:value == "1" or "2"这种写法总是 True。

B 正确:value in "1234"可以检查字符串是否是'1'、'2'、'3'、'4'之一。

C 错误:"1" <= value <= "4" 会出错,因为字符串比较不符合预期。

D 正确:int(value) in range(1,5)也能正确判断,不过如果输入不是数字会导致异常。

最稳妥的是 B。

答案:B. value in "1234"


Question 24
What exception should be used at <Error> to complete the function?

def foo() -> int:
"""
Prompts the user to enter an integer.
Repeats until a number is entered.
"""
try:
return int(input("Enter an integer "))
except <Error>:
return foo()

A. TypeError
B. ValueError
C. InputError
D. IntError
E. None of the above

查看答案与解析

解析:

如果输入不能被 int()转换,比如输入字母,会抛出 ValueError。

不是 TypeError,也没有 InputError 和 IntError 这类内置异常。

答案:B. ValueError


Question 25
Consider the following function.

def foo(xs: list[int], ys: dict) -> bool:
for x in xs:
if not x in [ys[k] for k in ys]:
return False
return True

A. foo always returns True.
B. foo always returns False.
C. foo returns True only when every element of xs is a key of ys.
D. foo returns True only when every element of xs is a value of ys.
E. None of the above

查看答案与解析

解析:

[ys[k] for k in ys] 是取字典所有的 value。

检查的是 x 是否在 ys 的 value 中。

所以:只有当 xs 中每个元素都出现在 ys 的 values 中时,返回 True。

答案:D. foo returns True only when every element of xs is a value of ys.


Question 26
The following tkinter window has been stretched using the mouse. What line of code should replace #sub in order to generate the window illustrated above?

import tkinter as tk
root = tk.Tk()
label = tk.Label(text="Drizzy", background="black", foreground="white")

# sub

label.pack(expand=opts[0], fill=opts[1])
root.mainloop()

A. opts = Tk.TRUE, Tk.NONE
B. opts = Tk.FALSE, Tk.BOTH
C. opts = Tk.NONE, Tk.TRUE
D. opts = Tk.BOTH, Tk.FALSE
E. None of the above

查看答案与解析

解析:

窗口被拉伸,说明 fill=BOTH,且 expand=True。

A、B、C 中 opts 配的不对,只有 D 符合。

Tk.BOTH 让控件填充水平和垂直方向,expand=False 不影响 stretch。

(注意:这里 Tk 应该大写,但也可能视环境略有不同。)

答案:D. opts = Tk.BOTH, Tk.FALSE


Question 27
What is the purpose of "setter" methods as they pertain to objects?

A. They are used to change the value of a private variable.
B. They are used to retrieve the value of a private variable.
C. They change a private variable to a public one and vice-versa.
D. They ensure that all private variables have the correct type.
E. None of the above

查看答案与解析

解析:

Setter(设置器)是专门用于修改对象私有属性的方法。

Getter(获取器)则是读取私有属性。

与修改属性的访问权限无关。

答案:A. They are used to change the value of a private variable.


Question 28
How many exclamation marks ! are in output.txt after running (only) the following code?

the_file = open("output.txt", 'a')
for k in range(1, 4):
the_file.write(k * '!')
the_file.close()

A. 1
B. 3
C. 6
D. Impossible to deduce without knowing the initial contents of output.txt.
E. None of the above

查看答案与解析

解析:

range(1,4) 是 [1,2,3]

写入的内容是:

1 * '!' = '!'

2 * '!' = '!!'

3 * '!' = '!!!'

总共写入 1 + 2 + 3 = 6 个感叹号。

注意'a'模式是追加,但不影响本题,因为是问新写入的量。

答案:C. 6


Question 29
Which of the following is not a necessary feature of an imperative programming language?

A. Iteration.
B. Selection.
C. Transparency.
D. Sequencing.
E. None of the above

查看答案与解析

解析:

迭代(Iteration)、选择(Selection)、顺序(Sequencing)是命令式编程语言的基本特征。

透明性(Transparency)不是编程语言必须具备的特征,它属于设计原则或系统属性。

答案:C. Transparency


Question 30
What is the value of z after running the following code?

xs = ['a', (3, 4), {1: 'b'}]
ys = xs.copy()
ys[2] = {2: 'c'}
z = xs[2][1]

A. 'a'
B. 'b'
C. 'c'
D. Error
E. None of the above

查看答案与解析

解析:

xs.copy()是浅拷贝,复制列表本身,但元素引用不变。

ys[2] = {2:'c'} 改变了 ys 的第 3 个元素,不影响原来的 xs。

所以 xs[2]仍然是{1: 'b'}

xs[2][1]取 key=1,value 是'b'。

答案:B. 'b'


Question 31
What does a.f(4) return?

class A(object):
def __init__(self, x):
self._x = 2 * x

def f(self, x):
return self.g(x) + 2

def g(self, x):
return x - 1

class B(A):
def g(self, y):
return self._x + y

class C(B):
def __init__(self, x, y):
super().__init__(x)
self._y = y + 2

def f(self, x):
return self._x + self._y

class D(B):
def __init__(self, x, y):
super().__init__(x)
self._x += y
self._y = y + 2

def f(self, y):
return self._y + y

def g(self, x):
return super().g(x) - x

a = A(1)
b = B(2)
c = C(3, 4)
d = D(5, 6)
查看答案与解析

解析:

a = A(1),所以 self._x = 2

a.f(4)调用了 self.g(4) + 2

g(4)在 A 中定义,返回 4 - 1 = 3

所以 3 + 2 = 5

答案:5


Question 32
What does b.g(3) return?

查看答案与解析

解析:

b = B(2),self._x = 4

b.g(3)调用了子类 B 的 g 方法,返回 self._x + y

即 4 + 3 = 7

答案:7


Question 33
What does c.f(2) return?

查看答案与解析

解析:

c = C(3, 4)

self._x = 2 * 3 = 6

self._y = 4 + 2 = 6

c.f(2)返回 self._x + self._y,即 6 + 6 = 12

答案:12


Question 34
What does d.f(1) return?

查看答案与解析

解析:

d = D(5, 6)

self._x = 2 * 5 = 10,然后 self._x += 6 → self._x = 16

self._y = 6 + 2 = 8

d.f(1)调用 return self._y + y → 8 + 1 = 9

答案:9


Question 35
What does d.g(0) return?

查看答案与解析

解析:

d.g(0)调用了重写的 g 方法:super().g(x) - x

先调用 super().g(0),即 B.g(0),返回 self._x + y = 16 + 0 = 16

然后 16 - 0 = 16

答案:16


Question 36
Implement the following function according to its specification:

def foo(xs: str, ys: str) -> bool:
"""
Given two strings xs and ys, return true only when xs is equal
to ys when typed into an empty text editor interpreting '!' as
typing a backspace character.

For example:
>>> foo("ab!c", "ac")
True
because "ab!c" becomes "ac" when typed.

>>> foo("ab!!", "ab")
False
because "ab!!" becomes "" (empty string) when typed.

>>> foo("a!c", "c")
True
because "a!c" becomes "c" when typed.

Note that backspacing on the empty string produces the empty string.
"""
查看答案与解析

解析:

题目要求模拟输入过程,遇到!执行退格删除前一个字符。 常用方法是使用一个栈来模拟编辑器。

处理步骤:

遍历字符串

正常字符入栈

遇到'!',弹栈(如果栈非空)

最后将处理完的字符串与ys比较

示例参考实现:

def process(s: str) -> str:
stack = []
for c in s:
if c == '!':
if stack:
stack.pop()
else:
stack.append(c)
return ''.join(stack)

def foo(xs: str, ys: str) -> bool:
return process(xs) == ys

注意:

stack模拟输入框。

!不会让字符串长度变负数,如果没有字符,退格也是安全操作。

直接比较process(xs)和ys即可。

答案:

def foo(xs: str, ys: str) -> bool:
stack = []
for c in xs:
if c == '!':
if stack:
stack.pop()
else:
stack.append(c)
return ''.join(stack) == ys