Reputation: 306
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?
Upvotes: 0
Views: 476
Reputation: 77912
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
Upvotes: 2
Reputation: 1500
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
Upvotes: 1