Overview
使用如下命令对每个 question 检查正确性:
python3 ok -q [question number] -i
使用 ok 系统允许的 debug 打印:
print("DEBUG:", x)
运行 cats GUI 系统:
python3 cats_gui.py
Problem 1
实现 pick 函数,其中函数接受的参数:
paragraphs: 表示 paragraphs 的字符串 list
select: 一个对字符串的判断函数,return True or False
k: 第 k 个满足 select 的 paragraphs
返回 paragraphs 中第 k 个满足 select 的字符串,没有满足的返回空字符串。
def pick(paragraphs, select, k):
"""Return the Kth paragraph from PARAGRAPHS for which the SELECT returns True.
If there are fewer than K such paragraphs, return an empty string.
Arguments:
paragraphs: a list of strings representing paragraphs
select: a function that returns True for paragraphs that meet its criteria
k: an integer
>>> ps = ['hi', 'how are you', 'fine']
>>> s = lambda p: len(p) <= 4
>>> pick(ps, s, 0)
'hi'
>>> pick(ps, s, 1)
'fine'
>>> pick(ps, s, 2)
''
"""
for str in paragraphs:
if select(str) and k == 0:
return str
elif select(str):
k -= 1
return ""
python3 ok -q 01 --local
Problem 2
实现 about 函数,其中,
subject: 字符串 list
返回一个函数,该函数也接收一个字符串,判断该字符串中是否有 subject 中的字符串,返回 True/False。不区分大小写,标点符号不考虑,需要全字匹配。
提供了几个 util 函数,split() 用来分割一个字符串成字符串 list。remove_punctuation() 用来去除标点符号。lower()用来大写转小写。
def about(subject):
"""Return a function that takes in a paragraph and returns whether
that paragraph contains one of the words in SUBJECT.
Arguments:
subject: a list of words related to a subject
>>> about_dogs = about(['dog', 'dogs', 'pup', 'puppy'])
>>> pick(['Cute Dog!', 'That is a cat.', 'Nice pup!'], about_dogs, 0)
'Cute Dog!'
>>> pick(['Cute Dog!', 'That is a cat.', 'Nice pup.'], about_dogs, 1)
'Nice pup.'
"""
assert all([lower(x) == x for x in subject]), "subjects should be lowercase."
def f(paragraph):
for sub_str in subject:
for para_str in split(remove_punctuation(paragraph)):
if sub_str == lower(para_str):
return True
return False
return f
Problem 3
实现 accuracy 函数, 计算准确率。
accuracy 函数接收两个字符串, typed 和 source, typed 为用户输入的字符串,source 为对照的字符串,准确率计算规则为:
- 被空格分开的计算为一个单词,一个单词中包括了标点符号
- 如果 typed 比 source 长,那么多出来的单词都算作错误
- 如果 typed 和 source 都为空,那么 accuracy 为 100;如果 typed 为空,source 不为空,那么 accuracy 为 0;如果 typed 不为空,source 为空,那么 accuracy 也为 0
Note: 大小写敏感
def accuracy(typed, source):
"""Return the accuracy (percentage of words typed correctly) of TYPED
compared to the corresponding words in SOURCE.
Arguments:
typed: a string that may contain typos
source: a model string without errors
>>> accuracy('Cute Dog!', 'Cute Dog.')
50.0
>>> accuracy('A Cute Dog!', 'Cute Dog.')
0.0
>>> accuracy('cute Dog.', 'Cute Dog.')
50.0
>>> accuracy('Cute Dog. I say!', 'Cute Dog.')
50.0
>>> accuracy('Cute', 'Cute Dog.')
100.0
>>> accuracy('', 'Cute Dog.')
0.0
>>> accuracy('', '')
100.0
"""
typed_words = split(typed)
source_words = split(source)
if len(typed_words) == 0 and len(source_words) == 0:
return 100
elif len(typed_words) == 0 and len(source_words) != 0:
return 0
elif len(typed_words) != 0 and len(source_words) == 0:
return 0
right = 0
# 如果两个字符串长度不同,那么比较到短的字符串结束为止
compare_len = (
len(typed_words) if len(typed_words) < len(source_words) else len(source_words)
)
for i in range(compare_len):
if typed_words[i] == source_words[i]: # 一个单词匹配,则right++
right += 1
return right / len(typed_words) * 100 # 以输入的字符串为基准计算准确率
Problem 4
实现 wpm 函数,计算 words per minute。其中 5 个 character 为一个 word,而不是具体一个单词的长度。
def wpm(typed, elapsed):
"""Return the words-per-minute (WPM) of the TYPED string.
Arguments:
typed: an entered string
elapsed: an amount of time in seconds
>>> wpm('hello friend hello buddy hello', 15)
24.0
>>> wpm('0123456789',60)
2.0
"""
assert elapsed > 0, "Elapsed time must be positive"
return 60 / elapsed * (len(typed) / 5)
Problem 5
def autocorrect(typed_word, word_list, diff_function, limit):
"""Returns the element of WORD_LIST that has the smallest difference
from TYPED_WORD based on DIFF_FUNCTION. If multiple words are tied for the smallest difference,
return the one that appears closest to the front of WORD_LIST. If the
difference is greater than LIMIT, return TYPED_WORD instead.
Arguments:
typed_word: a string representing a word that may contain typos
word_list: a list of strings representing source words
diff_function: a function quantifying the difference between two words
limit: a number
>>> ten_diff = lambda w1, w2, limit: 10 # Always returns 10
>>> autocorrect("hwllo", ["butter", "hello", "potato"], ten_diff, 20)
'butter'
>>> first_diff = lambda w1, w2, limit: (1 if w1[0] != w2[0] else 0) # Checks for matching first char
>>> autocorrect("tosting", ["testing", "asking", "fasting"], first_diff, 10)
'testing'
"""
for str in word_list:
if typed_word == str:
return typed_word
final_diff = diff_function(typed_word, word_list[0], limit)
final_str = word_list[0]
for str in word_list:
diff = diff_function(typed_word, str, limit)
if diff < final_diff:
final_diff = diff
final_str = str
if limit < final_diff:
return typed_word
else:
return final_str