0

Here's my for loop that does stuff:

for x in range(0, 100):
    currentRate10 = srall10[x].current_rate
    startRate10 = srall10[x].start_rate
    lessons10 = srall10[x].sr_completed
    if currentRate10 is not None and startRate10 is not None:
        gain10 = currentRate10 - startRate10
    else:
        gain10 = 0
    rateavg = gain10 / lessons10

rateavg returns 1.42. Seems accurate to me. However, when I put a variable in place of the 100 OR anything above 100, I get 0 returned back. So if I change 100 to 101, rateavg returns 0. If I put in a variable that contains 143, I still get 0.

srall10 contains a list

srall10 = DBSession.query(Summary).filter(Summary.sid == 6933).filter(
    Summary.sr_completed.between(1, 10)).all()

There are 143 entries, this was found by the exact same query except with count() at the end instead of all()

Any ideas?

9
  • Why not loop over srall10 directly instead of using range() then? for sr in srall:. But it's your actual values that might cause the problem. Is this Python 2 or Python 3? Commented Apr 10, 2014 at 13:11
  • 1
    Is it possible that current_rate or start_rate of srall10 is None? If so, rateavg will equal 0. Also, unless there is more for your loop to do, this is only giving you the value for the very last position, so there is no need to loop here. Commented Apr 10, 2014 at 13:12
  • Can't. Get a TypeError('list indices must be integers, not Summary',) This is python 2 Commented Apr 10, 2014 at 13:12
  • You want to calculate the average star rate of all records? Commented Apr 10, 2014 at 13:12
  • Yes, I want to calculate the average rate for all records. Commented Apr 10, 2014 at 13:14

2 Answers 2

2

You get rateavg as the result of the last item. and range(0, 100) will not iterate over all elements. Instead iterate directly over the list.

l = []
for s in srall10:
    if s.current_rate is not None and s.start_rate is not None:
        gain10 = s.current_rate - s.start_rate
    else:
        gain10 = 0
    l.append(gain10 / lessons10)  # average if each item

# total average
total_average = sum(l) / len(l)
Sign up to request clarification or add additional context in comments.

5 Comments

Returning correctly. Going to check the math now to be sure that's correct. Why is range() not the way to go here?
Because you don't go over the whole list. And what if you have less items than 100? You will get IndexError.
Indeed, which was why I was originally using a variable, range(0, srcount10) which returned 1 through 143. I originally thought it was a variable issue so I tried hardcoding in the numbers, but noticed an issue whenever it was above 100, even though there were more than 100 to loop through
why use the range when you can iterate over the list? And if you did use the count, that was ok. Only that you were calculation individually the averages. The count implied another SQL to the database.
I didn't think I could lol, kept getting that TypeError mentioned in the third comment on my question. Was going about it the wrong way.
0

Python will always return an integer value for the division of two integers, so when a division operation in Python returns 0 and you were expecting a number, the first thing to check is whether both the dividend and the divisor are integers. If so, and if the dividend is less than the divisor, then you'll get 0 instead of a float between 0 and 1.

You can avoid this with:

 rateavg = (gain10 * 1.0) / lessons10

I don't know if this is your problem since there's not enough information in the question to determine the type of the values in your lists, but it's often my problem when division unexpectedly returns 0.

1 Comment

Still getting 0. This was my thought previously so I changed gain to gain = 1 in my else

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.