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

CS50加油程序测试失败:未触发预期的ZeroDivisionError

CS50加油程序作业:ZeroDivisionError测试不通过问题

在CS50的加油程序作业中,触发ZeroDivisionError的测试始终无法通过,提示“DID NOT RAISE <class 'ZeroDivisionError'>”。我已在fuel.py中处理了分母为0的情况,但测试仍不通过。

现有代码

fuel.py

def main():
    percentage = -1
    while percentage == -1:
        fraction = input('Fraction: ')
        percentage = convert(fraction)
    return_val = gauge(percentage)
    print(return_val)


def convert(fraction):
    try:
        #if / not in fraction, not enough values to unpack so ValueError
        numerator, denominator = fraction.split('/')
        numerator = int(numerator)
        denominator = int(denominator)
        percentage = round((numerator/denominator)*100)
        if percentage > 100:
            raise ValueError
        else:
            return percentage
    except ValueError:
        return -1
    except ZeroDivisionError:
        return -1


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

if __name__ == "__main__":
    main()

test_fuel.py

from fuel import convert, gauge

import pytest

def test_gauge():
    assert gauge(1) == 'E'
    assert gauge(50) == '50%'
    assert gauge(99) == 'F'

def test_convert():
    assert convert('5/3') == -1
    assert convert('1/2') == 50
    with pytest.raises(ZeroDivisionError):
        convert('5/0')
    with pytest.raises(ValueError):
        convert('cat/dog') 

问题原因

测试用例通过pytest.raises(ZeroDivisionError)期望convert('5/0')时主动抛出ZeroDivisionError异常,但你的convert函数在捕获到ZeroDivisionError后,直接返回了-1,把异常“吞掉”了,导致测试无法检测到预期的异常,因此报错。

解决方案

需要调整convert函数的异常处理逻辑,让它在对应场景下抛出异常,同时修改main函数来捕获这些异常,实现原有的循环输入效果。

修改后的fuel.py

def main():
    while True:
        fraction = input('Fraction: ')
        try:
            percentage = convert(fraction)
            break
        except (ValueError, ZeroDivisionError):
            # 输入无效时继续循环
            continue
    return_val = gauge(percentage)
    print(return_val)


def convert(fraction):
    try:
        numerator, denominator = fraction.split('/')
        numerator = int(numerator)
        denominator = int(denominator)
        # 先检查分母为0的情况,提前抛出异常
        if denominator == 0:
            raise ZeroDivisionError
        percentage = round((numerator / denominator) * 100)
        # 检查百分比是否超出范围或分子为负
        if percentage > 100 or numerator < 0:
            raise ValueError
        return percentage
    except ValueError:
        # 重新抛出ValueError,让调用方处理
        raise

修改说明

  1. convert函数:移除了对ZeroDivisionError的捕获返回逻辑,改为遇到分母为0时主动抛出ZeroDivisionError;捕获ValueError后重新抛出,不返回-1,确保测试能捕获到异常。
  2. main函数:不再依赖convert返回-1来判断输入有效性,而是直接捕获convert抛出的异常,捕获到异常时继续循环输入,直到得到有效的结果。

这样修改后,test_convert中的异常测试用例就能正常捕获到ZeroDivisionError和ValueError,测试可以通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:55:16