An alphabet right-angled triangle prints a left-aligned staircase of letters: row i is the first i letters of the alphabet.
Remember
Rule: on row i, print A through the i-th letter
A
AB
ABC
ABCD
ABCDE ← 5 rows
In Python you solve it with two nested for loops: the outer loop picks the row, the inner loop prints letters with chr, then a bare print() moves to the next line. Once this clicks, reverse triangles and other letter patterns become much easier.
Approach
How to Solve It
Two ways to emit the same shape — start with nested ord/chr loops, then optionally shorten with slicing.
Method
Idea
Best for
Nested loops
Outer = rows; inner prints letters via chr
Learning, interviews, exams
letters[:i]
Take the first i letters of A–Z in one call
Shorter demos once loops click
Pseudocode
Pseudocode
start = code of 'A'
for i from 1 to rows:
for code from start to start + i - 1:
print chr(code) (no newline)
print newline
Cheat sheet
Goal
Pattern
Walk each row
for i in range(1, rows + 1):
Start code
start = ord('A')
Print i letters
for code in range(start, start + i): print(chr(code), end="")
Print letters without a newline, then end the row once.
Try it
Live Preview
Change the row count and the alphabet triangle updates instantly — including the triangular letter total.
Whole numbers from 1 to 10. Tap a chip or type a value — the preview redraws as you go.
Live result5 rows · last E · 15 letters
A
AB
ABC
ABCD
ABCDE
Trace
Worked Walkthrough — rows = 4
Trace each outer-loop value of i and the letters printed on that row.
i
Codes
Printed row
Letters
1
A
A
1
2
A..B
AB
2
3
A..C
ABC
3
4
A..D
ABCD
4
Total letter characters: 1 + 2 + 3 + 4 = 10 = 4×5/2. That triangular sum is why time is O(n²).
Code
Python Programs
Three complete programs: fixed rows, input(), and a slice shortcut. Use View Output to reveal sample results.
Example 1 — Fixed rows = 5
Hard-coded height — ideal for first demos and screenshots.
Python
rows = 5
start = ord('A')
for i in range(1, rows + 1):
for code in range(start, start + i):
print(chr(code), end="")
print()
Output
A
AB
ABC
ABCD
ABCDE
How It Works
1. Set height and start code.rows = 5; start is the code point of A.
2. Outer loop picks the row.i runs from 1 to rows.
3. Inner loop prints letters.code runs from start through start + i - 1, so row i gets exactly i letters.
4. Break the line. Bare print() after the inner loop starts the next row.
When i = 1 you get A; when i = 3 you get ABC; and so on up to ABCDE.
Example 2 — User Input Version
Read the row count at runtime with input(). Validate with int and clamp to 26 for A–Z demos.
Python
raw = input("Enter the number of rows: ").strip()
start = ord('A')
try:
rows = int(raw)
except ValueError:
print("Please enter a whole number of rows >= 1.")
else:
if rows < 1:
print("Please enter a whole number of rows >= 1.")
else:
if rows > 26:
rows = 26
for i in range(1, rows + 1):
for code in range(start, start + i):
print(chr(code), end="")
print()
Output (when user enters 4)
Enter the number of rows: 4
A
AB
ABC
ABCD
How It Works
1. Prompt and parse. Ask for a row count, then convert with int(...) inside try/except ValueError.
2. Validate and clamp. Reject non-positive values; cap at 26 so codes stay in A–Z.
3. Same nested-loop core. Only the source of rows changes — the print logic matches Example 1.
Example 3 — letters[:i]
Take the first i letters of A–Z in one call — same shape, no explicit inner letter loop.
Python
rows = 5
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i in range(1, rows + 1):
print(letters[:i])
Output
A
AB
ABC
ABCD
ABCDE
How It Works
1. One outer loop. Still walk i from 1 to rows.
2. Build the row.letters[:i] returns the first i characters of the alphabet string.
3. Print and advance.print prints that string and ends the line.
Learn the two-loop version first (Examples 1–2) so you can explain both bounds; treat this as a polish shortcut afterward.
Edge Cases & Pitfalls
Check these before calling the solution done.
print early
Column of letters
If bare print() (or default print(chr(code))) is inside the inner loop, each letter lands on its own line. Use end="" for letters; call print() only after the inner loop.
Wrong bound
Rectangle / wrong length
Inner range must be start through start + i - 1. A fixed end always prints the same width.
rows = 1
Single A
Output is just A on one line — a good sanity check.
rows > 26
Beyond Z
Clamp or reject — codes leave A–Z. Keep rows in 1…26 for alphabet demos.
Bad input
Catch ValueError
Bare int(input()) raises on letters — wrap in try/except ValueError or check isdigit() first.
off-by-one
range end is exclusive
Use range(1, rows + 1) and range(start, start + i) — forgetting the + 1 / exclusive end shortens the triangle.
Analysis
Time and Space Complexity
Program
Time
Extra space
Nested loops (Examples 1–2)
O(n²)
O(1)
letters[:i] (Example 3)
O(n²)
O(n) per temporary row string
Total letters printed = 1 + 2 + … + n = n(n+1)/2, which is still quadratic in n.
Remember
Key Takeaways
Rule: row i prints letters A through the i-th letter.
Two loops: outer = rows; inner prints with chr and end="".
Break the row: call bare print() only after the inner loop.
Complexity:O(n²) time from the triangular letter count.
One line: for each row i, print A through the i-th letter with end="", then print().
Frequently Asked Questions
The outer loop picks the row length. The inner loop walks letter codes from ord('A') through that many characters, so row 1 is A, row 2 is AB, row 3 is ABC, and so on.
Each row is a fresh sequence from A to the current end letter. If you kept advancing a single char across rows, you would get a different pattern (not this right-angled alphabet triangle).
print(ch, end="") stays on the same line. print() ends the current line. Letters use end=""; the row break uses print() after the inner loop.
Shrink the end letter each row — for example walk the outer loop from rows down to 1, or print letters[:i] with a decreasing i. See Alphabet Pattern Program 2.
O(n²) where n is the number of rows. Total printed characters equal 1+2+…+n = n(n+1)/2.
Yes. Keep a string of A–Z and print letters[:i] for row length i. Nested ord/chr loops are better for learning; slicing is a handy shortcut later.
Use a try/except ValueError around int(input()), or check raw.isdigit() before converting, then clamp rows between 1 and 26 so bad input does not walk past Z.
Letter codes can produce characters beyond Z. Clamp to 26 for A–Z demos, or define a clear wrap/error policy.
🤔
Did you know?
Row i prints letters from A through the i-th letter (A, AB, ABC, …). Total letters for n rows is the triangular number n(n+1)/2 — the same count that makes this pattern O(n²).