im trying to do a menu. I have a validation to don´t accept string input. If the value ins numeric the function goes well but when the input is a string, something go wrong
def menudos(diccionario, titulo):
os.system('clear')
list_menu = []
if diccionario:
print(titulo)
for key in diccionario:
list_menu.append(key)
list_menu.append("Volver")
for x in range(0, len(list_menu)):
print(x, ": ", list_menu[x])
try:
opcion = int(input("Seleccionar> "))
except:
menudos(diccionario, titulo)
return list_menu[opcion]
The error is that:
Traceback (most recent call last):
File "menudos.py", line 23, in <module>
print(menudos(a, "Prueba"))
File "menudos.py", line 21, in menudos
return list_menu[opcion]
UnboundLocalError: local variable 'opcion' referenced before assignment
Thanks
The problem is that when you provide not an int, the program raises the exception trying to convert non-int to int and nothing is assigned to your var opcion. If you want to protect your program from crashing. Execute try..except statement in an infinite loop waiting for the correct format of the index.
The specific traceback is caused because opcion is not defined in the except block, but you are trying to return list_menu[opcion] after going through the except block.
Instead, I would suggest that you use a while loop that will run forever until you get acceptable input from the user.
My approach to user menus has always been to separate the printing of the menu options and capturing the user input.
Something like:
def print_menu():
print("Please make a selection:")
print("1. Do item #1")
print("2. Do item #2")
# ...etc....
def get_user_input():
selection = None
while selection is None:
try:
selection = int(input("Selection: "))
return selection
except:
print("You selected an invalid choice. Please choose again.")
print_menu()
Hope this helps!
Edit: Also see this question on recursion in Python. There is a limit of 1000 recursive calls by default in Python - so, assuming your existing code worked, a user could enter 1000 incorrect entries and break your program.
Related
I need help with this code;
input()
print("Created by Mr.StiK")
input()
print('In a dark and creepy cave... You got your consciousness back...')
input()
print("Then you remember... you've no time to waste...")
input()
unit = input("Type the command 'wake' to start your adventure... ").lower()
while unit.lower() == "wake":
if unit.lower() == "wake":
print("And you starts your adventure...")
break
if not unit.lower() == "wake":
print("Sorry, unidentified command. Please type 'wake'")
The error;
When you type the command wrong, it does not say anything, just skips the code.
And when we input nothing, we get nothing.
And then when we say anything, the program crashes, with this;
Traceback (most recent call last):
File "<pyshell>", line 1, in <module>
NameError: name 'wake' is not defined
Please I need help with this.
PS: IF YOU CAN ALSO NEED TO RE-WRITE THE CODE WITH A BETTER CODE/ENGINE, PLEASE, IT WILL BE ACCEPTED TOO.
Change your WHILE_LOOP and INPUT to this
while True:
unit = input("Type the command 'wake' to start your adventure... ").lower()
if unit == "wake":
print("And you starts your adventure...")
break
else:
print("Sorry, unidentified command. Please type 'wake'")
Hello guys I'm really a newbie to python and I just writing a piece of code that opens Whatsapp
and you give it the person's name and the message then sends how many times you want.
But when I start debugging the code it gives me this:
Exception has occurred: TypeError 'WebElement' object is not subscriptable File "E:\Iliya\My Courses\Python\Projects\Whatsapp Robot\Whatsapp_Bot.py", line 15, in <module> msg = driver.find_element_by_class_name('_3FRCZ')[1]
# ======================================
from selenium import webdriver
PATH = 'C:\\Program Files (x86)\\chromedriver.exe'
driver = webdriver.Chrome(PATH)
driver.get('https://web.whatsapp.com/')
input("Please Press The 'Enter' Button... ")
name = input("Enter Person's Name: ")
msg = input("Enter The Message: ")
counter = int(input("How Many Times Do You Want To Repeat The Message?: "))
user = driver.find_element_by_xpath('//span[#title = "{}"]'.format(name))
user.click()
msg = driver.find_element_by_class_name('_3FRCZ')[1]
for i in range(counter):
msg.send_keys(msg)
button = driver.find_element_by_class_name('_1U1xa')[0]
button.click()
guys please someone good at python answer me !!!🙏🙏
find_element_by_class_name()
find_element_by_class_name() finds an element by class name.
In the line of code:
msg = driver.find_element_by_class_name('_3FRCZ')[1]
driver.find_element_by_class_name('_3FRCZ') would return a single WebElement. Hence you won't be able to attach an index to it or in other words make it subscriptable.
Solution
There are two solutions:
Remove the index i.e. [1] your code will be all good.
As an alternative, instead of driver.find_element_by_class_name() you need to use find_elements_by_class_name(). So effectively your line of code will be:
msg = driver.find_elements_by_class_name('_3FRCZ')[1]
#main program
while True:
ReadValue = Func03Modbus(1,70,40);#slave,start,number of registers
x3 = struct.pack('>HH',abs(ReadValue[3]),abs(ReadValue[2]))
pressure = struct.unpack('>f', x3)
print pressure[0]
c3 = struct.pack('>HH',abs(ReadValue[5]),abs(ReadValue[4]))
purity = struct.unpack('>f', c3)
print purity[0]
hrs = int(ReadValue[30])
mins= int(ReadValue[31])
timein =float(str(ReadValue[30])+"."+str(ReadValue[31]))
print timein
r=requests.get("http://api.thingspeak.com/update api_key=5RMT************&field4="+str(pressure[0])+"&field5="+str(purity[0])+"&field1="+str(ReadValue[i])+"&field2="+str(mins)+"&field3="+str(timein)))
print str(ReadValue[30])
time.sleep(15)
While running the above program it stops running with returning following error:
Traceback (most recent call last): File "/home/pi/v1.py", line 123,
in
x3 = struct.pack('>HH',abs(ReadValue[3]),abs(ReadValue[2])); IndexError: tuple index out of range
I want my program to run continuously even when it returns error. I want to skip the error and to run the program continuously. How can I do that ?
In theory you could wrap the code in an exception handler like:
while True:
try:
what you want to do
except Exception as e:
print("Something bad happened:", e)
finally:
# reset device here
time.sleep(15)
But this seems like a really bad idea if you're interacting with hardware, since you can't be sure what state you're leaving it in. Ideally, you'd want to make sure you're doing a proper reset of the device (or reconnect? depends what you're talking to) on every cycle.
Alternatively, if you want to explicitly verify that the values you get back are available, you can do:
ReadValue = Func03Modbus(1,70,40);#slave,start,number of registers
if len(ReadValue) < 32:
print("Got incomplete result")
time.sleep(15)
continue
The language reference/tutorial has more information about handling errors here: https://docs.python.org/3/tutorial/errors.html
In order to continue in the event of this kind of error, simply place the part you wish to ignore exceptions in within an appropriate try: ... except ...
while True:
try:
<body of work>
except IndexError:
<you might want to log the error>
pass
In this case, we continue only in the event of IndexError.
I have made a script for checking if a variable is the same as an input variable:
def password():
userPassword = str(input("Type Your Password: "))
if userPassword == storedPassword:
print 'Access Granted'
else:
print 'Access Denied'
password()
However whenever I type a letter for the input, it throws a NameError, but it works fine with numbers.
Error:
Traceback (most recent call last):
File "C:\Users\***\Desktop\Test\Script.py", line 16, in <module>
password()
File "C:\Users\***\Desktop\Test\Script.py", line 9, in password
userPassword = str(input("Type Your Password: "))
File "<string>", line 1, in <module>
NameError: name 'f' is not defined
You need to use raw_input instead of input on python 2.
Using input attempts to evaulate whatever you pass it. In the case of an integer it just resolves to that integer. In the case of a string, it'll attempt to find that variable name and that causes your error.
You can confirm this by typing a 'password' such as password which would have your input call return a reference to your password function.
Conversely, raw_input always returns a string containing the characters your user typed. Judging by your attempt to cast whatever the user types back into a string, this is exactly what you want.
userPassword = raw_input("Type Your Password: ")
For Python 2.7 you need to use raw_input() instead of input(), input() actually evaluates the input as Python code. raw_input() returns the verbatim string entered by the user.
See Python 2.7 getting user input and manipulating as string without quotations
I have this try/except code:
document = raw_input ('Your document name is ')
try:
with open(document, 'r') as a:
for element in a:
print element
except:
print document, 'does not exist'
How do I exit the program after I print "[filename] does not exist"? break and pass obviously don't work, and I don't want to have any crashing errors, so sys.exit is not an option.
Please ignore the try part - it's just a dummy.
Use the sys.exit:
import sys
try:
# do something
except Exception, e:
print >> sys.stderr, "does not exist"
print >> sys.stderr, "Exception: %s" % str(e)
sys.exit(1)
A good practice is to print the Exception that occured so you can debug afterwards.
You can also print the stacktrace with the traceback module.
Note that the int you return in sys.exit will be the return code of your program. To see what exit code your program returned (which will give you information about what happens and can be automated), you can do:
echo $?
Using
sys.exit(1)
is not a crashing error, it's a perfectly normal way to exit a program. The exit code of 1 is a convention that means something went wrong (you would return 0 in the case of a successful run).
Just re-raise it. It's more friendly for developer
document = raw_input ('Your document name is ')
try:
with open(document, 'r') as a:
for element in a:
print element
except:
print document, 'does not exist'
raise
Check python document in the Raising Exceptions section about re-raise error in except.
You can also put your code in a function and issue a return. You may call it main which you can call from your script.
def main():
document = raw_input ('Your document name is ')
try:
with open(document, 'r') as a:
for element in a:
print element
except:
print document, 'does not exist'
return
if __name__ == "__main__":
main()
In case that you are using an if statement inside a try, you are going to need more than one sys.exit() to actually exit the program.
For example, you are parsing an argument when calling the execution of some file, e.g. $./do_instructions.py 821 such as:
import sys
# index number 1 is used to pass a set of instructions to parse
# allowed values are integer numbers from 1 to 4, maximum number of instructions is 3
arg_vector = "821" # <- pretending to be an example of sys.argv[1]
if len(arg_vector) > 3:
sys.exit(2) # <- this will take you out, but the following needs an extra step.
# for an invalid input (8).
for i in arg_vector:
# to validate that only numbers are passed as args.
try:
int(i) # <- 8 is valid so far
# value (8) is not valid, since is greater than 4
if (int(i) == 0) or (int(i) > 4):
print("Values must be 1-4")
# the following call does not takes you out from the program,
# but rise the SystemExit exception.
sys.exit(2)
except SystemExit: # <- needed to catch the previous as the first evaluation
# The following parameter "2" is just for this example
sys.exit(2) # <- needed to actually interrupt the execution of the program/script.
# if there is no "except SystemExit:", the following will be executed when the
# previous "if" statement evaluates to True and the sys.exit(2) is called.
#
# and the "print("Only num...") function will be called, even when the intention
# of it is to advice the *user* to use only numbers, since 8 is a number this
# shouldn't be executed.
except:
print("Only numbers are allowed.")
sys.exit(2)
otherwise, you want to use one try-except block for each evaluation.
Probably not the best practice, but it worked for me:
import sys
close = False
try:
if SomethingBadHappend:
close = True
except:
pass
if close:
sys.exit(1)
Close dose does not seem to work inside 'try'.