Shape Rule
Palindrome row
Row i prints i down to 2, then 1 up to i — a symmetric sequence.

The palindrome number triangle prints 1, then 212, then 32123, … — a natural follow-up after Program 36’s right-aligned decreasing triangle. This tutorial covers descending and ascending inner loops, row symmetry, nested loops, a live preview, worked Python examples, edge cases, and complexity.
Palindrome row
Row i prints i down to 2, then 1 up to i — a symmetric sequence.
i = 1..rows
for i in range(1, rows + 1): — one palindrome row per iteration.
i..2
for j in range(i, 1, -1): — prints the descending left side of the palindrome.
1..i
for j in range(1, i + 1): — completes the palindrome with ascending digits.
3–7 rows
Pick a row count and draw the palindrome number triangle in the browser.
Complexity
Digits per row = 2i - 1 — total digits = n².
A palindrome number triangle prints a symmetric sequence on each row: 1, then 212, then 32123, and so on. With rows = 5, each row reads the same forward and backward.
In Python you use two inner loops per row: print j from i down to 2, then from 1 up to i, then print().
It combines descending and ascending inner loops to build symmetry — a step after Program 36’s right-aligned decreasing pattern.
Left half.
Right half.
Digits per row.
Follow Program 36; continue to Program 38 next.
In short: outer i = 1..rows, desc j = i..2, asc j = 1..i, then print().
Given rows = 5, print a palindrome number triangle: for each row i, print descending i..2 then ascending 1..i.
# rows = 5
# 1
# 212
# 32123
# 4321234
# 543212345 | Item | Type | Description |
|---|---|---|
rows | int | Triangle height — number of palindrome lines to print. |
i | int | Outer loop — current row (1 to rows). |
j | int | Inner loop — descending (i..2) or ascending (1..i). |
for i from 1 to rows:
for j from i down to 2: print j
for j from 1 to i: print j
print newline | Approach | Idea | Best for |
|---|---|---|
| Fixed rows | 1, 212, … | Learning and interviews |
| User-input rows | int(input(...)) | Configurable triangle size |
| Compact trace | rows = 3 on paper first | Debugging loop bounds |
| Goal | Pattern |
|---|---|
| Outer loop | for i in range(1, rows + 1): |
| Left half (desc) | for j in range(i, 1, -1): print(j, end="") |
| Right half (asc) | for j in range(1, i + 1): print(j, end="") |
| End the row | print() |
| User input | int(input()) |
Same palindrome triangle — different ways to control the row count.
i = 1..rowsOne palindrome row per iteration
j = i..2Descending digits
j = 1..iAscending digits
2i - 1Digits per row
Reach for this pattern when teaching symmetry, dual inner loops, and palindrome construction in nested loops.
Natural follow-up — replaces right alignment with symmetric palindrome rows built from two inner loops.
Practice descending then ascending loops to build mirrored sequences on each row.
Combine loops with input() and try/except ValueError for flexible row counts.
Compare Program 36 (decreasing) and Program 38 (next in series) 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, formatted output, and O(n²) thinking.
Choose a row count between 3 and 7 and draw the palindrome number triangle in the browser.
Three complete Python programs — fixed rows, user input, and a smaller trace demo. Click View Output to reveal sample console results.
Print five rows of the palindrome number triangle with descending and ascending inner loops.
rows = 5Hard-coded row count — ideal for first demos and screenshots.
rows = 5
for i in range(1, rows + 1):
for j in range(i, 1, -1):
print(j, end="")
for j in range(1, i + 1):
print(j, end="")
print() When i = 3, the first loop prints 3 2, the second prints 1 2 3 — output 32123. When i = 1, only the ascending loop runs — output 1.
Read the row count with input() and int() instead of hard-coding 5.
Read rows with input() and int() (wrap in try/except ValueError in real apps).
rows = int(input("Enter rows: "))
if rows < 1:
raise SystemExit
for i in range(1, rows + 1):
for j in range(i, 1, -1):
print(j, end="")
for j in range(1, i + 1):
print(j, end="")
print() Same palindrome core as Example 1; only rows 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 rows = 3 to trace every row on paper before scaling up.
rows = 3Same descending and ascending loops with a smaller row count for quick tracing.
rows = 3
for i in range(1, rows + 1):
for j in range(i, 1, -1):
print(j, end="")
for j in range(1, i + 1):
print(j, end="")
print() Only rows changes from 5 to 3 — the two inner loops stay identical. Trace i = 1, 2, 3 on paper to see how each row grows symmetrically.
No imports needed for fixed rows; use input() when reading. Set loop variables i, j with rows = 5.
for i in range(1, rows + 1): — ascending outer loop; one palindrome row per iteration.
for j in range(i, 1, -1): — prints i, i-1, ..., 2.
for j in range(1, i + 1): — completes the palindrome: 1, 2, ..., i.
print() ends the row after both inner loops finish.
Digits per row = 2i - 1 — total digits = n²; O(n²) time.
rows = 5Trace each outer-loop value of i, left and right halves, and full row output.
i | Left half (i..2) | Right half (1..i) | Row output |
|---|---|---|---|
1 | — | 1 | 1 |
2 | 2 | 1, 2 | 212 |
3 | 3, 2 | 1, 2, 3 | 32123 |
4 | 4, 3, 2 | 1, 2, 3, 4 | 4321234 |
5 | 5, 4, 3, 2 | 1, 2, 3, 4, 5 | 543212345 |
Digits per row = 2i - 1 — total digits = 1 + 3 + 5 + ... + (2n-1) = n².
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Clearest visual proof that outer and inner bounds interact.
Example: swap the ascending and descending loops and watch the palindrome break.
Foundation for symmetry-based patterns and mirrored sequences.
Example: compare with Program 36 (decreasing) and Program 38 next.
Practice concatenated digit output without spaces between numbers.
Example: add j + " " between digits for a spaced palindrome variant.
Add leading spaces for center alignment once the two-loop structure works.
Example: print rows - i spaces before the descending loop.
Triangular totals make O(n²) concrete for beginners.
Example: count digits for rows = 5 — total is 1+3+5+7+9 = 25 = 5².
Pair the pattern with try/except ValueError and positive-row validation.
Example: reject rows <= 0 and re-prompt.
Pro Tip: when an interviewer asks for patterns, explain the outer/inner roles first — then write the loops. The story matters as much as the code.
Why this pattern earns a permanent spot in beginner Python courses.
Wrong bounds show up immediately as a broken staircase.
Only loops and console output — no arrays or math libraries.
Invert, center, hollow, or change the fill character with small edits.
Streaming output needs no storage beyond loop counters.
Pro Tip: trace i and both inner loops on paper for rows = 3 before coding — watch how each row grows symmetrically.
Small habits that keep number-pattern code clean.
Descending loop (j > 1) must run before ascending loop (j <= i).
try/except ValueErrorAvoid undefined behavior when the user types letters instead of a number.
Only call print() after both inner loops finish the row.
Write left half (i..2) and right half (1..i) for each row before coding.
Trace i = 1..3 on paper before coding the full rows = 5 demo.
Pro Tip: if the output is a vertical list of single digits per line, you almost certainly put print() inside an inner loop.
Mistakes that commonly break palindrome number triangles.
Each digit lands on its own line — you get a column, not a triangle.
→ Use print(j, end=""); print() only after both inner loops.
Running ascending before descending breaks the palindrome symmetry.
→ Always print descending j = i..2 first, then ascending j = 1..i.
Using j >= 1 in the first loop duplicates the center digit.
→ Keep for j in range(i, 1, -1): — stop at 2, let the ascending loop print 1.
Starting the descending loop at j >= 1 prints 1 twice in the middle.
→ Descending stops at j > 1; ascending starts at j = 1.
int(input())Letters or empty input raise ValueError with bare int(input()).
→ Catch ValueError and re-prompt on failure.
Check these inputs before calling the solution done.
Output is just 1 — only the ascending loop runs.
Outer loop never runs when rows < 1 — print nothing or show a message.
rows < 1Treat as invalid; re-prompt instead of silent empty output.
Two rows: 1 and 212.
Bare int(input()) raises ValueError on bad input — use try/except first.
Total digits = rows² — grows quadratically with rows.
Try these variations to lock in the pattern.
i has 2i - 1 digitsi..2, right half = 1..irows >= 1 after reading inputi = 1..rows. Descending j = i..2, then ascending j = 1..i — row i prints 2i - 1 digits.print(j, end="") stays on the line; print() advances — mix them carefully.rows >= 1 for interactive programs; rows = 1 prints a single 1.1 — compare with Program 36 where each row restarts from rows.Quick Takeaway: outer i = 1..rows, desc j = i..2, asc j = 1..i, then print().
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–3) | O(n²) | O(1) |
| Smaller demo (Example 3) | O(n²) | O(1) |
The palindrome number triangle is a compact lesson in symmetry: print descending i..2, then ascending 1..i, and end each row with print(). Master the fixed-rows version, then try user input and a smaller trace demo.
Practice the three examples above, then continue to Program 38 for the next pattern in the series.
Descending loop must stop at j > 1 — validate rows when reading from the console.
for i in range(1, rows + 1): in the outer loopfor j in range(i, 1, -1): print(j, end="")for j in range(1, i + 1): print(j, end="")int(input()) in try/except ValueErrorprint() inside an inner loopj >= 1 in the descending loop (duplicates 1)input() input in user-facing demosrows = 1 edge casePrint the pattern the beginner-friendly way.
Left half
DefinitionRight half
CodeDigits/row
Codeprint() after both inner loops
O(n²) time
AnalysisEach row is a palindrome: print i down to 2, then 1 up to i. Row i prints 2i - 1 digits — total digits across all rows = n².
Move on to the next pattern in the Python number-pattern series.
12 people found this page helpful