0

I am trying to implement a recursive function, in which my base condition is working fine, another condition is also working properly. But when I jump to the recursive condition it gives me error that,"class name" object has no attribute "function name" .

My class:

class NGram(object):
    def __init__(self):
        self.n = None
        self.ngramprobability = None
        self.uniquegrams = [
            ["sample", "this"],
            ["is", "a"],
            ["this", "is"],
            ["sample"],
            ["this"],
            ["a"],
            ["is"],
            ["a", "sample"],
        ]

        self.out = [
            [
                ["sample", 0.16666666666666666],
                ["this", 0.3333333333333333],
                ["a", 0.16666666666666666],
                ["is", 0.3333333333333333],
            ],
            [
                ["sample", "this", 1.0],
                ["is", "a", 0.5],
                ["this", "is", 1.0],
                ["a", "sample", 1.0],
            ],
        ]

    def get_prob(self, words):

        if len(words) == 1:
            probability = [j[-1] for i in self.out for j in i if j[:-1] == words][0]
            return probability  # condition works fine

        elif words in self.uniquegrams:
            probability = [j[-1] for i in self.out for j in i if j[:-1] == words][0]
            return probability  # condition works fine
        else:
            return self.get_prob(self, words[1:]) * 0.4

My script that is raising errors:

# train bi_gram
bi_gram = NGram()

c = bi_gram.get_prob(["this", "sample"])
print(c)

Where I am making mistake?

11
  • It looks like this is in a class, it should be self.function_name and when you call self.function_name you shouldn't include the self var Commented Apr 14, 2020 at 9:03
  • Hi @Alex , I tried to use self.function_name, yes this function is in class. But then I got the error, "classname" object has no attribute "function_name" Commented Apr 14, 2020 at 9:19
  • @AdityaParikh if you want a correct answer, provide all required informations (cf How to Ask and minimal reproducible example). We have no time for guessing games. Commented Apr 14, 2020 at 9:25
  • I have edited my question. I hope this will help you. @brunodesthuilliers Here there are other functions where I have used self.out but it is working fine and gives its output so I didn't take that part of code it in question Commented Apr 14, 2020 at 9:42
  • 1
    @AdityaParikh this is STILL not a proper minimal reproducible example. A minimal reproducible example is a code snippet that we can copy-paste and execute. And with your updated code snippet, the error you'd get is another one, cf the above comment. Commented Apr 14, 2020 at 9:53

2 Answers 2

2

Here are two examples (you'll notice that I removed everything that's irrelevant and only kept what's necessary to reproduce the issues) :

1/ forgetting to use self. to reference the method:

class NGram(object):
    def get_prob(self, words):
        if len(words) == 1:
            return 1        
        else: 
            return get_prob(words[1:]) * 0.4

ng = NGram()
print(ng.get_prob(["foo"]))
print(ng.get_prob(["foo", "bar"]))

which constantly raises a NameError on the second call:

1
Traceback (most recent call last):
  File "probs.py", line 10, in <module>
    print(ng.get_prob(["foo", "bar"]))
  File "probs.py", line 6, in get_prob
    return get_prob(words[1:]) * 0.4
NameError: global name 'get_prob' is not defined

2/ using self. to reference the method but incorrectly passing self as argument:

class NGram(object):
    def get_prob(self, words):
        if len(words) == 1:
            return 1        
        else: 
            return self.get_prob(self, words[1:]) * 0.4

ng = NGram()
print(ng.get_prob(["foo"]))
print(ng.get_prob(["foo", "bar"]))

which constantly raises a TypeError on the second call:

1
Traceback (most recent call last):
  File "probs.py", line 10, in <module>
    print(ng.get_prob(["foo", "bar"]))
  File "probs.py", line 6, in get_prob
    return self.get_prob(self, words[1:]) * 0.4
TypeError: get_prob() takes 2 positional arguments but 3 were given

And to address your issue - which you wouldn't have if you had done the tutorial -, the correct way is:

 class NGram(object):
    def get_prob(self, words):
        if len(words) == 1:
            return 1        
        else: 
            return self.get_prob(words[1:]) * 0.4

ng = NGram()
print(ng.get_prob(["foo"]))
print(ng.get_prob(["foo", "bar"]))

which works as expected:

1
0.4
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much for your explanation, I will take care of the things you mention before, The reason my code not working was due to typo in function name at else condition. It's my bad and couldn't figure it out due to Jupyter notebook but when I changed IDE to VS it highlighted the error. Thank you again and sorry for all this inconvenience, I will try to be more clear in my questions from the next time.
1

Short answer: replace your code at line #22 from

return self.get_prob(self, words[1:]) * 0.4

to

return self.get_prob(words[1:]) * 0.4

You are not supposed to give self as an argument when calling any function of a class (it's only included in the definition).

Long answer: Check @Bruno's answer

4 Comments

Yes, I tried to make changes suggested by you and @Bruno. I was getting the sam error before and now also. If, I remove self, and try to run the code, I am getting an AttributeError: 'NGram' object has no attribute 'get_prob' . I might be doing silly mistake somewhere but still not getting this.
@AdityaParikh That's weird. Works fine for me after making the above change. Are you saving your script or not? Or are you running the right script? Also remove all the .pyc files from your project if possible.
Yes, it was my mistake, it was a typo in the spelling of function name, that's why I was getting error. My bad.
No worries man. That's why we should always use a linter (which takes care of these things).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.