20TD02U_Functions and Methods - itnett/FTD02H-N GitHub Wiki
Remembering: "What is a function? List the parts of a function definition."
Function: A function is a block of code that performs a specific task, is reusable, and can be executed when called. Functions help to organize code, make it more readable, and allow for code reuse.
Parts of a Function Definition:
- Function Name: The name by which the function can be called.
 - Parameters: Variables passed to the function.
 - Body: The block of code that performs the task.
 - Return Statement: The value or output that the function returns (optional).
 
Example Function Definitions:
# Function to add two numbers
def add(a, b):
    return a + b
# Function with no parameters
def greet():
    print("Hello, world!")
Understanding: "Describe the difference between a function and a method. Provide examples."
Difference Between Function and Method:
- Function:
- A function is a standalone block of code that can be called independently.
 - It is not bound to any object or class.
 
 
Example:
def add(a, b):
    return a + b
result = add(2, 3)
print(result)  # Output: 5
- Method:
- A method is a function that is associated with an object or class.
 - It is called on an instance of a class and can access or modify the data within that instance.
 
 
Example:
class Calculator:
    def add(self, a, b):
        return a + b
calc = Calculator()
result = calc.add(2, 3)
print(result)  # Output: 5
Applying: "Write a function to calculate the factorial of a number. Explain how it works."
Function to Calculate Factorial:
def factorial(n):
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorial(n - 1)
# Example usage
print(factorial(5))  # Output: 120
Explanation:
- The function 
factorialtakes an integernas an argument. - It checks if 
nis 0 or 1, in which case it returns 1 (base case). - If 
nis greater than 1, it returnsnmultiplied by the factorial ofn - 1(recursive case). - This process continues until the base case is reached, resulting in the product of all positive integers up to 
n. 
Analyzing: "Analyze the efficiency of recursive vs. iterative function implementations."
Recursive Implementation:
def factorial_recursive(n):
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorial_recursive(n - 1)
Iterative Implementation:
def factorial_iterative(n):
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result
Efficiency Analysis:
- 
Recursive:
- Space Complexity: O(n) due to call stack.
 - Time Complexity: O(n).
 - Pros: Simple and elegant for small 
n. - Cons: Can lead to stack overflow for large 
n. 
 - 
Iterative:
- Space Complexity: O(1) as no additional call stack is used.
 - Time Complexity: O(n).
 - Pros: More efficient in terms of memory.
 - Cons: Slightly more complex code compared to recursion.
 
 
Evaluating: "Evaluate the readability and maintainability of functions with different complexities."
Simple Function:
def add(a, b):
    return a + b
Complex Function:
def process_data(data):
    result = []
    for item in data:
        if isinstance(item, dict):
            for key, value in item.items():
                if key == 'target' and isinstance(value, list):
                    result.extend(value)
                elif key == 'target' and isinstance(value, dict):
                    result.append(value)
    return result
Evaluation:
- 
Readability:
- Simple functions are easy to read and understand.
 - Complex functions require careful documentation and clear variable naming to maintain readability.
 
 - 
Maintainability:
- Simple functions are easier to maintain due to their straightforward logic.
 - Complex functions should be broken down into smaller, manageable sub-functions to enhance maintainability.
 
 
Creating: "Design a set of reusable functions for a given application. Explain your design choices."
Application: Data Analysis
Reusable Functions:
- 
Load Data:
import pandas as pd def load_data(file_path): """ Load data from a CSV file. :param file_path: str :return: DataFrame """ return pd.read_csv(file_path) - 
Clean Data:
def clean_data(df): """ Clean the DataFrame by filling missing values. :param df: DataFrame :return: DataFrame """ df.fillna(0, inplace=True) return df - 
Analyze Data:
def analyze_data(df): """ Perform data analysis by calculating summary statistics. :param df: DataFrame :return: dict """ summary = { 'mean': df.mean(), 'median': df.median(), 'std': df.std() } return summary - 
Visualize Data:
import matplotlib.pyplot as plt def visualize_data(df): """ Create a bar plot of the DataFrame. :param df: DataFrame """ df.plot(kind='bar') plt.show() 
Design Choices:
- Modularity: Each function performs a specific task, making the code easy to manage and reusable.
 - Clarity: Function names and parameters are self-explanatory, enhancing readability.
 - Documentation: Docstrings provide clear descriptions of each function’s purpose and usage.
 
Example Usage:
data = load_data('data.csv')
cleaned_data = clean_data(data)
summary = analyze_data(cleaned_data)
visualize_data(cleaned_data)
print(summary)
This set of functions demonstrates a structured approach to data analysis, promoting code reuse and maintainability.