FLOW CONTROL
Blocks, Statements, and Indentation
Statement: A statement is a single line of instruction that the
Python interpreter can execute. For example, x = 5 is an assignment
statement, and print("Hello") is a function call statement.
Block (or Suite): A block is a group of consecutive statements that
are treated as a single unit. In many programming languages (like
C++, Java, or JavaScript), blocks are defined by curly braces {}.
The Python Rule: Indentation is Syntax. Python is unique in
that it uses indentation to define blocks. There are no curly
braces. A new block starts after a colon (:) and consists of
all subsequent lines that are indented to the same level. The
standard and strongly recommended indentation is 4 spaces.
# This is the outer block (level 0 indentation)
name = "Alice"
score = 95
# The 'if' statement ends with a colon, starting a new block.
if score > 90:
# This is an inner block (level 1 indentation - 4 spaces)
# Both statements in this block will execute together if the condition is
true.
print(f"Congratulations, {name}!")
print("You have scored an A.")
# This statement is back at level 0, so it's outside the 'if' block.
# It will always execute, regardless of the 'if' condition.
print("End of program.")
Remark:
o Fatal Error: Getting an IndentationError: expected an
indented block is a common beginner mistake. In an interview
or online assessment, this signals a lack of basic Python
fluency and is a major red flag.
Logical Operators (and, or, not)
Logical operators are used to combine or modify boolean (True/False)
expressions. They are the building blocks for complex conditions
in if statements.
and (Logical Conjunction):
o Returns True only if both the left and right expressions
are True.
o Analogy: "To get a driver's license, you must be over
18 and pass the driving test." Both conditions must be met.
or (Logical Disjunction):
o Returns True if at least one of the expressions is True.
o Analogy: "I will go out if it's the weekend or it's a holiday."
Only one condition needs to be met.
not (Logical Negation):
o Reverses the boolean value. not True becomes False, and not
False becomes True.
o Analogy: "The system is online if it is not under
maintenance."
Short-Circuiting (Important for Interviews):
In A and B, if A is False, Python does not evaluate B.
In A or B, if A is True, Python does not evaluate B.
This is an optimization and can be used to prevent errors, for
example: if x != 0 and 10 / x > 5:. If x is 0, the second part is never
run, avoiding a ZeroDivisionError.
The if-elif-else Structure
This structure allows your program to make decisions and execute
different blocks of code based on a series of conditions.
1. if: The starting point. Its condition is checked.
o If True, the if block is executed, and the entire if-elif-
else structure is skipped.
o If False, Python moves on to the next elif or else.
2. elif (short for "else if"): Used for additional, mutually exclusive
conditions.
o You can have zero or more elif statements.
o An elif is only checked if all
preceding if and elif conditions were False.
o The first elif whose condition is True will have its block
executed, and the rest of the structure is skipped.
3. else: The final catch-all.
o It's optional and can appear only once at the end.
o Its block is executed only if all
preceding if and elif conditions were False
# The flow of control
# Python checks these conditions from top to bottom.
# The FIRST one that evaluates to True gets its block executed, and the
chain is broken.
age = 25
if age < 13:
print("You are a child.")
elif age < 18: # Only checked if age is NOT < 13
print("You are a teenager.")
elif age < 65: # Only checked if age is NOT < 18
print("You are an adult.")
else: # Only runs if age is NOT < 65
print("You are a senior citizen.")
# Output: You are an adult.
Problem 13:
Scenario: A university needs a program to automatically
assign a letter grade based on a student's score. The rules
are:
o 90-100: 'A'
o 80-89: 'B'
o 70-79: 'C'
o 60-69: 'D'
o Below 60: 'F'
The input score should be validated to be between 0
and 100.
Placement Relevance: This is a classic if-elif-else problem. It
tests your understanding of condition order. Checking
for score >= 80 before score >= 90 would be a logical bug. It
also tests input validation, a key aspect of robust
programming.
Problem 14:
Scenario: A ride-sharing app needs to calculate the fare for
a trip. The logic is complex:
o There's a base fare of Rs. 50 for every ride.
o The charge is Rs. 12 per kilometer.
o During "peak hours" (from 5 PM to 9 PM, i.e., 17:00 to
21:00), there is a 50% surcharge on the entire fare.
o If the ride is on a weekend (Saturday or
Sunday) and the distance is over 10 km, the user gets
a 10% discount on the final fare (after any surcharge is
applied).
Placement Relevance: This problem is much closer to a real-
world business logic task. It requires combining multiple
conditions with and and or, performing calculations, and
applying modifiers in the correct order. It tests your ability
to break down a complex problem into a sequence of logical
steps.
Topic : The for Loop and Iteration Fundamentals
A for loop in Python is used for iterating over a sequence (that is either a
list, a tuple, a dictionary, a set, a string, or a range). It's a way to execute
a block of code repeatedly for each item in the sequence. This is often
called a "for-each" loop in other languages.
The in keyword: The in keyword is central to the for loop. It's used to
check for membership.
As a boolean operator: print('a' in 'apple') -> True
In a for loop: It assigns each item from the sequence to the loop
variable one by one.
Iterating over a range(): The range() function generates a sequence of
numbers, which is perfect when you need to perform an action a specific
number of times.
range(stop): Goes from 0 up to (but not including) stop. range(5) ->
0, 1, 2, 3, 4.
range(start, stop): Goes from start up to stop. range(2, 6) -> 2, 3, 4,
5.
range(start, stop, step): Jumps by step. range(1, 10, 2) -> 1, 3, 5, 7,
9.
Case-insensitive comparison with casefold():
When comparing strings, .lower() is common. However, the more robust
method is .casefold(), which is more aggressive and handles a wider
variety of Unicode characters correctly. For interviews, using casefold() for
case-insensitive comparisons shows a deeper knowledge.
# Iterating over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit.capitalize())
# Iterating over a string
for char in "Python":
print(char, end='-') # Output: P-y-t-h-o-n-
# Iterating using range()
for i in range(5):
print(f"This is loop number {i}")
# Using casefold()
user_input = "ß" # A German character that lowercases to 'ss'
print(user_input.lower()) # ss
print(user_input.casefold()) # ss
# For 'ß' and 'ss', casefold is better for matching
print('ß'.casefold() == 'ss'.casefold()) # True
Topic : Truth Value Testing
This is a fundamental concept that underpins all conditional logic
(if, while). In Python, any object can be tested for a "truth" value.
Considered False:
o The constant None.
o The boolean value False.
o Zero of any numeric type (0, 0.0, 0j).
o Any empty sequence or collection: "" (empty string), [] (empty
list), () (empty tuple), {} (empty dictionary), set().
Considered True:
o Everything else. Any non-empty string, any non-zero number,
any non-empty list, etc.
my_list = [1, 2, 3]
if my_list: # This is the same as 'if len(my_list) > 0:'
print("The list is not empty.")
name = ""
if not name: # The same as 'if name == "":'
print("Name is an empty string.")
Topic : Loop Control (break, continue) and Nested Loops
break: Immediately terminates the innermost loop it's in.
Execution continues at the first statement after the loop.
continue: Immediately skips the the current inner loop
iteration and jumps to the top of the loop to begin the next
iteration.
Nested Loop: A loop inside another loop. The inner loop will
complete all its iterations for each single iteration of the outer loop.
Placement Point of View
Nested Loops & Complexity: Nested loops are a primary source
of high time complexity. A loop nested inside another (for i in n: for j
in n:) immediately suggests an O(n²) algorithm. Interviewers want
you to recognize this and see if you can find a more optimal solution
(e.g., using a hash map).
break for Efficiency: Use break in search algorithms. Once you
find the item you're looking for, there's no need to continue iterating
through the rest of the data. This is a simple but important
optimization.
continue for Readability: Use continue to filter out data you don't
want to process. This can often prevent an extra level
of if statement nesting, making the code cleaner.
Topic : The while Loop
A while loop executes a block of code as long as a specified condition
is True.
Structure:
1. Initialization: A variable is initialized before the loop.
2. Condition: The while statement checks the condition.
3. Update: Inside the loop, the variable must be updated in a way that
will eventually cause the condition to become False, otherwise you
create an infinite loop.
for vs. while:
Use a for loop when you know the number of iterations or have a
definite sequence to iterate over. (e.g., "process every item in this
list", "do this 100 times").
Use a while loop when the number of iterations is unknown and
depends on a condition that changes within the loop. (e.g., "keep
asking for input until the user types 'quit'", "run the game as long as
the player has lives left").
# Example: User input in a loop
# We don't know how many times the user will enter a wrong password.
correct_password = "python123"
password_attempt = ""
attempts = 0
while password_attempt != correct_password:
# After 3 failed attempts, stop asking.
if attempts >= 3:
print("Too many failed attempts. Account locked.")
break
password_attempt = input("Enter password: ")
attempts += 1 # Update the counter
# The 'else' clause on a loop runs ONLY if the loop completed without a
'break'.
else:
print("Access granted!")
Problem 15
Problem Statement (A Classic): "Find the First Non-
Repeating Character"
Given a string s, find and return the first character that does
not repeat anywhere in the string. If all characters repeat,
return None. The comparison should be case-sensitive.
Placement Relevance: This is a fantastic interview question.
It has a simple O(n²) brute-force solution and a much better
O(n) optimal solution. It tests your ability to choose the
right data structures (for loops and dictionaries) to solve a
problem efficiently.
Problem 16
LeetCode Link: 412. FizzBuzz
Topics Covered: for loop, if-elif-else conditions, range(),
modulo operator (%).
Why It's a Good Placement Question:
This is a classic screening question to filter out candidates
who lack fundamental programming skills. It tests your
ability to handle multiple conditions in the correct order. A
common mistake is checking for divisibility by 3 or
5 before checking for both, which leads to incorrect output
for numbers like 15.
Problem 17
LeetCode : 344. Reverse String (Note: The problem asks to
do it in-place)
Topics Covered: while loop, list indexing, variable swapping.
Why It's a Good Placement Question:
This question tests whether you can manipulate data
structures directly (in-place modification). While Python's
slicing s[::-1] is elegant for creating a new reversed string,
this problem specifically forbids it by asking for an in-place
modification with O(1) extra memory. This forces the
candidate to use a two-pointer approach, a very common
and important algorithmic pattern.