1

I'm trying to implement a method in Python using recursion, but for some reason can't get it to work. When I enter the following code, I get an error "Undefined variable 'addDigits' (undefined-variable)". What am I doing wrong?

def addDigits(self, num):
    if len(str(num)) == 1:
        return num
    else:
        return (addDigits((num - num % 10)/10) + num % 10)
Yanjie
  • 21
  • 1

4 Answers4

4

The self tells me this is an instance method on a class. You need to call it via self like so:

def addDigits(self, num):
    if len(str(num)) == 1:
        return num
    else:
        return (self.addDigits((num - num % 10)/10) + num % 10)

Since it is not using any instance variables on that class, it is also suitable to be pulled out and put at the script level, or left in the class as a static method:

# you could leave it in the class and add the @stacticmethod decorator
class Klass:
    @staticmethod
    def addDigits(num):
        if len(str(num)) == 1:
            return num
        else:
            return (addDigits((num - num % 10)/10) + num % 10)

I assume you're doing this just for fun, but if you're really trying to implement this, here's a much more pythonic one-liner:

num = 1984
print(sum(int(c) for c in str(num)))
mattmc3
  • 17,595
  • 7
  • 83
  • 103
1

If this method is an instance method of class then you should try adding self to the return statement as in the above answers. However if it isn't a method of a class just do this:

def addDigits(num):
    if len(str(num)) == 1:
        return num
    else:
        return (addDigits((num - num % 10)/10) + num % 10)

This will work

Arnab
  • 1,037
  • 3
  • 16
  • 31
1

Just use self.addDigits instead of just addDigits

pauloaap
  • 828
  • 6
  • 11
1

Note that maximum recursion depth is quite small by default (1k on python 2.17 on my box). This can be checked by running:

import sys
print(sys.getrecursionlimit())

In most cases (to avoid hitting recursion limit) you can make your code iterative, here is good article about recursion-to-iteration.

Anyway, if your snippet is indeed an instance method, as 'self' could suggest, you can simply add an instance property, that would contain current value. Example:

class UselessObject(object):

    def __init__(self, start_value=0):
        self.value = start_value

    @staticmethod
    def is_numeric(s):
        try:
            float(s)
            return True
        except (ValueError, TypeError):
            return False

    def addDigit(self, number):
        assert self.is_numeric(number), "non-numeric value provided"
        if str(number).__len__() == 1:
            self.value += number
        else:
            self.value += (number - number%10)/10 + number%10
internety
  • 364
  • 3
  • 8
  • +1 for general recursion stuff (```getrecursionlimit``` and the article). However you may want to fix that code, it is missing the recursive part at the moment. – tevemadar May 28 '17 at 11:43