0% found this document useful (0 votes)
13 views18 pages

Python Functions and Control Statements

The document covers various programming concepts related to functions and strings in Python, including the differences between break and continue statements, the structure and purpose of functions, and the importance of scope and immutability. It explains function definitions, parameters, return statements, and best practices for writing functions. Additionally, it discusses string immutability, indexing, and advanced slicing techniques.

Uploaded by

flashyrebirth
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views18 pages

Python Functions and Control Statements

The document covers various programming concepts related to functions and strings in Python, including the differences between break and continue statements, the structure and purpose of functions, and the importance of scope and immutability. It explains function definitions, parameters, return statements, and best practices for writing functions. Additionally, it discusses string immutability, indexing, and advanced slicing techniques.

Uploaded by

flashyrebirth
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Module 3 - String and function

PREQUIZ

Question 1: What is the primary difference between break and continue statements
in loop control?
a) Break pauses the loop, continue stops it permanently
b) Break exits the loop entirely, continue skips the current iteration and moves to the
next
c) Both statements do the same thing
d) Continue exits the loop, break skips to the next iteration
Question 2: What will be the output of this code?
for i in range(5):
if i == 3:
break
print(i)
a) 0 1 2 3 4
b) 0 1 2
c) 0 1 2 3
d) 1 2 3
Question 3: Which statement would you use to skip printing the number 5 in a loop
from 1 to 10?
a) if i == 5: break
b) if i == 5: pass
c) if i == 5: continue
d) if i == 5: return
Question 4: Which of the following is the correct way to define a function in Python?
a) function myFunc():
b) def myFunc():
c) define myFunc():
d) func myFunc():
Question 5: Which method converts "python" to "PYTHON"?
a) [Link]()
b) [Link]()
c) [Link]()
d) [Link]()
Answer: b) [Link]()

Question 6: What happens if a recursive function lacks a base case?


a) It returns None
b) It causes infinite recursion/stack overflow
c) It won't compile
d) It returns 0
LEARN

Module 2.1: Introduction to Functions - Complete Understanding

What Are Functions?

Functions are self-contained blocks of code that accomplish specific tasks. Think of
them as mini-programs within your program. Just as a recipe combines ingredients
and steps to create a dish, a function combines parameters and statements to
produce a result. Functions are the building blocks of structured programming and
provide numerous benefits.
Why Use Functions?

Code Reusability: Instead of writing the same code multiple times, you write it once
in a function and call it whenever needed. This follows the DRY principle - Don't
Repeat Yourself.
Modularity: Functions break complex problems into smaller, manageable pieces.
Each function handles one specific task, making the overall program easier to
understand and maintain.
Abstraction: Functions hide implementation details. Users of a function don't need
to know how it works internally, only what inputs it needs and what output it provides.
Testing and Debugging: Isolated functions are easier to test and debug. You can
verify each function works correctly independently before integrating them.
Collaboration: Different team members can work on different functions
simultaneously without interfering with each other's code.
Function Terminology

 Function Definition: The actual code that describes what the function does

 Function Call/Invocation: Using the function in your program

 Function Name: The identifier used to call the function

 Function Body: The indented block of code that executes when the function
is called
 Function Signature: The combination of function name and parameters

Module 2.2: Defining Functions - In-Depth Guide


Basic Function Syntax
Every function definition in Python follows a specific structure. The def keyword
signals the start of a function definition. This is followed by the function name,
parentheses (which may contain parameters), and a colon. The function body must
be indented, typically by four spaces.
Naming Conventions

Function names should be:


 Descriptive: The name should clearly indicate what the function does

 Lowercase: Python convention uses lowercase letters


 Snake_case: Multiple words separated by underscores

 Verb-based: Functions perform actions, so use verbs like calculate, process,


validate
 Avoiding reserved words: Don't use Python keywords as function names

Good examples: calculate_average, validate_email, process_payment,


get_user_input
Poor examples: func1, x, data, function
Documentation Strings (Docstrings)

A docstring is a string literal that appears as the first statement in a function. It


describes what the function does, its parameters, return value, and any exceptions it
might raise. Docstrings are accessible through the function's doc attribute and are
used by documentation generation tools.

Docstring conventions:

 Use triple quotes for multi-line docstrings

 First line should be a brief summary


 More detailed explanation follows after a blank line
 Document parameters, return values, and exceptions

 Include usage examples for complex functions


Function Body Structure

The function body contains:


1. Input validation: Check if parameters meet requirements

2. Main logic: The core functionality

3. Error handling: Deal with potential problems


4. Return statement: Send results back to caller
Module 2.3: Parameters and Arguments - Comprehensive Guide

Understanding Parameters vs Arguments

Parameters are the variables listed in the function definition. They are placeholders
that will receive values when the function is called. Think of them as empty boxes
waiting to be filled.
Arguments are the actual values passed to the function when calling it. They are the
contents that fill those parameter boxes.
Types of Parameters

1. Positional Parameters
These are the most common type. Arguments must be provided in the same order as
parameters are defined. The position matters, hence the name. Each positional
parameter must receive exactly one argument unless it has a default value.
2. Keyword Parameters
When calling a function, you can specify arguments by parameter name. This allows
arguments to be provided in any order and makes function calls more readable.
Keyword arguments must come after positional arguments in the function call.
3. Default Parameters
Parameters can have default values specified in the function definition. If no
argument is provided for that parameter, the default value is used. Default
parameters must come after non-default parameters in the definition.
4. Variable-Length Parameters

 *args: Accepts any number of positional arguments as a tuple


 **kwargs: Accepts any number of keyword arguments as a dictionary

Parameter Passing Mechanism

Python uses "pass-by-object-reference" mechanism:


 Immutable objects (strings, numbers, tuples): Changes inside the function
don't affect the original
 Mutable objects (lists, dictionaries): Changes inside the function affect the
original
Best Practices for Parameters

1. Limit the number of parameters (ideally 3 or fewer)

2. Use descriptive parameter names


3. Group related parameters into objects if there are many
4. Document parameter types and expectations

5. Validate parameter values at the start of the function

6. Use default values for optional parameters

7. Consider using keyword-only parameters for clarity

Module 2.4: The Return Statement - Complete Analysis

Purpose of Return

The return statement serves multiple purposes:


1. Exits the function: Immediately terminates function execution

2. Sends value back: Provides a result to the calling code

3. Indicates success/failure: Can return status codes or boolean values

4. Enables function chaining: Returned values can be used as inputs to other


functions
Return Statement Behavior

No Return Statement:
If a function doesn't have a return statement, it implicitly returns None. This is
common for functions that perform actions rather than calculations.
Empty Return:
A return statement without a value also returns None but explicitly exits the function
early. Useful for conditional exits.
Multiple Return Statements:
A function can have multiple return statements, but only one executes per call. Often
used with conditional logic to return different values based on conditions.
Returning Multiple Values:
Python can return multiple values as a tuple. This is actually returning a single tuple
object that can be unpacked by the caller.
Return Value Types

Functions can return:


 Primitive types: integers, floats, strings, booleans

 Collections: lists, tuples, dictionaries, sets

 Objects: custom class instances


 Functions: functions can return other functions (higher-order functions)
 None: indicates no meaningful value to return

Best Practices for Return Statements

1. Be consistent with return types

2. Document what the function returns

3. Return early for error conditions

4. Avoid complex expressions in return statements

5. Consider returning named tuples for multiple values

6. Use None explicitly for no value


7. Don't mix return with and without values

Module 2.5: Default Argument Values - Advanced Concepts

How Default Arguments Work

Default arguments are evaluated once when the function is defined, not each time
it's called. This has important implications, especially with mutable default values.
Default arguments allow functions to be called with fewer arguments than
parameters, providing flexibility and backward compatibility.
Rules for Default Arguments

1. Order: Default parameters must come after non-default parameters

2. Evaluation: Default values are evaluated at definition time

3. Scope: Default values are evaluated in the scope where the function is
defined
4. Overriding: Providing an argument overrides the default value

The Mutable Default Argument Trap

Using mutable objects (lists, dictionaries) as default values can lead to unexpected
behavior because the same object is reused across function calls. Each call that
uses the default will share the same mutable object, leading to unintended data
sharing.
Solution: Use None as default and create new mutable objects inside the function.

Use Cases for Default Arguments

1. Configuration options: Provide sensible defaults for configuration


parameters
2. Optional features: Enable optional functionality without requiring all
arguments
3. Backward compatibility: Add new parameters without breaking existing
code
4. Convenience methods: Simplify common use cases

Advanced Default Argument Patterns

Sentinel Values:
Using None or custom sentinel objects to distinguish between "no argument
provided" and "None was explicitly passed"
Factory Functions:
Using callables as defaults that generate fresh values
Conditional Defaults:
Computing default values based on other parameters or system state

LEARN2

What is Scope?

Scope is the region of a program where a variable is accessible. It determines the


visibility and lifetime of variables. Understanding scope is crucial for writing bug-free
code and managing program state effectively. Python uses lexical (static) scoping,
meaning scope is determined by where variables are defined in the code, not where
they're called.
The LEGB Rule

Python resolves names using the LEGB rule, checking each scope in order:
L - Local Scope:

 Inside the current function

 Created when function is called

 Destroyed when function returns

 Each function call creates new local scope


E - Enclosing Scope:

 In the enclosing function (for nested functions)

 Accessible to inner functions


 Allows closures and function factories
 Created by nested function definitions
G - Global Scope:

 At the top level of the module

 Available throughout the module

 Persists for program duration

 Shared across all functions in the module


B - Built-in Scope:

 Pre-defined names in Python


 Always available

 Includes built-in functions and exceptions

 Lowest priority in name resolution


Namespace and Scope Relationship

A namespace is a container that maps names to objects. Each scope has its own
namespace. When you use a name, Python searches through namespaces in LEGB
order until it finds the name or raises a NameError.
Variable Lifetime

 Local variables: Live from creation until function returns

 Global variables: Live for entire program execution

 Enclosed variables: Live as long as the enclosing function exists

Module 3.2: Local Scope - Deep Dive

Creating Local Scope

Every function call creates a new local scope. Variables assigned within a function
are local by default. Parameters are also local variables. Local scope is isolated from
other scopes, providing encapsulation.
Local Variable Characteristics

Isolation: Local variables can't be accessed from outside the function


Shadowing: Local variables can have the same name as global variables, hiding
them
Temporary: Local variables are destroyed when function exits
Stack-based: Stored on the call stack, automatically managed
Local Scope Best Practices
1. Prefer local variables: They're safer and more predictable

2. Initialize variables: Always initialize before use

3. Minimize scope: Declare variables close to where they're used

4. Avoid shadowing: Don't reuse names from outer scopes

5. Document side effects: If function modifies external state

Common Local Scope Patterns

Accumulator Pattern:
Using local variables to build up results iteratively
Temporary Storage:
Local variables for intermediate calculations
Loop Variables:
Loop control variables are local to the function
Guard Variables:
Boolean flags for controlling flow
3.2 Working with Global Variables

Global variables are defined at module level, outside all functions. They're accessible
from any function in the module but require special handling to modify.
The global Keyword

To modify a global variable inside a function, you must declare it with the global
keyword. This tells Python to use the global namespace for that variable. Without
global, assignment creates a new local variable.
When to Use Global Variables

Appropriate uses:

 Configuration constants

 Shared state between functions

 Cache or memoization storage

 Module-level settings
Inappropriate uses:

 Function communication (use parameters/returns instead)

 Temporary storage
 Loop counters
 Function-specific data
Global Variable Pitfalls

1. Hidden dependencies: Functions depend on external state

2. Testing difficulties: Tests need to manage global state

3. Thread safety: Global variables aren't thread-safe

4. Debugging challenges: Hard to track modifications

5. Namespace pollution: Too many globals clutter namespace

Alternatives to Global Variables


 Class attributes: Encapsulate related data in classes

 Function parameters: Pass data explicitly

 Return values: Return modified data

 Closures: Capture state in nested functions

 Modules: Use separate modules for configuration

3.4

What is Recursion?

Recursion is a problem-solving technique where a function calls itself to solve


smaller instances of the same problem. It's based on the principle of mathematical
induction and is particularly elegant for problems with recursive structure.

4.1

What is Immutability?

Immutability means an object's state cannot be modified after creation. In Python,


strings are immutable - once created, their characters cannot be changed. Any
operation that appears to modify a string actually creates a new string object.
Why Are Strings Immutable?

Security: Strings can't be accidentally or maliciously modified


Hashability: Immutable objects can be used as dictionary keys
Thread Safety: Multiple threads can safely access the same string
Memory Optimization: Python can intern and reuse string objects
Predictability: String values remain constant throughout program execution

Implications of Immutability
Memory Usage:
String operations create new objects, potentially using more memory. Concatenating
strings in loops can be inefficient.
Performance Considerations:
Building strings character by character is inefficient. Use join() method or string
builders for better performance.
Reference Sharing:
Multiple variables can safely reference the same string object. Assignment creates
new references, not copies.
Working with Immutability
String Building Strategies:

1. Use join() for combining many strings

2. Use formatting for complex string construction

3. Use StringIO for file-like string building

4. List comprehensions for string transformation


Common Pitfalls:

 Attempting to modify string characters directly

 Inefficient string concatenation in loops

 Forgetting to assign results of string methods


String Indexing Fundamentals

Positive Indexing:

 Starts at 0 for first character

 Increments by 1 for each position

 Last character at length-1

 Out of bounds raises IndexError


Negative Indexing:

 Starts at -1 for last character


 Decrements moving backward
 First character at -length

 Provides convenient access from end


Understanding Index Positions

Think of indices as positions between characters:

 Index points to the start of a character

 Positive indices count from left

 Negative indices count from right

 Slicing uses these boundary positions


Step Parameter:

 Increment between characters

 Defaults to 1 if omitted

 Negative step reverses direction

 Zero step raises ValueError


Advanced Slicing Techniques

Reversing Strings:
Using [::-1] reverses entire string efficiently
Every Nth Character:
Using [::n] selects every nth character
Palindrome Check:
Compare string with its reverse using slicing
Substring Extraction:
Extract portions using calculated indices
String Rotation:
Rotate strings using slicing combinations

Slice Object Creation

Slices can be created as objects and reused:


 slice(start, stop, step) creates slice object

 Applied using bracket notation

 Useful for complex slicing patterns


 Can be stored and passed as parameters
Dynamic Slicing

Calculated Indices:
Use variables and expressions for slice boundaries
Conditional Slicing:
Choose slice based on conditions
Parameterized Slicing:
Pass slice parameters to functions
Common Slicing Patterns
Trimming Operations:

 Remove first/last n characters

 Strip specific prefixes/suffixes

 Extract middle portions


Chunking Strings:

 Divide into equal parts

 Split at specific intervals

 Create overlapping windows


Pattern Matching:

 Extract patterns using slicing

 Find repeating sequences

 Validate string structure


Length and Size Methods

len() Function:

 Returns character count including spaces


 Counts Unicode characters correctly

 O(1) time complexity

 Fundamental for iteration and validation


Case Conversion Methods

upper() Method:

 Converts all characters to uppercase


 Returns new string (immutability)
 Locale-independent for ASCII

 Useful for case-insensitive comparison


lower() Method:

 Converts all characters to lowercase

 Handles Unicode properly

 Common for normalization

 Used in search operations


capitalize() Method:

 First character uppercase, rest lowercase

 Useful for proper formatting

 Handles empty strings gracefully


title() Method:

 Capitalizes first letter of each word

 Uses Unicode definition of words

 May not handle contractions correctly


swapcase() Method:

 Inverts case of all characters

 Limited practical use

 Demonstration of string transformation


Search and Replace Methods

find() Method:

 Returns lowest index of substring

 Returns -1 if not found


 Optional start and end parameters

 Case-sensitive search
index() Method:

 Like find() but raises ValueError if not found

 Use when substring must exist


 Supports start and end parameters
rfind() and rindex():

 Search from right (highest index)

 Useful for finding last occurrence

 Same parameters as find()/index()


replace() Method:

 Replaces all occurrences of substring

 Optional count parameter limits replacements

 Returns new string


 Can replace with empty string to remove
count() Method:

 Counts non-overlapping occurrences

 Optional start and end parameters

 Case-sensitive counting

 Returns integer count


Trimming and Padding Methods

strip() Method:

 Removes leading and trailing whitespace

 Optional chars parameter for custom removal

 Doesn't modify internal whitespace

 Common for input cleaning


lstrip() and rstrip():

 Remove from left or right only

 Same parameters as strip()


 Useful for specific trimming needs
center() Method:

 Centers string in field of given width

 Optional fillchar parameter

 Returns original if width too small


ljust() and rjust():
 Left or right justify in field

 Padding with spaces or custom character

 Useful for formatting output


zfill() Method:

 Pads numeric string with zeros

 Handles signs correctly

isdigit() Method:

 True if all characters are digits

 Includes Unicode digits

 False for empty strings


isalnum() Method:

 True if all alphanumeric

 Combination of isalpha() and isdigit()

 No spaces or punctuation
isspace() Method:

 True if all characters are whitespace

 False for empty strings

 Includes various Unicode spaces


islower() and isupper():

 Check case of cased characters

 Ignore non-cased characters

 Require at least one cased character


istitle() Method:

 Checks title case formatting

 Each word starts with uppercase

 Following characters lowercase

Challenge1:
Code Task: Write a recursive function to calculate the $n^{th}$ number in the
Fibonacci sequence.
Challenge2:
Code Task: Write a function that accepts a full name string, uses string slicing to
extract the first name and last name, and returns the name formatted as: "Last
Name, First Name (Initials)".
Apply1:

Project Task: Develop a Palindrome Checker function. The function takes a string,
converts it to lowercase, and returns True if it reads the same forwards and
backwards, using string slicing or reversing.
Apply2:

Project Task: Create a simple Password Generator function that uses default
arguments to allow the user to specify the length and includes at least two required
string methods (e.g., upper(), replace()) for complexity.

POSTQUIZ:

Question 1: What is the primary difference between break and continue statements
in loop control?

a) Break pauses the loop, continue stops it permanently


b) Break exits the loop entirely, continue skips the current iteration and moves to the
next
c) Both statements do the same thing
d) Continue exits the loop, break skips to the next iteration
Question 2: What will be the output of this code?
for i in range(5):
if i == 3:
break
print(i)

a) 0 1 2 3 4
b) 0 1 2
c) 0 1 2 3
d) 1 2 3

Question 3: What is the scope of variable 'x' in this code?


def func():
x = 10
return x

a) Global
b) Local
c) Built-in
d) Universal
Question 4: Which method converts "python" to "PYTHON"?
a) [Link]()
b) [Link]()
c) [Link]()
d) [Link]()

Answer: b) [Link]()
Question 5: What does "Python"[-1] return?
a) "P"
b) "n"
c) Error
d) "Python"
Question 6: How do you reverse a string using slicing?
a) [Link]()
b) string[::-1]
c) string[-1:0]
d) reverse(string)
Question 7: What will len("Hello World") return?
a) 10
b) 11
c) 12
d) 2

You might also like