def oneCount(n):
n = str(n)
# Here, you check if the entire string is '1'.
# Not sure if you mean to check if a single digit is '1'.
if n == '1':
return 1
else:
# If the entire string is not '1', you recur on all but the least significant digit.
return 1 + oneCount(n[:-1])
print oneCount(1100)
Walk:
oneCount(1100) -> '1100' is not '1'. recurs on 1 + oneCount('110')
1 + oneCount('100') -> '110' is not '1'. recurs on 1 + (1 + oneCount('11'))
2 + oneCount('00') -> '11' is not '1'. recurs on 2 + (1 + oneCount('1'))
3 + oneCount('0') -> '1' is '1'. return 1
4
OK, so that's a wrong answer, but perhaps more insidious, what if your most significant digit weren't 1?
oneCount(2)
>>> RuntimeError: maximum recursion depth exceeded while calling a Python object
You end up recurring on the empty string. The empty string isn't '1', so the recursion is infinite!
When recurring over an iterable like a string or a list, a good rule of thumb is to consider the empty iterable your base case.
def oneCount(i):
i = str(i)
if i == '':
return 0
# Do not recur in the base case, above
# The below cases are not the base case, so expect to recur
# What is the nature of the recursion?
car, cdr = i[0], i[1:] # silly lisp reference
if car == '1':
???
# else?
Just for fun
Booleans as integers
Consider that a boolean value is equivalent to an integer value of 1 or 0 in Python. You can add that value to an integer.
return (car == 1) + oneCount(cdr)
Radical
Consider that you don't need to convert an integer into a string in order to iterate over it. Consider cdr, car = divmod(i, 10), or more plainly, cdr, car = i // 10, i % 10. What's fun is that gives you the ability to count the occurrence of digits in a number in any base.
def oneCount(i, base=10):
if i == 0:
return 0
cdr, car = divmod(i, base)
if car == 1:
???
???
>>> oneCount(int('111111100000', 2), 2)
7
Fiver?return (n[-1] == '1') + oneCount(n[:-1])