You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正弦函数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()

关键改动说明

  1. 统一输入处理:将所有输入逻辑整合到get_user_inputs函数,一次性返回所有变量,彻底解决作用域问题。
  2. 修正频率转换逻辑:明确区分Hz和角频率输入,直接计算正确的角频率,去掉错误的单位转换。
  3. 正确处理积分结果:提取quad返回的第一个元素作为积分值,严格按照RMS公式计算。
  4. 参数传递匹配:确保plot_signal接收正确的角频率参数,绘图与计算逻辑一致。
  5. 完善输入交互:支持起始时间的默认值输入,优化用户体验。
  6. 可读性优化:拆分函数职责,变量命名清晰,添加必要注释。

内容的提问来源于stack exchange,提问作者ImPickleRick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 17:06:10