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

Assert未抛出ValueError:代码修改后无法触发异常的排查求助

问题:修改代码后不再抛出异常,如何修复?

诊断出ValueError断言失败的问题后,我根据评论修改了代码,但现在代码不会抛出异常了。代码哪里出问题了?该如何修复?

实际代码

def main():
    fraction=input("Fraction: ")
    fraction_converted=convert(fraction)
    output=gauge(fraction_converted)
    print(output)


def convert(fraction):
    while True:
        try:
            X,Y=fraction.split("/")
            x=int(X)
            y=int(Y)
            f=x/y
            if f<=1:
                p=int(f*100)
                return p
            else:
                fraction=input("Fraction: ")
                pass

  
        except (ValueError, ZeroDivisionError):
            raise

def gauge(percentage):
    if percentage<=1:
        return "E"
    elif percentage>=99:
        return "F"
    else:
        return str(percentage)+"%"


if __name__=="__main__":
    main()

测试代码

from fuel import convert, gauge
import pytest

def test_correct_input():
    assert convert("1/2")==50 and gauge(50)=="50%"
    assert convert("1/4")==25 and gauge(25)=="25%"
    assert convert("0/4")==0 and gauge(0)=="E"
    assert convert("4/4")==100 and gauge(100)=="F"

def test_zero_division():
    with pytest.raises(ZeroDivisionError):
        convert("1/0")

def test_value():
    with pytest.raises(ValueError):
        convert("cat/dog")

问题分析

  1. convert函数职责越界:该函数本该只负责分数转百分比的逻辑,但现在内部嵌入了while True循环和input调用,导致测试时传入无效参数(比如"5/4"),函数不会抛出异常,反而会阻塞等待用户输入,完全不符合测试预期。
  2. 无效分数未触发异常:当输入的分数大于1时,代码只是重新获取输入,没有抛出ValueError,但测试用例明确要求这种情况属于无效输入,需要抛出异常。
  3. 循环逻辑干扰异常抛出:while True循环存在时,部分无效场景会被循环覆盖,无法触发预期的异常抛出逻辑。

修复方案

把用户输入的循环逻辑移到main函数中,让convert只专注于转换逻辑,遇到无效输入直接抛出异常:

def main():
    while True:
        try:
            fraction = input("Fraction: ")
            fraction_converted = convert(fraction)
            output = gauge(fraction_converted)
            print(output)
            break  # 输入有效则退出循环
        except (ValueError, ZeroDivisionError):
            continue  # 输入无效则重新获取

def convert(fraction):
    X, Y = fraction.split("/")
    x = int(X)
    y = int(Y)
    if y == 0:
        raise ZeroDivisionError
    if x > y:
        raise ValueError
    # 用round避免int截断导致的精度问题
    p = round(x / y * 100)
    return p

def gauge(percentage):
    if percentage <= 1:
        return "E"
    elif percentage >= 99:
        return "F"
    else:
        return f"{percentage}%"


if __name__ == "__main__":
    main()

修复说明

  • 拆分职责:main负责循环获取用户输入、处理异常并重试;convert只做字符串转百分比的纯逻辑转换,无效输入直接抛出对应异常,完全匹配测试用例要求。
  • 明确异常触发条件:主动判断分母为0、分子大于分母的情况,抛出对应异常,覆盖所有无效输入场景。
  • 优化百分比计算:用round替代int,避免类似3/7这种情况被截断为42%(实际应为43%)的精度问题,结果更准确。

现在运行测试代码,所有用例均可通过:

  • test_correct_input:正常转换场景返回正确结果;
  • test_zero_division:传入"1/0"会抛出ZeroDivisionError;
  • test_value:传入"cat/dog"(转int失败)或"5/4"(分子大于分母)都会抛出ValueError。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:55:23