{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bb725259",
   "metadata": {},
   "source": [
    "# Modules\n",
    "\n",
    "This section teaches how modules work in Python and how quickly you can build your own reusable modules for projects.\n",
    "\n",
    "**Learning Goals**\n",
    "- Explain what a Python module is\n",
    "- Create a custom module file\n",
    "- Import and use module functions in another file/notebook\n",
    "- Organize module code in a project-friendly way"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df0eaf85",
   "metadata": {},
   "source": [
    "## What Is a Module?\n",
    "\n",
    "A **module** is a Python file (`.py`) that contains reusable code (functions, classes, variables).\n",
    "\n",
    "Why this matters for projects:\n",
    "- You avoid copy-pasting logic\n",
    "- You separate concerns (I/O, processing, utilities)\n",
    "- You can test and reuse functionality across files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5837f65b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-19T03:58:55.454948Z",
     "iopub.status.busy": "2026-03-19T03:58:55.454857Z",
     "iopub.status.idle": "2026-03-19T03:58:55.457396Z",
     "shell.execute_reply": "2026-03-19T03:58:55.457168Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9.0\n",
      "3.141592653589793\n"
     ]
    }
   ],
   "source": [
    "# Built-in module example\n",
    "import math\n",
    "\n",
    "print(math.sqrt(81))\n",
    "print(math.pi)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0cbd546",
   "metadata": {},
   "source": [
    "## Create and Import Your Own Module\n",
    "\n",
    "A custom module is just a `.py` file.\n",
    "The example below writes a module file, imports it, and reuses its functions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "263d9f7a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-19T03:58:55.458533Z",
     "iopub.status.busy": "2026-03-19T03:58:55.458469Z",
     "iopub.status.idle": "2026-03-19T03:58:55.461119Z",
     "shell.execute_reply": "2026-03-19T03:58:55.460943Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "36\n",
      "27\n"
     ]
    }
   ],
   "source": [
    "from pathlib import Path\n",
    "import sys\n",
    "\n",
    "module_dir = Path('.')\n",
    "module_dir.mkdir(parents=True, exist_ok=True)\n",
    "module_path = module_dir / 'my_math_tools.py'\n",
    "\n",
    "module_path.write_text(\n",
    "    \"def square(x):\\n\"\n",
    "    \"    return x * x\\n\\n\"\n",
    "    \"def cube(x):\\n\"\n",
    "    \"    return x * x * x\\n\",\n",
    "    encoding='utf-8'\n",
    ")\n",
    "\n",
    "if str(module_dir.resolve()) not in sys.path:\n",
    "    sys.path.insert(0, str(module_dir.resolve()))\n",
    "\n",
    "import my_math_tools\n",
    "\n",
    "print(my_math_tools.square(6))\n",
    "print(my_math_tools.cube(3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "bb0c441c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-19T03:58:55.462650Z",
     "iopub.status.busy": "2026-03-19T03:58:55.462571Z",
     "iopub.status.idle": "2026-03-19T03:58:55.464036Z",
     "shell.execute_reply": "2026-03-19T03:58:55.463850Z"
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### Exercise: Build a Tax Module\n",
    "# Create a file `pricing_tools.py` with a function:\n",
    "# `add_tax(price, rate=0.07)` that returns price with tax.\n",
    "# Then import it and calculate the taxed value of 49.99.\n",
    "### Your code starts here.\n",
    "\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2a73c8ae",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-19T03:58:55.465047Z",
     "iopub.status.busy": "2026-03-19T03:58:55.464990Z",
     "iopub.status.idle": "2026-03-19T03:58:55.467496Z",
     "shell.execute_reply": "2026-03-19T03:58:55.467201Z"
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "53.49\n"
     ]
    }
   ],
   "source": [
    "### Solution\n",
    "from pathlib import Path\n",
    "import sys\n",
    "\n",
    "module_dir = Path('.')\n",
    "module_dir.mkdir(parents=True, exist_ok=True)\n",
    "module_path = module_dir / 'pricing_tools.py'\n",
    "module_path.write_text(\n",
    "    \"def add_tax(price, rate=0.07):\\n\"\n",
    "    \"    return price * (1 + rate)\\n\",\n",
    "    encoding='utf-8'\n",
    ")\n",
    "\n",
    "if str(module_dir.resolve()) not in sys.path:\n",
    "    sys.path.insert(0, str(module_dir.resolve()))\n",
    "\n",
    "import pricing_tools\n",
    "print(round(pricing_tools.add_tax(49.99), 2))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc508357",
   "metadata": {},
   "source": [
    "## Module Design for Projects\n",
    "\n",
    "Simple project pattern:\n",
    "- one file for entry point (`main.py`)\n",
    "- one or more module files for reusable logic (`utils.py`, `data_ops.py`, etc.)\n",
    "\n",
    "Keep module functions:\n",
    "- small\n",
    "- single-purpose\n",
    "- well-named\n",
    "- easy to test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "a907bfab",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-19T03:58:55.468684Z",
     "iopub.status.busy": "2026-03-19T03:58:55.468620Z",
     "iopub.status.idle": "2026-03-19T03:58:55.469976Z",
     "shell.execute_reply": "2026-03-19T03:58:55.469780Z"
    }
   },
   "outputs": [],
   "source": [
    "# Example project-style split (conceptual)\n",
    "# main.py\n",
    "# from my_math_tools import square\n",
    "# print(square(10))\n",
    "\n",
    "# my_math_tools.py\n",
    "# def square(x):\n",
    "#     return x * x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f394ff4",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "If students can build one custom module, they can scale to small projects:\n",
    "- define reusable functions once\n",
    "- import where needed\n",
    "- keep project code organized"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "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
}
