Worked Solutions · AP CSP-Feeder · US / ON / BC / AB Styles详细解析 · AP CSP 衔接 · 美 / 安 / 卑 / 阿省风格
Given s = "Python", which expression evaluates to "t"?给定 s = "Python",哪个表达式的值为 "t"?
Index map for "Python": P=0, y=1, t=2, h=3, o=4, n=5. So s[2] = "t"."Python" 的索引映射:P=0, y=1, t=2, h=3, o=4, n=5。因此 s[2] = "t"。
s[1] = "y", not "t".s[1] = "y",不是 "t"。s[-1] = "n" (last character).s[-1] = "n"(最后一个字符)。s[3] = "h".s[3] = "h"。s[1] expecting the first character -- that is an off-by-one mistake.Python 使用从零开始的索引。位置 0 处的字符始终是第一个字符。常见错误是写 s[1] 期望得到第一个字符,这是差一错误(off-by-one)。What does "computer"[3:6] evaluate to?"computer"[3:6] 的值是什么?
Index map: c=0, o=1, m=2, p=3, u=4, t=5, e=6, r=7. Slice [3:6] includes indices 3, 4, 5 and excludes 6. Characters at 3, 4, 5 are p, u, t = "put".索引映射:c=0, o=1, m=2, p=3, u=4, t=5, e=6, r=7。切片 [3:6] 包含索引 3、4、5,不含 6。这些位置的字符为 p、u、t = "put"。
"mpu" comes from indices 2, 3, 4 which is [2:5], not [3:6]."mpu" 来自索引 2、3、4,即 [2:5],不是 [3:6]。[3:6] gives 3 characters (indices 3, 4, 5), not 4. To get n characters starting at index k, write [k : k+n].切片的 stop 索引始终不包含。[3:6] 给出 3 个字符(索引 3、4、5),不是 4 个。要从索引 k 开始取 n 个字符,写 [k : k+n]。word = "hello"
word.upper()
print(word)
hello A1 -- word is unchanged.hello A1 -- word 未改变。
Strings are immutable in Python M1: upper() returns a new string object with the uppercased characters, but does not modify the original string that word refers to. A1 Because the return value is not assigned to anything, it is discarded.Python 中字符串是不可变的 M1:upper() 返回一个包含大写字符的新字符串对象,但不修改 word 所引用的原始字符串。A1 因为返回值没有赋给任何变量,所以被丢弃了。
word = word.upper()
A1 Assigning the return value back to word stores the new uppercased string.A1 将返回值重新赋给 word,即可保存新的大写字符串。
s = s.method(), not just s.method(), when you want to update a variable.这是字符串方法中最常见的错误。每个字符串方法都返回一个新字符串。如果不赋值,结果就丢失了。当你想更新变量时,始终写 s = s.method(),而不只是 s.method()。name = "Alex"
score = 88
# Program A: result_a = "Student: " + name + ", Score: " + score
# Program B: result_b = "Student: " + name + ", Score: " + str(score)
# Program C: result_c = f"Student: {name}, Score: {score}"
TypeError A1: The + operator cannot concatenate a string and an integer directly. score is the integer 88; Python does not auto-convert it to a string when using +. A1TypeError A1:+ 运算符不能直接拼接字符串和整数。score 是整数 88;使用 + 时 Python 不会自动将其转换为字符串。A1
Student: Alex, Score: 88 A1 -- str(88) converts the integer to the string "88" first, enabling concatenation.Student: Alex, Score: 88 A1 -- str(88) 先将整数转换为字符串 "88",从而可以拼接。
Student: Alex, Score: 88 A1Student: Alex, Score: 88 A1
The f prefix marks the string as a formatted string literal (f-string). M1 Any expression inside {} is evaluated at runtime and its result is converted to a string and inserted at that position. A1f 前缀将字符串标记为格式化字符串字面量(f-string)。M1 {} 内的任何表达式在运行时被求值,其结果被转换为字符串并插入该位置。A1
C (f-string) is preferred in modern Python A1 because it is more readable and requires no explicit type conversion.现代 Python 中首选 C(f-string)A1,因为可读性更强,无需显式类型转换。
+. F-strings handle this automatically.AB CSE1110 结果 2.4.6 将拼接和插值列为评估技能。程序 A 中的 TypeError 是初学者最常遇到的运行时错误之一:使用 + 之前必须将所有非字符串值转换为字符串。F-string 会自动处理这一点。sentence = "the quick brown fox"
in for boolean check答案:(a) True,布尔型 (b) 4,-1 (c) 2 (d) 只需布尔判断时用 in"fox" in sentence [2](a) "fox" in sentence [2]True A1. The in operator returns a bool value (True or False). A1 "fox" is a substring of "the quick brown fox".True A1。in 运算符返回布尔值(True 或 False)。A1 "fox" 是 "the quick brown fox" 的子字符串。
find() results [3](b) find() 结果 [3]sentence.find("quick") = 4 A1: "quick" starts at index 4 (t=0, h=1, e=2, space=3, q=4). A1sentence.find("quick") = 4 A1:"quick" 从索引 4 开始(t=0, h=1, e=2, 空格=3, q=4)。A1
sentence.find("cat") = -1 A1: find() returns -1 when the substring is not found in the string.sentence.find("cat") = -1 A1:find() 在字符串中未找到子字符串时返回 -1。
count("o") [2](c) count("o") [2]2 A1. The character "o" appears in "brown" (index 10) and "fox" (index 16) -- two non-overlapping occurrences. A12 A1。字符 "o" 出现在 "brown"(索引 10)和 "fox"(索引 16)中,共 2 次不重叠出现。A1
in over find() [1](d) 何时用 in 而非 find() [1]Use in when you only need to know whether a substring is present (a boolean answer) and do not need its position. A1 It is also cleaner and more readable.当你只需要知道子字符串是否存在(布尔答案)而不需要其位置时,使用 in。A1 它也更简洁易读。
in for existence, find() for position, count() for frequency.ON ICS3C A1.2 直接将"计算单词或字母的出现次数"列为评估技能。三种字符串搜索工具涵盖所有情形:in 用于检查存在性,find() 用于获取位置,count() 用于计算频率。| chch | Vowel?元音? | countcount |
|---|---|---|
| e | Yes | 1 |
| d | No | 1 |
| u | Yes | 2 |
| c | No | 2 |
| a | Yes | 3 |
| t | No | 3 |
| i | Yes | 4 |
| o | Yes | 5 |
| n | No | 5 |
Final output: 5 A1A1A1 (1 mark for correct vowel identification, 1 for correct count trace, 1 for output).最终输出:5 A1A1A1(1 分正确识别元音,1 分正确追踪计数,1 分输出)。
len("education") = 9 A1. i takes values 0, 1, 2, 3, 4, 5, 6, 7, 8 A1.len("education") = 9 A1。i 取值为 0, 1, 2, 3, 4, 5, 6, 7, 8 A1。
Choose for-range when you need the index (position) of the character, not just its value. M1 Example: replacing specific characters -- to change every vowel to "*" you need s[i] and the index to build the new string character by character. A1 Accept: comparing adjacent characters (s[i] vs s[i+1]), checking if a character at a specific position satisfies a condition. A1当你需要字符的索引(位置)而不只是其值时,选择 for-range。M1 例如:替换特定字符,要将每个元音改为 "*",你需要 s[i] 和索引,逐字符构建新字符串。A1 也接受:比较相邻字符(s[i] 与 s[i+1])、检查特定位置的字符是否满足条件等场景。A1
for ch in s) is the Pythonic default because it is cleaner. Use for-range only when the index matters. A real-world case: validating an ISBN number requires checking the character at each specific position -- position 0 must be a digit, position 9 can be "X", etc.for-each 风格(for ch in s)是 Python 的默认首选,因为更简洁。只有当索引重要时才使用 for-range。实际案例:验证 ISBN 号需要检查每个特定位置的字符,位置 0 必须是数字,位置 9 可以是 "X" 等。fields after line 2 [2](a) 第 2 行后 fields [2][" Alice ", " Biology ", " 92 "] A1A1. split(",") splits on each comma and preserves leading/trailing whitespace within each piece.[" Alice ", " Biology ", " 92 "] A1A1。split(",") 在每个逗号处分割,并保留每段中的首尾空白。
clean after line 3 [3](b) 第 3 行后 clean [3]["alice", "biology", "92"] A1["alice", "biology", "92"] A1
For the first element " Alice ": strip() removes the leading and trailing spaces to give "Alice" A1; lower() then converts all letters to lowercase to give "alice" A1.对于第一个元素 " Alice ":strip() 去除首尾空格,得到 "Alice" A1;lower() 将所有字母转为小写,得到 "alice" A1。
Line 4: ["alice", "biology", "92"] A1第 4 行:["alice", "biology", "92"] A1
Line 5: clean[0] is "alice". "alice".count("l") = 1 A1 (only one "l" in "alice").第 5 行:clean[0] 为 "alice"。"alice".count("l") = 1 A1("alice" 中只有一个 "l")。
Line 6: clean[1] is "biology". "bio" in "biology" = True A1 ("bio" is the first three characters of "biology").第 6 行:clean[1] 为 "biology"。"bio" in "biology" = True A1("bio" 是 "biology" 的前三个字符)。
strip() before lower() (not after) ensures spaces are removed first, which is slightly more efficient.先 strip 再 lower 是标准的 CSV 清理惯例。真实数据几乎总有不一致的空白和大小写。先 strip() 再 lower()(不是反过来)确保先去除空格,效率略高。Output: racecar A1输出:racecar A1
[::-1]: start is omitted (defaults to end of string), stop is omitted (defaults to beginning), step is -1 (traverse backwards). M1 The result is the entire string read from right to left, i.e., reversed. A1 Since "racecar" is a palindrome, the reverse equals the original.[::-1]:start 省略(默认为字符串末尾),stop 省略(默认为开头),step 为 -1(从后往前遍历)。M1 结果是从右到左读取整个字符串,即反转。A1 由于 "racecar" 是回文,反转后等于原字符串。
| Iteration迭代 | ch | rev2 |
|---|---|---|
| 1 | r | "r" |
| 2 | a | "ar" |
| 3 | c | "car" |
| 4 | e | "ecar" |
| 5 | c | "cecar" |
| 6 | a | "acecar" |
| 7 | r | "racecar" |
A1A1A1 (1 mark table set-up, 1 mark correct intermediate values, 1 mark final output). Final output: racecar A1. Each iteration prepends ch before rev2, building the reverse character by character.A1A1A1(1 分表格设置,1 分正确中间值,1 分最终输出)。最终输出:racecar A1。每次迭代将 ch 前置于 rev2,逐字符构建反转字符串。
s == s[::-1]
A1 This evaluates to True if the string equals its own reverse.A1 当字符串等于其反转时,该表达式值为 True。
result = ch + result is the standard loop-based string reversal. It builds the answer backwards because each new character is placed at the front. The slice [::-1] is O(n) and is the preferred one-liner, but knowing the loop version shows you understand what reversal means structurally.前置模式 result = ch + result 是标准的基于循环的字符串反转。它从后往前构建答案,因为每个新字符被放在最前面。切片 [::-1] 是 O(n) 的,是首选的单行写法,但了解循环版本表明你理解反转在结构上的含义。text and words [2](a) text 和 words [2]text = "the cat sat on the mat and the cat" A1 (lower() lowercases the capital T; strip() removes any leading/trailing whitespace -- none here, so no visible change).text = "the cat sat on the mat and the cat" A1(lower() 将大写 T 转为小写;strip() 去除首尾空白,此处无空白,所以无可见变化)。
words = ["the","cat","sat","on","the","mat","and","the","cat"] A1words = ["the","cat","sat","on","the","mat","and","the","cat"] A1
total and freq [3](b) total 和 freq [3]total = 9 A1total = 9 A1
freq = {"the": 3, "cat": 2, "sat": 1, "on": 1, "mat": 1, "and": 1} A1A1 (1 mark for "the":3 and "cat":2; 1 mark for all remaining entries correct).freq = {"the": 3, "cat": 2, "sat": 1, "on": 1, "mat": 1, "and": 1} A1A1(1 分 "the":3 和 "cat":2 正确;1 分其余条目全部正确)。
Line 1: Total words: 9 A1第 1 行:Total words: 9 A1
Line 2: Most frequent: 'the' (3 times) A1 (max(freq, key=freq.get) finds the key with the highest value = "the" with count 3).第 2 行:Most frequent: 'the' (3 times) A1(max(freq, key=freq.get) 找到值最大的键 = "the",计数为 3)。
Line 3: 'cat' appears: yes第 3 行:'cat' appears: yes
lower() before split() ensures "The" and "the" are counted as the same word. Without normalisation, "The" and "the" would be separate dictionary keys.这个流水线(规范化、分割、计数、报告)是文本分析的基础。ON ICS3C A1.2 明确要求"计算单词或字母的出现次数"。关键点是在 split() 之前调用 lower(),确保 "The" 和 "the" 被计为同一个词。如果不规范化,"The" 和 "the" 会是字典中的不同键。| ch | isupper()?isupper()? | upper_count |
|---|---|---|
| H | True | 1 |
| e | False | 1 |
| l | False | 1 |
| l | False | 1 |
| o | False | 1 |
| 5 | False | 1 |
| W | True | 2 |
| o | False | 2 |
| r | False | 2 |
| l | False | 2 |
| d | False | 2 |
A1A1A1A1 (1 mark correct isupper for H and W; 1 mark digits/lowercase return False; 1 mark correct count progression; 1 mark final count = 2).A1A1A1A1(1 分 H 和 W 的 isupper 正确;1 分数字/小写字母返回 False;1 分正确计数递进;1 分最终计数 = 2)。
2 A1 and True A12 A1 和 True A1
upper_count = sum(1 for ch in text if ch.isupper())
A1A1. sum() over a generator expression that yields 1 for each uppercase character is equivalent to the explicit loop. Accept also: upper_count = sum(ch.isupper() for ch in text) (booleans are integers in Python: True=1, False=0).A1A1。对生成器表达式(每遇一个大写字符产生 1)求 sum(),等价于显式循环。也接受:upper_count = sum(ch.isupper() for ch in text)(Python 中布尔值是整数:True=1,False=0)。
isupper() returns False for the digit "5" -- it only returns True for alphabetic characters that are uppercase. The generator expression one-liner is a pattern worth memorising: sum(condition for item in iterable) counts items satisfying the condition.注意 isupper() 对数字 "5" 返回 False,它只对大写字母字符返回 True。生成器表达式单行写法值得记忆:sum(condition for item in iterable) 计算满足条件的项目数。Index map of "2024-06-15": 2=0, 0=1, 2=2, 4=3, -=4, 0=5, 6=6, -=7, 1=8, 5=9."2024-06-15" 的索引映射:2=0, 0=1, 2=2, 4=3, -=4, 0=5, 6=6, -=7, 1=8, 5=9。
year = date[0:4] = "2024" A1 (indices 0,1,2,3)year = date[0:4] = "2024" A1(索引 0,1,2,3)
month = date[5:7] = "06" A1 (indices 5,6)month = date[5:7] = "06" A1(索引 5,6)
day = date[8:10] = "15" A1 (indices 8,9)day = date[8:10] = "15" A1(索引 8,9)
last_char = "5" A1. Negative index -1 counts from the right: index -1 refers to the last character in the string, which is "5". A1last_char = "5" A1。负索引 -1 从右计数:索引 -1 指字符串的最后一个字符,即 "5"。A1
Year: 2024, Month: 06, Day: 15, Last char: 5 A1A1Year: 2024, Month: 06, Day: 15, Last char: 5 A1A1
Strings are immutable A1: individual characters cannot be modified in place. To produce a corrected date string, use string concatenation or slicing: "3" + date[1:] A1. This creates a new string with "3" as the first character followed by the rest of date.字符串是不可变的 A1:不能就地修改单个字符。要生成修改后的日期字符串,使用字符串拼接或切片:"3" + date[1:] A1。这创建了一个以 "3" 为第一个字符、后跟 date 其余部分的新字符串。
[0:4] grabs 4 characters, [5:7] skips the dash at index 4 and grabs 2 characters for the month. Negative indices give clean access to the last few characters without knowing the length.用切片解析日期字符串是经典的 ON ICS3C A1.2 练习("提取一部分")。切片索引必须精确:[0:4] 取 4 个字符,[5:7] 跳过索引 4 处的连字符并取 2 个字符作为月份。负索引可以在不知道长度的情况下干净地访问最后几个字符。Current output: Not found. A1当前输出:Not found. A1
Bug: the in operator is case-sensitive. M1 sentence = "The Quick Brown Fox" contains "The" with a capital T, but target = "the" is all lowercase. "the" (lowercase) is not a substring of "The Quick Brown Fox" because the capital T at position 0 does not match the lowercase t. A1错误:in 运算符区分大小写。M1 sentence = "The Quick Brown Fox" 包含首字母大写的 "The",但 target = "the" 全是小写。"the"(小写)不是 "The Quick Brown Fox" 的子字符串,因为位置 0 的大写 T 与小写 t 不匹配。A1
sentence = "The Quick Brown Fox"
target = "the"
s_lower = sentence.lower()
if target in s_lower:
print("Found!")
print(s_lower.count(target))
M1 Normalise sentence to lowercase before searching. A1 Use the same normalised string for both in and count() to ensure consistent case-insensitive results. A1 Accept also: if target in sentence.lower() and sentence.lower().count(target).M1 搜索前将 sentence 规范化为小写。A1 对 in 和 count() 使用同一个规范化后的字符串,确保不区分大小写的一致结果。A1 也接受:if target in sentence.lower() 和 sentence.lower().count(target)。
Found! A1Found! A1
1 A1 -- "the quick brown fox" (lowercased) contains "the" exactly once, at the start.1 A1 -- "the quick brown fox"(小写后)包含 "the" 恰好一次,在开头。
target) is already lowercase here, so only the haystack needs normalising. If both could be mixed case, normalise both: target.lower() in sentence.lower().不区分大小写的搜索是字符串程序中最常见的错误之一。修复模式(在比较之前将被搜索字符串和搜索词都规范化为同一大小写)是标准技术。注意:此处搜索词(target)已经是小写,所以只需规范化被搜索字符串。如果两者都可能是混合大小写,则都规范化:target.lower() in sentence.lower()。