Here is the basic use of `range()`

:

In [1]:

```
for i in range(5):
print(i)
```

We can output `1...5`

instead using

In [2]:

```
for i in range(5):
print(i+1)
```

But that's not the clearest thing. Instead, `range`

lets us specify where we want to start counting:

In [3]:

```
for i in range(1, 6):
print(i)
```

`for i in range(a, b)`

assigns `a, a+1, a+2, ..., b-1`

to the variable `i`

. We go up to, but not including, `b`

.

Suppose now that we want to print `2, 4, 6, 8`

-- go up by increments of 2 instead of increments of 1. We *could* do it like this:

In [4]:

```
for i in range(1, 4):
print(2*i)
```

`range()`

actually allows us to specify the increment/step size:

In [5]:

```
for i in range(2, 7, 2):
print(i)
```

In general, `range(a, b, step)`

assigns
a
a + step
a + 2*step
a + 3*step
...
(up to the last possible number < b)

to the variable `i`

.

Note that the following also produces 2, 4, 6:

In [6]:

```
for i in range(2, 8, 2):
print(i)
```

That's because the upper limit, which should not be reached, was `8`

, so we didn't print `8`

as well.

We can also go backwards, by specifying a negative step size:

In [7]:

```
for i in range(5, 2, -1):
print(i)
```

We went down from 5 to 2, without including 2. The following is also possible:

In [8]:

```
for i in range(10, 1, -3):
print(i)
```

How could we accomplish the same kind of thing with the basic use of `range`

? Let's count from 4 down to 0.

In [9]:

```
n = 5
for i in range(n):
print(n-1-i)
```

Note that the following will note print anything:

In [10]:

```
for i in range(5, 2):
print(i)
```

In [11]:

```
for i in range(1, 10, -1):
print(i)
```

That's because, if we're using `range(a, b, step)`

, if `step`

positive, we need `a < b`

, and if step size is negative, we need `a > b`

in order for the range to not be empty.

Recall also that

In [12]:

```
for i in range(5, 5):
print(i)
```

prints nothing.