Skip to content

Commit

Permalink
minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidLeoni committed Dec 26, 2019
1 parent 7af10c5 commit 0133453
Showing 1 changed file with 52 additions and 37 deletions.
89 changes: 52 additions & 37 deletions exercises/errors-and-testing/errors-and-testing-solution.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"\n",
"In this notebook we will try to understand what our program should do when it encounters unforeseen situations, and how to test the code we write. In particular, we will describe the exercise format as proposed in Part A and in Part B (they are different!)\n",
"\n",
"For some strange reason, many people believe that computer programs do not need much error handling nor testing. Just to make a simple comparison, wuold you ever drive a car that did not undergo scrupolous checks? We wouldn't.\n",
"For some strange reason, many people believe that computer programs do not need much error handling nor testing. Just to make a simple comparison, would you ever drive a car that did not undergo scrupolous checks? We wouldn't.\n",
"\n"
]
},
Expand Down Expand Up @@ -96,7 +96,7 @@
"\n",
"## Unforeseen situations\n",
"\n",
"It is evening, there is to party for a birthday and they asked you to make a pie. I know you need the following steps:\n",
"It is evening, there is to party for a birthday and they asked you to make a pie. You need the following steps:\n",
"\n",
"\n",
"1. take milk\n",
Expand All @@ -106,8 +106,7 @@
"5. heat in the oven\n",
"\n",
"You take the milk, the sugar, but then you discover there is no flour. It is evening, and there aren't open shops.\n",
"Obviously, it makes no sense to proceed to point 4 with the mixture and you have to give up on the pie, telling the guest of honor the problem. You can only hope she/he decides for some alternative.\n",
"\n"
"Obviously, it makes no sense to proceed to point 4 with the mixture, and you have to give up on the pie, telling the guest of honor the problem. You can only hope she/he decides for some alternative."
]
},
{
Expand All @@ -118,20 +117,17 @@
},
"source": [
"\n",
"Translating everything in Python terms, we can ask ourselves if during the function execution, when we find an unforeseen situation, it is possible:\n",
"Translating everything in Python terms, we can ask ourselves if during the function execution, when we find an unforeseen situation, is it possible to:\n",
"\n",
"1. **interrupt** the execution flow of the program\n",
"2. **signal** to whoever called the function that a problem has occurred\n",
"3. **allow to manage** the problem to whoever called the function\n",
"\n",
"The answer it is yes, you can do it with the mechanism of **exceptions** (`Exception`)\n",
"The answer is yes, you can do it with the mechanism of **exceptions** (`Exception`)\n",
"\n",
"### make_problematic_pie\n",
"\n",
"Let's see how we can represent in Python the above problem. A basic version might be the following:\n",
"\n",
"\n",
"**QUESTION**: this version has a serious problem. Can you spot it ??"
"Let's see how we can represent the above problem in Python. A basic version might be the following:"
]
},
{
Expand Down Expand Up @@ -193,6 +189,13 @@
"print(\"Party\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**QUESTION**: this above version has a serious problem. Can you spot it ??"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -211,7 +214,12 @@
"\n",
"**EXERCISE**: We could correct the problems of the above pie by adding `return` commands. Implement the following function.\n",
"\n",
"**NOTE**: DO NOT move the `print(\"Party\")` inside the function. The exercise goal is exactly keep it outside so to use the value returned by `make_pie` to decide whether to party or not.\n",
"<div class=\"alert alert-warning\">\n",
"\n",
"**WARNING: DO NOT move the** `print(\"Party\")` **inside the function**\n",
"\n",
"The exercise goal is keeping it outside, so to use the value returned by `make_pie` for deciding whether to party or not.\n",
"</div>\n",
"\n",
"If you have any doubts on functions with return values, check [Chapter 6 of Think Python](http://greenteapress.com/thinkpython2/html/thinkpython2007.html)"
]
Expand Down Expand Up @@ -318,15 +326,15 @@
"raise Exception()\n",
"```\n",
"\n",
"If we want, we can also write a message to help programmers (who could be yourselves ...) to understand the problem origin. In our case it could be a message like this:\n",
"If we want, we can also write a message to help programmers (who could be ourselves ...) to understand the problem origin. In our case it could be a message like this:\n",
"\n",
"```python\n",
"raise Exception(\"Don't have enough flour !\")\n",
"```\n",
"\n",
"Note: in professional programs, the exception messages are intended for programmers, are verbose, and tipically end up hidden in system logs. To final users you should only show short messages which are understanble by a non-technical public. At most, you can add an error code which might be given by the user to the technician to help diagnose the problem.\n",
"Note: in professional programs, the exception messages are intended for programmers, verbose, and tipically end up hidden in system logs. To final users you should only show short messages which are understanble by a non-technical public. At most, you can add an error code which the user might give to the technician for diagnosing the problem.\n",
"\n",
"**EXERCISE**: Try to rewrite the function above by substituting the rows `return` with `raise Exception()`:"
"**EXERCISE**: Try to rewrite the function above by substituting the rows containing `return` with `raise Exception()`:"
]
},
{
Expand Down Expand Up @@ -383,7 +391,7 @@
"print(\"Party\")\n",
"```\n",
"\n",
"You should see (note how \"Party\" is _not_ printed):\n",
"you should see the following (note how \"Party\" is _not_ printed):\n",
" \n",
"```bash\n",
"take milk\n",
Expand Down Expand Up @@ -416,7 +424,7 @@
"id": "JifNcpcGMN1p"
},
"source": [
"We see the programm got interrupted before arriving to mix step (inside the function), and it didn't even arrived to party (which is outside the function). Let's try now to call the function with enough ingredients in the sideboard:\n"
"We see the program got interrupted before arriving to mix step (inside the function), and it didn't even arrived to party (which is outside the function). Let's try now to call the function with enough ingredients in the sideboard:\n"
]
},
{
Expand Down Expand Up @@ -491,9 +499,9 @@
"\n",
"### Particular exceptions\n",
"\n",
"Until know we used `Exception` which is a generic exception, but, if you will, it is possible to use more specific exceptions to better signal the nature of the error. For example, when you implement a function, since checking the input values for correctness is very frequent, Python gives you an exception called `ValueError`. If you use it instead of `Exception`, you allow the function caller to intercept only that particular error tipe. \n",
"Until know we used a generic `Exception`, but, if you will, you can use more specific exceptions to better signal the nature of the error. For example, when you implement a function, since checking the input values for correctness is very frequent, Python gives you an exception called `ValueError`. If you use it instead of `Exception`, you allow the function caller to intercept only that particular error type. \n",
"\n",
"If instead the function raises an error which is not intercepted in the catch, the program will halt."
"If the function raises an error which is not intercepted in the catch, the program will halt."
]
},
{
Expand Down Expand Up @@ -585,7 +593,7 @@
"\n",
"On inauguration day, the reactor is turned on. Unexpectedly, the water level goes down to 5 meters, and an uncontrolled chain reaction occurs. Plutoniom fireworks follow. \n",
"\n",
"Could have avoided all of this? We often believe everything is good but then for some reason we find variables with unexpected values. The wrong program described above might have been written like so:\n"
"Could we have avoided all of this? We often believe everything is good but then for some reason we find variables with unexpected values. The wrong program described above might have been written like so:\n"
]
},
{
Expand Down Expand Up @@ -651,7 +659,7 @@
"id": "jIZeJGG9dNgR"
},
"source": [
"How could we improve it? Let's lok at the `assert` command, which must be written by following it with a boolean condition.\n",
"How could we improve it? Let's look at the `assert` command, which must be written by following it with a boolean condition.\n",
"\n",
"`assert True` does absolutely nothing:"
]
Expand Down Expand Up @@ -759,9 +767,11 @@
"\n",
"# a lot of code\n",
"\n",
"# after a lot of code we might not know if there are the proper conditions so that everything works allright\n",
"# so before doing critical things, it is always a good idea to perform a check !\n",
"# if asserts fail (that is, the boolean expression is False), the execution suddenly stops\n",
"# after a lot of code we might not know if there are the proper conditions so that\n",
"# everything works allright so before doing critical things, it is always a good idea\n",
"# to perform a check ! if asserts fail (that is, the boolean expression is False),\n",
"# the execution suddenly stops\n",
"\n",
"assert water_level >= 20\n",
"\n",
"print(\"turn on nuclear reactor\")\n",
Expand All @@ -778,12 +788,12 @@
"\n",
"---------------------------------------------------------------------------\n",
"AssertionError Traceback (most recent call last)\n",
"<ipython-input-26-1fbeb6646ecf> in <module>\n",
" 29 # so before doing critical things, it is always a good idea to perform a check !\n",
" 30 # if asserts fail (that is, the boolean expression is False), the execution suddenly stops\n",
"---> 31 assert water_level >= 20\n",
"<ipython-input-3-d553a90d4f64> in <module>\n",
" 31 # the execution suddenly stops\n",
" 32 \n",
" 33 print(\"turn on nuclear reactor\")\n",
"---> 33 assert water_level >= 20\n",
" 34 \n",
" 35 print(\"turn on nuclear reactor\")\n",
"\n",
"AssertionError: \n",
"\n",
Expand All @@ -799,9 +809,11 @@
"source": [
"### When to use assert?\n",
"\n",
"The case above is willingly exagerated, but shows how a check more sometimes prevents disasters\n",
"The case above is willingly exagerated, but shows how a check more sometimes prevents disasters.\n",
"\n",
"Asserts are a quick way to do checks, so much so that Python even allows to ignore them during execution to improve the performance (calling `python` with the `-O` parameter like in `python -O my_file.py`).\n",
"\n",
"Asserts are a quick way to do checks, so much so that Python even allows to ignore them during execution to improve the performance (calling `python` with the `-O` parameter like in `python -O my_file.py`). But if performance are not a problem (like in the reactor above), it's more convenient to rewrite the program using an `if` and explicitly raising an `Exception`:\n"
"But if performance are not a problem (like in the reactor above), it's more convenient to rewrite the program using an `if` and explicitly raising an `Exception`:\n"
]
},
{
Expand Down Expand Up @@ -840,8 +852,9 @@
"\n",
"# a lot of code\n",
"\n",
"# after a lot of code we might not know if there are the proper conditions so that everything works all right\n",
"# so before doing critical things, it is always a good idea to perform a check !\n",
"# after a lot of code we might not know if there are the proper conditions so \n",
"# that everything works all right. So before doing critical things, it is always \n",
"# a good idea to perform a check !\n",
"\n",
"if water_level < 20:\n",
" raise Exception(\"Water level too low !\") # execution stops here\n",
Expand Down Expand Up @@ -876,7 +889,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Note how the reactor was _not_ turned on."
"Note how the reactor was _not_ turned on. "
]
},
{
Expand Down Expand Up @@ -1403,7 +1416,7 @@
"\n",
"#### Error kind a) An external user misuses you program.\n",
"\n",
"You can assume whover uses your software, final users or other programmers , they will try their very best to wreck your precious code by passing all sort of non-sense to functions. Everything can come in, strings instead of numbers, empty arrays, `None` objects ... In this case you should signal the user he made some mistake. The most crude signal you can have is raising an `Exception` with `raise Exception(\"Some error occurred\")`, which will stop the program and print the stacktrace in the console. Maybe final users won't understand a stacktrace, but at least programmers hopefully will get a clue about what's happening. \n",
"You can assume whover uses your software, final users or other programmers , they will try their very best to wreck your precious code by passing all sort of non-sense to functions. Everything can come in, strings instead of numbers, empty arrays, `None` objects ... In this case you should signal the user he made some mistake. The most crude signal you can have is raising an `Exception` with `raise Exception(\"Some error occurred\")`, which will stop the program and print the stacktrace in the console. Maybe final users won't understand a stacktrace, but at least programmers hopefully will get a clue about what is happening. \n",
"\n",
"In these case you can raise an appropriate Exception, like [TypeError](https://docs.python.org/3/library/exceptions.html#TypeError) for wrong types and [ValueError](https://docs.python.org/3/library/exceptions.html#ValueError) for more generic errors. Other basic exceptions can be found in [Python documentation](https://docs.python.org/3/library/exceptions.html#built-in-exceptions). Notice you can also define your own, if needed (we won't consider custom exceptions in this course).\n",
"\n",
Expand Down Expand Up @@ -1588,7 +1601,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"As before, the function will stop as soon we call it we wrong parameters. The big difference is, this time we are assume `even_numbers` is just for personal use and nobody else except us should directly call it. \n",
"As before, the function will stop as soon we call it we wrong parameters. The big difference is, this time we are assuming `even_numbers` is just for personal use and nobody else except us should directly call it. \n",
"\n",
"Since assertion consume CPU time, IF we care about performances AND once we are confident our program behaves correctly, we can even remove them from compiled code by using the `-O` compiler flag. For more info, see [Python wiki](https://wiki.python.org/moin/UsingAssertionsEffectively) "
]
Expand Down Expand Up @@ -1622,7 +1635,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 22,
"metadata": {
"raw_mimetype": "text/x-python"
},
Expand Down Expand Up @@ -2055,7 +2068,9 @@
"\n",
"<div class=\"alert alert-warning\">\n",
"\n",
"**NOTE: during the exam testing in VSCode might not work, so please be prepared to use the console**\n",
"**WARNING: spend time also with the console !!!!**\n",
"\n",
"During the exam testing in VSCode might not work, so please be prepared to use the console\n",
"\n",
"</div>"
]
Expand Down

0 comments on commit 0133453

Please sign in to comment.