From b1ea020901ba461f9ea40641678264a665cb05cb Mon Sep 17 00:00:00 2001 From: Woose Date: Mon, 27 Jan 2025 15:28:32 +0300 Subject: [PATCH] update --- module5.ipynb | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/module5.ipynb b/module5.ipynb index 280f5e7..a9f2444 100644 --- a/module5.ipynb +++ b/module5.ipynb @@ -558,6 +558,199 @@ " f.close() \n", " return characters" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Raising errors" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#!/usr/bin/env python3\n", + "def validate_user(username, minlen):\n", + " if minlen < 1:\n", + " raise ValueError(\"minlen must be at least 1\")\n", + " if len(username) < minlen:\n", + " return False\n", + " if not username.isalnum():\n", + " return False\n", + " return True\n", + "\n", + "from validations import validate_user\n", + "validate_user(\"\", -1)\n", + "\n", + "from validations import validate_user\n", + "validate_user(\"\", 1)\n", + "validate_user(\"myuser\", 1)\n", + "\n", + "from validations import validate_user\n", + "validate_user(88, 1)\n", + "\n", + "from validations import validate_user\n", + "validate_user([], 1)\n", + "\n", + "from validations import validate_user\n", + "validate_user([\"name\"], 1)\n", + "\n", + "#!/usr/bin/env python3\n", + "def validate_user(username, minlen):\n", + " assert type(username) == str, \"username must be a string\"\n", + " if minlen < 1:\n", + " raise ValueError(\"minlen must be at least 1\")\n", + " if len(username) < minlen:\n", + " return False\n", + " if not username.isalnum():\n", + " return False\n", + " return True\n", + "\n", + " from validations import validate_user\n", + "validate_user([3], 1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Testing for expected errors" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#!/usr/bin/env python3\n", + "import unittest\n", + "from validations import validate_user\n", + "class TestValidateUser(unittest.TestCase):\n", + " def test_valid(self):\n", + " self.assertEqual(validate_user(\"validuser\", 3), True)\n", + " def test_too_short(self):\n", + " self.assertEqual(validate_user(\"inv\", 5), False)\n", + " def test_invalid_characters(self):\n", + " self.assertEqual(validate_user(\"invalid_user\", 1), False)\n", + " def test_invalid_minlen(self):\n", + " self.assertRaises(ValueError, validate_user, \"user\", -1)\n", + "# Run the tests\n", + "unittest.main()\n", + "\n", + "./validations_test.py" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Exception handling**\n", + "\n", + "When performing exception handling, it is important to predict which exceptions can happen. Sometimes, to figure out which exceptions you need to account for, you have to let your program fail.\n", + "The simplest way to handle exceptions in Python is by using the try and except clauses. \n", + "In the try clause, Python executes all statements until it encounters an exception. You use the except clause to catch and handle the exception(s) that Python encounters in the try clause.\n", + "Here is the process for how it works: \n", + "1. Python runs the try clause, e.g., the statement(s) between the try and except keywords.\n", + "2. If no error occurs, Python skips the except clause and the execution of the try statement is finished.\n", + "3. If an error occurs during execution of the try clause, Python skips the rest of the try clause and transfers control to the corresponding except block. If the type of error matches what is listed after the except keyword, Python executes the except clause. The execution then continues on after the try/except block.\n", + "4. If an exception occurs but it does not match what is listed in the except clause, it is passed onto try statements outside of that try/except block. However, if a handler for that exception cannot be found, the exception becomes an unhandled exception, the execution stops, and Python displays a designated error message. \n", + "\n", + "Sometimes, a try statement can have more than one except clause so that the code can specify handlers for different exceptions. This can help to reduce the number of unhandled exceptions.\n", + "\n", + "You can use exceptions to catch almost everything. It is good practice as a developer or programmer to be as specific as possible with the types of exceptions that you intend to handle, especially if you’re creating your own exceptions. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Raise exceptions**\n", + "\n", + "As a developer or programmer, you might want to raise an error yourself. Usually, this happens when some of the conditions necessary for a function to do its job properly aren't met and returning none or some other base value isn't good enough. You can raise an error or raise an exception (also known as “throwing an exception”), which forces a particular exception to occur, and notifies you that something in your code is going wrong or an error has occurred. \n", + "\n", + "Here are some instances where raising an exception is a useful tool:\n", + "- A file doesn’t exist\n", + "- A network or database connection fails\n", + "- Your code receives invalid input\n", + "\n", + "In the example below, the code raises two built-in Python exceptions: raise ValueError and raise ZeroDivisionError. You can find more information on these raises in the example below, along with explanations of potential errors that may occur during an exception." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# File reading function with exception handling\n", + "def read_file(filename):\n", + "\ttry:\n", + "\t\twith open(filename, 'r') as f:\n", + "\t\t\treturn f.read()\n", + "\texcept FileNotFoundError:\n", + "\t\treturn \"File not found!\"\n", + "\tfinally:\n", + "\t\tprint(\"Finished reading file.\")\n", + "\n", + "def faulty_read_and_divide(filename):\n", + "\twith open(filename, 'r') as file:\n", + "\t\tdata = file.readlines()\n", + "\t\tnum1 = int(data[0])\n", + "\t\tnum2 = int(data[1])\n", + "\t\treturn num1 / num2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def enhanced_read_and_divide(filename):\n", + "\ttry:\n", + "\t\twith open(filename, 'r') as file:\n", + "\t\t\tdata = file.readlines()\n", + " # Ensure there are at least two lines in the file\n", + " if len(data) < 2:\n", + " raise ValueError(\"Not enough data in the file.\")\n", + " num1 = int(data[0])\n", + " num2 = int(data[1])\n", + " # Check if second number is zero\n", + " if num2 == 0:\n", + " raise ZeroDivisionError(\"The denominator is zero.\")\n", + " return num1 / num2\n", + "\texcept FileNotFoundError:\n", + " return \"Error: The file was not found.\"\n", + "\texcept ValueError as ve:\n", + " return f\"Value error: {ve}\"\n", + "\texcept ZeroDivisionError as zde:\n", + " return f\"Division error: {zde}\"\n", + "\n", + "# The errors should read:\n", + "# File-level issues:\n", + "# Value error: Not enough data in the file.\n", + "# Error: The file was not found.\n", + "# Data-level issues: Value error: invalid literal for int() with base 10: 'apple'\n", + "# Division error: The denominator is zero." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**assert statements**\n", + "\n", + "assert statements help you to verify if a certain condition is met and throw an exception if it isn’t. As is stated in the name, their purpose is to \"assert\" that certain conditions are true at specific points in your program. \n", + "\n", + "The assert statement exists in almost every programming language and has two main uses:\n", + "\n", + "- To help detect problems earlier in development, rather than later when some other operation fails. Problems that aren’t addressed until later in the development process can turn out to be more time-intensive and costly to fix.\n", + "- To provide a form of documentation for other developers reading the code." + ] } ], "metadata": {