forked from ninas/umonya_notes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunderstanding_errors.html
110 lines (93 loc) · 5.33 KB
/
understanding_errors.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Introductory Programming in Python: Understanding Python's Error Messages</title>
<link rel='stylesheet' type='text/css' href='style.css' />
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<script src="animation.js" type="text/javascript">
</script>
</head>
<body onload="animate_loop()">
<div class="page">
<h1>Introductory Programming in Python: Lesson 24<br />
Understanding Python's Error Messages</h1>
<div class="centered">
[<a href="writing_errors.html">Prev: Writing Meaningful Error Messages</a>] [<a href="index.html">Course Outline</a>] [<a href="exceptions.html">Next: Flow Control: Exceptions</a>]
</div>
<h2>Traceback most recent WTF???</h2>
<p>We are by now all familiar with the dreaded <code>Traceback (most
recent call last):</code>. The sign that something has gone wrong, that
your late night just got later, your assignment is rapidly becoming
overdue, and that there's not nearly enough coffee left in the jug!
Well, believe it or not, the messages python prints are there to help
you, as long as you are willing to read and understand them.</p>
<h2>The Call Stack</h2>
<p>First we need to understand to concept of the call stack. When we
are running our python program, the execution point moves around, from
top to bottom, branching at if statements, looping with while or for
statements, or jumping inside functions... but this causes issues. If
an error occurs in our main program block, it's easy to track down
where it is by line number alone. There's generally only one way for
execution to reach that line. But in a function, which can be called
from many places within our program, including itself or other
functions, knowing that the error occurred on a line in a particular
function definition doesn't help us understand how the flow of
execution led up to the error. Enter the call stack! Every time a
function is called, python pushes it onto something called the call
stack. Think of a stack like getting into the elevator in a crowded
mall. You get in first, and as more people enter the elevator, you are
forced to the back. When you arrive at your floor, the last person in,
now being closest to the doors exits first. If you want to get out in
the middle somewhere, everyone who got in after you must briefly step
out, to let you out, then go back in. This is exactly what happens with
the call stack. As functions are called, their names are placed on the
stack, and as they return, their names are removed. The Traceback
presents us with the list of called functions (from the first called to
the most recent called [most recent call last]), telling us the file
where the call occurred, the line in that file, and the name of the
function the call was made from if any (otherwise '?'). On the next
line slightly indented it tells us the name of the function called. So
looking at the following traceback,</p>
<pre class='listing'>
Traceback (most recent call last):
File "test.py", line 25, in ?
triangle()
File "test.py", line 12, in triangle
inc_total_height()
File "test.py", line 8, in inc_total_height
total_height = total_height + height
UnboundLocalError: local variable 'total_height' referenced before assignment
</pre>
<p>We see that execution started in the file test.py and proceeded to
line 25, where the function 'triangle' was called. Within the function
triangle, execution proceeded until line 12, where the function
'inc_total_height' was called. Within 'inc_total_height' and error
occurred on line 8.</p>
<h2>The Nature of The Problem</h2>
<p>The last line (or sometimes two lines) of the traceback describe
what actually went wrong. In python, all errors are given a class, e.g.
input/output error, undefined variable, index out of range, etc...
These classes are given names that are one word without spaces, and
which can in fact be used within python code (but we'll get to that
later). The class name of the error, describing roughly what type of
error occurred, is printed first, and then everything following the
colon (':') is further description of the actual variables,
expressions, and statements involved in the error, and what they were
doing. So we can tell from the above example that the class was
'UnboundLocalError' and that the local variable 'total_height' was
referenced (evaluated) before a value was assigned to it.</p>
<p>Learning the meaning of the class names comes with time, but the
description following is usually sufficient to point you in the right
direction. At least now you can track down exactly what line is causing
the problem, and how the program got there.</p>
<h2>Exercises</h2>
<div class="centered">
[<a href="writing_errors.html">Prev: Writing Meaningful Error Messages</a>] [<a href="index.html">Course Outline</a>] [<a href="exceptions.html">Next: Flow Control: Exceptions</a>]
</div>
</div>
<div class="pagefooter">
Copyright © James Dominy 2007-2008; Released under the <a href="http://www.gnu.org/copyleft/fdl.html">GNU Free Documentation License</a><br />
<a href="intropython.tar.gz">Download the tarball</a>
</div>
</body>
</html>