Skip to content

Added section to emphasize difference between exceptions and assertions #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: gh-pages
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 43 additions & 30 deletions 03-exceptions.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,48 +30,49 @@
<h2 class="subtitle">Exceptions</h2>
<section class="objectives panel panel-warning">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-certificate"></span>Learning Objectives</h2>
<h2 id="learning-objectives"><span class="glyphicon glyphicon-certificate"></span>Learning Objectives</h2>
</div>
<div class="panel-body">
<ul>
<li>Understand that exceptions are effectively specialized runtime tests</li>
<li>Learn when to use exceptions and what exceptions are available</li>
<li>Learner will understand that exceptions are specialized runtime tests</li>
<li>Learner will recognize scenarios when to use exceptions and what exceptions are available</li>
<li>Learner will recognize when to use exceptions as opposed to assertions</li>
</ul>
</div>
</section>
<p>Exceptions are more sophisticated than assertions. They are the standard error messaging system in most modern programming languages. Fundamentally, when an error is encountered, an informative exception is ‘thrown’ or ‘raised’.</p>
<p>For example, instead of the assertion in the case before, an exception can be used.</p>
<pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="kw">if</span> <span class="dt">len</span>(num_list) == <span class="dv">0</span> :
<span class="kw">raise</span> <span class="ot">Exception</span>(<span class="st">&quot;The algebraic mean of an empty list is undefined. Please provide a list of numbers&quot;</span>)
<span class="kw">else</span> :
<span class="kw">return</span> <span class="dt">sum</span>(num_list)/<span class="dt">len</span>(num_list)</code></pre>
<p>Once an exception is raised, it will be passed upward in the program scope. An exception be used to trigger additional error messages or an alternative behavior. rather than immediately halting code execution, the exception can be ‘caught’ upstream with a try-except block. When wrapped in a try-except block, the exception can be intercepted before it reaches global scope and halts execution.</p>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="cf">if</span> <span class="bu">len</span>(num_list) <span class="op">==</span> <span class="dv">0</span> :
<span class="cf">raise</span> <span class="pp">Exception</span>(<span class="st">&quot;The algebraic mean of an empty list is undefined. Please provide a list of numbers&quot;</span>)
<span class="cf">else</span> :
<span class="cf">return</span> <span class="bu">sum</span>(num_list)<span class="op">/</span><span class="bu">len</span>(num_list)</code></pre></div>
<p>Once an exception is raised, it will be passed upward in the program scope. An exception can be used to trigger additional error messages or an alternative behavior. Rather than immediately halting code execution, the exception can be ‘caught’ upstream with a try-except block. When wrapped in a try-except block, the exception can be intercepted before it reaches global scope and halts execution.</p>
<p>To add information or replace the message before it is passed upstream, the try-catch block can be used to catch-and-reraise the exception:</p>
<pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="kw">try</span>:
<span class="kw">return</span> <span class="dt">sum</span>(num_list)/<span class="dt">len</span>(num_list)
<span class="kw">except</span> <span class="ot">ZeroDivisionError</span> <span class="ch">as</span> detail :
msg = <span class="st">&quot;The algebraic mean of an empty list is undefined. Please provide a list of numbers.&quot;</span>
<span class="kw">raise</span> <span class="ot">ZeroDivisionError</span>(detail.<span class="ot">__str__</span>() + <span class="st">&quot;</span><span class="ch">\n</span><span class="st">&quot;</span> + msg)</code></pre>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="cf">try</span>:
<span class="cf">return</span> <span class="bu">sum</span>(num_list)<span class="op">/</span><span class="bu">len</span>(num_list)
<span class="cf">except</span> <span class="pp">ZeroDivisionError</span> <span class="im">as</span> detail :
msg <span class="op">=</span> <span class="st">&quot;The algebraic mean of an empty list is undefined. Please provide a list of numbers.&quot;</span>
<span class="cf">raise</span> <span class="pp">ZeroDivisionError</span>(detail.<span class="fu">__str__</span>() <span class="op">+</span> <span class="st">&quot;</span><span class="ch">\n</span><span class="st">&quot;</span> <span class="op">+</span> msg)</code></pre></div>
<p>Alternatively, the exception can simply be handled intelligently. If an alternative behavior is preferred, the exception can be disregarded and a responsive behavior can be implemented like so:</p>
<pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="kw">try</span>:
<span class="kw">return</span> <span class="dt">sum</span>(num_list)/<span class="dt">len</span>(num_list)
<span class="kw">except</span> <span class="ot">ZeroDivisionError</span> :
<span class="kw">return</span> <span class="dv">0</span></code></pre>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="cf">try</span>:
<span class="cf">return</span> <span class="bu">sum</span>(num_list)<span class="op">/</span><span class="bu">len</span>(num_list)
<span class="cf">except</span> <span class="pp">ZeroDivisionError</span> :
<span class="cf">return</span> <span class="dv">0</span></code></pre></div>
<p>If a single function might raise more than one type of exception, each can be caught and handled separately.</p>
<pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="kw">try</span>:
<span class="kw">return</span> <span class="dt">sum</span>(num_list)/<span class="dt">len</span>(num_list)
<span class="kw">except</span> <span class="ot">ZeroDivisionError</span> :
<span class="kw">return</span> <span class="dv">0</span>
<span class="kw">except</span> <span class="ot">TypeError</span> <span class="ch">as</span> detail :
msg = <span class="st">&quot;The algebraic mean of an non-numerical list is undefined. Please provide a list of numbers.&quot;</span>
<span class="kw">raise</span> <span class="ot">TypeError</span>(detail.<span class="ot">__str__</span>() + <span class="st">&quot;</span><span class="ch">\n</span><span class="st">&quot;</span> + msg)</code></pre>
<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="kw">def</span> mean(num_list):
<span class="cf">try</span>:
<span class="cf">return</span> <span class="bu">sum</span>(num_list)<span class="op">/</span><span class="bu">len</span>(num_list)
<span class="cf">except</span> <span class="pp">ZeroDivisionError</span> :
<span class="cf">return</span> <span class="dv">0</span>
<span class="cf">except</span> <span class="pp">TypeError</span> <span class="im">as</span> detail :
msg <span class="op">=</span> <span class="st">&quot;The algebraic mean of an non-numerical list is undefined. Please provide a list of numbers.&quot;</span>
<span class="cf">raise</span> <span class="pp">TypeError</span>(detail.<span class="fu">__str__</span>() <span class="op">+</span> <span class="st">&quot;</span><span class="ch">\n</span><span class="st">&quot;</span> <span class="op">+</span> msg)</code></pre></div>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-pencil"></span>What Else Can Go Wrong?</h2>
<h2 id="what-else-can-go-wrong"><span class="glyphicon glyphicon-pencil"></span>What Else Can Go Wrong?</h2>
</div>
<div class="panel-body">
<ol style="list-style-type: decimal">
Expand All @@ -82,7 +83,7 @@ <h2><span class="glyphicon glyphicon-pencil"></span>What Else Can Go Wrong?</h2>
</section>
<section class="challenge panel panel-success">
<div class="panel-heading">
<h2><span class="glyphicon glyphicon-pencil"></span>Cause All of the Errors</h2>
<h2 id="cause-all-of-the-errors"><span class="glyphicon glyphicon-pencil"></span>Cause All of the Errors</h2>
</div>
<div class="panel-body">
<ul>
Expand All @@ -91,6 +92,18 @@ <h2><span class="glyphicon glyphicon-pencil"></span>Cause All of the Errors</h2>
</div>
</section>
<p>Exceptions have the advantage of being simple to include and powerfully helpful to the user. However, not all behaviors can or should be found with runtime exceptions. Most behaviors should be validated with unit tests.</p>
<aside class="callout panel panel-info">
<div class="panel-heading">
<h2 id="exceptions-vs.assertions"><span class="glyphicon glyphicon-pushpin"></span>Exceptions vs. Assertions</h2>
</div>
<div class="panel-body">
<p>To resolve any possible confusion on when to use assertions as opposed to exceptions, we would like to make the following points.</p>
<ol style="list-style-type: decimal">
<li><p><em>Assertions</em> can be thought of as your internal checks (as the developer) to make sure that your program is behaving how you would like it to. When you are writing unit tests for your own software, you should use <em>assertions</em> in those tests since the user will likely not see the tests.</p></li>
<li><p><em>Exceptions</em> can be thought of as messages that you would like the actual user of your program to see to let them know that the program behavior is incorrect (e.g. because their input was not correctly formatted) or to trigger alternative program behaviors. Two particular cases where exceptions are useful is when there is a program failure, and when there are special results or cases that need to be handled. A helpful mnemonic is that <em>Exceptions</em> are <em>external</em>.</p></li>
</ol>
</div>
</aside>
</div>
</div>
</article>
Expand Down
26 changes: 17 additions & 9 deletions 03-exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ minutes: 10

> ## Learning Objectives {.objectives}
>
> * Understand that exceptions are effectively specialized runtime tests
> * Learn when to use exceptions and what exceptions are available
> * Learner will understand that exceptions are specialized runtime tests
> * Learner will recognize scenarios when to use exceptions and what exceptions are available
> * Learner will recognize when to use exceptions as opposed to assertions

Exceptions are more sophisticated than assertions. They are the standard error
messaging system in most modern programming languages. Fundamentally, when an
Expand All @@ -26,14 +27,12 @@ def mean(num_list):
~~~

Once an exception is raised, it will be passed upward in the program scope.
An exception be used to trigger additional error messages or an alternative
behavior. rather than immediately halting code
An exception can be used to trigger additional error messages or an alternative
behavior. Rather than immediately halting code
execution, the exception can be 'caught' upstream with a try-except block.
When wrapped in a try-except block, the exception can be intercepted before it reaches
global scope and halts execution.
When wrapped in a try-except block, the exception can be intercepted before it reaches global scope and halts execution.

To add information or replace the message before it is passed upstream, the try-catch
block can be used to catch-and-reraise the exception:
To add information or replace the message before it is passed upstream, the try-catch block can be used to catch-and-reraise the exception:

~~~ {.python}
def mean(num_list):
Expand All @@ -48,7 +47,6 @@ Alternatively, the exception can simply be handled intelligently. If an
alternative behavior is preferred, the exception can be disregarded and a
responsive behavior can be implemented like so:


~~~ {.python}
def mean(num_list):
try:
Expand Down Expand Up @@ -85,3 +83,13 @@ def mean(num_list):
Exceptions have the advantage of being simple to include and powerfully helpful
to the user. However, not all behaviors can or should be found with runtime
exceptions. Most behaviors should be validated with unit tests.

> ## Exceptions vs. Assertions {.callout}
> To resolve any possible confusion on when to use assertions as opposed to exceptions, we would like to make the following points.
>
> 1. _Assertions_ can be thought of as your internal checks (as the developer)
> to make sure that your program is behaving how you would like it to. When you are writing unit tests for your own software, you should use _assertions_ in those tests since the user will likely not see the tests.
>
> 2. _Exceptions_ can be thought of as messages that you would like the actual user of your program to see to let them know that the program behavior is incorrect (e.g. because their input was not correctly formatted) or to trigger alternative program behaviors. Two particular cases where exceptions are useful is when there is a program failure, and when there are special results or cases that need to be handled.
> A helpful mnemonic is that _Exceptions_ are _external_.