{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Python 101\n", "## Part V.\n", "\n", "---\n", "\n", "## Objects, Exceptions and Exercises\n", "\n", "\n", "## 1. Objects\n", "\n", "### Basics\n", "\n", "In Python, everything is an \"object\". So when you create a variable, you actually created an object. The object you create is used to store values (called attributes) and have special functions (called methods) which interacts with the object's values. You can even create your own objects, by defining a \"class\".\n", "\n", "A class describes the object you will create and will determine what it can do. You manipulate the objects by calling their methods and setting their attributes to achieve the desired outcome.\n", "\n", "The process described above is a programming style - a programming paradigm, called Object Oriented Programming (OO). It is one of the main paradigms. Our previous codes were created using the Imperative paradigm.\n", "\n", "### Workflow:\n", "\n", "- Define a class" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class MyClass:\n", " attribute = 1\n", " def method(self):\n", " print('Hello World!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Initialize an object" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "myobject = MyClass()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Access the values you set in the class definition by using the `object_name.attribute_name` statement:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(myobject.attribute)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Execute the functions from your class definition in the same way:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "myobject.method()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_Basically, the __class is the blueprint__ and the __object is the product__._ \n", "Just like a car factory uses the plans of a car to manufacture cars:\n", "\n", "![car_factory](pics/car_object_factory.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Use case\n", "\n", "We want our webshop to handle customers who has names, emails (attributes) and can order items or cancel their orders (methods).\n", "\n", "![object_use_case](pics/object_use_case.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### From our perspective\n", "\n", "Objects are integral parts of the Python language, so we'll use them all the time. Most of the 3rd party libraries rely on their special objects which we'll use in order to access the library's features.\n", "\n", "We could also create objects of our own, if you are interested in the topic [this notebook](./python101_06.ipynb) has detailed explanation, examples and exercises." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Exceptions\n", "\n", "### Errors\n", "\n", "If the code is syntactically incorrect the interpreter won't be able to execute it. -> You'll get a syntax error." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "while True print('Hello world')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exceptions\n", "\n", "If the code is syntactically correct unexpected events can still happen during execution, and the program will terminate like this:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " return num1 / num2\n", "\n", "print(divide(2, 1))\n", "print(divide(1, 0))\n", "print(divide(3, 2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, dividing by zero is not possible, so a ZeroDivisionError emerged and our program stopped. Our program shouldn't stop running, so we have to handle these cases! -> Let's use Exceptions!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " # in order to catch the errors, we need to use the try except structure:\n", " try:\n", " # we try to do something\n", " return num1 / num2\n", " # in case an exception happened, handle it!\n", " except ZeroDivisionError:\n", " print('Dividing by zero is not possible!')\n", " return 0\n", " \n", "print(divide(2, 1))\n", "print(divide(1, 0))\n", "print(divide(3, 2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ZeroDivisionError is a subclass of the Exception class. There are many different type of Exceptions." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " try:\n", " return num1 / num2\n", " except ZeroDivisionError:\n", " print('Dividing by zero is not possible!')\n", " return 0\n", " \n", "print(divide(1, 0))\n", "# for example this will cause a different type of exception:\n", "print(divide(3, '2'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like the TypeError. We cannot divide a number with a string. Let's fix it!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " try:\n", " return num1 / num2\n", " except ZeroDivisionError:\n", " print('Dividing by zero is not possible!')\n", " return 0\n", " # we can have as many except branch as many we want!\n", " except TypeError:\n", " print('Numbers can only be divided by numbers!')\n", " return 0\n", " \n", "print(divide(1, 0))\n", "print(divide(3, '2'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also merge multiple exceptions into one:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " try:\n", " return num1 / num2\n", " except (ZeroDivisionError, TypeError):\n", " print('ERROR!')\n", " return 0\n", " \n", "print(divide(1, 0))\n", "print(divide(3, '2'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Other exception types:\n", "\n", "- ValueError" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " print(int('string'))\n", "except ValueError:\n", " print('This string is not a number!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- NameError " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " print(spam)\n", "except NameError:\n", " print('There is no such thing as \\'spam\\'!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- IndexError" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " mylist = [1, 2, 3]\n", " print(mylist[len(mylist)])\n", "except IndexError:\n", " print('Index is larger then the length of the list!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- KeyError" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " mydict = {'a': 1, 'b': 2}\n", " print(mydict['c'])\n", "except KeyError:\n", " print('Key not exists!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- IOError" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " not_existing_filename = 'a_file_that_is_not_exists.txt'\n", " myfile = open(not_existing_filename, 'r')\n", " myfile.readlines()\n", "except IOError:\n", " print('The specified file does not exist!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__BAD PRACTICE__: \n", "\n", "we can catch every exception, if we're not specifically tell the program which one we want to handle:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " try:\n", " return num1 / num2\n", " except:\n", " print('ERROR!')\n", " return 0\n", " \n", "print(divide(1, 0))\n", "print(divide(3, '2'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's really bad, because we don't know what caused the problem. But at least we can get the details:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " try:\n", " return num1 / num2\n", " except Exception as e:\n", " print('ERROR!', type(e))\n", " return 0\n", " \n", "print(divide(1, 0))\n", "print(divide(3, '2'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can even invoke Exceptions:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def awesome_function():\n", " # you can invoke an Exception with the raise keyword\n", " # use this Exception if you havent implemented a function yet\n", " raise NotImplementedError(\"You've got to wait buddy!\")\n", "\n", " \n", "def foo(number):\n", " if number != 2:\n", " # general exception\n", " raise Exception('This number is not 2!')\n", " \n", " \n", "try:\n", " awesome_function()\n", "except NotImplementedError:\n", " print('This method is not yet implemented!')\n", " \n", " \n", "try:\n", " foo(3)\n", "except Exception as e:\n", " # print the \n", " # - type of the Exception\n", " print(type(e))\n", " # - arguments of the Exception\n", " print(e.args)\n", " # - arguments of the Exception as string\n", " print(e)\n", " arg = e.args\n", " # - arguments of the Exception saved in a variable\n", " print(arg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we want to execute something only if no Exceptions were raised, we can use the else statement." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " try:\n", " result = num1 / num2\n", " except ZeroDivisionError:\n", " print('Cannot divide by Zero!')\n", " else:\n", " print(num1, '/', num2, '=' , result)\n", " \n", "divide(2, 0)\n", "divide(2, 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also add a cleanup method as well:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def divide(num1, num2):\n", " try:\n", " result = num1 / num2\n", " except ZeroDivisionError:\n", " print('Cannot divide by Zero!')\n", " else:\n", " print(num1, '/', num2, '=' , result)\n", " finally:\n", " print('finished running')\n", " \n", "divide(2, 0)\n", "divide(2, 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## Let's do some...\n", "\n", "\n", "
\n", "\n", "### Not so Cool library of the week: Turtle\n", "#### Draw with a \"turtle\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import turtle" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "turtle.color('red', 'yellow')\n", "turtle.begin_fill()\n", "while True:\n", " turtle.forward(200)\n", " turtle.left(170)\n", " if abs(turtle.pos()) < 1:\n", " break\n", "turtle.end_fill()\n", "turtle.done()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Exercises\n", "Selected from [Tanuljunk meg programozni python nyelven](http://mek.oszk.hu/08400/08435/08435.pdf) from Gérard Swinnen.\n", "\n", "---\n", "\n", "### 1. Write a function that transforms a given amount of seconds into years, months, hours, minutes and seconds.\n", "\n", "Example: input: 311 --> output: 0 years, 0 months, 0 days, 0 hours, 5 minutes, 11 seconds\n", "\n", "Hint: `%`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. Write a function that prints the multiplication table of number 7 (first 20 elements are enough, but we dare you to test the limitations of your computer). Elements that are also divisible by 3 should get a * label.\n", "Example: `7 14 21 * 28 35 42 * 49 ...`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3. Write a function that calculates the first 50 elements of the multiplication table of number 13 and prints the ones that are divisible by 7." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4. Write a function which prints \"the half of a christmas tree\" with your code:\n", "```\n", "*\n", "**\n", "***\n", "****\n", "*****\n", "******\n", "*******\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.a Extend the previous function with the height parameter with which the number of rows can be set." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.b Instead of half tree, display an arbitrary sized full tree\n", "\n", "Hint: \n", "```python\n", "'*'.center(width=3)\n", ">\" * \"\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 4.c Instead of a tree, create an arbitrarily sized (only odd numbers are accepted) diamond shape.\n", "\n", "Example: \n", "- `size=3` should display: \n", "\n", "```\n", " * \n", "***\n", " * \n", "```\n", "\n", "- `size=5` should display: \n", "\n", "```\n", " * \n", " ***\n", "*****\n", " ***\n", " *\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5. Write a function that decides whether a string contains the character `« e »` or not." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 6. Write a function that transforms text into \"szögödi\" dialect. It should replace all the `« e »` characters in a string with `« ö »`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 7. Getting tired of `« e »` characters? Naah, one more: write a function that counts the number of `« e »` characters in a string." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 8. Write a function that inserts a * between every two characters in a string.\n", "\n", "Example: `gaston` > `g*a*s*t*o*n`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 9. Write a function that prints a string in reverse order.\n", "Example: `live` > `evil`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 10. Write a function that decides whether a string is [palindrome](https://en.wikipedia.org/wiki/Palindrome) or not.\n", "Example: `python` > False, `mom` > True" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 10.a Extend the previous function to work with sentences as well (ignore casing, whitespace or symbols).\n", "\n", "Examples:\n", "- `Was it a car or a cat I saw?` > True\n", "- `Are we not pure? “No, sir!” Panama’s moody Noriega brags. “It is garbage!” Irony dooms a man—a prisoner up to new era.` > True\n", "- `Random not palindrome sentence` > False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 11. Combine two lists into a third one like in the following example:\n", "`t1 = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]` \n", "`t2 = ['January', 'February', 'March', 'April', 'May', 'June',\n", " 'July', 'August', 'September', 'Okteber', 'November', 'December']`\n", " \n", "t3 should look like: `['January',31,'February',28,'March',31, ...].`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 12. Given a list of numbers, create two separate list; one containing the even numbers, the other the odd numbers.\n", "\n", "Example:\n", "From `[32, 5, 12, 8, 3, 75, 2, 15]` the program should create `[32, 12, 8, 2]` and `[5, 3, 75, 15]`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 13. Write a function that decides whether a given year is leap year or not.\n", "\n", "From [wiki](https://en.wikipedia.org/wiki/Leap_year#Gregorian_calendar):\n", "> Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400. For example, the years 1700, 1800, and 1900 were not leap years, but the years 1600 and 2000 were." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 14. Write a `generate(n, char)` function that has two inputs: `n` and `char`. The output should be a string which contains `char` ,`n` times." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 15. Write a function called `count_char` that has two inputs :`char`, `string`. The output should be the number of appearances of `char` in `string`.\n", "\n", "Example: \n", "```python\n", "print(count_char('e', 'easy peasy'))\n", "> 2\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 16. Write a function to play the \"Guess the number\" game\n", "\n", "Example: \n", "```python\n", "print(guess_a_number(from_number=1, to_number=10))\n", "> Guess: \n", "[5]\n", "> Lower, guess again: \n", "[3]\n", "> Congratulations, you won!\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 17. Write a function to play the \"Guess the number\" game which handle erroneous inputs\n", "\n", "Example: \n", "```python\n", "print(guess_a_number(from_number=1, to_number=10))\n", "> Guess: \n", "[apple]\n", "> That's not a number, guess again:\n", "[15]\n", "> Number out of range, guess again: \n", "[5]\n", "> Lower, guess again: \n", "[3]\n", "> Congratulations, you won!\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.8.10" } }, "nbformat": 4, "nbformat_minor": 2 }