{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "brNDGX-kvzds"
   },
   "source": [
    "# Template for Notes for CIS 521 Midterm 1\n",
    "\n",
    "The midterm exam for CIS 521 will be **open notes**. No other matierals are allowed for the exam - you may not use the textbook, the internet, a Python envionement, or communicate with anyone during the exam. \n",
    "\n",
    "This python notebook is where you should save all of your notes.  It provides a structured template that allows you to add summaries for each of the textbook sections that are part of the required reading, plus room for lecture notes and definitions.\n",
    "\n",
    "Your summaries must be written in your own words.  Do not copy and paste from the textbook.  Do not share your notes with classmates, or copy any of your classmates' notes.  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "aPtM8g7R0Pds"
   },
   "source": [
    "# Instructions\n",
    "\n",
    "1. Make a copy of this Google Colab file. From the colab menu, pick **File > Save a copy in Drive**.  That will save a copy of this notebook in your Google drive.\n",
    "2. Go through each section of the notebook, and fill in all the summaries for each chapter and its corresponding sections.  Be sure to save your work frequently!\n",
    "3. Read the notes below about how you can format your summaries.\n",
    "4. In addition to these notes, you are allowed 1 page (both sides) for figures or handwritten notes.\n",
    "5. Submit your version of this notebook to Gradescope before you start the exam.\n",
    "6. If you are taking the exam in person, then you must print a copy of your notes for yourself.   Here's how to print: \n",
    "* Run the last cell of this notebook\n",
    "* Click the \"Mirror cell in tab\" button (this is located in the upper right corner of the cell, immediately to the right of the trash can).  This will open the cell.  \n",
    "* In Chrome, you can then print your notes using the **File > Print** option from the browser's menu.  \n",
    "* In the print options, change the layout from Landscape to Portrait. \n",
    "* Clicking the Save, will save a PDF that you can then print.\n",
    "\n",
    "## Formatting Notes\n",
    "\n",
    "1. The max length for each section's summary is 500 words / 3000 characters.\n",
    "2. You can also write a 2000 word summary of the lectures for each module.\n",
    "3. You may also write definitions of concepts for each module.  The definitions should be written in your own words (not copy and pasted), and they should be no more than 20 words long for each concept. \n",
    "2. You can use Markdown formatting for your summaries. \n",
    "3. You can use Latex formatting for equations. Put two dollar signs before and after your equation like this: \n",
    "$$ \\epsilon = \\frac{1}{mc^2} $$\n",
    "4. When you write python code or psuedocode algorithms, you should surround it with triple backticks like this:\n",
    "```\n",
    "def function():\n",
    "      print('hello world')\n",
    "```\n",
    "5. Write \\ whenever you want to keep writing on the next line without a newline being inserted."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "cw5IpDLCZa4W"
   },
   "source": [
    "## Example summary\n",
    "\n",
    "This is a sample summary of [Section 2.1.1](https://web.stanford.edu/~jurafsky/slp3/2.pdf ) of Jurfasky and Martin's Speech and Language Processing's book\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "lzaavW96tcxM",
    "outputId": "344222ad-a216-45e3-9726-b566dead59fe"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The example summary is 116 words long, so you could write an additional 384 words.\n"
     ]
    }
   ],
   "source": [
    "chapter_2_1_example = \"\"\"\n",
    "Regular expressions are an algebraic notation for characterizing \\\n",
    "a set of strings that are useful for searching for a pattern or through a corpus.\\\n",
    "Only the first matching result will be shown. The search string is case sensitive, \\\n",
    "but it can consist of a single character or a sequence of characters. \\\n",
    "While square braces specify a disjunction of characters, the dash can more easily look \\\n",
    "for characters over a range. The caret specifies the non-existence of a character. \\\n",
    "Additionally, the (?) is used to for flexibility on a single character, meaning \\\n",
    "\"the preceding character or nothing\". More importantly, the Kleene star means zero or \\\n",
    "more occurrences of the immediately previous character or regular expression in square braces.\\\n",
    "...\n",
    "\"\"\"\n",
    "\n",
    "length = len(chapter_2_1_example.split(\" \"))\n",
    "print(\"The example summary is {len} words long, so you could write an additional \\\n",
    "{remaining} words.\".format(len=length, remaining=(500-length)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "s3Uk9gQTevcj"
   },
   "source": [
    "## Example summary length\n",
    "\n",
    "The maximum summary length for each section is 500 words / 3000 characters.  Hopefully you'll find that to be quite generous. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "8DvZ57A-djo1",
    "outputId": "ef81cd11-e574-43c8-fb57-4c2e2e3d803c"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The length in words is 500\n",
      "The length in characters is 3030\n"
     ]
    }
   ],
   "source": [
    "# This is an example of a 500 word placeholder\n",
    "placeholder = \"\"\"ultrices vitae auctor eu augue ut lectus arcu bibendum at varius \\\n",
    " vel pharetra vel turpis nunc eget lorem dolor sed viverra ipsum nunc aliquet \\\n",
    " bibendum enim facilisis gravida neque convallis a cras semper auctor neque vitae \\\n",
    " tempus quam pellentesque nec nam aliquam sem et tortor consequat id porta nibh \\\n",
    " venenatis cras sed felis eget velit aliquet sagittis id consectetur purus ut \\\n",
    " faucibus pulvinar elementum integer enim neque volutpat ac tincidunt vitae semper \\ \n",
    " quis lectus nulla at volutpat diam ut venenatis tellus in metus vulputate eu \\\n",
    " scelerisque felis imperdiet proin fermentum leo vel orci porta non pulvinar neque \\ \n",
    " laoreet suspendisse interdum consectetur libero id faucibus nisl tincidunt eget \\\n",
    " nullam non nisi est sit amet facilisis magna etiam tempor orci eu lobortis \\\n",
    " elementum nibh tellus molestie nunc non blandit massa enim nec dui nunc mattis \\\n",
    " enim ut tellus elementum sagittis vitae et leo duis ut diam quam nulla porttitor \\\n",
    " massa id neque aliquam vestibulum morbi blandit cursus risus at ultrices mi tempus \\\n",
    " imperdiet nulla malesuada pellentesque elit eget gravida cum sociis natoque \\\n",
    " penatibus et magnis dis parturient montes nascetur ridiculus mus mauris vitae \\\n",
    " ultricies leo integer malesuada nunc vel risus commodo viverra maecenas accumsan \\\n",
    " lacus vel facilisis volutpat est velit egestas dui id ornare arcu odio ut sem nulla \\\n",
    " pharetra diam sit amet nisl suscipit adipiscing bibendum est ultricies integer \\\n",
    " quis auctor elit sed vulputate mi sit amet mauris commodo quis imperdiet massa \\\n",
    " tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada proin libero nunc \\\n",
    " consequat interdum varius sit amet mattis vulputate enim nulla aliquet porttitor \\\n",
    " lacus luctus accumsan tortor posuere ac ut consequat semper viverra nam libero \\\n",
    " justo laoreet sit amet cursus sit amet dictum sit amet justo donec enim diam \\\n",
    " vulputate ut pharetra sit amet aliquam id diam maecenas ultricies mi eget mauris \\\n",
    " pharetra et ultrices neque ornare aenean euismod elementum nisi quis eleifend quam \\\n",
    " adipiscing vitae proin sagittis nisl rhoncus mattis rhoncus urna neque viverra justo \\\n",
    " nec ultrices dui sapien eget mi proin sed libero enim sed faucibus turpis in \\\n",
    " eu mi bibendum neque egestas congue quisque egestas diam in arcu cursus euismod \\\n",
    " quis viverra nibh cras pulvinar mattis nunc sed blandit libero volutpat sed cras \\\n",
    " ornare arcu dui vivamus arcu felis bibendum ut tristique et egestas quis ipsum \\\n",
    " suspendisse ultrices gravida dictum fusce ut placerat orci nulla pellentesque \\\n",
    " dignissim enim sit amet venenatis urna cursus eget nunc scelerisque viverra mauris \\\n",
    " in aliquam sem fringilla ut morbi tincidunt augue interdum velit euismod in \\\n",
    " pellentesque massa placerat duis ultricies lacus sed turpis tincidunt id aliquet \\\n",
    " risus feugiat in ante metus dictum at tempor commodo ullamcorper a lacus vestibulum \\\n",
    " sed arcu non odio euismod lacinia at quis risus sed vulputate odio ut enim blandit \\\n",
    " volutpat maecenas volutpat blandit aliquam etiam erat velit scelerisque in \\\n",
    " dictum non consectetur a erat nam at lectus urna\"\"\"\n",
    "\n",
    "print(\"The length in words is\", len(placeholder.split(' ')))\n",
    "print(\"The length in characters is\", len(placeholder))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "5yG3-YncJfTB"
   },
   "source": [
    "# Permissions to use your summaries\n",
    "\n",
    "We'd like to use your summaries to help develop better educational resources like [remember.school](https://remember.school) or a question-answering system about the textbook.  \n",
    "\n",
    "1. Please enter your name.  \n",
    "\n",
    "2. If you grant permission for us to use your summaries under a [Creative Commons License](https://creativecommons.org/licenses/by/4.0/), please set ```permission = True```.  If you do not grant permission, please set it to false. Your answer won't affect your grade.\n",
    "\n",
    "3. If you grant us permission, and you'd like to remain anonymous, set ```anonymous = True```.  We'll remove your name before sharing your summaries with anyone. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "2RECnJArJew4"
   },
   "outputs": [],
   "source": [
    "name = \"\"\n",
    "permission = True\n",
    "anonymous = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GZZXyrV-xuAp"
   },
   "source": [
    "# Module 1 - Intro to AI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "Y2NfE1CKxzS-"
   },
   "outputs": [],
   "source": [
    "# Russell and Norvig, AIMA 4th Edition, Chapter 1 “Introduction”, Section 1.1 “What is AI”\n",
    "\n",
    "chapter1_1 = \"\"\" Artificial Intelligence can be defined in 4 quadrants - \n",
    "Thought vs Behavior (is the internal comprehension more important or the behavior?)\n",
    "Human vs Rational (are humans occasionally irrational?)\n",
    "The Turing test - if we cannot differentiate between a person and a computer, is the computer essentially a person?\n",
    "AI Technologies - Natural Language Processing, Knowledge Representation, Automated Reasoning, Machine Learning\n",
    "Total Turing Test - including real world interaction, not just written text - Computer Vision, Speech Recognition, Robotics\n",
    "Cognitive Modelling - how do our brains work? \n",
    "Rational Thinking - what is the 'right' way to think?\n",
    "Standard Model - AI research has focused on making agents that do the right thing. But we have to supply the 'right thing'\n",
    "Beneficial machines - What if we cannot supply the 'right thing' in a form that covers all bases, i.e. is fully specified? \n",
    "There is a risk of negative consequences to logical actions towards an incomplete objective. We want agents that are provably beneficial.\n",
    "\"\"\" \n",
    "\n",
    "\n",
    "# Russell and Norvig, AIMA 4th Edition, Chapter 27 “Philosophical Foundations”, Sections 27.1 “The Limits of AI” and 27.2 “Can Machines Really Think?”\n",
    "chapter27_1 = \"\"\" Weak AI vs Strong AI - Weak AI act as if intelligent, Strong AI are actually intelligent\n",
    "What are some of the things people have postulated that AI can't do?\n",
    "Informality of behavior - 'Human intelligence and behavior is too complex to be formalized into a set of rules, and thus cannot be codified'\n",
    "Disability - \"AI can never be emotional, be moral, enjoy things, fall in love, do something truly new\"\n",
    "Mathematical - Godel sentence - \"My current sentence is a lie\"\n",
    "Measuring AI - Turing Test, Games - Chess, Go, StarCraft II, Defense of the Ancients 2\n",
    "\"\"\"\n",
    "chapter27_2 = \"\"\" Can machines really think?\n",
    "Chinese room example - if you follow some rules to respond in chinese to a chinese input, does that mean you understand chinese? \n",
    "Or - does a chatbot really understand english? In fact, what does it mean to \"understand\"?\n",
    "Consciousness is mysterious. \n",
    "\"\"\"\n",
    "\n",
    "# Russell and Norvig, AIMA 4th Edition, Chapter 2 “Intelligent Agents” (whole chapter)\n",
    "chapter2_1 = \"\"\" Agents perceive 'percepts' (e.g. light, sound) through 'sensors' (e.g. eyes, ears) and do 'actions' (e.g. walk, pick) through 'actuators' (e.g. legs, hands). \n",
    "Agent's 'percept sequence' is everything they have ever perceived. Agents act based on built-in knowledge and their percept sequence, but cannot act on anything outside that.\n",
    "Behavior is described by 'agent function' that maps a specific percept sequence to an action. Agent function is implemented by 'agent program'. Function is abstract, program is implementation. \n",
    "\"\"\"\n",
    "chapter2_2 = \"\"\" Rational agents do the right thing. \n",
    "The right thing is a performance measure \n",
    "Good to design performance measure according to what needs to be achieved in the environment.\n",
    "What is rational depends on: The perofmrance measure, the agent's prior knowledge, actions the agent can perform, agent's percept sequence\n",
    "Rational agents may make mistakes - agents are not omniscient. Agents simply maximize expected performance.\n",
    "Agents should learn from experience, unless environments are already fully understood in prior knowledge. \n",
    " \"\"\"\n",
    "chapter2_3 = \"\"\" Task environments consist of PEAS - Performance Measure, Environment, Actuators, Sensors \n",
    "Example: Taxi Driver\n",
    "Performance Measure - drive safely and legally, as fast as possible\n",
    "Environment - roads, other drivers, law enforcement, pedestrians\n",
    "Actuators - Steering wheel, brake, signal, horn, etc\n",
    "Sensors - Visual, Auditory, Speedometer, GPS, etc\n",
    "When designing an agent, specify the task environment as fully as possible.\n",
    "Task enviromnets may be: \n",
    "Fully observable vs Partially observable\n",
    "Single-Agent vs Multi-Agent\n",
    "Deterministic vs Non-deterministic\n",
    "Episodic vs Sequential\n",
    "Static vs Dynamic\n",
    "Discrete vs Continuous\n",
    "Known vs Unknown\n",
    "\"\"\"\n",
    "chapter2_4 = \"\"\" An agent is architecture (hardware - device with sensors, actuators) + program (software) \n",
    "4 basic kinds of agent programs:\n",
    "Simple reflex agents - act based on current precept\n",
    "Model-based reflex agents - keeps track of some amount of part precepts and draws inferences from that\n",
    "Goal-based agents - acts based on goal information that describes situations that are desirable\n",
    "Utility-based agents - acts on more general performance measures of 'utility'\n",
    "\"\"\"\n",
    "\n",
    "# Lecture notes \n",
    "module1_lecture_notes = \"\"\" Basically the same as the textbook \"\"\"\n",
    "\n",
    "\n",
    "# Definitions of concepts from Module 1.\n",
    "# You can define any bolded term in the textbook, \n",
    "# but you most use your own words for the definitions.\n",
    "# Each definition should be at most 20 words long.\n",
    "module1_definitions = {\n",
    "\"AI\": \"the science of making machines that think like people, think rationally, act like people, act rationally\",\n",
    "\"agent\" : \"anything that can perceive through sensors and act through actuators in an environment\"\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "elCCgY64spuq"
   },
   "source": [
    "## Preview of your notes for Module 1\n",
    "\n",
    "Here's a preview of your how your notes will be displayed.  At the end of this Python notebook, we'll aggregate your notes for all modules together into a single display.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "cellView": "form",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 1000
    },
    "id": "gYYeNcdM_maE",
    "outputId": "2f238a9d-2345-46f1-881a-60e85b4ab978"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# Module 1: Rational Agents and Task Environments\n",
       "## AIMA Chapter 1.1 What is AI?\n",
       " Artificial Intelligence can be defined in 4 quadrants - \n",
       "Thought vs Behavior (is the internal comprehension more important or the behavior?)\n",
       "Human vs Rational (are humans occasionally irrational?)\n",
       "The Turing test - if we cannot differentiate between a person and a computer, is the computer essentially a person?\n",
       "AI Technologies - Natural Language Processing, Knowledge Representation, Automated Reasoning, Machine Learning\n",
       "Total Turing Test - including real world interaction, not just written text - Computer Vision, Speech Recognition, Robotics\n",
       "Cognitive Modelling - how do our brains work? \n",
       "Rational Thinking - what is the 'right' way to think?\n",
       "Standard Model - AI research has focused on making agents that do the right thing. But we have to supply the 'right thing'\n",
       "Beneficial machines - What if we cannot supply the 'right thing' in a form that covers all bases, i.e. is fully specified? \n",
       "There is a risk of negative consequences to logical actions towards an incomplete objective. We want agents that are provably beneficial.\n",
       "\n",
       "\n",
       "## AIMA Chapter 27.1 The Limits of AI\n",
       " Weak AI vs Strong AI - Weak AI act as if intelligent, Strong AI are actually intelligent\n",
       "What are some of the things people have postulated that AI can't do?\n",
       "Informality of behavior - 'Human intelligence and behavior is too complex to be formalized into a set of rules, and thus cannot be codified'\n",
       "Disability - \"AI can never be emotional, be moral, enjoy things, fall in love, do something truly new\"\n",
       "Mathematical - Godel sentence - \"My current sentence is a lie\"\n",
       "Measuring AI - Turing Test, Games - Chess, Go, StarCraft II, Defense of the Ancients 2\n",
       "\n",
       "\n",
       "## AIMA Chapter 27.1 Can Machines Really Think?\n",
       " Can machines really think?\n",
       "Chinese room example - if you follow some rules to respond in chinese to a chinese input, does that mean you understand chinese? \n",
       "Or - does a chatbot really understand english? In fact, what does it mean to \"understand\"?\n",
       "Consciousness is mysterious. \n",
       "\n",
       "\n",
       "## AIMA 2.1 Agents and Environments\n",
       " Agents perceive 'percepts' (e.g. light, sound) through 'sensors' (e.g. eyes, ears) and do 'actions' (e.g. walk, pick) through 'actuators' (e.g. legs, hands). \n",
       "Agent's 'percept sequence' is everything they have ever perceived. Agents act based on built-in knowledge and their percept sequence, but cannot act on anything outside that.\n",
       "Behavior is described by 'agent function' that maps a specific percept sequence to an action. Agent function is implemented by 'agent program'. Function is abstract, program is implementation. \n",
       "\n",
       "\n",
       "## AIMA 2.2 Good Behavior: The Concept of Rationality\n",
       " Rational agents do the right thing. \n",
       "The right thing is a performance measure \n",
       "Good to design performance measure according to what needs to be achieved in the environment.\n",
       "What is rational depends on: The perofmrance measure, the agent's prior knowledge, actions the agent can perform, agent's percept sequence\n",
       "Rational agents may make mistakes - agents are not omniscient. Agents simply maximize expected performance.\n",
       "Agents should learn from experience, unless environments are already fully understood in prior knowledge. \n",
       " \n",
       "\n",
       "## AIMA 2.3 The Nature of Environments\n",
       " Task environments consist of PEAS - Performance Measure, Environment, Actuators, Sensors \n",
       "Example: Taxi Driver\n",
       "Performance Measure - drive safely and legally, as fast as possible\n",
       "Environment - roads, other drivers, law enforcement, pedestrians\n",
       "Actuators - Steering wheel, brake, signal, horn, etc\n",
       "Sensors - Visual, Auditory, Speedometer, GPS, etc\n",
       "When designing an agent, specify the task environment as fully as possible.\n",
       "Task enviromnets may be: \n",
       "Fully observable vs Partially observable\n",
       "Single-Agent vs Multi-Agent\n",
       "Deterministic vs Non-deterministic\n",
       "Episodic vs Sequential\n",
       "Static vs Dynamic\n",
       "Discrete vs Continuous\n",
       "Known vs Unknown\n",
       "\n",
       "\n",
       "## AIMA 2.4 The Structure of Agents\n",
       " An agent is architecture (hardware - device with sensors, actuators) + program (software) \n",
       "4 basic kinds of agent programs:\n",
       "Simple reflex agents - act based on current precept\n",
       "Model-based reflex agents - keeps track of some amount of part precepts and draws inferences from that\n",
       "Goal-based agents - acts based on goal information that describes situations that are desirable\n",
       "Utility-based agents - acts on more general performance measures of 'utility'\n",
       "\n",
       "\n",
       "## Module 1 Lecture Notes\n",
       " Basically the same as the textbook \n",
       "\n",
       "## Module 1 Definitions\n",
       "* **Ai** - the science of making machines that think like people, think rationally, act like people, act rationally\n",
       "* **Agent** - anything that can perceive through sensors and act through actuators in an environment\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#@title Preview of your summary\n",
    "#@markdown You don't need to modify anything in this cell. Just press play.\n",
    "from IPython.display import display, Markdown, Latex\n",
    "\n",
    "module1_sections = [\n",
    "  (\"AIMA Chapter 1.1 What is AI?\", chapter1_1),\n",
    "  (\"AIMA Chapter 27.1 The Limits of AI\", chapter27_1),\n",
    "  (\"AIMA Chapter 27.1 Can Machines Really Think?\", chapter27_2),\n",
    "  (\"AIMA 2.1 Agents and Environments\", chapter2_1),\n",
    "  (\"AIMA 2.2 Good Behavior: The Concept of Rationality\", chapter2_2),\n",
    "  (\"AIMA 2.3 The Nature of Environments\", chapter2_3),\n",
    "  (\"AIMA 2.4 The Structure of Agents\", chapter2_4),\n",
    "  (\"Module 1 Lecture Notes\", module1_lecture_notes),\n",
    "]\n",
    "\n",
    "\n",
    "def length_check(sections):\n",
    "  warnings = \"\"\n",
    "  for section, summary in sections:\n",
    "    max_word_length = 500\n",
    "    max_character_length = 3000\n",
    "    if \"lecture\" in section.lower():\n",
    "      # It's OK to do longer summaries of the lectures\n",
    "      max_word_length = 2000\n",
    "      max_character_length = 12000  \n",
    "    if (len(summary) > max_character_length or len(summary.split(' ')) > max_word_length):\n",
    "      warnings += \"WARNING: Your summary of '{section}' is too long!\\n\".format(section=section)\n",
    "  return warnings\n",
    "\n",
    "def length_check_definitions(definitions):\n",
    "  warnings = \"\"\n",
    "  for concept, definition in definitions.items():\n",
    "    if(len(definition.split(' ')) > 20):\n",
    "      warnings += \"WARNING: Your definition of '{concept}' is too long!\\n\".format(concept=concept)\n",
    "  return warnings\n",
    "\n",
    "\n",
    "def format_module(module_num, title, sections, definitions, show_placeholder=False):\n",
    "  markdown = \"\"\n",
    "\n",
    "  # Check summary lengths\n",
    "  warnings = length_check(sections)\n",
    "  if warnings != \"\":\n",
    "    markdown += \"## \" + warnings\n",
    "\n",
    "  # Check definition lengths\n",
    "  warnings = length_check_definitions(definitions)\n",
    "  if warnings != \"\":\n",
    "    markdown += \"## \" + warnings\n",
    "\n",
    "  markdown += \"# Module {num}: {title}\\n\".format(num=module_num, title=title)\n",
    "\n",
    "\n",
    "  for section, summary in sections:\n",
    "    if show_placeholder and summary == \" Your summary here \":\n",
    "      summary = placeholder\n",
    "    markdown += \"## {section}\\n{summary}\\n\\n\".format(section=section, summary=summary)\n",
    "  \n",
    "  markdown += \"## Module {num} Definitions\\n\".format(num=module_num)\n",
    "  for concept, definition in definitions.items():\n",
    "    markdown += \"* **{concept}** - {definition}\\n\".format(concept=concept.capitalize(), definition=definition)\n",
    "  return markdown\n",
    "\n",
    "\n",
    "module1_markdown = format_module(1, \"Rational Agents and Task Environments\", module1_sections, module1_definitions)\n",
    "display(Markdown(module1_markdown))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9xRbdqDox2zD"
   },
   "source": [
    "#Module 2 - Python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "id": "DpBvu7EMx7sy"
   },
   "outputs": [],
   "source": [
    "# No readings for this module.  Instead you can summarize the lecture instead.\n",
    "\n",
    "# Lecture notes \n",
    "module2_lecture_notes = \"\"\" no notes for python \"\"\"\n",
    "\n",
    "# Each definition should be at most 20 words long.\n",
    "module2_definitions = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "cellView": "form",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 185
    },
    "id": "ydOK__lwWgdp",
    "outputId": "33d9357e-a287-43ae-caf3-f23340681f55"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# Module 2: Python\n",
       "## Module 2 Lecture Notes\n",
       " no notes for python \n",
       "\n",
       "## Module 2 Definitions\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#@title Preview of your summary\n",
    "#@markdown You don't need to modify anything in this cell. Just press play.\n",
    "\n",
    "module2_sections = [\n",
    "  (\"Module 2 Lecture Notes\", module2_lecture_notes),\n",
    "]\n",
    "\n",
    "module2_markdown = format_module(2, \"Python\", module2_sections, module2_definitions)\n",
    "display(Markdown(module2_markdown))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "46MQLR-Gx8dZ"
   },
   "source": [
    "#Module 3 - Search Problems"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "BN0b1eVYx-nd"
   },
   "outputs": [],
   "source": [
    "# Russell and Norvig, AIMA 4th Edition, AIMA Chapter 3 “Problem Solving by Search” (3.1-3.4)\n",
    "chapter3_1 = \"\"\" Problem solving agents: Agent has a goal, formulates the problem as a description of states and actions, does a search to find a solution, and executes.\n",
    "Search problem is defined formally as: \n",
    "A set of possible states the environment can be in, the state space; \n",
    "the initial state; \n",
    "a set of one or more goal states; \n",
    "the actions the agent can take\n",
    "a transition model, describing what each action does\n",
    "an action cost function\n",
    "Agents may create a path \n",
    "An optimal solution is one that has the lowest path cost\n",
    "\n",
    "\"\"\"\n",
    "chapter3_2 = \"\"\" Think through the example of a vacuum. \"\"\"\n",
    "chapter3_3 = \"\"\" Algorithms \n",
    "Best-first search - we have an evaluation function, f(n), and on each iteration we choose the node on the frontier with the lowest f(n) value. Will return path if there is one, may not be optimal path.\n",
    "\"\"\"\n",
    "chapter3_4 = \"\"\" More Algorithms\n",
    "Breadth-first search - put all unseen neighbors on FIFO queue and mark neighbors as seen, mark node visited, pop next node off queue. If all edges have equal weight, will return optimal path, but can be space and time intensive\n",
    "Depth-first search - recursively visit neighbors until a dead-end is reached, or goal is reached. May not return a path if space is infinite or cyclic. If it does return a path, path may not be optimal. Has a smaller memory consumption.\n",
    "Uniform-cost search - Dijkstra's algorithm. Similar to breadth-first search, but expanding by path cost instead of number of nodes. \n",
    "Depth-limited and iterative deepening - DFS but with a limit to depth; iterative deepening increases depth by an amount each iteration; will return optimal path if all edges have equal weight.\n",
    "Bidirectional search - simultaneously searches from the initial state and from the goal state. Halves the required depth from each direction.  \n",
    "\"\"\"\n",
    "\n",
    "# Lecture notes \n",
    "module3_lecture_notes = \"\"\" Same as textbook \"\"\"\n",
    "\n",
    "# Definitions of concepts from Module 3.\n",
    "# You can define any bolded term in the textbook, \n",
    "# but you most use your own words for the definitions.\n",
    "# Each definition should be at most 20 words long.\n",
    "module3_definitions = {\n",
    "\"problem-solving agent\" : \"an agent that can formulate a plan via search\",    \n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "cellView": "form",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 634
    },
    "id": "lvtN3p7ET3Tx",
    "outputId": "4bf41e44-92de-4f1c-de48-6b925f58adfd"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# Module 3: Search Problems\n",
       "## AIMA Chapter 3.1 Problem-Solving Agents\n",
       " Problem solving agents: Agent has a goal, formulates the problem as a description of states and actions, does a search to find a solution, and executes.\n",
       "Search problem is defined formally as: \n",
       "A set of possible states the environment can be in, the state space; \n",
       "the initial state; \n",
       "a set of one or more goal states; \n",
       "the actions the agent can take\n",
       "a transition model, describing what each action does\n",
       "an action cost function\n",
       "Agents may create a path \n",
       "An optimal solution is one that has the lowest path cost\n",
       "\n",
       "\n",
       "\n",
       "## AIMA Chapter 3.2 Example Problems\n",
       " Think through the example of a vacuum. \n",
       "\n",
       "## AIMA Chapter 3.3 Search Algorithms\n",
       " Algorithms \n",
       "Best-first search - we have an evaluation function, f(n), and on each iteration we choose the node on the frontier with the lowest f(n) value. Will return path if there is one, may not be optimal path.\n",
       "\n",
       "\n",
       "## AIMA Chapter 3.4 Uninformed Search Strategies\n",
       " More Algorithms\n",
       "Breadth-first search - put all unseen neighbors on FIFO queue and mark neighbors as seen, mark node visited, pop next node off queue. If all edges have equal weight, will return optimal path, but can be space and time intensive\n",
       "Depth-first search - recursively visit neighbors until a dead-end is reached, or goal is reached. May not return a path if space is infinite or cyclic. If it does return a path, path may not be optimal. Has a smaller memory consumption.\n",
       "Uniform-cost search - Dijkstra's algorithm. Similar to breadth-first search, but expanding by path cost instead of number of nodes. \n",
       "Depth-limited and iterative deepening - DFS but with a limit to depth; iterative deepening increases depth by an amount each iteration; will return optimal path if all edges have equal weight.\n",
       "Bidirectional search - simultaneously searches from the initial state and from the goal state. Halves the required depth from each direction.  \n",
       "\n",
       "\n",
       "## Module 3 Lecture Notes\n",
       " Same as textbook \n",
       "\n",
       "## Module 3 Definitions\n",
       "* **Problem-solving agent** - an agent that can formulate a plan via search\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#@title Preview of your summary\n",
    "#@markdown You don't need to modify anything in this cell. Just press play.\n",
    "module3_sections = [\n",
    "  (\"AIMA Chapter 3.1 Problem-Solving Agents\", chapter3_1),\n",
    "  (\"AIMA Chapter 3.2 Example Problems\", chapter3_2),\n",
    "  (\"AIMA Chapter 3.3 Search Algorithms\", chapter3_3),\n",
    "  (\"AIMA Chapter 3.4 Uninformed Search Strategies\", chapter3_4),\n",
    "  (\"Module 3 Lecture Notes\", module3_lecture_notes),\n",
    "]\n",
    "\n",
    "module3_markdown = format_module(3, \"Search Problems\", module3_sections, module3_definitions)\n",
    "display(Markdown(module3_markdown))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "WHREsHSSyA-h"
   },
   "source": [
    "#Module 4 - Informed Search"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "tuFC8w7CyCns"
   },
   "outputs": [],
   "source": [
    "# Russell and Norvig, AIMA Chapter 3 “Problem Solving by Search” (3.5-3.6)\n",
    "chapter3_5 = \"\"\" \n",
    "Greedy Best First Search - using a heuristic h(n) we select the node that is closest to the goal. May not return optimal path.\n",
    "A* search - A* value is the elapsed distance + the heuristic distance. Returns an optimal path.\n",
    "Iterative deepening A* is A* with iteratively increasing depth limits\n",
    "\"\"\"\n",
    "chapter3_6 = \"\"\" Acceptable heuristics are admissable (will never overestimate the real distance)\n",
    "Good heuristics are admissable and consistent (if a is further than b, h(a) > h(b)). \"\"\"\n",
    "\n",
    "# Lecture notes \n",
    "module4_lecture_notes = \"\"\" Same as textbook \"\"\"\n",
    "\n",
    "# Definitions\n",
    "module4_definitions = {  \n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "cellView": "form",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 336
    },
    "id": "vqtEs0gHs9sO",
    "outputId": "aa4e8269-0e29-4088-80f9-33f5e0e066b7"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# Module 4: Informed Search\n",
       "## AIMA Chapter 3.5 Informed (Heuristic) Search Strategies\n",
       " \n",
       "Greedy Best First Search - using a heuristic h(n) we select the node that is closest to the goal. May not return optimal path.\n",
       "A* search - A* value is the elapsed distance + the heuristic distance. Returns an optimal path.\n",
       "Iterative deepening A* is A* with iteratively increasing depth limits\n",
       "\n",
       "\n",
       "## AIMA Chapter 3.6 Heuristic Functions\n",
       " Acceptable heuristics are admissable (will never overestimate the real distance)\n",
       "Good heuristics are admissable and consistent (if a is further than b, h(a) > h(b)). \n",
       "\n",
       "## Module 4 Lecture Notes\n",
       " Same as textbook \n",
       "\n",
       "## Module 4 Definitions\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#@title Preview of your summary\n",
    "#@markdown You don't need to modify anything in this cell. Just press play.\n",
    "module4_sections = [\n",
    "  (\"AIMA Chapter 3.5 Informed (Heuristic) Search Strategies\", chapter3_5),\n",
    "  (\"AIMA Chapter 3.6 Heuristic Functions\", chapter3_6),\n",
    "  (\"Module 4 Lecture Notes\", module4_lecture_notes),\n",
    "]\n",
    "\n",
    "module4_markdown = format_module(4, \"Informed Search\", \n",
    "                         module4_sections, \n",
    "                         module4_definitions)\n",
    "display(Markdown(module4_markdown))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "F3FPMzG9yUls"
   },
   "source": [
    "#Module 5 - Adversarial Search and Games"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "id": "iEIOpL7vyWcc"
   },
   "outputs": [],
   "source": [
    "# Russell and Norvig, AIMA chapter 5 \"Adversarial Search\"”\" (5.1-5.3, and 5.5).\n",
    "chapter5_1 = \"\"\"  \n",
    "3 stances in multi-agent environments - aggregate, part of environment, adversaries\n",
    "Adversarial agents are actively trying to defeat us.\n",
    "Most common - 2 player zero-sum games\n",
    "Game definition: initial state, turn, actions, results, is game over, utility function \n",
    "State space and game tree my be infinite\n",
    "\"\"\"\n",
    "chapter5_2 = \"\"\" Optimal decisions - we assume that opponent is rational, i.e. running the same analysis against us\n",
    "Minimax - effectively MAX(a, b) = MIN(-b, -a)\n",
    "Alpha Beta pruning - at each node, when possible, we set the outcome threshold such that the opponent would never choose any leaf past that threshold.\n",
    "We can thus eliminate any such leaves. \n",
    "Still too many possibilities in games like chess and go;\n",
    "Type A strategy: Wide but shallow (see all possibilities but to limited depth)\n",
    "Type B strategy: Deep but narrow (choose most promising options)\n",
    "\"\"\"\n",
    "chapter5_3 = \"\"\"\n",
    "Heuristic Alpha-Beta Tree Search\n",
    "heuristic function returns estimate of expected utility\n",
    "We prune branches with too low an expected utility estimate\n",
    "\"\"\"\n",
    "chapter5_5 = \"\"\" Stochaistic games\n",
    "Expectiminmax - using probability to maxmize / minimize utility\n",
    "\"\"\"\n",
    "\n",
    "# Russell and Norvig, AIMA Chapter 16 “Making Simple Decisions” (16.1-16.3)\n",
    "chapter16_1 = \"\"\" Maximization of expected utility \n",
    "action = argmax EU(a)\n",
    "basically, agent should do the right thing by maximizing expected utility.\n",
    "\"\"\"\n",
    "chapter16_2 = \"\"\" utility functions\n",
    "concept of preferemces - prefers A over B (in some strategy), indifferent between A and B (like in a lottery drawing)\n",
    "\"\"\"\n",
    "chapter16_3 = \"\"\" relations of utility functions to money\n",
    "Money can be a form of utility - cost of of an action, value of an outcome, etc\n",
    "Other aspects - aspect quality, volatility/certainty, framing (e.g. lottery as monetary value vs entertainment value)\n",
    "\"\"\"\n",
    "\n",
    "# Lecture notes \n",
    "module5_lecture_notes = \"\"\" Expectimax search is computing average score under optimal play \"\"\"\n",
    "\n",
    "# Definitions\n",
    "module5_definitions = {   \n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "cellView": "form",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 739
    },
    "id": "KUc_LgzDvWf-",
    "outputId": "b390dcf7-fd7e-4fcc-90c4-fa9fd4018f28"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# Module 5: Adversarial Search and Games\n",
       "## AIMA Chapter 5.1 Game Theory\n",
       "  \n",
       "3 stances in multi-agent environments - aggregate, part of environment, adversaries\n",
       "Adversarial agents are actively trying to defeat us.\n",
       "Most common - 2 player zero-sum games\n",
       "Game definition: initial state, turn, actions, results, is game over, utility function \n",
       "State space and game tree my be infinite\n",
       "\n",
       "\n",
       "## AIMA Chapter 5.2 Optimal Decisions in Games\n",
       " Optimal decisions - we assume that opponent is rational, i.e. running the same analysis against us\n",
       "Minimax - effectively MAX(a, b) = MIN(-b, -a)\n",
       "Alpha Beta pruning - at each node, when possible, we set the outcome threshold such that the opponent would never choose any leaf past that threshold.\n",
       "We can thus eliminate any such leaves. \n",
       "Still too many possibilities in games like chess and go;\n",
       "Type A strategy: Wide but shallow (see all possibilities but to limited depth)\n",
       "Type B strategy: Deep but narrow (choose most promising options)\n",
       "\n",
       "\n",
       "## AIMA Chapter 5.3 Heuristic Alpha–Beta Tree Search\n",
       "\n",
       "Heuristic Alpha-Beta Tree Search\n",
       "heuristic function returns estimate of expected utility\n",
       "We prune branches with too low an expected utility estimate\n",
       "\n",
       "\n",
       "## AIMA Chapter 5.5 Stochastic Games\n",
       " Stochaistic games\n",
       "Expectiminmax - using probability to maxmize / minimize utility\n",
       "\n",
       "\n",
       "## AIMA Chapter 16.1 Combining Beliefs and Desires under Uncertainty\n",
       " Maximization of expected utility \n",
       "action = argmax EU(a)\n",
       "basically, agent should do the right thing by maximizing expected utility.\n",
       "\n",
       "\n",
       "## AIMA Chapter 16.2 The Basis of Utility Theory\n",
       " utility functions\n",
       "concept of preferemces - prefers A over B (in some strategy), indifferent between A and B (like in a lottery drawing)\n",
       "\n",
       "\n",
       "## AIMA Chapter 16.3 Utility Functions\n",
       " relations of utility functions to money\n",
       "Money can be a form of utility - cost of of an action, value of an outcome, etc\n",
       "Other aspects - aspect quality, volatility/certainty, framing (e.g. lottery as monetary value vs entertainment value)\n",
       "\n",
       "\n",
       "## Module 5 Lecture Notes\n",
       " Expectimax search is computing average score under optimal play \n",
       "\n",
       "## Module 5 Definitions\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#@title Preview of your summary\n",
    "#@markdown You don't need to modify anything in this cell. Just press play.\n",
    "module5_sections = [\n",
    "  (\"AIMA Chapter 5.1 Game Theory\", chapter5_1),\n",
    "  (\"AIMA Chapter 5.2 Optimal Decisions in Games\", chapter5_2),\n",
    "  (\"AIMA Chapter 5.3 Heuristic Alpha–Beta Tree Search\", chapter5_3),\n",
    "  (\"AIMA Chapter 5.5 Stochastic Games\", chapter5_5),\n",
    "  (\"AIMA Chapter 16.1 Combining Beliefs and Desires under Uncertainty\", chapter16_1),\n",
    "  (\"AIMA Chapter 16.2 The Basis of Utility Theory\", chapter16_2),\n",
    "  (\"AIMA Chapter 16.3 Utility Functions\", chapter16_3),\n",
    "  (\"Module 5 Lecture Notes\", module5_lecture_notes),\n",
    "]\n",
    "\n",
    "module5_markdown = format_module(5, \"Adversarial Search and Games\", \n",
    "                         module5_sections, \n",
    "                         module5_definitions)\n",
    "display(Markdown(module5_markdown))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "qVSQhTVSyYYO"
   },
   "source": [
    "#Module 6 - \"Constraint Satisfaction Problems\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "id": "Wm4mfW82yaRH"
   },
   "outputs": [],
   "source": [
    "# Russell and Norvig, AIMA, Chapter 6 “Constraint Satisfaction Problems” (6.1-6.5)\n",
    "chapter6_1 = \"\"\" Constraint satisfaction problems\n",
    "3 components - set of variables, set of domains, set of constraints\n",
    "Domains are the allowable values for each variable\n",
    "Constraints are the restrictions for a tuple (one or more) of variables\n",
    "Simplest CSPs have discrete, finite domains (e.g. sudoku). \n",
    "You can also have discrete but infinite domains - constraints in this case may be functions rather than specific values\n",
    "In sudoku puzzle we largely did binary constraints, but global constraints are also valid, can be more efficient and less error prone.\n",
    " \"\"\"\n",
    "chapter6_2 = \"\"\" Inference in CSPs\n",
    "Arc Consistency - while there are revisions, ensure all domains are consistent\n",
    "\"\"\"\n",
    "chapter6_3 = \"\"\" Backtracking search - basically what we did for sudoku with guessing\n",
    "detection of failure condition (unsolvable puzzle)\n",
    "backtracking algorithm (to which state? - can be most recent move, or to some earlier node)\n",
    "\"\"\"\n",
    "chapter6_4 = \"\"\"Local search - focus on conflicted variables, and reassign in a way that minimizes conflicts\n",
    "We can also weight constraints to focus on the hardest / most important constraints\n",
    "\"\"\"\n",
    "chapter6_5 = \"\"\"Important to decompose problems into subproblems. \"\"\"\n",
    "\n",
    "\n",
    "# Lecture notes \n",
    "module6_lecture_notes = \"\"\" Same as textbook \"\"\"\n",
    "\n",
    "# Definitions\n",
    "module6_definitions = {  \n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "cellView": "form",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 606
    },
    "id": "kKWbCsbfxL3R",
    "outputId": "4bc8020a-0247-468f-f913-6b8a9c6a40ff"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# Module 6: Constraint Satisfaction Problems\n",
       "## AIMA Chapter 6.1 Defining Constraint Satisfaction Problems\n",
       " Constraint satisfaction problems\n",
       "3 components - set of variables, set of domains, set of constraints\n",
       "Domains are the allowable values for each variable\n",
       "Constraints are the restrictions for a tuple (one or more) of variables\n",
       "Simplest CSPs have discrete, finite domains (e.g. sudoku). \n",
       "You can also have discrete but infinite domains - constraints in this case may be functions rather than specific values\n",
       "In sudoku puzzle we largely did binary constraints, but global constraints are also valid, can be more efficient and less error prone.\n",
       " \n",
       "\n",
       "## AIMA Chapter 6.2 Constraint Propagation: Inference in CSPs\n",
       " Inference in CSPs\n",
       "Arc Consistency - while there are revisions, ensure all domains are consistent\n",
       "\n",
       "\n",
       "## AIMA Chapter 6.3 Backtracking Search for CSPs\n",
       " Backtracking search - basically what we did for sudoku with guessing\n",
       "detection of failure condition (unsolvable puzzle)\n",
       "backtracking algorithm (to which state? - can be most recent move, or to some earlier node)\n",
       "\n",
       "\n",
       "## AIMA Chapter 6.4 Local Search for CSPs\n",
       "Local search - focus on conflicted variables, and reassign in a way that minimizes conflicts\n",
       "We can also weight constraints to focus on the hardest / most important constraints\n",
       "\n",
       "\n",
       "## AIMA Chapter 6.5 The Structure of Problems\n",
       "Important to decompose problems into subproblems. \n",
       "\n",
       "## Module 6 Lecture Notes\n",
       " Same as textbook \n",
       "\n",
       "## Module 6 Definitions\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#@title Preview of your summary\n",
    "#@markdown You don't need to modify anything in this cell. Just press play.\n",
    "module6_sections = [\n",
    "  (\"AIMA Chapter 6.1 Defining Constraint Satisfaction Problems\", chapter6_1),\n",
    "  (\"AIMA Chapter 6.2 Constraint Propagation: Inference in CSPs\", chapter6_2),\n",
    "  (\"AIMA Chapter 6.3 Backtracking Search for CSPs\", chapter6_3),\n",
    "  (\"AIMA Chapter 6.4 Local Search for CSPs\", chapter6_4),\n",
    "  (\"AIMA Chapter 6.5 The Structure of Problems\", chapter6_5),\n",
    "  (\"Module 6 Lecture Notes\", module6_lecture_notes),\n",
    "]\n",
    "\n",
    "module6_markdown = format_module(6, \"Constraint Satisfaction Problems\", \n",
    "                         module6_sections, \n",
    "                         module6_definitions)\n",
    "display(Markdown(module6_markdown))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "RYESi2kMybL8"
   },
   "source": [
    "#Module 7 - Logical Agents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "id": "qIRJ4YYCzNHL"
   },
   "outputs": [],
   "source": [
    "# Russell and Norvig, AIMA Chapter 7 “Logical Agents” (Sections 7.1-7.5)\n",
    "\n",
    "chapter7_1 = \"\"\" Central component of knowledge-based agent is its knowledge base. \n",
    "Add to knowledge base: Tell\n",
    "Query knowledge base: Ask\n",
    "Agent Program: Tell(precepts) > Ask(what do you think?) > Tell(chosen action) > Executes(action) > Tell(outcome)\n",
    "\n",
    "\"\"\"\n",
    "chapter7_2 = \"\"\" Wumpussss worldddd \"\"\"\n",
    "chapter7_3 = \"\"\" Knowledge bases consist of sentences. These sentences are logical representations. \n",
    "Logical reasoning is the relation of logical entailment between sentences, to determine possibilities and conclusions.\n",
    "\"\"\"\n",
    "chapter7_4 = \"\"\" \n",
    "Negation (NOT) ¬\n",
    "Conjunction (AND) ∧\n",
    "Disjunction (OR) ∨\n",
    "Implication ⇒\n",
    "IFF ⇔\n",
    "Logically Equivalent ≡\n",
    "\"\"\"\n",
    "chapter7_5 = \"\"\"\n",
    "(A∧B) ≡ (B∧A) commutativity of ∧ \\n\n",
    "(A∨B) ≡ (B∨A) commutativity of ∨ \\n\n",
    "((A∧B)∧C) ≡ (A∧(B∧C)) associativity of ∧ \\n\n",
    "((A∨B)∨C) ≡ (A∨(B∨C)) associativity of ∨ \\n\n",
    "¬(¬A) ≡ A double negation elimination \\n\n",
    "A⇒B ≡ ¬B⇒¬A contraposition \\n\n",
    "A⇒B ≡ ¬A∨B implication elimination \\n\n",
    "A⇔B ≡ (A⇒B) ∧ (A⇒B) biconditional elimination \\n\n",
    "¬(A∧B) ≡ (¬B∨¬A) de morgan \\n\n",
    "¬(A∨B) ≡ (¬B∧¬A) de morgan \\n\n",
    "(A∧(B∨C)) ≡ ((A∧B)∨(A∧C)) distributivity of ∧ over ∨ \\n\n",
    "(A∨(B∧C)) ≡ ((A∨B)∧(A∨C)) distributivity of ∨ over ∧ \\n\n",
    "\"\"\"\n",
    "\n",
    "# Lecture notes \n",
    "module7_lecture_notes = \"\"\" Same as textbook \"\"\"\n",
    "\n",
    "# Definitions\n",
    "module7_definitions = { \n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "cellView": "form",
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 588
    },
    "id": "lXNcHuKjyNXa",
    "outputId": "f2b37fbd-c51c-432c-9e03-d6a2079a0e65"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# Module 7: Logical Agents\n",
       "## AIMA Chapter 7.1 Knowledge-Based Agents\n",
       " Central component of knowledge-based agent is its knowledge base. \n",
       "Add to knowledge base: Tell\n",
       "Query knowledge base: Ask\n",
       "Agent Program: Tell(precepts) > Ask(what do you think?) > Tell(chosen action) > Executes(action) > Tell(outcome)\n",
       "\n",
       "\n",
       "\n",
       "## AIMA Chapter 7.2 The Wumpus World\n",
       " Wumpussss worldddd \n",
       "\n",
       "## AIMA Chapter 7.3 Logic\n",
       " Knowledge bases consist of sentences. These sentences are logical representations. \n",
       "Logical reasoning is the relation of logical entailment between sentences, to determine possibilities and conclusions.\n",
       "\n",
       "\n",
       "## AIMA Chapter 7.4 Propositional Logic: A Very Simple Logic\n",
       " \n",
       "Negation (NOT) ¬\n",
       "Conjunction (AND) ∧\n",
       "Disjunction (OR) ∨\n",
       "Implication ⇒\n",
       "IFF ⇔\n",
       "Logically Equivalent ≡\n",
       "\n",
       "\n",
       "## AIMA 7.5 Propositional Theorem Proving\n",
       "\n",
       "(A∧B) ≡ (B∧A) commutativity of ∧\n",
       "(A∨B) ≡ (B∨A) commutativity of ∨\n",
       "((A∧B)∧C) ≡ (A∧(B∧C)) associativity of ∧\n",
       "((A∨B)∨C) ≡ (A∨(B∨C)) associativity of ∨\n",
       "¬(¬A) ≡ A double negation elimination\n",
       "A⇒B ≡ ¬B⇒¬A contraposition\n",
       "A⇒B ≡ ¬A∨B implication elimination\n",
       "A⇔B ≡ (A⇒B) ∧ (A⇒B) biconditional elimination\n",
       "¬(A∧B) ≡ (¬B∨¬A) de morgan\n",
       "¬(A∨B) ≡ (¬B∧¬A) de morgan\n",
       "(A∧(B∨C)) ≡ ((A∧B)∨(A∧C)) distributivity of ∧ over ∨ \n",
       "(A∨(B∧C)) ≡ ((A∨B)∧(A∨C)) distributivity of ∨ over ∧ \n",
       "\n",
       "\n",
       "## Module 7 Lecture Notes\n",
       " Same as textbook \n",
       "\n",
       "## Module 7 Definitions\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#@title Preview of your summary\n",
    "#@markdown You don't need to modify anything in this cell. Just press play.\n",
    "module7_sections = [\n",
    "  (\"AIMA Chapter 7.1 Knowledge-Based Agents\", chapter7_1),\n",
    "  (\"AIMA Chapter 7.2 The Wumpus World\", chapter7_2),\n",
    "  (\"AIMA Chapter 7.3 Logic\", chapter7_3),\n",
    "  (\"AIMA Chapter 7.4 Propositional Logic: A Very Simple Logic\", chapter7_4),\n",
    "  (\"AIMA 7.5 Propositional Theorem Proving\", chapter7_5),\n",
    "  (\"Module 7 Lecture Notes\", module7_lecture_notes),\n",
    "]\n",
    "\n",
    "module7_markdown = format_module(7, \"Logical Agents\", \n",
    "                         module7_sections, \n",
    "                         module7_definitions)\n",
    "display(Markdown(module7_markdown))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "vX7lbnJd4sT5"
   },
   "source": [
    "# Your Exam Notes\n",
    "\n",
    "Here are your full set of exam notes that you can use on your midterm.  Choose **Runtime > Run all**, then your notes will be displayed.\n",
    "\n",
    "If you are taking the exam in person, then you must print a copy of your notes for yourself.   Here's how to print:\n",
    "* Run the cell below. \n",
    "* Click its \"Mirror cell in tab\" button (this is located in the upper right corner of the cell, immediately to the right of the trash can).  This will open the cell.  \n",
    "* In Chrome, you can then print your notes using the **File > Print** option from the browser's menu.  \n",
    "* In the print options, change the layout from Landscape to Portrait. \n",
    "* Clicking the Save, will save a PDF that you can then print.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 1000
    },
    "id": "T3cm1WV542_a",
    "outputId": "2ee23545-8eee-4294-a3ec-a62e785c01cd"
   },
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "# Module 1: Rational Agents and Task Environments\n",
       "## AIMA Chapter 1.1 What is AI?\n",
       " Artificial Intelligence can be defined in 4 quadrants - \n",
       "Thought vs Behavior (is the internal comprehension more important or the behavior?)\n",
       "Human vs Rational (are humans occasionally irrational?)\n",
       "The Turing test - if we cannot differentiate between a person and a computer, is the computer essentially a person?\n",
       "AI Technologies - Natural Language Processing, Knowledge Representation, Automated Reasoning, Machine Learning\n",
       "Total Turing Test - including real world interaction, not just written text - Computer Vision, Speech Recognition, Robotics\n",
       "Cognitive Modelling - how do our brains work? \n",
       "Rational Thinking - what is the 'right' way to think?\n",
       "Standard Model - AI research has focused on making agents that do the right thing. But we have to supply the 'right thing'\n",
       "Beneficial machines - What if we cannot supply the 'right thing' in a form that covers all bases, i.e. is fully specified? \n",
       "There is a risk of negative consequences to logical actions towards an incomplete objective. We want agents that are provably beneficial.\n",
       "\n",
       "\n",
       "## AIMA Chapter 27.1 The Limits of AI\n",
       " Weak AI vs Strong AI - Weak AI act as if intelligent, Strong AI are actually intelligent\n",
       "What are some of the things people have postulated that AI can't do?\n",
       "Informality of behavior - 'Human intelligence and behavior is too complex to be formalized into a set of rules, and thus cannot be codified'\n",
       "Disability - \"AI can never be emotional, be moral, enjoy things, fall in love, do something truly new\"\n",
       "Mathematical - Godel sentence - \"My current sentence is a lie\"\n",
       "Measuring AI - Turing Test, Games - Chess, Go, StarCraft II, Defense of the Ancients 2\n",
       "\n",
       "\n",
       "## AIMA Chapter 27.1 Can Machines Really Think?\n",
       " Can machines really think?\n",
       "Chinese room example - if you follow some rules to respond in chinese to a chinese input, does that mean you understand chinese? \n",
       "Or - does a chatbot really understand english? In fact, what does it mean to \"understand\"?\n",
       "Consciousness is mysterious. \n",
       "\n",
       "\n",
       "## AIMA 2.1 Agents and Environments\n",
       " Agents perceive 'percepts' (e.g. light, sound) through 'sensors' (e.g. eyes, ears) and do 'actions' (e.g. walk, pick) through 'actuators' (e.g. legs, hands). \n",
       "Agent's 'percept sequence' is everything they have ever perceived. Agents act based on built-in knowledge and their percept sequence, but cannot act on anything outside that.\n",
       "Behavior is described by 'agent function' that maps a specific percept sequence to an action. Agent function is implemented by 'agent program'. Function is abstract, program is implementation. \n",
       "\n",
       "\n",
       "## AIMA 2.2 Good Behavior: The Concept of Rationality\n",
       " Rational agents do the right thing. \n",
       "The right thing is a performance measure \n",
       "Good to design performance measure according to what needs to be achieved in the environment.\n",
       "What is rational depends on: The perofmrance measure, the agent's prior knowledge, actions the agent can perform, agent's percept sequence\n",
       "Rational agents may make mistakes - agents are not omniscient. Agents simply maximize expected performance.\n",
       "Agents should learn from experience, unless environments are already fully understood in prior knowledge. \n",
       " \n",
       "\n",
       "## AIMA 2.3 The Nature of Environments\n",
       " Task environments consist of PEAS - Performance Measure, Environment, Actuators, Sensors \n",
       "Example: Taxi Driver\n",
       "Performance Measure - drive safely and legally, as fast as possible\n",
       "Environment - roads, other drivers, law enforcement, pedestrians\n",
       "Actuators - Steering wheel, brake, signal, horn, etc\n",
       "Sensors - Visual, Auditory, Speedometer, GPS, etc\n",
       "When designing an agent, specify the task environment as fully as possible.\n",
       "Task enviromnets may be: \n",
       "Fully observable vs Partially observable\n",
       "Single-Agent vs Multi-Agent\n",
       "Deterministic vs Non-deterministic\n",
       "Episodic vs Sequential\n",
       "Static vs Dynamic\n",
       "Discrete vs Continuous\n",
       "Known vs Unknown\n",
       "\n",
       "\n",
       "## AIMA 2.4 The Structure of Agents\n",
       " An agent is architecture (hardware - device with sensors, actuators) + program (software) \n",
       "4 basic kinds of agent programs:\n",
       "Simple reflex agents - act based on current precept\n",
       "Model-based reflex agents - keeps track of some amount of part precepts and draws inferences from that\n",
       "Goal-based agents - acts based on goal information that describes situations that are desirable\n",
       "Utility-based agents - acts on more general performance measures of 'utility'\n",
       "\n",
       "\n",
       "## Module 1 Lecture Notes\n",
       " Basically the same as the textbook \n",
       "\n",
       "## Module 1 Definitions\n",
       "* **Ai** - the science of making machines that think like people, think rationally, act like people, act rationally\n",
       "* **Agent** - anything that can perceive through sensors and act through actuators in an environment\n",
       "\n",
       "\n",
       "# Module 2: Python\n",
       "## Module 2 Lecture Notes\n",
       " no notes for python \n",
       "\n",
       "## Module 2 Definitions\n",
       "\n",
       "\n",
       "# Module 3: Search Problems\n",
       "## AIMA Chapter 3.1 Problem-Solving Agents\n",
       " Problem solving agents: Agent has a goal, formulates the problem as a description of states and actions, does a search to find a solution, and executes.\n",
       "Search problem is defined formally as: \n",
       "A set of possible states the environment can be in, the state space; \n",
       "the initial state; \n",
       "a set of one or more goal states; \n",
       "the actions the agent can take\n",
       "a transition model, describing what each action does\n",
       "an action cost function\n",
       "Agents may create a path \n",
       "An optimal solution is one that has the lowest path cost\n",
       "\n",
       "\n",
       "\n",
       "## AIMA Chapter 3.2 Example Problems\n",
       " Think through the example of a vacuum. \n",
       "\n",
       "## AIMA Chapter 3.3 Search Algorithms\n",
       " Algorithms \n",
       "Best-first search - we have an evaluation function, f(n), and on each iteration we choose the node on the frontier with the lowest f(n) value. Will return path if there is one, may not be optimal path.\n",
       "\n",
       "\n",
       "## AIMA Chapter 3.4 Uninformed Search Strategies\n",
       " More Algorithms\n",
       "Breadth-first search - put all unseen neighbors on FIFO queue and mark neighbors as seen, mark node visited, pop next node off queue. If all edges have equal weight, will return optimal path, but can be space and time intensive\n",
       "Depth-first search - recursively visit neighbors until a dead-end is reached, or goal is reached. May not return a path if space is infinite or cyclic. If it does return a path, path may not be optimal. Has a smaller memory consumption.\n",
       "Uniform-cost search - Dijkstra's algorithm. Similar to breadth-first search, but expanding by path cost instead of number of nodes. \n",
       "Depth-limited and iterative deepening - DFS but with a limit to depth; iterative deepening increases depth by an amount each iteration; will return optimal path if all edges have equal weight.\n",
       "Bidirectional search - simultaneously searches from the initial state and from the goal state. Halves the required depth from each direction.  \n",
       "\n",
       "\n",
       "## Module 3 Lecture Notes\n",
       " Same as textbook \n",
       "\n",
       "## Module 3 Definitions\n",
       "* **Problem-solving agent** - an agent that can formulate a plan via search\n",
       "\n",
       "\n",
       "# Module 4: Informed Search\n",
       "## AIMA Chapter 3.5 Informed (Heuristic) Search Strategies\n",
       " \n",
       "Greedy Best First Search - using a heuristic h(n) we select the node that is closest to the goal. May not return optimal path.\n",
       "A* search - A* value is the elapsed distance + the heuristic distance. Returns an optimal path.\n",
       "Iterative deepening A* is A* with iteratively increasing depth limits\n",
       "\n",
       "\n",
       "## AIMA Chapter 3.6 Heuristic Functions\n",
       " Acceptable heuristics are admissable (will never overestimate the real distance)\n",
       "Good heuristics are admissable and consistent (if a is further than b, h(a) > h(b)). \n",
       "\n",
       "## Module 4 Lecture Notes\n",
       " Same as textbook \n",
       "\n",
       "## Module 4 Definitions\n",
       "\n",
       "\n",
       "# Module 5: Adversarial Search and Games\n",
       "## AIMA Chapter 5.1 Game Theory\n",
       "  \n",
       "3 stances in multi-agent environments - aggregate, part of environment, adversaries\n",
       "Adversarial agents are actively trying to defeat us.\n",
       "Most common - 2 player zero-sum games\n",
       "Game definition: initial state, turn, actions, results, is game over, utility function \n",
       "State space and game tree my be infinite\n",
       "\n",
       "\n",
       "## AIMA Chapter 5.2 Optimal Decisions in Games\n",
       " Optimal decisions - we assume that opponent is rational, i.e. running the same analysis against us\n",
       "Minimax - effectively MAX(a, b) = MIN(-b, -a)\n",
       "Alpha Beta pruning - at each node, when possible, we set the outcome threshold such that the opponent would never choose any leaf past that threshold.\n",
       "We can thus eliminate any such leaves. \n",
       "Still too many possibilities in games like chess and go;\n",
       "Type A strategy: Wide but shallow (see all possibilities but to limited depth)\n",
       "Type B strategy: Deep but narrow (choose most promising options)\n",
       "\n",
       "\n",
       "## AIMA Chapter 5.3 Heuristic Alpha–Beta Tree Search\n",
       "\n",
       "Heuristic Alpha-Beta Tree Search\n",
       "heuristic function returns estimate of expected utility\n",
       "We prune branches with too low an expected utility estimate\n",
       "\n",
       "\n",
       "## AIMA Chapter 5.5 Stochastic Games\n",
       " Stochaistic games\n",
       "Expectiminmax - using probability to maxmize / minimize utility\n",
       "\n",
       "\n",
       "## AIMA Chapter 16.1 Combining Beliefs and Desires under Uncertainty\n",
       " Maximization of expected utility \n",
       "action = argmax EU(a)\n",
       "basically, agent should do the right thing by maximizing expected utility.\n",
       "\n",
       "\n",
       "## AIMA Chapter 16.2 The Basis of Utility Theory\n",
       " utility functions\n",
       "concept of preferemces - prefers A over B (in some strategy), indifferent between A and B (like in a lottery drawing)\n",
       "\n",
       "\n",
       "## AIMA Chapter 16.3 Utility Functions\n",
       " relations of utility functions to money\n",
       "Money can be a form of utility - cost of of an action, value of an outcome, etc\n",
       "Other aspects - aspect quality, volatility/certainty, framing (e.g. lottery as monetary value vs entertainment value)\n",
       "\n",
       "\n",
       "## Module 5 Lecture Notes\n",
       " Expectimax search is computing average score under optimal play \n",
       "\n",
       "## Module 5 Definitions\n",
       "\n",
       "\n",
       "# Module 6: Constraint Satisfaction Problems\n",
       "## AIMA Chapter 6.1 Defining Constraint Satisfaction Problems\n",
       " Constraint satisfaction problems\n",
       "3 components - set of variables, set of domains, set of constraints\n",
       "Domains are the allowable values for each variable\n",
       "Constraints are the restrictions for a tuple (one or more) of variables\n",
       "Simplest CSPs have discrete, finite domains (e.g. sudoku). \n",
       "You can also have discrete but infinite domains - constraints in this case may be functions rather than specific values\n",
       "In sudoku puzzle we largely did binary constraints, but global constraints are also valid, can be more efficient and less error prone.\n",
       " \n",
       "\n",
       "## AIMA Chapter 6.2 Constraint Propagation: Inference in CSPs\n",
       " Inference in CSPs\n",
       "Arc Consistency - while there are revisions, ensure all domains are consistent\n",
       "\n",
       "\n",
       "## AIMA Chapter 6.3 Backtracking Search for CSPs\n",
       " Backtracking search - basically what we did for sudoku with guessing\n",
       "detection of failure condition (unsolvable puzzle)\n",
       "backtracking algorithm (to which state? - can be most recent move, or to some earlier node)\n",
       "\n",
       "\n",
       "## AIMA Chapter 6.4 Local Search for CSPs\n",
       "Local search - focus on conflicted variables, and reassign in a way that minimizes conflicts\n",
       "We can also weight constraints to focus on the hardest / most important constraints\n",
       "\n",
       "\n",
       "## AIMA Chapter 6.5 The Structure of Problems\n",
       "Important to decompose problems into subproblems. \n",
       "\n",
       "## Module 6 Lecture Notes\n",
       " Same as textbook \n",
       "\n",
       "## Module 6 Definitions\n",
       "\n",
       "\n",
       "# Module 7: Logical Agents\n",
       "## AIMA Chapter 7.1 Knowledge-Based Agents\n",
       " Central component of knowledge-based agent is its knowledge base. \n",
       "Add to knowledge base: Tell\n",
       "Query knowledge base: Ask\n",
       "Agent Program: Tell(precepts) > Ask(what do you think?) > Tell(chosen action) > Executes(action) > Tell(outcome)\n",
       "\n",
       "\n",
       "\n",
       "## AIMA Chapter 7.2 The Wumpus World\n",
       " Wumpussss worldddd \n",
       "\n",
       "## AIMA Chapter 7.3 Logic\n",
       " Knowledge bases consist of sentences. These sentences are logical representations. \n",
       "Logical reasoning is the relation of logical entailment between sentences, to determine possibilities and conclusions.\n",
       "\n",
       "\n",
       "## AIMA Chapter 7.4 Propositional Logic: A Very Simple Logic\n",
       " \n",
       "Negation (NOT) ¬\n",
       "Conjunction (AND) ∧\n",
       "Disjunction (OR) ∨\n",
       "Implication ⇒\n",
       "IFF ⇔\n",
       "Logically Equivalent ≡\n",
       "\n",
       "\n",
       "## AIMA 7.5 Propositional Theorem Proving\n",
       "\n",
       "(A∧B) ≡ (B∧A) commutativity of ∧\n",
       "(A∨B) ≡ (B∨A) commutativity of ∨\n",
       "((A∧B)∧C) ≡ (A∧(B∧C)) associativity of ∧\n",
       "((A∨B)∨C) ≡ (A∨(B∨C)) associativity of ∨\n",
       "¬(¬A) ≡ A double negation elimination\n",
       "A⇒B ≡ ¬B⇒¬A contraposition\n",
       "A⇒B ≡ ¬A∨B implication elimination\n",
       "A⇔B ≡ (A⇒B) ∧ (A⇒B) biconditional elimination\n",
       "¬(A∧B) ≡ (¬B∨¬A) de morgan\n",
       "¬(A∨B) ≡ (¬B∧¬A) de morgan\n",
       "(A∧(B∨C)) ≡ ((A∧B)∨(A∧C)) distributivity of ∧ over ∨ \n",
       "(A∨(B∧C)) ≡ ((A∨B)∧(A∨C)) distributivity of ∨ over ∧ \n",
       "\n",
       "\n",
       "## Module 7 Lecture Notes\n",
       " Same as textbook \n",
       "\n",
       "## Module 7 Definitions\n"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# This will generate the full set of notes that you can use for your exam.\n",
    "full_markdown = \"\\n\\n\".join([module1_markdown, \n",
    "                             module2_markdown, \n",
    "                             module3_markdown, \n",
    "                             module4_markdown, \n",
    "                             module5_markdown,\n",
    "                             module6_markdown,\n",
    "                             module7_markdown,]\n",
    "                       )\n",
    "display(Markdown(full_markdown))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "id": "GTmjtNmNN-_N"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "Copy of FINAL Template_for CIS521_midterm notes.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "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.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
