Properly terminate script without error message in Spyder - python

SO for my project in python, I am taking two inputs say a & b as integer values. Now the code goes like:
import sys
a = input("enter a")
b = input("enter b")
if a < b:
print(" enter a greater than b and try again")
sys.exit()
# Rest of the code is here
Now this works fine. But creates an extra statement
An exception has occurred, use %tb to see the full traceback.
SystemExit
And I do not want that as the user may think that the code's functioning is not proper. So is there any way that this statement is not shown or any other function which would exit the code without printing anything except the line which I have written?
NOTE I have tried exit() but it continues to execute the code beneath it. Also, I have noticed this related question but the approaches listed there don't work in this case.
EDIT: I am adding some more information. I need to put this exit function into a user-defined function so that every time the user enters some wrong data, the code will call this user-defined function and will exit the code.
If I try to put my code in an if else statement like
def end():
print("incorrect input try again")
os.exit()
a = input("enter data")
if a < 10:
end()
b = input ("enter data")
if b < 20:
end()
# more code here
I don't know why but I can't even define this user-defined function in the end as it raises the error of undefined function end(). I'm using Python with Spyder on Windows.

You can use os._exit()
a = int(input("enter a"))
b = int(input("enter b"))
if a < b:
print(" enter a greater than b and try again")
os._exit(0)

This seems to work just fine:
import sys
def end():
print("incorrect input try again")
sys.exit(1)
a = input("enter data")
if int(a) < 10:
end()
b = input ("enter data")
if int(b) < 20:
end()
I used the sys.exit and fixed your conditions to avoid comparing string with integers. I cannot see any additional messages in the output. Only this:
>py -3 test2.py
enter data1
incorrect input try again
>
Please also take notice of this qoute from python docs:
The standard way to exit is sys.exit(n). [os]_exit() should normally only
be used in the child process after a fork().
It also works in the repl

Related

Python Raising an Exception within "try" block, then catching the same Exception

Came across try/except blocks, such as:
def foo(name):
try:
if name == "bad_name":
raise Exception()
except Exception:
do_something()
return
Is there a reason for doing this, instead of:
def foo(name):
if name == "bad_name":
do_something()
return
In your example specific I would also not have used try/except because as you stated, you could just use an if statement.
Try/except is for occasions where you know the program may crash, so therefore you have written some code that'll run instead of the entire program crashing. You could for example override the default error messages with custom ones.
A better example could be that you want to multiply a number the user wrote times two. Since the input function always returns a string, we need to cast it to an int using the built-in int function. This would work fine if the user had typed in an integer, but if the user had typed in a str instead, the entire program would crash. Let's say we want to print out a message if that happens, we could use try/except. If we also want to repeat the question over and over again until the user writes an integer, we can use a simple while loop. The code below is an implementation of this.
print("Write any integer and I will multiply it with two!")
while True:
# Get user input
userInput = input("Write any number: ")
try:
# Here we try to cast str to int
num = int(userInput)
# The next line will only be run if the line before
# didn't crash. We break out of the while loop
break
# If the casting didn't work, this code will run
# Notice that we store the exception as e,
# so if we want we could print it
except Exception as e:
print("{} is not an integer!\n".format(userInput))
# This code will be run if the while loop
# is broken out of, which will only happen
# if the user wrote an integer
print("Your number multiplied with 2:\n{}".format(num * 2))
Expected outcome:
Write any integer and I will multiply it with two!
Write any number: a
a is not an integer!
Write any number: b
b is not an integer!
Write any number: 4
Your number multiplied with 2:
8

windows Command prompt vanishes after running a python script converted to .exe using pyinstaller

I am using python3.7
I wrote a script which takes some inputs (e.g. a=input("enter a value")
it runs smoothly if i go to its path and run it on command prompt.
I can give input also and run .
If i give wrong input it shows an error or exception(traceback)
So i converted it to .exe using pyinstaller
when i run .exe , it asks for input as expected ,it runs and vanishes , i can't see any output.
if i give a wrong input it suddenly vanishes without showing any traceback
I read many questions regarding this on stackoverflow and google , so i added an input statement at end to make program wait before exiting,
but it doesn't works in case of wrong input or if i use sys.exit("test failed") in some cases it just vanishes ,how to resolve and keep cmd window open?
Adding script for e.g.:
import sys
x = int(input(" enter a number :"))
y = int(input(" enter a number :"))
if x>100 or y > 100 :
sys.exit("ERROR :value out of range")
z=x+y;
print(z)
input('press enter to exit')
if inputs are less than 100 and integer then script(.exe file) runs smoothly and i get message "press enter to exit"
but if input number greater than 100 or if i put a "string or float" in input , cmd window vanishes without display any traceback
whereas if i run py file from cmd then i get proper traceback for wrong input.
You could use try-except and input() function, so that when there is any error, it will wait for the user to interact.
Look at this example -
a = input('Please enter a number: ')
try:
int(a) # Converts into a integer type
except ValueError as v:
# This will run when it cannot be converted or if there is any error
print(v) # Shows the error
input() # Waits for user input before closing
For your e.g code, try this -
import sys
try:
x = int(input(" enter a number :"))
y = int(input(" enter a number :"))
except ValueError as v:
print(v)
input('Press any key to exit ')
sys.exit()
if x>100 or y > 100 :
try:
sys.exit("ERROR :value out of range")
except SystemExit as s:
print(s)
input('Press any key to exit ')
sys.exit()
z=x+y
print(z)
You will see that the command prompt does not close immediately
You're not waiting for input.
When you run a .exe that's set up to run in the Windows console, unless you've already opened the console and if your program through that using console commands, and it was set up to just run all the way through to the end, you'll just see the window pop up and then close itself unless your program is doing something that requires user input or a lot of computational time.
This is fairly common sight when programming with languages like C# that natively run as .exes; presumably, this behaviour would also be fairly common in Python. The way to fix this is to add in a line at the end of your program to ask the user for input, so that the console will wait for the user before closing.
In your case, you mention that you have added to the end of your program; the problem is that the program isn't getting to that stage because it's hitting an exception and then exiting. You'll need to handle your exceptions and add a prompt for user input to prevent this behaviour.
Use while loop so if you gave wrong input then it will return to input again so you can give any input. and for example if you want to use only integer value then input must be convert as integer or string depend on you. example below now I think you can
ask = "" #ask variable empty here because I want to use in while condition
print("YOU LOVE ME")
while ask != 'Ok Son':
ask = input("Why? : ")
print("OK THANKS DAD")

unexpected function return different type / number only checker

I'm trying to make a quick and simple function to check if an entered value is an int/bool. I've had a quick look around and even the solution elsewhere comes to the same issue.
I have this in my test script and it seems to work, but when copying the exact code to my main program it will return the first value entered (say I entered hello instead of a number it will exit with "hello" after typing a number and save that to file).
Is there something with a function calling another function that causes it to fail?
I can post my actual code later, there's a lot of calls in it so it may be quite long. Will try with these short examples first and if we can't figure I can post the long one.
#option 1
import json
with open("settings.json", "r") as f:
pref_file = json.load(f)
def float_check(t):
if t.isdigit():
global prompt
prompt = float(t)
return #I have tried 'return prompt' too
else:
prompt = input ("Enter numerical value only:\n")
float_check(prompt)
prompt = input ("Enter a number: ")
float_check(prompt)
#I'm saving the value to JSON file.
#\\ settings.json
#{
# "o2_percent": 0.0
#}
pref_file["o2_percent"] = prompt
with open("settings.json", "w") as f:
json.dump(pref_file, f, indent=4)
In option 2 I tried calling a function from a function as I thought that was the issue. But this also seems to work.
#option 2
import json
def num_check(t):
if t.isdigit():
global prompt
prompt = float(t)
pref_file["o2_percent"] = prompt
with open("settings.json", "w") as f:
json.dump(pref_file, f, indent=4)
runit()
else:
prompt = input ("Enter numerical numer only:\n")
num_check(prompt)
def runit():
prompt = input ("enter a number: ")
num_check(prompt)
runit()
I found this solution (How to validate a users input to Numbers only?) and have adapted it a little but I'm having the exact same issue - my main code will return the first value entered not the number when exiting the loop.
enter number: hello
enter number: elephant
enter number: why
enter number: 5
saves value to settings.json "hello"
Also why does the first print return float as expected but the second is an str, I've done no further processing? I'm new to all this - is there some jenky thing if using variables in a function even if declared global?
def mk_float(answer):
while True:
try:
answer = float(answer)
print (type(answer)) #returns float
break
except ValueError:
answer = input ("Enter number!")
answer = input ("number: ")
mk_float(answer)
print (type(answer)) #returns int
I'm about ready to table flip.
Edit
This was my comment that I deleted, as Prune pointed out its a seperate question. But will throw it on the edit so people know what it was in reference to.
def t_check(prompt):
while True:
try:
prompt = int(prompt)
return int(prompt)
break
except ValueError:
prompt = input ("Enter a number only: ")
continue
prompt = input ("enter something: ")
t_check(prompt)
print (prompt)
print (type(prompt))
The surface problem is because, when you repeat the request for valid input, instead of using a simple loop-until-valid approach, you use recursion. As you wind back up the stack on final return, you can easily get a reversal of the data you want.
The next problem is using global variables. Use parameters for input to your function; return the result. Global variables usually indicate poor design.
Note that print returns None, not a float.
Finally, you should trace your program's execution, as well as intermediate results, using simple print commands. This is the simplest and most immediately effective debugging tool.
Does that help you get going?
I am not sure I can help with the json part of your code, however you may use this function to ask the user to input a number (float or int) :
def input_number():
try:
return float(input ("Enter numerical value only:\n"))
except ValueError:
return input_number()
When the user input something, input_number will try to return the input as a float (which cover the int type).
If the conversion to float fails, a ValueError will be catch and input_number will ask the user to enter the value again.
In your very specific case you may do pref_file["o2_percent"] = input_number()
Edit:
Looking at Prune's answer, recursion might not be the best good solution. ^_^

converting logic tests into try statements (python3)

I have been trying to convert some code into a try statement but I can't seem to get anything working.
Here is my code in pseudo code:
start
run function
check for user input ('Would you like to test another variable? (y/n) ')
if: yes ('y') restart from top
elif: no ('n') exit program (loop is at end of program)
else: return an error saying that the input is invalid.
And here is my code (which works) in python 3.4
run = True
while run == True:
spuriousCorrelate(directory)
cont = True
while cont == True:
choice = input('Would you like to test another variable? (y/n) ')
if choice == 'y':
cont = False
elif choice == 'n':
run = False
cont = False
else:
print('This is not a valid answer please try again.')
run = True
cont = True
Now what is the proper way for me to convert this into a try statement or to neaten my code somewhat?
This isn't a copy of the mentioned referenced post as I am trying to manage two nested statements rather than only get the correct answer.
If you want to make your code neater, you should consider having
while run:
instead of
while run == True:
and also remove the last two lines, because setting run and cont to True again isn't necessary (their value didn't change).
Furthermore, I think that a try - except block would be useful in the case of an integer input, for example:
num = input("Please enter an integer: ")
try:
num = int(num)
except ValueError:
print("Error,", num, "is not a number.")
In your case though I think it's better to stick with if - elif - else blocks.
Ok so as a general case I will try to avoid try...except blocks
Don't do this. Use the right tool for the job.
Use raise to signal that your code can't (or shouldn't) deal with the scenario.
Use try-except to process that signal.
Now what is the proper way for me to convert this into a try statement?
Don't convert.
You don't have anything that raises in your code, so there is no point of try-except.
What is the proper way to neaten my code somewhat?
Get rid of your flag variables (run, cont). You have break, use it!
This is prefered way of imlementing do-while, as Python docs says; unfortunately, I cannot find it to link it right now.
If someone finds it, feel free to edit my answer to include it.
def main()
while True: # while user wants to test variables
spuriousCorrelate(directory) # or whatever your program is doing
while True: # while not received valid answer
choice = input('Would you like to test another variable? (y/n) ')
if choice == 'y':
break # let's test next variable
elif choice == 'n':
return # no more testing, exit whole program
else:
print('This is not a valid answer please try again.')

Exit while loop by user hitting ENTER key

I am a python newbie and have been asked to carry out some exercises using while and for loops. I have been asked to make a program loop until exit is requested by the user hitting <Return> only. So far I have:
User = raw_input('Enter <Carriage return> only to exit: ')
running = 1
while running == 1:
Run my program
if User == # Not sure what to put here
Break
else
running == 1
I have tried: (as instructed in the exercise)
if User == <Carriage return>
and also
if User == <Return>
but this only results in invalid syntax.
Please could you advise me on how to do this in the simplest way possible.
Thanks
I ran into this page while (no pun) looking for something else. Here is what I use:
while True:
i = input("Enter text (or Enter to quit): ")
if not i:
break
print("Your input:", i)
print("While loop has exited")
The exact thing you want ;)
https://stackoverflow.com/a/22391379/3394391
import sys, select, os
i = 0
while True:
os.system('cls' if os.name == 'nt' else 'clear')
print "I'm doing stuff. Press Enter to stop me!"
print i
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
line = raw_input()
break
i += 1
Actually, I suppose you are looking for a code that runs a loop until a key is pressed from the keyboard. Of course, the program shouldn't wait for the user all the time to enter it.
If you use raw_input() in python 2.7 or input() in python 3.0, The program waits for the user to press a key.
If you don't want the program to wait for the user to press a key but still want to run the code, then you got to do a little more complex thing where you need to use kbhit() function in msvcrt module.
Actually, there is a recipe in ActiveState where they addressed this issue. Please follow this link
I think the following links would also help you to understand in much better way.
python cross platform listening for keypresses
How do I get a single keypress at a time
Useful routines from the MS VC++ runtime
I hope this helps you to get your job done.
Use a print statement to see what raw_input returns when you hit enter. Then change your test to compare to that.
This works for python 3.5 using parallel threading. You could easily adapt this to be sensitive to only a specific keystroke.
import time
import threading
# set global variable flag
flag = 1
def normal():
global flag
while flag==1:
print('normal stuff')
time.sleep(2)
if flag==False:
print('The while loop is now closing')
def get_input():
global flag
keystrk=input('Press a key \n')
# thread doesn't continue until key is pressed
print('You pressed: ', keystrk)
flag=False
print('flag is now:', flag)
n=threading.Thread(target=normal)
i=threading.Thread(target=get_input)
n.start()
i.start()
You need to find out what the variable User would look like when you just press Enter. I won't give you the full answer, but a tip: Fire an interpreter and try it out. It's not that hard ;) Notice that print's sep is '\n' by default (was that too much :o)
if repr(User) == repr(''):
break
a very simple solution would be, and I see you have said that you
would like to see the simplest solution possible.
A prompt for the user to continue after halting a loop Etc.
raw_input("Press<enter> to continue")
user_input=input("ENTER SOME POSITIVE INTEGER : ")
if((not user_input) or (int(user_input)<=0)):
print("ENTER SOME POSITIVE INTEGER GREATER THAN ZERO") #print some info
import sys #import
sys.exit(0) #exit program
'''
#(not user_input) checks if user has pressed enter key without entering
# number.
#(int(user_input)<=0) checks if user has entered any number less than or
#equal to zero.
'''
Here is the best and simplest answer. Use try and except calls.
x = randint(1,9)
guess = -1
print "Guess the number below 10:"
while guess != x:
try:
guess = int(raw_input("Guess: "))
if guess < x:
print "Guess higher."
elif guess > x:
print "Guess lower."
else:
print "Correct."
except:
print "You did not put any number."
You are nearly there. the easiest way to get this done would be to search for an empty variable, which is what you get when pressing enter at an input request. My code below is 3.5
running = 1
while running == 1:
user = input(str('Enter <Carriage return> only to exit: '))
if user == '':
running = 0
else:
print('You had one job...')
I recommend to use u\000D. It is the CR in unicode.
Here's a solution (resembling the original) that works:
User = raw_input('Enter <Carriage return> only to exit: ')
while True:
#Run my program
print 'In the loop, User=%r' % (User, )
# Check if the user asked to terminate the loop.
if User == '':
break
# Give the user another chance to exit.
User = raw_input('Enter <Carriage return> only to exit: ')
Note that the code in the original question has several issues:
The if/else is outside the while loop, so the loop will run forever.
The else is missing a colon.
In the else clause, there's a double-equal instead of equal. This doesn't perform an assignment, it is a useless comparison expression.
It doesn't need the running variable, since the if clause performs a break.
If you want your user to press enter, then the raw_input() will return "", so compare the User with "":
User = raw_input('Press enter to exit...')
running = 1
while running == 1:
Run your program
if User == "":
break
else
running == 1
The following works from me:
i = '0'
while len(i) != 0:
i = list(map(int, input(),split()))

Categories

Resources