-2

I'm having some trouble getting a piece of software to run. What I am required to do is take an input of numbers and tell if they are increasing or decreasing, starting with an interval of one, meaning that if the list was [13,15,17,15,18] the first set would be [13,15], then [15,17], and finally [15,18]. The first interval section works perfectly fine, but when I increase a to 2 to try and increase the step of the range function it outputs the same groups as when a is 1. The correct outputs when a = 2 should be [13,17],[17,18],[15,15]. If I copy paste it and replace the variable a with two, the program does run however it gives me an incorrect number of increases and decreases. I'm sure I'm overlooking something simple, but I've stared at this problem so long that it's gotten freaky. I didn't include all my code, but prod_list is just a list of integers that are all greater than zero.

a = 1
for i in range(0,len(prod_list),a):
    while(i-1 < 0):
        i +=1
    while(i > len(prod_list)):
        i -= 1
    if(prev != (prod_list[i-1],prod_list[i])):
        if((prod_list[i-1] - prod_list[i]) > 0):
            decr += 1
        elif((prod_list[i-1] - prod_list[i]) < 0):
            incr += 1
        elif((prod_list[i-1] == prod_list[i]) < 0):
            same += 1
        print(prod_list[i-1],prod_list[i])
        prev = (prod_list[i-1],prod_list[i])
        a += 1
Loic Mouchard
  • 1,121
  • 7
  • 22
  • 2
    Possible duplicate of [Changing step in Python loop](https://stackoverflow.com/questions/46179757/changing-step-in-python-loop) – Mark Oct 13 '19 at 02:08
  • 1
    You're doing this in a fairly non-pythonic way. `range()` is a function, it's evaluated once at the top of the loop. Try looking at something like: `print([(a, b) for (a, b) in zip(prod_list, l[i:])])` in your loop. – Mark Oct 13 '19 at 02:25

1 Answers1

1

Python's for is a for-each in an iterator. It does not work like C's int i=0; i<x; i+=a style for loops. If you want it to work like that in Python, use while instead, with the initial value above the while, and the i+=a update inside the loop.

If the iterator happens to be a range() object, you do get integers out of it, but the iterator itself has already been constructed when the loop starts. Updating a after you've already initialized the range() object is not going to change its state. In fact, after constructing the range, you could even delete the a variable altogether. It's not going to change anything. a is a reference to an immutable int object. Once range() has it, changing what a points to does not affect the int that the range object already has.

Using explicit integer indexes when you could have used values from the iterator directly is considered unpythonic, but when translating textbook algorithms, sometimes that's where you have to start.

It is possible to send parameters back to a generator function, and this will be the value of the yield expression. range() is not designed to do that (and its step attribute is readonly) but one could implement a generator that does, and uses it to change the step size. But the obvious implementation of that would again use a while loop internally, so I'm not sure how much that helps.

gilch
  • 10,813
  • 1
  • 23
  • 28