Using If Statements To Check If Something Raises An Error - python

I'm trying to write a program that will solve questions about parametric equations for me. I'm trying to do the following:
I'm trying to find 2 answers to a parametric equation. The first answer will be the positive square root. The second answer will be the negative square root. If the first square root raises a math domain error, don't find the second answer. This is what I have so far:
def hitsGround(vertical_velocity, y_coordinate):
h = vertical_velocity/-16/-2
k = -16*(h)**2 + vertical_velocity*(h) + y_coordinate
time = float(input("At what height do you want me to solve for time?: "))
try:
hits_height1 = math.sqrt((time - k)/-16) + h
except ValueError:
print("It won't reach this height.")
else:
print(f"It will take {hits_height1} seconds to hit said height.")
try:
hits_height2 = -math.sqrt((time - k)/16) + h
except ValueError:
print("There is no second time it will reach this height.")
else:
print(f"It will take {hits_height2} seconds to hit said height.")
Is there any way to use an if statement to check if the first equation raises a math domain error so I can make it so it doesn't find the second answer? Thanks!

You cannot test for a run-time exception with if; that's exactly what try-except does. However, when the illegal operation is so directly defined, you can test for that condition before you try the sqrt opertaion:
if (time - k)/-16 < 0:
# no roots
else:
# proceed to find roots.

In general, the way to make exception handling easier to is to do everything you need to do to handle the exception within the except. For example, if you don't want to find the second answer after you hit the first exception, just return:
try:
hits_height1 = math.sqrt((time - k)/-16) + h
except ValueError:
print("It won't reach this height.")
return
print(f"It will take {hits_height1} seconds to hit said height.")
If you want to make life even easier, just allow the exception to raise (without catching it at all), and catch it in the calling function!
def hitsGround(vertical_velocity, y_coordinate):
h = vertical_velocity/-16/-2
k = -16*(h)**2 + vertical_velocity*(h) + y_coordinate
time = float(input("At what height do you want me to solve for time?: "))
hits_height1 = math.sqrt((time - k)/-16) + h
print(f"It will take {hits_height1} seconds to hit said height.")
hits_height2 = -math.sqrt((time - k)/16) + h
print(f"It will take {hits_height2} seconds to hit said height.")
try:
hitGround(1.0, 10.0)
except ValueError:
print("It won't reach that height again.")
Wherever the exception is raised in hitsGround, it will immediately stop whatever that function is doing, and it will hit the except in the calling scope. That way you only need a single try/except to cover both cases.

Related

How can I get this code to run properly? I'm having issues with the if and else statements and apparently it's not indented correctly

I'm trying to create a program that calculates the stopping distance of a car and I want to make it so that if the user inputs the deceleration as greater than 0, then the program will print Cannot use positive integers. Also, the program is having indention errors with the else statements.
I already played around with the indentation and it doesn't fix anything.
a = raw_input("How quickly is the vehicle decelerating? ")
if a > 0:
print "cannot be a positive integer"
else a < 0:
s1 = (0 - float(u)**2)
s2 = (2*float(a))
s = s1/s2
print "The vehicle will travel %s meters before coming to a complete stop" % (s)
it is indeed incorrectly indented. Your last print function should be backspaced once to be out of else. Secondly, else does not receive a condition, i.e, if you type:
if a > 5:
print(True)
else a < 5:
print(False)
You will receive the following message:
SyntaxError: invalid syntax
Two options to solve it:
if a > 5:
print(True)
else:
print(False)
or
if a > 5:
print(True)
elif a < 5:
print(False)
Third, as your object a is a string, the first condition a > 0 will fail, once that to accomplish such comparison a must be an int or float;
Lastly, raw_input is not a valid function in Python 3.x. If you go to a more recent version of Python, you should substitute it for just input (). With that in mind, your code should look something like this:
a = input("How quickly is the vehicle decelerating? ")
a = int(a)
if a > 0:
print ("cannot be a positive integer")
else:
s1 = (0 - float(u)**2)
s2 = (2*float(a))
s = s1/s2
print ("The vehicle will travel %i meters per second before coming to a complete stop" % (s))
Hope it helps
Here's a good start for solving the problems with your code. The correct indentation is the following:
a = raw_input("How quickly is the vehicle decelerating? ")
if a > 0:
print("cannot be a positive integer")
elif a < 0:
s1 = (0 - float(u)**2)
s2 = (2*float(a))
s = s1/s2
print("The vehicle will travel %s meters per second before coming to a complete stop" % (s))
Notice I added the parentheses to the print() module. Also, I traded out your else with elif, since another if is what is required if you want to condition it.
Here's some other hints to consider:
1) Try copying and pasting the error message with your post. You'll find that learning to read the errors will benefit you greatly. Feel free to comment them to this answer for further guidance.
2) If you are using python 3.*, raw_input() is depreciated. freecodecamp.com has a great montra: "Read-Search-Ask" in that order.
3) raw_input(), or at least the python3 version I used, will give you a char return.
Good luck!

try, except and while loop in Python

I'm trying to do this exercise for school, but the code won't work, precisely it doesn't execute if statements, after calculating BMI. Further if the input is not correct, the except statment is now checked. Please advise what to correct in the code. Thanks!
user_input_1 = input('What is your weight')
user_input_2 = input('What is your height')
b = 'BMI'
b = int(user_input_1)/(float(user_input_2)**2)
while True:
try:
user_input_1 == int and user_input_1 > 0
user_input_2 == float and user_input_2 > 0
print(b)
if b in range(1, 19):
print('You are skinny as a rail')
break
if b in range(19, 26):
print('You are fit as a butcher\'s dog')
break
if b >= 25:
print('You are as plum as a partridge')
break
break
except ZeroDivisionError:
input('Enter your height in meters as a float')
except user_input_1 != int:
input('Please enter your weight in kg')
for start: note that you declare the variable b row after another. this means that the first deceleration is redundant.
second, don't use break, but elif instead of the 'if'.
third, the first two rows after try, do nothing..
Where to start?
The only division takes place before entering the try block, so your except ZeroDivisionError will never get triggered.
except user_input_1 != int evaluates to except True which is meaningless and will never get triggered
The only way you don't hit a break in your while loop, is if you throw an exception that gets caught (if it's not caught, it'll escape your while loop and exit your program). Since the code that gets user input is outside of the while loop, there would be (if the exceptions could ever be caught) no difference and you'd see the error messages just repeating forever.
There seem to be some fundamental gaps in your understanding of python. I'd suggest filling those first; try and implement just a single desired feature (for example, take user input and display suitable error message if it is invalid) and build from there.
There are lots of problems with your code as SpoonMeiser already mentioned:
The only division takes place before entering the try block, so your except ZeroDivisionError will never get triggered.
except user_input_1 != int evaluates to except True which is meaningless and will never get triggered
The only way you don't hit a break in your while loop, is if you throw an exception that gets caught (if it's not caught, it'll
escape your while loop and exit your program). Since the code that
gets user input is outside of the while loop, there would be (if
the exceptions could ever be caught) no difference and you'd see the
error messages just repeating forever.
Other errors are:
The use of b in range(x, y): These only include integer values values in that interval. And you can test it with:
print(2.1 in range(0,10)) # Prints: False
print(2 in range(0,10)) # Prints: True
You should use = float(input(...)) from the start: if you'll always will use the user input as a float just do it once.
b = 'BMI' ?
Here is the resulting code:
def foo():
try:
user_input_1 = float(input('What is your weight? '))
user_input_2 = float(input('What is your height? '))
if all(x>0 for x in [user_input_1,user_input_2]):
b = user_input_1/user_input_2**2
print(b)
if 0 > b > 26:
print('You are skinny as a rail')
elif 19 > b > 26:
print("You are fit as a butcher's dog")
else:
print('You are as plum as a partridge')
else: raise ValueError
except ValueError:
print('Enter your height in meters as a float')
foo()

Number refuses to divide

I have made a simple function called "Approx" which multiplies two numbers together then divides them by two. When I use the function by itself it works great but it seems in the hunk of code I have it doesn't divide the number in half and I have no idea why. This is my code where is the error and how can I fix it?
import math
def Approx(low,high):
base = low * high
return base/2
root = float(input("What to approx the sqrt of : "))
vague = float(input("How off can it be? : "))
wrong = True
oroot = root
root = math.floor(float(root))
trunk = root + 1
step = 0
while wrong:
if Approx(root,trunk) > oroot - vague and Approx(root,trunk) < oroot:
print("Done. " + str(step) + " steps taken.")
else:
if Approx(root,trunk) > oroot:
temproot = root
root = Approx(root,trunk)
trunk = temproot
step += 1
print("Step " + str(step) + " finished. Approx is " + str(Approx(root,trunk)))
else:
temptrunk = trunk
trunk = Approx(root,trunk)
root = trunk
step += 1
print("Step " + str(step) + " finished. Approx is " + str(Approx(root,trunk)))
if step > 50:
print("More than fifty steps required.")
wrong = False
It looks to me that it definitely does divide by two, it is just that dividing by two doesn't undo multiplying two large numbers together. For example, say you wanted to find the square root of 10. trunk is set to 11. Approx(root, trunk) is 10 * 11 / 2 = 55. This is set to root and trunk becomes the old root, 10. Now you have 55 and 10 instead of 10 and 11. Repeat this a few times and you end up with inf. Look more into the method you're trying to implement (is it the Babylonian method?) and see where your program and the method differ. That is likely the source of your woes, and not a lack of division.
Your function works the way you describe it, however I don't understand how you use it in the rest of the code.
It seems like you are trying to approximate square roots using a variant of Newton's method, but it's hard to understand how you implement it. Some variables in your code are not used (what is temptrunk for ?), and it's hard to determine if it's intended or a mistake.
If it is indeed the newton method you'd like to implement, you'll want to have an approximation function that converges to the target value. In order to do that, you compute the arithmetic mean of a guess and your target value divided by this guess (new_guess = mean([old_guess, target/old_guess])). Once you have that, you just need to compare the difference between new_guess and target, and once it reaches a given threshold (in your code, vague), you can break of the loop.
There are multiple ways to improve other aspects of your code:
I'd advise against using a sentinel value for breaking out of the loop, break statements are more explicit.
You can directly make a loop have maximum number of steps, with :
for step in range(MAX_STEPS):
guess = ... # try to guess
if abs(target - guess) < delta:
break
else:
print("Maximum steps reached.")
The else block will only be called if break is not reached.

Python excepting input only if in range

Hi I want to get a number from user and only except input within a certain range.
The below appears to work but I am a noob and thought whilst it works there is no doubt a more elegant example... just trying not to fall into bad habits!
One thing I have noticed is when I run the program CTL+C will not break me out of the loop and raises the exception instead.
while True:
try:
input = int(raw_input('Pick a number in range 1-10 >>> '))
# Check if input is in range
if input in range(1,10):
break
else:
print 'Out of range. Try again'
except:
print ("That's not a number")
All help greatly appreciated.
Ctrl+C raises a KeyboardInterruptException, your try … except block catches this:
while True:
try:
input = int(raw_input('Pick a number in range 1-10 >>> '))
except ValueError: # just catch the exceptions you know!
print 'That\'s not a number!'
else:
if 1 <= input < 10: # this is faster
break
else:
print 'Out of range. Try again'
Generally, you should just catch the exceptions you expect to happen (so no side effects appear, like your Ctrl+C problem). Also you should keep the try … except block as short as possible.
There are several items in your code that could be improved.
(1) Most importantly, it's not a good idea to just catch a generic exception, you should catch a specific one you are looking for, and generally have as short of a try-block as you can.
(2) Also,
if input in range(1,10):
would better be coded as
if 1 <= input < 10:
as currently function range() repeatedly creates a list of values form 1 to 9, which is probably not what you want or need. Also, do you want to include value 10? Your prompt seems to imply that, so then you need to adjust your call to range(1, 11), as the list generated will not include the upper-range value. and the if-statement should be changed to if 1 <= input <= 10:
You can use this code:
def read_int(prompt, min, max):
while True:
try:
val = int(input(prompt))
except ValueError:
print('Error: wrong input')
else:
if(min <= val < max): # this is faster
break
else:
print('Error: the value is not within permitted range (min..max)')
return val
v = read_int("Enter a number from -10 to 10: ", -10, 10)
print("The number is:", v)

How to determine when input is alphabetic?

I been trying to solve this one for a while and can't seem to make it work right.. here is my current work
while True:
guess = int(raw_input('What is your number?'))
if 100 < guess or guess < 1:
print '\ninvalid'
else:
.....continue on
Right now I have made it so when a user input a number higher than 100 or lower than 1, it prints out "invalid". BUT what if i want to make it so when a user input a string that is not a number(alphabetic, punctuation, etc.) it also returns this "invalid" message?
I have thought about using if not ...isdigit(), but it won't work since I get the guess as an integer in order for the above range to work. Try/except is another option I thought about, but still haven't figured out how to implement it in correctly.
You can use exception handling:
try:
guess = int(raw_input('What is your number?'))
if not (1 <= guess <= 100):
raise ValueError
# .....continue on
except ValueError:
print '\ninvalid'
That way, \ninvalid will be printed if the user either inputs a non-numeric string or inputs a numeric string greater than 100 or smaller than 1.
EDIT: Okay, I submit to the x < y < z syntax. Still think it loses some of its charm when it's used with not, though.
while True:
try:
guess = int(raw_input("..."))
except EOFError:
print "whoa nelly! EOF? we should probably exit"
break # or sys.exit, or raise a different exception,
# or don't catch this at all, and let it percolate up,
# depending on what you want
except ValueError:
print "illegal input: expected an integer"
else:
if not (1 <= guess <= 100):
print "out of range"
else:
print "processing guess... (but if it wasn't 42, then it's wrong)"
break # out of while loop after processing

Categories

Resources