Reputation: 151
I've been looking at my code for a while and I'm just stuck as to where I messed up, so maybe one of you can help.
What my for loop should do is: It iterates through a long list of times. It averages the first 100 times, and sets that as a value. This part works. What it should do next is add one to t (the value i'm using for my for loop) so it will average the 1st and 101st time together, if this average is less than .1 seconds faster, add the t value to a list of x values, then, set that value as the new average to beat. If it's not .1 lower, we increase t and try again until it works.
Here's my code, and I'll walk you through what it means to make it more readable
for t in times:
t = int(t)
sumset = sum(times[t:t + 100])
avgset = (int(round(float(sumset/100), 3) * 10)) /10
if t + 100 > len(times):
break
elif (avgset) <= firstavg - .1:
avglist.append(avgset)
firstavg -= .1
xlist.append(t)
print(t)
print("avgset is "+str(avgset))
print("should decrease by .1 " + str(math.ceil(firstavg * 10) / 10))
tlist.append(t)
t += 1
else:
t += 1
I'll explain it here.
for t in times:
t = int(t)
sumset = sum(times[t:t + 100])
avgset = (int(round(float(sumset/100), 3) * 10)) /10
for each value in the my list called times, we take the value and make sure it's an int, I do this because earlier I was getting an indexing problem saying it wasn't an int. Sumset gets the sum of the first 100 times that we need, and avgset turns it into an average, multiplies it by 10, uses int to chop off the decimal, and divide by ten to get a tenth value.
Ex
12.34 * 10 = 123.4, int(123.4) = 123, 123 / 10 is 12.3.
Then here
if t + 100 > len(times):
break
We make sure there are 100 values left to iterate through, if not we end the loop.
On this big chunk
elif (avgset) <= firstavg - .1:
avglist.append(avgset)
firstavg -= .1
xlist.append(t)
print(t)
print("avgset is "+str(avgset))
print("should decrease by .1 " + str(math.ceil(firstavg * 10) / 10))
tlist.append(t)
t += 1
We check: if the set is <= to the first average - .1, we append that set of averages to a list of lowering averages. Then we decrease the first avg, and append the value of t to a list that will make up our x-values. What it should do, is produce me a list of x values where each value corresponds to a decrease of .1 from the original average (t: t +100) where t is 0. And we get a y-list (which would be avglist) which is each decrease of .1. I'm not sure where I messed up, so if someone could point me in the right direction I would really appreciate it, thanks!
Upvotes: 0
Views: 1203
Reputation: 722
In my opinion, there are multiple things to address in your code:
1) The main and most important is that you are mixing up the elements in your list (floats) with their indices, i.e. their positions in the list. What you want is to iterate over the indices, not over the elements themselves. What I mean is that given the list:
my_list = [5.67, 4.23, 7.88, 9.5]
the indices of [5.67, 4.23, 7.88, 9.5]
are respectively: 0,1,2,3
. Python wants to have integer number to iterate because it interpretes these numbers as the position of the elements in the list, regardless of their value. And positions, obviously, always need to be integers, i.e. you are either the 4th or the 5th, not the 4.23th. However, this DOES NOT mean that the values of the elements themselves need to be integers. For accounting for this difference there is the python builtin function enumerate()
:
>>> for index, value in enumerate([5.67, 4.23, 7.88, 9.5]):
... print (index, '->', value)
...
0 -> 5.67
1 -> 4.23
2 -> 7.88
3 -> 9.5
>>>
this is the reason for which you needed to convert your values (not the indices) to integers, and make the trick of multiplying and dividing by 10 for not losing the 0.1 resolution that you use to compare. You can forget about all that.
2) You do not really need to check in each iteration wheter there are still 100 elements left in the list or not. It suffices to iterate until the -100th element:
for index, time in enumerate(times[:-100]):
and it will automatically stop at the -100th. However, when you do it, remember you want to use always index
as the iterator variable, not time
. Moreover, in another for
loop you might use in some other case, if you need to check whether some condition is fulfilled to process the current element, and if not skip to the next one, you should use continue
instead of break
:
for index, time in enumerate(times):
if index+100 > len(times):
continue
continue
gets you out of the if
statement and brings you to the for
loop, ready to iterate with the next element. break
will break the for
loop and stop the iteration.
3) At the end of each of your iterations you have a
elif (...):
...
t += 1
else:
t += 1
this is wrong in many ways:
3.1) first because you are inside an iterator, and t
refers to the variable you are using for iterating. You do not need at all to tell the iterator to sum 1 to the iteration variable at the end of each iteration. Doing that is its one job. It knows.
3.2) Supposing that would be any other control variable inside the loop that you indeed need to manually increase by one, you are repeating code lines. You basically get the same effect if you remove the else
clause and remove the indent of the last line of the elif
clause:
elif (...):
...
t += 1
so the algorithm will fall into t +=1
regardles of whether the elif
clause is satisfied or not.
3.3) This is related to the above bullet 1): In your particular case and since you are wrongly using t
to iterate (as discussed above), by doing t += 1
you are modifying the list you iterate over, i.e. you are altering the input data.
Taking all this into account, one possible way to roughly implement your code could be:
import numpy as np
times = 100*np.random.rand(150)
list_of_avgs = [np.sum(times[:100])/100.]
for index, element in enumerate(times[:-100]):
avg = np.sum(times[index:index+100])/100.
if avg + 0.1 <= list_of_avgs[-1]:
list_of_avgs.append(avg)
else:
continue
print (list_of_avgs)
which results into (input data is radomly generated):
[49.779866192794358, 49.594673775689778, 49.4409179407875,
49.304759324340424, 49.106580355542434, 48.651419303532919,
48.505888846346672, 47.834645246733295, 47.300679740055074,
46.956253292222293, 46.598627928361239, 46.427709019922297]
Cheers and good luck!
D.
Upvotes: 1