{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3946e483",
   "metadata": {
    "hideOutput": true,
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Practice Writing Functions\n",
    "#### CS 66: Introduction to Computer Science II"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4bd8b664",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Purpose\n",
    "\n",
    "We want to get good at writing functions\n",
    "* Abstraction!\n",
    "* Divide and conquer\n",
    "* We are going to do a lot with classes - that needs functions\n",
    "\n",
    "\n",
    "## References for this lecture\n",
    "\n",
    "Problem Solving with Algorithms and Data Structures using Python, Section 1.12: [https://runestone.academy/ns/books/published/pythonds/Introduction/DefiningFunctions.html](https://runestone.academy/ns/books/published/pythonds/Introduction/DefiningFunctions.html)\n",
    "\n",
    "\n",
    "Also see Chapter 3 of Think Python( [https://greenteapress.com/thinkpython2/html/thinkpython2004.html](https://greenteapress.com/thinkpython2/html/thinkpython2004.html) )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0ef93fc",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Here's a function that isn't very useful\n",
    "\n",
    "Discuss: Why is this a bad function?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b1cec0a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f_to_c():\n",
    "    fahrenheit_temp = float(input(\"Enter a temperature in Fahrenheit: \"))\n",
    "    celsius_temp = (fahrenheit_temp-32)*(5/9)\n",
    "    print(\"That's\",celsius_temp,\"in Celsius\") "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0863bd9d",
   "metadata": {},
   "outputs": [],
   "source": [
    "f_to_c()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b35d2a71",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "If we instead write the function like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76294a10",
   "metadata": {},
   "outputs": [],
   "source": [
    "def f_to_c(fahrenheit_temp):\n",
    "    celsius_temp = (fahrenheit_temp-32)*(5/9)\n",
    "    return celsius_temp"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "edb3c95f",
   "metadata": {},
   "source": [
    "then we can use it in many different contexts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1dea7ace",
   "metadata": {},
   "outputs": [],
   "source": [
    "#....\n",
    "if f_to_c(value_from_file) < 0:\n",
    "    freezing_days += 1\n",
    "#...."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "16c899fe",
   "metadata": {},
   "source": [
    "Let's draw some pictures to remind ourselves how parameters and return values work."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "468b1766",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Another Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8d7f7d94",
   "metadata": {},
   "outputs": [],
   "source": [
    "def calculate_pay(wage,hours):\n",
    "    if hours <= 40:\n",
    "        pay = wage*hours\n",
    "    else:\n",
    "        overtime_hours = hours-40\n",
    "        pay = (wage*40) + (wage*1.5*overtime_hours)\n",
    "\n",
    "    print(\"Total pay:\",pay)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fffa0243",
   "metadata": {},
   "source": [
    "vs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f79163d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def calculate_pay(wage,hours):\n",
    "    if hours <= 40:\n",
    "        pay = wage*hours\n",
    "    else:\n",
    "        overtime_hours = hours-40\n",
    "        pay = (wage*40) + (wage*1.5*overtime_hours)\n",
    "\n",
    "    return pay\n",
    "\n",
    "employee_database = [(\"Lola Howell\",17.65,42),(\"Nicolas Wagner\",14.05,38),(\"Marlene Ramos\",15.80,40)] #etc\n",
    "\n",
    "for employee in employee_database:\n",
    "    issue_paycheck(employee[0],calculate_pay(employee[1],employee[2]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6408719d",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Rule of thumb\n",
    "\n",
    "Put all your user interaction (`input`, `print`, etc.) into one function like `main`, `user_interface`, etc.\n",
    "\n",
    "Most other functions shouldn't have any `print` or `input` statements at all!"
   ]
  },
  {
   "attachments": {
    "Chimpanzee_seated_at_typewriter.jpg": {
     "image/jpeg": "/9j/4AAQSkZJRgABAQAAlgCWAAD/4QCARXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAACWAAAAAQAAAJYAAAABAAKgAgAEAAAAAQAAASygAwAEAAAAAQAAAO8AAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/iEaxJQ0NfUFJPRklMRQABAQAAEZxhcHBsAgAAAG1udHJHUkFZWFlaIAfcAAgAFwAPAC4AD2Fjc3BBUFBMAAAAAG5vbmUAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtYXBwbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWRlc2MAAADAAAAAeWRzY20AAAE8AAAIGmNwcnQAAAlYAAAAI3d0cHQAAAl8AAAAFGtUUkMAAAmQAAAIDGRlc2MAAAAAAAAAH0dlbmVyaWMgR3JheSBHYW1tYSAyLjIgUHJvZmlsZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAB8AAAAMc2tTSwAAAC4AAAGEZGFESwAAADoAAAGyY2FFUwAAADgAAAHsdmlWTgAAAEAAAAIkcHRCUgAAAEoAAAJkdWtVQQAAACwAAAKuZnJGVQAAAD4AAALaaHVIVQAAADQAAAMYemhUVwAAABoAAANMa29LUgAAACIAAANmbmJOTwAAADoAAAOIY3NDWgAAACgAAAPCaGVJTAAAACQAAAPqcm9STwAAACoAAAQOZGVERQAAAE4AAAQ4aXRJVAAAAE4AAASGc3ZTRQAAADgAAATUemhDTgAAABoAAAUMamFKUAAAACYAAAUmZWxHUgAAACoAAAVMcHRQTwAAAFIAAAV2bmxOTAAAAEAAAAXIZXNFUwAAAEwAAAYIdGhUSAAAADIAAAZUdHJUUgAAACQAAAaGZmlGSQAAAEYAAAaqaHJIUgAAAD4AAAbwcGxQTAAAAEoAAAcuYXJFRwAAACwAAAd4cnVSVQAAADoAAAekZW5VUwAAADwAAAfeAFYBYQBlAG8AYgBlAGMAbgDhACAAcwBpAHYA4QAgAGcAYQBtAGEAIAAyACwAMgBHAGUAbgBlAHIAaQBzAGsAIABnAHIA5QAgADIALAAyACAAZwBhAG0AbQBhAC0AcAByAG8AZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBvAHMAIABnAGUAbgDoAHIAaQBjAGEAIAAyAC4AMgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBtACAAQwBoAHUAbgBnACAARwBhAG0AbQBhACAAMgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIAaQBjAG8AIABkAGEAIABHAGEAbQBhACAAZABlACAAQwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsETAQ9BDAAIABHAHIAYQB5AC0EMwQwBDwEMAAgADIALgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1AGUAIABnAHIAaQBzACAAZwBhAG0AbQBhACAAMgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/AByAGsAZQAgAGcAYQBtAG0AYQAgADIALgAykBp1KHBwlo5RSV6mADIALgAygnJfaWPPj/DHfLwYACDWjMDJACCsELnIACAAMgAuADIAINUEuFzTDMd8AEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAZwBhAG0AbQBhACAAMgAsADIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A4QAgAWEAZQBkAOEAIABnAGEAbQBhACAAMgAuADIF0gXQBd4F1AAgBdAF5AXVBegAIAXbBdwF3AXZACAAMgAuADIARwBhAG0AYQAgAGcAcgBpACAAZwBlAG4AZQByAGkAYwEDACAAMgAsADIAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAtAFAAcgBvAGYAaQBsACAARwBhAG0AbQBhACAAMgAsADIAUAByAG8AZgBpAGwAbwAgAGcAcgBpAGcAaQBvACAAZwBlAG4AZQByAGkAYwBvACAAZABlAGwAbABhACAAZwBhAG0AbQBhACAAMgAsADIARwBlAG4AZQByAGkAcwBrACAAZwByAOUAIAAyACwAMgAgAGcAYQBtAG0AYQBwAHIAbwBmAGkAbGZukBpwcF6mfPtlcAAyAC4AMmPPj/Blh072TgCCLDCwMOwwpDCsMPMw3gAgADIALgAyACAw1zDtMNUwoTCkMOsDkwO1A70DuQO6A8wAIAOTA7oDwQO5ACADkwOsA7wDvAOxACAAMgAuADIAUABlAHIAZgBpAGwAIABnAGUAbgDpAHIAaQBjAG8AIABkAGUAIABjAGkAbgB6AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBtAG0AYQAgADIALAAyAEEAbABnAGUAbQBlAGUAbgAgAGcAcgBpAGoAcwAgAGcAYQBtAG0AYQAgADIALAAyAC0AcAByAG8AZgBpAGUAbABQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBtAG0AYQAgAGQAZQAgAGcAcgBpAHMAZQBzACAAMgAsADIOIw4xDgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4iDkwOFw4xDkgOJw5EDhsAIAAyAC4AMgBHAGUAbgBlAGwAIABHAHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZAGwAZQBpAG4AZQBuACAAaABhAHIAbQBhAGEAbgAgAGcAYQBtAG0AYQAgADIALAAyACAALQBwAHIAbwBmAGkAaQBsAGkARwBlAG4AZQByAGkBDQBrAGkAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABwAHIAbwBmAGkAbABVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBmAGkAbAAgAHMAegBhAHIAbwFbAGMAaQAgAGcAYQBtAG0AYQAgADIALAAyBjoGJwZFBicAIAAyAC4AMgAgBkQGSAZGACAGMQZFBicGLwZKACAGOQYnBkUEHgQxBEkEMARPACAEQQQ1BEAEMARPACAEMwQwBDwEPAQwACAAMgAsADIALQQ/BEAEPgREBDgEOwRMAEcAZQBuAGUAcgBpAGMAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABQAHIAbwBmAGkAbABlAAB0ZXh0AAAAAENvcHlyaWdodCBBcHBsZSBJbmMuLCAyMDEyAABYWVogAAAAAAAA81EAAQAAAAEWzGN1cnYAAAAAAAAEAAAAAAUACgAPABQAGQAe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"
    }
   },
   "cell_type": "markdown",
   "id": "36020075",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## In-Class Coding Activity: Infinite Monkey Theorem\n",
    "\n",
    "_A monkey hitting random keys on a typewriter for an infinite amount of time will eventually type the complete works of Shakespeare._\n",
    "\n",
    "![Chimpanzee_seated_at_typewriter.jpg](attachment:Chimpanzee_seated_at_typewriter.jpg)\n",
    "\n",
    "\n",
    "\n",
    "You are going to write some functions which simulate this. If we generate a bunch of random strings, how close will they get to a line of Shakespeare?\n",
    "\n",
    "After class, copy whatever code your group worked on, and put it into file called `infinite_monkey.py`, and continue working through the problems on your own computer - the result will be submitted for __Assignment 2__.\n",
    "\n",
    "This exercise is adapted from the example in Section 1.12 of the book, though note that the specific expectations of how each function works are different."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8866bcb2",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Group Activity Problem 1\n",
    "\n",
    "Run the following code example. In the notes section below, describe what the code does. Also, answer the following questions in the notes: What happens when you change the 9 to a different number? What is the type of `alphabet`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "854a357d",
   "metadata": {},
   "outputs": [],
   "source": [
    "alphabet = \"abcdefghijklmnopqrstuvwxyz \"\n",
    "print( alphabet[9] )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4259bd08",
   "metadata": {},
   "source": [
    "### Notes: \n",
    "\n",
    "_write your notes here_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b8cdb1f",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Group Activity Problem 2\n",
    "\n",
    "Run the following code example multiple times. In the notes section below, describe what the code does. Also, answer the following questions in the notes: What is the purpose of the import statement? Is it possible for a 26 to be printed by this code? What happens when you change the 26 to a different number?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b908f8b2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "print( random.randint(0,26) )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e233fb3",
   "metadata": {},
   "source": [
    "### Notes: \n",
    "\n",
    "_write your notes here_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "561ad8bf",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Group Activity Problem 3\n",
    "\n",
    "Run the following code example multiple times. In the notes section below, describe what the code does. Also, answer the following questions in the notes: What effect would changing the 26 to a different number have on this code? Is there a better way to write this code that avoids having to hard-code the literal 26 into the code?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7118ad03",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "alphabet = \"abcdefghijklmnopqrstuvwxyz \"\n",
    "print( alphabet[ random.randint(0,26) ] )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4895812d",
   "metadata": {},
   "source": [
    "### Notes: \n",
    "\n",
    "_write your notes here_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8dc4d60f",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Group Activity Problem 4\n",
    "\n",
    "The code below turns the above code into a function. Write the function call that will cause this function to run multiple times. Notice that this function prints its result, but to be more useful, it should instead return it. Go ahead and fix that, and then adjust your call to the function so that it will print the returned value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f827b2e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "def random_letter():\n",
    "    alphabet = \"abcdefghijklmnopqrstuvwxyz \"\n",
    "    print( alphabet[ random.randint(0,26) ] )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87ce15e7",
   "metadata": {},
   "source": [
    "### Notes: \n",
    "\n",
    "_write your notes here_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7edb75ec",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Group Activity Problem 5\n",
    "\n",
    "Run the following code example multiple times. In the notes section below, describe what the code does. Also, answer the following questions in the notes: What effect does changing the number 28 to another number have? What is the type of the `random_string` variable? What is the purpose of the `+=` operator in this code?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "05133ba3",
   "metadata": {},
   "outputs": [],
   "source": [
    "random_string = \"\"\n",
    "for i in range(28):\n",
    "    random_string += random_letter()\n",
    "print(random_string)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d304be10",
   "metadata": {},
   "source": [
    "### Notes: \n",
    "\n",
    "_write your notes here_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc409b9f",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Group Activity Problem 6\n",
    "\n",
    "Create a function called `random_text` based on the code from the previous problem. It should allow a number to be passed to the function as an __argument__, and it should __return__ a random string with that many characters in it. It should work if we test it with some code like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "37f97cc7",
   "metadata": {},
   "outputs": [],
   "source": [
    "#write your code for the definition of the random_text function here\n",
    "\n",
    "print( random_text(28) ) #generates random text with 28 characters in it, e.g., lzqnnzantpgfmmkziadskr tzwez\n",
    "print( random_text(5) ) #generates random text with 5 characters in it, e.g., bnhou\n",
    "print( random_text(50) ) #e.g., hiep hwx tfkvbjjyqycaefvsbqipaylnqeiujhccvvpvelsxk"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8ead68f9",
   "metadata": {},
   "source": [
    "### Notes: \n",
    "\n",
    "_write your notes here_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e3004b9",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Group Activity Problem 7\n",
    "\n",
    "Write a function called `score` that will tell us how close some random text is to some goal text. It should work as follows:\n",
    "\n",
    "* take two arguments with strings to be compared\n",
    "* loop through the indexes of one of the strings (you can assume the two strings have the same length)\n",
    "* compare each character in one string to the corresponding character in the other string\n",
    "* add 1 to an accumulator variable when you find the same letter at the same position in both strings\n",
    "* return the number of characters that match\n",
    "\n",
    "You should be able to call it like this"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fa337db6",
   "metadata": {},
   "outputs": [],
   "source": [
    "#write your code for the definition of the score function here\n",
    "\n",
    "print( score(\"test string 1\",\"test string 2\") )  #should print 12\n",
    "\n",
    "goal_shakespeare = \"methinks it is like a weasel\"\n",
    "random_test_string = random_text(len(goal_shakespeare)) #generate a random string with the same length as the goal string\n",
    "print( score(random_test_string, goal_shakespeare) ) #print how many characters they have in common"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc02d783",
   "metadata": {},
   "source": [
    "### Notes: \n",
    "\n",
    "_write your notes here_"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cefdccb3",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Group Activity Problem 8\n",
    "\n",
    "Write a function called `monkey_experiment` that takes in a goal string (e.g., `\"methinks it is like a weasel\"`) and a number of iterations as an argument. Run the experiment for that many iterations, and return a tuple with the highest-scoring text that was generated along with the score that it got.\n",
    "\n",
    "That is, your function should have a loop that does something like this many many times (i.e., the number of times that is passed in as an argument):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84267d36",
   "metadata": {},
   "outputs": [],
   "source": [
    "random_test_string = random_text(len(goal_shakespeare))\n",
    "print( score(random_test_string, goal_shakespeare) ) "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0024cbd4",
   "metadata": {},
   "source": [
    "__Hint:__ You should have a variable for keeping track of the best score you've found so far, and another variable for saving the string that is associated with that best score. Whenever you find one with a better score, update these variables."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41c0f334",
   "metadata": {},
   "source": [
    "You should also test your function with several different goal strings and numbers of iterations - something like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "77abc593",
   "metadata": {},
   "outputs": [],
   "source": [
    "#write your code for the definition of the monkey_experiment function here\n",
    "\n",
    "print(monkey_experiment(\"methinks it is like a weasel\",100000))\n",
    "print(monkey_experiment(\"methinks it is like a weasel\",100))\n",
    "print(monkey_experiment(\"brevity is the soul of wit\",100000))\n",
    "print(monkey_experiment(\"to be\",100000))\n",
    "print(monkey_experiment(\"to be\",200000))\n",
    "print(monkey_experiment(\"to be\",500000))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1c85d62",
   "metadata": {},
   "source": [
    "When I tested my function, I got results that look like this for the above tests:\n",
    "\n",
    "```\n",
    "('yetha  xqtynpxgfkkoaedweasf ', 8)\n",
    "('ktsnmgoknxlkldupuce jgvnaael', 5)\n",
    "('vfcmitu emgthe h svidavhhs', 7)\n",
    "('lo be', 4)\n",
    "('tf by', 3)\n",
    "('toube', 4)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb922238",
   "metadata": {},
   "source": [
    "### Notes: \n",
    "\n",
    "_write your notes here_"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Attachments",
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.10.6"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
