Except block not recovering from error - python

In the following code for my RPG, I deal with user input and therefore create my code in a way that it can handle errors. When the user enters in a game command such as acquire (which takes two arguments) shown below, the acquire function is called, which tries to use the second part of the split input. If the user only enters 'acquire' and there is no second part to the split string, I expect that the IndexError raises and some text is printed. Again, when my code then tries to access RawInput[1] through the Items dictionary and fails to find it, I expect the KeyError to be raised and the text printed. None of this is happening for me.
When each of these errors should be raising, the error that I'm expecting to occur occurs, but the try/ except block does recover from it.
Items = {
'Rapier': Item('Rapier', 1, [None, None], 2)}
def Acquire(self):
try:
if Pos[0] == self.Pos[0] and Pos[1] == self.Pos[1]:
for i in range(1, 4):
j = i - 1
if self.Type == i and not Inventory[j]:
Inventory[j] = self
self.Pos = None
print(Name, 'picked up the', self.Name)
elif None not in Inventory:
print(Name, 'cannot carry any more!')
else:
print('There is no', RawInput[1].title(), 'here')
except KeyError:
print('That doesn\'t exist!')
except IndexError:
print('Acquire takes two arguments')
def ParseInput():
global RawInput
RawInput = input('> ').lower().split(' ', 1)
if RawInput[0] == 'acquire':
Acquire(Items[RawInput[1].title().strip()])
Could anyone explain to me how to fix my code or explain what is happening?

The errors you're trying to catch won't occur inside of the code itself, but rather when the code is interpreted. putting the try-except around the function call should fix it.
if RawInput[0] == 'acquire':
try:
Acquire(Items[RawInput[1].title().strip()])
except KeyError:
print('That doesn\'t exist!')
except IndexError:
print('Acquire takes two arguments')

Related

Problems with exceptions

I'm trying to do an exercise on Python. For this, I have to use the following function:
def getNumber() :
x = input ('Choose a number: ')
if x == 17:
raise ("ErrorBadNumber","17 is a bad number")
return x
The exercise says create another function that uses getNumber and handle the exception ErrorBadNumber.
I've created the function getNumber_2 to try solve the exercise:
def getNumber() :
x = input ('Choose a number: ')
if x == 17:
raise ("ErrorBadNumber","17 is a bad number")
return x
while True:
def getNumber_2 ():
try:
getNumber ()
except ErrorBadNumber:
print('Write another number, please')
getNumber ()
Then, it appears an error: "Undefined name 'ErrorBadNumber' ". Anyway, when I only execute the function getNumber the exception doesn't happen. I don't know why. Thanks in advance.
Exceptions have to be classes that derive from the base Exception class. And i your while loop, you are defining a function, but you never call the function, so nothing ever runs. It's an infinite loop, doing nothing.
For example:
class ErrorBadNumber(Exception):
pass
def getNumber() :
x = input ('Choose a number: ')
if x != '17':
raise ErrorBadNumber("17 is a bad number")
return x
while True:
try:
getNumber ()
break
except ErrorBadNumber:
print('Write another number, please')

How to try-except block exit when try is working

The code I have works. The last for loop gets reached and choice.click() gets clicked on. The question I have is why the except block gets executed even though the:
if choice.text == call_resource:
choice.click()
break
piece of the code is reached and the choice.click() portion works?
def select_choice(driver, resource_tag):
try:
call_resource = None
access_data = common.retrieve_tag_access_data()
for row in access_data["access_data"]:
if str(row["id"]) == resource_tag:
call_resource = row["row_tag"]["name"]
break
if call_resource is None:
access_data = common.retrieve_fixture_access_data()
for row in access_data["access_data"]:
if str(row["id"]) == resource_tag:
call_resource = row["row_tag"]["name"]
break
menu = driver.find_element_by_css_selector("ul[role='listgrid']")
choices = menu.find_elements_by_css_selector("li[role='choices']")
for choice in choices:
if choice.text == call_resource:
choice.click()
break
except:
error(logger, "unable to select choice")
pass
Because the last for loop works, shouldn't it break entirely out of the function after choice.click() without executing the except: portion of the code?
The except: portion will run only if an Exception occurred inside the try block. You should change the except: line to something like except Exception as e: and print the variable e in some way so you can discover what the problem is.
choices = menu.find_elements_by_css_selector("li[role='choices']")
for choice in choices:
if choice.text == call_resource:
choice.click()
break
Could be replaced with since your only trying to click one element with a certain text why not just try to find it. If it errors out it will go to the exception you provided.
driver.find_element(By.XPATH,f"//li[#role='choices' and contains(text(),{call_resource})]").click()
Also use to find errors use the following.
except Exception as e:
print(str(e))

unittest while loop with input python

I wrote the following code:
def load_tests(self):
while True:
try:
return [tests[int(x)] for x in input("\nEnter integer values of tests to execute (seperate by 'space'): ").split()]
except ValueError:
logger.error("Non-integer value found.")
except IndexError:
logger.error("Entered non-existing list value")
And I tried to write a unit test for this code using the following code:
def test_load_static_tests_string(self):
with mock.patch('builtins.input', return_value="string"):
with mock.patch("sys.stdout", new=StringIO()) as fakeOutput:
load_tests()
self.assertEqual(fakeOutput.getvalue().strip(), 'Non-integer value found.')
But the console keeps printing "Non-integer value found.". How can I fix this code and break out of the loop after testing it once?

I am getting an error when running this code saying str1 is not defined,when i have already defined it in try block

I am trying to write a small code block where in i take an input (user can enter any input in words or letters), my code should try to find if it is a positive or negative number or the entered value is a string.
try:
str1=int(input('Enter a number:'))
print('try block is completed')
except:
str1=str(str1)
if str1>0:
print('entered value is positive')
elif str1<0:
print('entered value is negative')
else:
print(str1)
The reason is the exception is caused in int(input(...)) so the str1 remains undeclared.
str1=input('Enter a number:')
try:
str1=int(str1)
print('try block is completed')
except:
str1=str(str1)
if str1>0:
print('entered value is positive')
elif str1<0:
print('entered value is negative')
else:
print(str1)
Modify your code like this to handle exception on integer and string
On your except branch you have the following call:
str1=str(str1)
Since you are on your except, and you haven't defined your str1 variable outside the try/except block, your statement will fail when it tries to cast the contentes of the str1 variable (which does not exist outside of the try branch).
A possible implementation to deal with this case would be to set str1 to None or an empty string on your except block. Something like this:
try:
str1 = int(input('Enter a number:'))
print('try block is completed')
except:
str1 = None
# First we check that our variable is not None (caught an exception)
try:
int_str1 = int(str1)
except:
int_str1 = None
if int_str1:
if int_str1 > 0:
print('entered value is positive')
elif int_str1 < 0:
print('entered value is negative')
else:
print('Could not get integer value of input')
It's because you use str1 in your except clause. If there is an exception during the processing of input or int, the variable str1 is never set.
If you add str1=None before your try statement, I am sure, it won't complain anymore, but you need to change your except clause then.
If you're just concerned about the cast to int, you could do:
str1= None
try:
str1=input('Enter a number:')
val=int(str1)
print('try block is completed')
except:
val=None
if val is None:
print('input is not a valid number')
elif val>0:
print('entered value is positive')
elif val<0:
print('entered value is negative')
else:
print(str1)
in the case fn an exception in the call int, the variable str1 never gets created, because int is evaluated (and raises the error) before str1 gets assigned.
also - in the case of an exception you'll get a TypeError for trying to compare a string with 0, so put all you int-assuming logic inside the try, like this:
str1=input('Enter a number:')
try:
str1=int(str1)
if str1>0:
print('entered value is positive')
elif str1<0:
print('entered value is negative')
except:
str1=str(str1)
print(str1)

Why can't I call a function here?

Hi guys I was working on a shoppinglist-creator code but at the end I faced with a surprise.
My code:
import time
import math
import random
dict_of_lists={}
def addlist():
while True:
try:
listname=str(raw_input("=>Name of the list:\n"))
dict_of_lists[listname]={}
break
except ValueError:
print "=>Please enter a valid name.\n"
print "=>You added a new list named %s.\n" % (listname)
def printlists():
for lists in dict_of_lists:
return "-"+lists
def addproduct():
while True:
try:
reachlistname=input("=>Name of the list you want to add a product,Available lists are these:\n %s \nPlease enter one:\n" % (printlists()))
break
except ValueError:
print "=>Please enter a valid list name.\n"
while True:
try:
productname=raw_input("=>Name of the product:\n")
break
except ValueError:
print "=>Please enter a valid name.\n"
while True:
try:
productprice=input("=>Price of the product:\n")
if isinstance(float(productprice),float):
break
except ValueError:
print "=>Please enter a valid number.\n"
while True:
try:
productcount=input("=>Amount of the product:\n")
if isinstance(int(productcount),int):
break
except ValueError:
print "=>Please enter a valid number.\n"
dict_of_lists[reachlistname][productname]={"price":productprice,"count":productcount}
dict_of_lists[reachlistname]={productname:{"price":productprice,"count":productcount}}
allevents="1-Add a list"+" 2-Add a product to a list"
def eventtochoose():
while True:
try:
event=raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
if not isinstance(int(event),int):
print "\n=>Please enter a number.\n"
else:
if event==1:
addlist()
break
elif event==2:
addproduct()
break
except ValueError:
print "\n=>Please enter a valid input.\n "
while True:
print "%s" % ("\n"*100)
eventtochoose()
So, the problem is (I suggest you run the code) it says "=>What would you like to do? Here are the all things you can do:
1-Add a list 2-Add a product to a list
Please enter the number before the thing you want to do:" and when i put an answer it simply doesn't call the fucntion.
If I put 1 It should have called the fucntion addlist but I think it doesn't. There is nothing to explain I think just look at the code and find the problem if you want to help crocodiles. Thx
When you do int(event), that returns an int if possible, and raises a ValueError if not. So, testing the type of the result doesn't do you any good—if your code gets that far, the type has to be an int.
You already have code to handle the ValueError, so you don't need any other test for the same problem.
Meanwhile, you want to start the number that you got from int(event). That's the thing that can be == 1; the original string '1' will never be == 1.
So:
while True:
try:
event=raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
event = int(event)
if event==1:
addlist()
break
elif event==2:
addproduct()
break
except ValueError:
print "\n=>Please enter a valid input.\n "
You are not converting your input to an integer before comparing, so the comparisons are always false:
'1' == 1 # false
Try:
event = raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
try:
event = int(event)
if event == 1:
addlist()
elif event == 2:
addproduct()
break
except ValueError:
print('Please enter a valid input')

Categories