Python食谱转换程序报Fraction参数TypeError问题修复
食谱转换程序报错修复
问题背景
- 基于Python
fractions模块开发的食谱转换程序,核心逻辑为读取固定格式食谱文本,接收用户输入的转换系数后,将每行开头为整数/分数格式的食材用量乘以系数,非数字开头的文本行保持不变,最终将转换结果写入文件名带conv_前缀的输出文件。 - 测试场景:输入食谱文件名
chocchipcookie.txt、转换系数2,程序未生成输出文件,抛出如下错误:
TypeError: both arguments should be Rational instances
根因排查
代码存在4类问题导致运行失败:
- 核心类型错误:
scanAsFractor函数解析数字时,提取到的分子、分母是字符串类型,未转为整数就直接传入Fraction构造方法,触发参数类型不匹配报错,这是本次运行崩溃的直接原因。 - 函数逻辑错误:
delete_digit函数存在两个缺陷:一是Python字符串切片使用了逗号语法(写为text[k, len(text)]),属于语法错误;二是仅判断索引0位置的字符,无法正确跳过行首所有和用量相关的数字、斜杠、空格,会导致后续文本拼接错误。 - 边界处理缺失:逐行读取文本时如果遇到空行,直接访问
line[0]会触发索引越界错误。 - 冗余代码问题:
convertline函数使用了不必要的全局变量,同时存在函数名拼写错误(Fraction错写为Fractor)、未指定文件编码易引发中文乱码、转换后用量和食材名之间缺少空格导致文本粘连等小问题。
修复后完整代码
# 食谱转换程序 from fractions import Fraction def getfile(): filename = input("请输入文件名: ") num_attempts = 1 inputfile_limit = False readFile = None while not inputfile_limit and num_attempts < 3: try: readFile = open(filename, 'r', encoding='utf-8') inputfile_limit = True except IOError: print("文件打开失败,请检查文件名是否正确") num_attempts += 1 filename = input("请输入文件名: ") if num_attempts == 3: raise IOError('文件打开尝试次数超限') return filename, readFile def delete_digit(text): '''删除行首所有和用量相关的数字、斜杠、空格,返回剩余食材说明部分''' k = 0 while k < len(text) and (text[k].isdigit() or text[k] in (' ', '/')): k += 1 return text[k:] def scanAsFraction(line): '''扫描行首的整数/分数字符串,返回对应的Fraction对象''' scan_stop = False get_fraction = Fraction(0, 1) line = line.strip() while not scan_stop and len(line) > 0: k = 0 # 读取分子部分 while k < len(line) and line[k].isdigit(): k += 1 numerator_str = line[0:k] numerator = int(numerator_str) if numerator_str else 0 # 判断是否为分数格式,读取分母 if k < len(line) and line[k] == '/': k += 1 flash = k while k < len(line) and line[k].isdigit(): k += 1 denominator_str = line[flash:k] denominator = int(denominator_str) if denominator_str else 1 else: denominator = 1 get_fraction += Fraction(numerator, denominator) if k >= len(line): scan_stop = True else: line = line[k:].strip() if len(line) == 0 or not line[0].isdigit(): scan_stop = True return get_fraction def convertline(line, factor): """行首为数字时,将用量乘以转换系数返回;否则原样返回""" # 处理空行边界 if len(line.strip()) == 0: return line if line[0].isdigit(): frac_result = scanAsFraction(line) * factor # 分母为1时直接输出整数格式 if frac_result.denominator == 1: frac_result = frac_result.numerator conv_line = str(frac_result) + ' ' + delete_digit(line) else: conv_line = line return conv_line # 主程序 if __name__ == "__main__": file_name, input_file = getfile() # 获取转换系数 conv_factor = input("请输入转换系数: ") conv_factor = scanAsFraction(conv_factor) # 初始化输出文件 output_file_name = "conv_" + file_name output_file = open(output_file_name, 'w', encoding='utf-8') # 逐行转换写入 recipe_line = input_file.readline() while recipe_line: converted_line = convertline(recipe_line, conv_factor) output_file.write(converted_line) recipe_line = input_file.readline() # 关闭文件句柄 input_file.close() output_file.close() print(f"转换完成,结果已保存至{output_file_name}")
修复点说明
- 修正
Fraction传参类型:所有提取到的分子、分母字符串先转为整数再传入构造方法,解决核心报错 - 重写
delete_digit逻辑:循环遍历跳过所有行首的数字、斜杠、空格,修正切片语法错误,正确分离用量和食材说明 - 增加空行边界判断,避免索引越界
- 移除冗余全局变量,修正函数名拼写错误,增加utf-8编码声明避免中文乱码
- 补全转换后用量和食材说明之间的空格,避免文本粘连
效果验证
使用示例食谱测试,输入转换系数2,输出文件内容如下,完全符合预期:
Chocolate Chip Cookie Recipe.
9 cups of all-purpose flour.
4 teaspoon baking soda.
4 cups butter, softened.
3 cups packed brown sugar.
1 white sugar.
1 white sugar.
4 packages of instant vanilla pudding mix.
8 eggs.
内容的提问来源于stack exchange,提问作者annyeong
相关产品推荐
相关产品推荐

