Reverse Ascending Number Triangle in Python

Beginner
⏱️ 8 min read
📚 Updated: Sep 2026
🎯 3 Code Examples
🚀 Live Preview
Nested Loops

What You’ll Learn

Program 6 prints a reverse ascending number triangle: each row adds one digit on the left until the last row shows 1..rows — the mirror companion to Program 5’s growing triangle. This tutorial covers the shape rule, descending outer loop, inner bound i..rows, a live preview, worked Python examples, edge cases, and complexity.

Shape Rule

i..rows per row

Row with outer i = 5 prints 5; row with i = 1 prints 12345 — digits grow from the left.

Outer Loop

i = rows..1

for i in range(rows, 0, -1) — start value moves leftward from the peak digit down to 1.

Inner Loop

j = i..rows

for j in range(i, rows + 1) prints from the current start digit up to rows.

print vs newline

Same line / next line

Digits use print(j, end=""); end each row with print().

Live Preview

rows = 3..9

Pick row count and draw the reverse ascending triangle in the browser.

O(n²)

Complexity

Total prints = 1+2+…+n = n(n+1)/2 — same triangular number as Program 5.

Introduction

A reverse ascending number triangle grows digits from the left: the first row shows only the peak digit, and each next row adds one more number on the left until the last row shows 1..rows. With rows = 5, you get 5, 45, 345, 2345, 12345.

In Python use an outer loop counting down from rows to 1, an inner loop printing j from i to rows, then print() after each row.

Why it matters?

It pairs with Program 5’s ascending triangle — changing the outer direction and inner start teaches how loop bounds control shape.

Key Highlights

Outer down

i = rows..1 — peak row first.

Inner i..rows

Fixed end at rows, start moves left.

vs Program 5

Program 5 outer counts up, inner 1..i; Program 6 outer counts down, inner i..rows.

Series Foundation

Follow Program 5; continue to Program 7 next.

In short: outer i = rows..1, inner j = i..rows, print(j, end="") per digit, then print().

📝 Problem & Approach

Given row count rows = 5, print a reverse ascending number triangle — row outer index i shows digits i..rows.

Python
# rows = 5
//5
//45
//345
//2345
//12345

Inputs & Outputs

ItemTypeDescription
rowsintTriangle height — also the peak digit and inner loop end.
i (outer)intCurrent row start — runs rows down to 1.
j (inner)intPrints i..rows with print(j, end="").
Row widthintRow with outer i prints rows - i + 1 digits.
First rowintSingle digit rows when i = rows.
Last rowstringDigits 1..rows when i = 1.

Minimal workflow

Pseudocode
for i from rows down to 1:
    for j from i to rows:
        print j
    print newline

Approach comparison

ApproachIdeaBest for
Descending outerfor i in range(rows, 0, -1)Peak-first row order
Inner i..rowsStart moves left, end fixed at rowsLeft-growing triangle
User-input rowsint(input())Flexible height
Compact tracerows = 3 on paper firstQuick dry-runs
Spaced outputprint(j, end=" ")Readable columns

⚡ Quick Reference

GoalPattern
Outer loopfor i in range(rows, 0, -1)
Inner loopfor j in range(i, rows + 1): print(j, end="")
End rowprint()
Program 5 contrastProgram 5: outer up, inner 1..i; Program 6: outer down, inner i..rows

📋 Fixed Rows vs User Input vs Compact Trace

Same reverse ascending triangle — three ways to set row count and trace the logic.

Fixed rows
rows = 5

Hard-coded height for demos

User input
int(input())

Read row count from console

Compact trace
rows = 3

Quick dry-run on paper

Outer
i = rows..1

Descending row index

Inner
j = i..rows

Fixed end at rows

Context

When This Pattern Shows Up

Reach for this pattern when teaching descending outer loops, variable inner starts, and comparing shapes with Program 5.

  1. Post Program 5 exercise

    Natural companion to Program 5 — same triangular print count, opposite growth direction.

  2. Loop bound drills

    Changing inner start i while keeping end rows fixed — concrete bound practice.

  3. Interview warm-ups

    Classic nested-loop question — explain outer down, inner i..rows before coding.

  4. Gateway to Program 7

    Compare this left-growing triangle with the next pattern in the series.

  5. Not a UI layout tool

    This is a console teaching pattern — not how you build modern app screens.

Key benefit: one small program that locks in descending outers, variable inner starts, and O(n²) thinking.

🔮 Live Preview

Choose a row count between 3 and 9 and draw the reverse ascending number triangle in the browser.

Try 4, 5, or 7. Max up to 9 in this preview.

Live result
Press "Draw pattern".

Examples Gallery

Three complete Python programs — fixed rows, user input, and a compact trace with rows = 3. Click View Output to reveal sample console results.

📚 Getting Started

Print five rows of the reverse ascending number triangle with nested loops.

Example 1 — Fixed rows = 5

Hard-coded height — ideal for first demos and screenshots.

Python
rows = 5

for i in range(rows, 0, -1):
    for j in range(i, rows + 1):
        print(j, end="")
    print()

How It Works

When i = 5, the inner loop prints 5 only. When i = 1, it prints 12345 — each row adds one more digit on the left. print() after the inner loop starts the next row.

📈 Practical Variant

Let the user choose the height at runtime.

Example 2 — User Input Version

Read rows with int(input()) and validate the result.

Python
try:
    rows = int(input("Enter the number of rows: "))
except ValueError:
    print("Please enter a positive integer.")
else:
    if rows < 1:
        print("Please enter a positive integer.")
    else:
        for i in range(rows, 0, -1):
            for j in range(i, rows + 1):
                print(j, end="")
            print()

How It Works

Same inner-loop core as Example 1; only the source of rows changes from a literal to user input.

⚡ Compact Trace

Use rows = 3 for a quick paper trace before larger demos.

Example 3 — Compact rows = 3

Same loops with a smaller height — easy to dry-run on paper.

Python
rows = 3

for i in range(rows, 0, -1):
    for j in range(i, rows + 1):
        print(j, end="")
    print()

How It Works

Outer i runs 3, 2, 1; inner j prints i..rows each time. Trace this small case before scaling to rows = 5 or more.

🧠 How the Algorithm Prints Rows

1

Set up

Set rows (fixed or from int(input())) before the nested loops.

Setup
2

Outer loop (rows)

for i in range(rows, 0, -1) selects the row start digit, beginning at the peak.

Row
3

Inner loop (digits)

for j in range(i, rows + 1) prints digits i..rows with print(j, end="").

Digits
4

New line

print() ends the row so the next outer iteration starts fresh.

Break
=

Reverse ascending triangle complete

Total digit prints: 1+2+…+n = n(n+1)/2O(n²) time, O(1) extra memory.

🔎 Worked Walkthrough — rows = 5

Trace each outer-loop value of i (counting down) and count how many digits the inner loop prints.

iInner j rangePrinted rowDigits this row
55..551
44..5452
33..53453
22..523454
11..5123455

Total digit prints: 1 + 2 + 3 + 4 + 5 = 15 = 5×6/2.

Use Cases

Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.

1. Teaching Nested Loops

Clearest visual proof that outer and inner bounds interact.

Example: change inner start j = i and watch the left edge move.

2. Pattern Series Base

Foundation for inverted, pyramid, diamond, and hollow variants.

Example: Program 5 grows each row from 1 to i; Program 6 grows from i to rows.

3. Output Formatting Drills

Practice print(..., end="") vs print() without complex math.

Example: put print() inside the inner loop by mistake.

4. Character Substitution

Swap digits for letters, stars, or spaced output once the loop works.

Example: use print(j, end=" ") for spaced digits on each row.

5. Complexity Intuition

Triangular totals make O(n²) concrete for beginners.

Example: count printed digits for n = 10 → 55.

6. Input Validation Labs

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 the outer/inner roles first — then write the loops. The story matters as much as the code.

Advantages

Why this pattern earns a permanent spot in beginner Python courses.

  1. 1. Instant Visual Feedback

    Wrong bounds show up immediately as a broken staircase.

  2. 2. Minimal Concepts

    Only loops and console output — no arrays or math libraries.

  3. 3. Easy to Extend

    Invert, center, hollow, or change the fill character with small edits.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: trace i and j on paper for rows = 3 before coding — watch how each row adds one digit on the left.

Usage Tips

Small habits that keep number-pattern code clean.

  1. 1. Name Bounds Clearly

    Use rows (or n) and keep i/j for row/column — or rename to row/col.

  2. 2. Use try/except for Input

    Avoid crashes when the user types letters instead of a number.

  3. 3. Keep Newline Outside

    Only call print() after the inner loop finishes the row.

  4. 4. Count Down on the Outer Loop

    rows..1 with inner j = i..rows matches “row i prints digits i..rows” naturally.

  5. 5. Dry-Run One Small n

    Trace rows = 3 on paper before coding larger demos.

Pro Tip: if the output is a vertical list of single digits, you almost certainly put print() inside the inner loop.

Common Pitfalls

Mistakes that commonly break reverse ascending number triangles.

  1. 1. Newline Inside the Inner Loop

    Each digit lands on its own line — you get a column, not a triangle.

    → Use print(j, end="") for digits; print() only after the inner loop.

  2. 2. Wrong Inner Bound

    j = 1..i gives Program 5’s ascending triangle; j = 1..rows every row prints a full line.

    → For this shape, keep inner start at j = i and end at rows.

  3. 3. Forgetting the Row Break

    Omitting print() glues every digit onto one endless line.

    → Always end the row after the inner loop.

  4. 4. Unchecked int(input())

    Letters or empty input raise ValueError or leave rows unset.

    → Wrap int(input()) in try/except ValueError and re-prompt on failure.

  5. 5. Off-by-One on 0-Based Loops

    Switching to i = 0 without adjusting the inner bound prints an empty first row or wrong counts.

    → If 0-based, print digits (i+1)..rows (e.g. j = i + 1; j <= rows).

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single digit row

Output is just the peak digit rows on one line (e.g. 1 when rows is 1).

rows = 0

Empty pattern

Outer loop never runs — print nothing or show a message.

Negative

rows < 0

Treat as invalid; re-prompt instead of silent empty output.

Large n

Many rows

Output grows as n²/2 characters — fine for labs, noisy for huge n.

Bad input

Non-numeric input

Bare int(input()) raises ValueError — wrap it in try/except.

Fill char

Spaced digits

Try print(j, end=" ") for spaces between numbers.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Compare with Program 5

  • Program 5: outer up, inner 1..i
  • Program 6: outer down, inner i..rows

2. Spaced output

  • Use print(j, end=" ") between digits
  • Same loops, wider visual spacing

3. Next in series

  • Continue with Program 7
  • Build on the same nested-loop skills

4. Paper trace

  • Dry-run rows = 3 before coding
  • Fill the walkthrough table by hand

Notes

  • Triangular count. Total digit prints for n rows is n(n+1)/2 — hence O(n²) time.
  • print(..., end="") stays on the line; print() advances — mix them carefully.
  • Validate rows > 0 for interactive programs; rows = 1 should print a single peak digit.
  • This page is left-aligned. Centered pyramids need leading spaces — covered later in the series.

Quick Takeaway: outer loop counts down from rows, inner loop prints digits i..rows, then break the line — that is the whole pattern.

⏱️ Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(rows²)O(1)
Compact trace (Example 3)O(rows²)O(1)
Wrap Up

🎉 Conclusion

The reverse ascending number triangle pattern is a small nested-loop exercise with lasting payoff: row/column thinking, print(..., end="") vs print(), and O(n²) intuition. Master the fixed-rows version, then try user input and the compact rows = 3 trace.

Practice the three examples above, then continue to Program 7 for the next pattern in the series.

Row outer index i prints i..rows — keep print(j, end="") for digits and print() for the break, and validate row counts when reading input.

💡 Best Practices

✅ Do

  • Explain outer counts down, inner prints i..rows before coding
  • Use for i in range(rows, 0, -1) in the outer loop
  • Use print(j, end="") for digits and print() after each row
  • Validate rows ≥ 1 for interactive programs
  • Use try/except ValueError around int(input()) for user input
  • State O(n²) time when asked about complexity

❌ Don’t

  • Call print() inside the inner digit loop
  • Use ascending outer loop when you meant Program 5 instead of this pattern
  • Skip the newline after each row
  • Ignore bad console input in user-facing demos
  • Skip the rows = 1 edge case

Key Takeaways

Knowledge Unlocked

Five things to remember about this number pattern

Print the triangle the beginner-friendly way.

5
Core concepts
02

Outer loop

Controls each row

Code
1 03

Inner loop

Prints digits with print(j, end="")

Code
04

Newline

print() ends each row

I/O
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

The outer loop begins at i = rows. The inner loop prints j from i to rows, so the first row prints only that single digit.
When i = 1, the inner loop runs j from 1 to rows — printing 1, 2, 3, 4, 5 on one line.
Each row adds one more digit on the left: row i prints digits i through rows, e.g. rows=5 gives 5, 45, 345, 2345, 12345.
Program 5 counts the outer loop up and prints 1..i. Program 6 counts the outer loop down and prints i..rows — digits grow from the left instead of the right.
Program 1 also uses a descending outer loop but typically shrinks the inner bound. Program 6 keeps the inner end fixed at rows so digits accumulate on the left.
print(j, end="") stays on the same line for each digit. print() ends the row after the inner loop finishes.
Change rows or read it from user input with int(input()) — see Example 2.
O(n²) for n rows because total prints are 1 + 2 + ... + n = n(n+1)/2.
Use try/except ValueError around int(input()). Bare int(input()) raises ValueError on bad input.
One row prints a single digit 1 — the inner loop runs j from 1 to 1 only once.

Did you Know? 🔊

The outer loop starts from rows down to 1, and the inner loop prints i..rows — producing 5, 45, 345, and so on. Total prints still grow as O(n²).

Continue to Program 7

Move on to the next pattern in the Python number-pattern series.

Program 7 tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

11 people found this page helpful