1.2.19 · D4Introduction to Programming (Python)

Exercises — `range()` — start, stop, step

2,899 words13 min readBack to topic

Two symbols we reuse everywhere below (defined once, so nothing is unearned):

  • means round up — the smallest whole number that is not below . Example: , . We round up because even a tiny leftover distance to stop still fits one more term before we cross the wall.
  • is a half-open interval: the square bracket [ means include the left end, the round bracket ) means exclude the right end. That single round bracket is the whole personality of range().
Figure — `range()` — start, stop, step

Level 1 — Recognition

Recall Solution

WHAT: Single-argument form → start = 0, step = 1, stop = 6. Terms: . Keep while : . Output: [0, 1, 2, 3, 4, 5]. Count: . This is the golden identity len(range(n)) == n.

Recall Solution

WHAT: Two-argument form → step = 1, start = 3, stop = 8. Terms: . Include while , i.e. , so . Output: [3, 4, 5, 6, 7]. Note the wall at 8 is never landed on. Count: .

Recall Solution

type(r) is <class 'range'>not a list. A range is a lazy immutable sequence: it stores only start, stop, step and computes any element on demand. But it supports indexing like a sequence: r[2] = a_2 = 0 + 2\cdot 1 = 2. So r[2] is 2.


Level 2 — Application

Recall Solution

Terms: : . Next is , so stop. Output: [2, 6, 10, 14, 18]. Count: ✓.

Recall Solution

WHY negative step: to descend — each hop goes left on the number line (the mirror image of the mint-dot figure above). WHY the test flips to : when we walk leftward, "we haven't crossed the stop wall yet" means "we are still strictly above stop." So the moment a term drops to or below stop, we halt. This is the descending case proved in the box above — same ceiling formula, flipped inequality. Terms: : . Next is , so stop. Output: [20, 17, 14, 11, 8, 5]. Count: ✓. Interval view: this is the half-open interval read downward20 is included, 4 is the excluded left-wall we descend toward but never land on.

Recall Solution

Because stop is excluded, to make 100 appear we must aim one past it: range(1, 101). Check: last term ✓; ✗. Count .

Recall Solution

range(1, 6) yields 1, 2, 3, 4, 5. Sum . It prints 15. (This is an arithmetic sum; see also for loops for the iteration mechanics.)


Level 3 — Analysis

Recall Solution

Count first (the point of the formula): . First: . Last: . Indeed and ✓. So the range is 7, 12, 17, 22, 27, 32, 37, 42, 47 — nine numbers.

Recall Solution

(a) empty []. (b) , then empty (going up but start already above stop). (c) empty (going down but start below stop; the descending test fails immediately since ). (d) 7 elements: 9, 8, 7, 6, 5, 4, 3. Not empty. The pattern: a range is non-empty exactly when the sign of step matches the direction from start to stop — which is precisely when the ceiling fraction is positive and the max(0, …) guard does nothing.

Recall Solution

len(r): . r[3]: use the term rule directly — . Ranges support O(1) indexing precisely because they never store the numbers; they recompute each time. This mirrors Indexing and slicing.


Level 4 — Synthesis

Recall Solution

start = first term = 3. step = gap between consecutive terms = . stop = must exclude the term after the last: the last term is 23, and the next would-be term is . So we need stop big enough to keep 23 but small enough to reject 28. The valid window is (any stop here yields the identical list). What "shortest" means here: since every valid stop gives the same output, "shortest" refers to the range(...) call whose stop literal is the smallest number of characters / smallest value. Among the minimal valid stop is 24 — the smallest integer strictly above the last term 23. Choosing 24 also makes the intent clearest ("stop just past 23"), whereas 28 accidentally equals the next term and invites the reader to wonder if it should have appeared. Call: range(3, 24, 5). Check count ✓.

Recall Solution

(a) range(5, 0, -1) → terms (stop 0 excluded). ✓ (b) list(reversed(range(1, 6)))range(1,6) is 1,2,3,4,5, reversed → 5,4,3,2,1. ✓ Both produce [5, 4, 3, 2, 1]. The negative-step form is usually clearer; reversed() is handy when the forward range already exists.

Recall Solution

Outer count: range(0, 6, 2)0, 2, 4 iterations. Inner count: range(1, 4)1, 2, 3 iterations, and it restarts fully for each outer value. Total: prints.


Level 5 — Mastery

Recall Solution

Multiples of 7 in are 0, 7, 14, …. Model as range(0, 1000, 7). Count: . Check the last term: ✓; ✗. So the largest multiple below 1000 is 994, and there are 143 multiples.

Recall Solution

(a) ValueError: range() arg 3 must not be zero. A zero step would never advance , so it could never reach stop — Python refuses rather than loop forever. (b) TypeError. range accepts integers only; 0.5 is a float. For float steps use numpy.arange or linspace. (c) Negative start is perfectly legal (only step = 0 and floats are banned). , include while : [-3, -2, -1, 0, 1, 2]. Count .

Recall Solution

Same term rule: both have step = 1, so for both — identical terms in identical order. Same count: both give .

  • If : , sequence a, a+1, …, b-1.
  • If : , so , sequence is empty [] — the max(0, …) handles the degenerate case for both. Since term rule and count coincide in every case, the two calls are identical. (The one-argument default is just this with a = 0.)

Connections

  • for loops — every exercise here is a loop driver in disguise.
  • Lists and list()list(range(...)) materialises the lazy sequence.
  • Indexing and slicingr[k] uses the same term rule .
  • Arithmetic sequences — a range is a discrete arithmetic progression.
  • numpy.arange / linspace — reach for these the moment you need float steps (L5.2b).
  • enumerate() — when you need index and value together.