import webbrowser
import time
import sys
import urllib.request
def con():
cont = input("Do you want to continue? ")
if (cont.lower() == "yes" or cont.lower() == "y"):
main()
elif (cont.lower() == "no" or cont.lower() == "n"):
sys.exit()
else:
print("Invalid answer. Please try again")
time.sleep(1)
con()
def main():
try:
website = input("What website do you want to go to? (ex. Example.com) ")
fWebsite = "http://{}".format(website)
time.sleep(1)
if (urllib.request.urlopen(fWebsite).getcode() == 200):
webbrowser.open(fWebsite)
time.sleep(1)
except:
print("Invalid website. Please enter another one")
time.sleep(1)
main()
con()
main()
when the code runs con(), when ever I try to enter no, it always says invalid website. Please enter another one. How do I fix it to exit the program? everything else works it is just this one part.
The sys.exit function works by raising an SystemExit exception. Your code has a bare except block which is catching that exception and suppressing its normal purpose (that is, to exit quietly).
The best fix for this issue is to make your except clause more specific to the kinds of exceptions you expect to catch. It is almost always a bad idea to catch everything (the only exception to that is when you're catching all exceptions, but logging and re-raising most of them).
Since your specific code is trying to deal with exceptions from urllib, catching urllib.error.URLError is probably your best bet.
Related
is there a way on IDLE to close the users shell if they were to enter something that would be supposed to "quit"?
You can use exit(0) to terminate the program, as follows:
while True:
i = input()
if i == "quit":
exit(0)
else:
# do something
pass
For more information about what 0 for exit() means:
Difference between exit(0) and exit(1) in Python
Currently I have a program which follows:
try:
while True:
print("Running")
except KeyboardInterrupt:
pass
The idea bring that the terminal will print "Running" until the user inputs CRTL+C, what I want to be able to do is have the program continue to run until a user enters a key word in additional to this. This is to make my program more robust so no accidental inputs could stop the loop.
Is there a way to do this?
Here a possible way to achieve that:
while True:
try:
print("Running")
except KeyboardInterrupt:
if input("Type exit to exit: ") != "exit":
continue
break
Or if you want to a more flexible escaping string you can declare it as follow:
escape_string = "exit"
while True:
try:
print("Running")
except KeyboardInterrupt:
if input(f"Type {escape_string} to exit: ") != escape_string:
continue
break
You need the try/except block to be inside the loop, so that the interrupt does not exit the loop. The exception handler activates the loop exit condition.
ans = ""
while ans != "please":
try:
print("Running")
sleep(1)
except KeyboardInterrupt:
ans = input("Please enter secret ")
Here are the parts of my code that could have something to do with the problem: (I cut away as much as possible)
import os
import getpass
def PAUSE():
input("= Press <ENTER> to continue...")
def clearscreen():
os.system('cls' if os.name=='nt' else 'clear')
def loginscreen():
clearscreen()
print("==================================================================")
print("= LOGIN =")
print("==================================================================")
print("= None Important. =")
print("==================================================================")
username = input("= Please enter your username: ")
password = getpass.getpass("= Please enter the password that belongs to that username: ")
print("==================================================================")
try:
# I had too cut away the MariaDB Section for a MCVE, and thus i had to fill the dbusername and sdbpassword and isadmin, but without modifying relevant code. Thus i might have made a mistake in this array, dont use them alot sooo... if this were to occur i am sorry....
['dbusername = "stackoverflow", dbpassword = "stackoverflow", isadmin = "No"']
for row in results:
dbusername = row[0]
dbpassword = row[1]
isadmin = row [2]
if username == dbusername:
if password == dbpassword:
if isadmin == "Yes":
admin_main_menu()
elif isadmin == "No":
clearscreen()
main_menu()
########## For some reason the same problem arises when i use the commented away code under this comment.
# clearscreen()
# print("==============================================")
# print("= Unkown Username / Password =")
# print("==============================================")
# PAUSE()
# print("==============================================")
# loginscreen()
except:
clearscreen()
print("Failed to check codes. (Error: 5646FCJU), Contact N.S. Geldorp")
PAUSE()
def main_menu():
clearscreen()
print("=============================================")
print("= Main Menu =")
print("=============================================")
print("= 1. All unimportant... =")
print("= 5. Exit =")
print("=============================================")
answer = input("= Please enter the number of the function you wish to use: ")
print("=============================================")
clearscreen()
if answer == "1":
# print_animals()
print("Not needed")
PAUSE()
elif answer == "5":
# pass
print("Exiting...")
exit()
else:
print("Unimportant...")
PAUSE()
main_menu()
Now, I cut away everything but perhaps relevant parts of the login screen and the standard main menu. And of course the functions as PAUSE and clearscreen as they always reappear in relevant functions. At least if I wrote them. Now what happens is that when I have a successful login and I go to the menu, And I decide to exit, It shows me the error written in the except of the login screen... I don't get it, do you?
This is demonstration 1,442,633 of why you must never, ever use a blank except clause.
sys.exit() works by raising an exception: SystemExit. Normally, that exception bubbles all the way up to the interpreter, which catches it and exits gracefully. But because your try/except code catches everything, it catches that too; so you see your own error message instead of the interpreter quitting.
You should only ever catch the things that you know you can deal with. I'm not sure what exceptions you are expecting with that code, but presumably they are ones that are raised by the database code. You should work out which ones could be raised, and catch those only: for example, except TypeError:.
At the very least, you should restrict your except to only catch actual errors, which you can do with except Exception:; SystemExit descends from BaseException, which is the parent class of Exception which all other runtime errors descend from. But, you really shouldn't do that, you should catch the specific exceptions only.
(Note also, it makes no sense to have that for loop over the database results; I don't understand why you have done that.)
I am currently working on a automated troubleshooter using Python. Below is a piece of my script which I need help with.
s1 = input("Is your phone freezing/stuttering? ")
if s1 == "Yes" or s1 == "yes":
print("Try deleting some apps and this might help with your problem.")
if s1 == "No" or s1 == "no":
def foo():
while True:
return False
So what I want to happen is my script to stop when the user types in YES and when the solution to the fix comes up. Is there a possible loop for that or something similar? Also if the user types in NO then I want the script to continue to the next question.
So one thing that you can do is utilize the sys.
So you can modify your program to look like the following:
import sys
s1 = input("Is your phone freezing or stuttering (yes/no)? ")
if s1.lower() == "yes":
print("Deleting some apps and this might help!")
elif s1.lower() == "no":
print("Your phone is working fine! Program is terminating.")
sys.exit(0) # this exits your program with exit code 0
The sys package is great for program control and also interacting with the interpreter. Please read more about it here.
If you don't want your program to exit and you just want to check that the user entered no, you could do something like:
import sys
s1 = input("Is your phone freezing or stuttering (yes/no)? ")
if s1.lower() == "yes":
print("Deleting some apps and this might help!")
elif s1.lower() == "no":
pass
else:
# if the user printed anything else besides yes or no
print("Your phone is working fine! Program is terminating.")
sys.exit(0) # this exits your program with exit code 0
Let me know if I can help in any other way!
EDIT
A comment by crickt_007 suggested that it might be helpful to repeat the input and continually query the user. You could wrap this whole function in a while loop then.
import sys
while True:
s1 = input("Is your phone freezing or stuttering (yes/no)? ")
if s1.lower() == "yes":
print("Deleting some apps and this might help!")
# solve their issue
elif s1.lower() == "no":
# supposedly move on to the rest of the problem
pass
else:
# if the user printed anything else besides yes or no
# maybe we want to just boot out of the program
print("An answer that is not yes or no has been specified. Program is terminating.")
sys.exit(0) # this exits your program with exit code 0
A while loop sounds like what you are looking for?
import sys
s1 = "no"
while s1.lower() != 'yes':
input("Is your phone freezing/stuttering? ")
if s1.lower() == 'yes':
print("Try deleting some apps and this might help with your problem.")
sys.exit(0)
elif s1.lower() == 'no':
print("something")
else:
print("invalid input")
I have an infinite while loop that I want to break out of when the user presses a key. Usually I use raw_input to get the user's response; however, I need raw_input to not wait for the response. I want something like this:
print 'Press enter to continue.'
while True:
# Do stuff
#
# User pressed enter, break out of loop
This should be a simple, but I can't seem to figure it out. I'm leaning towards a solution using threading, but I would rather not have to do that. How can I accomplish this?
You can use non-blocking read from stdin:
import sys
import os
import fcntl
import time
fl = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK)
while True:
print("Waiting for user input")
try:
stdin = sys.stdin.read()
if "\n" in stdin or "\r" in stdin:
break
except IOError:
pass
time.sleep(1)
I think you can do better with msvcrt:
import msvcrt, time
i = 0
while True:
i = i + 1
if msvcrt.kbhit():
if msvcrt.getwche() == '\r':
break
time.sleep(0.1)
print(i)
Sadly, still windows-specific.
On python 3.5 you can use the following code. It can be adjusted for a specific keystroke. The while loop will keep running until the user presses a key.
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()
I could not get some of the popular answers working. So I came up with another approach using the CTRL + C to plug in user input and imbibe a keyboard interrupt. A simple solution can be using a try-catch block,
i = 0
try:
while True:
i+=1
print(i)
sleep(1)
except:
pass
# do what you want to do after it...
I got this idea from running a number of servers like flask and django. This might be slightly different from what the OP asked, but it might help someone else who wanted a similar thing.
Using the msvcrt module as thebjorn recommended I was able to come up with something that works. The following is a basic example that will exit the loop if any key is pressed, not just enter.
import msvcrt, time
i = 0
while True:
i = i + 1
if msvcrt.kbhit():
break
time.sleep(0.1)
print i
What you need is a non-blocking raw input, if you don't want to use threads there is a simple solution like this one below where he is doing a timeout of 20 ms and then raise and exception if the user doesn't press a key, if he does then the class returns the key pressed.
import signal
class AlarmException(Exception):
pass
def alarmHandler(signum, frame):
raise AlarmException
def nonBlockingRawInput(prompt='', timeout=20):
signal.signal(signal.SIGALRM, alarmHandler)
signal.alarm(timeout)
try:
text = raw_input(prompt)
signal.alarm(0)
return text
except AlarmException:
print '\nPrompt timeout. Continuing...'
signal.signal(signal.SIGALRM, signal.SIG_IGN)
return ''
Source code
I have defined the function which ask number input from the user and returns the factorial of that number. If user wants to stop they have to press 0 and then it will exit from the loop. We can specify any specific key to input 'n' to exit from the loop.
import math
def factorial_func(n):
return math.factorial(n)
while True:
n = int(input("Please enter the number to find factorial: "))
print(factorial_func(n))
if n == 0:
exit()