# Exception Handling : Calculating Average Efficiency With a Method

``````class Trial(object):
def __init__(self, datarow):
self.efficiency = float(datarow)
self.individual = int(datarow)
self.chopstick_length = int(datarow)

class Chopstick(object):
def __init__(self, length):
self.length = length
self.trials = []
for row in chopsticks:
if int(row) == self.length:
self.trials.append(Trial(row))
class Chopstick(object):
def __init__(self, length):
self.length = length
self.trials = []
for row in chopsticks:
if int(row) == self.length:
self.trials.append(Trial(row))
def num_trials(self):
self.trail_num =  len(self.trials)
return self.trail_num
def avg_efficiency(self):
efficiency_sum = 0
for trial in self.trials:
efficiency_sum += trial.efficiency
return efficiency_sum / self.num_trials()
avg_eff_210 = Chopstick(210).avg_efficiency()
``````

Here what is happening at line 24 ( efficiency_sum += trial.efficiency). How are we able to access ‘efficacy’ item of ‘Trial’ class here. without even calling Trail class.

Also here, ’ return efficiency_sum / self.num_trials()’ why I have to access it with method name ‘self.num_trials()’’? why can’t I access it with by saying return efficiency_sum / self.trail_num ? as we are accessing self.trials from init method ?

1 Like

Hi @kabyabasu,

``````class Trial(object):
def __init__(self, datarow):
self.efficiency = float(datarow)
self.individual = int(datarow)
self.chopstick_length = int(datarow)

class Chopstick(object):
def __init__(self, length):
self.length = length
self.trials = []
for row in chopsticks:
if int(row) == self.length:
self.trials.append(Trial(row))
def num_trials(self):
self.trail_num =  len(self.trials)
return self.trail_num
def avg_efficiency(self):
efficiency_sum = 0
for trial in self.trials:
efficiency_sum += trial.efficiency
return efficiency_sum / self.num_trials()
avg_eff_210 = Chopstick(210).avg_efficiency()
``````

Here what is happening at line 24 ( efficiency_sum += trial.efficiency). How are we able to access ‘efficacy’ item of ‘Trial’ class here. without even calling Trail class.

`Chopstick(210)` will execute:

``````self.length = 210
self.trials = []
for row in chopsticks:
if int(row) == 210:
self.trials.append(Trial(row))
``````

`Trial(row)` is executed when the chopstick length is equal to 210. And then, it is appended to `self.trials` list. Therefore, all of the data in `self.trials` is a `Trial` object

After initialisation is done, `.avg_efficiency()` method is called.

Which will execute this code:

``````efficiency_sum = 0
for trial in self.trials:
efficiency_sum += trial.efficiency
return efficiency_sum / self.num_trials()
``````

Since `trial` is actually a `Trial` object, we are able to access it’s `.efficiency` attribute.

Also here, ’ return efficiency_sum / self.num_trials()’ why I have to access it with method name ‘self.num_trials()’’? why can’t I access it with by saying return efficiency_sum / self.trail_num ? as we are accessing self.trials from init method ?

You can use `self.trail_num` instead of `self.num_trials()`, both will produce the same output.

Best,
Sahil