Try and except block not running the exception - python

The code works fine except for the exceptions i.e., when I input something like cat/dog or 1/0 or for the case 3/2, instead of re-prompting, the terminal just goes into blank infinite mode that I have to manually stop with cmd+c. Please help identify what I'm doing wrong. Thanks!
def main():
fuel=input("Fuel: ")
c=convert(fuel)
print(f"{convert(fuel)}%")
gauge(c)
def convert(fraction):
while True:
try:
X,Y=fraction.split("/")
x=int(X)
y=int(Y)
f=x/y
z=int((x/y)*100)
if f<=1:
return z
except (ValueError, ZeroDivisionError):
pass
def gauge(percentage):
if percentage<=1:
print("E")
elif percentage>=99:
print("F")
else:
print("Z%")
if __name__ == "__main__":
main()

Well, you never re-ask the question. To solve it, move the input("Fuel: ") call inside the while loop:
def main():
c = convert()
print(f"{c}%")
gauge(c)
def convert():
while True:
fraction = input("Fuel:")
try: # Rest can be the same

Related

How do I create a function/method out of this code and then call it to the main()?

enter code hereThis is the original code that I wrote:
while True:
user_input = (input(">>",))
try:
user_input = int(user_input)
except ValueError:
pass
if user_input in range(1, len(something):
break
I want to put in a method:
`get_user_answer(n: int, p: str) -> int` # This is what the method should look like kind of
#But what should I write here?
def main()
# and how would I call it?
main()
I'm learning about methods so I'm confused
I'm expecting it to work like the code I first wrote, but in a method instead that I call to the main function.
# get user answer function
def get_user_answer():
while True:
user_input = (input(">>",))
try:
user_input = int(user_input)
except ValueError:
pass
if user_input in range(1, len(something):
break
# main function
def main():
# calling get_user_answer function here
get_user_answer()
#calling main function here
main()
Thanks everyone for trying to help, I managed to figure it out. If anyone is interested it was:
def get_user_answer(max_num: int, prompt: str) -> int:
while True:
user_input = input(prompt)
try:
user_input = int(user_input)
except ValueError:
pass
if user_input in range(1, max_num):
break
print(f"Write a number between - {max_num}")
return user_input
I probably didn't give enough information to help me in the best way, now that I think about it, but thanks anyway.
and calling the function to main:
user_input = get_user_answer(len(something), ">>")

Python How to iterate through a list of functions

I have a bunch of functions that do x y and z, these functions get executed after an exception has occured. so my problem is that instead of writing the functions one by one i want to create a list of functions and a write a function to iterate through those functions in the list.
If you could show me an example that would be of great help.
here is what i have:
def call_va_funcs(self, stop):
self.disableZüruckVA()
while True:
try:
correct = urllib.request.urlopen("http://192.168.167.12", timeout=10).getcode()
print(correct, "192.168.100.2 is reachable: FAIL")
if correct == 200:
self.enableZüruckVA()
self.exitflag == True
break
except Exception:
print('Preflash')
if self.exitflag == True:
self.enableZüruckVA()
break
self.ping_all_va()
time.sleep(1)
if self.exitflag == True:
self.enableZüruckVA()
break
self.run_rxtx()
time.sleep(1)
if self.exitflag == True:
self.enableZüruckVA()
break
self.call_netzteil()
time.sleep(1)
if self.exitflag == True:
self.enableZüruckVA()
break
As you can see here i am repeating the same process over and over again but with a different function. Can anyone help me figure out how to have a list and then just iterate through the bunch of functions.
Thank you
Let's say you have functionA(), functionB() and functionC().
You could put the names of the functions in a list like this:
f_list = [functionA, functionB, functionC]
You can then call these functions one after another:
while True:
# other code here...
try:
#... other code
except:
# ...other code
for func in f_list:
func()
time.sleep(1)
if self.exitflag == True:
self.enableZüruckVA()
break
you could try smth like this
my_methods = []
my_methods.append('ping_all_va')
my_methods.append('run_rxtx')
my_methods.append('next_func')
for cmd in my_methods:
method = getattr(self, cmd)
method()
time.sleep(1)
if self.exitflag == True:
self.enableZüruckVA()
break

problem printing a string within except? Program just ends instead of printing statement

The program isn't printing what I want ("too slow") after the except with the KeyboardInterrupt, which should end the program and print the string, instead the program just ends. I tried messing around with it a bit but can't seem to figure it out. What should I do?
import os
import signal
import threading
from random import randint
def timed_input(interval, *args):
t = threading.Timer(interval, os.kill, args=(os.getpid(), signal.SIGINT))
t.start()
try:
return int(input(*args))
except:
pass
finally:
t.cancel()
while True:
want = randint(1,9)
try:
got = timed_input(5, f'type "{want}": ')
except KeyboardInterrupt:
print('too slow')
else:
if got != want:
print('You Lose.')
break
This is because your first function is removing the KeyboardInterrupt thus making the second try block useless.
To fix this add another except block for the first function so it is properly raised:
import os
import signal
import threading
from random import randint
def timed_input(interval, *args):
t = threading.Timer(interval, os.kill, args=(os.getpid(), signal.SIGINT))
t.start()
try:
return int(input(*args))
except KeyboardInterrupt:
raise
except ValueError:
pass
finally:
t.cancel()
while True:
want = randint(1,9)
try:
got = timed_input(5, f'type "{want}": ')
except KeyboardInterrupt:
print('too slow')
else:
if got != want:
print('You Lose.')
break

Get user input to stop a while loop

I need a way to stop a loop by getting user input without blocking the loop itself which works cross-platform.
Things I have tried:
processes (closes stdin so I can't use input())
threads (can't kill a thread if the while loop terminates and I no longer need the input())
FLAG = False
def break_main_loop(): # how do I get this to execute?
global FLAG
user_in = input()
if user_in == 'stop':
FLAG = True
return
else:
break_main_loop()
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if FLAG:
break
return # if I return here, I need to cancel break_main_loop's input()
main()
This will work for you and simple to use. Replace main function with this
def main():
# do stuff, e.g. getting other user input()
try:
while True:
stuff()
except KeyboardInterrupt:
print("Press 1 to quit")
return # if I return here, I need to cancel break_main_loop's input()
main()
I'd love to answer your question. You see, once you are in the main-loop, you don't necessarily need to use a FLAG variable, rather, I'd suggest doing something like this :
def break_main_loop(): # how do I get this to execute?
user_in = input()
if user_in == 'stop':
return True # Returning integer 1 also works just fine
else:
return False # Returning integer 0 also works just fine
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if break_main_loop(): # If the user inputs stop, the loop stops via the return statement automatically
return
main()
If you wish to get out of the loop without returning anything else and keep the main() function running for doing stuff:
def break_main_loop(): # how do I get this to execute?
user_in = input()
if user_in == 'stop':
return True # Returning integer 1 also works just fine
else:
return False # Returning integer 0 also works just fine
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if break_main_loop():
break
#continue doing stuff
main()
Now, there's a better way to break out of the loop without using the helper function break_main_loop(), and that's done like so:
def stuff():
pass
def main():
# do stuff, e.g. getting other user input()
while True:
stuff()
if str(input("Do you wish to continue:[y/n]")) == 'n':
break
#continue doing stuff
main()
This lets you get rid of the helper function completely.
I hope this answer was helpful. :D
try this:
class new_game:
start_game = True
# end_game = False
def break_main_loop(self): # how do I get this to execute?
print("game is ending!")
def stuff(self):
print("this is stuff happening....now...game is: ", self.start_game)
def game_loop(self):
user_in = int(input("enter '2' to end game or '1' to keep playing:" ))
if user_in == 1:
self.stuff()
self.game_loop()
else:
return self.break_main_loop()
Test_game = new_game()
Test_game.game_loop()

Trigger Break Keyword Using Dictionary Python

I'm trying to make do with Python's lack of a switch statement and make code more efficient by using a dictionary, but I can't quite get what I'm looking for. Here's a simplified version of the code I'm working with
def zero():
print("Yo")
def one():
print("Hey")
options = {
0: zero,
1: one,
}
while True:
response = int(input("Number: "))
try:
options.get(response)()
except TypeError:
print("Not a valid response")
and what I would like to see is some way to break the loop such as 2: break that exits the loop. Currently I'm using sys.exit(0), but was wondering if it was possible to use the break keyword
You could define a LoopBreak exception, raise that in a two function, and catch it in the loop to break:
class LoopBreak(Exception):
pass
def zero():
print("Yo")
def one():
print("Hey")
def two():
raise LoopBreak
options = {
0: zero,
1: one,
2: two
}
while True:
response = int(input("Number: "))
try:
options.get(response)()
except TypeError:
print("Not a valid response")
except LoopBreak:
break
As a point of interest, this is similar to the pattern used natively by Python to stop generators; they raise a StopIteration exception when they run out of values to yield.
EDIT: As #mfripp correctly notes below, this will mask any TypeErrors that are raised during execution of zero or one. I would change the main loop to this instead (so you don't have to rely on TypeError):
while True:
response = int(input("Number: "))
action = options.get(response)
if action is None:
print("Not a valid response")
continue
try:
action()
except LoopBreak:
break
There are a few ways you could do this.
Here's a more robust version of #BingsF's clever answer (this one won't mask exceptions raised within the selected function):
class LoopBreak(Exception):
pass
def zero():
print("Yo")
def one():
print("Hey")
def two():
raise LoopBreak
options = {
0: zero,
1: one,
2: two
}
while True:
try:
response = int(input("Number: "))
action = options[response]
except (ValueError, KeyError):
print("Not a valid response")
continue
try:
action()
except LoopBreak:
break
Or you could specify a special flag in your dictionary that will force a break:
def zero():
print("Yo")
def one():
print("Hey")
options = {
0: zero,
1: one,
2: False
}
while True:
try:
response = int(input("Number: "))
action = options[response]
except (ValueError, KeyError):
print("Not a valid response")
continue
if action is False:
break
else:
action()
Or use a special return value to force a break:
def zero():
print("Yo")
# returns None by default
def one():
print("Hey")
# returns None by default
def two():
return False
options = {
0: zero,
1: one,
2: two
}
while True:
try:
response = int(input("Number: "))
action = options[response]
except (ValueError, KeyError):
print("Not a valid response")
continue
if action() is False:
break
The following code might be more "Pythonic". It could be infinitesimally slower than the approaches above, because it has to check all the if statements instead of looking up the function in a dictionary via a hash. But it may be easier to read and maintain.
while True:
try:
response = int(input("Number: "))
except ValueError:
response = -1 # error flag
if response == 0:
print("Yo")
elif response == 1:
print("Hey")
elif response == 2:
break
else:
print("Not a valid response")
This is all you need:
while True:
response = int(input("Number: "))
if response not in options:
print("Not a valid response")
else if response == 2:
break
else:
options[response]() # invoke the corresponding function
Incidentally, storing functions in a dictionary and having to invoke them like this isn't exactly Pythonic. It's a lot nicer to simply explicitly enumerate the behaviour you need with successive ifs.

Categories