# [Tutor] Strange list behaviour in classes

James Reynolds eire1130 at gmail.com
Thu Feb 25 00:26:58 CET 2010

```Thanks for the reply.

I understand, but if self.value is any number other then 0, then the "for"
will append to the square list, in which case square_list will always have
some len greater than 0 when "value" is greater than 0?

I'm just trying to understand the mechanics. I'm assuming that isn't the way
the statement is evaluated?

When I get home from work I'll work around it.

Is this an occasion which is best suited for a try:, except statement? Or
should it, in general, but checked with "if's". Which is more expensive?

The rest of the code was in the prior email (please see below)

Module 1:

import Statistics

a = [1,2,3,4,5,6,7,8,9,10]

mean = Statistics.stats.mean(*a)
median = Statistics.stats.median(*a)
var = Statistics.stats.variance(*a)
print(mean, median, var)
print()

Module 2:

#!/usr/bin/python
# Filename: Statistics.py

import math
value_list = []
class Statistics:
def __init__(self, *value_list):
self.value = value_list
#self.average = mean(*value_list)
self.square_list= []
def mean(self, *value_list):
if len(self.value) == 0:
ave = 0
else:
ave = sum(self.value) / len(self.value)
return ave

def median(self, *value_list):
if len(self.value) <= 2:
n = self.mean(self.value)
elif len(self.value) % 2 == 1:
m = (len(self.value) - 1)/2
n = self.value[m+1]
else:
m = len(self.value) / 2
m = int(m)
n = (self.value[m] + self.value[m+1]) / 2
return n
def variance(self, *value_list):
if self.value == 0:
var = 0
else:
average = self.mean(*self.value)
for n in range(len(self.value)):
square = (self.value[n] - average)**2
self.square_list.append(square)
var = sum(self.square_list) / len(self.square_list)
return var

stats = Statistics(*value_list)

On Wed, Feb 24, 2010 at 5:59 PM, ALAN GAULD <alan.gauld at btinternet.com>wrote:

> Forwarding to the list.
> Please alweays use Reply All so others can comment too.
>
> I made a few changes, but I'm getting the same error on variance (see
> below):
>
> Looks like a different error to me!
>
> It would seem to me that it should never evaluate if the denominator is
> zero because of the if statement.
>
> But the if statement doesn't test whether len(self.square_list) is zero.
> It tests whether self.value is zero.
>
> The other thing I don't understand is that the object that is being passed
> into the instance is a list, but it seems to be a tuple once the object is
> called. Why does this happen? Am I doing something additional wrong?
>
> Sorry, your code doesn't show any instances let alone lists being pased in?
>
> Alan G.
>
>   File "C:\Python31\Lib\COI\Project\Statistics.py", line 39, in variance
>     var = sum(self.square_list) / len(self.square_list)
> ZeroDivisionError: int division or modulo by zero
>
> #!/usr/bin/python
> # Filename: Statistics.py
>
> import math
> value_list = []
> class Statistics:
> def __init__(self, *value_list):
>  self.value = value_list
> #self.average = mean(*value_list)
> self.square_list= []
>  def mean(self, *value_list):
> if len(self.value) == 0:
>  ave = 0
> else:
> ave = sum(self.value) / len(self.value)
>  return ave
>
> def median(self, *value_list):
> if len(self.value) <= 2:
>  n = self.mean(self.value)
> elif len(self.value) % 2 == 1:
> m = (len(self.value) - 1)/2
>  n = self.value[m+1]
> else:
> m = len(self.value) / 2
>  m = int(m)
> n = (self.value[m] + self.value[m+1]) / 2
> return n
>  def variance(self, *value_list):
> if self.value == 0:
>  var = 0
> else:
> average = self.mean(*self.value)
>  for n in range(len(self.value)):
> square = (self.value[n] - average)**2
>  self.square_list.append(square)
> var = sum(self.square_list) / len(self.square_list)
>  return var
>
>
> On Wed, Feb 24, 2010 at 4:02 AM, Alan Gauld <alan.gauld at btinternet.com>wrote:
>
>>
>> "James Reynolds" <eire1130 at gmail.com> wrote
>>
>>
>>  This thread inspired me to start learning object oriented as well, but it
>>> seems I must be missing something fundamental.
>>>
>>
>> No, this has nothing to do with objects, its just a broken algorithm.
>>
>>    median = Statistics.stats.median(*a)
>>>   n = (self.value[m] + self.value[m+1]) / 2
>>> IndexError: tuple index out of range
>>>
>>> def median(self, *value_list):
>>>     if len(self.value) % 2 == 1:
>>>          m = (len(self.value) - 1)/2
>>>          n = self.value[m+1]
>>>     else:
>>>          m = len(self.value) / 2
>>>          m = int(m)
>>>          n = (self.value[m] + self.value[m+1]) / 2
>>>     return n
>>>
>>
>> Consider the case where the length of value is 2.
>> We will use the else part of the branch.
>> m will have value 1
>> The highest index is 1 because indexes start at zero
>> so value[m+1] will fail with an index error.
>>
>> A similar error will happen when the list has only 1 entry
>> since the highest index there will be zero.
>>
>> You need to rethink your rules for generating the indexes
>> remembering that they start at zero.
>>
>>
>>
>> --
>> Alan Gauld
>> Author of the Learn to Program web site
>> http://www.alan-g.me.uk/
>>
>> _______________________________________________
>> Tutor maillist  -  Tutor at python.org
>> To unsubscribe or change subscription options:
>> http://mail.python.org/mailman/listinfo/tutor
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20100224/89d06382/attachment-0001.html>
```