# For loops in Learn Python the hardway

Sorry if this seems dumb to you but I'm having problems with LPTH's exercise 33

http://www.learnpythonthehardway.org/book/ex33.html

Zed asks us to: re-write that exercise to use for-loops and range instead. and Do you need the incrementor in the middle anymore? What happens if you do not get rid of it?

I did this:

``numbers = []def NumbersLoop(x):"""This function will loop as long as x is less than the limit,at the same time it will print the numbers list"""limit = int(input('Limit: '))increment = int(input('Increment: '))for i in (x, limit):print('At the top x is : {}'.format(x))numbers.append(x)x += incrementprint('Numbers now: ', numbers)print('At the bottom x is {}'.format(x))NumbersLoop(1)print('The numbers: ')for num in numbers:print(num)``

But I don't understand why it only loops until

3. Also is it possible to get rid of the incrementor in the middle? I see no way to do it...

You've got a few things wrong with that code, firstly:

``````for i in (x, limit):
``````

You are missing the `range` call, and `x` is actually the start point, it is not changed by the range call.

Next:

``````print('At the top x is : {}'.format(x))
numbers.append(x)

x += increment
``````

`x` is not affected by the `range` call, or the loop. The thing you want to be using is `i`, which is the number that the range is currently at.

Also, the `range` function takes the following arguments:

``````range(start, stop, increment)
``````

You also don't need an to increment `x`, try the following with various arguments:

``````start = 0
stop = 10
inc = 2
for i in range(start, stop, inc):
print(i)
``````

If you ever have any problem in python, the first thing you should do is go to the Python Documentation You will almost always find the answer you want.

``````for i in (x, limit):
``````

This means "run the loop twice: once with `i = x`, and once with `i = limit`".

Look at the assignment specification again. It says:

re-write that exercise to use for-loops and `range` instead.

`range` is a function. You are not currently using it anywhere. You should be using it here.

`range` conceptually creates a range of numbers. This means that you can then loop `for i in` those numbers. For details, you should read the documentation for that function.

is it possible to get rid of the incrementor in the middle? I see no way to do it...

Get the `range` call working first, and then try it.

This one was a good learning experiment; it causes the student to stretch for the answer while keeping it in reach. After extra credit step 5, this is where I ended up:

``````#!/usr/bin/env python
# -*- coding: utf-8 -*-

# FUNCTIONS
def genNos(noMin, noMax, noIncrement):
"""Returns numbers 0 through i in an array"""
numbers = []
for myNum in range(noMin, noMax, noIncrement):
# print "At the top noMin is %d" % noMin
numbers.append(myNum)
# print "Numbers now: ", numbers
# print "At the bottom noMin is %d" % noMin
return numbers

# MAIN PROGRAM
print "The numbers: "
myVal = genNos(7, 21, 2)
print "%r" % myVal

for num in myVal:
print num
``````

Extra Credit:

Convert this while-loop to a function that you can call:

1. Function: genNos
2. Replace 6 in the test (i < 6) with a variable.
3. NOTE: initializing i outside of the function no longer works; move 'i = 0' to function.

Now use this function to rewrite the script to try different numbers:

1. Replace numbers with variables
2. Pass ranges to the function arguments.
3. NOTE: This works as long as the min is less than the max and the max is greater than/equal to noMin+(2*noIncrement).

Add another variable to the function arguments that you can pass in that lets you change the + 1 on line 8 so you can change how much it increments by

1. ADD: `noIncrement` (number by which you increment the count) to function arguments, pass a third value to the function.

Rewrite the script again to use this function to see what effect that has.

1. I did this to test everything above; it works to this point.

Now, write it to use for-loops and range instead. Do you need the incrementor in the middle anymore? What happens if you do not get rid of it?

1. OK, use for with range(); the range function will take all of our arguments - no problem.

NOTES: I never use 'i' or 'x' to represent variables in a loop, except for maybe unit testing; you can't do a search/replace in vim unless you use unique names; EG: :%s/myNo/MyVal/g; but this would be true of any program's search and replace.

Also, it seems like a `for-loop` is of greater cost to the compiler than a `while-loop`. In the context of causing a student to reach, this is a good experiment. I wouldn't use in real program however. Long-live the while loop!

I realize this is an old question, but I would like to add something, because I just finished this problem.

What the OP might have been thinking(had he used range) is something like this:

``````numbers = []

def NumbersLoop(x):
limit = int(input('Limit: '))
increment = int(input('Increment: '))

for i in range(x, limit):
numbers.append(i) #The i would be the newly incremented x on next iteration. != True

x += increment
``````

This code does not work properly.

The reason is that while you may be expecting the newly incremented `x+= increment` to change the start point of the range on the next iteration, thus making `i` jump up by the incremented amount it does not .

The `x` that the range function uses is basically set in stone from when you first call it, so even if you changed the value to

``````x = 50
``````

The next number that `i` takes on will be the next step towards the limit range based on the original x.

Maybe this will save the next person some time. You use `range(start, end, increment)` .