{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1a680ee7",
   "metadata": {},
   "source": [
    "# Control Flow & Data Structures Practice (Instructor Solutions)\n",
    "\n",
    "This notebook contains **15 Python practice problems** focused on **if/elif/else statements, for loops, and lists**.\n",
    "\n",
    "**Difficulty Distribution:**\n",
    "- **7 Extremely Easy Questions** (Questions 1-7)\n",
    "- **5 Intermediate Questions** (Questions 8-12)\n",
    "- **3 Extremely Hard Questions** (Questions 13-15)\n",
    "\n",
    "Each question includes:\n",
    "- Function definition with correct return statements\n",
    "- Clear explanation of what the function should return\n",
    "- Test cases with assertions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "17da3759",
   "metadata": {},
   "outputs": [],
   "source": [
    "name = 'student name'\n",
    "roll_number = 'student roll number'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec13c669",
   "metadata": {},
   "source": [
    "---\n",
    "## EXTREMELY EASY QUESTIONS (1-7)\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5481d68c",
   "metadata": {},
   "source": [
    "### 1. Check if a number is odd\n",
    "**Return:** `True` if the number is odd, `False` otherwise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5b4b121e",
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_odd(n: int) -> bool:\n",
    "    if n % 2 != 0:\n",
    "        return True\n",
    "    else:\n",
    "        return False\n",
    "\n",
    "# is_odd(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c27c418c",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert is_odd(3) == True\n",
    "assert is_odd(4) == False\n",
    "assert is_odd(1) == True"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83d7e03f",
   "metadata": {},
   "source": [
    "### 2. Classify age group\n",
    "**Return:** `'Child'` if age < 13, `'Teen'` if 13-19, `'Adult'` if 20-59, `'Senior'` if 60+"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5febf39a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def classify_age(age: int) -> str:\n",
    "    if age < 13:\n",
    "        return 'Child'\n",
    "    elif age < 20:\n",
    "        return 'Teen'\n",
    "    elif age < 60:\n",
    "        return 'Adult'\n",
    "    else:\n",
    "        return 'Senior'\n",
    "\n",
    "# classify_age(25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5f02f43",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert classify_age(10) == 'Child'\n",
    "assert classify_age(15) == 'Teen'\n",
    "assert classify_age(35) == 'Adult'\n",
    "assert classify_age(75) == 'Senior'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6695eefe",
   "metadata": {},
   "source": [
    "### 3. Find length of a list\n",
    "**Return:** The length of the list (number of elements)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0d7a1dee",
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_length(lst: list) -> int:\n",
    "    length = 0\n",
    "    for _ in lst:\n",
    "        length += 1\n",
    "    return length\n",
    "\n",
    "# find_length([1, 2, 3, 4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "18e17c49",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert find_length([]) == 0\n",
    "assert find_length([1]) == 1\n",
    "assert find_length([5, 10, 15, 20]) == 4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69f9b169",
   "metadata": {},
   "source": [
    "### 4. Sum all elements in a list\n",
    "**Return:** The sum of all numbers in the list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7739ea9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def total_sum(lst: list[int]) -> int:\n",
    "    total = 0\n",
    "    for num in lst:\n",
    "        total += num\n",
    "    return total\n",
    "\n",
    "# total_sum([2, 4, 6])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "014a905a",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert total_sum([1, 2, 3]) == 6\n",
    "assert total_sum([10]) == 10\n",
    "assert total_sum([]) == 0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9a1c835",
   "metadata": {},
   "source": [
    "### 5. Check if list is empty\n",
    "**Return:** `True` if list is empty, `False` otherwise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e96dff75",
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_empty(lst: list) -> bool:\n",
    "    if len(lst) == 0:\n",
    "        return True\n",
    "    else:\n",
    "        return False\n",
    "\n",
    "# is_empty([])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cd4b28d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert is_empty([]) == True\n",
    "assert is_empty([1]) == False\n",
    "assert is_empty([None]) == False"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e5849fe",
   "metadata": {},
   "source": [
    "### 6. Get absolute value of a number\n",
    "**Return:** The absolute value (always positive) of the number"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6fcf163",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_absolute(n: int) -> int:\n",
    "    if n < 0:\n",
    "        return -n\n",
    "    else:\n",
    "        return n\n",
    "\n",
    "# get_absolute(-5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c3e95c25",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert get_absolute(-5) == 5\n",
    "assert get_absolute(10) == 10\n",
    "assert get_absolute(0) == 0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8a1a093",
   "metadata": {},
   "source": [
    "### 7. Get the smaller of two numbers\n",
    "**Return:** The minimum value between two numbers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "26506828",
   "metadata": {},
   "outputs": [],
   "source": [
    "def min_of_two(a: int, b: int) -> int:\n",
    "    if a <= b:\n",
    "        return a\n",
    "    else:\n",
    "        return b\n",
    "\n",
    "# min_of_two(5, 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8acd45c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert min_of_two(5, 3) == 3\n",
    "assert min_of_two(100, 50) == 50\n",
    "assert min_of_two(7, 7) == 7"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c2dbdc4",
   "metadata": {},
   "source": [
    "---\n",
    "## INTERMEDIATE QUESTIONS (8-12)\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a67cdb6",
   "metadata": {},
   "source": [
    "### 8. Count how many even numbers in a list\n",
    "**Return:** The count of even numbers\n",
    "**Example:** `[1, 2, 3, 4, 5, 6]` → `3` (because 2, 4, 6 are even)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "981e2681",
   "metadata": {},
   "outputs": [],
   "source": [
    "def count_even(lst: list[int]) -> int:\n",
    "    count = 0\n",
    "    for num in lst:\n",
    "        if num % 2 == 0:\n",
    "            count += 1\n",
    "    return count\n",
    "\n",
    "# count_even([1, 2, 3, 4, 5, 6])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "48ba3a63",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert count_even([1, 2, 3, 4, 5, 6]) == 3\n",
    "assert count_even([1, 3, 5]) == 0\n",
    "assert count_even([2, 4, 6]) == 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7fdcacc",
   "metadata": {},
   "source": [
    "### 9. Create list of squared numbers\n",
    "**Return:** A new list where each element is squared\n",
    "**Example:** `[1, 2, 3]` → `[1, 4, 9]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9be91799",
   "metadata": {},
   "outputs": [],
   "source": [
    "def square_all(lst: list[int]) -> list[int]:\n",
    "    squared = []\n",
    "    for num in lst:\n",
    "        squared.append(num * num)\n",
    "    return squared\n",
    "\n",
    "# square_all([1, 2, 3, 4])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "94056d91",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert square_all([1, 2, 3]) == [1, 4, 9]\n",
    "assert square_all([2, 4]) == [4, 16]\n",
    "assert square_all([]) == []"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f9998de",
   "metadata": {},
   "source": [
    "### 10. Find maximum value in a list\n",
    "**Return:** The largest number in the list (assume list is not empty)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0615c31c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_max(lst: list[int]) -> int:\n",
    "    max_val = lst[0]\n",
    "    for num in lst:\n",
    "        if num > max_val:\n",
    "            max_val = num\n",
    "    return max_val\n",
    "\n",
    "# find_max([3, 7, 2, 9, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab58669f",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert find_max([3, 7, 2, 9, 1]) == 9\n",
    "assert find_max([5, 5, 5]) == 5\n",
    "assert find_max([-10, -5, -20]) == -5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2cd7e37",
   "metadata": {},
   "source": [
    "### 11. Check if a number exists in a list\n",
    "**Return:** `True` if number is in list, `False` otherwise\n",
    "**Example:** `(5, [1, 2, 5, 8])` → `True`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "acfa1ea6",
   "metadata": {},
   "outputs": [],
   "source": [
    "def number_exists(num: int, lst: list[int]) -> bool:\n",
    "    for element in lst:\n",
    "        if element == num:\n",
    "            return True\n",
    "    return False\n",
    "\n",
    "# number_exists(5, [1, 2, 5, 8])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73796e72",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert number_exists(5, [1, 2, 5, 8]) == True\n",
    "assert number_exists(10, [1, 2, 3]) == False\n",
    "assert number_exists(1, [1]) == True"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7500d7e3",
   "metadata": {},
   "source": [
    "### 12. Create list with only odd numbers\n",
    "**Return:** A new list containing only odd numbers from input list\n",
    "**Example:** `[1, 2, 3, 4, 5]` → `[1, 3, 5]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63d6a916",
   "metadata": {},
   "outputs": [],
   "source": [
    "def filter_odd(lst: list[int]) -> list[int]:\n",
    "    odds = []\n",
    "    for num in lst:\n",
    "        if num % 2 != 0:\n",
    "            odds.append(num)\n",
    "    return odds\n",
    "\n",
    "# filter_odd([1, 2, 3, 4, 5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "acf3672c",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert filter_odd([1, 2, 3, 4, 5]) == [1, 3, 5]\n",
    "assert filter_odd([2, 4, 6]) == []\n",
    "assert filter_odd([1, 3, 5]) == [1, 3, 5]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96f74750",
   "metadata": {},
   "source": [
    "---\n",
    "## EXTREMELY HARD QUESTIONS (13-15)\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "88940b64",
   "metadata": {},
   "source": [
    "### 13. Find all pairs in a list that sum to a target\n",
    "**Return:** A list of tuples, where each pair sums to target value\n",
    "**Example:** `([1, 2, 3, 4, 5], 6)` → `[(1, 5), (2, 4)]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0601e9ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_pairs(lst: list[int], target: int) -> list[tuple]:\n",
    "    pairs = []\n",
    "    for i in range(len(lst)):\n",
    "        for j in range(i + 1, len(lst)):\n",
    "            if lst[i] + lst[j] == target:\n",
    "                pairs.append((lst[i], lst[j]))\n",
    "    return pairs\n",
    "\n",
    "# find_pairs([1, 2, 3, 4, 5], 6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4155d81a",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'normalize_pairs' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mNameError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[43mnormalize_pairs\u001b[49m(find_pairs([\u001b[32m1\u001b[39m, \u001b[32m2\u001b[39m, \u001b[32m3\u001b[39m, \u001b[32m4\u001b[39m, \u001b[32m5\u001b[39m], \u001b[32m6\u001b[39m)) == normalize_pairs([(\u001b[32m1\u001b[39m, \u001b[32m5\u001b[39m), (\u001b[32m2\u001b[39m, \u001b[32m4\u001b[39m)])\n\u001b[32m      2\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m normalize_pairs(find_pairs([\u001b[32m2\u001b[39m, \u001b[32m4\u001b[39m, \u001b[32m6\u001b[39m], \u001b[32m8\u001b[39m)) == normalize_pairs([(\u001b[32m2\u001b[39m, \u001b[32m6\u001b[39m)])\n\u001b[32m      3\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m normalize_pairs(find_pairs([\u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m], \u001b[32m2\u001b[39m)) == normalize_pairs([(\u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m), (\u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m), (\u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m), (\u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m), (\u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m), (\u001b[32m1\u001b[39m, \u001b[32m1\u001b[39m)])\n",
      "\u001b[31mNameError\u001b[39m: name 'normalize_pairs' is not defined"
     ]
    }
   ],
   "source": [
    "from collections import Counter\n",
    "\n",
    "def normalize_pairs(result):\n",
    "    # Result is list of tuples or lists like [(1,5),(2,4)]\n",
    "    return Counter([tuple(sorted(p)) for p in result])\n",
    "\n",
    "assert normalize_pairs(find_pairs([1, 2, 3, 4, 5], 6)) == normalize_pairs([(1, 5), (2, 4)])\n",
    "assert normalize_pairs(find_pairs([2, 4, 6], 8)) == normalize_pairs([(2, 6)])\n",
    "assert normalize_pairs(find_pairs([1, 1, 1, 1], 2)) == normalize_pairs([(1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1)])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a36db89b",
   "metadata": {},
   "source": [
    "### 14. Generate Fibonacci sequence up to n terms\n",
    "**Return:** A list of first n Fibonacci numbers\n",
    "**Example:** n=5 → `[0, 1, 1, 2, 3]` (each number is sum of previous two)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "36571dc9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fibonacci(n: int) -> list[int]:\n",
    "    if n <= 0:\n",
    "        return []\n",
    "    elif n == 1:\n",
    "        return [0]\n",
    "\n",
    "    fib_list = [0, 1]\n",
    "    for i in range(2, n):\n",
    "        next_fib = fib_list[i-1] + fib_list[i-2]\n",
    "        fib_list.append(next_fib)\n",
    "    return fib_list\n",
    "\n",
    "# fibonacci(6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73f928c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert fibonacci(5) == [0, 1, 1, 2, 3]\n",
    "assert fibonacci(1) == [0]\n",
    "assert fibonacci(6) == [0, 1, 1, 2, 3, 5]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16d43944",
   "metadata": {},
   "source": [
    "### 15. Check if a list is a palindrome\n",
    "**Return:** `True` if list reads the same forwards and backwards, `False` otherwise\n",
    "**Example:** `[1, 2, 3, 2, 1]` → `True`, but `[1, 2, 3]` → `False`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7fc750b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_palindrome(lst: list) -> bool:\n",
    "    n = len(lst)\n",
    "    for i in range(n // 2):\n",
    "        if lst[i] != lst[n - 1 - i]:\n",
    "            return False\n",
    "    return True\n",
    "\n",
    "# is_palindrome([1, 2, 3, 2, 1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "368175e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert is_palindrome([1, 2, 3, 2, 1]) == True\n",
    "assert is_palindrome([1, 2, 3]) == False\n",
    "assert is_palindrome([5]) == True\n",
    "assert is_palindrome([]) == True"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv (3.13.7)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
