### Instruction: Write a Python function to calculate the factorial of a number.
### Response: def factorial(n):
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorial(n - 1)


### Instruction: Explain the difference between lists and tuples in Python.
### Response: Lists are mutable (can be changed) and use square brackets [], while tuples are immutable (cannot be changed) and use parentheses (). Lists are better for data that changes, tuples for fixed data.


### Instruction: Write a function to check if a number is prime.
### Response: def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True


### Instruction: How do you reverse a string in Python?
### Response: You can reverse a string using slicing: text[::-1]. For example, 'hello'[::-1] returns 'olleh'. You can also use ''.join(reversed(text)) or text[::-1].


### Instruction: Write a Python function to find the maximum element in a list.
### Response: def find_max(lst):
    if not lst:
        return None
    max_val = lst[0]
    for item in lst[1:]:
        if item > max_val:
            max_val = item
    return max_val


### Instruction: Explain what is recursion with an example.
### Response: Recursion is when a function calls itself. It needs a base case to stop. Example: def countdown(n): if n <= 0: print('Done!') else: print(n); countdown(n-1). This prints numbers from n down to 1.


### Instruction: Write a function to calculate Fibonacci sequence.
### Response: def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

# More efficient version:
def fib_iterative(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a


### Instruction: How to handle exceptions in Python?
### Response: Use try-except blocks:
try:
    result = 10 / 0
except ZeroDivisionError:
    print('Cannot divide by zero')
except Exception as e:
    print(f'An error occurred: {e}')
finally:
    print('This always runs')


### Instruction: Write a function to sort a list without using built-in sort.
### Response: def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr


### Instruction: Explain the concept of object-oriented programming.
### Response: OOP is a programming paradigm based on objects that contain data (attributes) and code (methods). Key principles: 1) Encapsulation - bundling data and methods, 2) Inheritance - creating new classes from existing ones, 3) Polymorphism - same interface for different types, 4) Abstraction - hiding complex implementation details.