{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-df7302b349aba739",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "# Classes in Python\n",
    "\n",
    "First, let's consider some data in a plain Python dictionary:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-5eb4e7d87487b636",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "car1 = {\n",
    "    'name': 'Fer',\n",
    "    'worth': 60000,\n",
    "    'type_': 'convertible',\n",
    "    'color': 'red'\n",
    "}\n",
    "car2 = {\n",
    "    'name': 'Jump',\n",
    "    'worth': 10000,\n",
    "    'type_': 'van',\n",
    "    'color': 'blue'\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-b6fe8f994da7634c",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Fer'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "car1['name']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-2b0e27117c238bca",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "Now, let's make a Python class which will hold this same kind of data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-17b8022fd73e630c",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "class Car:\n",
    "    def __init__(self,name,worth,type_,color):\n",
    "        self.name = name\n",
    "        self.worth = worth\n",
    "        self.type_ = type_\n",
    "        self.color = color\n",
    "    def print_car(self):\n",
    "        print(\"%s is worth %d and is a %s %s.\"%(self.name, self.worth, self.color, self.type_))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-98bd27b61013b730",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "car1 = Car(\"Fer\",60000,\"convertible\",\"red\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-1055b5581d221586",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "## Takeaway message\n",
    "\n",
    "- The data in an instances of a class are conceptually very similar to python dicts with a few special features. One of these special features is methods. Another is that you access instance variables with with the `x_instance.name` syntax instead of `x_dict['name']` syntax."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-ce0b6c546e3ec2d5",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "## Q1 creating an instance of a class\n",
    "\n",
    "We have a class defined for vehicles. Create two new vehicles (\"instances of the class\") with the variable names `car1` and `car2`. Set car1 to be a red convertible worth EUR 60,000.00 with a name of Fer, and car2 to be a blue van named Jump worth EUR 10,000.00."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-ae7291a16e80887f",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "class Vehicle:\n",
    "    def __init__(self, color, worth, name):    \n",
    "        self.color = color\n",
    "        self.worth = worth\n",
    "        self.name = name\n",
    "    def get_description(self):\n",
    "        return 'name: {}, worth: {}, color: {}'.format(self.name, self.worth, self.color)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-3f2711d5634d8201",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "car1 = Vehicle('red', 60000, 'Fer')\n",
    "car2 = Vehicle('blue', 10000, 'Jump')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "nbgrader": {
     "grade": true,
     "grade_id": "cell-081ffcbe096c0760",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# This checks if your code works. Do not change it. It should run without error.\n",
    "assert( car1.get_description()==\"name: Fer, worth: 60000, color: red\" )\n",
    "assert( car2.get_description()==\"name: Jump, worth: 10000, color: blue\" )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-634909b4b67c316a",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "## Q2 creating a class\n",
    "\n",
    "Create a class called `Pet`. The `__init__` function should take 3 arguments: `self`, `name`, and `sound`. The `name`, and `sound` arguments should be assigned to the instance variables `self.name` and `self.sound`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-6976ffa1c6d95602",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "class Pet:\n",
    "    def __init__(self, name, sound):\n",
    "        self.name = name\n",
    "        self.sound = sound"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "nbgrader": {
     "grade": true,
     "grade_id": "cell-c49bb38441eca03a",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# This checks if your code works. Do not change it. It should run without error.\n",
    "my_pet = Pet('Bob', 'talk')\n",
    "assert(my_pet.name=='Bob')\n",
    "assert(my_pet.sound=='talk')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-f34bb63b09eccd59",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "## Q3 writing a method\n",
    "\n",
    "Now, create a new class called `NoisyPet`. The `__init__` function should be like in `Pet`. (It takes 3 arguments: `self`, `name`, and `sound`. The `name`, and `sound` arguments should be assigned to the instance variables `self.name` and `self.sound`.)\n",
    "\n",
    "`NoisyPet` should have an additional method called `make_noise` which takes zero additional arguments (of course `self` is required). The `make_noise` for a name of `\"cricket\"` and sound of `\"chirp\"`, this method should return a string like `\"My pet cricket makes a noise like chirp\"`. Thus, you will need to return a string you have created using string formatting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-30ebdf29d3de2e41",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "class NoisyPet:\n",
    "    def __init__(self, name, sound):\n",
    "        self.name = name\n",
    "        self.sound = sound\n",
    "    def make_noise(self):\n",
    "        return \"My pet {} makes a noise like {}\".format(self.name, self.sound)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "nbgrader": {
     "grade": true,
     "grade_id": "cell-232b938072cf100c",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# This checks if your code works. Do not change it. It should run without error.\n",
    "assert(NoisyPet(\"cricket\", \"chirp\").make_noise()==\"My pet cricket makes a noise like chirp\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-ded0dd503cbcd3b7",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "## Q4 using instances 1\n",
    "\n",
    "Now create a list named `my_pets` with 5 instances of the NoisyPet class given the following names and noises.\n",
    "\n",
    "| name | noise |\n",
    "| --- | --- |\n",
    "| Fido | slobber |\n",
    "| Mr. Skinny Legs | (silent) |\n",
    "| cricket | chirp |\n",
    "| Adelheid | cackle |\n",
    "| Bello | bark |"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-9e7de69ef49036d8",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "my_pets = [\n",
    "    NoisyPet(\"Fido\", \"slobber\"),\n",
    "    NoisyPet(\"Mr. Skinny Legs\", \"(silent)\"),\n",
    "    NoisyPet(\"cricket\", \"chirp\"),\n",
    "    NoisyPet(\"Adelheid\", \"cackle\"),\n",
    "    NoisyPet(\"Bello\", \"bark\"),\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "nbgrader": {
     "grade": true,
     "grade_id": "cell-ef3307b4ff8e4134",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# This checks if your code works. Do not change it. It should run without error.\n",
    "assert(type(my_pets)==list)\n",
    "assert(len(my_pets)==5)\n",
    "for my_pet in my_pets:\n",
    "    assert(isinstance(my_pet,NoisyPet))\n",
    "    my_pet.make_noise()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-7f3ab5609b4c6d4b",
     "locked": true,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "source": [
    "## Q5 using instances 2\n",
    "\n",
    "Now create a function list named `get_pet_name_length` which takes a single argument, which is an instance of the NoisyPet class. It should return the number of letters in the pet's name."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "nbgrader": {
     "grade": false,
     "grade_id": "cell-4fb1927bd55587b9",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "def get_pet_name_length(pet):\n",
    "    return len(pet.name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "nbgrader": {
     "grade": true,
     "grade_id": "cell-adabc63962b7ba48",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    }
   },
   "outputs": [],
   "source": [
    "# This checks if your code works. Do not change it. It should run without error.\n",
    "assert(get_pet_name_length(NoisyPet(\"Bello\", \"bark\"))==5)\n",
    "assert(get_pet_name_length(NoisyPet(\"cricket\", \"chirp\"))==7)"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Create Assignment",
  "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.11.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
