This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed 4 years ago.
I had trouble understanding why this function returns None:
def rem(x, a):
"""
x: a non-negative integer argument
a: a positive integer argument
returns: integer, the remainder when x is divided by a.
"""
if x == a:
return 0
elif x < a:
return x
else:
rem(x-a, a)
rem(7, 5)
I then realized that the last line in the function should be:
return rem(x-a, a)
I am still unsure as to what really happens in the first one. It looks like there are 2 seperate function calls, one returning 2 and the other None... any help?
All python function returns None if it doesn't terminate by a return statement. In your case, you successfully called the recursion but you discarded the result in the else part. And after the if-block, the default return None is implicitly executed.
This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 4 years ago.
I'm checking if the argument of a function is a float or an int with this line and it keeps return false, can anyone explain why this happens?
def distance_from_zero(number):
if type(number) == (int or float):
return abs(number)
else:
return "Nope"
This is the shortest, most pythonic way.
Use isinstance:
if isinstance(number, (int, float)):
In the spirit of Easier to ask for forgiveness than permission you could use an exception instead of explicit type checking, like
def distance_from_zero(number):
try:
return abs(number)
except TypeError:
return 'Nope'
for x in [1, 1.1, 'a']:
print(x, distance_from_zero(x))
1 1
1.1 1.1
a Nope
IMO this is often clearer and more foolproof.
This question already has answers here:
Convert integer to string in Python
(14 answers)
Closed 6 years ago.
My code:
def digit_sum(n):
result = 0
s = str(n)
for c in s:
result += (int)c # invalid syntax??????????
return result
print digit_sum(1234)
Result:
result += (int)c # invalid syntax??????????
^
SyntaxError: invalid syntax
The function is supposed to return the sum of each digit of the argument "n".
Why do I get SyntaxError in the commented line? The variable c is of type string so it shouldn´t be an issue to apply a type cast to int.
In Python you do not cast that way. You use:
result += int(c)
Technically speaking this is not casting: you call the int(..) builtin function which takes as input the string and produces its equivalent as int. You do not cast in Python since it is a dynamically typed language.
Note that it is of course possible that c contains text that is not an integer. Like 'the number fifteen whohaa'. Of course int(..) cannot make sense out of that. In that case it will raise a ValueError. You can use try-except to handle these:
try:
result += int(c)
except ValueError:
# ... (do something to handle the error)
pass
In Python, you cast a string to an integer by using a function int().
result += int(c)
def digit_sum(n):
numsum=[]
add_up=str(n)
for n in add_up[0: len(add_up)]:
numsum.append(int(n))
return sum(numsum)
print digit_sum(1234)
Basically, you need to cast string to integer using int(n)
This question already has answers here:
how to tell a variable is iterable but not a string
(11 answers)
Type checking: an iterable type that is not a string
(1 answer)
Closed 6 years ago.
I have a function designed for interactive usage that takes either a single "scalar" value as argument or an iterable. The output should match the input. Here is a toy example.
def func(x):
flag = False
if isinstance(x, int):
flag = True
x = (x,)
retval = tuple(i**2 for i in x)
return retval[0] if flag else retval
>>> func(5)
25
>>> func((1,2,3,4))
(1, 4, 9, 16)
Question: Is there a more convenient method to check whether the user provided a "scalar" or an iterable? I don't want to rely on checking the with isinstance?
I tried with hasattr(x, '__iter__'), but this return True for "scalar" string input (not covered in the example here).
This question already has answers here:
How to convert a string to a number if it has commas in it as thousands separators?
(10 answers)
Closed 9 years ago.
I have not tried decorators yet or functions within functions, but this current un-pythonic method seems a little convoluted. I dont like how I need to repeat myself when I check the return_type (3 times)?
Any suggestions are welcome, especially if the repetion can be dealt with in an elegant way. Please note that I am not that interested in the numerous reference to test if an object is a number as I believe this part is incorporated within my solution. I am interested in addressing the 3x duplication to deal with the return type. Moreover, while I appreciate the locale method is the more rigorous way of dealing with internationalisation, I prefer the simplicity of allowing the caller more flexibility in choosing the characters.
Thanks
def is_number(obj, thousand_sep=',', decimal_sep=None, return_type='b'):
""" determines if obj is numeric.
if return_type = b, returns a boolean True/False
otherwise, it returns the numeric value
Examples
--------
>>> is_number(3)
True
>>> is_number('-4.1728')
True
>>> is_number('-4.1728', return_type='n')
-4.1728
>>> is_number(-5.43)
True
>>> is_number("20,000.43")
True
>>> is_number("20.000,43", decimal_sep=",", thousand_sep=",")
True
>>> is_number("20.000,43", decimal_sep=",", thousand_sep=".", return_type="n")
20000.43
>>> is_number('Four')
False
# I am a few light years away from working that one out!!!
"""
try:
if is_string(obj):
if decimal_sep is None:
value = float(obj.replace(thousand_sep, ""))
else:
value = float(obj.replace(thousand_sep, "").replace(decimal_sep, "."))
if return_type.lower() == 'b':
return True
else:
return value
else:
value = float(obj)
if return_type.lower() == 'b':
return True
else:
return value
except ValueError:
return False
if return_type.lower() == 'b':
return False
else:
return None
using regular expressions, you may do:
import re
regex = re.compile( r'[+-]{0,1}\d{1,3}(,\d\d\d)*(\.\d+)*'
now if you have string txt, and do below
regex.sub( '', txt, count=1 )
you will end up with an empty string if that string is a number with , as thousands separator and . as decimal separator.
This method enforces a strict 3 digits thousands separator. so for example 20,0001.43 is not a number because the thousands separator is wrong. 1220,001.43 is not a number either because it is missing a ,.
def numval( txt ):
import re
regex = re.compile( r'[+-]{0,1}\d{1,3}(,\d\d\d)*(\.\d+)*'
if regex.sub( '', txt.strip(' '), count=1 ) != '':
raise ValueError ( 'not a number' )
else:
return float( txt.replace( ',', '' ))
I would probably separate the logic ... I think this does what you are trying to do ...
def get_non_base_10(s):
#support for base 2,8,and 16
if s.startswith("O") and s[1:].isdigit():
return int(s[1:],8)
elif s.startswith("0x") and s[2:].isdigit():
return int(s[2:],16)
elif s.startswith("0b") and s[2:].isdigit():
return int(s[2:],2)
def get_number(s,decimal_separator=".",thousands_separator=","):
if isinstance(s,basestring):
temp_val = get_non_base_10(s)
if temp_val is not None:
return temp_val
s = s.replace(decimal_separator,".").replace(thousands_separator,"")
try:
return float(s)
except ValueError:
return "nan"
def is_number(s,decimal_separator=".",thousands_separator=",",return_type="b"):
numeric = get_number(s,decimal_separator,thousands_separator)
return numeric if return_type != "b" else numeric != "nan"