{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "66b62e33",
   "metadata": {},
   "source": [
    "# In-Class Exercises, Session 7"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43f15ac6",
   "metadata": {},
   "source": [
    "<U>Notes if you are using Jupyter Notebook</U>:  to call <B>exit()</B> from a notebook, please use <B>sys.exit()</B> (requires <B>import sys</B>).\n",
    "\n",
    "If a strange error occurs, it may be because Jupyter retains variables from all executed cells.  To reset the notebook, click 'Restart Kernel' (the circular arrow) -- this will not undo any changes made."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e25f5ba",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5095577b",
   "metadata": {},
   "source": [
    "CLASS VARIABLES / ATTRIBUTES"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "88070c17",
   "metadata": {},
   "source": [
    "<B>7.1:  Identify the object and attribute in each of the bottom 4 code lines.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "850a4e19",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import sys\n",
    "\n",
    "mylist = [1, 2, 3, 4]\n",
    "mystr = 'hello'\n",
    "fh = open('../pconfig.json')\n",
    "\n",
    "# identify the object and attribute in each of the below\n",
    "\n",
    "mylist.append(5)\n",
    "\n",
    "mystr.upper()\n",
    "\n",
    "json.load(fh)\n",
    "\n",
    "sys.argv"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43b1b4be",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b192ec72",
   "metadata": {},
   "source": [
    "<B>7.2:  Without calling any of the below attributes, print the type of each.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "85647b95",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import sys\n",
    "\n",
    "mylist = [1, 2, 3, 4]\n",
    "mystr = 'hello'\n",
    "fh = open('../pconfig.json')\n",
    "\n",
    "# print the type of each of the following:\n",
    "\n",
    "# mylist.append\n",
    "\n",
    "# mystr.upper\n",
    "\n",
    "# json.load\n",
    "\n",
    "# sys.argv"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9448ff6",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61c671c7",
   "metadata": {},
   "source": [
    "<B>7.3:  What exception does this code cause Python to raise and why?</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "42a101c3",
   "metadata": {},
   "outputs": [],
   "source": [
    "mystr = '1, 2, 3, 4, 5'\n",
    "\n",
    "mystr.append(5)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a91b056d",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83ae153e",
   "metadata": {},
   "source": [
    "<B>7.4:  Use <B>dir()</B> on one or more of these objects and examine the result.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a25c21bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys                           # module object\n",
    "import json                          # module object\n",
    "\n",
    "mylist = ['a', 'b', 'c']             # list object\n",
    "mydict = {'a': 1, 'b': 2, 'c': 3}    # dict object\n",
    "mystr = 'hello'                      # str object\n",
    "myint = 55                           # int object\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed5b1717",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1ff839b",
   "metadata": {},
   "source": [
    "<B>7.5:  Use <B>hasattr()</B> in an <B>if</B> statement to check for an attribute within an object; if True, use <B>getattr()</B> to retrieve and print the attribute.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "847e3def",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys                           # retrieve the 'version' attribute\n",
    "\n",
    "mylist = ['a', 'b', 'c']             # retrieve the 'append' attribute\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2c723435",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96c94430",
   "metadata": {},
   "source": [
    "<B>7.6:  <B>Do</B> is a class object; the class has a <B>cval</B> attribute assigned as a class variable.  Investigate the class' attributes with the following tools:</B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20131691",
   "metadata": {},
   "source": [
    "<OL>\n",
    "  <LI>regular attribute lookup (i.e., <B>.cval</B>)</LI>\n",
    "  <LI>dir()</LI>\n",
    "  <LI>Do.\\_\\_dict\\_\\_.keys()</LI>\n",
    "</OL>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e726b682",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do:\n",
    "\n",
    "    cval = 5\n",
    "\n",
    "    def dothis(self):\n",
    "        print('done!')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "299ea4ef",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55c2a1b7",
   "metadata": {},
   "source": [
    "<B>7.7:  <B>obj</B> is an instance of the <B>Do()</B> class; an attribute has been set in the instance, and the class also has its own attribute, set as a class variable.  Investigate the instance and class attributes with the following tools:</B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd317bc9",
   "metadata": {},
   "source": [
    "<OL>\n",
    "  <LI>regular attribute lookup (i.e., <B>[instance].oattr</B> and <B>[instance].cval)</LI>\n",
    "  <LI>class lookup (i.e., <B>[class].cval</B>)</LI>\n",
    "  <LI>dir()</LI>\n",
    "  <LI>obj.\\_\\_dict\\_\\_</LI>\n",
    "</OL>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "871744c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do():\n",
    "\n",
    "    cval = 10\n",
    "\n",
    "    def __init__(self):\n",
    "        self.oattr = 500     # setting an attribute in the instance\n",
    "\n",
    "    def dothis(self):\n",
    "        print('done!')\n",
    "\n",
    "\n",
    "obj = Do()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "612df567",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5e1c1c0",
   "metadata": {},
   "source": [
    "<B>7.8:  class <B>What</B> inherits from class <B>Do</B>.  Investigate the <B>What</B> instance attributes with the following tools:</B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "790bb0a7",
   "metadata": {},
   "source": [
    "<OL>\n",
    "  <LI>regular attribute lookup (i.e., <B>.cval</B>)</LI>\n",
    "  <LI>dir()</LI>\n",
    "  <LI>Do.\\_\\_dict\\_\\_.keys()</LI>\n",
    "</OL>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b505d297",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do:\n",
    "\n",
    "    dovar = 5\n",
    "\n",
    "    def dothis(self):\n",
    "        print('done!')\n",
    "\n",
    "\n",
    "class What(Do):\n",
    "\n",
    "    whatvar = 10\n",
    "\n",
    "    def __init__(self):\n",
    "        self.instval = 500\n",
    "\n",
    "z = What()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fd7bf76",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b206bdc7",
   "metadata": {},
   "source": [
    "<B>7.9:  Again with class <B>What</B> inheriting from class <B>Do</B>, compare the results from <B>dir()</B> and the results from the <B>.\\_\\_dict\\_\\_</B> attribute of the class.  (No need to create an instance, simply work with the <B>What</B> class object.)</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "38281a2b",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do:\n",
    "\n",
    "    d = 5\n",
    "\n",
    "    def dothis(self):\n",
    "        print('done!')\n",
    "\n",
    "\n",
    "class What(Do):\n",
    "    w = 10\n",
    "\n",
    "    def whatever(self):\n",
    "        print('chill!')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d03a2be",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "daf13811",
   "metadata": {},
   "source": [
    "<B>7.10:  Again with class <B>What</B> inheriting from class <B>Do</B>, view the <B>.\\_\\_bases\\_\\_</B> attribute of both the <B>What</B> class and the <B>Do</B> class.  (Again, no need to create an instance.)</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6d67ebf",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do:\n",
    "    dval = 5\n",
    "\n",
    "class What(Do):\n",
    "    wval = 10\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "647f9213",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b6a7dba",
   "metadata": {},
   "source": [
    "<B>7.11:  Compare <B>dir()</B> of <B>Do</B> to <B>dir()</B> of <B>object</B>.  Is one a subset of the other?  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a267a825",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do:\n",
    "    pass\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f6b8e3f",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad861742",
   "metadata": {},
   "source": [
    "<B>7.12:  Cause class <B>Do</B> to inherit from the builtin class <B>list</B>.  See if the list <B>.append</B> attribute is available in the instance.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35581872",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do:\n",
    "\n",
    "    d = 5\n",
    "\n",
    "    def dothis(self):\n",
    "        print('done!')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a603710d",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c7ad07ea",
   "metadata": {},
   "source": [
    "<B>7.13:  Look at the <B>.\\_\\_bases\\_\\_</B> attribute of the exception class <B>ValueError</B>; see if you can follow the chain of bases all the way up to <B>object</B>.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "23a23433",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "69d3bf49",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "664b61c6",
   "metadata": {},
   "source": [
    "<B>7.14:  Examine the return value from the following function calls:  <B>vars().keys()</B>, <B>locals().keys()</B> (called from inside the function) and <B>dir(builtins)</B>.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "12a83ada",
   "metadata": {},
   "outputs": [],
   "source": [
    "import builtins\n",
    "\n",
    "a = 5\n",
    "b = [1, 2, 3]\n",
    "\n",
    "print('== vars().keys() ==')\n",
    "print(vars().keys())\n",
    "print()\n",
    "\n",
    "def do():\n",
    "    lvar = 500\n",
    "    print('== locals().keys() ==')\n",
    "    print(locals().keys())\n",
    "    print()\n",
    "\n",
    "do()\n",
    "\n",
    "print('== dir(builtins) ==')\n",
    "print(dir(builtins))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f77e29f",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f09bae64",
   "metadata": {},
   "source": [
    "<B>7.15:  Run the code to view the '.\\_\\_doc\\_\\_' attribute for the class and for the <B>dothis()</B> method.  Now add \"docstrings\" (floating triple-quoted strings) just inside both the <B>class</B> and <B>def</B> statements.  Run the program again to see how the <B>.\\_\\_doc\\_\\_</B> attributes have changed.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "04715558",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do:\n",
    "\n",
    "    d = 5\n",
    "\n",
    "    def dothis(self):\n",
    "        print('done!')\n",
    "\n",
    "\n",
    "print(Do.__doc__)\n",
    "print(Do.dothis.__doc__)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bac7aa1c",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1198a1d",
   "metadata": {},
   "source": [
    "<B>7.16:  Compare <B>dir(Do)</B> with <B>inspect.getmembers(Do)</B>.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5680d25f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import inspect\n",
    "\n",
    "class Do:\n",
    "\n",
    "    d = 5\n",
    "\n",
    "    def dothis(self):\n",
    "        print('done!')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2cca4399",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "941b09d5",
   "metadata": {},
   "source": [
    "<B>7.17:  Check to see whether <B>Do.d</B> and <B>Do.dothis</B> are callable.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e1f13c9",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Do:\n",
    "\n",
    "    d = 5\n",
    "\n",
    "    def dothis(self):\n",
    "        print('done!')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebd443b0",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7d5389d",
   "metadata": {},
   "source": [
    "\"MAGIC\" METHODS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a4635af",
   "metadata": {},
   "source": [
    "<B>7.18:  <u>Allow a class to \"print\" itself</u>.  Define a <B>\\_\\_str\\_\\_(self)</B> method that returns a string.  Now print the object.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6387e6ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Value:\n",
    "    def __init__(self, val):\n",
    "        self.aaa = val\n",
    "\n",
    "    def getval(self):\n",
    "        return self.aaa\n",
    "\n",
    "mynum = Value(10)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f32f8d5",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51095533",
   "metadata": {},
   "source": [
    "<B>7.19:  <u>Allow an object to respond to subscripting</u>.  Define a <B>\\_\\_setitem\\_\\_(self)</B> method that takes two arguments (besides <B>self</B>) and prints the two arguments.  Now attempt to subscript the object.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fe543a94",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Value:\n",
    "    def __init__(self, val):\n",
    "        self.aaa = val\n",
    "\n",
    "mynum = Value(10)\n",
    "\n",
    "mynum['a'] = 55     # prints \"called __setitem__(a, 55)\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e44aa074",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a472378",
   "metadata": {},
   "source": [
    "<B>7.20:  <u>Replace <B>getval()</B> with <B>\\_\\_getitem\\_\\_()</B></u>.  The method should take one argument (besides <B>self</B>) and return the <B>.aaa</B> attribute.  Now attempt to subscript the object.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3781f6d6",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Value:\n",
    "    def __init__(self, val):\n",
    "        self.aaa = val\n",
    "\n",
    "    def getval(self):\n",
    "        return self.aaa\n",
    "\n",
    "mynum = Value('10')\n",
    "\n",
    "val = mynum.getval()      # 10\n",
    "\n",
    "# uncomment after adding __getitem__\n",
    "# val = mynum['whaeva']      # 10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "180ff694",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0f0cf63",
   "metadata": {},
   "source": [
    "INHERITING FROM BUILTINS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a25a274d",
   "metadata": {},
   "source": [
    "<B>7.21:  <u>Make <B>IntList</B> inherit from <B>list</B> and then treat it like a list</u>.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "52741d80",
   "metadata": {},
   "outputs": [],
   "source": [
    "class IntList:\n",
    "    pass           # means an empty block\n",
    "\n",
    "x = IntList()\n",
    "\n",
    "# uncomment once we are inheriting from list.\n",
    "#x.append(5)\n",
    "#x.append(3)\n",
    "#print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c79c072",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de99a6ff",
   "metadata": {},
   "source": [
    "<B>7.22:  <u>Add an <B>append()</B> method to <B>IntList</B> to specialize the method.  Inside the method, only print a message; don't try to perform the append.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c3005d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "class IntList(list):\n",
    "    pass\n",
    "\n",
    "x = IntList()\n",
    "\n",
    "x.append(5)       # now appending 5!\n",
    "x.append(3)       # now appending 3!\n",
    "\n",
    "print(x)          # [5, 3]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "65c54f51",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35a3f232",
   "metadata": {},
   "source": [
    "<B>7.23:  <U>Call <B>list.append()</B> from within the inheriting class</U>.  From inside the <B>IntList</B> <B>.append()</B> method, call the <B>append()</B> method on the object by calling it on the parent class.  (Don't call it on <B>self</B> or you will set up an endless loop.)</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b958032b",
   "metadata": {},
   "outputs": [],
   "source": [
    "class IntList(list):\n",
    "    def append(self, item):\n",
    "        print(f'now appending {5}!')\n",
    "\n",
    "x = IntList()\n",
    "\n",
    "x.append(5)       # now appending 5!\n",
    "x.append(3)       # now appending 3!\n",
    "\n",
    "print(x)          # []"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7df420f1",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48924071",
   "metadata": {},
   "source": [
    "TRAPPING AND RAISING EXCEPTIONS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da00d673",
   "metadata": {},
   "source": [
    "<B>7.24:  (Review) <u>Trap the exception</u>.  First, run the script to see what exception is raised.  Then, use a <B>try/except</B> statement to trap the error.  In the <B>except</B> block, set <B>xi</B> to <B>1</b>.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13862334",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = input('please enter an integer: ')\n",
    "\n",
    "xi = int(x)\n",
    "\n",
    "print(f'{xi} * 2 = {xi * 2}')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e01812c5",
   "metadata": {},
   "source": [
    "<B>PLEASE DO NOT USE except: BY ITSELF!</B>  This works, but we must always specify the exception we are expecting.\n",
    "\n",
    "To test, run the program once with \"correct\" input (i.e., numbers only) and then run it again with \"bad\" input (i.e., letters) to trigger the exception."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e2a868b",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20e6b27d",
   "metadata": {},
   "source": [
    "<B>7.25:  (Review) <u>Trap the exception</u>.  Again, determine the exception type that will occur if the user types in a key that doesn't exist in the dict.  Then use the <B>try/except</B> to trap the exception (PLEASE DO NOT USE except: BY ITSELF).  If the exception is raised, assign None to <B>val</B>.    </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a03fa236",
   "metadata": {},
   "outputs": [],
   "source": [
    "keydict = {'a': 1, 'b': 2, 'c': 3}\n",
    "\n",
    "x = input('please enter a key for this dict: ')\n",
    "\n",
    "val = keydict[x]\n",
    "\n",
    "print(f'the value for {x} is {val}.')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94968ff4",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04f6a123",
   "metadata": {},
   "source": [
    "<B>7.26:  <u>Trap the exception, then <B>raise</B> a new one</u>.  Inside the <B>except</B> block, raise another <B>KeyError</B>, or any existing exception that you choose.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "52e143f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "keydict = {'a': 1, 'b': 2, 'c': 3}\n",
    "\n",
    "x = input('please enter a key for this dict: ')\n",
    "\n",
    "try:\n",
    "    val = keydict[x]\n",
    "except KeyError:\n",
    "    print('uh-oh')   # replace this code\n",
    "\n",
    "print(f'the value for {x} is {val}.')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "533c4268",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e35c37a",
   "metadata": {},
   "source": [
    "<B>7.27:  <u>Without any reason, raise a <B>ValueError</B> exception</u>.  Choose your favorite exception!  You don't have one?  Then <B>raise ZeroDivisionError</b>.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f3b155ac",
   "metadata": {},
   "outputs": [],
   "source": [
    "# your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d9aeb49",
   "metadata": {},
   "source": [
    " "
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 5
}
