{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Tuples\n",
    "* Tuples are like lists but \n",
    "    * are immutable,\n",
    "    * are created with ```( )``` instead of ```[ ]```,\n",
    "    * elements are still accessed with ```[ ]```,\n",
    "    * changing an element, like ```t[1]=55``` gives an error."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "t = (1.1, 2.2, 3.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "* For a tuple with just a single element:\n",
    "    * Use this: ```t = (1.1,)```\n",
    "    * Not this: ```t = (1.1)```\n",
    "* The trailing comma is needed, otherwise ```t``` is just 1.1, not a tuple holding 1.1 as the first element.\n",
    "* For multiple elements, a trailing comma is valid but not required: ```t = (1, 2, 3,)```\n",
    "    * Lists can also have trailing commas: ```L = [1, 2, 3,]```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Tuple unpacking (mutiple assignment)\n",
    "- (this works for lists too)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "t = (1, 2.5 , -3)         # make a tuple\n",
    "\n",
    "x, y, z   = t             # unpack the tuple \"into\" x, y, and z\n",
    "x, y, z   = 1, 2.5, -3    # same thing\n",
    "(x, y, z) = t             # same thing\n",
    "(x, y, z) = (1, 2.5, -3)  # same thing\n",
    "\n",
    "print(f\"x = {x}\")\n",
    "print(f\"y = {y}\")\n",
    "print(f\"z = {z}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "**Note, we used this in returning more than one thing from a function**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "def add_and_multiply(x, y):\n",
    "    return x+y, x*y            # returning a tuple\n",
    "\n",
    "s, p = add_and_multiply(3,4)   # unpack the tuple into s, p\n",
    "t = add_and_multiply(3,4)      # t is a tuple\n",
    "\n",
    "\n",
    "print(s, p)\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `*args`\n",
    "\n",
    "### Packing\n",
    "You can pass an arbitrary number of arguments to a function using the `*args` parameter.\n",
    "- The passed arguments get *packed* into a a tuple called `args`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n",
      "720\n"
     ]
    }
   ],
   "source": [
    "def multiply(*args):\n",
    "    m = 1\n",
    "    for a in args:\n",
    "        m *= a\n",
    "    return m\n",
    "\n",
    "print(multiply(1,2,3))\n",
    "print(multiply(1,2,3,4,5,6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Unpacking\n",
    "\n",
    "Similarly, you can unpack a tuple into several function arguments by by *unpacking* a tuple."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name: David\n",
      "age:  48\n",
      "hair: brown\n"
     ]
    }
   ],
   "source": [
    "def print_profile(name, age, hair):\n",
    "    print(f\"name: {name}\")\n",
    "    print(f\"age:  {age}\")\n",
    "    print(f\"hair: {hair}\")\n",
    "\n",
    "person = ('David', 48, 'brown')\n",
    "\n",
    "print_profile(*person)              # the tuple person is unpacked into parameters name, age, hair"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Dictionaries\n",
    "\n",
    "* Dictionaries are like lists but \n",
    "    * are created with ```{ }``` instead of ```[ ]```,\n",
    "    * use ```key:value``` pairs\n",
    "    * elements are accessed with ```[key]``` instead of by ```[i]``` for some integer index ```i```,\n",
    "    * Below, we use strings as the keys, but they can be anything.\n",
    "* [Click here for more information](https://www.w3schools.com/python/python_dictionaries.asp)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "mw of o2 is  31.998\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "mw = {\n",
    "      \"CO2\":12.011+15.999*2,\n",
    "      \"H2O\":1.0079*2+15.999,\n",
    "      \"O2\" :15.999*2,\n",
    "      \"N2\" :14.0067*2,\n",
    "     }\n",
    "\n",
    "print(\"mw of o2 is \", mw[\"O2\"])\n",
    "\n",
    "funcs = {np.sin:\"what up sin?\", np.log10:np.tanh}  # evil!\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Functions:\n",
    "* ```mw.keys()```\n",
    "* ```mw.values()```\n",
    "* ```mw.items()``` \n",
    "* ```len(mw)```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CO2 44.009\n",
      "H2O 18.0148\n",
      "O2 31.998\n",
      "N2 28.0134\n"
     ]
    }
   ],
   "source": [
    "for k in mw.keys():      \n",
    "    print(k, mw[k])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "44.009\n",
      "18.0148\n",
      "31.998\n",
      "28.0134\n"
     ]
    }
   ],
   "source": [
    "for v in mw.values():\n",
    "    print(v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CO2 44.009\n",
      "H2O 18.0148\n",
      "O2 31.998\n",
      "N2 28.0134\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "dict_items([('CO2', 44.009), ('H2O', 18.0148), ('O2', 31.998), ('N2', 28.0134)])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for k, v in mw.items():\n",
    "    print(k,v)\n",
    "    \n",
    "mw.items()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Check if present"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "if \"H2\" in mw:\n",
    "    print(\"H2 is there\")\n",
    "else:\n",
    "    print(\"H2 is not there\")\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Add items\n",
    "* ```mw[\"new_key\"] = newValue```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'CO2': 44.009, 'H2O': 18.0148, 'O2': 31.998, 'N2': 28.0134}\n",
      "{'CO2': 44.009, 'H2O': 18.0148, 'O2': 31.998, 'N2': 28.0134, 'H2': 2.0158}\n"
     ]
    }
   ],
   "source": [
    "print(mw)\n",
    "\n",
    "mw[\"H2\"] = 1.0079*2\n",
    "\n",
    "print(mw)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Delete items\n",
    "\n",
    "* ```del mw[\"some_key\"]```\n",
    "* ```mw.pop(\"some_key\")```\n",
    "* ```mw.popitem()``` deletes the last inserted item"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'CO2': 44.009, 'H2O': 18.0148, 'O2': 31.998, 'N2': 28.0134, 'H2': 2.0158}\n",
      "{'CO2': 44.009, 'H2O': 18.0148, 'O2': 31.998, 'N2': 28.0134}\n"
     ]
    }
   ],
   "source": [
    "print(mw)\n",
    "mw.popitem()\n",
    "print(mw)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "base",
   "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.14.7"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
