{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "09472fdb",
   "metadata": {},
   "source": [
    "# Creating Tuples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "711dcf82",
   "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": "2d4232ac",
   "metadata": {},
   "source": [
    "\n",
    "Tuples in Python can be created in several ways, primarily: \n",
    "- Using tuple literals: through the use of commas and optional parentheses\n",
    "- by using the built-in tuple() constructor\n",
    "\n",
    "| How to create | Method | Example | Result |\n",
    "|---|---|---|---|\n",
    "| Use parentheses with comma-separated values | Parentheses | `(1, 2, 3)` | `(1, 2, 3)` |\n",
    "| Write comma-separated values without parentheses | Tuple packing | `1, 2, 3` | `(1, 2, 3)` |\n",
    "| Use empty parentheses | Empty tuple | `()` | `()` |\n",
    "| Add a trailing comma for one value | Single-item tuple | `(1,)` or `1,` | `(1,)` |\n",
    "| Use the tuple constructor on an iterable | Constructor | `tuple([1, 2, 3])` | `(1, 2, 3)` |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e00a9e2",
   "metadata": {},
   "source": [
    "## Tuple Literals\n",
    "\n",
    "To create a tuple, you can write a comma-separated list of values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a4fbf044",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tuple"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "status = 'NEW', 'PROCESSING', 'SHIPPED', 'DELIVERED', 'CLOSED'\n",
    "type(status)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd01df23",
   "metadata": {},
   "source": [
    "Parentheses are optional, but it is common to use them with tuples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "id": "facc9296",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('NEW', 'PROCESSING', 'SHIPPED', 'DELIVERED', 'CLOSED')\n",
      "<class 'tuple'>\n",
      "('NEW', 'PROCESSING', 'SHIPPED', 'DELIVERED', 'CLOSED')\n",
      "<class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "t1 = ('NEW', 'PROCESSING', 'SHIPPED', 'DELIVERED', 'CLOSED')\n",
    "print(t1)\n",
    "print(type(t1))\n",
    "\n",
    "t2 = 'NEW', 'PROCESSING', 'SHIPPED', 'DELIVERED', 'CLOSED'  # tuple packing\n",
    "print(t2)\n",
    "print(type(t2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a55573b5",
   "metadata": {},
   "source": [
    "## Single-Element Tuples"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "601ec2fb",
   "metadata": {},
   "source": [
    "To make a one-element tuple, include a trailing **comma**. Parentheses are optional."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "id": "c9e90297",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'tuple'>\n",
      "URGENT\n",
      "<class 'tuple'>\n",
      "URGENT\n"
     ]
    }
   ],
   "source": [
    "t1 = ('URGENT',)\n",
    "print(type(t1))\n",
    "print(t1[0])\n",
    "\n",
    "t2 = 'URGENT',               # tuple packing with one element\n",
    "print(type(t2))\n",
    "print(t2[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d5feda0",
   "metadata": {},
   "source": [
    "However, a single value inside parentheses is not a tuple without a comma."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b2405131",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "str"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t2 = ('URGENT')\n",
    "type(t2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73c45f96",
   "metadata": {},
   "source": [
    "## `tuple()` Constructor\n",
    "\n",
    "Another way to create a tuple is with the built-in function/type constructor `tuple`. With no argument, it creates an empty tuple."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09065ed6",
   "metadata": {},
   "source": [
    "If the argument is a sequence (list, tuple, or string), the `tuple` constructor returns a tuple containing the elements of that sequence — and `list` works the same way in reverse."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "id": "7aa729ac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Laptop', 'Mouse', 'Keyboard', 'Monitor')\n",
      "<class 'tuple'>\n",
      "['Laptop', 'Mouse', 'Keyboard', 'Monitor']\n",
      "<class 'list'>\n"
     ]
    }
   ],
   "source": [
    "t = tuple(['Laptop', 'Mouse', 'Keyboard', 'Monitor'])\n",
    "print(t)\n",
    "print(type(t))\n",
    "\n",
    "l = list(('Laptop', 'Mouse', 'Keyboard', 'Monitor'))\n",
    "print(l)\n",
    "print(type(l))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40955a1b",
   "metadata": {},
   "source": [
    "## Empty Tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "6e77fd12",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "()\n",
      "<class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "t = tuple()\n",
    "\n",
    "print(t)\n",
    "print(type(t))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08a67131",
   "metadata": {},
   "source": [
    "## Nested Tuples\n",
    "\n",
    "A **nested tuple** is a tuple that contains one or more tuples as elements. This is useful for representing multi-dimensional or grouped data, such as a matrix or a list of coordinate pairs. You access elements using chained indexing: the first index selects the inner tuple, and the second index selects an element within it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d9d799ab",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(4, 5, 6)\n",
      "6\n",
      "x=0, y=0\n",
      "x=1, y=2\n",
      "x=3, y=4\n"
     ]
    }
   ],
   "source": [
    "# A tuple containing other tuples\n",
    "matrix = ((1, 2, 3), (4, 5, 6), (7, 8, 9))\n",
    "\n",
    "# Access the second row\n",
    "print(matrix[1])        # (4, 5, 6)\n",
    "\n",
    "# Access the third element of the second row\n",
    "print(matrix[1][2])     # 6\n",
    "\n",
    "# Tuple of coordinate pairs\n",
    "points = ((0, 0), (1, 2), (3, 4))\n",
    "for x, y in points:\n",
    "    print(f'x={x}, y={y}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "3308eb8f",
   "metadata": {
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### Exercise: Creating Tuples\n",
    "#   1. Create a tuple named `colors` containing \"red\", \"green\", \"blue\" using parentheses.\n",
    "#   2. Create a single-element tuple named `one` containing the integer 42.\n",
    "#   3. Create a tuple named `letters` by passing the string \"hello\" to the tuple() constructor.\n",
    "#   4. Print each tuple and its type.\n",
    "### Your code starts here.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "19a73617",
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('red', 'green', 'blue') <class 'tuple'>\n",
      "(42,) <class 'tuple'>\n",
      "('h', 'e', 'l', 'l', 'o') <class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "### solution\n",
    "\n",
    "colors = (\"red\", \"green\", \"blue\")\n",
    "one = (42,)\n",
    "letters = tuple(\"hello\")\n",
    "\n",
    "print(colors, type(colors))\n",
    "print(one, type(one))\n",
    "print(letters, type(letters))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea5f8ebe",
   "metadata": {},
   "source": [
    "## Accessing Elements"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce1e4032",
   "metadata": {},
   "source": [
    "## Indexing and Slicing\n",
    "\n",
    "Tuples support indexing and slicing the same way lists do."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "id": "e6acd9a0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Mon', 'Tue', 'Wed', 'Thu', 'Fri')\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'Mon'"
      ]
     },
     "execution_count": 153,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri')\n",
    "print(t)\n",
    "t[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "714460b0",
   "metadata": {},
   "source": [
    "The slice operator selects a range of elements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "id": "66e9caad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('Tue', 'Wed')"
      ]
     },
     "execution_count": 154,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t[1:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "bbd11359",
   "metadata": {
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### Exercise: Indexing and Slicing\n",
    "#   Given the tuple: t = ('a', 'b', 'c', 'd', 'e')\n",
    "#   1. Print the first and last elements using indexing.\n",
    "#   2. Print the middle three elements using slicing.\n",
    "#   3. Print the tuple in reverse using a slice.\n",
    "### Your code starts here.\n",
    "\n",
    "t = ('a', 'b', 'c', 'd', 'e')\n",
    "\n",
    "\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "390f1a74",
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a e\n",
      "('b', 'c', 'd')\n",
      "('e', 'd', 'c', 'b', 'a')\n"
     ]
    }
   ],
   "source": [
    "### solution\n",
    "\n",
    "t = ('a', 'b', 'c', 'd', 'e')\n",
    "\n",
    "print(t[0], t[-1])    # first and last\n",
    "print(t[1:4])          # middle three\n",
    "print(t[::-1])         # reversed"
   ]
  }
 ],
 "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
}
