Class 11Computer Science · Programming with PythonFull chapter

Flow of Control

The whole chapter in one place — read it, then test yourself. Clear notes, a reference sheet, a practice quiz, and worked NCERT solutions & PYQs.

Sequential Flow and Why Indentation Is Syntax

Quick answer Python runs statements top to bottom by default, and marks every block of code with indentation instead of braces, which makes a stray space a real error and a mis-indented line a silent bug.

Every program is a list of instructions. Flow of control means the order in which those instructions actually run when you press Run. Python's default order is the simplest one possible: top to bottom, one line after another, each line exactly once. That is called sequential flow.

Worked example 1 — pure sequential flow

price = 250
qty = 3
total = price * qty
print("Total bill = Rs", total)
print("Thank you")

Real output:

Total bill = Rs 750
Thank you

Five lines, five steps, in that order. Nothing is skipped and nothing repeats. But a real program has to make decisions ("if the balance is low, warn the user") and repeat work ("print the table of 7, ten lines"). So Python gives you two more kinds of flow.

Kind of flowWhat it doesStatements used
SequentialRuns every statement once, in written orderplain statements
Conditional (selection)Chooses which block to run, based on a conditionif, if-else, if-elif-else
Iterative (repetition)Runs the same block again and againfor, while

Worked example 2 — all three flows in one program

fare = 0                      # sequential
for stop in range(1, 4):      # iterative
    fare = fare + 120         #   inside the loop body
    if fare > 200:            #   conditional, nested inside the loop
        print("Stop", stop, "-> fare Rs", fare, "(above Rs 200)")
    else:
        print("Stop", stop, "-> fare Rs", fare)
print("Final fare = Rs", fare)   # sequential again

Real output:

Stop 1 -> fare Rs 120
Stop 2 -> fare Rs 240 (above Rs 200)
Stop 3 -> fare Rs 360 (above Rs 200)
Final fare = Rs 360

Indentation is not decoration. In Python it is syntax. C, C++ and Java mark a block with braces { }, and indentation there is only for looks — you can delete every space and the program still compiles. Python threw the braces away and promoted the indentation itself to be the block marker. The gain is that ugly, misleading layout cannot exist: what your eye sees is exactly what the interpreter sees. The price is that a single stray space is an error.

The rules are short:

  1. A header line (if, elif, else, for, while) must end with a colon :.
  2. The statements belonging to that header — its block or suite — must be indented further than the header.
  3. Every line of one block must be indented by exactly the same amount.
  4. The block ends at the first line that goes back to a smaller indentation.
  5. Use 4 spaces per level. Never mix tabs and spaces.

Worked example 3 — the error you will meet on day one. Saved as demo.py:

marks = 82
if marks >= 33:
print("Pass")

Real output:

  File "demo.py", line 3
    print("Pass")
    ^^^^^
IndentationError: expected an indented block after 'if' statement on line 2

The colon promised a block, and no block arrived. The opposite mistake gives the opposite message:

total = 0
  total = total + 5
print(total)
  File "demo.py", line 2
    total = total + 5
IndentationError: unexpected indent

And if you indent one line with a Tab key and the next with the space bar inside the same block:

if True:
	print("this line uses a TAB")
        print("this line uses 8 SPACES")
  File "demo.py", line 3
    print("this line uses 8 SPACES")
TabError: inconsistent use of tabs and spaces in indentation

Python 3 refuses to guess how wide your Tab is, so it stops. Set your editor to "insert spaces" once and you will never see this again.

Worked example 4 — the dangerous one: no error, wrong answer

These two versions differ by four spaces on one line. Both run cleanly. They do different things.

# Version A - the second print is INSIDE the if block
marks = 20
if marks >= 33:
    print("Pass")
    print("Report card printed")
print("--- A over ---")

# Version B - the second print is OUTSIDE the if block
marks = 20
if marks >= 33:
    print("Pass")
print("Report card printed")
print("--- B over ---")

Real output:

--- A over ---
Report card printed
--- B over ---

Version A printed nothing for a failing student, which is right. Version B printed "Report card printed" for a student who scored 20, which is wrong — because that line is no longer part of the if. This is the single most common Python bug in Class 11 practicals, and no error message will warn you.

One more small thing: a block can never be empty. If you want a block that does nothing yet, use the pass statement.

attendance = 0
if attendance == 0:
    pass          # to be filled in later
else:
    print("Present")
print("Program continues")

Real output:

Program continues
Block header if / elif / else / for / while ... : The colon is compulsory. Omitting it gives SyntaxError: expected ':'.
Standard indent 4 spaces per nesting level Any consistent amount is legal, but all lines of one block must match exactly.
IndentationError (missing) header ends with ':' but next line is not indented Message: expected an indented block after 'if' statement on line N.
IndentationError (extra) a line is indented although no block was opened Message: unexpected indent.
TabError tabs and spaces mixed inside one block Python 3 will not guess the tab width, so it stops with TabError.
pass pass Legal 'do nothing' filler for a block that must exist but has no statements yet.
Remember
  • Default flow is sequential — top to bottom, each statement once; conditional and iterative statements exist to break that default.
  • A header line always ends with a colon, and the indented block under it is its body. Both are compulsory.
  • Every line of one block must carry exactly the same indentation; 4 spaces per level is the standard.
  • Shifting a line in or out by four spaces changes the meaning of the program without producing any error — this is the classic silent bug.
  • Missing indent gives IndentationError: expected an indented block; extra indent gives unexpected indent; mixing tab and space gives TabError.

Conditional Statements: if, if-else, if-elif-else

Quick answer if chooses whether a block runs, if-else picks exactly one of two blocks, and the if-elif-else ladder is tested strictly top to bottom so only the first true condition ever fires.

A condition is any expression that Python can judge True or False — usually built from the relational operators ==, !=, <, >, <=, >= and joined with and, or, not. A conditional statement uses that judgement to decide which block of code to run.

1. The plain if — the block runs only if the condition is True; otherwise it is skipped entirely.

balance = 4500
if balance < 5000:
    print("Low balance. Please recharge your UPI wallet.")
print("Done checking")

Real output:

Low balance. Please recharge your UPI wallet.
Done checking

2. if-else — exactly one of the two blocks runs, never both, never neither.

age = 16
if age >= 18:
    print("Eligible to vote")
else:
    print("Not eligible to vote")
    print("Wait for", 18 - age, "more years")

Real output:

Not eligible to vote
Wait for 2 more years

Here is that decision drawn as a flowchart, the form CBSE asks you to produce. A diamond is a decision with two labelled exits; a rectangle is a process; a rounded box is start/stop.

            +-------------------+
            |      START        |
            +-------------------+
                      |
                      v
            +-------------------+
            |    read marks     |
            +-------------------+
                      |
                      v
                  /---------\
                 /  marks    \    No
                 \  >= 33 ?  /----------+
                  \---------/           |
                      | Yes             v
                      v            +----------+
                +----------+       | print    |
                | print    |       | "Fail"   |
                | "Pass"   |       +----------+
                +----------+            |
                      |                 |
                      +--------+--------+
                               v
                          +---------+
                          |  STOP   |
                          +---------+

3. if-elif-else — a ladder for more than two outcomes. Python tests the conditions strictly top to bottom, runs the block of the first one that is True, and then jumps past the whole ladder. At most one block ever runs.

marks = 73
if marks >= 91:
    grade = "A1"
elif marks >= 81:
    grade = "A2"
elif marks >= 71:
    grade = "B1"
elif marks >= 61:
    grade = "B2"
elif marks >= 33:
    grade = "Pass"
else:
    grade = "E (needs improvement)"
print("Marks:", marks, "-> Grade:", grade)

Real output:

Marks: 73 -> Grade: B1

Notice that 73 >= 61 and 73 >= 33 are also True — but Python never reaches those tests, because it stopped at the first True one. Drawn as a flowchart the ladder is a staircase of diamonds, each "No" exit feeding the next test:

              +---------+
              |  START  |
              +---------+
                   |
                   v
               /-------\
              / c1 ?    \  No      /-------\
              \         /-------> / c2 ?    \  No      +----------+
               \-------/          \         /-------> | block C  |
                   | Yes           \-------/          | (else)   |
                   v                   | Yes          +----------+
              +---------+              v                    |
              | block A |         +---------+               |
              +---------+         | block B |               |
                   |              +---------+               |
                   |                   |                    |
                   +---------+---------+--------------------+
                             v
                        +---------+
                        |  STOP   |
                        +---------+

That staircase is exactly why the order of a ladder matters. Write the same tests in the wrong order and the ladder breaks:

marks = 95
if marks >= 33:
    grade = "Pass"
elif marks >= 91:
    grade = "A1"
else:
    grade = "Fail"
print(grade)

Real output:

Pass

A 95 was labelled just "Pass" and the A1 branch became unreachable. In a ladder of overlapping ranges, always test the narrowest (most extreme) condition first.

4. Nested if — an if inside the block of another if, used when the second question only makes sense after the first is answered.

bill = 3200
member = True

if bill >= 2000:
    if member:
        discount = 0.20
    else:
        discount = 0.10
else:
    discount = 0.0

print("Bill Rs", bill)
print("Discount =", int(discount * 100), "%")
print("Payable = Rs", bill - bill * discount)

Real output:

Bill Rs 3200
Discount = 20 %
Payable = Rs 2560.0

In a nested if, an else belongs to the if at its own indentation level. That is one more thing indentation decides for you.

Syllabus program A — absolute value without abs()

for n in [-17, 0, 17]:
    if n < 0:
        result = -n
    else:
        result = n
    print("n =", n, "-> absolute value =", result)

Real output:

n = -17 -> absolute value = 17
n = 0 -> absolute value = 0
n = 17 -> absolute value = 17

Syllabus program B — divisibility of a number

n = int(input("Enter a number: "))
if n % 3 == 0 and n % 5 == 0:
    print(n, "is divisible by both 3 and 5")
elif n % 3 == 0:
    print(n, "is divisible by 3 only")
elif n % 5 == 0:
    print(n, "is divisible by 5 only")
else:
    print(n, "is divisible by neither 3 nor 5")

Real output for four separate runs. The number you type sits on the same line as the prompt, which is why each transcript line below looks like one sentence:

Enter a number: 45 is divisible by both 3 and 5
Enter a number: 9 is divisible by 3 only
Enter a number: 20 is divisible by 5 only
Enter a number: 22 is divisible by neither 3 nor 5

The "both" test has to come first for the same ordering reason as the grade ladder.

Syllabus program C — sort three numbers using only conditionals

a, b, c = 47, 12, 30

if a <= b and a <= c:
    small = a
    if b <= c:
        mid, large = b, c
    else:
        mid, large = c, b
elif b <= a and b <= c:
    small = b
    if a <= c:
        mid, large = a, c
    else:
        mid, large = c, a
else:
    small = c
    if a <= b:
        mid, large = a, b
    else:
        mid, large = b, a

print("Ascending order:", small, mid, large)

Real output:

Ascending order: 12 30 47

Why <= and not <. The else at the bottom catches everything the first two tests reject, so no value ever escapes this ladder — instead the wrong branch quietly claims it. Replace all six comparisons with strict < and feed it a triple whose smallest value is repeated:

a, b, c = 3, 3, 5

if a < b and a < c:
    small = a
    if b < c:
        mid, large = b, c
    else:
        mid, large = c, b
elif b < a and b < c:
    small = b
    if a < c:
        mid, large = a, c
    else:
        mid, large = c, a
else:
    small = c
    if a < b:
        mid, large = a, b
    else:
        mid, large = b, a

print("Strict < version says:", small, mid, large)

Real output:

Strict < version says: 5 3 3

Here a < b is False (3 is not less than 3) and b < a is False as well, so the if and the elif are both rejected and the else runs. The else assumes c must be the smallest, so it announces 5 as the smallest of 3, 3 and 5 — a wrong answer with no error message. Writing <= lets a tie satisfy the first test, and the program then gives the correct order for every triple, including ones with two or three equal values.

Two extras worth knowing. First, a conditional expression is a one-line if-else that produces a value rather than running a block:

n = -8
sign = "negative" if n < 0 else "non-negative"
print(n, "is", sign)

Real output:

-8 is negative

Second, a condition does not have to be a comparison. Python treats 0, the empty string and the empty list as False and almost everything else as True:

for value in [0, 7, "", "hi", []]:
    if value:
        print(repr(value), "-> treated as True")
    else:
        print(repr(value), "-> treated as False")

Real output. repr() is used only so that the empty string shows up as a visible pair of quotes instead of a blank:

0 -> treated as False
7 -> treated as True
'' -> treated as False
'hi' -> treated as True
[] -> treated as False
if if condition: statements Block runs only when the condition is True; otherwise it is skipped.
if-else if condition: A else: B Exactly one of A or B runs. else takes no condition of its own.
if-elif-else if c1: A elif c2: B else: C Tested top to bottom; the first True block runs and the rest are skipped. elif may repeat; else is optional.
Relational operators == != = All give True or False. == compares, = assigns. 'if m = 78:' raises SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
Logical operators cond1 and cond2 | cond1 or cond2 | not cond and needs both True; or needs at least one True; not flips the value.
Conditional expression value_if_true if condition else value_if_false Produces a value, so it can sit on the right of =. Not a replacement for a multi-line block.
Remember
  • if runs a block or skips it; if-else guarantees exactly one of two blocks runs.
  • An if-elif-else ladder is tested top to bottom and stops at the first True condition, so overlapping ranges must be ordered narrowest first.
  • == compares while = assigns; writing if m = 78: is a SyntaxError, not a bug you can run and debug.
  • In nested ifs, an else pairs with the if at its own indentation level, decided purely by indentation.
  • Use <= rather than < when comparing three values: with strict <, a tie such as 3, 3, 5 satisfies neither the if nor the elif, so the else claims it and prints a wrong answer silently.

The for Loop and range()

Quick answer A for loop walks through the items of a sequence one at a time, and range() manufactures a run of integers that always stops one short of its stop value.

A for loop is a counted loop: it takes a sequence, hands you one item at a time in the loop variable, and stops automatically when the sequence runs out. You never write the stopping test yourself, so a for loop cannot run forever.

Worked example 1 — looping over a string and over a list

for ch in "PATNA":
    print(ch, end=" ")
print()

for city in ["Delhi", "Chennai", "Kochi"]:
    print("Branch:", city)

Real output:

P A T N A
Branch: Delhi
Branch: Chennai
Branch: Kochi

The syllabus also asks for the flowchart of an iterative statement. A loop is drawn as a decision diamond with an arrow that goes backwards — that back-arrow is what makes it a loop rather than a branch:

             +---------+
             |  START  |
             +---------+
                  |
                  v
      +----->/-----------------\
      |     /  any item left    \   No
      |     \  in the sequence ? /-------+
      |      \-----------------/         |
      |               | Yes              |
      |               v                  |
      |     +---------------------+      |
      |     | var = next item     |      |
      |     +---------------------+      |
      |               |                  |
      |               v                  |
      |     +---------------------+      |
      |     |     loop body       |      |
      |     +---------------------+      |
      |               |                  v
      +---------------+             +---------+
                                    |  STOP   |
                                    +---------+

Very often you do not have a ready-made list — you just want the numbers 1 to 10. That is what range() is for. It builds a sequence of integers on demand.

FormMeaningExampleProduces
range(stop)0 up to stop−1range(5)0, 1, 2, 3, 4
range(start, stop)start up to stop−1range(1, 5)1, 2, 3, 4
range(start, stop, step)start, start+step, ... while below stoprange(1, 10, 2)1, 3, 5, 7, 9
negative stepcounts downward, stays above stoprange(10, 0, -2)10, 8, 6, 4, 2

Worked example 2 — proving that range() excludes its stop value

print(list(range(5)))
print(list(range(1, 5)))
print(list(range(1, 10, 2)))
print(list(range(10, 0, -2)))
print(list(range(5, 5)))
print(list(range(5, 1)))
print(len(range(1, 10, 3)))

Real output:

[0, 1, 2, 3, 4]
[1, 2, 3, 4]
[1, 3, 5, 7, 9]
[10, 8, 6, 4, 2]
[]
[]
3

Read those carefully. range(5) stops at 4, not 5. range(10, 0, -2) stops at 2, not 0. range(5, 5) and range(5, 1) are both empty — the loop body simply never runs, and Python does not complain. This exclusive-stop behaviour is not an accident: it makes range(len(s)) give exactly the valid indices of s, and it makes range(a, b) contain exactly b - a items.

So to loop from 1 to n inclusive, you must write range(1, n + 1). Forgetting the + 1 is the most common loop error in Class 11.

Two things range() refuses to do:

print(list(range(1, 5.0)))
TypeError: 'float' object cannot be interpreted as an integer
print(list(range(1, 10, 0)))
ValueError: range() arg 3 must not be zero

A zero step would never move, so Python rejects it rather than hang.

Also note that range is a lazy object, not a list — it stores only start, stop and step, which is why range(1, 10000000) costs no memory:

r = range(1, 6)
print(r)
print(type(r))
print(list(r))
print(3 in r, 9 in r)

Real output:

range(1, 6)

[1, 2, 3, 4, 5]
True False

Syllabus program A — factorial of a positive number

n = 6
fact = 1
for i in range(1, n + 1):
    fact = fact * i
    print("after i =", i, "-> fact =", fact)
print("Factorial of", n, "is", fact)

Real output:

after i = 1 -> fact = 1
after i = 2 -> fact = 2
after i = 3 -> fact = 6
after i = 4 -> fact = 24
after i = 5 -> fact = 120
after i = 6 -> fact = 720
Factorial of 6 is 720

The accumulator fact starts at 1, not 0 — starting at 0 would make every product 0. For a sum the accumulator starts at 0; for a product it starts at 1.

Syllabus program B — summation of a series: S = 1 + 1/2 + 1/3 + ... + 1/n

n = 5
total = 0
for i in range(1, n + 1):
    total = total + 1 / i
print("Sum of first", n, "terms =", total)
print("Rounded to 4 places:", round(total, 4))

Real output:

Sum of first 5 terms = 2.283333333333333
Rounded to 4 places: 2.2833

Worked example 3 — checking a loop against a known formula

n = 10
total = 0
for i in range(1, n + 1):
    total = total + i ** 2
print("Loop total   =", total)
print("Formula n(n+1)(2n+1)/6 =", n * (n + 1) * (2 * n + 1) // 6)

Real output:

Loop total   = 385
Formula n(n+1)(2n+1)/6 = 385

Whenever a maths formula exists, use it to verify your loop. If the two disagree, your range() bounds are wrong.

Worked example 4 — a gotcha worth marks: changing the loop variable inside the body does not change the loop, because the next round overwrites it from the sequence.

for i in range(1, 5):
    print("i at top =", i, end="   ")
    i = i * 100
    print("i after change =", i)
print("i after the loop ends =", i)

Real output:

i at top = 1   i after change = 100
i at top = 2   i after change = 200
i at top = 3   i after change = 300
i at top = 4   i after change = 400
i after the loop ends = 400

The loop still ran exactly 4 times. And note the last line: in Python the loop variable survives after the loop, holding whatever it held on the final round.

for statement for var in sequence: body sequence may be a string, list, tuple or range. var is reassigned from the sequence each round.
range(stop) range(stop) -> 0, 1, ..., stop-1 Starts at 0, step 1. range(5) gives 5 numbers ending at 4.
range(start, stop) range(start, stop) -> start ... stop-1 Contains exactly stop-start values; empty if start >= stop.
range(start, stop, step) range(start, stop, step) step may be negative to count down. step = 0 raises ValueError: range() arg 3 must not be zero.
Loop over indices for i in range(len(s)): Gives 0 to len(s)-1, exactly the valid index positions of s.
Number of iterations len(range(a, b, c)) Fast way to count rounds without running the loop; len(range(1, 10, 3)) is 3.
Remember
  • for walks a sequence item by item and ends by itself, so it can never become an infinite loop.
  • range() always excludes its stop value, so to cover 1 to n you must write range(1, n + 1).
  • range(5, 5) and range(5, 1) are empty, so the loop body runs zero times with no error.
  • range() accepts only integers (a float raises TypeError), and a step of 0 raises ValueError.
  • A sum accumulator starts at 0, a product accumulator starts at 1; the loop variable keeps its last value after the loop finishes.
  • In a loop flowchart the decision diamond has a backward arrow returning to the test; that back-arrow is what distinguishes a loop from a plain branch.

while Loops, break and continue

Quick answer while repeats as long as a condition stays True and needs you to update it yourself, while break abandons the loop entirely and continue only abandons the current round.

Use a for loop when you know how many rounds you need. Use a while loop when you do not — when the loop should keep going "until something happens". A while loop tests its condition before every round, so if the condition is False at the start the body never runs at all.

A correct while loop always has three parts, and forgetting the third one is what makes loops hang:

  1. Initialisation — set up the variable the condition uses, before the loop.
  2. Condition — the test in the while header.
  3. Update — change that variable inside the body so the condition eventually becomes False.

Those same three parts are what you draw in the flowchart of a while loop. The initialisation sits above the diamond, the update sits inside the loop, and the arrow from the update runs backwards to the diamond:

             +---------+
             |  START  |
             +---------+
                  |
                  v
        +---------------------+
        |  i = 1   (initialise)|
        +---------------------+
                  |
                  v
      +----->/---------------\
      |     /                 \   False
      |     \    i <= 5 ?     /---------+
      |      \---------------/          |
      |               | True            |
      |               v                 |
      |     +---------------------+     |
      |     |     print(i)        |     |
      |     +---------------------+     |
      |               |                 |
      |               v                 |
      |     +---------------------+     |
      |     |  i = i + 1  (update)|     |
      |     +---------------------+     |
      |               |                 v
      +---------------+            +---------+
                                   |  STOP   |
                                   +---------+

That flowchart is the program below, and both agree:

i = 1
while i <= 5:
    print(i, end=" ")
    i = i + 1
print()
print("loop ended with i =", i)

Real output:

1 2 3 4 5
loop ended with i = 6

The loop ends with i at 6, not 5 — the update runs on the last round too, and it is the failed test on 6 that stops the loop.

Worked example 1 — a recharge that lasts until the money runs out

balance = 1000
month = 0
while balance >= 250:
    balance = balance - 250
    month = month + 1
    print("Month", month, "-> balance Rs", balance)
print("Recharge lasted", month, "months. Left over: Rs", balance)

Real output:

Month 1 -> balance Rs 750
Month 2 -> balance Rs 500
Month 3 -> balance Rs 250
Month 4 -> balance Rs 0
Recharge lasted 4 months. Left over: Rs 0

Nothing in the program said "4". The loop worked it out.

Worked example 2 — reversing a number, the classic while question

n = 4056
rev = 0
while n > 0:
    digit = n % 10
    rev = rev * 10 + digit
    n = n // 10
    print("digit =", digit, "| rev so far =", rev, "| n left =", n)
print("Reversed number =", rev)

Real output:

digit = 6 | rev so far = 6 | n left = 405
digit = 5 | rev so far = 65 | n left = 40
digit = 0 | rev so far = 650 | n left = 4
digit = 4 | rev so far = 6504 | n left = 0
Reversed number = 6504

You cannot write this as a for loop cleanly, because you do not know in advance how many digits the number has. % peels off the last digit and // throws it away; when n reaches 0 the condition fails and the loop ends. Note that this version destroys n; if you still need the original number at the end, copy it into another variable first.

Worked example 3 — the infinite loop. Here the update step is missing:

i = 1
while i <= 5:
    print("i =", i)

Real output (first six lines, before the process was stopped by hand):

i = 1
i = 1
i = 1
i = 1
i = 1
i = 1
...

i never changes, so i <= 5 is True forever. If this happens to you, press Ctrl + C to stop the program.

break and continue. Both are jump statements used inside a loop, and the difference is exactly one word:

  • break — leave the loop completely, right now. The remaining rounds never happen.
  • continue — skip the rest of this round only and go straight to the next round.

Worked example 4 — the same loop, once with each

print("WITH break:")
for n in range(1, 8):
    if n == 4:
        break
    print(n, end=" ")
print()

print("WITH continue:")
for n in range(1, 8):
    if n == 4:
        continue
    print(n, end=" ")
print()

Real output:

WITH break:
1 2 3
WITH continue:
1 2 3 5 6 7

break lost everything from 4 onwards. continue lost only the 4.

Worked example 5 — where break is the right tool: stop searching once found

roll_numbers = [11, 14, 19, 23, 27, 31]
target = 19
position = -1
for i in range(len(roll_numbers)):
    print("checking index", i)
    if roll_numbers[i] == target:
        position = i
        break
print("Found", target, "at index", position)

Real output:

checking index 0
checking index 1
checking index 2
Found 19 at index 2

Indices 3, 4 and 5 were never checked. That is the whole point — break saves work.

Worked example 6 — where continue is the right tool: skip bad data, keep the rest

marks = [78, -1, 65, -1, 90, 42]
total = 0
count = 0
for m in marks:
    if m == -1:
        continue
    total = total + m
    count = count + 1
print("Students present:", count)
print("Total marks:", total)
print("Average:", round(total / count, 2))

Real output:

Students present: 4
Total marks: 275
Average: 68.75

The -1 entries (absentees) are skipped, and crucially count is not incremented for them, so the average is over 4 students and not 6.

Worked example 7 — while True with a sentinel. When the stopping condition is only discoverable in the middle of the body, the standard shape is a deliberately infinite loop plus a break. Here 0 is the sentinel value meaning "no more items".

entries = [250, 120, 80, 0, 999]
i = 0
total = 0
while True:
    value = entries[i]
    i = i + 1
    if value == 0:
        break
    total = total + value
print("Bill total = Rs", total)
print("Items after the sentinel were never read. i stopped at", i)

Real output:

Bill total = Rs 450
Items after the sentinel were never read. i stopped at 4

The 999 was never added, because the loop had already left. A while True loop is safe only if some path through the body definitely reaches a break.

while statement while condition: body Condition is tested before each round. If it is False at the start, the body runs 0 times.
Counter update i = i + 1 (or i += 1) Must appear inside the body, on every path, or the loop never ends.
break break Terminates the innermost enclosing loop at once; execution resumes at the first statement after that loop.
continue continue Skips the rest of the current iteration only; the loop itself keeps running.
Sentinel loop while True: ... if stop_condition: break Deliberate infinite loop broken from inside. Safe only if the break is reachable.
Digit peeling d = n % 10 ; n = n // 10 Standard while-loop idiom for reverse-a-number and sum-of-digits. Ends when n becomes 0.
Remember
  • while tests its condition before every round, so a condition that is False at the start means zero rounds.
  • Every while loop needs initialisation, a condition, and an update inside the body; a missing update is an infinite loop, and Ctrl+C stops it.
  • In a while flowchart the initialisation sits above the diamond and the update arrow runs backwards into the diamond.
  • break exits the whole loop immediately; continue skips only the remainder of the current round.
  • break is for searches (stop as soon as you find it); continue is for skipping unwanted items while processing the rest.
  • while True with a break is the standard shape when the stopping condition is only known mid-body.

Nested Loops and Pattern Programs

Quick answer Putting one loop inside another makes the inner loop run completely for every single round of the outer loop, which is exactly the machinery behind every star, number and letter pattern in the practical file.

A loop can be the body of another loop. When it is, the inner loop finishes completely for every single round of the outer loop. If the outer loop runs 4 times and the inner runs 3 times, the innermost statement runs 4 × 3 = 12 times.

Worked example 1 — counting the rounds. The outer loop runs 5 times and the inner loop runs 3 times, so the print inside runs 15 times and fills 5 rows of 3 entries.

for i in range(1, 6):
    for t in range(2, 5):
        print(t, "x", i, "=", t * i, end="   ")
    print()

Real output:

2 x 1 = 2   3 x 1 = 3   4 x 1 = 4
2 x 2 = 4   3 x 2 = 6   4 x 2 = 8
2 x 3 = 6   3 x 3 = 9   4 x 3 = 12
2 x 4 = 8   3 x 4 = 12   4 x 4 = 16
2 x 5 = 10   3 x 5 = 15   4 x 5 = 20

Note the bare print() at the end of the outer body, aligned with the inner for, not inside it. That is the line-break. Every pattern program in this section uses the same two tools:

  • print(x, end="") prints without moving to a new line, so the inner loop builds one row across.
  • print() with nothing prints just the newline, ending the row.

The universal recipe: outer loop = which row, inner loop = how many characters in that row. Get the inner loop's count expression right and the pattern falls out.

Pattern 1 — right triangle of stars (row i has i stars)

n = 5
for i in range(1, n + 1):
    for j in range(1, i + 1):
        print("*", end="")
    print()

Real output:

*
**
***
****
*****

Pattern 2 — inverted triangle (count the outer loop downwards)

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

Real output:

*****
****
***
**
*

Pattern 3 — number pattern, printing the inner variable

n = 4
for i in range(1, n + 1):
    for j in range(1, i + 1):
        print(j, end="")
    print()

Real output:

1
12
123
1234

Pattern 4 — number pattern, printing the outer variable. The loops are identical to Pattern 3; only the variable inside print changed from j to i. That one character is the whole difference.

n = 4
for i in range(1, n + 1):
    for j in range(1, i + 1):
        print(i, end="")
    print()

Real output:

1
22
333
4444

Pattern 5 — letter pattern. chr() converts a character code to a character, and the code for 'A' is 65, so chr(64 + j) gives A when j is 1, B when j is 2, and so on. ord('A') converts back and gives 65.

n = 5
for i in range(1, n + 1):
    for j in range(1, i + 1):
        print(chr(64 + j), end="")
    print()

Real output:

A
AB
ABC
ABCD
ABCDE

Swap j for i and you get the repeated-letter version. Since a string multiplied by an integer repeats it, this one does not even need the inner loop:

n = 5
for i in range(1, n + 1):
    print(chr(64 + i) * i)

Real output:

A
BB
CCC
DDDD
EEEEE

Pattern 6 — centred pyramid. Two inner loops now: one prints leading spaces, the other prints stars. Row i needs n - i spaces and 2i - 1 stars.

n = 5
for i in range(1, n + 1):
    for s in range(1, n - i + 1):
        print(" ", end="")
    for j in range(1, 2 * i):
        print("*", end="")
    print()

Real output:

    *
   ***
  *****
 *******
*********

Check the arithmetic against the output: row 1 has 4 spaces and 1 star, row 5 has 0 spaces and 9 stars. range(1, 2 * i) runs 2i - 1 times because range excludes its stop value — the exclusive-stop rule from the previous section is doing real work here.

Worked example 2 — break inside a nested loop leaves ONLY the inner loop. This is a favourite exam trap.

for i in range(1, 4):
    for j in range(1, 4):
        if j == 2:
            break
        print("i =", i, "j =", j)
    print("inner loop over for i =", i)
print("done")

Real output:

i = 1 j = 1
inner loop over for i = 1
i = 2 j = 1
inner loop over for i = 2
i = 3 j = 1
inner loop over for i = 3
done

The outer loop still completed all three of its rounds. break only ever ends the loop it is directly inside — Python has no "break out of two loops" statement.

Nested for for i in range(...): for j in range(...): body body runs (outer count) x (inner count) times.
Same-line printing print(value, end="") Suppresses the newline. The default is end="\n".
End of row print() Prints just a newline. Must be indented at the outer body's level, not inside the inner loop.
String repetition "*" * n Repeats a string n times; n <= 0 gives an empty string. Replaces a simple inner loop.
Letter from a number chr(64 + i) chr(65) is 'A'. So i = 1 gives 'A', i = 2 gives 'B'. ord('A') gives back 65.
Pyramid row counts row i: (n - i) spaces, then (2*i - 1) stars Written as range(1, n-i+1) and range(1, 2*i) because range excludes its stop value.
Remember
  • The inner loop completes fully for every single round of the outer loop, so total iterations multiply.
  • Outer loop chooses the row, inner loop chooses how many characters that row contains.
  • print(x, end="") keeps the cursor on the same line; a bare print() at the end of the outer body ends the row.
  • Printing the inner variable j gives 1, 12, 123 while printing the outer variable i gives 1, 22, 333 — same loops, one character different.
  • break inside a nested loop exits only the inner loop; the outer loop carries on to its next round.

The formula sheet

Every formula in this chapter, in one place — screenshot it before your exam.

if / elif / else / for / while ... :
Block header
4 spaces per nesting level
Standard indent
header ends with ':' but next line is not indented
IndentationError (missing)
a line is indented although no block was opened
IndentationError (extra)
tabs and spaces mixed inside one block
TabError
pass
pass
if condition: statements
if
if condition: A else: B
if-else
if c1: A elif c2: B else: C
if-elif-else
== != =
Relational operators
cond1 and cond2 | cond1 or cond2 | not cond
Logical operators
value_if_true if condition else value_if_false
Conditional expression
for var in sequence: body
for statement
range(stop) -> 0, 1, ..., stop-1
range(stop)
range(start, stop) -> start ... stop-1
range(start, stop)
range(start, stop, step)
range(start, stop, step)
for i in range(len(s)):
Loop over indices
len(range(a, b, c))
Number of iterations
while condition: body
while statement
i = i + 1 (or i += 1)
Counter update
break
break
continue
continue
while True: ... if stop_condition: break
Sentinel loop
d = n % 10 ; n = n // 10
Digit peeling
for i in range(...): for j in range(...): body
Nested for
print(value, end="")
Same-line printing
print()
End of row
"*" * n
String repetition
chr(64 + i)
Letter from a number
row i: (n - i) spaces, then (2*i - 1) stars
Pyramid row counts

Test yourself

Tap an answer to check it instantly — you'll see why it's right, and what to revise if it isn't.

0 correct · 0/12 answered
Q1

What is the exact output of this code?for i in range(2, 12, 3): print(i, end="#")

Q2

What is printed?x = 0for i in range(1, 6): if i % 2 == 0: continue x = x + iprint(x)

Q3

What is printed?count = 0for i in range(3): for j in range(i): count = count + 1print(count)

Q4

What is printed?n = 100if n > 10: print("A")elif n > 50: print("B")elif n > 90: print("C")else: print("D")

Q5

What is the output?s = "PYTHON"for i in range(len(s)): if s[i] == "H": break print(s[i], end="")

Q6

What is the output?i = 5while i > 0: print(i, end=" ") i = i - 2print(i)

Q7

What is printed?c = 0for i in "MADAM": if i == "M": continue c = c + 1print(c)

Q8

What does this print? (rows shown separated by / )for i in range(3, 0, -1): print(i * "#")

Q9

A student writes:x = 10if x > 5:print("big")What happens when this is run?

Q10

How many times does the body of for i in range(1, 20, 4): run?

Q11

Which statement is correct about break and continue?

Q12

What is the output?a = 7if a > 5: if a > 10: print("big")else: print("small")print("end")

NCERT solutions & previous-year questions

Step-by-step model answers — tap a question to reveal the full solution.

NCERT questions 6

1 Write a program to find the largest of three numbers entered by the user.Conditional statements (if-elif-else)

The idea: a number is the largest if it is greater than or equal to both of the others. Test each candidate in turn. Use >= rather than >, for the reason shown below.

a, b, c = 34, 91, 58
if a >= b and a >= c:
    largest = a
elif b >= a and b >= c:
    largest = b
else:
    largest = c
print("Largest of", a, b, c, "is", largest)

Real output:

Largest of 34 91 58 is 91

Working for these values: 34 >= 91 is False, so the first branch fails. 91 >= 34 and 91 >= 58 is True, so largest = 91 and the else is skipped. To read the numbers from the keyboard instead, replace the first line with three int(input(...)) calls — the logic is unchanged.

Why >= matters. With strict >, a tie between the two largest values is rejected by both the if and the elif, and the else then wrongly hands the answer to c:

a, b, c = 91, 91, 58
if a > b and a > c:
    largest = a
elif b > a and b > c:
    largest = b
else:
    largest = c
print("Strict > version says the largest is", largest)

Real output:

Strict > version says the largest is 58

The value never "falls out" of the ladder — the else always catches it. That is exactly what makes the bug dangerous: there is no error message, just a wrong number.

2 Write a program to check whether a given number is a prime number or not.for loop with break

A number n (n > 1) is prime if no integer from 2 up to √n divides it. Checking only up to the square root is enough: if n = p × q with p > √n, then q must be smaller than √n and we would already have found q. A break stops the search the moment a divisor turns up.

n = 91
is_prime = True
if n < 2:
    is_prime = False
else:
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            print(n, "is divisible by", i)
            is_prime = False
            break
if is_prime:
    print(n, "is a prime number")
else:
    print(n, "is not a prime number")

Real output for n = 91:

91 is divisible by 7
91 is not a prime number

Real output for n = 97:

97 is a prime number

Note the + 1 in range(2, int(n ** 0.5) + 1). Without it, a perfect square like 49 would loop over range(2, 7), which is 2, 3, 4, 5, 6 — it would never test its own root 7 and would wrongly report 49 as prime. That is a direct consequence of range() excluding its stop value.

3 Write a program to print the first n terms of the Fibonacci series.for loop and simultaneous assignment

In the Fibonacci series each term is the sum of the two before it, starting from 0 and 1. Keep only the last two terms in two variables and slide them forward each round.

n = 10
a, b = 0, 1
for i in range(n):
    print(a, end=" ")
    a, b = b, a + b
print()

Real output:

0 1 1 2 3 5 8 13 21 34

The line a, b = b, a + b is the important one. Python builds the whole right-hand side first, using the old values, and only then assigns. Written as two separate statements it would be wrong:

a = b        # a is now the old b
b = a + b    # this uses the NEW a, so b doubles instead

That broken version prints 0 1 2 4 8 16 — the powers of 2, not the Fibonacci numbers. If you must use separate statements, keep a temporary: t = a + b, then a = b, then b = t, which prints 0 1 1 2 3 5 correctly. Also note range(n), not range(1, n) — we need exactly n terms, and the loop variable is never used inside the body.

4 Write a program to find the sum of the digits of a number entered by the user.while loop, % and // operators

You do not know how many digits the number has, so this is a while loop, not a for loop. n % 10 gives the last digit and n // 10 removes it. Repeat until nothing is left.

n = 5837
temp = n
total = 0
while temp > 0:
    total = total + temp % 10
    temp = temp // 10
print("Sum of digits of", n, "=", total)

Real output:

Sum of digits of 5837 = 23

Trace of the loop: temp = 5837, total = 7, temp = 583; total = 10, temp = 58; total = 18, temp = 5; total = 23, temp = 0 → condition fails, loop ends. Check: 5 + 8 + 3 + 7 = 23.

Two habits worth copying. First, the original n is preserved in its own variable and the destruction happens to temp, so you can still print n at the end. Second, // (integer division) is used, not / — / would give a float such as 583.7, the digits would stop being whole numbers, and the value would shrink towards 0 without ever reaching it exactly.

5 Write a program to check whether a year entered by the user is a leap year or not.if-elif-else ladder ordering

The Gregorian rule has three layers: a year divisible by 400 is a leap year; otherwise a year divisible by 100 is not; otherwise a year divisible by 4 is. The reason is that the Earth's year is about 365.2422 days, so adding a day every 4 years over-corrects slightly, and the century rules trim the excess back.

Because these conditions overlap, the ladder must be written strictest-first.

for year in [1900, 2000, 2024, 2025]:
    if year % 400 == 0:
        print(year, "is a leap year")
    elif year % 100 == 0:
        print(year, "is NOT a leap year")
    elif year % 4 == 0:
        print(year, "is a leap year")
    else:
        print(year, "is NOT a leap year")

Real output:

1900 is NOT a leap year
2000 is a leap year
2024 is a leap year
2025 is NOT a leap year

1900 and 2000 are the pair that catch people out: both are divisible by 100 and by 4, and only the % 400 test tells them apart. If you put the % 4 test first, 1900 would be wrongly reported as a leap year. The same logic written as a single condition is if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:.

6 What is the difference between the break and continue statements? Explain with the help of a program.Jump statements

break terminates the loop completely — control jumps to the first statement after the loop, and none of the remaining iterations happen. continue terminates only the current iteration — the rest of the loop body is skipped, but the loop itself goes on to the next value.

breakcontinue
EffectLeaves the loopSkips the rest of this round
Remaining iterationsCancelledStill happen
Typical useStop a search once foundSkip invalid or unwanted data
In nested loopsExits the inner loop onlyAffects the inner loop only

The same data, the same loop, one word different:

nums = [4, 7, 0, 9, 3]

print("With break  :", end=" ")
for x in nums:
    if x == 0:
        break
    print(100 // x, end=" ")
print()

print("With continue:", end=" ")
for x in nums:
    if x == 0:
        continue
    print(100 // x, end=" ")
print()

Real output:

With break  : 25 14
With continue: 25 14 11 33

Both versions avoid the ZeroDivisionError that 100 // 0 would cause. But break threw away the valid 9 and 3 that came after the zero, while continue processed them. Choosing between them is therefore a decision about the data, not about style.

Previous-year board questions 4

Q1 Rewrite the following code after removing all syntax errors. Underline each correction.n = 5s = 0for i in range(1,n+1) if i % 2 = 0 s = s + i else s = s - iprint(s) 2023 (board pattern)

There are five errors, and they are the three things this chapter is about: colons, == versus =, and indentation.

  1. Missing colon after the for header.
  2. = used in a condition instead of ==.
  3. Missing colon after the if header.
  4. Missing colon after else.
  5. The statement below else is not indented into its block.

Corrected program, with each correction shown in bold (that is what "underline" means on paper):

n = 5
s = 0
for i in range(1, n + 1):
    if i % 2 == 0:
        s = s + i
    else:
        s = s - i
print(s)

Real output of the corrected program:

-3

Working: i = 1 odd → s = −1; i = 2 even → s = 1; i = 3 odd → s = −2; i = 4 even → s = 2; i = 5 odd → s = −3.

Marking note. Python reports only the first error, so you cannot find all five by running the file once — you must read it. Fixing them one at a time in Python 3.13 produces this sequence of messages, which is a useful way to check your own answer:

Errors fixed so farMessage Python then gives
noneSyntaxError: expected ':' (the for line)
1SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?
1, 2SyntaxError: expected ':' (the if line)
1, 2, 3SyntaxError: expected ':' (the else line)
1, 2, 3, 4IndentationError: expected an indented block after 'else' statement on line 6

Note that the = message depends on what is on the left. Here the left side is the expression i % 2, so Python says "cannot assign to expression here". For a plain variable, as in if m = 78:, the message is the more familiar SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? Either way it is a syntax error, not a logical slip you can run and debug.

Q2 Find and write the output of the following Python code:x = 10y = 0while x > y: print(x, y) x = x - 3 y = y + 2 2022 (board pattern)

Trace it in a table. Test the condition before each round, because while is a pre-test loop.

Roundxyx > y ?Printedx, y after update
1100True10 07, 2
272True7 24, 4
344False—loop ends

Real output:

10 0
7 2

The trap is round 3: 4 > 4 is False, because > is strict. Students who read it as >= add a third line "4 4" that never happens. Also note that print(x, y) with a comma puts a single space between the two values — that is the default separator sep=" ".

Q3 Write a Python program to print the following pattern for a given value of n (shown here for n = 5): 1 21 321 432154321 2024 (board pattern)

Read the pattern row by row before writing anything. Row i contains n - i leading spaces, then the numbers counting down from i to 1. So the outer loop chooses the row and there are two inner loops — one for the spaces, one for the digits.

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

Real output:

    1
   21
  321
 4321
54321

Three things earn the marks here:

  • range(1, n - i + 1) runs n - i times: 4 spaces for row 1 and 0 spaces for row 5, which matches the picture.
  • range(i, 0, -1) counts down and stops at 1, because the stop value 0 is excluded.
  • The bare print() is indented at the outer body's level. Push it one level in and the newline would come after every character, destroying the pattern.
Q4 Differentiate between a for loop and a while loop with one example of each. Then write a program to compute the sum of the series 1 &minus; 2 + 3 &minus; 4 + ... up to n terms. 2023 (board pattern)
for loopwhile loop
KindCounted / definiteCondition-controlled / indefinite
Number of roundsKnown before the loop startsDecided while the loop is running
Update of control variableAutomatic, from the sequenceYou must write it in the body
Can it hang?No — the sequence is finiteYes, if the update is missing
Typical useTable of 7, factorial of nReverse a number, keep asking until valid input

Example of each (both already executed in this chapter): a for loop computes 6! as 720 in exactly 6 known rounds, while a while loop reverses 4056 to 6504 in a number of rounds nobody counted in advance.

Program for the series. The sign alternates, so use the parity of the term number to decide whether to add or subtract.

n = 9
total = 0
for i in range(1, n + 1):
    if i % 2 == 1:
        total = total + i
    else:
        total = total - i
print("Sum of first", n, "terms =", total)

Real output:

Sum of first 9 terms = 5

Check by hand: (1 − 2) + (3 − 4) + (5 − 6) + (7 − 8) + 9 = −1 − 1 − 1 − 1 + 9 = 5. In general the sum is (n + 1) / 2 for odd n and −n/2 for even n, which is a quick way to verify your program for any value you are given.

Part of Priodemy for School

Interactive CBSE lessons, Class 8–12 — free with every school on Priodemy EduSuite. Explore more chapters and labs on the Priodemy for School hub.

Ask AI