1

I am attempting to find the standard deviation of numbers in python. This is an entry level programming class so i am avoiding trying to use a function since they have not been introduced yet.

This program allows me to add numbers to a list, analyze said list, and then bring out the average, min, max, STDev, ect. I have managed to successfully display everything except STDev, the error i keep getting is float object not iterable. here is the code for the related part:

elif (menuchoice == 4):
        sum = 0.0
        print("std deviation")
        stdev = 0.0
        for i in range(listcount):
            scorenum4 = eval(scorenum[i])
            scoreaverage2 += scorenum4
        scoreaverage2 /= listcount
        for i in range(listcount):
            stdev = []
            scorenum3 = eval(scorenum[i])
            stdev += (scorenum3 - scoreaverage2)**2
            dev = sqrt((stdev)/listcount-1)
        print(dev)

any help would be geat, thank you.

-Self edit - I just removed stdev=[] out of my for loop, not sure why it was there - I am getting an answer now, but it is mathematically off

  • Changed to dev = sqrt((stdev)/listcount) and it fixed my math error, DSM confirmed this fix as well. Thank you
  • Program is functioning properly now! woot. Thank you everyone for the advise.
anotherfiz
  • 19
  • 1
  • 3

4 Answers4

5

That's a very long winded way of calculating the standard deviation. This is a more pythonic way, and I dare say it's also more readable.

mean = sum(scorenum, 0.0) / len(scorenum)
d = [ (i - mean) ** 2 for i in scorenum]
std_dev = math.sqrt(sum(d) / len(d))
CadentOrange
  • 3,263
  • 1
  • 34
  • 52
0

First, remove the stdev = [], which just does not make any sense (according to your edit you already did this, but it is still in the code).

Second, move the line dev = sqrt(stdev/(listcount-1)) out of the for loop (decrease the level of indentation). This should be done only once after the terms have been added up. Edit: Also fix the parentheses, as pointed out by @DSM.

tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • I will try moving it out of the loop, because I understand what you are saying, but it appears to be working now within the loop. thank you – anotherfiz Oct 05 '12 at 16:54
  • @anotherfiz It works because you overwrite the value from the previous iteration each time. Still, if I had to judge on your assignment I would at least put a big questionmark next to that line. ;-) – tobias_k Oct 05 '12 at 18:57
0

The mathematical error in your code is here:

        dev = sqrt((stdev)/listcount-1)

You want either dev = sqrt(stdev/listcount) or dev = sqrt(stdev/(listcount-1)), depending on your d.o.f. preference. After I fix this, your (modified) code seems to work.

DSM
  • 342,061
  • 65
  • 592
  • 494
0

Another answer proposes a more pythonic way of doing, but I propose here a correction. It is not as efficient, but the classical algorithm is more understandable for a beginner.

Say scorenum is the array storing data from which you need and STD.

import math
average=0.0
for ii in scorenum: # iterate the data array, it can contain float
    sum+=ii
average/=float(len(scorenum)) # number of data=array length

# now, compute an estimator of std=sqrt(variance/n), where variance=sum((xi-xavg)**2)
std=0.0
for ii in scorenum:
    std+=(ii-average)**2
std=math.sqrt(std/float(len(scorenum))) # if you prefer n-1: std/float(len(scorenum)-1)

print "average=",average," std=",std

Comments: - you can iterate any kind of array - you must import math library - operators like += and /= are here for fancyness. They are equivalent to sum=sum+ii, average=average/....

Bruno von Paris
  • 882
  • 1
  • 7
  • 26