-1

I couldn't figure out why I'm getting a NameError when trying to access a function inside the class.

This is the code I am having a problem with. Am I missing something?

class ArmstrongNumber:

    def cubesum(num):
        return sum([int(i)**3 for i in list(str(num))])

    def PrintArmstrong(num):
        if cubesum(num) == num:
            return "Armstrong Number"
        return "Not an Armstrong Number"

    def Armstrong(num):
        if cubesum(num) == num:
            return True
        return False

[i for i in range(1000) if ArmstrongNumber.Armstrong(i)] # this return NameError

Error-message:

NameError                                 Traceback (most recent call last)
<ipython-input-32-f3d39f24a48c> in <module>
----> 1 ArmstrongNumber.Armstrong(153)

<ipython-input-31-fd21586166ed> in Armstrong(num)
     10 
     11     def Armstrong(num):
---> 12         if cubesum(num) == num:
     13             return True
     14         return False

NameError: name 'cubesum' is not defined
piet.t
  • 11,718
  • 21
  • 43
  • 52
Goutham
  • 435
  • 3
  • 16

2 Answers2

2

Use classname before method:

class ArmstrongNumber:

    def cubesum(num):
        return sum([int(i)**3 for i in list(str(num))])

    def PrintArmstrong(num):
        if ArmstrongNumber.cubesum(num) == num:
            return "Armstrong Number"
        return "Not an Armstrong Number"

    def Armstrong(num):
        if ArmstrongNumber.cubesum(num) == num:
            return True
        return False

print([i for i in range(1000) if ArmstrongNumber.Armstrong(i)])

Unlsess you pass self to the functions those functions are not instance methods. Even if you define that within class you still need to access them using classname.

Sociopath
  • 13,068
  • 19
  • 47
  • 75
  • 1
    @AkshayNevrekar Correction: They **are** class methods (or static methods, depending on the decorator used). What you probably wanted to mean is that they are **not** instance methods. – Selcuk Feb 06 '19 at 06:53
  • 1
    If you do it like this then there is no point in using class for this case, best would be just use static methods – Nihal Feb 06 '19 at 06:55
0

this should be your actual solution if you really want to use class

class ArmstrongNumber(object):

    def cubesum(self, num):
        return sum([int(i)**3 for i in list(str(num))])

    def PrintArmstrong(self, num):
        if self.cubesum(num) == num:
            return "Armstrong Number"
        return "Not an Armstrong Number"

    def Armstrong(self, num):
        if self.cubesum(num) == num:
            return True
        return False


a = ArmstrongNumber()

print([i for i in range(1000) if a.Armstrong(i)])

output

[0, 1, 153, 370, 371, 407]

2nd method:

if you dont want to use class then use static methods like this

def cubesum(num):
    return sum([int(i)**3 for i in list(str(num))])


def PrintArmstrong(num):
    if cubesum(num) == num:
        return "Armstrong Number"
    return "Not an Armstrong Number"


def Armstrong(num):
    if cubesum(num) == num:
        return True
    return False


# a = ArmstrongNumber()

print([i for i in range(1000) if Armstrong(i)])
Nihal
  • 5,262
  • 7
  • 23
  • 41
  • 1
    This is still pointless. Maybe move `num` into an `__init__` method then have methods like `.is_armstrong_number()`? – Selcuk Feb 06 '19 at 07:07