I have one function (F1) returning the values of (a, b, c)
and other function (F2) using those values. I need to check on F2 if "a is None".
This is the first function (F1)
def get_info():
msg = get_msg()
number = get_number()
if msg is not None:
return msg, number
return False, False
Secound function (F2)
def save_log():
msg, number = get_info()
if msg:
do_more_stuff
If I don't do return False, False in the first function I get TypeError: 'bool' object is not iterable in the second function.
Do I have a better way of returning those values other than return False, False.
What is the pythonic best practice in this situation?
Thanks
This is what a solution using errors/exceptions would look like. get_msg (and maybe get_number if applicable) would raise an exception when they fail to return a value, instead of returning a value that indicates failure.
class MessageRetrievalError(Exception):
pass
def get_msg():
message = message_code()
if message is None:
raise MessageRetrievalError
return message
def get_info():
return get_msg(), get_number()
def save_log():
try:
msg, number = get_info()
do_more_stuff
except MessageRetrievalError:
do_other_stuff
Related
im trying to write a function that takes as a value a dict,
and return if the key is exists at the dict.
i debugged the function and i fount out that even if the function
enter a code where it should return True, it is still calling the other recursive calls,
and return none instead of the initial True value.
the function:
def checkIfKeyExsists(self,searchKey,passingValue):
if searchKey in passingValue:
return True
else:
for value in passingValue.values():
if type(value) == dict:
if searchKey in value.keys():
print("yes")
return True
else:
self.checkIfKeyExsists(searchKey,value)
elif type(value) == list:
for dicInLst in value:
self.checkIfKeyExsists(searchKey,dicInLst)
dict that i used:
thisdict = {
"brand": "Ford",
"model": {"Mustang":{"car":"motti","car123":"34"}},
"year": [{"a":"test"},{"c":"er"}] }
jn = JsonNode(thisdict)
x = jn.checkIfKeyExsists("car",jn.getJsonDic())
**this function is a part of class that calls JsonNode
There are three issues with your recursive function.
First you don't return anything at the end of your function. So what does happen if you don't fall in the different branches of your code? Then the function will return None as you experienced. So first you should terminate your function with return False.
Second you don't do anything of the value returned by your recursive calls. Hence this value is just ignored. So this why even when the key is found, you keep performing recursive calls. You should do something like this instead: replace
self.checkIfKeyExsists(searchKey,dicInLst)
by
if(self.checkIfKeyExsists(searchKey,dicInLst)):
return True
Last, it does not affect the correctness of your function but your check if searchKey in value.keys() is actually useless as it's already performed as the first test (if searchKey in passingValue) when performing a recursive call. Hence this case will be covered by your recursive call (self.checkIfKeyExsists(searchKey,value)).
I just saw the following Python code, and I'm a bit confused by the first return. Does it return None by default? Is it equivalent to return(None)? If the first return is executed, will the function inner() automatically end there and the second return be left alone?
def smart_check(f):
def inner(a,b):
if b==0:
print("illegit: b =", b)
return # the first return
return(f(a,b))
return(inner)
#smart_check
def divide(a,b):
return(a/b)
Does it return None by default? Is it equivalent to return(None)
Yes, see docs: If an expression list is present, it is evaluated, else None is
substituted.
If the first return is executed, will the function inner()
automatically end there and the second return be left alone?
Yes
If you don't want to return anything you can even drop the return statement completely:
def smart_check(f):
def inner(a,b):
if b != 0:
return f(a,b)
print("illegit: b =", b)
return(inner)
As print doesn't return anything you could even rewrite this function as
def smart_check(f):
def inner(a,b):
return f(a,b) if b!=0 else print("illegit: b =", b)
return(inner)
I have a task to define a function contains_only_integers which takes a tuple as the argument and returns True is every element of the tuple is an integer, and false otherwise. I'm a bit stuck on why I get false every time.
I would use a for-loop, but the task asks specifically for a while loop.
def contains_only_integers(tup):
while isinstance(tup, int)==True:
return True
else:
return False
What am I missing?
Mthrsj covered your problem and how to fix it but an alternative, perhaps more pythonic, way of doing this would be to use the builtin all function.
def contains_only_integers(tup):
return all(isinstance(v, int) for v in tup)
When you do while isintance(tup,int), the function evaluates the tuple, not each element. To achieve what you want, you need to iterate over the tuple. An example below:
def contains_only_integers(tup):
for item in tup:
if not isinstance(item, int):
return False
return True
If the code find any item in the tuple that is not an integer instance it will return False. Otherwise, it will return True.
EDIT
As you said you need to use a while loop, there it is:
def contains_only_integers(tup):
i = 0
while i < len(tup):
if not isinstance(tup[i], int):
return False
i+=1
return True
I am trying to refactor a python class into Genie, but I am stuck with how to handle errors. Some pointers would be greatly appreciated.
If I understood properly, the way of handling errors with Genie is using Try...except blocks, but how to translate the following type of error handling into this paradigm:
# Enable dictionary/list-style access to options and arguments.
def __getitem__(self, key):
if isinstance(key, int):
if key < len(self.arguments):
return self.arguments[key]
else:
raise ArgParserError(
"positional argument index [%s] is out of bounds" % key
)
else:
option = self._get_opt(key)
return option.value
The code I am at right now looks like (in Genie):
def getitem (key:int):string
if key.is_int()
if key < len(_arguments)
return _arguments[key]
else
raise ArgParserError(
"positional argument index [%s] is out of bounds", key
)
else
var option = _get_opt(key)
return option.value
This is a dummy code, I am only modelling the problem and I am aware that it will not compile as is. I am only looking for a pointer on how to transate the '''raise''' command from python.
You need to define the error type as an exception and then identify that your getitem function raises such an error:
exception ArgParserError
OUT_OF_BOUNDS
def getitem( key:int ):string raises ArgParserError
if key < len(_arguments)
return _arguments[key]
else
raise new ArgParserError.OUT_OF_BOUNDS(
"positional argument index [%s] is out of bounds", key
)
Genie is statically typed so the if key.is_int() is unnecessary. The Vala compiler will check at compile time that all calls to the getitem function pass an integer as the argument.
An alternative approach is to use an out parameter for the result value and use the function's return value to signal if the result is valid:
def getitem( key:uint, out value:string ):bool
result:bool = false
value = ""
if key < _arguments.length
value = _arguments[ key ]
result = true
else
info( "positional argument index [%s] is out of bounds", key )
return result
By making the key an unsigned integer, uint, a negative index can't be passed. The call to info() will log some details of the out of bounds index should you need it for debugging later.
why does the following code returns none:
j = 22
def test(j):
if j > 0:
print('j>0')
else:
print('j<0')
Output:
j>0
None
A function in Python always has a return value, even if you do not use a return statement, defaulting to None
Because the test function doesn't return a value, it ends up returning the object None. that's why it ended up printing None Since you do not have a return value specified
you may not use print in your function, but return a string instead
def test(j):
if j > 0:
return 'j>0'
else:
return 'j<0'
then call it like this: print it when calling the function
print(test(22))
see answer's here for more detail