Rotation Rule
Shift start, fixed width
Every row prints exactly rows letters; the first letter moves one step forward each row.

Each row is a fixed width of rows letters, but the start letter shifts forward every line: ABCDE, BCDEA, CDEBA, DECBA, EDCBA for five rows. Two inner loops per row — forward to the top letter, then wrap down to A — teach cyclic rotation without string tricks. Compare with Program 1 (growing rows, no wrap). Includes a live preview, worked Python examples, edge cases, and complexity.
Shift start, fixed width
Every row prints exactly rows letters; the first letter moves one step forward each row.
Start → top
for j in range(i, top + 1): prints from the row start up to the top letter.
Previous → A
for k in range(i - 1, base - 1, -1): fills remaining slots wrapping back to A.
Letter codes
base = ord('A') and top = base + rows - 1 bound the alphabet window.
1–26 rows
Pick a row count and draw the rotation pattern in the browser instantly.
Complexity
n rows × n letters per row = n² total characters; extra memory stays O(1).
An alphabet rotation pattern prints fixed-width rows where each line starts one letter later than the row above. After reaching the top letter, the row wraps back down to A to fill the remaining slots — a cyclic shift you may know from string rotation.
In Python you solve it with an outer loop over start letters, two inner loops (forward then wrap), and ord()/chr() — or a one-line slice shortcut once the idea clicks.
It teaches cyclic wrap-around with loops before you reach string slicing. The same rotation idea appears in circular buffers, Caesar ciphers, and queue rotation — all from two tiny inner loops.
Every row prints exactly rows letters — unlike Program 1’s growing triangle.
Outer loop walks start letters from A through the top letter.
Second inner loop prints from the previous letter down to A.
Program 1 restarts at A each row with no wrap — A, AB, ABC.
In short: set base = ord('A') and top = base + rows - 1, loop i from A to the top letter, print forward with one inner loop, wrap down with a second, then print() for the newline.
Given a positive integer rows, print rows lines of exactly rows uppercase letters each. Row 1 starts at A and runs forward to the top letter; each next row starts one letter later and wraps back to A after the top.
# First 5 rows
# ABCDE
# BCDEA
# CDEBA
# DECBA
# EDCBA | Item | Type | Description |
|---|---|---|
rows | int | Number of rows and width of each row. Clamp to 1–26 for A–Z demos. |
| Printed output | text | Fixed-width uppercase rows with cyclic wrap — no spaces between letters. |
base = ord('A')
top = base + rows - 1
for i from base to top:
print letters i..top (forward)
print letters (i-1)..base (wrap, descending)
print newline | Approach | Idea | Best for |
|---|---|---|
| Two inner loops | Forward range(i, top+1) + wrap range(i-1, base-1, -1) | Learning ord/chr and loop bounds |
| Slice rotation | letters[i:] + letters[:i][::-1] | Compact production code |
| Program 1 style | See Program 1 (A, AB, ABC, …) | Growing rows, no wrap-around |
| Goal | Pattern |
|---|---|
| Bound the alphabet | base = ord('A'); top = base + rows - 1 |
| Outer loop (start letter) | for i in range(base, top + 1): |
| Forward part | for j in range(i, top + 1): print(chr(j), end="") |
| Wrap part | for k in range(i - 1, base - 1, -1): print(chr(k), end="") |
| End the row | print() |
| Slice shortcut | print(letters[i:] + letters[:i][::-1]) |
Three ways to build the same rotation rows — pick based on what you are learning.
range(i, top+1)
i..EPrints from the row start letter up to the top — ABCDE starts with all five forward.
range(i-1, base-1, -1)
..AFills remaining slots wrapping down — BCDEA adds A after BCDE.
letters[i:]
+ letters[:i]One expression per row — same output, less loop bookkeeping.
reset A
no wrapProgram 1 grows rows from A — A, AB, ABC — with no cyclic fill.
Reach for rotation loops when each row is fixed width but the starting token shifts cyclically.
Program 1 grows from A with no wrap — this keeps width fixed and rotates the start.
Practice forward and descending ranges on the same row before using slices.
The slice form letters[i:] + letters[:i][::-1] matches the forward + reversed-prefix loops.
Next pattern in the alphabet series builds on cyclic ideas.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one program that proves you can split a cyclic row into a forward segment and a wrap segment — a pattern used far beyond alphabet demos.
Choose a row count between 1 and 26 and draw the alphabet rotation pattern in the browser.
Three complete Python programs — fixed five rows with two inner loops, console input, and a slice rotation shortcut. Click View Output to reveal sample console results.
Print five rotation rows with forward and wrap inner loops.
rows = 5Hard-coded height — ideal for first demos and screenshots.
rows = 5
rows = max(1, min(rows, 26))
base = ord('A')
top = base + rows - 1
for i in range(base, top + 1): # A..E
for j in range(i, top + 1): # i..E (increasing)
print(chr(j), end="")
for k in range(i - 1, base - 1, -1): # (i-1)..A (decreasing)
print(chr(k), end="")
print() The outer loop sets each row’s start letter i from A through E. The first inner loop prints forward to the top; the second wraps from the previous letter down to A. When i is the top letter, the wrap loop alone produces the reversed row EDCBA.
Let the user choose the height at runtime.
Read rows and clamp to 1–26. Wrap int(input()) in try/except ValueError in real apps.
try:
rows = int(input("Enter number of rows (1-26): "))
except ValueError:
print("Please enter a whole number.")
raise SystemExit(1)
rows = max(1, min(rows, 26))
base = ord('A')
top = base + rows - 1
for i in range(base, top + 1):
for j in range(i, top + 1):
print(chr(j), end="")
for k in range(i - 1, base - 1, -1):
print(chr(k), end="")
print() Same two-loop core as Example 1; only the outer bound and clamp change. Three rows use letters A–C with width 3 on every line.
Rotate a string slice instead of two inner loops.
letters[i:] + letters[:i][::-1] VariantBuild each row as forward suffix plus reversed prefix — compact and matches the two-loop output.
rows = 5
rows = max(1, min(rows, 26))
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[:rows]
for i in range(rows):
print(letters[i:] + letters[:i][::-1]) letters[i:] is the forward run; letters[:i][::-1] is the wrap in reverse. Row index i matches the outer loop start — identical output to the ord/chr version.
Clamp rows, then set base = ord('A') and top = base + rows - 1 for the alphabet window.
for i in range(base, top + 1): walks each row’s first letter from A through the top.
First inner loop prints i through top; second prints i-1 down to A with print(chr(...), end="").
print() ends the row after both inner loops finish; the outer loop advances i to the next start letter.
Total characters: n × n = n² — O(n²) time, O(1) extra memory (loop version).
rows = 5Trace each outer-loop value of i and see how the forward and wrap parts combine into each printed row.
i (start) | Forward part | Wrap part | Printed row |
|---|---|---|---|
'A' | ABCDE | (none) | ABCDE |
'B' | BCDE | A | BCDEA |
'C' | CDE | BA | CDEBA |
'D' | DE | CBA | DECBA |
'E' | E | DCBA | EDCBA |
Total character prints: 5 × 5 = 25 = n² for n = 5 rows.
Where this tiny pattern (and its forward/wrap split) shows up beyond the homework prompt.
Program 1 grows from A — A, AB, ABC. Rotation keeps width fixed and shifts the start.
Example: side-by-side A/AB/ABC vs ABCDE/BCDEA/CDEBA.
Reinforce range(i - 1, base - 1, -1) with immediate visual feedback.
Example: trace wrap part for row 3 (C) on paper before coding.
The slice form is the same left-rotation used in cipher and buffer problems.
Example: letters[2:] + letters[:2] for ABCDE gives CDEBA.
Swap letters for digits 1..n with the same forward + wrap logic.
Example: rows=3 gives 123, 231, 312.
Square totals make O(n²) concrete for beginners.
Example: 5 rows → 25 characters printed.
Classic nested-loop question that tests range bounds and wrap logic.
Example: explain why row 5 is EDCBA without running code.
Pro Tip: say “forward to top, wrap down to A” before coding — that story prevents skipping the second inner loop or mixing up range bounds.
Why this pattern earns a spot after the basic alphabet triangle from Program 1.
Two inner loops make cyclic fill explicit before you reach string slicing.
Every line has the same length — easier to verify output than shrinking triangles.
Loop version for learning; slice version for compact production code.
Streaming output needs no storage beyond loop counters and code.
Pro Tip: when the start letter equals the top letter, the forward loop prints one character and the wrap loop prints the rest in reverse — that is how EDCBA appears.
Small habits that keep alphabet rotation pattern code clean.
Use base and top for letter bounds — keep i, j, k for loop variables.
int(input()) in try/exceptAvoid crashes when the user types letters instead of a number.
rows = max(1, min(rows, 26)) keeps demos inside A–Z.
For row start i, wrap runs from i - 1 down to base (stop before base - 1).
Trace ABC, BCA, CAB on paper before coding larger demos.
Pro Tip: if rows look like Program 1 (A, AB, ABC), you likely restarted from A each row instead of shifting the start letter.
Mistakes that commonly break alphabet rotation patterns.
Only the forward loop prints BCDE, CDE, DE — rows are too short after row 1.
→ Always run the second loop: for k in range(i - 1, base - 1, -1):.
range(base, i) walks upward and duplicates forward letters.
→ Wrap must descend: range(i - 1, base - 1, -1).
Each letter lands on its own line — you get a column, not rotation rows.
→ Use print(chr(...), end="") in both loops; print() only after both finish.
Non-numeric input raises ValueError with bare int(input()).
→ Wrap int(input()) in try/except ValueError and validate range.
Program 1 restarts at A and grows width — no cyclic wrap on any row.
→ Here every row has width rows and the start letter shifts forward.
Check these inputs before calling the solution done.
Output is just A on one line — forward and wrap loops both empty except one forward char.
Treat as invalid; re-prompt instead of silent empty output.
26 rows of width 26 — last row is a single Z reversed through A (full reverse).
Clamp to 26 or define a wrap/error policy before printing.
Use try/except ValueError before clamping rows.
Same loops work with base = ord('a') and lowercase output.
Try these variations to lock in the pattern.
letters[i:] + letters[:i][::-1]n rows is n² — each row prints n letters.range(i, top + 1). Wrap loop: range(i - 1, base - 1, -1).letters[i:] + letters[:i][::-1] is equivalent to the two-loop version — use whichever fits your lesson.Quick Takeaway: outer loop shifts the start letter, forward loop runs to the top, wrap loop fills back to A, then break the line — that is the whole rotation pattern.
| Program | Time | Extra space |
|---|---|---|
| Two inner loops (Examples 1–2) | O(rows²) | O(1) |
| Slice variant (Example 3) | O(rows²) | O(rows) for the letters string |
The alphabet rotation pattern teaches cyclic wrap-around with two inner loops per row — forward to the top letter, then down to A. Master the ord/chr version, then try the slice shortcut for the same output in fewer lines.
Practice the three examples above, then continue to Program 27 in the alphabet pattern series.
Set base and top, run forward then wrap loops, clamp rows to 26, and compare with Program 1 to see the difference from growing rows.
base = ord('A') and top = base + rows - 1print(chr(...), end="") in loops; print() after bothprint() inside the letter loopsPrint the rotation rows the beginner-friendly way.
Fixed width, shifted start
Definitioni through top
Codei-1 down to A
Codeletters[i:]+letters[:i][::-1]
AltO(n²) time
AnalysisEach row starts one letter later but still prints rows characters: forward from the start letter to the top, then wrap from the previous letter down to A. Row 1 is ABCDE; row 5 becomes EDCBA when the start reaches the top letter.
Next up: right-aligned alphabet pyramid (A, A B, A B C, …).
12 people found this page helpful