Class 11Computer Science · Programming with PythonFull chapter

Introduction to Problem Solving

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

The Five Steps of Problem Solving

Quick answer A computer supplies no common sense, so you first analyse a problem into Input, Process and Output with its constraints and edge cases, then design an algorithm, code it, test it and debug it - with testing routinely throwing you back to an earlier step.

A computer is fast and it is exact, but it has no common sense. Tell a friend "book my ticket on IRCTC" and they will fill in a hundred small decisions on their own — which train, which class, which date. Tell a computer the same thing and it fills in nothing. It does exactly what the instructions say, in exactly the order they are written, every single time. So the hard part of programming is not typing Python. The hard part is working out the complete, unambiguous list of steps before you type anything.

CBSE splits that work into five steps.

StepWhat you actually doWhat it produces
1. Analysing the problemRead the problem and list what is given, what is wanted, and what the limits areAn Input-Process-Output description
2. Developing an algorithmWrite the exact sequence of steps as pseudocode, or draw it as a flowchartAn algorithm — still language-independent
3. CodingTranslate the algorithm into PythonA program (source code)
4. TestingRun the program on chosen inputs, including nasty ones, and compare with the answer you already knowA pass/fail result for each test case
5. DebuggingFind why a failing case failed, fix it, and test againA corrected program

Steps 4 and 5 loop back into step 3, and sometimes all the way back to step 1. If testing shows the algorithm itself was wrong, no amount of fiddling with the code will save it.

Step 1 in detail. Analysing a problem means answering three questions before you write a single line:

  • Input — what data is given to me, and in what form?
  • Process — what has to be done to that data?
  • Output — what exactly has to be shown, and in what form?

Two more questions save you most of the pain later. What are the constraints (marks lie between 0 and 100, an age cannot be negative), and what are the edge cases (zero students, all marks equal, a bill of exactly ₹1000)?

Worked example. Problem: a student wrote five unit tests. Print the total, the average, and PASS if the average is 33 or more, otherwise FAIL.

Part of the analysisFor this problem
InputFive marks: 72, 65, 88, 54, 91
Processtotal = sum of the marks; average = total ÷ 5; compare average with 33
OutputTotal, average, and the word PASS or FAIL
ConstraintsEach mark is 0 to 100; there are exactly five tests
Edge casesAll marks 0; average exactly 33; no marks at all
marks = [72, 65, 88, 54, 91]       # INPUT
total = sum(marks)                 # PROCESS
average = total / len(marks)
if average >= 33:
    result = "PASS"
else:
    result = "FAIL"
print("Total   :", total)          # OUTPUT
print("Average :", average)
print("Result  :", result)

Real output:

Total   : 370
Average : 74.0
Result  : PASS

Why the analysis step is not optional. Suppose the student was absent for every test, so the list is empty. The same "process" now blows up:

marks = []                 # the student was absent for every test
average = sum(marks) / len(marks)
print(average)

Real output:

Traceback (most recent call last):
  File "avg.py", line 2, in 
    average = sum(marks) / len(marks)
              ~~~~~~~~~~~^~~~~~~~~~~~
ZeroDivisionError: division by zero

Nothing is wrong with the Python here. The analysis was incomplete — nobody ever decided what an empty list should mean. That decision belongs in step 1, not in step 5.

The computer follows order, not intention. Statements run top to bottom, and a name must exist before it is used.

total = price * qty      # used before they exist
price = 60
qty = 3
print(total)

Real output:

Traceback (most recent call last):
  File "order.py", line 1, in 
    total = price * qty      # used before they exist
            ^^^^^
NameError: name 'price' is not defined. Did you mean: 'print'?

You and I can read those three lines and see what was meant. Python cannot. It reaches line 1, looks for price, finds nothing, and stops. Ordering the steps correctly is part of the algorithm, not an afterthought.

Step 1 - Analysing Problem statement -> { Input, Process, Output } List constraints and edge cases here too. Every bug you avoid at this step costs nothing to avoid.
Step 2 - Algorithm IPO -> finite ordered steps (pseudocode or flowchart) Language-independent. The same algorithm can later become Python, C++ or Java.
Step 3 - Coding Algorithm -> Python source code If coding feels like inventing the logic, step 2 was never finished.
Step 4 - Testing actual output of Run(program, test input) == expected output ? You must already know the right answer, otherwise you are only watching, not testing.
Step 5 - Debugging failing test case -> locate cause -> fix -> retest everything Testing tells you a bug exists; debugging tells you where it lives. They are different steps.
Remember
  • The five steps are analysing the problem, developing an algorithm, coding, testing and debugging; testing regularly sends you back to coding or even back to the analysis.
  • Analysing means writing down Input, Process and Output plus the constraints and edge cases, before any code is typed.
  • An algorithm is designed on paper and is independent of any language; coding is only the translation step.
  • Most beginner bugs are analysis failures wearing a disguise - an empty list, a zero, a negative value that nobody thought about.
  • Python executes statements strictly top to bottom, so using a name before it is assigned raises a NameError rather than being guessed.

Algorithms and Pseudocode

Quick answer An algorithm is a finite, definite, effective sequence of steps with clear input and output, and pseudocode is the structured-English way of writing one down before it becomes Python.

An algorithm is a finite sequence of well-defined steps that solves a problem. The word comes from the name of the 9th-century mathematician al-Khwarizmi. An algorithm is not Python and not any other language — it is the plan. The same algorithm for finding the largest of three numbers works whether you finally write it in Python, in C++, or carry it out with a pencil.

The five characteristics of a valid algorithm. These are exam favourites, so learn the failure column as well as the definition.

CharacteristicWhat it demandsIt fails when…
FinitenessIt must stop after a finite number of stepsa loop condition never becomes false
DefinitenessEvery step means exactly one thinga step says "add a few numbers" or "make it fast"
InputZero or more inputs, clearly specifiedit says "read the marks" without saying how many
OutputAt least one result is producedit computes something and never reports it
EffectivenessEach step is basic enough to be done by hand in finite timea step says "guess the correct answer"

Pseudocode is an algorithm written in structured English. No computer runs it, so no compiler will catch a mistake — the discipline has to come from you. There is no single official standard, so pick a set of keywords and stay consistent for the whole answer. These are the ones used throughout this chapter.

PurposeKeywordExample
Start and endBEGIN … ENDBEGIN
InputREADREAD n
OutputPRINTPRINT total
AssignmentSET … = …SET total = 0
Two-way decisionIF … THEN … ELSE … ENDIFIF n > 0 THEN
Multi-way decisionELSE IFELSE IF n = 0 THEN
Pre-test loopWHILE … DO … ENDWHILEWHILE i <= n DO
Counted loopFOR … TO … DO … ENDFORFOR i = 1 TO 10 DO
Leave a loop earlyEXIT LOOPEXIT LOOP
RemainderMODIF num MOD 5 = 0 THEN
Division, remainder discardedDIVSET temp = temp DIV 10
Comment//// i counts the terms

Two rows there deserve a second look, because they are where pseudocode and Python quietly disagree. MOD and DIV become % and // when you code them. But // in this pseudocode starts a comment, while // in Python is floor division. Same two characters, opposite meanings — keep track of which language you are currently writing in.

Worked example 1 — largest of three numbers (selection).

BEGIN
    READ a, b, c
    IF a >= b AND a >= c THEN
        SET largest = a
    ELSE IF b >= c THEN
        SET largest = b
    ELSE
        SET largest = c
    ENDIF
    PRINT largest
END

The same algorithm coded in Python:

a, b, c = 47, 92, 92

if a >= b and a >= c:
    largest = a
elif b >= c:
    largest = b
else:
    largest = c

print("a =", a, " b =", b, " c =", c)
print("Largest =", largest)

Real output:

a = 47  b = 92  c = 92
Largest = 92

Two things worth noticing. The second test compares only b with c — if the first test failed, then a was not greater than or equal to both of the others, so a cannot be the largest and re-testing it would be wasted work. And >= is used instead of > so that ties are handled: 47, 92, 92 must still report 92 rather than falling through every branch. Deliberately testing with equal values is exactly the edge-case thinking from step 1.

Worked example 2 — sum of the first n natural numbers (iteration).

BEGIN
    READ n
    SET total = 0
    SET i = 1
    WHILE i <= n DO
        SET total = total + i
        SET i = i + 1
    ENDWHILE
    PRINT total
END

In Python, with an extra print inside the loop so you can watch the algorithm work:

n = 5
total = 0
i = 1
while i <= n:
    total = total + i
    print("i =", i, "-> total =", total)
    i = i + 1
print("Sum of first", n, "natural numbers =", total)

Real output:

i = 1 -> total = 1
i = 2 -> total = 3
i = 3 -> total = 6
i = 4 -> total = 10
i = 5 -> total = 15
Sum of first 5 natural numbers = 15

Breaking finiteness. Delete one line — the one that changes i — and it stops being an algorithm at all:

SET total = 0
SET i = 1
WHILE i <= n DO
    SET total = total + i      // i is never changed
ENDWHILE

The condition i <= n is true on the first check and stays true forever, so the steps never end. Every loop needs three things: a starting value, a condition, and something inside the body that eventually makes the condition false. If you cannot point to all three, the loop is broken.

Algorithm finite + definite + effective + (0 or more inputs) + (1 or more outputs) All five must hold. Miss any one and it is a procedure, not an algorithm.
Assignment SET variable = expression The right side is worked out first, then stored on the left. SET i = i + 1 is legal, unlike in maths.
Selection IF condition THEN ... ELSE ... ENDIF Always close with ENDIF in pseudocode so a nested IF cannot be misread.
Pre-test loop WHILE condition DO ... ENDWHILE Tests before the body, so it may run zero times. Needs initialisation before it and an update inside it.
Counted loop FOR i = start TO end DO ... ENDFOR Use when the number of repetitions is known in advance; the counter updates automatically.
Integer arithmetic a MOD b -> remainder ; a DIV b -> quotient, remainder discarded In Python these are a % b and a // b. 4523 MOD 10 is 3 and 4523 DIV 10 is 452.
Loop safety check initialisation + condition + update-that-falsifies Missing the update is the single commonest cause of a non-terminating algorithm.
Remember
  • An algorithm is a finite sequence of well-defined steps; it is written before coding and is independent of the programming language.
  • The five characteristics are finiteness, definiteness, input, output and effectiveness - an endless loop violates finiteness, and a vague step violates definiteness.
  • Pseudocode is structured English, is never executed by a computer, and has no single official standard, so pick one set of keywords and use it consistently through the whole answer.
  • Pseudocode MOD and DIV become Python % and //, but pseudocode // is a comment marker, which is not what // means in Python.
  • Every loop needs an initialisation, a condition, and an update inside the body that eventually falsifies the condition.
  • In a multi-way selection, later tests only need to compare the values that are still in the running.

Drawing the Logic: Flowcharts

Quick answer A flowchart is the same algorithm drawn with standard shapes - oval, parallelogram, rectangle, diamond, connector and arrows - built entirely from the three control structures of sequence, selection and iteration.

A flowchart is an algorithm drawn as boxes joined by arrows. Pseudocode is faster to write; a flowchart is far easier to see, especially when the logic branches. CBSE expects you to know the standard symbols and to be able to convert freely between flowchart, pseudocode and Python.

SymbolNameUsed forExample
OvalTerminalStart or stopSTART, STOP
ParallelogramInput / OutputReading data in, printing results outREAD marks, PRINT total
RectangleProcessCalculation or assignmenttotal = total + i
DiamondDecisionA yes/no question with exactly two labelled exitsis marks >= 33 ?
CircleConnectorJoining parts of a chart split across pagesA, B
ArrowFlow lineThe direction control travels—>

Four rules the examiner checks: exactly one START, at least one STOP, every decision has both exits labelled Yes and No, and every arrow points in one direction only. Since this page cannot draw real shapes, the charts below use text boxes and name the shape in a comment. On your answer sheet, draw the real shapes.

The three control structures. Everything you write this year is built from just these three patterns.

1. Sequence — one step after another, no choices.

   ( START )        oval
       |
  / READ n /        parallelogram
       |
  [ sq = n * n ]    rectangle
       |
  / PRINT sq /      parallelogram
       |
   ( STOP )         oval

2. Selection — the path splits and then rejoins.

            |
            v
   +--------------------+
   |  is marks >= 33 ?  |   diamond
   +--------------------+
      | Yes        | No
      v            v
  [ PRINT     ]  [ PRINT     ]
  [ "PASS"    ]  [ "FAIL"    ]
      |            |
      +-----+------+
            |
            v

3. Iteration — an arrow goes back up, and the decision is the only way out.

   [ SET i = 1 ]
         |
         v
   +--------------------+   No
+->|  is i <= 10 ?      |--------> exit loop
|  +--------------------+
|        | Yes
|        v
|  [ PRINT i ]
|        |
|        v
|  [ SET i = i + 1 ]
|        |
+--------+

Worked example 1 — leap year (nested selection). A year is a leap year if it is divisible by 400; otherwise, if it is divisible by 100 it is not; otherwise, if it is divisible by 4 it is; otherwise it is not.

          +-------------------+
          |      START        |   oval
          +-------------------+
                    |
                    v
          / READ year /            parallelogram
                    |
                    v
          +-------------------+
          | year MOD 400 = 0 ?|   diamond
          +-------------------+
             | Yes      | No
             |          v
             |   +-------------------+
             |   | year MOD 100 = 0 ?|   diamond
             |   +-------------------+
             |      | Yes      | No
             |      |          v
             |      |   +------------------+
             |      |   | year MOD 4 = 0 ? |   diamond
             |      |   +------------------+
             |      |      | Yes     | No
             v      v      v         v
         [leap=  ][leap=  ][leap=  ][leap=  ]
         [ True  ][ False ][ True  ][ False ]
             |      |      |         |
             +------+---+--+---------+
                        |
                        v
              / PRINT leap /          parallelogram
                        |
                        v
                  (  STOP  )          oval

Coded in Python and run on four years chosen to hit every branch:

for year in [1900, 2000, 2023, 2024]:
    if year % 400 == 0:
        leap = True
    elif year % 100 == 0:
        leap = False
    elif year % 4 == 0:
        leap = True
    else:
        leap = False
    print(year, "-> leap year?", leap)

Real output:

1900 -> leap year? False
2000 -> leap year? True
2023 -> leap year? False
2024 -> leap year? True

The order of the diamonds is the whole algorithm. Test 400 first, because 2000 is divisible by 4, by 100 and by 400, and only the first matching test decides the answer. Swap the first two diamonds and 2000 wrongly comes out as False, a non-leap year.

Worked example 2 — multiplication table (iteration).

          +----------------+
          |     START      |          oval
          +----------------+
                   |
                   v
          / READ num /                parallelogram
                   |
                   v
          +----------------+
          |   SET i = 1    |          rectangle
          +----------------+
                   |
                   v
          +----------------+   No
       +->| is i <= 10 ?   |------+   diamond
       |  +----------------+      |
       |           | Yes          v
       |           v         (  STOP  )
       |  / PRINT num * i /
       |           |
       |           v
       |  +----------------+
       |  | SET i = i + 1  |
       |  +----------------+
       |           |
       +-----------+
num = 7
i = 1
while i <= 10:
    print(num, "x", i, "=", num * i)
    i = i + 1
print("Table over")

Real output:

7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
Table over

Which one should you use?

BasisFlowchartPseudocode
FormDiagram of standard shapesStructured English text
Best atShowing branches and loops at a glanceWriting long algorithms quickly
Weak atLong algorithms — the page runs outMaking branching visually obvious
Standardised?Yes, the symbols are fixedNo, keep your own style consistent
Runs on a computer?NoNo
Terminal (oval) ( START ) ... ( STOP ) Exactly one START; at least one STOP. Marks are cut for a chart with no STOP.
Input / Output (parallelogram) / READ x / or / PRINT y / Any data crossing the program boundary. Calculation never goes in this shape.
Process (rectangle) [ total = total + i ] Assignment and arithmetic. One clear action per box.
Decision (diamond) is condition ? -> Yes branch / No branch Two exits, both labelled. A loop's back-arrow always re-enters above a decision.
Connector (circle) ( A ) jumps to ( A ) Only for continuing a chart on the next page. Never use it to dodge drawing an arrow.
Loop shape init -> decision -> body -> update -> back to decision If the arrow returns below the update box, the counter never advances and the loop never ends.
Remember
  • Oval means terminal, parallelogram means input or output, rectangle means process, diamond means decision, circle means connector, and arrows carry the flow.
  • A decision symbol has exactly two exits and both must be labelled Yes and No.
  • Sequence, selection and iteration are the only three control structures needed; every flowchart is a combination of them.
  • In a chain of decisions the order matters - the leap-year test must check 400 before 100, or the year 2000 comes out wrong.
  • A flowchart is clearer for branching logic while pseudocode scales better to long algorithms; neither is executed by a computer.

Coding, Testing and Debugging

Quick answer Coding turns the algorithm into Python, testing runs it on normal, boundary and invalid inputs whose answers you already know, and debugging traces the failing case through a dry run to find the syntax, run-time or logical error behind it.

Once the algorithm is settled, coding is mostly translation. Three habits make the debugging step short: meaningful names (total_marks, not t), one idea per line, and a comment wherever the reason for a line is not obvious from the line itself.

Three kinds of errors. This table is worth memorising in full.

KindCauseWhen you find outTypical examples
Syntax errorYou broke a grammar rule of the Python languageBefore anything runs — Python refuses to startMissing colon, unbalanced bracket, wrong indentation, misspelt keyword
Run-time errorThe code is legal Python, but a particular input makes an operation impossibleMidway through the run, with a tracebackDivision by zero, int("Rahul"), an undefined name
Logical (semantic) errorThe instructions are legal and they run, but they are the wrong instructionsNever — unless you test. This is the dangerous oneWrong formula, missing brackets, wrong operator, conditions in the wrong order

Syntax error — real run.

price = 250
if price > 100
    print("Discount applies")
  File "bill.py", line 2
    if price > 100
                  ^
SyntaxError: expected ':'

Notice that the correct line 1 never ran either. A syntax error stops the whole file before execution begins.

Run-time error — real run.

age = "Rahul"
print(int(age) + 1)
Traceback (most recent call last):
  File "age.py", line 2, in 
    print(int(age) + 1)
          ~~~^^^^^
ValueError: invalid literal for int() with base 10: 'Rahul'

Read a traceback from the bottom up. The last line names the error, the line above shows the exact statement, and the arrows point at the guilty part of it.

Logical error — real run. This one is the reason testing exists.

marks = [40, 50, 60]
average = marks[0] + marks[1] + marks[2] / 3
print("Average =", average)
Average = 110.0

No error message, no traceback, a confident wrong answer. Python obeyed precedence and divided only 60 by 3, giving 40 + 50 + 20. The fix is one pair of brackets:

marks = [40, 50, 60]
average = (marks[0] + marks[1] + marks[2]) / 3
print("Average =", average)
Average = 50.0

Testing. Testing means running the program on inputs whose correct answer you already know, and comparing. Pick test cases from three groups:

  • Normal values — an ordinary case from the middle of the range.
  • Boundary values — exactly on the limit, and one step either side. Most bugs hide here.
  • Invalid or special values — zero, negative numbers, empty input, text where a number was expected.

Take the rule: a shop gives 10% discount when the bill is more than ₹1000. The boundary is 1000, so test 999, 1000 and 1001.

# Rule: 10% discount only when the bill is MORE THAN 1000 rupees.
for bill in [999, 1000, 1001, 0]:
    if bill > 1000:
        payable = bill - bill * 0.10
    else:
        payable = bill
    print("bill =", bill, "-> payable =", payable)

Real output:

bill = 999 -> payable = 999
bill = 1000 -> payable = 1000
bill = 1001 -> payable = 900.9
bill = 0 -> payable = 0
TestInputWhy this caseExpectedObservedResult
T1999Just below the boundary999999Pass
T21000Exactly on the boundary — no discount10001000Pass
T31001Just above the boundary900.9900.9Pass
T40Special value00Pass

If the programmer had written bill >= 1000, tests T1, T3 and T4 would still pass — only T2 changes, from 1000 to 900.0. That single case is the whole reason boundary values are non-negotiable.

Debugging with a dry run. A dry run (trace table) means executing the code in your head, one line at a time, writing down every variable after every step. Here the program is asked for the largest of five numbers:

nums = [12, 45, 7, 99, 3]
largest = nums[0]
for n in nums:
    if n > largest:
        largest = n
    print("n =", n, "-> largest so far =", largest)
print("Largest =", largest)

Real output:

n = 12 -> largest so far = 12
n = 45 -> largest so far = 45
n = 7 -> largest so far = 45
n = 99 -> largest so far = 99
n = 3 -> largest so far = 99
Largest = 99
PassnIs n > largest ?largest after this pass
before loop——12
112No12
245Yes45
37No45
499Yes99
53No99

Four debugging techniques worth having:

  1. Dry run on paper with a trace table — the only method that works when there is no error message at all.
  2. Extra print statements inside loops and branches, exactly as done above, then delete them once fixed.
  3. Comment out a block to see whether the bug disappears, which narrows down where it lives.
  4. Explain the code out loud, line by line, to a friend or an empty chair. You will usually catch the wrong line while saying it.
Syntax error detected before execution -> 0 lines run Python prints the file, the line number and a caret. Fix it top-down; one mistake often reports oddly on the next line.
Run-time error legal code + bad input -> Traceback ... : ErrorName Depends on the input, so the same program can run fine one day and crash the next.
Logical error program runs + output is wrong -> no message Only testing against a known correct answer will expose it.
Test case ( input, expected output ) -> compare with observed You must be able to state the expected output before running, otherwise it is not a test.
Boundary testing test at limit L, and at L-1 and L+1 Catches the classic > versus >= mistake. Ordinary mid-range values never will.
Dry run / trace table columns = every variable ; rows = every step Do it exactly as Python would, not as you meant it - the point is to find where the two differ.
Remember
  • A syntax error stops the file before any line runs, a run-time error stops it midway with a traceback, and a logical error never announces itself at all.
  • Read a traceback from the bottom upwards: the last line names the error, the line above points to the guilty statement.
  • Testing needs inputs whose correct answer you already know, drawn from normal, boundary and invalid values.
  • Boundary tests catch off-by-one mistakes such as > written where >= was meant; ordinary test values will not.
  • A dry run or trace table records every variable after every step and is the standard way to hunt a logical error.

Decomposition: Breaking a Big Problem Down

Quick answer Decomposition splits one large problem into smaller sub-problems that can be solved, tested and reused independently - the same idea that lets math, random and statistics hand you solved sub-problems for free.

Nobody can hold a five-hundred-step problem in their head. Decomposition is the habit of breaking a large problem into smaller sub-problems, each small enough to be understood, solved and tested on its own, and then joining the solutions back together.

Four reasons it is worth the effort:

  • Each small piece is easy to check, so a bug is trapped inside one piece instead of hiding in the whole program.
  • Pieces can be reused. "Find the highest mark" is needed by the report card, the merit list and the topper announcement.
  • Work can be split. Four students in a project team can take one sub-problem each.
  • Changes stay local. If the grading rule changes, only the grading piece is touched.

Worked example — a class result report. "Print the result report for a section" is too big to attack directly. Decompose it:

Sub-problemInputOutput
1. Collect the dataNames and marksTwo matching lists
2. Check the data is usableThe two listsTrue if the counts match
3. Compute the statisticsThe marks listHighest, lowest, mean, median, mode
4. Present the reportAll of the abovePrinted lines
import statistics
import math

# ---- Sub-problem 1: collect the data ----
names = ["Aarav", "Diya", "Kabir", "Meera", "Rohan"]
marks = [78, 91, 55, 91, 62]

# ---- Sub-problem 2: check the data is usable ----
print("Records match?", len(names) == len(marks))

# ---- Sub-problem 3: compute the statistics ----
highest = max(marks)
lowest = min(marks)
mean = statistics.mean(marks)
median = statistics.median(marks)
mode = statistics.mode(marks)

# ---- Sub-problem 4: present the report ----
print("Topper  :", names[marks.index(highest)], "with", highest)
print("Lowest  :", lowest)
print("Mean    :", mean)
print("Median  :", median)
print("Mode    :", mode)
print("Mean rounded up :", math.ceil(mean))

Real output:

Records match? True
Topper  : Diya with 91
Lowest  : 55
Mean    : 75.4
Median  : 78
Mode    : 91
Mean rounded up : 76

Each block can be tested by itself. If the topper line is wrong, you know the bug is in sub-problem 3 or 4 and never touch sub-problem 1.

Someone has already decomposed a lot for you. Built-in functions such as sum(), max(), len(), and modules such as math, random and statistics, are sub-problems that other programmers solved and packaged. Finding a square root is a genuine sub-problem — here it is solved by hand with the Babylonian method, then compared with the packaged version:

import math

n = 2
guess = 1.0
step = 1
while step <= 5:
    guess = (guess + n / guess) / 2
    print("step", step, "-> guess =", guess)
    step = step + 1

print("My answer   :", guess)
print("math.sqrt(2):", math.sqrt(n))

Real output:

step 1 -> guess = 1.5
step 2 -> guess = 1.4166666666666665
step 3 -> guess = 1.4142156862745097
step 4 -> guess = 1.4142135623746899
step 5 -> guess = 1.414213562373095
My answer   : 1.414213562373095
math.sqrt(2): 1.4142135623730951

Five lines of loop get to within one digit of math.sqrt, which is impressive. That last digit is worth understanding, though, because it is not impatience on the loop's part. Running the same loop for 6, 7 or 8 steps prints exactly the same value — the iteration has settled on a number it can no longer improve, and that number sits one tiny step below the closest value the computer can store for the square root of 2. math.sqrt is built to land on that closest value every time. So the packaged sub-problem here is not merely shorter than the hand-written one, it is also more accurate. Once a sub-problem is solved and trusted, you use the solved version and spend your thinking on the parts that are actually new.

Worked example — a dice experiment. "Throw a die ten times and summarise the result" decomposes into generate, then summarise:

import random
import statistics

random.seed(11)            # fixes the sequence so the result is repeatable

# Sub-problem 1: generate the throws
throws = []
count = 1
while count <= 10:
    throws.append(random.randint(1, 6))
    count = count + 1

# Sub-problem 2: summarise them
print("Throws  :", throws)
print("Highest :", max(throws))
print("Sixes   :", throws.count(6))
print("Mean    :", statistics.mean(throws))

Real output (identical on every run, because of the seed):

Throws  : [4, 5, 4, 4, 5, 5, 2, 2, 5, 4]
Highest : 5
Sixes   : 0
Mean    : 4

random.seed(11) is itself a testing tool. Random output cannot be tested, because you never know the expected answer; fixing the seed makes the sequence repeatable so the summarising half can be tested properly.

How to decompose in an exam answer. Write the main problem at the top, list its sub-problems as numbered steps, and beside each write its input and its output. If a sub-problem still needs more than about five or six steps to describe, break it again. In Class 12 you will learn how to package each sub-problem under a name of its own; for now, a clearly commented block of code per sub-problem is exactly the right structure.

Decomposition rule Problem -> sub-problem 1 + sub-problem 2 + ... , each with its own IPO If describing a sub-problem still takes more than five or six steps, split it again.
sum() / max() / min() sum(list) -> number ; max(list) -> item ; min(list) -> item Built-in. On strings they compare character codes, not the dictionary: every capital letter counts as smaller than every small letter, so max(["apple", "Zebra"]) is "apple".
list.index() / list.count() L.index(item) -> position ; L.count(item) -> how many times index() returns the FIRST match only, and raises ValueError if the item is absent.
statistics module statistics.mean(L) / median(L) / mode(L) Needs import statistics. mode() returns the first most-common value; all three raise StatisticsError on an empty list.
math module math.sqrt(x) / math.ceil(x) / math.floor(x) Needs import math. ceil() rounds up and floor() rounds down, so math.floor(-2.5) is -3, not -2.
random module random.randint(a, b) -> integer in a...b ; random.seed(k) randint includes BOTH ends. Set a seed while testing, remove it in the finished program.
Remember
  • Decomposition breaks one large problem into smaller sub-problems that can be understood, solved and tested independently.
  • It makes bugs local, lets pieces be reused, allows work to be split across a team, and keeps later changes confined to one piece.
  • For each sub-problem, state its input and its output - that is what lets the pieces be joined together correctly.
  • Built-in functions and the math, random and statistics modules are sub-problems already solved and packaged for you, and a packaged solution is usually more accurate than a hand-rolled one, not merely shorter.
  • Fixing random.seed() makes random output repeatable, which is what makes a program that uses random numbers testable at all.

The formula sheet

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

Problem statement -> { Input, Process, Output }
Step 1 - Analysing
IPO -> finite ordered steps (pseudocode or flowchart)
Step 2 - Algorithm
Algorithm -> Python source code
Step 3 - Coding
actual output of Run(program, test input) == expected output ?
Step 4 - Testing
failing test case -> locate cause -> fix -> retest everything
Step 5 - Debugging
finite + definite + effective + (0 or more inputs) + (1 or more outputs)
Algorithm
SET variable = expression
Assignment
IF condition THEN ... ELSE ... ENDIF
Selection
WHILE condition DO ... ENDWHILE
Pre-test loop
FOR i = start TO end DO ... ENDFOR
Counted loop
a MOD b -> remainder ; a DIV b -> quotient, remainder discarded
Integer arithmetic
initialisation + condition + update-that-falsifies
Loop safety check
( START ) ... ( STOP )
Terminal (oval)
/ READ x / or / PRINT y /
Input / Output (parallelogram)
[ total = total + i ]
Process (rectangle)
is condition ? -> Yes branch / No branch
Decision (diamond)
( A ) jumps to ( A )
Connector (circle)
init -> decision -> body -> update -> back to decision
Loop shape
detected before execution -> 0 lines run
Syntax error
legal code + bad input -> Traceback ... : ErrorName
Run-time error
program runs + output is wrong -> no message
Logical error
( input, expected output ) -> compare with observed
Test case
test at limit L, and at L-1 and L+1
Boundary testing
columns = every variable ; rows = every step
Dry run / trace table
Problem -> sub-problem 1 + sub-problem 2 + ... , each with its own IPO
Decomposition rule
sum(list) -> number ; max(list) -> item ; min(list) -> item
sum() / max() / min()
L.index(item) -> position ; L.count(item) -> how many times
list.index() / list.count()
statistics.mean(L) / median(L) / mode(L)
statistics module
math.sqrt(x) / math.ceil(x) / math.floor(x)
math module
random.randint(a, b) -> integer in a...b ; random.seed(k)
random module

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

In the CBSE list of problem-solving steps, which step comes immediately after developing an algorithm?

Q2

What is the exact output of this code?x = 10y = 3print(x // y, x % y, x / y)

Q3

A set of steps says 'SET i = 1; WHILE i <= 5 DO: SET total = total + i; ENDWHILE'. Which characteristic of an algorithm does it violate?

Q4

What is the exact output of this code?a = 5b = 0while a > 0: b = b + a a = a - 2print(a, b)

Q5

In a flowchart, which symbol is used to ask a question that has exactly two possible answers?

Q6

What is the exact output of this code?m = 85if m >= 33: g = "Pass"elif m >= 75: g = "Distinction"print(g)

Q7

A student writes if price > 100 and forgets the colon. What kind of error is this, and when is it detected?

Q8

What is the exact output of this code?n = 1234s = 0while n > 0: s = s + n % 10 n = n // 10print(s)

Q9

Which statement best describes decomposition?

Q10

What is the exact output of this code?c = 0for i in range(1, 10, 3): c = c + iprint(c)

Q11

Which of these is NOT a characteristic that a valid algorithm must have?

Q12

A shop's rule is: give a 10% discount when the bill is more than ₹1000. Which single test input is most likely to expose an off-by-one mistake in the condition?

NCERT solutions & previous-year questions

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

NCERT questions 6

1 Write pseudocode and draw a flowchart where multiple conditions are checked to categorise a person as either a child (age below 13), a teenager (age 13 or above but below 20), or an adult (age 20 or above), based on the age given as input.Multi-way selection: pseudocode, flowchart and code

Analysis. Input: the age. Process: compare against the two cut-offs 13 and 20. Output: one of three words. Boundary cases to test: exactly 13 and exactly 20.

Pseudocode

BEGIN
    READ age
    IF age < 13 THEN
        SET category = "Child"
    ELSE IF age < 20 THEN
        SET category = "Teenager"
    ELSE
        SET category = "Adult"
    ENDIF
    PRINT category
END

The second test is written simply as age < 20. Control only reaches it when age < 13 has already failed, so age >= 13 is guaranteed and need not be re-checked.

Flowchart

        (  START  )                oval
             |
             v
        / READ age /               parallelogram
             |
             v
     +-----------------+
     |   age < 13 ?    |           diamond
     +-----------------+
       | Yes      | No
       |          v
       |   +-----------------+
       |   |   age < 20 ?    |     diamond
       |   +-----------------+
       |     | Yes      | No
       v     v          v
  [category ][category ][category ]  rectangles
  [="Child" ][="Teen-  ][="Adult" ]
  [         ][  ager"  ][         ]
       |     |          |
       +-----+----+-----+
                  |
                  v
         / PRINT category /        parallelogram
                  |
                  v
            (  STOP  )             oval

Python, run on the boundary values

for age in [8, 13, 19, 20, 45]:
    if age < 13:
        category = "Child"
    elif age < 20:
        category = "Teenager"
    else:
        category = "Adult"
    print("age =", age, "->", category)

Real output

age = 8 -> Child
age = 13 -> Teenager
age = 19 -> Teenager
age = 20 -> Adult
age = 45 -> Adult

13 correctly comes out as Teenager and 20 as Adult, which is what the boundary tests were chosen to confirm.

2 Write pseudocode and draw a flowchart to accept three numbers and print the largest of the three.Selection with compound conditions

Analysis. Input: three numbers a, b, c. Process: compare them. Output: the largest value. Edge case: two or three numbers being equal — the algorithm must still print one answer, not fall through every branch.

Pseudocode

BEGIN
    READ a, b, c
    IF a >= b AND a >= c THEN
        SET largest = a
    ELSE IF b >= a AND b >= c THEN
        SET largest = b
    ELSE
        SET largest = c
    ENDIF
    PRINT largest
END

Flowchart

        (  START  )                     oval
             |
             v
      / READ a, b, c /                  parallelogram
             |
             v
   +--------------------------+
   |  a >= b AND a >= c ?     |         diamond
   +--------------------------+
      | Yes            | No
      |                v
      |     +--------------------------+
      |     |  b >= a AND b >= c ?     |  diamond
      |     +--------------------------+
      |        | Yes           | No
      v        v               v
  [largest ][largest      ][largest      ]  rectangles
  [ = a    ][ = b         ][ = c         ]
      |        |               |
      +--------+-------+-------+
                       |
                       v
              / PRINT largest /        parallelogram
                       |
                       v
                 (  STOP  )           oval

Python, run on three cases including ties

for a, b, c in [(12, 45, 7), (99, 99, 12), (5, 5, 5)]:
    if a >= b and a >= c:
        largest = a
    elif b >= a and b >= c:
        largest = b
    else:
        largest = c
    print(a, b, c, "-> largest =", largest)

Real output

12 45 7 -> largest = 45
99 99 12 -> largest = 99
5 5 5 -> largest = 5

Using >= rather than > is what makes the tie cases work, and it is not a cosmetic choice — strict > gives a wrong answer on three numbers, not just on bigger versions of the problem:

for a, b, c in [(5, 5, 5), (7, 7, 2)]:
    if a > b and a > c:          # strict > : the broken version
        largest = a
    elif b > a and b > c:
        largest = b
    else:
        largest = c
    print(a, b, c, "-> largest =", largest)

Real output

5 5 5 -> largest = 5
7 7 2 -> largest = 2

On 7, 7, 2 the first test a > b fails because the two 7s are equal, the second test b > a fails for exactly the same reason, and control drops into the ELSE and prints 2 — the smallest of the three. Notice that 5, 5, 5 still comes out right, because there the ELSE returns c, which happens to be 5 as well. That is precisely what makes this bug easy to miss: if 5, 5, 5 is the only tie you test, the program looks correct.

A note on the second condition. It is written out in full as b >= a AND b >= c, which is safe and reads clearly in an exam. Strictly the b >= a half is not needed: control only arrives there after a >= b AND a >= c has already failed, so a is already known not to be the largest and b >= c alone decides it — that is the shorter form used earlier in the chapter. Either version earns full marks; be able to explain why the shorter one is enough.

3 Write pseudocode that reads two numbers and divides one by the other, displaying the quotient. Dividing a number by zero must be handled.Guarding against an invalid input

Analysis. Input: num1 and num2. Process: divide num1 by num2, but only if num2 is not zero. Output: the quotient, or a message. This is exactly the kind of case that must be caught at the analysis stage, because in Python it produces a run-time error, not a wrong number.

Pseudocode

BEGIN
    READ num1, num2
    IF num2 = 0 THEN
        PRINT "Division by zero is not allowed"
    ELSE
        SET quotient = num1 / num2
        PRINT quotient
    ENDIF
END

The check comes before the division. Checking afterwards is useless, because the program has already crashed by then.

Python, run on a valid case, the zero case, and a negative case

for num1, num2 in [(45, 5), (7, 0), (-9, 2)]:
    if num2 == 0:
        print(num1, "/", num2, "-> Division by zero is not allowed")
    else:
        print(num1, "/", num2, "->", num1 / num2)

Real output

45 / 5 -> 9.0
7 / 0 -> Division by zero is not allowed
-9 / 2 -> -4.5

Without the guard, the middle case would stop the program with ZeroDivisionError: division by zero and the third case would never run at all. Note also that / always returns a float, which is why 45 / 5 prints as 9.0 and not 9.

4 Write pseudocode to print all the multiples of 5 between 10 and 25 (including both 10 and 25).Iteration with a condition inside the loop

Analysis. Input: none — the range is fixed by the problem. Process: walk from 10 to 25 and keep the numbers divisible by 5. Output: 10, 15, 20, 25. The words "including both" fix the loop condition as <= 25, not < 25.

Pseudocode

BEGIN
    SET num = 10
    WHILE num <= 25 DO
        IF num MOD 5 = 0 THEN
            PRINT num
        ENDIF
        SET num = num + 1
    ENDWHILE
END

Python

num = 10
while num <= 25:
    if num % 5 == 0:
        print(num, end=" ")
    num = num + 1
print()

Real output

10 15 20 25

A shorter algorithm. Since 10 is already a multiple of 5, you can step by 5 and drop the IF altogether:

BEGIN
    SET num = 10
    WHILE num <= 25 DO
        PRINT num
        SET num = num + 5
    ENDWHILE
END

Both are correct algorithms for the same problem, and both print the same four numbers. The first makes 16 passes through the loop and the second makes 4, which is a good illustration of why the algorithm step deserves thought before the coding step.

5 Write pseudocode and draw a flowchart to input a number and check whether it is a prime number or a composite number.Iteration with a flag variable

Analysis. Input: a number num. Process: try to divide num by every integer from 2 up to num DIV 2; if any of them divides exactly, num is composite. Output: "Prime" or "Composite". Special case: 1 is neither prime nor composite, and it must be handled separately or the algorithm reports it wrongly as prime.

Pseudocode

BEGIN
    READ num
    IF num < 2 THEN
        PRINT "Neither prime nor composite"
    ELSE
        SET flag = 0
        SET i = 2
        WHILE i <= num DIV 2 DO
            IF num MOD i = 0 THEN
                SET flag = 1
                EXIT LOOP
            ENDIF
            SET i = i + 1
        ENDWHILE
        IF flag = 0 THEN
            PRINT "Prime"
        ELSE
            PRINT "Composite"
        ENDIF
    ENDIF
END

Flowchart of the main loop. Note that there are two ways out of the loop and they meet at the same place: the loop can run out of values to try, or it can be left early by EXIT LOOP once a divisor is found. Both paths lead to the single test on flag.

   [ SET flag = 0 ]
   [ SET i = 2    ]                 rectangles
          |
          v
   +--------------------+   No
+->|  i <= num DIV 2 ?  |----------------+   diamond
|  +--------------------+                |
|          | Yes                         |
|          v                             |
|  +--------------------+   Yes          |
|  |  num MOD i = 0 ?   |--------+       |   diamond
|  +--------------------+        |       |
|          | No                  v       |
|          v              [ SET flag = 1 ]   rectangle
|  +--------------------+        |       |
|  |   SET i = i + 1    |        |       |
|  +--------------------+        |       |
|          |                     |       |
+----------+                     v       v
                          +---------------------+
                          |     flag = 0 ?      |   diamond
                          +---------------------+
                            | Yes        | No
                            v            v
                    / PRINT "Prime" /  / PRINT "Composite" /
                            |            |
                            +-----+------+
                                  |
                                  v
                            (  STOP  )        oval

Python, run on the tricky values as well as ordinary ones

for num in [1, 2, 9, 17, 21]:
    if num < 2:
        verdict = "Neither prime nor composite"
    else:
        i = 2
        flag = 0
        while i <= num // 2:
            if num % i == 0:
                flag = 1
                break
            i = i + 1
        if flag == 0:
            verdict = "Prime"
        else:
            verdict = "Composite"
    print(num, "->", verdict)

Real output

1 -> Neither prime nor composite
2 -> Prime
9 -> Composite
17 -> Prime
21 -> Composite

Check 2 by hand: num // 2 is 1, so the condition 2 <= 1 is false and the loop body never runs, leaving flag at 0 and the verdict Prime. That is the correct answer, and it is the case most students get wrong when they start the loop at 1 instead of 2. Note also that pseudocode DIV becomes Python //, and pseudocode MOD becomes Python %.

6 Give an example of a loop that never terminates. Which characteristic of an algorithm does it violate, and how would you correct it?Finiteness and loop control

The example.

SET i = 1
WHILE i <= 5 DO
    PRINT i
ENDWHILE

Which characteristic is violated. Finiteness. An algorithm must terminate after a finite number of steps. Here i is set to 1 and nothing inside the loop ever changes it, so the condition i <= 5 is true on the first check and true on every check after that. The steps never end, so this set of instructions is not a valid algorithm at all — the other four characteristics (definiteness, input, output, effectiveness) are all satisfied, which is exactly why the mistake is easy to miss.

Demonstrating it safely. A genuinely endless loop would hang the machine, so the run below adds a safety counter purely so that it can print and stop. The bug — i never changing — is untouched.

# The bug: i is never increased, so "i <= 5" is True forever.
# A safety counter is added ONLY so this demo can print and stop.
i = 1
rounds = 0
while i <= 5 and rounds < 4:
    print("round", rounds + 1, ": i is still", i)
    rounds = rounds + 1
print("i never changed. Without the safety counter this loop never ends.")

print("--- corrected ---")
i = 1
while i <= 5:
    print("i =", i, end="  ")
    i = i + 1
print()
print("Loop ended because i became", i)

Real output

round 1 : i is still 1
round 2 : i is still 1
round 3 : i is still 1
round 4 : i is still 1
i never changed. Without the safety counter this loop never ends.
--- corrected ---
i = 1  i = 2  i = 3  i = 4  i = 5
Loop ended because i became 6

The correction. Add the update statement inside the loop body:

SET i = 1
WHILE i <= 5 DO
    PRINT i
    SET i = i + 1        // this is what was missing
ENDWHILE

The general rule. Every loop needs three things, and you should be able to point to all three before you move on: an initialisation before the loop, a condition that controls it, and an update inside the body that eventually makes the condition false. Note in the corrected run that the loop ends only when i reaches 6, one past the last value printed — the loop variable always overshoots by one step.

Previous-year board questions 4

Q1 Differentiate between an algorithm and a flowchart. Also state why pseudocode is used even though it cannot be executed by a computer. Board pattern - 2 marks

Algorithm vs flowchart

BasisAlgorithmFlowchart
What it isA finite sequence of well-defined steps that solves a problemA pictorial representation of that same sequence of steps
FormWritten in words, usually as pseudocodeDrawn using standard symbols joined by arrows
StrengthCompact; scales well to long solutionsBranching and loops can be seen at a glance
WeaknessBranching is harder to follow visuallyBecomes large and unreadable for long solutions

Strictly, a flowchart is one way of representing an algorithm; pseudocode is the other. They are not rivals — the same algorithm can be shown as either.

Why pseudocode is used. It lets you fix the logic before worrying about the grammar of any one language. Because it is language-independent, the same pseudocode can later be coded in Python, C++ or Java. It is much faster to write and correct than real code, and a mistake found at this stage costs nothing to fix, whereas the same mistake found after coding means rewriting the program. It is also readable by people who do not know Python, which matters when a team or a teacher has to check the logic.

Q2 Identify the type of error (syntax, run-time or logical) in each of the following and rewrite the corrected code:(i) Num = 10 / if Num > 5 / print("Greater")(ii) n = input("Enter a number: ") / print("Double =", n * 2) - for the input 7 the program prints 77 instead of 14(iii) a = 10 / b = 0 / print("Result =", a / b) Board pattern - 3 marks

(i) Syntax error. The if header is missing its colon, so Python cannot parse the file and nothing at all runs.

  File "e1.py", line 2
    if Num > 5
              ^
SyntaxError: expected ':'

Corrected code:

Num = 10
if Num > 5:
    print("Greater")

(ii) Logical (semantic) error. The code is perfectly legal and it runs without any message — it just does the wrong thing. input() always returns a string, and "7" * 2 repeats the string rather than doubling a number.

Enter a number: Double = 77

Corrected code — convert the input to an integer first:

n = int(input("Enter a number: "))
print("Double =", n * 2)
Enter a number: Double = 14

(iii) Run-time error. The code is legal Python; it is the particular value of b that makes the operation impossible, so the program starts and then stops midway with a traceback.

Traceback (most recent call last):
  File "e3.py", line 3, in 
    print("Result =", a / b)
                      ~~^~~
ZeroDivisionError: division by zero

Corrected code — guard the division before performing it:

a = 10
b = 0
if b == 0:
    print("Division by zero is not allowed")
else:
    print("Result =", a / b)
Division by zero is not allowed

Point to note. Case (ii) is the most dangerous of the three. Cases (i) and (iii) announce themselves loudly; (ii) produces a confident wrong answer that only a test case with a known correct result will ever catch.

Q3 What is meant by decomposition in problem solving? Explain with a suitable example how a large problem is decomposed, and state two advantages of doing so. Board pattern - 3 marks

Definition. Decomposition is the process of breaking a large, complicated problem into smaller sub-problems, each of which is simple enough to be understood, solved and tested on its own. The solutions to the sub-problems are then combined to solve the original problem. Each sub-problem is described by its own input and its own output.

Example — printing the result report of a class. Stated as one problem it is too big to attack. Decomposed:

Sub-problemInputOutput
1. Collect the names and the marksData entered or suppliedTwo matching lists
2. Validate the dataThe two listsTrue if the counts match
3. Compute the statisticsThe marks listHighest, lowest, mean, median, mode
4. Present the reportEverything abovePrinted report lines
import statistics

names = ["Aarav", "Diya", "Kabir", "Meera", "Rohan"]   # sub-problem 1
marks = [78, 91, 55, 91, 62]

print("Records match?", len(names) == len(marks))       # sub-problem 2

highest = max(marks)                                    # sub-problem 3
mean = statistics.mean(marks)

print("Topper  :", names[marks.index(highest)], "with", highest)  # sub-problem 4
print("Mean    :", mean)

Real output

Records match? True
Topper  : Diya with 91
Mean    : 75.4

Two advantages

  1. Easier testing and debugging. Each sub-problem is checked separately, so a wrong topper name is known to lie in sub-problem 3 or 4 and the data-collection part is never disturbed.
  2. Reuse and division of work. "Find the highest mark" is needed by the report card, the merit list and the topper announcement, and it is written once. In a team project, four members can take one sub-problem each and work at the same time.

A third advantage worth mentioning if the question carries more marks: changes stay local. If the school changes its grading rule, only the sub-problem that computes the grade is touched.

Q4 Write an algorithm, draw the corresponding flowchart, and give the Python code to find the sum of the digits of a number entered by the user. Also give a dry run for the input 4523. Board pattern - 5 marks

Analysis. Input: a positive integer num. Process: repeatedly take the last digit with MOD 10, add it to a running total, and remove that digit by dividing by 10 and discarding the remainder, until nothing is left. Output: the sum of the digits.

Algorithm (pseudocode)

BEGIN
    READ num
    SET total = 0
    SET temp = num                // keep num safe for printing later
    WHILE temp > 0 DO
        SET digit = temp MOD 10
        SET total = total + digit
        SET temp = temp DIV 10    // remainder discarded; becomes // in Python
    ENDWHILE
    PRINT total
END

Flowchart

          (  START  )                    oval
                |
                v
         / READ num /                    parallelogram
                |
                v
    +--------------------------+
    | SET total = 0            |         rectangle
    | SET temp  = num          |
    +--------------------------+
                |
                v
    +--------------------------+   No
 +->|      temp > 0 ?          |--------+   diamond
 |  +--------------------------+        |
 |             | Yes                    v
 |             v                / PRINT total /
 |  +--------------------------+         |
 |  | digit = temp MOD 10      |         v
 |  | total = total + digit    |   (  STOP  )
 |  | temp  = temp DIV 10      |
 |  +--------------------------+
 |             |
 +-------------+

Python code (with a print inside the loop so the dry run can be checked against the machine):

num = 4523
total = 0
temp = num
while temp > 0:
    digit = temp % 10
    total = total + digit
    print("temp =", temp, " digit =", digit, " total =", total)
    temp = temp // 10
print("Sum of digits of", num, "=", total)

Real output

temp = 4523  digit = 3  total = 3
temp = 452  digit = 2  total = 5
temp = 45  digit = 5  total = 10
temp = 4  digit = 4  total = 14
Sum of digits of 4523 = 14

Dry run for 4523

Passtemp at starttemp > 0 ?digit = temp % 10total aftertemp = temp // 10
before loop4523——0—
14523Yes33452
2452Yes2545
345Yes5104
44Yes4140
50No — loop ends—14—

Check: 4 + 5 + 2 + 3 = 14, which matches the program. Two marks are commonly lost here. First, using / instead of // in the Python — 4523 / 10 is 452.3, so temp never reaches exactly 0 and the loop misbehaves. Second, destroying num inside the loop, which is why a copy is taken in temp before the loop begins.

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