Python Unit II Notes
Python Unit II Notes
if value:
print("True block")
else:
print("False block")
Output:
False block
9. Common Syntax and Logic Errors (Must Warn Students)
1. Missing colon : after if, elif, else
2. Incorrect indentation
3. Using = instead of == in conditions
4. Overlapping conditions in elif ladder
5. Deep nesting instead of clear logic
Incorrect:
if x = 5: # ERROR
Correct:
if x == 5:
10. Best Practices (Engineering Discipline)
1. Keep conditions simple and readable
2. Use elif instead of multiple independent if
3. Avoid redundant comparisons
4. Use meaningful variable names in conditions
5. Comment complex decision logic
11. Flow of Control (Conceptual)
Start
|
Condition?
|—— True ——> Execute block
|
|—— False ——> Next condition / else
This decision structure underpins:
• Validation checks
• Control systems
• Simulation branching
• Error handling
12. Summary (Exam-Ready Points)
• if executes code when condition is True
• else executes when condition is False
• elif handles multiple conditions
• Conditions use comparison and logical operators
• Indentation defines the conditional block
• Only one block executes in an if–elif–else ladder
Lecture 12: While Loops and Handling Infinite Loops in Python
The while loop is a condition-controlled iteration structure. It is indispensable when the
number of iterations is not known in advance—typical in engineering simulations, convergence
checks, monitoring systems, and iterative solvers. However, mishandling while loops leads
directly to infinite loops, which can freeze programs and consume system resources.
1. The while Loop: Concept and Purpose
Definition
A while loop repeatedly executes a block of code as long as a given condition remains True.
Key principle:
The loop condition is evaluated before each iteration.
2. Syntax of the while Loop
while condition:
statement_block
Rules:
• Condition must evaluate to a Boolean (True / False)
• Colon : is mandatory
• Indentation defines the loop body
3. Basic Example
count = 1
while x <= 5:
print(x)
Problem:
• x is never updated
• Condition always remains True
Result:
• Program runs forever
7. Intentional Infinite Loops (Controlled)
Sometimes infinite loops are deliberately used, especially in:
• Servers
• Embedded systems
• Continuous monitoring
Controlled Infinite Loop
while True:
command = input("Enter command (q to quit): ")
if command == "q":
break
Here:
• Loop is infinite by design
• break provides a safe exit
8. Handling Infinite Loops Safely
1. Ensure Condition Changes
Every while loop must have:
• A variable in the condition
• A statement that modifies that variable
while error > tolerance:
error = compute_error()
2. Use break to Exit Loop
while True:
if condition_met:
break
break:
• Immediately exits the loop
• Control moves to the next statement after the loop
3. Use continue Carefully
while i < 10:
i += 1
if i == 5:
continue
print(i)
continue:
• Skips the remaining code in the current iteration
• Goes back to condition check
Misuse of continue can also cause infinite loops if updates are skipped.
9. The while–else Construct (Often Ignored)
Python supports else with while.
Syntax
while condition:
block
else:
block
Behavior
• else executes only if the loop ends normally
• else does not execute if break is used
Example:
i = 1
while i <= 3:
print(i)
i += 1
else:
print("Loop completed successfully")
10. Common Errors (Must Be Explicitly Warned)
1. Forgetting to update loop variable
2. Wrong comparison operator (< vs <=)
3. Using assignment (=) instead of comparison (==)
4. Floating-point conditions without tolerance
5. Infinite loops caused by continue before update
Dangerous example:
while x != 0:
x = x - 0.1
Reason:
• Floating-point precision may never reach exactly zero
Correct approach:
while abs(x) > 1e-6:
x -= 0.1
11. Best Practices (Engineering Discipline)
1. Always verify loop termination
2. Use counters or convergence criteria
3. Avoid floating-point equality in conditions
4. Prefer for loop when iteration count is known
5. Comment the exit condition clearly
6. Test loops with small limits first
12. Comparison: while vs for
Aspect while Loop for Loop
Condition Logical condition Sequence-based
Iterations known? No Yes
Risk of infinite loop High Low
Typical use Convergence, monitoring Counting, traversal
13. Summary (Exam-Ready Points)
• while loop executes as long as condition is True
• Condition is checked before each iteration
• Loop variable must be updated to avoid infinite loops
• Infinite loops occur when condition never becomes False
• break safely exits loops
• continue skips current iteration
• while–else executes only on normal termination
Lecture 13: For Loops and the range() Function in Python
The for loop is a count-controlled iteration structure. It is the safest and most commonly
used loop in Python, especially when the number of iterations is known in advance. In
engineering programs, for loops dominate data traversal, numerical summations, simulations,
and batch processing.
1. What is a for Loop?
Definition
A for loop iterates over a sequence (such as a range of numbers, list, or string) and executes a
block of code once for each element in that sequence.
Key principle:
Python’s for loop iterates over elements, not indices (unlike C-style loops).
2. Syntax of the for Loop
for variable in sequence:
statement_block
Rules:
• Colon : is mandatory
• Indentation defines the loop body
• Loop variable takes each value from the sequence automatically
3. Basic for Loop Example
for i in range(5):
print(i)
Output:
0
1
2
3
4
Explanation:
• Loop starts from 0
• Ends at 4
• Upper limit is excluded
4. The range() Function (CRITICAL CONCEPT)
Purpose
range() generates a sequence of integers used commonly with for loops.
General Syntax
range(start, stop, step)
Where:
• start → starting value (inclusive)
• stop → ending value (exclusive)
• step → increment/decrement value
5. Forms of range()
1. range(stop)
range(5)
Generates:
0, 1, 2, 3, 4
2. range(start, stop)
range(2, 6)
Generates:
2, 3, 4, 5
3. range(start, stop, step)
range(1, 10, 2)
Generates:
1, 3, 5, 7, 9
Negative step:
range(10, 0, -2)
Generates:
10, 8, 6, 4, 2
6. Loop Variable Behavior
for x in range(3):
print(x)
print(x)
Output:
0
1
2
2
Explanation:
• Loop variable retains the last value after loop completion
• This can cause logical errors if reused carelessly
7. Common Applications of for Loops
1. Summation
total = 0
print(total)
2. Iterating Over a String
for ch in "Python":
print(ch)
3. Iterating Over Lists (Preview)
values = [10, 20, 30]
for v in values:
print(v)
8. break and continue in for Loops
break – Exit Loop Immediately
for i in range(5):
if i == 3:
break
print(i)
Output:
0
1
2
continue – Skip Current Iteration
for i in range(5):
if i == 2:
continue
print(i)
Output:
0
1
3
4
9. Nested for Loops
Definition
A nested loop is a loop inside another loop.
for i in range(3):
for j in range(2):
print(i, j)
Used in:
• Matrix operations
• Grid-based simulations
• Pattern generation
10. for–else Construct (Often Ignored)
Syntax
for i in range(3):
print(i)
else:
print("Loop completed")
Rule:
• else executes only if loop completes normally
• else does not execute if break is encountered
11. Common Student Errors (Must Be Highlighted)
1. Expecting range(5) to include 5
2. Using wrong step direction (positive vs negative)
3. Modifying loop variable inside the loop
4. Using for where while is more appropriate
5. Forgetting indentation
Incorrect assumption:
for i in range(1, 5):
pass
# i is NOT 5, it is 4
12. Best Practices (Engineering Discipline)
1. Prefer for loops when iteration count is known
2. Use meaningful loop variable names
3. Avoid changing loop variable manually
4. Keep loop body short and clear
5. Comment non-obvious loop logic
13. Comparison: for vs while
Aspect for Loop while Loop
Iterations known Yes No
Risk of infinite loop Very low High
Readability High Moderate
Typical use Counting, traversal Convergence, monitoring
14. Summary (Exam-Ready Points)
• for loop iterates over sequences
• range() generates integer sequences
• range() excludes the stop value
• Loop variable automatically updates
• break exits loop, continue skips iteration
• Nested loops handle multi-dimensional problems
• for–else executes on normal completion
Lecture 14: Loop Control Statements in Python: break, continue, and pass
Loop control statements alter the normal flow of loop execution. They are essential for writing
correct, efficient, and readable iteration logic—particularly in validation routines, simulations,
search problems, and error handling.
1. Overview of Loop Control Statements
Python provides three loop control statements:
Statement Purpose
break Terminates the loop immediately
continue Skips the current iteration and proceeds to the next
pass Acts as a placeholder; does nothing
These statements are used inside for and while loops.
2. The break Statement
Purpose
break exits the loop immediately, regardless of the loop condition.
Syntax
break
Example
for i in range(10):
if i == 5:
break
print(i)
Output:
0
1
2
3
4
Key Points
• Control jumps outside the loop
• Often used when a condition is satisfied early
• Prevents unnecessary iterations
Engineering Use Cases
• Stop iteration when convergence is reached
• Exit search once a target is found
• Abort loop on error condition
3. The continue Statement
Purpose
continue skips the remaining statements in the current iteration and moves to the next
iteration.
Syntax
continue
Example
for i in range(5):
if i == 2:
continue
print(i)
Output:
0
1
3
4
Key Points
• Loop does not terminate
• Only current iteration is skipped
• Loop condition is re-evaluated
Engineering Use Cases
• Ignore invalid or missing data points
• Skip faulty sensor readings
• Filter specific values during processing
4. The pass Statement
Purpose
pass is a null statement—it does nothing.
It is used when a statement is syntactically required but no action is needed.
Syntax
pass
Example
for i in range(3):
pass
Result:
• Loop executes with no operation
• No output, no error
pass in Conditional Blocks
if value < 0:
pass
else:
print("Valid value")
Here:
• Negative values are intentionally ignored
• Program continues normally
Why pass Exists
Python does not allow empty blocks.
pass prevents syntax errors during:
• Incomplete code
• Future implementation placeholders
• Structural scaffolding
5. break vs continue vs pass (Critical Comparison)
Aspect break continue pass
Effect Exits loop Skips iteration No effect
Loop ends? Yes No No
Used for Termination Filtering Placeholder
Control flow Jumps outside loop Goes to next iteration Continues normally
6. Loop Control with while Loop
break in while
while True:
x = input("Enter q to quit: ")
if x == "q":
break
continue in while
x = 0
while x < 5:
x += 1
if x == 3:
continue
print(x)
Output:
1
2
4
5
⚠ Warning:
• Using continue before updating loop variables can cause infinite loops.
7. Interaction with for–else and while–else
Important Rule
• else executes only if loop ends normally
• else does not execute if break is used
for i in range(5):
if i == 3:
break
else:
print("Completed")
Output:
• No else execution
8. Common Student Errors (Must Be Corrected)
1. Using break when continue is required
2. Forgetting loop-variable update with continue
3. Using pass instead of break
4. Expecting pass to skip iteration
5. Overusing continue, reducing readability
Incorrect assumption:
if condition:
pass # This does NOT skip loop iteration
9. Best Practices (Engineering Discipline)
1. Use break sparingly and intentionally
2. Avoid excessive continue—clarity over cleverness
3. Use pass only as a temporary or structural placeholder
4. Clearly comment non-obvious loop exits
5. Test loops with boundary and failure cases
10. Summary (Exam-Ready Points)
• break terminates a loop immediately
• continue skips the current iteration
• pass does nothing; used as a placeholder
• break prevents execution of loop else
• Incorrect use can cause infinite loops or logic errors
• Loop control is essential for efficient iteration
Lecture 15: Nested Loops and Multi-level Logic in Python
Nested loops and multi-level logic are structural control mechanisms used to solve problems
involving two or more dimensions, hierarchies, or layered decision-making. In engineering
and scientific programming, they are unavoidable—matrix operations, grid simulations, pattern
analysis, and rule-based logic all depend on them.
Poor understanding here leads to exponential inefficiency and logical chaos.
1. What is a Nested Loop?
Definition
A nested loop is a loop placed inside another loop.
Key rule:
The inner loop executes fully for every single iteration of the outer loop.
2. Basic Syntax of Nested Loops
for outer in range(n):
for inner in range(m):
statement
Execution order:
1. Outer loop starts
2. Inner loop runs completely
3. Outer loop moves to next iteration
4. Inner loop runs again
3. Simple Nested for Loop Example
for i in range(3):
for j in range(2):
print(i, j)
Output:
0 0
0 1
1 0
1 1
2 0
2 1
Explanation:
• Outer loop (i) runs 3 times
• Inner loop (j) runs 2 times per outer iteration
• Total executions = 3 × 2 = 6
4. Nested Loops with while
i = 1
while i <= 3:
j = 1
while j <= 2:
print(i, j)
j += 1
i += 1
⚠ Critical rule:
• Inner loop variable must be reinitialized each time
• Failure causes infinite loops
5. Engineering Use Cases of Nested Loops
1. Matrix and grid computations
2. Spatial simulations (2D/3D domains)
3. Pattern generation
4. Multi-parameter sensitivity analysis
5. Time–space iteration (e.g., time steps × locations)
Example (matrix traversal preview):
for row in range(3):
for col in range(3):
print(f"Cell ({row},{col})")
6. Multi-level Conditional Logic
Definition
Multi-level logic uses:
• Nested if statements, or
• Combined conditions using logical operators
to make hierarchical decisions.
7. Nested if Statements
depth = 120
quality = "good"
greet()
Purpose:
• Encapsulate repeated actions
• Improve readability
8. Functions with Parameters
def add(a, b):
return a + b
function(arg1, arg2)
Example
def subtract(a, b):
return a - b
result = subtract(10, 5)
print(result) # 5
Here:
• a = 10
• b = 5
Order Sensitivity (CRITICAL)
subtract(5, 10)
Output:
-5
Same values, different order → different result.
Common Mistake
def power(base, exponent):
return base ** exponent
power(2, 3) # 8
power(3, 2) # 9
3. Default Arguments
Definition
A default argument has a predefined value in the function header.
If no argument is supplied during function call, the default value is used.
Syntax
def function(parameter=default_value):
block
Example
def greet(name="User"):
print("Hello", name)
print(calculate_area(10)) # width = 1
print(calculate_area(10, 5)) # width = 5
Rules:
• Positional arguments are matched first
• Default arguments fill missing values
6. Argument Matching Mechanism (Conceptual)
Function Header: def f(a, b=2)
Call: f(5)
Mapping:
a = 5
b = 2 (default)
7. Common Errors (Must Warn Students)
1. Changing argument order unintentionally
2. Assuming default arguments change automatically
3. Placing default parameters before non-default ones
4. Forgetting that position matters
5. Overusing defaults and hiding logic
Incorrect assumption:
compute_force(g=9.8, mass=10) # NOT allowed yet (keyword args
come later)
8. Best Practices (Engineering Discipline)
1. Use positional arguments for mandatory inputs
2. Use default arguments for standard constants
3. Keep defaults simple and safe
4. Document default values clearly
5. Do not overload functions with many defaults
9. Positional vs Default Arguments (Comparison)
Aspect Positional Default
Order matters Yes Yes (after positional)
Mandatory Yes Optional
Flexibility Low High
Risk Order errors Hidden assumptions
10. Summary (Exam-Ready Points)
• Arguments pass data to functions
• Positional arguments depend on order
• Default arguments provide optional values
• Default arguments must follow positional arguments
• Defaults are used only when values are not provided
• Misuse leads to logical errors, not syntax errors
Lecture 18: Return Values in Python: Fruitful vs. Void Functions
Return values define what a function gives back to the caller. Understanding this distinction is
essential for writing correct, reusable, and testable code. In engineering programs, confusing
these concepts leads to silent failures—values are computed but never used.
1. The return Statement: Purpose and Behavior
Purpose
The return statement:
• Sends a value back to the caller
• Immediately terminates function execution
Syntax
return expression
Key rules:
• A function can have zero or more return statements
• Code after return is never executed
• If no return is present, Python returns None
2. Fruitful Functions (Functions with Return Value)
Definition
A fruitful function returns a value that can be:
• Stored in a variable
• Used in expressions
• Passed to other functions
These functions produce a result.
Example
def area_of_circle(radius):
return 3.14159 * radius * radius
area = area_of_circle(5)
print(area)
Here:
• The function computes a value
• The value is returned
• The caller decides how to use it
Using Return Value in an Expression
total_area = area_of_circle(3) + area_of_circle(4)
Engineering Relevance
• Numerical computations
• Formula evaluation
• Data transformation
• Algorithm outputs
3. Void Functions (Functions without Return Value)
Definition
A void function performs an action but does not return a value.
In Python:
• Such functions implicitly return None
Example
def display_message():
print("Welcome to Python")
result = display_message()
print(result)
Output:
Welcome to Python
None
Explanation:
• Function performs printing
• No value is returned
• result stores None
Typical Uses of Void Functions
• Printing results
• Logging messages
• User interaction
• File output
4. Fruitful vs. Void Functions (Critical Comparison)
Aspect Fruitful Function Void Function
Uses return Yes No (or returns None)
Produces value Yes No
Can be used in expressions Yes No
Suitable for computation Yes No
Aspect Fruitful Function Void Function
Suitable for display/logging Sometimes Yes
5. Returning Multiple Values (Python Feature)
Python allows returning multiple values using tuples.
Example
def min_max(values):
return min(values), max(values)
def square_return(x):
return x * x
Difference:
• print() → displays output
• return → sends value back to caller
y = square_print(4) # y = None
z = square_return(4) # z = 16
7. Early Return (Control Flow Use)
return can be used to exit a function early.
def check_positive(x):
if x <= 0:
return "Invalid"
return "Valid"
Benefit:
• Cleaner logic
• Avoids deep nesting
8. Common Student Errors (Must Be Explicitly Warned)
1. Using print() instead of return
2. Expecting a value from a void function
3. Writing code after return
4. Forgetting to store the returned value
5. Mixing computation and display logic in the same function
Incorrect:
def add(a, b):
print(a + b)
numbers = [3, 1, 4]
print(len(numbers)) # Length of list
area = calculate_area(5)
print(area)
Characteristics of User-defined Functions
• Created to solve specific problems
• Improve code reuse
• Reduce repetition
• Enhance readability and structure
• Easy to test and modify
Engineering Use Cases
• Formula implementation
• Simulation steps
• Data processing pipelines
• Reusable computational modules
3. Why Not Use Only Built-in Functions?
Built-in functions:
• Solve general-purpose tasks
• Cannot handle domain-specific logic
Example:
• Python has sum()
• Python does not have compute_groundwater_recharge()
That logic must be written as a user-defined function.
4. Built-in vs. User-defined Functions (Comparison)
Aspect Built-in Functions User-defined Functions
Defined by Python Programmer
Availability Always available Must be defined
Purpose General operations Problem-specific tasks
Performance Highly optimized Depends on implementation
Flexibility Limited Very high
Example len(), abs() calculate_area()
5. Combining Built-in and User-defined Functions
Best practice is to combine both.
def average(values):
return sum(values) / len(values)