1

I can't seem to figure out why my averages in the code below are wrong when I use a mix of positive and negative numbers. any help is greatly appreciated, thanks in advance.

my_num = []


while True:
    n = input("Enter a number (-9999 to end):")

    if n == '-9999':
        break               # if user enters -9999 it will come out of loop

    my_num.append(int(n))   # adding the numbers with append function

avg = sum(my_num)/len(my_num)   #using sum and len function to determine averages

avgpos = sum([ x for x in my_num if x>=0 ])/len(my_num)

avgneg = sum([ x for x in my_num if x<0 ])/len(my_num)


print("the list of all numbers entered are:")
print(my_num)

print("The dictionary with averages is:")

my_dict = {'AvgPositive': avgpos, 'AvgNonPos': avgneg, 'AvgAllNum': avg}

print(my_dict)    
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
qaguy
  • 39
  • 4

4 Answers4

3

Your averages are wrong because your denominators are wrong for calculating the partial averages

avgpos = sum([ x for x in my_num if x>=0 ])/len(my_num)

avgneg = sum([ x for x in my_num if x<0 ])/len(my_num)

In the above, you are taking the correct sum, but the incorrect length.

Instead, use the appropriate lengths

pos = [ x for x in my_num if x>=0 ]
neg = [ x for x in my_num if x<0 ]

avgpos = sum(pos)/len(pos) if len(pos) else None
avgneg = sum(neg)/len(neg) if len(neg) else None

Note that I am using the ternary operator above, because otherwise the above code may raise ZeroDivisionError if either of the lists pos or neg is empty (i.e., the cases when all numbers entered are positive, and when all numbers entered are negative).

Community
  • 1
  • 1
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
1

Here is the issue:

avgpos = sum([ x for x in my_num if x>=0 ])/len(my_num)

avgneg = sum([ x for x in my_num if x<0 ])/len(my_num)

You're summing the set of positive/negative numbers but using the set of all numbers to do so!

Try:

avgpos = sum([ x for x in my_num if x>=0 ])/len([ x for x in my_num if x>=0 ])

avgneg = sum([ x for x in my_num if x<0 ])/len([ x for x in my_num if x<0 ])
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
JBux
  • 1,394
  • 8
  • 17
0

Let me introduce you to the filter and lambda:

pos = filter(lambda x: x>=0 and x,my_num)
neg = filter(lambda x: x<0 and x,my_num)
avgpos = sum(pos)/len(pos)
avgneg = sum(neg)/len(neg)
Hackaholic
  • 19,069
  • 5
  • 54
  • 72
0

i think the easiest way is with numpy:

import numpy as np

a = np.array(my_num)
avg = a.mean()
avg_pos = a[a > 0].mean()
avg_neg = a[a < 0].mean()
acushner
  • 9,595
  • 1
  • 34
  • 34