2

I'm trying to create a recursive function that adds all the digits in a number. Here's what I've come up with:

def sumOfDigits(num):
    num=str(num)
    if len(num)==0:
        return 0
    elif len(num)==1:
        return int(num)
    elif len(num)>1:
        return int(num[0]) + int(num[-1]) + int(sumOfDigits(num[1:-1]))

this seems to work for almost any number:

sumOfDigits(999999999)
>>>81
sumOfDigits(1234)
>>>10
sumOfDigits(111)
>>>3
sumOfDigits(1)
>>>1
sumOfDigits(0)
>>>0

strange things happen though if the number begins with '0'

sumOfDigits(012)
>>>1
sumOfDigits(0123)
>>>11
sumOfDigits(00010)
>>>8

what am I missing here??

djechlin
  • 59,258
  • 35
  • 162
  • 290
Pav Ametvic
  • 1,727
  • 4
  • 12
  • 14

3 Answers3

12

In Python 2, integer literals that start with zero are octal.

To take your examples:

In [46]: 012
Out[46]: 10

In [47]: 0123
Out[47]: 83

In [48]: 0010
Out[48]: 8

Since your function works in base ten, it is doing its job correctly. :)

As an aside, you need neither string manipulation nor recursion for this problem. Since others have already suggested non-recursive solutions, here is a recursive one that doesn't use string manipulation:

def sumOfDigits(n):
   return 0 if n == 0 else sumOfDigits(n // 10) + n % 10
jdotjdot
  • 16,134
  • 13
  • 66
  • 118
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 1
    Note that in Python 3 the OP cannot make this mistake as octal literals are now expressed `0o12` not `012`. – Steven Rumbalski Dec 04 '12 at 19:58
  • didn't know about 'octal' integer literals. Thanks! will look into it. – Pav Ametvic Dec 04 '12 at 19:59
  • 1
    Which is a very sensible change and really how it should have been to begin with. – jdotjdot Dec 04 '12 at 20:00
  • @jdotjdot one could also argue that `print` should never have been a statement, and that blah blah blah.... :) – Jon Clements Dec 04 '12 at 20:40
  • I actually don't have a problem with `print` as a statement. The only things I really have problems with are where the syntax directly opposes what you think it should do, and does so silently--octals being a great example. `print` just prints, even if it's a statement instead of a function. As this OP is seeing, that extra `0` in front of the number makes everything go wrong, and there's no obvious way to figure out way, since when `013` evaluates to `11`, it's still an `int`, and even `oct(013)` returns a `str`! – jdotjdot Dec 04 '12 at 20:45
2

To be honest, there's an easier way to do this whole thing.

sum(map(int, str(num)))

Note that this doesn't take care of the octal string issue wisely pointed out above.

jdotjdot
  • 16,134
  • 13
  • 66
  • 118
0

Numbers stats with 0 are treated as octal number .

Octal Value for 00010 is 8 .

For more refer the post binary numbers? .

Python numbers starts with 0 will not work . For octal number you have to specify Oo to convert it as octal number.

Community
  • 1
  • 1
kannanrbk
  • 6,964
  • 13
  • 53
  • 94