Python读取文件计算平均值遇ZeroDivisionError及结果不一致问题
Python作业脚本问题分析
问题描述
我正在完成一项Python作业,要求开发程序从文件读取数值数据、执行计算并将结果写入输出文件,同时需包含健壮的异常处理。但编写的原脚本在读取文件计算平均值时出现ZeroDivisionError: float division by zero错误,错误指向total_avg = total / count行,且循环计算结果与单独提取循环逻辑的脚本结果不一致。期望输出的平均值为21.0。
原脚本代码
""" Develop a Python program that reads numerical data from a file, performs a series of calculations on the data, and writes the results to an output file. The program should include robust exception handling to manage potential errors during file operations and calculations. 1. Reading Data from a File: - The program should read a file named input.txt. Use the sample input.txt file attached. Each line in the file contains a single integer. - The file may contain invalid lines (e.g., non-integer values). These lines should be skipped, and an appropriate message should be logged. Use the invalid line sample input_invalid.txt file attached. 2. Performing Calculations: - Compute the sum, average, maximum, and minimum of the valid integers read from the file. - Ensure that the program handles cases where the file may be empty or contain no valid integers by logging a suitable message. 3. Writing Results to a File: - Write the calculated results (sum, average, maximum, and minimum) to a file named output.txt. - Each result should be written on a new line in the format: Sum: <value>, Average: <value>, etc. 4. output.txt sample Sum: 105 Average: 21.0 Maximum: 50 Minimum: -5 5. Exception Handling: - Include exception handling to manage: -- File not found errors. -- Value errors when converting strings to integers. -- Any other unforeseen errors. - Log appropriate error messages for each type of exception. Evaluation Criteria: Correctness: The program correctly reads, processes, and writes data. Robustness: The program handles exceptions and edge cases effectively. Code Quality: The code is well-organized, commented, and follows best practices. """ def main(): # Initializing variables to 0 for the for loop section to get the average total = 0.0 count = 0 input_file = open(r'/home/ed/files/Documents/School/Classes/ITEC2270-01_Application_Development/input.txt', 'r') # Reading each line and placing that value in a variable line1 = int(input_file.readline()) line2 = int(input_file.readline()) line3 = int(input_file.readline()) line4 = int(input_file.readline()) line5 = int(input_file.readline()) # Create a variable to store the sum of all the lines read above total_sum = line1 + line2 + line3 + line4 + line5 # For loop to count the lines in the input.txt file opened above for line in input_file: val = float(line) count += 1 total += val input_file.close() # Assigning a variable to the calculation of average from the for loop above total_avg = total / count # Printing that average total to the screen print(f'{total_avg:.1f}') # Designating output file to write to output_file = open('/home/ed/files/Documents/School/Classes/ITEC2270-01_Application_Development/output.txt', 'w') # Write the sum total of the input file to the output file output_file.write(f'Sum: {total_sum}\n') #output_file.write(f'Average: {total_avg}\n') if __name__ == '__main__': main()
测试用的循环脚本代码
def main(): total = 0.0 count = 0 input_file = open(r'/home/ed/files/Documents/School/Classes/ITEC2270-01_Application_Development/input.txt', 'r') for line in input_file: val = float(line) count += 1 total += val input_file.close() total_avg = total / count print(f'The average of all numbers in the file is {total_avg:.1f}.') main()
问题原因分析
- 文件指针耗尽导致循环无数据:原脚本先通过
readline()手动读取了5行数据,此时文件读取指针已移动到文件末尾。后续for line in input_file循环从当前指针位置开始读取,没有剩余内容,所以count保持为0,执行total_avg = total / count时触发ZeroDivisionError。 - 数据计算逻辑拆分错误:原脚本手动计算了前5行的
total_sum,但循环部分未处理这些数据,导致平均值仅计算了不存在的剩余行,和实际需要计算所有行的需求不符。
修正后的脚本
def main(): total = 0.0 count = 0 valid_numbers = [] try: # 使用with语句自动管理文件关闭,避免资源泄漏 with open(r'/home/ed/files/Documents/School/Classes/ITEC2270-01_Application_Development/input.txt', 'r') as input_file: for line_num, line in enumerate(input_file, 1): line = line.strip() if not line: continue # 跳过空行 try: num = int(line) valid_numbers.append(num) total += num count += 1 except ValueError: print(f"警告:第{line_num}行 '{line}' 不是有效整数,已跳过") if count == 0: print("错误:文件中没有有效整数") return total_sum = total total_avg = total / count max_num = max(valid_numbers) min_num = min(valid_numbers) # 打印结果到控制台 print(f'Average: {total_avg:.1f}') # 写入输出文件 with open('/home/ed/files/Documents/School/Classes/ITEC2270-01_Application_Development/output.txt', 'w') as output_file: output_file.write(f'Sum: {total_sum}\n') output_file.write(f'Average: {total_avg:.1f}\n') output_file.write(f'Maximum: {max_num}\n') output_file.write(f'Minimum: {min_num}\n') except FileNotFoundError: print("错误:未找到输入文件input.txt") except Exception as e: print(f"发生未知错误:{str(e)}") if __name__ == '__main__': main()
修正说明
- 使用
with语句管理文件,无需手动调用close(),避免资源泄漏。 - 一次性读取并处理所有行,解决文件指针位置问题。
- 加入完整异常处理:捕获文件不存在、数值转换错误等情况,并给出明确提示。
- 收集所有有效数字,方便计算最大值和最小值,满足作业要求。
- 处理空行和无效行,符合作业中跳过无效行的要求。
- 增加空文件/无有效数据的判断,避免除以零错误。
内容的提问来源于stack exchange,提问作者t3kg33k
相关产品推荐
相关产品推荐

