I wrote a python program to try to grade my ml predictions using object oriented programming and I am trying to chain functions together. Like say:
answers = predictionsGrader().merge_on('PassengerId').compare("Survived_x", "Survived_y").grade()
However, my code started to throw errors of attribute error.
AttributeError: 'NoneType' object has no attribute 'compare'
After trying to understand what the problem was, I realized that although the initialization was returning an object,
<class 'predictionsGrader.predictionsGrader'>
the function which was called after the initialization (which is the merge_on
function) was returning a NoneType
<class 'NoneType'>
Please what could be wrong. Here's the full code:
import pandas as pd
class predictionsGrader():
def __init__(self, predictions, target):
self.correct = []
self.predictions = predictions
self.target = target
return
def merge_on(self, row):
self.row = row
self.md = pd.merge(self.predictions, self.target, on=[self.row])
return
def compare(self, predicted_target, confirmed_target):
self.predicted_target = predicted_target or "predicted_target"
self.confirmed_target = confirmed_target or "confirmed_target"
return
def grade(self):
for x in range(len(self.md[self.predicted_target])):
if (self.md[self.predicted_target][x] == self.md[self.confirmed_target][x]):
self.correct.append("right")
else:
self.correct.append("wrong")
return self.correct
If you want a fluid interface like that, your methods (other than __init__
) need to return self
.
class predictionsGrader():
def __init__(self, predictions, target):
self.correct = []
self.predictions = predictions
self.target = target
def merge_on(self, row):
self.row = row
self.md = pd.merge(self.predictions, self.target, on=[self.row])
return self
def compare(self, predicted_target, confirmed_target):
self.predicted_target = predicted_target or "predicted_target"
self.confirmed_target = confirmed_target or "confirmed_target"
return self
def grade(self):
for x in range(len(self.md[self.predicted_target])):
if (self.md[self.predicted_target][x] == self.md[self.confirmed_target][x]):
self.correct.append("right")
else:
self.correct.append("wrong")
return self.correct
__init__
shouldn't return anything - it's an initializer, not a constructor.