📌 Snapshot
- Trace if, elif, for, while, break and continue line by line to predict any CUET output with confidence.
- How Python chooses between paths and repeats work, and why indentation is the syntax that decides everything.
- Trace tables for loops, a range() cheat table, and a for versus while comparison you can rebuild from memory.
- The traps NTA sets again and again: the exclusive stop value, break versus continue, and the silent infinite loop.
📖 Detailed Notes
Written and reviewed by Rohit Singh, Computer Science & Commerce faculty at UniDrill (MCA, Osmania University · 6 years teaching). Based on NCERT Computer Science Class XI, Chapter 6.
Why does a program ever need to choose?
A school bus has one road. The driver cannot decide anything, so he simply follows the milestones one after another. Now open a map app: it offers the shortest route and the least crowded route, and you pick one. Programs behave the same way. Until now yours ran like the bus, one statement after another. This chapter gives them a steering wheel (decisions) and a lap counter (repetition). Almost every CUET code question is really asking: which statements run, and how many times?
The three ways a program can flow
The order in which statements are executed is called the flow of control. Python supports three patterns, and every program you will ever read is built from them.
| Pattern | What it means | Python tool | Real-life picture |
|---|---|---|---|
| Sequence | One statement after another, top to bottom (the default) | Ordinary statements | The school bus on its single road |
| Selection | Choose one path from two or more, based on a condition | if, if..else, if..elif..else |
Picking a route on a map |
| Repetition (iteration) | Run a block again and again | for, while |
Paying the electricity bill every month |
Selection: if, if..else and if..elif..else
An if statement runs its indented block only when the condition is true. If it is false, the block is skipped and Python moves on. The if..else form gives two alternatives, and exactly one of them runs.
| Code |
|---|
age = int(input("Enter your age: ")) |
if age >= 18: |
print("Eligible to vote") |
else: |
print("Not eligible to vote") |
When you have more than two alternatives, chain the conditions with elif, which simply means else if. Python checks the conditions from top to bottom, runs the block of the first true condition and then skips the whole rest of the chain. A final else is optional and catches everything that failed all the tests.
Worked example: grade by marks. What does this program print, and what goes wrong if the conditions are written in the opposite order?
| Code |
|---|
marks = 72 |
if marks >= 90: |
print("A") |
elif marks >= 75: |
print("B") |
elif marks >= 60: |
print("C") |
else: |
print("D") |
| Step | What Python does | Result |
|---|---|---|
| 1 | Test marks >= 90, which is 72 >= 90 |
False, skip block |
| 2 | Test marks >= 75, which is 72 >= 75 |
False, skip block |
| 3 | Test marks >= 60, which is 72 >= 60 |
True, run print("C") |
| 4 | The chain ends here; else is never tested |
Output: C |
The common wrong step is to put the loosest test first. If marks >= 60 came first, a student with 95 marks would also print C, because the chain stops at the first true condition and the >= 90 test is never reached. Order conditions from the most specific to the most general.
Nested if. An if..else placed inside another if or elif block is a nested if. The inner test is reached only if the outer one passed. For example, a calculator can first check the operator and, for division, check inside that block whether the divisor is zero.
| Code |
|---|
if op == "/": |
if val2 == 0: |
print("Division by zero is not allowed") |
else: |
result = val1 / val2 |
Pause and predict: x = 15. Statement A is if x > 10: print("A"). Statement B, written directly below it as a separate statement, is if x > 12: print("B"). What is printed? What changes if B is written as elif x > 12: attached to A?
Check your answer: With two separate if statements, both conditions are tested independently, so both A and B are printed. With elif, the chain stops after the first true test, so only A is printed. This difference is behind many "predict the output" questions.
Indentation: Python's replacement for curly brackets
Most languages mark a block with curly brackets. Python marks it with indentation: the leading white space (spaces or tabs) at the start of a statement. Statements with the same indentation belong to one block, and the interpreter checks this strictly, raising an error if the levels do not match. The usual habit is one tab for each level.
This is not just style, because moving one line changes what the program does.
Worked example: one line, two meanings. The only difference between the two programs below is the indentation of the last print.
| Code |
|---|
for i in range(3): |
print(i) |
print("done") |
| Output |
|---|
0 |
1 |
2 |
done |
| Code |
|---|
for i in range(3): |
print(i) |
print("done") |
| Output |
|---|
0 |
done |
1 |
done |
2 |
done |
In the first program print("done") is outside the loop, so it runs once, after the loop ends. In the second it is inside the loop body, so it runs three times.
Beyond the textbook. For the exam: a block is any group of statements at the same indentation. In reality: a block can never be empty. If you need a placeholder where Python demands a statement but you have nothing to do yet, write the keyword pass, which does nothing. It is useful when you are sketching a program and want it to run before you have filled in every branch.
Repetition: the idea of a loop
Printing the first five natural numbers needs five print statements. Printing the first 100,000 would need 100,000, which no sensible person would type. A loop solves this: it runs a block repeatedly as long as a condition stays true. The condition is tested using the value of a control variable. The programmer must make sure that the condition eventually becomes false. If it never does, the result is an infinite loop, which is a logical error rather than a syntax error, so Python will not warn you.
Python has two loops. Use for when you know in advance how many times (or over which items) you want to repeat. Use while when you only know the condition for stopping.
The for loop and range()
A for loop takes each item of a range or a sequence in turn (the characters of a string, the elements of a list or tuple) and runs the body once per item. When the items are exhausted, control moves to the statement after the loop.
| Code |
|---|
for letter in "PYTHON": |
print(letter) |
This prints P, Y, T, H, O and N, one per line. To loop over numbers, Python gives you the built-in function range(), with the syntax range([start], stop[, step]).
The three rules of range(). start is included and defaults to 0. stop is never included. step defaults to 1, may be negative, but may never be zero. All three must be integers. Here is how common calls behave.
| Call | Values generated | Count |
|---|---|---|
range(5) |
0, 1, 2, 3, 4 | 5 |
range(2, 10) |
2, 3, 4, 5, 6, 7, 8, 9 | 8 |
range(0, 30, 5) |
0, 5, 10, 15, 20, 25 | 6 |
range(2, 10, 3) |
2, 5, 8 | 3 |
range(10, 2, -2) |
10, 8, 6, 4 | 4 |
range(0, -9, -1) |
0, -1, -2, ... -8 | 9 |
range(0, 9, -1) |
nothing (start is already below stop for a falling step) | 0 |
range(1, 6, 0) |
ValueError: the step cannot be zero | none |
You can count the values without listing them. For a positive or negative step:
$$\text{count} = \max\left(0,\ \left\lceil \dfrac{\text{stop} - \text{start}}{\text{step}} \right\rceil\right)$$
Check it on range(2, 10, 3): $(10 - 2)/3 = 2.67$, and the ceiling is 3, which matches 2, 5, 8. Check it on range(0, 9, -1): $(9 - 0)/(-1) = -9$, so the count is 0.
Worked example: tracing a for loop. What is printed by this program?
| Code |
|---|
total = 0 |
for i in range(1, 6, 2): |
total = total + i |
print(total) |
| Pass | Value of i |
total before |
total after |
|---|---|---|---|
| 1 | 1 | 0 | 1 |
| 2 | 3 | 1 | 4 |
| 3 | 5 | 4 | 9 |
| End | the range is exhausted | print(total) shows 9 |
range(1, 6, 2) gives 1, 3, 5. Writing the table is the fastest way to avoid the usual slip of including 6 or stepping by 1 out of habit.
Pause and predict: after for i in range(5): pass, what is the value of i?
Check your answer: 4. The control variable is an ordinary variable. It keeps the last value it received, even after the loop has finished.
The while loop
A while loop tests its condition before every pass. While it is true the body runs, and when it becomes false control moves to the statement after the loop. If the condition is false the very first time, the body runs zero times. Because Python never changes the control variable for you, the body itself must contain a statement that eventually makes the condition false.
Worked example: sum of the digits of 345. The two operators do the work: n % 10 gives the last digit and n // 10 removes it.
| Code |
|---|
n = 345 |
s = 0 |
while n > 0: |
s = s + n % 10 |
n = n // 10 |
print(s) |
| Pass | n > 0? |
n % 10 |
s after |
n after |
|---|---|---|---|---|
| 1 | 345 > 0, True | 5 | 5 | 34 |
| 2 | 34 > 0, True | 4 | 9 | 3 |
| 3 | 3 > 0, True | 3 | 12 | 0 |
| Test | 0 > 0, False | stop | print(s) shows 12 |
If the line n = n // 10 were forgotten, n would stay 345 for ever and the loop would never end. That is the classic infinite loop.
for or while? The two loops are interchangeable in theory, but each fits a different situation.
| Feature | for loop |
while loop |
|---|---|---|
| Number of repeats | Known in advance, or equal to the number of items | Not known, decided by a condition |
| Control variable | Handled automatically by the loop | You create it and update it yourself |
| Typical use | Walk through a range, string, list or tuple | Repeat until the user types something, or until a value reaches a limit |
| Risk of an infinite loop | Very low | High, if you forget to update the variable |
| Runs zero times when | The range or sequence is empty | The condition is false at the start |
break and continue
Sometimes a loop needs to be interrupted from inside. Python gives two statements for this, and CUET loves to test whether you can tell them apart.
| Feature | break |
continue |
|---|---|---|
| What it does | Leaves the loop completely | Skips the rest of this pass only |
| Where control goes | To the first statement after the loop | Back to the loop's next pass (the condition or next item is checked again) |
| Does the loop continue? | No | Yes, until it finishes normally |
| Typical use | Stop searching once the item is found | Ignore one unwanted value |
Worked example: break. Program: the body adds 1 to num, quits the loop if num is 8, and otherwise prints it.
| Code |
|---|
for num in range(10): |
num = num + 1 |
if num == 8: |
break |
print("Num has value", num) |
print("Out of loop") |
Each pass, for hands num the next value from the range (0, 1, 2, ...), then the body adds 1. So the body sees 1, 2, 3, ... The first seven passes print 1 to 7. On the eighth pass num becomes 8, break runs before the print, and control jumps to print("Out of loop"). The line with value 8 is never printed, so the loop body prints exactly 7 times.
Worked example: continue. Same idea, but the loop uses continue for the value 3 and the range is range(6).
| Code |
|---|
for num in range(6): |
num = num + 1 |
if num == 3: |
continue |
print(num, end=" ") |
| Pass | Value from range(6) |
num after + 1 |
Condition num == 3 |
Printed |
|---|---|---|---|---|
| 1 | 0 | 1 | False | 1 |
| 2 | 1 | 2 | False | 2 |
| 3 | 2 | 3 | True, continue skips the print |
nothing |
| 4 | 3 | 4 | False | 4 |
| 5 | 4 | 5 | False | 5 |
| 6 | 5 | 6 | False | 6 |
| Output |
|---|
1 2 4 5 6 |
Why the next pass is not affected. Changing num inside the body does not change the range. At the top of every pass, for overwrites num with the next value from the range. That is why the loop still makes six passes even though num was bumped up inside.
Pause and predict: a while loop starts with i = 1 and runs while i <= 5. Inside, if i == 3: continue comes first, and i = i + 1 comes last. What happens?
Check your answer: it prints 1 and 2, then hangs. When i reaches 3, continue jumps back to the test before i is incremented, so i stays 3 for ever. In a for loop continue is safe because the loop advances itself. In a while loop, you must update the control variable before continue.
Beyond the textbook. For the exam: while repeats while the condition is true, and break exits the loop. In reality: the most common professional pattern combines them: while True: starts a loop that never ends by itself, and a break inside leaves it when the work is done, for example as soon as the user enters a negative number. Used carefully this is clean, because the exit condition sits exactly where you detect it.
Beyond the textbook. For the exam: a prime-number checker loops over possible factors and uses break as soon as one is found. In reality: the stop value of range() is exclusive, so a loop written as range(2, int(num / 2)) never tests num / 2 itself. For num = 4 the range is empty, no factor is found, and 4 is wrongly reported as prime. Writing range(2, num // 2 + 1) repairs it. This is the exclusive-stop trap showing up in real code.
Nested loops
A loop inside another loop is a nested loop. Any mix of for and while is allowed, to any depth. The rule to remember: for each single pass of the outer loop, the inner loop runs through its complete cycle. So if the outer loop runs $m$ times and the inner runs $n$ times, the inner body runs $m \times n$ times.
Worked example: a number pattern.
| Code |
|---|
for i in range(1, 4): |
for j in range(i): |
print(i, end=" ") |
print() |
Outer i |
Inner range(i) |
Printed on that row |
|---|---|---|
| 1 | range(1) gives 0 (one pass) |
1 |
| 2 | range(2) gives 0, 1 (two passes) |
2 2 |
| 3 | range(3) gives 0, 1, 2 (three passes) |
3 3 3 |
| Output |
|---|
1 |
2 2 |
3 3 3 |
The print() at one indentation level less than the inner loop belongs to the outer loop, so it runs once per row and moves the cursor to a new line. A break inside the inner loop ends only the inner loop. The outer loop carries on with its next pass.
Exam traps
| The trap | Why it's tempting | The truth |
|---|---|---|
range(1, 6) prints 1 to 6 |
The word "to" suggests the end is included | The stop value is never included: 1, 2, 3, 4, 5 |
range(10) starts at 1 |
We count from 1 in daily life | The default start is 0, so it gives 0 to 9 |
break skips just this pass |
Both break and continue interrupt the loop |
break ends the loop; continue skips only the rest of the current pass |
break exits every nested loop |
"Break out" sounds total | It leaves only the innermost loop that contains it |
| A while body always runs once | Other languages have do..while | The test comes first, so the body can run zero times |
range(0, 9, -1) counts down |
The negative step suggests falling values | A falling step needs start greater than stop; this call is empty |
step of 0 means "stay put" |
Zero feels harmless | range(1, 6, 0) raises a ValueError |
After the loop, i is gone |
Variables inside loops feel temporary | The control variable keeps its last value |
60-second revision
| Topic | Lock this in |
|---|---|
| Flow of control | Sequence (default) · selection (if) · repetition (for, while) |
| elif chain | Top to bottom, first true block runs, rest skipped; order specific to general |
| Block | Same indentation = same block; wrong indentation changes the output or raises an error |
| range(start, stop, step) | Start included (default 0) · stop excluded · step default 1, never 0, can be negative |
| Count of range | $\max(0, \lceil (\text{stop}-\text{start})/\text{step} \rceil)$ |
| for | Known repeats, or one pass per item; control variable handled for you |
| while | Test first, body can run zero times; you must change the variable |
| Infinite loop | Condition never becomes false; a logical error, not a syntax error |
| break | Leave the loop, continue after it |
| continue | Skip the rest of this pass, go to the next |
| Nested loop | Inner loop runs fully for each outer pass: $m \times n$ runs |
Where this chapter connects
- Previous: Getting Started with Python gives the data types, operators and input and output that every condition and loop body here depends on.
- Next: Functions wraps the loops and decisions you just wrote into named, reusable blocks.
- Where loops return: Strings and Lists use
forloops to traverse every character or element, and Introduction to Problem Solving shows the flowcharts for the same three patterns.
🎯 Practice MCQs
First 3 questions free · create a free account to unlock the rest — answers & explanations included, no payment needed
Q1. Consider: (1) for i in range(2, 10, 3): (2) print(i, end=' '), where statement (2) is the body of the loop. What is printed?
▸ Show answer & explanation
Answer: C
range(2, 10, 3) starts at 2 and adds 3 each time: 2, 5, 8. The next value, 11, is beyond the stop value 10, so option A is wrong. Options B and D use a different step.
Q2. Which statement about indentation in Python is correct?
▸ Show answer & explanation
Answer: B
Python uses indentation, not brackets, to define blocks, and it checks the levels strictly. Option A reverses this, option C is wrong because if, while and function bodies also need indentation, and option D is wrong because all statements of one block must be indented equally.
Q3. Consider: (1) for num in range(10): (2) num = num + 1 (3) if num == 8: break (4) print(num). Statements (2), (3) and (4) are in the loop body, and break is inside the if. How many times is print executed?
▸ Show answer & explanation
Answer: D
The body sees num as 1, 2, 3 and so on, because 1 is added before the test. For 1 to 7 the print runs. When num becomes 8, break runs before print, so the loop ends. That makes 7 prints. Option C is the usual wrong answer, because the eighth pass never reaches print.
🔒 12 more practice MCQs
Create a free account to unlock every MCQ in this chapter — answers and explanations included. No payment needed.
Already registered? Just log in and they'll all appear here.
Q4. Assertion (A): The body of a while loop may never execute. Reason (R): A while loop tests its condition before running the body, so a condition that is false at the start skips the body.
▸ Show answer & explanation
Answer: A
The condition is evaluated first. If it is false the very first time, the body is skipped completely, so R directly explains A. Neither statement is false, which rules out options C and D.
Q5. Match List I with List II. List I: (i) break (ii) continue (iii) range(5, 0, -1) (iv) elif. List II: (p) skips the rest of the current pass (q) leaves the loop (r) produces 5, 4, 3, 2, 1 (s) tests another condition only if the earlier ones were false.
▸ Show answer & explanation
Answer: B
break leaves the loop and continue skips only the current pass. range(5, 0, -1) counts down from 5 and stops before 0. elif means else if. Option A swaps break and continue, which is the most common mistake.
Q6. Consider: (1) for num in range(6): (2) num = num + 1 (3) if num == 3: continue (4) print(num, end=' '). Statements (2) to (4) are in the loop body and continue is inside the if. What is printed?
▸ Show answer & explanation
Answer: B
The loop makes six passes and num takes the values 1 to 6 after the increment. Only the pass with num equal to 3 is skipped by continue, so 1 2 4 5 6 is printed. Option D forgets that 6 is reached, and option C wrongly treats continue like break.
Q7. How many integers does range(3, 20, 4) generate?
▸ Show answer & explanation
Answer: B
The values are 3, 7, 11, 15 and 19. The next one, 23, exceeds the stop value 20. Option A leaves out the value 19, and option D is the gap between start and stop, not the number of values.
Q8. Consider a while loop that runs while i <= 5, starting from i = 1. Inside the body, the first statement is: if i == 3 then continue. The next statements are print(i) and i = i + 1. What happens when it runs?
▸ Show answer & explanation
Answer: B
When i becomes 3, continue jumps back to the test before i = i + 1 is reached, so i stays 3 and the loop never ends. Option A would be correct only if i were incremented before continue. An infinite loop is a logical error, so option D is wrong.
Q9. What is the value of list(range(10, 2, -2))?
▸ Show answer & explanation
Answer: B
The sequence starts at 10 and falls by 2 each time, and it stops before reaching the stop value 2. So 2 is excluded, which rules out option A. Option D would be correct only if the step were positive.
Q10. Consider: (1) x = 15 (2) if x > 10: print('A') (3) if x > 12: print('B') (4) else: print('C'). Statements (3) and (4) form one if..else, and statement (2) is a separate if. What is printed, line by line?
▸ Show answer & explanation
Answer: B
The first if is independent, and 15 is greater than 10, so A is printed. In the second if..else, 15 is greater than 12, so B is printed and the else part is skipped. Option C would need the second condition to be false.
Q11. Consider: (1) for i in range(3): (2) for j in range(2): (3) print(i, j), where statement (3) is the body of the inner loop. How many times does print execute, and which pair is printed last?
▸ Show answer & explanation
Answer: B
The inner loop runs fully (2 passes) for each of the 3 outer passes, giving 3 x 2 = 6 prints. The last values are i = 2 and j = 1. Option C uses the stop values instead of the last values, which are never reached.
Q12. Consider: x = 6, followed by an if that tests x > 5. Inside it, a nested if..else prints A when x > 7 and B otherwise. An outer else prints C. What is printed?
▸ Show answer & explanation
Answer: B
The outer test x > 5 is true, so the nested if..else is reached. There, x > 7 is false, so the else part prints B. The outer else is skipped because the outer condition was true.
Q13. Consider: (1) for i in range(3): (2) for j in range(3): (3) if j == 1: break (4) print(i, j). Statements (3) and (4) are in the inner loop, and break is inside the if. How many times is print executed?
▸ Show answer & explanation
Answer: C
In each outer pass the inner loop prints for j equal to 0, then j becomes 1 and break ends only the inner loop. The outer loop continues, so there is one print per outer pass: 3 in total. Option D wrongly assumes break ends both loops.
Q14. Assertion (A): In nested loops, break terminates only the innermost loop that contains it. Reason (R): break transfers control to the first statement after the loop in which it appears.
▸ Show answer & explanation
Answer: A
break works on the loop that directly contains it, and control resumes right after that loop, which may still be inside an outer loop. So R explains A. Option C and D are wrong because both statements are true.
Q15. Which of the following statements are correct? (i) The step in range() can be negative but not zero. (ii) After a for loop ends, the control variable keeps its last value. (iii) The body of a while loop always runs at least once. (iv) A for loop can iterate over the characters of a string.
▸ Show answer & explanation
Answer: B
Statements (i), (ii) and (iv) are true. Statement (iii) is false because a while loop whose condition is false at the start runs zero times. So option B is correct and options A, C and D each wrongly include (iii).
📊 Previous-Year Questions
Practise with real CUET Computer Science previous-year papers — every question solved, with the correct answer and a step-by-step explanation.
View solved CUET PYQ papers →Ready to drill Computer Science?
Unlock all MCQs, chapter tests, mocks & PYQs for ₹199/year.
Get UniDrill Pro