cs61a 2020 fall cats作业
2022.12.28 (¦3[▓▓]
"""Typing test implementation"""
from utils import lower, split, remove_punctuation, lines_from_file
from ucb import main, interact, trace
from datetime import datetime
###########
# Phase 1 #
###########
def choose(paragraphs, select, k):
"""Return the Kth paragraph from PARAGRAPHS for which SELECT called on the
paragraph returns true. If there are fewer than K such paragraphs, return
the empty string.
"""
# BEGIN PROBLEM 1
"*** YOUR CODE HERE ***"
# END PROBLEM 1
length = len(paragraphs)
if length <= k+1:
return ''
else:
for i in range(k,length):
if select(paragraphs[i]):
return paragraphs[i]
return ''
def about(topic):
"""Return a select function that returns whether a paragraph contains one
of the words in TOPIC.
>>> about_dogs = about(['dog', 'dogs', 'pup', 'puppy'])
>>> choose(['Cute Dog!', 'That is a cat.', 'Nice pup!'], about_dogs, 0)
'Cute Dog!'
>>> choose(['Cute Dog!', 'That is a cat.', 'Nice pup.'], about_dogs, 1)
'Nice pup.'
"""
assert all([lower(x) == x for x in topic]), 'topics should be lowercase.'
# BEGIN PROBLEM 2
"*** YOUR CODE HERE ***"
# END PROBLEM 2
def about_select(sentence):
#sentence = sentence.lower()
#sentence = sentence.strip('.')
#sentence = sentence.split(' ')
#print(sentence)
sentence = remove_punctuation(sentence)
for i in topic:
if i in sentence.lower().split(' '):
return True
return False
return about_select
def accuracy(typed, reference):
"""Return the accuracy (percentage of words typed correctly) of TYPED
when compared to the prefix of REFERENCE that was typed.
>>> 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
"""
typed_words = split(typed)
reference_words = split(reference)
# BEGIN PROBLEM 3
"*** YOUR CODE HERE ***"
# END PROBLEM 3
""" the lenght of two sequence"""
typed_L = len(typed_words)
referenceL = len(reference_words)
tmp = min(typed_L,referenceL)
if typed_L == 0:
return 0.0
else:
count = 0
for i in range(tmp):
if typed_words[i] == reference_words[i]:
count = count + 1
return (float(count) / typed_L )* 100
def wpm(typed, elapsed):
"""Return the words-per-minute (WPM) of the TYPED string."""
assert elapsed > 0, 'Elapsed time must be positive'
# BEGIN PROBLEM 4
"*** YOUR CODE HERE ***"
# END PROBLEM 4
length = len(typed)
if length == 0:
return 0.0
else:
num = float(length / 5)
tmp =float( elapsed / 60)
return num/tmp
def autocorrect(user_word, valid_words, diff_function, limit):
"""Returns the element of VALID_WORDS that has the smallest difference
from USER_WORD. Instead returns USER_WORD if that difference is greater
than LIMIT.
"""
# BEGIN PROBLEM 5
"*** YOUR CODE HERE ***"
# END PROBLEM 5
if user_word in valid_words:
return user_word
else:
tmp = limit+1
num = -1
for i in range(len(valid_words)):
score = diff_function(user_word,valid_words[i],limit)
if score < tmp:
tmp = score
num = i
if tmp <= limit:
return valid_words[num]
else:
return user_word
def shifty_shifts(start, goal, limit):
"""A diff function for autocorrect that determines how many letters
in START need to be substituted to create GOAL, then adds the difference in
their lengths.
"""
# BEGIN PROBLEM 6
#assert False, 'Remove this line'
# END PROBLEM 6
def insert(start,goal,count,limit):
if count > limit:
return count
if len(start) ==1 or len(goal) == 1:
tmp = max(len(start)-1,len(goal) -1 ) + count
return tmp if((start[0] == goal[0])) else tmp+1
else:
if(start[0] == goal[0]):
return insert(start[1:],goal[1:],count,limit)
else:
return insert(start[1:],goal[1:],count+1,limit)
return insert(start,goal,0,limit)
def pawssible_patches(start, goal, limit):
"""A diff function that computes the edit distance from START to GOAL."""
#assert False, 'Remove this line'
def insert(start,goal,count,limit):
if count > limit:
return count
if len(start) == 1 or len(goal) == 1:
tmp = abs(len(start) - len(goal)) + count #tmp是指现在的修改数加上两个字符串相差的长度部分
if(start[0]!=goal[0]):
tmp = tmp + 1
add_diff = insert(str(goal[0])+start,goal,count+1,limit)
#在这个长度下,仍然可以进行添加操作,此种操作最终结果可能要小于tmp
if len(start) > 1:
#如果是因为goal为1,此时start使用删除操作可能不tmp小
remove_diff = insert(start[1:],goal,count+1,limit)
add_diff = min(remove_diff,add_diff) #此处直接用add_diff 来表示添加和删除操作中的最小值了;
if add_diff < tmp:
tmp = add_diff
return tmp
if(start[0] == goal[0]):
return insert(start[1:],goal[1:],count,limit)
else:
add_diff = insert(start,goal[1:],count+1,limit)# Fill in these lines
remove_diff = insert(start[1:],goal,count+1,limit)
substitute_diff = insert(start[1:],goal[1:],count+1,limit)
return min(add_diff,remove_diff,substitute_diff)
return insert(start,goal,0,limit)
def final_diff(start, goal, limit):
"""A diff function. If you implement this function, it will be used."""
assert False, 'Remove this line to use your final_diff function'
###########
# Phase 3 #
###########
def report_progress(typed, prompt, user_id, send):
"""Send a report of your id and progress so far to the multiplayer server."""
# BEGIN PROBLEM 8
"*** YOUR CODE HERE ***"
# END PROBLEM 8
count = 0
for i in range(len(typed)):
if typed[i] == prompt[i]:
count = count + 1
else:
break
ratio = float(count)/len(prompt)
information = {'id': user_id,'progress': ratio}
send(information)
return ratio
def fastest_words_report(times_per_player, words):
"""Return a text description of the fastest words typed by each player."""
game = time_per_word(times_per_player, words)
fastest = fastest_words(game)
report = ''
for i in range(len(fastest)):
words = ','.join(fastest[i])
report += 'Player {} typed these fastest: {}\n'.format(i + 1, words)
return report
def time_per_word(times_per_player, words):
"""Given timing data, return a game data abstraction, which contains a list
of words and the amount of time each player took to type each word.
Arguments:
times_per_player: A list of lists of timestamps including the time
the player started typing, followed by the time
the player finished typing each word.
words: a list of words, in the order they are typed.
"""
# BEGIN PROBLEM 9
"*** YOUR CODE HERE ***"
# END PROBLEM 9
i = len(times_per_player)
time = []
for n in range(i):
tmp = []
for m in range(0,len(times_per_player[n])-1):
subs = times_per_player[n][m+1] - times_per_player[n][m]
tmp.append(subs)
time.append(tmp)
#print(time)
return game(words,time)
def fastest_words(game):
"""Return a list of lists of which words each player typed fastest.
Arguments:
game: a game data abstraction as returned by time_per_word.
Returns:
a list of lists containing which words each player typed fastest
"""
player_indices = range(len(all_times(game))) # contains an *index* for each player
word_indices = range(len(all_words(game))) # contains an *index* for each word
# BEGIN PROBLEM 10
"*** YOUR CODE HERE ***"
# END PROBLEM 10
fastest_player = []
s = []
times = all_times(game)
for i in range(len(word_indices)):
tmp = 10000
for j in range(len(player_indices)):
if times[j][i] < tmp:
tmp = times[j][i]
player_num = j
fastest_player.append(player_num)
#print(fastest_player)
for i in range(len(player_indices)):
tmp = []
for j in range(len(word_indices)):
if fastest_player[j] == i:
tmp.append(all_words(game)[j])
s.append(tmp)
return s
def game(words, times):
"""A data abstraction containing all words typed and their times."""
assert all([type(w) == str for w in words]), 'words should be a list of strings'
assert all([type(t) == list for t in times]), 'times should be a list of lists'
assert all([isinstance(i, (int, float)) for t in times for i in t]), 'times lists should contain numbers'
assert all([len(t) == len(words) for t in times]), 'There should be one word per time.'
return [words, times]
def word_at(game, word_index):
"""A selector function that gets the word with index word_index"""
assert 0 <= word_index < len(game[0]), "word_index out of range of words"
return game[0][word_index]
def all_words(game):
"""A selector function for all the words in the game"""
return game[0]
def all_times(game):
"""A selector function for all typing times for all players"""
return game[1]
def time(game, player_num, word_index):
"""A selector function for the time it took player_num to type the word at word_index"""
assert word_index < len(game[0]), "word_index out of range of words"
assert player_num < len(game[1]), "player_num out of range of players"
return game[1][player_num][word_index]
def game_string(game):
"""A helper function that takes in a game object and returns a string representation of it"""
return "game(%s, %s)" % (game[0], game[1])
enable_multiplayer = True # Change to True when you're ready to race.
##########################
# Command Line Interface #
##########################
def run_typing_test(topics):
"""Measure typing speed and accuracy on the command line."""
paragraphs = lines_from_file('data/sample_paragraphs.txt')
select = lambda p: True
if topics:
select = about(topics)
i = 0
while True:
reference = choose(paragraphs, select, i)
if not reference:
print('No more paragraphs about', topics, 'are available.')
return
print('Type the following paragraph and then press enter/return.')
print('If you only type part of it, you will be scored only on that part.\n')
print(reference)
print()
start = datetime.now()
typed = input()
if not typed:
print('Goodbye.')
return
print()
elapsed = (datetime.now() - start).total_seconds()
print("Nice work!")
print('Words per minute:', wpm(typed, elapsed))
print('Accuracy: ', accuracy(typed, reference))
print('\nPress enter/return for the next paragraph or type q to quit.')
if input().strip() == 'q':
return
i += 1
@main
def run(*args):
"""Read in the command-line argument and calls corresponding functions."""
import argparse
parser = argparse.ArgumentParser(description="Typing Test")
parser.add_argument('topic', help="Topic word", nargs='*')
parser.add_argument('-t', help="Run typing test", action='store_true')
args = parser.parse_args()
if args.t:
run_typing_test(args.topic)