Debugging Your Code

Scratch Spell with Logging Messages

Now we'll look at the same spell, but this time we've sprinkled logging messages through the code. We've added 20 logging statmenets, and they are highlighted in dark red italics, so you can spot them easily.

<span class='string'>"""</span><br><span class='keyword'></span>scratch<span class='keyword'></span>.<span class='keyword'></span>py<span class='keyword'></span><br><br><span class='keyword'></span>An<span class='keyword'></span> <span class='keyword'></span>example<span class='keyword'></span> <span class='keyword'></span>spell<span class='keyword'></span>, <span class='keyword'></span>for<span class='keyword'></span> <span class='keyword'></span>demonstrating<span class='keyword'></span> <span class='keyword'></span>logging<span class='keyword'></span>.  <span class='keyword'></span>There<span class='keyword'></span> <span class='keyword'></span>is<span class='keyword'></span><br><span class='keyword'></span>a<span class='keyword'></span> <span class='keyword'></span>bunch<span class='keyword'></span> <span class='keyword'></span>of<span class='keyword'></span> <span class='keyword'></span>logging<span class='keyword'></span> <span class='keyword'></span>code<span class='keyword'></span> <span class='keyword'></span>in<span class='keyword'></span> <span class='keyword'></span>this<span class='keyword'></span> <span class='keyword'></span>version<span class='keyword'></span> <span class='keyword'></span>of<span class='keyword'></span> <span class='keyword'></span>the<span class='keyword'></span> <span class='keyword'></span>spell<span class='keyword'></span>.<br><br><span class='keyword'></span>Copyright<span class='keyword'></span> <span class='keyword'></span>2003<span class='keyword'></span> <span class='keyword'></span>Cabochon<span class='keyword'></span> <span class='keyword'></span>Technologies<span class='keyword'></span>, <span class='keyword'></span>Inc<span class='keyword'></span>.<br><span class='keyword'></span>Author<span class='keyword'></span>: <span class='keyword'></span>Steve<span class='keyword'></span> <span class='keyword'></span>Yegge<span class='keyword'></span><br><span class='string'>"""</span><br><br><span class='keyword'></span>from<span class='keyword'></span> <span class='keyword'></span>java<span class='keyword'></span>.<span class='keyword'></span>lang<span class='keyword'></span> <span class='keyword'></span>import<span class='keyword'></span> <span class='keyword'></span>String<span class='keyword'></span><br><span class='keyword'></span>from<span class='keyword'></span> <span class='keyword'></span>wyvern<span class='keyword'></span>.<span class='keyword'></span>lib<span class='keyword'></span> <span class='keyword'></span>import<span class='keyword'></span> <span class='keyword'></span>Timed<span class='keyword'></span>, <span class='keyword'></span>Range<span class='keyword'></span>, <span class='keyword'></span>Kernel<span class='keyword'></span><br><span class='keyword'></span>from<span class='keyword'></span> <span class='keyword'></span>wyvern<span class='keyword'></span>.<span class='keyword'></span>lib<span class='keyword'></span>.<span class='keyword'></span>classes<span class='keyword'></span>.<span class='keyword'></span>magic<span class='keyword'></span> <span class='keyword'></span>import<span class='keyword'></span> <span class='keyword'></span>Spell<span class='keyword'></span><br><br><span class='keyword'>class</span> <span class='function'>scratch</span>(Spell, Timed):<br><br>    <span class='keyword'>def</span> <span class='function'>initialize</span>(self):<br>        <span class="code_callout">Kernel.finest('scratch.py', 'initialize', 'calling superclass')</span><br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>super__initialize<span class='keyword'></span>()<br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>setIntProperty<span class='keyword'></span>('<span class='keyword'></span>lore<span class='keyword'></span>', <span class='keyword'></span>1<span class='keyword'></span>)<br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>setProperty<span class='keyword'></span>('<span class='keyword'></span>short<span class='keyword'></span>', '<span class='keyword'></span>scratch<span class='keyword'></span>')<br>        <span class="code_callout">Kernel.finest('scratch.py', 'initialize', 'done initializing')</span><br><br>    <span class='keyword'>def</span> <span class='function'>getArt</span>(self):<br>        <span class="code_callout">Kernel.entering('scratch.py', 'getArt')</span><br>        <span class='keyword'></span>return<span class='keyword'></span> <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>INCANTATION<span class='keyword'></span><br><br>    <span class='keyword'>def</span> <span class='function'>getElement</span>(self):<br>        <span class="code_callout">Kernel.entering('scratch.py', 'getElement')</span><br>        <span class='keyword'></span>return<span class='keyword'></span> <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>SPIRIT<span class='keyword'></span><br><br>    <span class='keyword'>def</span> <span class='function'>start</span>(self):<br><br>        <span class="code_callout">Kernel.fine('scratch.py', 'start', 'looking for target')</span><br><span class='comment'>        # look for target, or use caster if there isn't one</span><br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>target<span class='keyword'></span> = <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>findTargetObject<span class='keyword'></span>(<span class='keyword'></span>1<span class='keyword'></span>)<br>        <span class='keyword'></span>if<span class='keyword'></span> (<span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>target<span class='keyword'></span> == <span class='keyword'></span>None<span class='keyword'></span>):<br>            <span class="code_callout">Kernel.fine('scratch.py', 'start', 'no target found!')</span><br>            <span class='keyword'></span>return<span class='keyword'></span><br><br>        <span class="code_callout">Kernel.fine('scratch.py', 'start', 'setting timer')</span><br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>timer<span class='keyword'></span> = <span class='keyword'></span>Kernel<span class='keyword'></span>.<span class='keyword'></span>setRepeatingTimer<span class='keyword'></span> ( <span class='keyword'></span>20000<span class='keyword'></span>, <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span> )<br><br>        <span class="code_callout">Kernel.fine('scratch.py', 'start', 'making dispellable')</span><br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>makeDispellable<span class='keyword'></span>()<br><br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>getAgent<span class='keyword'></span>().<span class='keyword'></span>message<span class='keyword'></span>('<span class='keyword'></span>You<span class='keyword'></span> <span class='keyword'></span>cast<span class='keyword'></span> <span class='keyword'></span>scratch<span class='keyword'></span> <span class='keyword'></span>on<span class='keyword'></span> ' + <span class='keyword'></span>str<span class='keyword'></span>(<span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>target<span class='keyword'></span>))<br><br>    <span class='keyword'>def</span> <span class='function'>timerExpired</span>(self):<br>        <span class="code_callout">Kernel.fine('scratch.py', 'timerExpired', 'entering')</span><br>        <span class='keyword'></span>target<span class='keyword'></span> = <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>target<span class='keyword'></span><br>        <span class='keyword'></span>roll<span class='keyword'></span> = <span class='keyword'></span>Range<span class='keyword'></span>.<span class='keyword'></span>percent<span class='keyword'></span>()<br>        <span class='keyword'></span>pronoun<span class='keyword'></span> = <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>getGenderString<span class='keyword'></span>()<br>        <span class='keyword'></span>name<span class='keyword'></span> = <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>getName<span class='keyword'></span>()<br><br>        <span class="code_callout">Kernel.finer('scratch.py', 'timerExpired', 'rolled ' + str(roll))</span><br>        <span class="code_callout">Kernel.finer('scratch.py', 'timerExpired', 'gender ' + pronoun)</span><br>        <span class="code_callout">Kernel.finer('scratch.py', 'timerExpired', 'name: ' + name)</span><br><br>        <span class='keyword'></span>if<span class='keyword'></span> <span class='keyword'></span>roll<span class='keyword'></span> < <span class='keyword'></span>20<span class='keyword'></span>:<br>            <span class="code_callout">Kernel.finest('scratch.py', 'timerExpired', 'scratching self')</span><br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>message<span class='keyword'></span> ( <span class='string'>"<span class='keyword'></span>You<span class='keyword'></span> <span class='keyword'></span>scratch<span class='keyword'></span> <span class='keyword'></span>yourself<span class='keyword'></span>."</span> )<br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>broadcast<span class='keyword'></span> ( <span class='keyword'></span>name<span class='keyword'></span> + <span class='string'>" <span class='keyword'></span>scratches<span class='keyword'></span> "</span> +<br>                               <span class='keyword'></span>pronoun<span class='keyword'></span> + <span class='string'>"<span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span> <span class='keyword'></span>vigorously<span class='keyword'></span>."</span> )<br>        <span class='keyword'></span>elif<span class='keyword'></span> <span class='keyword'></span>roll<span class='keyword'></span> < <span class='keyword'></span>40<span class='keyword'></span>:<br>            <span class="code_callout">Kernel.finest('scratch.py', 'timerExpired', 'scratching nose')</span><br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>message<span class='keyword'></span> ( <span class='string'>"<span class='keyword'></span>You<span class='keyword'></span> <span class='keyword'></span>rub<span class='keyword'></span> <span class='keyword'></span>your<span class='keyword'></span> <span class='keyword'></span>nose<span class='keyword'></span>."</span> )<br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>broadcast<span class='keyword'></span> ( <span class='keyword'></span>name<span class='keyword'></span> + <span class='string'>" <span class='keyword'></span>rubs<span class='keyword'></span> "</span> +<br>                               <span class='keyword'></span>pronoun<span class='keyword'></span> + <span class='string'>" <span class='keyword'></span>nose<span class='keyword'></span> <span class='keyword'></span>for<span class='keyword'></span> <span class='keyword'></span>a<span class='keyword'></span> <span class='keyword'></span>long<span class='keyword'></span> <span class='keyword'></span>while<span class='keyword'></span>."</span> )<br>        <span class='keyword'></span>elif<span class='keyword'></span> <span class='keyword'></span>roll<span class='keyword'></span> < <span class='keyword'></span>60<span class='keyword'></span>:<br>            <span class="code_callout">Kernel.finest('scratch.py', 'timerExpired', 'scratching ear')</span><br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>message<span class='keyword'></span> ( <span class='string'>"<span class='keyword'></span>You<span class='keyword'></span> <span class='keyword'></span>scratch<span class='keyword'></span> <span class='keyword'></span>your<span class='keyword'></span> <span class='keyword'></span>ear<span class='keyword'></span>."</span> )<br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>broadcast<span class='keyword'></span> ( <span class='keyword'></span>name<span class='keyword'></span> + <span class='string'>" <span class='keyword'></span>sticks<span class='keyword'></span> "</span> +<br>                               <span class='keyword'></span>pronoun<span class='keyword'></span> + <span class='string'>" <span class='keyword'></span>finger<span class='keyword'></span> <span class='keyword'></span>in<span class='keyword'></span> "</span> + <span class='keyword'></span>pronoun<span class='keyword'></span> +<br>                               <span class='string'>" <span class='keyword'></span>ear<span class='keyword'></span> <span class='keyword'></span>and<span class='keyword'></span> <span class='keyword'></span>scratches<span class='keyword'></span> <span class='keyword'></span>an<span class='keyword'></span> <span class='keyword'></span>itch<span class='keyword'></span>."</span> )<br>        <span class='keyword'></span>elif<span class='keyword'></span> <span class='keyword'></span>roll<span class='keyword'></span> < <span class='keyword'></span>80<span class='keyword'></span>:<br>            <span class="code_callout">Kernel.finest('scratch.py', 'timerExpired', 'belching')</span><br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>message<span class='keyword'></span> ( <span class='string'>"<span class='keyword'></span>You<span class='keyword'></span> <span class='keyword'></span>suddenly<span class='keyword'></span> <span class='keyword'></span>belch<span class='keyword'></span>."</span> )<br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>broadcast<span class='keyword'></span> ( <span class='keyword'></span>name<span class='keyword'></span> + <span class='string'>" <span class='keyword'></span>belches<span class='keyword'></span> <span class='keyword'></span>loudly<span class='keyword'></span>, "</span> +<br>                               <span class='string'>"<span class='keyword'></span>and<span class='keyword'></span> <span class='keyword'></span>looks<span class='keyword'></span> <span class='keyword'></span>very<span class='keyword'></span> <span class='keyword'></span>embarrassed<span class='keyword'></span> <span class='keyword'></span>about<span class='keyword'></span> <span class='keyword'></span>it<span class='keyword'></span>."</span> )<br>        <span class='keyword'></span>else<span class='keyword'></span>:<br>            <span class="code_callout">Kernel.finest('scratch.py', 'timerExpired', 'smelling')</span><br>            <span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>broadcast<span class='keyword'></span> ( <span class='keyword'></span>name<span class='keyword'></span> + <span class='string'>" <span class='keyword'></span>smells<span class='keyword'></span> <span class='keyword'></span>terrible<span class='keyword'></span> <span class='keyword'></span>today<span class='keyword'></span>."</span> )<br>            <br>    <span class='keyword'>def</span> <span class='function'>dispel</span>(self):<br>        <span class="code_callout">Kernel.fine('scratch.py', 'dispel', 'calling superclass')</span><br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>super__dispel<span class='keyword'></span>()<br><br>        <span class="code_callout">Kernel.fine('scratch.py', 'dispel', 'killing timer')</span><br>        <span class='keyword'></span>Kernel<span class='keyword'></span>.<span class='keyword'></span>killTimer<span class='keyword'></span>(<span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>timer<span class='keyword'></span>)<br>        <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>target<span class='keyword'></span>.<span class='keyword'></span>message<span class='keyword'></span> ( <span class='string'>"<span class='keyword'></span>You<span class='keyword'></span> <span class='keyword'></span>suddenly<span class='keyword'></span> <span class='keyword'></span>feel<span class='keyword'></span> <span class='keyword'></span>more<span class='keyword'></span> <span class='keyword'></span>sophisticated<span class='keyword'></span>."</span> )<br><br>    <span class='keyword'>def</span> <span class='function'>__repr__</span>(self):<br>        <span class='keyword'></span>return<span class='keyword'></span> <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>getProperty<span class='keyword'></span>('<span class='keyword'></span>short<span class='keyword'></span>')<br><br>    <span class='keyword'>def</span> <span class='function'>toString</span>(self):<br>        <span class='keyword'></span>return<span class='keyword'></span> <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>__repr__<span class='keyword'></span>()<br><br>    <span class='keyword'>def</span> <span class='function'>getSpellDescription</span>(self):<br>        <span class="code_callout">Kernel.entering('scratch.py', 'getSpellDescription')</span><br>        <span class='keyword'></span>return<span class='keyword'></span> (<span class='string'>"<span class='keyword'></span>This<span class='keyword'></span> "</span> + <span class='keyword'></span><span class='instance'>self</span><span class='keyword'></span>.<span class='keyword'></span>getDescString<span class='keyword'></span>() +<br>                <span class='string'>" <span class='keyword'></span>lowers<span class='keyword'></span> <span class='keyword'></span>the<span class='keyword'></span> <span class='keyword'></span>target<span class='keyword'></span> <span class='keyword'></span>several<span class='keyword'></span> <span class='keyword'></span>rungs<span class='keyword'></span> <span class='keyword'></span>on<span class='keyword'></span> <span class='keyword'></span>the<span class='keyword'></span> <span class='keyword'></span>Social<span class='keyword'></span> <span class='keyword'></span>Ladder<span class='keyword'></span>."</span>)

The first thing you probably noticed was that there are a LOT of logging statements. The entire program is 97 lines long, including blank lines, and 20 of them are for logging. That's almost 20% of the entire program devoted to logging!

Normally you won't put in quite that much logging - or if you do, it's because the class is really complicated and is being debugged all the time. It's more common to have about 5% of your code (1 line out of 20) be logging statements.

The second thing you probably noticed is that we had to pass in the class name and method name to each logging statement. That's true, but we'll cover how to simplify this a bit in later lessons.

We only used four kinds of logging statements in this example:

  • Kernel.fine()
  • Kernel.finer()
  • Kernel.finest()
  • Kernel.entering()

Kernel.entering() is a new one that we didn't mention before. It simply prints a message saying we're entering the method. It happens at log level FINEST, so it's similar to saying:

Kernel.finest('scratch.py', 'mymethod', 'entering')

Because we're not using INFO, WARNING, or SEVERE logging levels, none of these statements will get printed to any logs unless we turn on debugging for this class. We'll see how to do that in the next lesson.

<< Previous Chapter Next Chapter >>