unittest while loop with input python - 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?

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))

Exception In Python Doesn't Do Anything

I am beginner to python and I have doubt in one program when using try except part
I try to take input from user and add that number by 1 like if you enter 5 then 6 will be printed but if you enter string then except would come in role and print enter only number
I've written code but except is not working there, code is working like if I enter 5 then 6 gets printed but except statement is not working
Here is the code that I've written
def increment(num):
try:
return num + 1
except Exception as e:
print("ufff error occured :", e)
n = int(input("enter your num: "))
a = increment(n)
print(a)
You would have to change to the following:
def increment(num):
try:
return int(num) + 1
except Exception as e:
print("ufff error occured :", e)
n = input("enter your num: ")
a = increment(n)
print(a)
The reason for that is that the exception was raised by the int() functions, because it couldn't convert your input to int. The call to int() was before the increment function. Therefore the exception was unhandled.
You tried converting the input to int before going into the try/except block. If you just put it in the try block it will work.
def increment(num):
try:
num = int(num)
return num + 1
except Exception as e:
print("ufff error occured :", e)
n = input("enter your num: ")
a = increment(n)
print(a)
You have to use the type conversion within the try block so that if num is not a number, the controller would move to expect portion.
The problem here is you are using type conversion outside of try-catch block.
Another point to note, convert e to string as a good practice.
Third point to note,the last line print(a) will itself cause trouble in cases of exception as you have returned nothing from the exception part and directly printed the error. Use a return statement in there else it would return None type and which itself will mess up the flow.
def increment(num):
try:
return int(num) + 1 #Updated Line
except Exception as e:
return "ufff error occurred :" + str(e) #Updated Line
n = input("enter your num: ")
a = increment(n)
print(a)
Might I recommend the following?
def increment(num):
try:
return int(num) + 1
except Exception as e:
print("ufff error occurred:", e)
n = input("enter your num: ")
a = increment(n)
print(a)
The only difference here is that the attempt to convert the user's input to an int occurs within the try-except block, rather than outside. This allows the type conversion error to be caught and your message ("ufff error occurred: ...") to be displayed.
Edit: regarding your comment:
yes it worked out thanks everyone, but can anyone tell what should i have to do if i use int with input line what changes i've to make
Optionally, you could do the following:
def increment(num):
return num + 1
try:
n = int(input("enter your num: "))
a = increment(n)
print(a)
except Exception as e:
print("ufff error occurred:", e)
In this case, I would recommend removing the try-except block in the increment function, because you can safely assume that all values passed to that function will be numeric.
The only code that would raise an exception is the int(...) conversion - and it is not protected under a try/except block. You should put it under the try:
def increment():
try:
return int(input("enter your num: ")) + 1
except ValueError as e:
return f"ufff error occured: {e}"
print(increment())
You should always try to catch the narrowest exception. In this case, a ValueError.

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')

Except block not recovering from error

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')

Categories