Shape Rule
Rotating row
Row i prints i..max_num, then wraps with i-1..1 — exactly max_num digits per row.

The rotating number pattern prints 12345, then 23451, then 34521, … — each row starts at i and wraps back to 1 — a natural follow-up after Program 38’s decreasing-width triangle. This tutorial covers forward and wrap-around inner loops, row rotation, nested loops, a live preview, worked Python examples, edge cases, and complexity.
Rotating row
Row i prints i..max_num, then wraps with i-1..1 — exactly max_num digits per row.
i = 1..max_num
for i in range(1, max_num + 1): — one rotating row per iteration.
i..max_num
for j in range(i, max_num + 1): — prints the increasing forward part of the row.
i-1..1
for k in range(i - 1, 0, -1): — completes the row with wrap-around digits.
3–9 rows
Pick a row count and draw the rotating number pattern in the browser.
Complexity
Each row prints max_num digits — total digits = n².
A rotating number pattern prints a circular-shift sequence on each row: 12345, then 23451, then 34521, and so on. With max_num = 5, each row starts at the row number and wraps back to 1.
In Python you use two inner loops per row: print print(j, end="") from i up to max_num, then print print(k, end="") from k = i - 1 down to 1, then print().
It combines forward and wrap-around inner loops to build rotation — a step after Program 38’s continuous decreasing triangle.
Forward segment.
Wrap segment.
Per row.
Follow Program 38; continue to Program 40 next.
In short: outer i = 1..max_num, forward j = i..max_num, wrap k = i-1..1, then print().
Given max_num = 5, print a rotating number pattern: for each row i, print ascending i..max_num then wrap with i-1..1.
# max_num = 5
# 12345
# 23451
# 34521
# 45321
# 54321 | Item | Type | Description |
|---|---|---|
max_num | int | Pattern width — highest digit and number of rotating lines. |
i | int | Outer loop — current row (1 to max_num). |
j | int | Forward loop — ascending from i to max_num. |
k | int | Wrap loop — descending from i - 1 to 1. |
for i from 1 to max_num:
for j from i to max_num: print j
for k from i-1 down to 1: print k
print newline | Approach | Idea | Best for |
|---|---|---|
| Fixed max_num | 12345, 23451, … | Learning and interviews |
| User input | int(input()) | Configurable pattern size |
| Compact trace | max_num = 3 on paper first | Debugging loop bounds |
| Goal | Pattern |
|---|---|
| Outer loop | for i in range(1, max_num + 1): |
| Forward segment | for j in range(i, max_num + 1): print(j, end="") |
| Wrap segment | for k in range(i - 1, 0, -1): print(k, end="") |
| End the row | print() |
| User input | max_num = int(input("Enter the maximum number: ")) |
Same rotating number pattern — different ways to emit each row.
same lineClassic nested-loop approach — prints each digit without a newline
whole rowBuild the row string first, then print once per line
wrapDescending wrap segment from i-1 down to 1
loops firstMaster the two inner loops before the join shortcut
Reach for this pattern when teaching forward and wrap-around inner loops, circular rotation, and sequence design.
Natural follow-up — replaces decreasing-width rows with rotating sequences built from forward and wrap loops.
Practice forward then wrap loops to build circular-shift sequences on each row.
Combine loops with input() and validation for flexible row counts.
Compare Program 38 (decreasing) and Program 40 (alternating 1/0) next.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one small program that locks in dual inner loops, wrap-around logic, and O(n²) thinking.
Choose a row count between 3 and 9 and draw the rotating number pattern in the browser.
Three complete Python programs — fixed width, user input, and a smaller trace demo. Click View Output to reveal sample console results.
Print five rows of the rotating number pattern with forward and wrap-around inner loops.
max_num = 5Hard-coded width — ideal for first demos and screenshots.
max_num = 5
for i in range(1, max_num + 1):
for j in range(i, max_num + 1):
print(j, end="")
for k in range(i - 1, 0, -1):
print(k, end="")
print() When i = 3, the forward loop prints 3 4 5, the wrap loop prints 2 1 — output 34521. When i = 1, only the forward loop runs — output 12345.
Read the maximum number with input() instead of hard-coding 5.
Read max_num with int(input()) (wrap in try/except ValueError in real apps).
max_num = int(input("Enter the maximum number: "))
for i in range(1, max_num + 1):
for j in range(i, max_num + 1):
print(j, end="")
for k in range(i - 1, 0, -1):
print(k, end="")
print() Same rotating core as Example 1; only max_num comes from user input instead of being hard-coded as 5. Non-numeric input raises ValueError with bare int(input()) — use try/except for safer labs.
Run with max_num = 3 to trace every row on paper before scaling up.
max_num = 3Same forward and wrap loops with a smaller width for quick tracing.
max_num = 3
for i in range(1, max_num + 1):
for j in range(i, max_num + 1):
print(j, end="")
for k in range(i - 1, 0, -1):
print(k, end="")
print() Only max_num changes from 5 to 3 — the two inner loops stay identical. Trace i = 1, 2, 3 on paper to see how each row rotates the sequence.
No imports needed for fixed width; use input() when reading. Set max_num = 5.
for i in range(1, max_num + 1): — ascending outer loop; one rotating row per iteration.
for j in range(i, max_num + 1): — prints i, i+1, ..., max_num.
for k in range(i - 1, 0, -1): — prints i-1, i-2, ..., 1.
print() ends the row after both inner loops finish.
Each row prints exactly max_num digits — total digits = n²; O(n²) time.
max_num = 5Trace each outer-loop value of i, forward and wrap segments, and full row output.
i | Forward (i..max_num) | Wrap (i-1..1) | Row output |
|---|---|---|---|
1 | 1, 2, 3, 4, 5 | — | 12345 |
2 | 2, 3, 4, 5 | 1 | 23451 |
3 | 3, 4, 5 | 2, 1 | 34521 |
4 | 4, 5 | 3, 2, 1 | 45321 |
5 | 5 | 4, 3, 2, 1 | 54321 |
Each row prints exactly max_num digits — total digits = n × n = n².
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Forward then wrap loops show how two segments build one fixed-width row.
Example: swap forward and wrap loops and watch the rotation break.
Foundation for rotation-based patterns and circular-shift sequences.
Example: compare with Program 38 and Program 40.
Practice concatenated digit output with end="" between prints.
Example: add a space after each digit for a spaced rotation variant.
Swap digits for letters once the two-loop structure works.
Example: print chr(ord('A') + j - 1) for an A..E rotation pattern.
Square totals make O(n²) concrete for beginners.
Example: count printed digits for n = 5 → 25.
Pair the pattern with try/except and positive-width checks.
Example: reject max_num <= 0 and re-prompt.
Pro Tip: think of each row as two concatenated sequences — an ascending prefix and a descending suffix. That split makes many rotation patterns easier.
Why this pattern earns a permanent spot in beginner Python courses.
Wrong bounds show up immediately as broken or short rows.
Only nested loops and print — no arrays or math libraries.
Switch to cyclic ascending wrap, letters, or spaced output with small edits.
Streaming output needs no storage beyond loop counters.
Pro Tip: learn the two-loop version first; treat "".join(str(x) for x in ...) as a polish shortcut afterward.
Small habits that keep rotating number-pattern code clean.
Use max_num for width and keep i/j/k for row/forward/wrap loops.
Avoid crashes when the user types letters instead of a number.
Only call print() after both inner loops finish the row.
Smaller width makes forward and wrap segments easy to verify on paper.
Every row should print exactly max_num digits — a quick sanity check.
Pro Tip: if rows have different lengths, you almost certainly mixed up the wrap loop range.
Mistakes that commonly break rotating number patterns.
Each digit lands on its own line — you get a column, not a rotating row.
→ Use print(j, end="") for digits; print() only after both inner loops.
range(1, i) prints ascending wrap; range(i, 0, -1) includes i twice.
→ For this shape, keep range(i - 1, 0, -1).
Omitting print() glues every digit onto one endless line.
→ Always end the row after both inner loops.
Letters or empty input raise ValueError with bare int(input()).
→ Catch ValueError and re-prompt on failure.
Changing only the variable but not loop bounds breaks generalization.
→ Use max_num in both range(1, max_num + 1) and range(i, max_num + 1).
Check these inputs before calling the solution done.
Output is just 1 on one line — wrap loop does not run.
Outer loop never runs — print nothing or show a message.
max_num < 0Treat as invalid; re-prompt instead of silent empty output.
Output grows as n² characters — fine for labs, noisy for huge n.
Bare int(input()) raises ValueError — use try/except first.
Use range(1, i) instead of descending wrap for a pure cycle.
Try these variations to lock in the pattern.
range(i - 1, 0, -1) with range(1, i)try/except until max_num >= 1n² — hence O(n²) time.print(x, end="") stays on the line; print() advances — mix them carefully.max_num > 0 for interactive programs; max_num = 1 should print a single 1.i = 1.Quick Takeaway: forward loop prints i..max_num, wrap loop prints i-1..1, then break the line — that is the whole pattern.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–2) | O(max_num²) | O(1) |
| Compact demo (Example 3) | O(max_num²) | O(1) |
The rotating number pattern is a compact dual-loop exercise with lasting payoff: forward and wrap segments, fixed row width, and O(n²) intuition. Master the classic two-inner-loop version, then optionally try cyclic or spaced variants.
Practice the three examples above, then continue to Program 40 for the alternating 1/0 triangle pattern.
Row i prints i..max_num then i-1..1 — keep end="" for digits and print() for the break.
print(j, end="") for digits and print() after each rowmax_num ≥ 1 for interactive programsint(input()) in try/except ValueErrorprint() inside the inner digit loopsrange(i, 0, -1) when you meant range(i - 1, 0, -1)max_num = 1 edge casePrint the pattern the beginner-friendly way.
i..max_num then i-1..1
Definitionrange(i, max_num + 1)
Coderange(i - 1, 0, -1)
Codemax_num digits per row
ShapeO(n²) time
AnalysisEach row starts at i, prints i..max_num, then wraps with i-1..1. Row i always prints exactly max_num digits — total digits = n².
Move on to the alternating 1/0 triangle pattern in the Python number-pattern series.
12 people found this page helpful