Python乘法测试项目:如何根据新纪录类型自定义结果提示字符串
Python乘法测试项目新纪录提示功能实现
你原来写的嵌套分支判断逻辑完全没必要,靠变量存在性+多层if枚举所有破纪录组合的写法维护性极差,还藏了两处逻辑错误,直接按下面的方式改就行,代码量少还不会漏情况。
先修复原有代码的显性问题
- 原代码指定乘法表得分纪录的判断条件写反:得分越高成绩越好,原来的
if score < score_recordN要改成if score > score_recordN - 原代码耗时/得分的颜色判断有覆盖问题:破纪录设置的绿色会被后续
time_lapsed > time_record的分支覆盖成红色,要把颜色判断统一放到所有纪录比对完成后再做 - 原代码用
format做变量名会和Python内置的字符串格式化函数重名,改成其他名字避免隐性bug - 新用户初始纪录值统一规则:得分类初始值设为0(最低可能得分),耗时类初始值设为远大于正常答题时长的值(比如9999秒,原来写的61也能用,但遇到答题超过61秒的新用户会出现首次答题不破纪录的bug)
新纪录提示的简洁实现逻辑
不用枚举4种纪录的16种组合情况,直接用列表收集所有触发的新纪录项,最后用顿号拼接成提示语即可,不管同时破几个纪录都能自动生成通顺的提示:
- 一开始就把4个新纪录的标记初始化为
False,完全删掉用locals()判断变量是否存在的逻辑 - 每命中一个新纪录,就把对应提示文本加到收集列表里,同时更新本地存储的纪录值
- 所有纪录比对完成后,把列表里的文本拼接成最终提示,没有破纪录就返回空字符串
修复后的完整核心代码段
from random import sample import time import math import os # 统一定义颜色常量,避免到处写转义序列难维护 GREEN = '\u001b[32;1m' RED = '\u001b[31;1m' BLUE = '\u001b[34;1m' RESET = '\u001b[0m' username = input("What is your first name? ").strip() record_file = f'{username}.txt' # 新用户初始化纪录文件:索引0存通用耗时纪录,1存通用得分纪录,2-14存1-12乘法表耗时,15-27存1-12乘法表得分 if not os.path.exists(record_file): # 初始值:耗时统一设9999(不可能达到的慢成绩),得分统一设0(最低分) init_records = ['9999\n', '0\n'] + ['9999\n']*12 + ['0\n']*12 with open(record_file, 'w') as f: f.writelines(init_records) with open(record_file, 'r') as f: content = [line.strip() for line in f.readlines()] tt = int(input("Enter a times table: ")) # 读取对应历史纪录 global_time_record = float(content[0]) global_score_record = int(content[1]) tt_time_record = float(content[tt+1]) # 2~14对应1~12的乘法表耗时索引 tt_score_record = int(content[tt+14]) # 15~27对应1~12的乘法表得分索引 score = 0 numberList = sample(range(13), k=13) start_time = time.time() for number in numberList: answer = input(f"{number} x {tt} = ") if int(answer) == number * tt: print(f"{GREEN}Correct!{RESET}\n") score +=1 else: print(f"{RED}Incorrect{RESET}") print(f"{BLUE}{number*tt}{RESET}\n") end_time = time.time() time_lapsed = end_time - start_time # 时间格式化 seconds = round(time_lapsed % 60, 2) minutes = math.trunc((time_lapsed // 60) % 60) hours = math.trunc(time_lapsed // 3600) if time_lapsed < 60: time_bracket = "{}" time_val = (seconds,) elif time_lapsed < 3600: time_bracket = "{}分{}秒" time_val = (minutes, seconds) else: time_bracket = "{}时{}分{}秒" time_val = (hours, minutes, seconds) # 比对所有纪录,收集破纪录项 record_tips = [] # 指定乘法表耗时 if time_lapsed < tt_time_record: content[tt+1] = str(time_lapsed) record_tips.append(f"{tt}x乘法表新耗时纪录") # 指定乘法表得分 if score > tt_score_record: content[tt+14] = str(score) record_tips.append(f"{tt}x乘法表新得分纪录") # 通用耗时 if time_lapsed < global_time_record: content[0] = str(time_lapsed) record_tips.append("全乘法表通用新耗时纪录") # 通用得分 if score > global_score_record: content[1] = str(score) record_tips.append("全乘法表通用新得分纪录") # 拼接最终新纪录提示 if record_tips: nr = f" {BLUE}恭喜打破:{'、'.join(record_tips)}!{RESET}" else: nr = "" # 统一判断成绩颜色 rg = GREEN if time_lapsed <= global_time_record else RED rg2 = GREEN if score >= global_score_record else RED # 写入更新后的纪录 with open(record_file, 'w') as f: f.writelines([f'{line}\n' for line in content]) # 打印最终结果 print(f"{RESET} You got a score of {rg2}{score}{RESET} out of 13 in {rg}{time_bracket.format(*time_val)}{RESET} seconds!{nr}")
改完之后不管同时破1个、2个、3个还是全部4个纪录,都能自动生成正确的提示,不会出现逻辑遗漏,后续要加新的纪录类型只要在比对部分加一段判断就行,不用改后面的拼接逻辑。
内容的提问来源于stack exchange,提问作者shoewis
相关产品推荐
相关产品推荐

