0

My code for fuel.py:

def main():
    while True:
        # Prompting the user to enter a fraction
        fraction = input("Fraction: ")

        # Calling check_fraction() function to validate the input
        x, y = convert(fraction)

        # If x or y is None, prompting the user again to enter a valid fraction
        if x is None or y is None:
            continue

        # Calculating the percentage of the fraction
        percentage = int(round(x / y * 100))

        # Output E if the percentage is less than or equal to 1
        if percentage <= 1:
            print(gauge(percentage))
        # Output F if the percentage is greater than or equal to 99
        elif percentage >= 99:
            print(gauge(percentage))
        # Output the percentage as a percentage value
        else:
            print(f"{gauge(percentage)}%")
        break

def convert(fraction):
    try:
        # Splitting the fraction by '/' and convert the values to integers
        x, y = map(int, fraction.split("/"))

        # Raising ValueError if x is greater than y or y is less than or equal to zero
        if x > y or not str(x).isnumeric() or not str(y).isnumeric() or y==0:
            # Returning None for x and y if an exception is raised
            return None, None
        #frac=x/y I included this line to create  a situation for ZeroDivisionError, but it did not work

        # Returning x and y if the fraction is valid
        return x, y

    # Handle ValueError and ZeroDivisionError exceptions
    except (ValueError, ZeroDivisionError):
        raise

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


if __name__ == "__main__":
    main()

My code for checking ZeroDivisionError in test_fuel.py:

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

1 Answer 1

2

Short answer: you don't raise a ValueError because you have return None, None in this code block when you catch y==0:

if x > y or not str(x).isnumeric() or not str(y).isnumeric() or y==0:
    # Returns None for x and y when logic above is True
    return None, None

Use a try/except block to raise exceptions. try/except "tries" to execute the line(s) of code after the try: statement and continues silently if there are no errors. The except: block is only executed if there is an error. That's where you raise the appropriate exception.

Something like this would work to catch the divide by zero error when y=0:

# Raise ZeroDivisionError if y is zero
try:
    frac = x/y 
except:
    raise ZeroDivisionError

Ideally you have try/except blocks to catch each exception you want to raise. In other words, 1 for the map()/split function, and another for divide by zero.

Also, you need to add some try/except logic in main() to handle exceptions when they are raised by convert(). Otherwise you will just get an ugly traceback with the exception. :-)

1
  • Thank you! I was unknown of the flow of 'try and except' and 'return' keywords. Whenever return keyword is executed, the lines below it are not executed. Therefore, my code was not raising an exception when y==0. I placed the line "If y==0: raise ZeroDivisionerror" before the code which returns None, and my code worked.
    – nirraya
    Commented Jan 31, 2023 at 2:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .