Mixed Rule
Descend then ascend
Every row prints exactly rows letters: prefix down to A, suffix up from B.

Each row stitches together a descending prefix from the row start letter down to A and an ascending suffix from B up to a shrinking end letter: ABCDE, BABCD, CBABC, DCBAB, EDCBA for five rows. Two inner loops per row teach opposite directions on the same line. Compare with Program 26 (cyclic rotation). Includes a live preview, worked Python examples, edge cases, and complexity.
Descend then ascend
Every row prints exactly rows letters: prefix down to A, suffix up from B.
start → A
for code in range(start, base - 1, -1): prints the descending part.
B → end
for code in range(base + 1, end + 1): fills the ascending tail — skips A.
Letter codes
base = ord('A'), top = base + rows - 1, start = base + r, end = top - r.
1–26 rows
Pick a row count and draw the mixed alphabet pattern in the browser instantly.
Complexity
n rows × n letters per row = n² total characters; extra memory stays O(1).
A mixed alphabet pattern prints fixed-width rows where each line begins with a descending run from the row start letter down to A, then continues with an ascending run from B to a shrinking end letter. Row 1 is pure ascending; the last row is pure descending.
In Python you solve it with an outer loop over row index r, two inner loops (descending prefix then ascending suffix), and ord()/chr() — or build each row in a list and print(''.join(row)) for clarity.
It teaches opposite loop directions on one row — descending then ascending — and the subtle rule of skipping A in the suffix so the join point is not duplicated. The same split appears in palindrome builders and symmetric string patterns.
Every row prints exactly rows letters — prefix plus suffix always sum to rows.
end = top - r shrinks each row so the suffix gets shorter as the prefix grows.
Suffix starts at B (base + 1) — never duplicate A at the join.
Program 26 wraps cyclically — BCDEA. Here row 2 is BABCD, not BCDEA.
In short: set base = ord('A') and top = base + rows - 1, loop r from 0 to rows - 1, compute start = base + r and end = top - r, print descending prefix, ascending suffix from B, then print() for the newline.
Given a positive integer rows, print rows lines of exactly rows uppercase letters each. Row 1 descends from A only in the prefix then ascends to the top; each next row starts one letter later and ends one letter earlier.
# First 5 rows
# ABCDE
# BABCD
# CBABC
# DCBAB
# 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: descending prefix + ascending suffix — no spaces between letters. |
base = ord('A')
top = base + rows - 1
for r from 0 to rows-1:
start = base + r
end = top - r
print letters start..A (descending)
print letters B..end (ascending)
print newline | Approach | Idea | Best for |
|---|---|---|
| Two inner loops | Descend range(start, base-1, -1) + ascend range(base+1, end+1) | Learning ord/chr and opposite loop directions |
| Join list | Build row in a list, print(''.join(row)) | Clearer debugging and row inspection |
| Program 26 contrast | See Program 26 (ABCDE, BCDEA, …) | Cyclic rotation with wrap-around |
| Goal | Pattern |
|---|---|
| Bound the alphabet | base = ord('A'); top = base + rows - 1 |
| Outer loop (row index) | for r in range(rows): |
| Row bounds | start = base + r; end = top - r |
| Prefix (descending) | for code in range(start, base - 1, -1): print(chr(code), end="") |
| Suffix (ascending) | for code in range(base + 1, end + 1): print(chr(code), end="") |
| End the row | print() |
| List join variant | row.append(chr(code)); print(''.join(row)) |
Three ways to think about the same mixed rows — pick based on what you are learning.
range(start, base-1, -1)
start..APrints from the row start letter down to A — row 1 prefix is just A.
range(base+1, end+1)
B..endFills the ascending tail from B — skips A to avoid duplication at the join.
row.append(...)
''.join(row)Collect letters in a list, then print one string — easier to inspect each row while debugging.
forward + wrap
BCDEAProgram 26 wraps cyclically — row 2 is BCDEA, not BABCD.
Reach for mixed prefix/suffix loops when each row combines a descending run with an ascending tail on fixed-width lines.
Program 26 wraps cyclically — BCDEA. This pattern descends then ascends — BABCD.
Practice descending and ascending ranges on the same row before tackling palindromes.
Building rows in a list mirrors real string assembly in larger programs.
Next pattern in the alphabet series builds on symmetric row ideas.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one program that proves you can split a row into a descending prefix and ascending suffix — a pattern used in palindromes and symmetric string builders far beyond alphabet demos.
Choose a row count between 1 and 26 and draw the mixed alphabet pattern in the browser.
Three complete Python programs — fixed five rows with dual inner loops, console input, and a list-join variant for clarity. Click View Output to reveal sample console results.
Print five mixed rows with descending prefix and ascending suffix 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 r in range(rows): # 0..4
start = base + r # A, B, C, D, E
end = top - r # E, D, C, B, A
# Descending prefix: start..A
for code in range(start, base - 1, -1):
print(chr(code), end="")
# Ascending suffix: B..end (skip A)
for code in range(base + 1, end + 1):
print(chr(code), end="")
print() The outer loop walks row index r from 0 to 4. For each row, start = base + r sets the prefix start and end = top - r shrinks the suffix bound. The first inner loop prints descending from start to A; the second prints ascending from B to end. When end is below B, the suffix loop is empty and the row is pure descending — that is how EDCBA appears.
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.
rows = int(input("Enter number of rows (1-26): "))
rows = max(1, min(rows, 26))
base = ord('A')
top = base + rows - 1
for r in range(rows):
start = base + r
end = top - r
for code in range(start, base - 1, -1):
print(chr(code), end="")
for code in range(base + 1, end + 1):
print(chr(code), end="")
print() Same dual-loop core as Example 1; only the row count comes from input. Three rows use letters A–C with width 3 on every line — row 2 is BAC, not cyclic BCA.
Build each row in a list, then print with ''.join(row).
''.join(row) VariantCollect letters in a list for clearer row inspection — same logic, easier debugging.
rows = 5
rows = max(1, min(rows, 26))
base = ord('A')
top = base + rows - 1
for r in range(rows):
start = base + r
end = top - r
row = []
for code in range(start, base - 1, -1):
row.append(chr(code))
for code in range(base + 1, end + 1):
row.append(chr(code))
print(''.join(row)) Each loop appends characters to row instead of printing immediately. ''.join(row) concatenates without spaces — identical output to Examples 1 and 2, but you can inspect row before printing during debugging.
Clamp rows, then set base = ord('A') and top = base + rows - 1 for the alphabet window.
for r in range(rows): walks each row from 0 to rows - 1, computing start and end.
First inner loop prints start down to A; second prints B up to end with print(chr(...), end="").
print() ends the row after both inner loops finish; the outer loop advances r to the next row.
Total characters: n × n = n² — O(n²) time, O(1) extra memory (loop version).
rows = 5Trace each outer-loop value of r and see how the prefix and suffix combine into each printed row.
r | start | end | Prefix | Suffix | Full row |
|---|---|---|---|---|---|
| 0 | 'A' | 'E' | A | BCDE | ABCDE |
| 1 | 'B' | 'D' | BA | BCD | BABCD |
| 2 | 'C' | 'C' | CBA | BC | CBABC |
| 3 | 'D' | 'B' | DCBA | B | DCBAB |
| 4 | 'E' | 'A' | EDCBA | (empty) | EDCBA |
Total character prints: 5 × 5 = 25 = n² for n = 5 rows.
Where this tiny pattern (and its prefix/suffix split) shows up beyond the homework prompt.
Program 26 wraps cyclically — BCDEA. This descends then ascends — BABCD.
Example: side-by-side ABCDE/BCDEA vs ABCDE/BABCD.
Reinforce descending range(start, base-1, -1) and ascending range(base+1, end+1) on the same row.
Example: trace prefix and suffix for row 2 (r=1) on paper before coding.
Descend then ascend on one line mirrors half-palindrome construction.
Example: row 3 prefix CBA + suffix BC forms CBABC — almost symmetric.
Swap letters for digits 1..n with the same prefix + suffix logic.
Example: rows=3 gives 123, 212, 321.
Square totals make O(n²) concrete for beginners.
Example: 5 rows → 25 characters printed.
Classic nested-loop question that tests prefix/suffix bounds and the skip-A rule.
Example: explain why row 5 is EDCBA without running code.
Pro Tip: say “descend from start to A, ascend from B to end” before coding — that story prevents duplicating A or skipping the descending loop.
Why this pattern earns a spot after the rotation pattern from Program 26.
Two inner loops run descending then ascending on the same row — a core loop skill.
Every line has the same length — prefix and suffix always sum to rows.
Direct print version for learning; list-join version for clearer debugging.
Streaming output needs no storage beyond loop counters (join variant uses O(n) per row).
Pro Tip: when end is below B, the suffix loop is empty and the row is pure descending — that is how EDCBA appears on the last line.
Small habits that keep mixed alphabet pattern code clean.
Use start = base + r and end = top - r — keep r and code 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.
range(base + 1, end + 1) — never start the suffix at A or you duplicate the join letter.
Trace ABC, BAC, CBA on paper before coding larger demos.
Pro Tip: if rows look like Program 26 (BCDEA, CDEBA), you likely used forward + wrap instead of descend + ascend.
Mistakes that commonly break mixed alphabet patterns.
Starting the suffix at A gives BAA, CABA — double A at the join.
→ Suffix must start at B: for code in range(base + 1, end + 1):.
Using end = top or end = top + r keeps the suffix too long — rows exceed width rows.
→ Use end = top - r so prefix and suffix lengths always sum to rows.
Only the ascending suffix prints BCD, CD, D — rows are too short and miss the descending prefix.
→ Always run the prefix loop first: for code in range(start, base - 1, -1):.
Non-numeric input raises ValueError with bare int(input()).
→ Wrap int(input()) in try/except ValueError and validate range.
Program 26 wraps cyclically — row 2 is BCDEA, not BABCD.
→ Here prefix descends and suffix ascends — no cyclic wrap between the two parts.
Check these inputs before calling the solution done.
Output is just A on one line — prefix is A, suffix loop empty because end is below B.
Treat as invalid; re-prompt instead of silent empty output.
26 rows of width 26 — last row is pure descending from Z down to A.
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.
row.append and ''.join(row)n rows is n² — each row prints n letters.range(start, base - 1, -1). Suffix loop: range(base + 1, end + 1).''.join(row) after building in a list is equivalent to the direct-print version — use whichever fits your lesson.Quick Takeaway: outer loop sets r, compute start and end, print descending prefix, ascending suffix from B, then break the line — that is the whole mixed alphabet pattern.
| Program | Time | Extra space |
|---|---|---|
| Two inner loops (Examples 1–2) | O(rows²) | O(1) |
| Join variant (Example 3) | O(rows²) | O(rows) for the row list per line |
The mixed alphabet pattern teaches opposite loop directions on one row — descending prefix from the start letter to A, then ascending suffix from B to end. Master the direct-print version, then try the list-join variant for clearer debugging.
Practice the three examples above, then continue to Program 31 in the alphabet pattern series.
Set start and end each row, run prefix then suffix loops, clamp rows to 26, and compare with Program 26 to see the difference from cyclic rotation.
base = ord('A'), top = base + rows - 1start = base + r and end = top - r each rowB (base + 1) — never duplicate Aprint(chr(...), end="") in loops; print() after bothA — duplicates the join letterend bound — rows will be too long or too shortprint() inside the letter loopsPrint the mixed rows the beginner-friendly way.
Descend + ascend
Definitionstart down to A
CodeB up to end
Code''.join(row)
AltO(n²) time
AnalysisEach row uses two passes: a descending prefix from the row start letter down to A, then an ascending suffix from B up to end = top - r. Row 1 is pure ascending ABCDE; the last row is pure descending EDCBA.
Next up: the Alphabet X pattern — build on symmetric row ideas from this tutorial.
12 people found this page helpful