[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>
More information about the Tutor
mailing list