I need to create functions to perform the calculation of the triangle area that include error handling using exceptions.
Def 1: Function named checkTriangleEdges(a, b, c) that verifies:
- That the three parameters are greater than 0, and
- if the three parameters can form a triangle. Raise a ValueError exception with the error message “All triangle edges must be > 0” if condition 1 is violated, and with the error message “a, b and c can not form a triangle” if condition 2 is violated.
Def 2: Function named requestTriangleEdges() that uses the input() function to obtain 3 numbers from the user and checks them with the checkTriangleEdges(a, b, c) function. If an exception occurs, the function must print the error message and repeat until valid triangle edges are obtained. Return the obtained valid triangle edges as a tuple.
Def 3: Function named calculateTriangleArea() that uses requestTriangleEdges() to obtain valid triangle edges from the user and to calculate and return the triangle area.
import math
def checkTriangleEdges(a, b, c):
if a<=0 or b<=0 or c<=0:
raise ValueError("All triangle edges must be > 0")
if a b<c or b c<a or c a<b:
raise ValueError("a, b and c can not form a triangle")
def requestTriangleEdges():
try:
a = float(input("Length of edge a: "))
b = float(input("Length of edge b: "))
c = float(input("Length of edge c: "))
checkTriangleEdges(a, b, c)
return (a, b, c)
except ValueError as e:
print(e)
requestTriangleEdges()
def calculateTriangleArea():
a, b, c = requestTriangleEdges()
p = (a b c) / 2
s = p * (p - a) * (p - b) * (p - c)
result = math.sqrt(s)
return print(result)
calculateTriangleArea()
The problem is that when I check the program and immediately enter data that does not imply an error, everything works, but when I enter such data that imply an error, everything works until the moment when I enter the correct value and the program gives an error
Output example:
In case when all data is correct:
Length of edge a: 3
Length of edge b: 3
Length of edge c: 3
3.897114317029974
After handling an error
Length of edge a: x
could not convert string to float: 'x'
Length of edge a: 3
Length of edge b: 10
Length of edge c: 1
a, b and c can not form a triangle
Length of edge a: 0
Length of edge b: 1
Length of edge c: 3
All triangle edges must be > 0
Length of edge a: 4
Length of edge b: 4
Length of edge c: 4
Traceback (most recent call last):
File "C:\Users\Alex\Documents\HTML5\Fundamentals-S1\tp7.py", line 42, in <module>
calculateTriangleArea()
File "C:\Users\Alex\Documents\HTML5\Fundamentals-S1\tp7.py", line 32, in calculateTriangleArea
a, b, c = requestTriangleEdges()
TypeError: cannot unpack non-iterable NoneType object
I completely don't understand where I did a mistake and why program is not working.
CodePudding user response:
Do not use recursion for repeated input. Use a while True loop then break (or, in this case, return) once you have valid inputs.
Return values from your functions rather than printing within them.
For example:
def checkTriangleEdges(a, b, c):
if a <= 0 or b <= 0 or c <= 0:
raise ValueError("All triangle edges must be > 0")
if a b < c or b c < a or c a < b:
raise ValueError("a, b and c can not form a triangle")
return a, b, c
def requestTriangleEdges():
while True:
try:
a = float(input("Length of edge a: "))
b = float(input("Length of edge b: "))
c = float(input("Length of edge c: "))
return checkTriangleEdges(a, b, c)
except ValueError as e:
print(e)
def calculateTriangleArea():
a, b, c = requestTriangleEdges()
p = (a b c) / 2
s = p * (p - a) * (p - b) * (p - c)
return s**0.5
area = calculateTriangleArea()
print(area)
CodePudding user response:
my addition to @Cobra answer
look step by step what happens in this snippet when you make an error at first and then gives to it a valid data :
def requestTriangleEdges():
try:
a = float(input("Length of edge a: "))
b = float(input("Length of edge b: "))
c = float(input("Length of edge c: "))
checkTriangleEdges(a, b, c)
return (a, b, c)
except ValueError as e:
print(e)
requestTriangleEdges()
you make an error, execution comes to the line
checkTriangleEdges(a, b, c)
here it breaks and exception block is to be executed now
print(e)
requestTriangleEdges()
ok, it prints an error and runs requestTriangleEdges
again
and here is the thing you need to understand - what exactly happens when requestTriangleEdges
is run,
your mistake is that you think that requestTriangleEdges
run for the second time 'stays' in the same place
like here
def requestTriangleEdges():
try:
a = float(input("Length of edge a: "))
b = float(input("Length of edge b: "))
c = float(input("Length of edge c: "))
checkTriangleEdges(a, b, c)
return (a, b, c)
except ValueError as e:
print(e)
requestTriangleEdges()
and you can see it when you look at your code
that's the mistake
when it run for the second time it is in fact inside of this code you look at
to be more precise now it's here in this last line:
requestTriangleEdges()
and when it will be executed normally and without any mistakes will be ended your 'the most up lvl' (in terms of recursion) code will be executed further and as we remember initially code was broken on this line
checkTriangleEdges(a, b, c)
and so it means that this line:
return (a, b, c)
wasn't executed
and after ending in except block the function returns None
(cuz there is no other return)
and so you get an error here
a, b, c = requestTriangleEdges()
a,b,c cannot be assigned to `None
as @Cobra says the problem is to be solved by getting rid of recursion and using While
loop
but for understanding how your code can be work, you can just change this Except block:
print(e)
requestTriangleEdges()
to this one:
print(e)
return requestTriangleEdges()
and your code will be working because now it return not None
but a,b,c
in the last rec depth lvl
(but again it's really bad idea to use recursion for user input, stack isn't endless)