Vro
Vro

Reputation: 63

How to ask user for input when an exception has occurred?

I am making a code to solve quadratic formula and need exception handling such that missing command line arguments are detected. In the except IndexError: block, instead of exiting the program you should use input() to ask the user for the missing input data. It doesn't work with the following code. Anyone have any ideas?

from math import sqrt
import sys

print('This program will solve the quadratic formula with given values, please enter below.')

try:
    a=float(sys.argv[1]) #first system argument
    b=float(sys.argv[2]) #second system argument 
    c=float(sys.argv[3]) #third system argument
    d=b**2-4*a*c #discriminant
    x1=((-b+sqrt(d))/2*a) #first solution
    x2=((-b-sqrt(d))/2*a) #second solution
except IndexError:
    raise IndexError(
        'Oops! Looks like you have not entered all values. Try again.') #request user input
    a=input(sys.argv[1]) #first system argument
    b=input(sys.argv[2]) #second system argument 
    c=input(sys.argv[3]) #third system argument
    d=b**2-4*a*c #discriminant
    x1=((-b+sqrt(d))/2*a) #first solution
    x2=((-b-sqrt(d))/2*a) #second solution
    
print(f'The quadratic formula with used a,b,c values gives two roots {x1:.2f} and {x2:.2f}')

Upvotes: 1

Views: 517

Answers (2)

Bryan Taylor
Bryan Taylor

Reputation: 66

I see several ways to improve with the original code:

  • Statements following raise are never executed
  • Conversion of string via float() may throw a ValueError
  • If less than 3 arguments are supplied, then sys.argv[n] will throw an error
  • You should revalidate re-entered input until it's correct.
  • You shouldn't trigger reentry of correct values if later ones have issues.
  • If your discriminant d is negative, sqrt() will throw a ValueError
  • Make your code DRY (Don't Repeat Yourself) by factoring out validation logic.
  • You need some way to do output.

The following code fixes these by:

  • Adding a validate method to be more DRY and validate input and handle ValueError.
  • Process the 3 arguments in order via an iterator that returns '' if not supplied, which the validate method will handle.
  • Test for negative discriminant.
from math import sqrt
import sys

print('This program will solve the quadratic formula with given values, please enter below.')

def validate(name, value):
    try:
        return float(value)
    except ValueError:
        new_value = input(f"Entered a value for {name}: ")
        return validate(name, new_value)

args = iter(sys.argv)
a = validate('a', next(args, ''))
b = validate('b', next(args, ''))
c = validate('c', next(args, ''))
d=b**2-4*a*c #discriminant
if d >= 0 :
    x1=((-b+sqrt(d))/2*a) #first solution
    x2=((-b-sqrt(d))/2*a) #second solution
    print(f"the roots {x1} and {x2}")
else:
    print("the equation has no real-valued solutions")

Upvotes: 1

Itzik Friedland
Itzik Friedland

Reputation: 245

You are raising un exception inside the catch block:

except IndexError:
  raise IndexError(
    'Oops! Looks like you have not entered all values. Try again.')

You can remove it and prompt the user this message using input() or something similar. for example:

except IndexError:

    a= input('Oops! Looks like you have not entered all values. Enter the value again.')

Upvotes: 0

Related Questions