If Try statement - python-3.x

In my scripts I wanna cleanup my error Handling. What I read is that I need:
try:
do something
exept:
raise Error("give error")
finaly:
print("something else")
The problem I have is that I don't know how to handle an error in this way in my former written function.
How do I create a try statement with multiple conditions like the simple example below.
def varlist(var, length):
from numpy import array
if len(array(var)) > length:
return(False)
raise ValueError('list is to long only first ' + str(length) + ' paramerets will be used')
elif len(array(var)) < length:
return(False)
raise ValueError('list is to short ' + str(length) + ' is less than required')
else:
return(True)
So in general my question is: How to handle an if/ try statement with multiple outputs all baased on their value....
In this case I have two outputs but I have others with more values( sometimes strings)

I don't quite get your problem but here is a code using the try statement:
def varlist(var, length):
from numpy import array
try:
return True
except len(array(var)) > length :
return False
raise ValueError('#Your Error message 1')
except len(array(var)) < length :
return False
raise ValueError('#Your Error message 2')
If you meant how to return multiple values, just 'pack' them in a tuple like this:
returntuple = ('statement1', 'statement2', etc)
return returntuple
Then you can 'unpack' it like this:
returntuple[1]
will return 'statement2'
Like this you can return multiple values. You need to trick python, because it doesn't provide returning multiple values(, as far as I know!). But if you 'pack' your values in a tuple or a listeverything is fine!
If those two answers doesn't get your problem, I'm sorry I just don't get the question.
Sincerely, heureka

Related

how to throw an error if certain condition evaluates to true

I have below code block:
try:
if str(symbol.args[0]) != str(expr.args[0]):
print('true')
raise SyntaxError('====error')
except:
pass
Here I am trying to raise Syntax error if certain condition is true.I am testing this code block, I can see 'true' is getting printed which means condition is met but even after that also the code is not throwing syntax error.
I am trying to understand what is wrong in the above code.
You're putting pass in the except: block which is swallowing the exception. Either remove the code from the try-except block or change pass to raise
Above answer is pointing the issue, I just want to give some examples to help you better understand how try/except works:
# Just raise an exception (no try/except is needed)
if 1 != 2:
raise ValueError("Values do not match")
# Catch an exception and handle it
a = "1"
b = 2
try:
a += b
except TypeError:
print("Cannot add an int to a str")
# Catch an exception, do something about it and re-raise it
a = "1"
b = 2
try:
a += b
except TypeError:
print("Got to add an int to a str. I'm re-raising the exception")
raise
try/except can also be followed by else and finally, you can check more about these here: try-except-else-finally

Pytest checking messages returned by errors

Something about the interaction between pytest, str() and python Error types breaks full error testing where we want to confirm the EXACT TEXT returned by the error.
Example below:
def erroring_func(name, required_item_list):
# skip boring bit. Just throw an error.
raise KeyError(f'{name} is missing required item(s): {required_item_list')
def test_erroring_func():
with pytest.raises(KeyError) as err:
name = 'This dataframe'
required_item_list = ['a column']
_ = erroring_func(name, required_item_list)
assert str(err.value) == f"{name} is missing required item(s): {required_item_list}"
This looks sensible, but will return the error:
assert '"This dataframe is missing required item(s): [\'lat\']"' == "This dataframe is missing required item(s): ['lat']
Somehow, str(err.value) creates single backslashes in the output that are EXTREMELY difficult to recreate in an f-string (actually impossible) or to insert in a string once created.
You can completely solve by matching how KeyError alters text. This can be done with an f-string with single quotes and then double quotes f'"your text {here}"'
assert str(err.value) == f'"{name} is missing required item(s): {required_item_list}"'
(With thanks to Anthony Sotile)
An incomplete patch (missing the major value of verbose errors) is to test that a fixed substring exists in the returned error.
def test_erroring_func()
with pytest.raises(KeyError) as err:
name = 'This dataframe'
required_item_list = ['a column']
_ = erroring_func(name, required_item_list)
assert "is missing required item(s):" in str(err.value)
PS. Updating to more modern pytest syntax, a regex match can be defined as a arg in pytest.raises
def test_erroring_func():
with pytest.raises(KeyError, match="is missing required item(s):") as err:
name = 'This dataframe'
required_item_list = ['a column']
_ = erroring_func(name, required_item_list)

How to return two different error messages when querying the same model in Django

Take a look at the following:
def mutate(self, info, first_id, second_id):
try:
first = Model.objects.get(pk=first_id)
second = Model.objects.get(pk=second_id)
except Model.DoesNotExist:
return Exception('Object does not exist.')
else:
...
How can I return a custom error message depending on which of the ids actually does not exist? It's be nice to have something like:
{first_id} does not exist
I can't have two different except blocks because it's the same Model. What to do?
You can simply split up your query's in two statements:
def mutate(self, info, first_id, second_id):
try:
first = Model.objects.get(pk=first_id)
except Model.DoesNotExist:
raise Exception('Your first id {} Does not exist'.format(first_id))
try:
second = Model.objects.get(pk=second_id)
except Model.DoesNotExist:
raise Exception('Your second id {} Does not exist'.format(second_id))
...
PS: you need to raise exceptions. Not return them.

How can I test a loop with multiple input calls?

I'm trying to test a fuction that dependets a of multiple user inputs to return some value.
I've already looked for multiples unswers here but none was able to resolve my problem. I saw things with parametrize, mock and monkey patch but none helped. I think a lot is because I don't clearly understood the concepts behind what was being done and I couldn't adapt to my problem. I saw suggestion of using external file for this but I don't wont to depend on that. I'm trying with pytest and python 3.7.3
The function that I want to test is something like this
def function():
usr_input = input('please enter a number: ')
while True:
if int(usr_input) < 5:
usr_input = input('please, enter a value less then 5: ')
else:
break
return usr_input
I want to know how can I pass two input values to test the function when the inserted value is not valid. Example: Send value 6 and 2, make an assert expecting value 2 and pass the test. My others tests look like this:
def test_input(monkeypatch):
monkeypatch.setattr('builtins.input', lambda x: 6)
test = function()
assert test == 2
but, for this case, they loop. It's possible to do this only with parametrize or other simple code?
EDIT
I added a int() in my "if", as wim pointed in the accepted answer, just to prevent any confusion for future readers. I'm assuming the cast is possible.
Two problems here, you need to convert the input into a number otherwise the comparison will fail, comparing a string with a number: usr_input < 5. Note that the real input will never return a number, only a string.
Once you've cleared that up, you can monkeypatch input with a callable that can return different values when called:
def fake_input(the_prompt):
prompt_to_return_val = {
'please enter a number: ': '6',
'please, enter a value less then 5: ': '2',
}
val = prompt_to_return_val[the_prompt]
return val
def test_input(monkeypatch):
monkeypatch.setattr('builtins.input', fake_input)
test = function()
assert test == 2
If you install the plugin pytest-mock, you can do this more easily with the mock API:
def test_input(mocker):
mocker.patch('builtins.input', side_effect=["6", "2"])
test = function()
assert test == 2

Write a program which gives an input from the user by asking 'Give me an input:'

Write a program which gets an input from the user by asking 'Give me an input:',and passes this string to 'silly_function' if the function returns without an error.simply print whatever it returned. However: if the function produces a ValueError,the program should instead print'I cannot use this value'; if the function produces a TypeError,the program should instead print 'Invalid input'
def silly_function(a):
a = input('Give me an input')
try:
sily_function(a)
except ValueError:
print('I cannot see this value')[enter image description here][1]
Let's try this together.
Code Analysis
def silly_function(a):
a = input('Give me an input')
this is fine, it will prompt the user for an input**
try:
silly_function(a)
Why do you need to call silly_function again ? I don't think that was the intended behavior ?
Also silly_function doesn't do anything that will terminate the recursion or generate an error , so this is bound to break.
except ValueError:
print('I cannot see this value')[enter image description here][1]
Suppose this is a typo, but see != useand you are only handling one error and not the other one.
Suggestion
Let's right in pseudocode a bit of help
def error_handling_function(a):
a = input('Give me an input')
try:
silly_function(a)
except #input error here:
#handle error here
except #input error here:
#handle error here
def silly_function(a):
#write code that can break and generate the two error you are looking for

Resources