{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ac00bb4f",
   "metadata": {},
   "source": [
    "# Python Built-in Functions\n",
    "\n",
    "In Python, built-in functions and built-in modules are both part of the standard tools the language gives you, but they serve different purposes. Built-in functions are ready to use without requiring any imports. They are automatically available in every Python program. Modules, on the other hand, need to be imported to use. For the functionalities that Python does not provide, we either\n",
    "\n",
    "1. Find a third-party **package** (module or library) with the functions, install the package, and use the contained functions, or\n",
    "2. Write a **user-defined** custom function. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64db313e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "from pathlib import Path\n",
    "\n",
    "# Find project root by looking for _config.yml\n",
    "current = Path.cwd()\n",
    "for parent in [current, *current.parents]:\n",
    "    if (parent / '_config.yml').exists():\n",
    "        project_root = parent\n",
    "        break\n",
    "else:\n",
    "    project_root = Path.cwd().parent.parent\n",
    "\n",
    "# Add project root to path\n",
    "sys.path.insert(0, str(project_root))\n",
    "\n",
    "# Import shared teaching helpers and cell magics\n",
    "from shared import thinkpython, diagram, jupyturtle, structshape\n",
    "from shared.download import download\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47e29003",
   "metadata": {},
   "source": [
    "**Built-in** vs **custom functions**: Python ships with functions like `print()` and `len()`, and you can also create your own custom functions."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "caf4cda6",
   "metadata": {},
   "source": [
    "Python built-in functions are tools for quick operations (such as length, conversion, and output). A few of them that you will use constantly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e8ac9c01",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello!\n",
      "3\n",
      "42\n",
      "6\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "print(\"Hello!\")              # Output to screen\n",
    "\n",
    "len_num = len([1, 2, 3])     # 3: len() get the length of the argument\n",
    "num = int(\"42\")              # 42 (string → int); int() is a type constructor\n",
    "sum_num = sum([1, 2, 3])     # 6 (sum a list sequence)\n",
    "max_num = max(5, 2, 9)       # 9\n",
    "\n",
    "print(len_num)\n",
    "print(num)\n",
    "print(sum_num)\n",
    "print(max_num)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "435d7f0c",
   "metadata": {},
   "source": [
    "In the [Python Standard Library](https://docs.python.org/3/library/index.html), you can find all the Python built-in functions listed:\n",
    "\n",
    "```{figure} ../../images/python-builtin-functions.png\n",
    "---\n",
    "width: 400px\n",
    "name: python-builtin-functions\n",
    "---\n",
    "[Python Built-In Functions](https://docs.python.org/3/library/functions.html#built-in-functions)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a5e1218",
   "metadata": {},
   "source": [
    "We may group the 71 built-in functions by their purposes.\n",
    "\n",
    "| Group                           | Functions                                                                                                                          | Notes                                                            |\n",
    "| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |\n",
    "| Numbers & math                  | `abs`, `divmod`, `max`, `min`, `pow`, `round`, `sum`                                                                               | `pow(a, b, mod=None)` supports modular exponentiation.           |\n",
    "| Type construction/conversion | **`bool`**, **`int`**, **`float`**, `complex`, **`str`**, `bytes`, `bytearray`, `memoryview`, **`list`**, **`tuple`**, `set`, `frozenset`, **`dict`**, **`range`** | Convert or construct core types.                                 |\n",
    "| Object/attribute introspection  | **`type`**, **`isinstance`**, `issubclass`, **`id`**, `hash`, `dir`, `vars`, `repr`, `ascii`                                                   | `vars(obj)` → `obj.__dict__` when available.                     |\n",
    "| Attribute access                | `getattr`, `setattr`, `delattr`, `hasattr`                                                                                         | Dynamic attribute management.                                    |\n",
    "| Iteration & functional tools    | `iter`, `next`, **`enumerate`**, `zip`, `map`, `filter`, `sorted`, `reversed`                                                          | Prefer comprehensions when clearer.                              |\n",
    "| Sequence/char helpers           | **`len`**, `ord`, `chr`, `slice`                                                                                                       | `len()` works on many containers.                                |\n",
    "| I/O                             | **`print`**, **`input`**, `open`                                                                                                           | `open` returns a context manager; prefer `with open(...) as f:`. |\n",
    "| Formatting / representation     | `format`, `bin`, `oct`, `hex`                                                                                                      | Also see f-strings for formatting.                               |\n",
    "| Object model (OOP helpers)      | `object`, `property`, `classmethod`, `staticmethod`, `super`                                                                       | Define descriptors and class behaviors.                          |\n",
    "| Execution / metaprogramming     | `compile`, `eval`, `exec`                                                                                                          | Use with care; security concerns for untrusted input.            |\n",
    "| Environment / namespaces        | `globals`, `locals`                                                                                                                | Introspection of current namespaces.                             |\n",
    "| Help/debugging                  | `help`, `breakpoint`                                                                                                               | `breakpoint()` respects `PYTHONBREAKPOINT`.                      |\n",
    "| Import                          | `__import__`                                                                                                                       | Low-level import; usually use `import` statement instead.        |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce81ad3b",
   "metadata": {},
   "source": [
    "But Python has more than the built-in functions listed above. Let's look at arithmetic/math functions as an example. You see that Python provides three groups of arithmetic **functions**:\n",
    "1. **built-in** functions (the 7 functions as listed in the table above)\n",
    "2. **`operator`** module functions\n",
    "3. **`math`** module functions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64f51e70",
   "metadata": {},
   "source": [
    "For the **`operator`** module, there are math functions to perform the same operations as the arithmetic operators, which you will need to perform operations such `map` and `reduce`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "643f1238",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import operator\n",
    "operator.add(3, 2)       # 5\n",
    "operator.sub(3, 2)       # 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c5fca0d",
   "metadata": {},
   "source": [
    "The `math` module functions do better with high-level arithmetic, as shown below. These functions are self-explanatory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ca5fac69",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48660645",
   "metadata": {},
   "source": [
    "| Function              | Purpose                 | Example        |    |      |\n",
    "| --------------------- | ----------------------- | ---------------|----|------ |\n",
    "| `math.sqrt(x)`        | Square root             | `math.sqrt(16)` | →  | `4.0`   |\n",
    "| `math.factorial(x)`   | Factorial               | `math.factorial(5)` | → | `120` |\n",
    "| `math.ceil(x)`        | Round up                | `math.ceil(3.2)` | → | `4`      |\n",
    "| `math.floor(x)`       | Round down              | `math.floor(3.9)` | → | `3`     |\n",
    "| `math.prod(iterable)` | Multiply all items      | `math.prod([2, 3, 4])` | → | `24` |\n",
    "| `math.fabs(x)`        | Absolute (always float) | `math.fabs(-7)` | → | `7.0`     |\n",
    "| `math.isfinite(x)`    | Finite number?          | `math.isfinite(2)` | → | `True` |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ab6e2c3",
   "metadata": {},
   "source": [
    "```{index} argument\n",
    "```\n",
    "\n",
    "## Arguments\n",
    "\n",
    "When you call a function, the `expression` in parentheses is called an **argument**. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "32d3b139",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Any number of arguments\n"
     ]
    }
   ],
   "source": [
    "int('101')           ### take one argument\n",
    "math.pow(5, 2)       ### take two\n",
    "int('101', 2)        ### take additional optional arguments, such as base 2 here\n",
    "round(math.pi, 3)    ### takes an optional second argument, **decimal places** \n",
    "print('Any', 'number', 'of', 'arguments')   ### multiple arguments"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57b81d54",
   "metadata": {},
   "source": [
    "## Return Values\n",
    "\n",
    "When you call built-in functions such as `abs`, `round`, `sqrt`, and `pow`, they return a value you can assign to a variable or use as part of an expression. \n",
    "\n",
    "Some use the `print` function to display values, but they don't return values we assign to variables or use in expressions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50e1de8b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.656366395715726"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import math\n",
    "\n",
    "math.sqrt(42 / math.pi)            ### returns value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f34c75e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.656366395715726"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "radius = math.sqrt(42 / math.pi)    ### assign to variable\n",
    "radius"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3d640fb",
   "metadata": {},
   "source": [
    "If a function doesn't have a `return` statement, it returns **`None`**, which is a special value like `True` and `False`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74b379e4",
   "metadata": {},
   "source": [
    "You have used the `print` function to display a string, but it does not use a `return` statement to return a value. If we assign the result to a variable, it still displays the string. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97d6346c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "print(print())   ### returns None"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "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
}
