正弦函数RMS计算器代码重构求助:解决作用域与数据类型问题
正弦信号RMS计算器代码重构与问题修复
原代码核心问题
- 未定义变量直接使用:
main函数里的frequency、end_time、start_time未获取或定义就直接调用,会抛出NameError。 - 频率转换逻辑错误:
get_time_vars中,非Hz单位(角频率)的转换逻辑搞反,且额外添加了无意义的*1000转mHz操作,导致计算混乱。 - 函数返回值无效:
get_time_vars中return语句后的代码永远不会执行,且未返回起始时间。 - 积分结果处理错误:
scipy.integrate.quad返回元组(积分结果, 误差),原代码直接用result开平方会报错,需取第一个元素。 - 参数传递不匹配:调用
plot_signal时传入frequency,但函数需要angular_frequency,导致绘图完全错误。 - 起始时间未处理:原需求要求获取起始时间,但原代码未提供输入入口,直接用默认值0。
修复后的完整代码
import math import numpy as np from scipy.integrate import quad import matplotlib.pyplot as plt def get_user_inputs(): # 获取振幅 amplitude = float(input("请输入振幅: ")) # 获取相位角(度) phase_angle_deg = float(input("请输入相位角(单位:度): ")) phase_angle_rad = math.radians(phase_angle_deg) # 获取频率/角频率 is_hertz = input("频率单位是Hz吗?y/n: ").strip().lower() if is_hertz == "y": freq_hz = float(input("请输入频率(Hz): ")) angular_freq = freq_hz * 2 * math.pi else: angular_freq = float(input("请输入角频率(rad/s): ")) # 获取起始时间,支持默认值0 start_time_input = input("请输入起始时间(默认0,直接回车使用默认值): ").strip() start_time = float(start_time_input) if start_time_input else 0 # 获取结束时间,未提供则自动设置为10个周期 has_end_time = input("是否提供结束时间?y/n: ").strip().lower() if has_end_time == "y": end_time = float(input("请输入结束时间: ")) else: # 周期T = 2π/ω,10个周期的结束时间为起始时间+10*T period = 2 * math.pi / angular_freq end_time = start_time + 10 * period return amplitude, phase_angle_deg, phase_angle_rad, angular_freq, start_time, end_time def integrand(t, amplitude, angular_freq, phase_angle_rad): # 被积函数:正弦信号的平方(cos和sin的RMS结果一致) signal = amplitude * np.cos(angular_freq * t + phase_angle_rad) return signal ** 2 def calculate_rms(amplitude, angular_freq, phase_angle_rad, start_time, end_time): # 计算积分:∫(start到end) signal² dt integral_result, error = quad(integrand, start_time, end_time, args=(amplitude, angular_freq, phase_angle_rad)) # RMS公式:sqrt( (1/(end-start)) * 积分结果 ) rms_value = math.sqrt(integral_result / (end_time - start_time)) return rms_value, integral_result, error def plot_signal(amplitude, angular_freq, phase_angle_rad, start_time, end_time): time_values = np.linspace(start_time, end_time, num=1000) signal_values = amplitude * np.cos(angular_freq * time_values + phase_angle_rad) plt.figure(figsize=(10, 6)) plt.plot(time_values, signal_values, label='正弦信号', color='#1f77b4') plt.axhline(y=0, color='gray', linestyle='--', alpha=0.7) plt.xlabel('时间 (s)') plt.ylabel('振幅') plt.title('正弦信号波形') plt.legend() plt.grid(True, linestyle=':', alpha=0.6) plt.show() def main(): # 获取所有输入变量,避免作用域问题 amplitude, phase_angle_deg, phase_angle_rad, angular_freq, start_time, end_time = get_user_inputs() # 计算RMS rms_value, integral, error = calculate_rms(amplitude, angular_freq, phase_angle_rad, start_time, end_time) # 打印输入信息和结果 print("\n===== 输入参数 =====") print(f"振幅: {amplitude}") print(f"起始时间: {start_time} s") print(f"结束时间: {end_time} s") print(f"角频率: {angular_freq:.4f} rad/s") print(f"相位角: {phase_angle_deg}° ({phase_angle_rad:.4f} rad)") print("\n===== 计算结果 =====") print(f"积分结果: {integral:.4f}") print(f"积分误差估计: {error:.4e}") print(f"RMS值: {rms_value:.4f}") # 绘制信号 plot_signal(amplitude, angular_freq, phase_angle_rad, start_time, end_time) if __name__ == "__main__": main()
关键改动说明
- 统一输入处理:将所有输入逻辑整合到
get_user_inputs函数,一次性返回所有变量,彻底解决作用域问题。 - 修正频率转换逻辑:明确区分Hz和角频率输入,直接计算正确的角频率,去掉错误的单位转换。
- 正确处理积分结果:提取
quad返回的第一个元素作为积分值,严格按照RMS公式计算。 - 参数传递匹配:确保
plot_signal接收正确的角频率参数,绘图与计算逻辑一致。 - 完善输入交互:支持起始时间的默认值输入,优化用户体验。
- 可读性优化:拆分函数职责,变量命名清晰,添加必要注释。
内容的提问来源于stack exchange,提问作者ImPickleRick
相关产品推荐
相关产品推荐

