Shape Rule
Current letter down to A
Row 0 prints A, row 1 prints BA, row 2 prints CBA, up to EDCBA for five rows.

The reverse alphabet triangle grows each row by one letter, but every row counts down to A instead of up from it. This tutorial covers the shape rule, descending inner loop, a live preview, algorithm steps, worked Python examples, edge cases, and complexity.
Current letter down to A
Row 0 prints A, row 1 prints BA, row 2 prints CBA, up to EDCBA for five rows.
Rows
for i in range(rows): picks the starting letter for each row (0-based index).
Descending letters
for code in range(base + i, base - 1, -1): prints from the current letter down to A.
Same line / next line
Letters use print(..., end=""); end each row with print().
1–26 rows
Pick a row count and draw the reverse alphabet triangle instantly in the browser.
Complexity
Total letters = n(n+1)/2 — same triangular count as Program 1; extra memory stays O(1).
A reverse alphabet triangle grows by one letter per row, but each line counts down to A instead of up from it. With five rows the console shows A, BA, CBA, DCBA, EDCBA.
In Python you solve it with two nested for loops: the outer loop picks the row index, the inner loop walks letter codes downward with range(..., -1), then print() moves to the next line.
It teaches reverse iteration with range(step=-1) and the exclusive stop at base - 1 — skills you reuse in inverted patterns, pyramids, and more advanced letter shapes.
On row i, print letters from chr(ord('A') + i) down to A.
range(base + i, base - 1, -1) walks codes downward.
print(chr(code), end="") in the inner loop; print() after.
Same outer growth — inner direction flips from ascending to descending.
In short: for each row index i from 0 to rows - 1, print letters from chr(ord('A') + i) down to A with print(chr(code), end=""), then call print().
Given a positive integer rows, print a left-aligned reverse alphabet triangle where row i starts at the i-th letter and counts down to A.
# First 5 rows (conceptual shape)
# A
# BA
# CBA
# DCBA
# EDCBA | Item | Type | Description |
|---|---|---|
rows | int | Number of triangle lines to print (typically ≥ 1). |
| Printed output | text | Left-aligned rows; row i (0-based) has letters from chr(ord('A') + i) down to A. |
for i from 0 to rows - 1:
for code from (A + i) down to A:
print letter (no newline)
print newline | Approach | Idea | Best for |
|---|---|---|
| Nested loops (descending inner) | Outer rows + inner codes down to A | Learning and interviews |
letters[i::-1] | Reverse slice for the whole row | Shorter production-style demos |
| Goal | Pattern |
|---|---|
| Walk each row | for i in range(rows): |
| Print current letter down to A | for code in range(base + i, base - 1, -1): print(chr(code), end="") |
| End the row | print() |
| One-line row shortcut | print(letters[i::-1]) |
| Ascending variant | Inner loop up from A — see Program 1 |
Three ways to emit each row — compare inner-loop direction and the letters[i::-1] shortcut.
A..endrange(base, base + i) — row grows from A upward (AB, ABC)
end..Arange(base + i, base - 1, -1) — row starts at current letter and counts down to A
whole rowReverse slice from index i to start — skip the inner loop entirely
loops firstMaster descending range(..., -1) before the reverse-slice shortcut
Reach for this pattern when teaching descending inner loops or contrasting with Program 1’s ascending rows.
Natural follow-up after Program 1 — same outer growth, inner loop counts down with step -1.
Practice range(base + i, base - 1, -1) with an immediate visual check.
Combine loops with input() for a flexible row count.
Leads to Program 3’s fixed-top rows and Program 5’s decreasing width pattern.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one small program that locks in reverse inner loops, the exclusive base - 1 stop, and O(n²) thinking.
Choose a row count between 1 and 26 and draw the reverse alphabet triangle in the browser.
Three complete Python programs — fixed row count, CLI input, and a letters[i::-1] shortcut. Click View Output to reveal sample console results.
Print five rows with classic nested loops — each row counts down to A.
rows = 5Hard-coded height — ideal for first demos and screenshots.
rows = 5
base = ord('A')
for i in range(rows):
for code in range(base + i, base - 1, -1):
print(chr(code), end="")
print() When i = 0, the inner loop prints A. When i = 2, it prints CBA, and when i = 4 it prints EDCBA. print() after the inner loop starts the next row.
Let the user choose the height at runtime.
Read the row count with input() and convert with int() (wrap in try/except ValueError in real apps).
rows = int(input("Enter the number of rows (max 26): "))
rows = max(1, min(rows, 26))
base = ord('A')
for i in range(rows):
for code in range(base + i, base - 1, -1):
print(chr(code), end="")
print() Same ord/chr core as Example 1; only the source of rows changes. The inner loop still counts down to A on every row. Non-numeric input raises ValueError with bare int(input()) — use try/except for safer labs.
Same shape without an explicit inner letter loop.
letters[i::-1]Reverse-slice from index i to the start of the alphabet string for each row.
rows = 5
rows = max(1, min(rows, 26))
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i in range(rows):
print(letters[i::-1]) letters[i::-1] returns letters from index i down to index 0 — exactly the reverse row shape. Great once you understand the nested-loop idea; keep the two-loop version for exams that ask you to show descending bounds.
Use input() when reading input. Set rows (fixed or from CLI) and base = ord('A').
for i in range(rows): selects the starting letter index for the current line.
for code in range(base + i, base - 1, -1): prints each letter downward with print(chr(code), end="").
print() ends the row so the next outer iteration starts fresh.
Total letters: 1+2+…+n = n(n+1)/2 — O(n²) time, O(1) extra memory.
rows = 5Trace each outer-loop index and see what the descending inner loop prints down to A.
Row index i | Inner code range | Printed row | Letters this row |
|---|---|---|---|
0 | A..A | A | 1 |
1 | B..A | BA | 2 |
2 | C..A | CBA | 3 |
3 | D..A | DCBA | 4 |
4 | E..A | EDCBA | 5 |
Total letter prints: 1 + 2 + 3 + 4 + 5 = 15 = 5×6/2.
Where this reverse triangle (and its descending inner loop) shows up beyond the homework prompt.
Clearest visual proof that range(start, stop, -1) needs an exclusive stop one below the last value.
Example: change stop from base - 1 to base and watch A disappear.
Same growing row width — only inner direction changes from ascending to descending.
Example: side-by-side output of AB vs BA on row 2.
Practice character loops with step -1 and print(..., end="")/print() without complex math.
Example: accidentally use an ascending inner loop and get Program 1’s shape.
Swap to lowercase or digits once the descending letter loop works.
Example: print lowercase edcba with ord('a') as base.
Triangular totals make O(n²) concrete for beginners.
Example: count printed letters for n = 10 → 55.
Pair the pattern with try/except ValueError and positive-row checks.
Example: reject rows <= 0 and re-prompt.
Pro Tip: when an interviewer asks for patterns, explain why the inner stop is base - 1 — that detail separates a working reverse row from a missing A.
Why this reverse triangle earns a spot in beginner Python pattern courses.
Wrong stop values show up immediately — rows missing A or printing extra codes.
Only loops and console output — no arrays or math libraries.
Flip inner direction to recover Program 1; compare with Program 3’s fixed-top rows and Program 5’s shrinking width.
Streaming output needs no storage beyond loop counters.
Pro Tip: learn the nested-loop version first; treat letters[i::-1] as a polish shortcut afterward.
Small habits that keep alphabet-pattern code clean.
Use rows (or n) and keep i/j for row/column — or rename to row/col.
int(input()) in try/exceptAvoid crashes when the user types letters instead of a number.
Only call print() after the inner loop finishes the row.
Prefer ord('A') over hardcoded 65 — clearer intent and easier to switch to lowercase.
Trace rows = 3 on paper — confirm range(base + i, base - 1, -1) includes A.
Pro Tip: if the output is a vertical list of single letters, you almost certainly put print() inside the inner loop.
Mistakes that commonly break reverse alphabet triangle patterns.
Each letter lands on its own line — you get a column, not a triangle.
→ Use print(..., end="") for letters; print() only after the inner loop.
Using base as the stop skips A; using base - 2 may print unwanted characters below A.
→ For this shape, keep range(base + i, base - 1, -1) so A is included.
range(base, base + i) prints Program 1’s shape (AB, not BA).
→ Use step -1 and start at base + i, not at base.
Magic ASCII numbers work but obscure intent and break when switching to lowercase.
→ Always set base = ord('A') and derive codes from base + i.
Non-numeric input raises ValueError with bare int(input()).
→ Wrap in try/except ValueError and validate range.
Omitting print() after the inner loop glues every letter onto one endless line.
→ Always end the row after the inner loop.
Check these inputs before calling the solution done.
Output is just A on one line.
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Output grows as n²/2 characters — fine for labs, noisy for huge n.
int(input()) raises ValueError — validate first.
Same loops work with #, digits, or letters.
Try these variations to lock in the reverse pattern.
rows = 5base = ord('a') with the same logica, ba, cba, …try/except ValueError until rows >= 1letters[i::-1]range(base + i, base - 1, -1) includes A because range stops before base - 1.rows > 0 for interactive programs; rows = 1 should print a single A.Quick Takeaway: outer loop picks the start letter, inner loop counts down to A with step -1, then break the line — that is the whole pattern.
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–2) | O(rows²) | O(1) |
letters[i::-1] (Example 3) | O(rows²) | O(rows) per row string (temporary) |
The reverse alphabet triangle is a focused nested-loop exercise with lasting payoff: descending inner bounds, the exclusive base - 1 stop, and O(n²) intuition. Master the classic two-loop version, then optionally shorten rows with letters[i::-1].
Practice the three examples above, then continue to Program 5 for the decreasing-width pattern (ABCDE down to A).
Row i prints from chr(ord('A') + i) down to A — keep print(..., end="") for letters, print() for the break, and validate row counts when reading input.
range(base + i, base - 1, -1) so every row ends at Abase = ord('A') over hardcoded ASCII valuesrows ≥ 1 and clamp to 26 for A–Z demosrange(base, base + i))base — that skips Aprint() inside the inner letter loop65 instead of ord('A')rows = 1 edge casePrint each row from the current letter down to A.
Row i counts down to A
Definitionrange(rows) picks start
Step -1 down to A
CodeIncludes letter A
BoundsO(n²) time
AnalysisShrink each row from ABCDE down to A — the decreasing alphabet pattern.
12 people found this page helpful