<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Saving the Band &#187; python</title>
	<atom:link href="http://george.savetheband.net/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://george.savetheband.net</link>
	<description>The sporadic online life of an information superhighwayman</description>
	<lastBuildDate>Wed, 03 Nov 2010 14:42:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Windows dot2tex and exemaker gotchas</title>
		<link>http://george.savetheband.net/2010/11/03/windows-dot2tex-and-exemaker-gotchas/</link>
		<comments>http://george.savetheband.net/2010/11/03/windows-dot2tex-and-exemaker-gotchas/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 14:42:30 +0000</pubDate>
		<dc:creator>duplico</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[dot2tex]]></category>
		<category><![CDATA[GraphViz]]></category>
		<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[MiKTeX]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://george.savetheband.net/?p=339</guid>
		<description><![CDATA[This whole post deals with Python 2.7 on Windows. Your mileage may vary in other environments. I&#8217;m doing some writing on the topic of hybrid automata, and it looks like the best way to generate figures of the automata in LaTeX is with GraphViz and the dot2texi package, which works with the very nice dot2tex [...]]]></description>
			<content:encoded><![CDATA[<p>This whole post deals with Python 2.7 on Windows. Your mileage may vary in other environments.</p>
<p>I&#8217;m doing some writing on the topic of <a href="http://en.wikipedia.org/wiki/Hybrid_automaton">hybrid automata</a>, and it looks like the best way to generate figures of the automata in LaTeX is with GraphViz and the dot2texi package, which works with the very nice <a href="http://www.fauskes.net/code/dot2tex/">dot2tex</a> tool to generate figures from GraphViz dot formatted code embedded directly in LaTeX.</p>
<p>One of the issues, however, is that it expects an executable called &#8220;dot2tex&#8221; to be available on the shell. This means that, first and foremost, shell escape needs to be enabled when compiling the document (&#8211;shell-escape in many distributions, and &#8211;enable-write18 in MiKTeX, which I use). Adding this line to the beginning of the LaTeX source will handle it:</p>
<pre>%&amp; --shell-escape --enable-write18</pre>
<p>Next, since the executable file that&#8217;s installed (in Windows on Python 2.7 it goes, by default, to <code>C:\Python27\Scripts\dot2tex</code>) is made executable by a shebang on its first line, even if this file is on your path in Windows, it won&#8217;t do anything. So you need to use <a href="http://effbot.org/zone/exemaker.htm">ExeMaker</a>, which creates a very lightweight exe file to call a Python script. I put it in a directory that&#8217;s in my PATH (I made <code>C:\Users\george\bin</code> for this purpose) ran it like this:</p>
<pre>C:\Users\george&gt; rename C:\Python27\Scripts\dot2tex dot2tex.py
C:\Users\george&gt; exemaker C:\Python27\Scripts\dot2tex.py</pre>
<p>In my case, this created dot2tex.exe and dot2tex.py in C:\Users\george\bin. However, running dot2tex.exe causes an error:</p>
<pre>C:\Users\george&gt;dot2tex
Traceback (most recent call last):
  File "C:\Users\george\bin\dot2tex.py", line 6, in &lt;module&gt;
    from dot2tex.dot2tex import main
  File "C:\Users\george\bin\dot2tex.py", line 6, in &lt;module&gt;
    from dot2tex.dot2tex import main
ImportError: No module named dot2tex</pre>
<p>A bit of poking around reveals that this is due to the way that Python searches paths in import statements: the script, dot2tex.py, conflicts in its name with the module that we want to import, and the first directory that Python searches when looking for a file to import is the directory containing the executing script (or, in interactive mode, the working directory). The workaround I came up with, which seems to work well, is just to add two lines to dot2tex.py:</p>
<pre>import sys
del sys.path[0]</pre>
<p>Now my dot2tex.py file (the one in <code>C:\Users\george\bin</code>) looks like this:</p>
<pre>#!C:\Python27\python.exe
import site
import sys
del sys.path[0]
#!C:\Python27\python.exe
from dot2tex.dot2tex import main
if __name__ == '__main__':
    main()</pre>
<p>So far, this seems to have fixed all of my problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://george.savetheband.net/2010/11/03/windows-dot2tex-and-exemaker-gotchas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vulnerable Code: MoinMoin User</title>
		<link>http://george.savetheband.net/2010/06/07/vulnerable-code-moinmoin-user/</link>
		<comments>http://george.savetheband.net/2010/06/07/vulnerable-code-moinmoin-user/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 21:12:44 +0000</pubDate>
		<dc:creator>duplico</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[moinmoin]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[secure coding]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[vulnerable code]]></category>

		<guid isPermaLink="false">http://george.savetheband.net/?p=272</guid>
		<description><![CDATA[I&#8217;ve just started posting code samples from the wonderful SpotTheVuln.com on the walls in our building on 11&#215;17 cardstock behind thin plexiglass panes so they can be annotated with dry erase marker when people solve them or have comments: I love the site but wanted to branch out a little bit into some samples outside [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just started posting code samples from the wonderful <a href="http://spotthevuln.com/" target="_self">SpotTheVuln.com</a> on the walls in our building on 11&#215;17 cardstock behind thin plexiglass panes so they can be annotated with dry erase marker when people solve them or have comments:</p>
<p><a href="http://george.savetheband.net/wp-content/uploads/2010/06/stv.jpg"><img class="alignnone size-medium wp-image-282" title="SpotTheVuln on the Wall" src="http://george.savetheband.net/wp-content/uploads/2010/06/stv-225x300.jpg" alt="" width="225" height="300" /></a></p>
<p>I love the site but wanted to branch out a little bit into some samples outside of the PHP and WordPress world. In my first attempt, I didn&#8217;t branch very far, and it&#8217;s a bit longer than I would have preferred, but here it is &#8212; from MoinMoin. Hopefully I included enough information to find the issue.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> getUserId<span style="color: black;">&#40;</span>request, searchName<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;
    Get the user ID for a specific user NAME.
&nbsp;
    @param searchName: the user name to look up
    @rtype: string
    @return: the corresponding user ID or None
    &quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> searchName:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
    cfg = request.<span style="color: black;">cfg</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        _name2id = cfg._name2id
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">AttributeError</span>:
        arena = <span style="color: #483d8b;">'user'</span>
        key = <span style="color: #483d8b;">'name2id'</span>
        cache = caching.<span style="color: black;">CacheEntry</span><span style="color: black;">&#40;</span>request, arena, key<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            _name2id = <span style="color: #dc143c;">pickle</span>.<span style="color: black;">loads</span><span style="color: black;">&#40;</span>cache.<span style="color: black;">content</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">pickle</span>.<span style="color: black;">UnpicklingError</span>, <span style="color: #008000;">IOError</span>, <span style="color: #008000;">EOFError</span>, <span style="color: #008000;">ValueError</span><span style="color: black;">&#41;</span>:
            _name2id = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
        cfg._name2id = _name2id
    <span style="color: #008000;">id</span> = _name2id.<span style="color: black;">get</span><span style="color: black;">&#40;</span>searchName, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">id</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> userid <span style="color: #ff7700;font-weight:bold;">in</span> getUserList<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span>:
            name = User<span style="color: black;">&#40;</span>request, <span style="color: #008000;">id</span>=userid<span style="color: black;">&#41;</span>.<span style="color: black;">name</span>
            _name2id<span style="color: black;">&#91;</span>name<span style="color: black;">&#93;</span> = userid
        cfg._name2id = _name2id
        arena = <span style="color: #483d8b;">'user'</span>
        key = <span style="color: #483d8b;">'name2id'</span>
        cache = caching.<span style="color: black;">CacheEntry</span><span style="color: black;">&#40;</span>request, arena, key<span style="color: black;">&#41;</span>
        cache.<span style="color: black;">update</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">pickle</span>.<span style="color: black;">dumps</span><span style="color: black;">&#40;</span>_name2id, PICKLE_PROTOCOL<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">id</span> = _name2id.<span style="color: black;">get</span><span style="color: black;">&#40;</span>searchName, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">id</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> User:
    <span style="color: #483d8b;">&quot;&quot;&quot;A MoinMoin User&quot;&quot;&quot;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request, <span style="color: #008000;">id</span>=<span style="color: #008000;">None</span>, name=<span style="color: #483d8b;">&quot;&quot;</span>, password=<span style="color: #008000;">None</span>,
                 auth_username=<span style="color: #483d8b;">&quot;&quot;</span>, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot; Initialize User object
&nbsp;
        @param request: the request object
        @param id: (optional) user ID
        @param name: (optional) user name
        @param password: (optional) user password (unicode)
        @param auth_username: (optional) already authenticated user name
                              (e.g. when using http basic auth) (unicode)&quot;&quot;&quot;</span>
        <span style="color: #008000;">self</span>._cfg = request.<span style="color: black;">cfg</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">valid</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">trusted</span> = <span style="color: #ff4500;">0</span>
        <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> = <span style="color: #008000;">id</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">auth_username</span> = auth_username
        <span style="color: #008000;">self</span>.<span style="color: black;">auth_method</span> = kw.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'auth_method'</span>, <span style="color: #483d8b;">'internal'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">auth_attribs</span> = kw.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'auth_attribs'</span>, <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;"># we got an already authenticated username:</span>
        check_pass = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">self</span>.<span style="color: black;">auth_username</span>:
            <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> = getUserId<span style="color: black;">&#40;</span>request, <span style="color: #008000;">self</span>.<span style="color: black;">auth_username</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> password <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #008000;">None</span>:
                check_pass = <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">load_from_id</span><span style="color: black;">&#40;</span>check_pass<span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">name</span> == <span style="color: #008000;">self</span>.<span style="color: black;">auth_username</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">trusted</span> = <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">self</span>.<span style="color: black;">name</span>:
            <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> = getUserId<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._request, <span style="color: #008000;">self</span>.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">load_from_id</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>:
                <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> = <span style="color: #008000;">self</span>.<span style="color: black;">make_id</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> = <span style="color: #008000;">self</span>.<span style="color: black;">make_id</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> __filename<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot; Get filename of the user's file on disk
        @rtype: string
        @return: full path and filename of user account file
        &quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._cfg.<span style="color: black;">user_dir</span>, <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: #483d8b;">&quot;...NONE...&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> save<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;&quot; Save user account data to user account file on disk.
&nbsp;
        This saves all member variables, except &quot;id&quot; and &quot;valid&quot; and
        those starting with an underscore.
        &quot;&quot;&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span>:
            <span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
        user_dir = <span style="color: #008000;">self</span>._cfg.<span style="color: black;">user_dir</span>
        filesys.<span style="color: black;">makeDirs</span><span style="color: black;">&#40;</span>user_dir<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">last_saved</span> = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
        data = <span style="color: #dc143c;">codecs</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.__filename<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">&quot;w&quot;</span>, config.<span style="color: black;">charset</span><span style="color: black;">&#41;</span>
        data.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;# Data saved '%s' for id '%s'<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>
            <span style="color: #dc143c;">time</span>.<span style="color: black;">strftime</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._cfg.<span style="color: black;">datetime_fmt</span>, <span style="color: #dc143c;">time</span>.<span style="color: black;">localtime</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
            <span style="color: #008000;">self</span>.<span style="color: #008000;">id</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        attrs = <span style="color: #008000;">vars</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        attrs.<span style="color: black;">sort</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">for</span> key, value <span style="color: #ff7700;font-weight:bold;">in</span> attrs:
            <span style="color: #ff7700;font-weight:bold;">if</span> key <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>._cfg.<span style="color: black;">user_transient_fields</span> <span style="color: #ff7700;font-weight:bold;">and</span> key<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">'_'</span>:
                <span style="color: #808080; font-style: italic;"># Encode list values</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> key <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'quicklinks'</span>, <span style="color: #483d8b;">'subscribed_pages'</span><span style="color: black;">&#93;</span>:
                    value = encodeList<span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span>
                line = u<span style="color: #483d8b;">&quot;%s=%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>key, <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>value<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                data.<span style="color: black;">write</span><span style="color: black;">&#40;</span>line<span style="color: black;">&#41;</span>
        data.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">disabled</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">valid</span> = <span style="color: #ff4500;">1</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://george.savetheband.net/2010/06/07/vulnerable-code-moinmoin-user/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java is not Python and Cygwin is not Linux</title>
		<link>http://george.savetheband.net/2010/05/07/java-is-not-python/</link>
		<comments>http://george.savetheband.net/2010/05/07/java-is-not-python/#comments</comments>
		<pubDate>Fri, 07 May 2010 06:19:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[beanshell]]></category>
		<category><![CDATA[bsh]]></category>
		<category><![CDATA[cygwin]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[repl]]></category>
		<category><![CDATA[required: class or array]]></category>
		<category><![CDATA[type erasure]]></category>
		<category><![CDATA[typechecking]]></category>

		<guid isPermaLink="false">http://george.savetheband.net/?p=262</guid>
		<description><![CDATA[I&#8217;m burning the midnight oil working on a project in Java and came upon a number of gripes, all right in a row, that I thought were all worth blogging about in case I can help make somebody else&#8217;s night a little bit better. So here are some things I learned today. Java is not [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m burning the midnight oil working on a project in Java and came upon a number of gripes, all right in a row, that I thought were all worth blogging about in case I can help make somebody else&#8217;s night a little bit better. So here are some things I learned today.</p>
<p><strong>Java is not Python.</strong> Java&#8217;s changes that introduced generics (to allow expressions like, for example, &#8220;Vector&lt;Integer&gt;&#8221;) were pretty much all in the compiler. The bytecode stays the same; the compiler just gets some additional data to use for typechecking. Then your beautifully generic Java 5.0 code undergoes a process called <a href="http://en.wikipedia.org/wiki/Generics_in_Java#Type_erasure">type erasure</a> producing the same &#8212; but better typechecked &#8212; bytecode that your old 1.4 code would have. The result is that when I, with my limited understanding of Java generics, tried to write overly dynamic code, the compiler scoffed.</p>
<p>&#8220;required: class or array&#8221;, it said. What it really meant was, &#8220;You can&#8217;t use a generic type in an instanceof operation, you dummy, because I&#8217;m about to erase that type and replace it with Object.&#8221; Doi.</p>
<p><strong>Cygwin is not Linux. </strong> Especially where Java is concerned. I spent about 20 minutes trying to figure out why I couldn&#8217;t pass the JDK an absolute classpath from Cygwin when relative classpaths worked just fine. It was because the JDK I was calling is Windows native, not Cygwin, so it doesn&#8217;t understand the Unix-style directory structure I was giving it.</p>
<p><strong>Java is not Python (redux).</strong> I&#8217;ve mostly been using Python for my various and sundry programming needs over the past couple of years. And it&#8217;s impressive how quickly one gets used to a REPL (read-eval-print-loop) &#8212; and how useful it is for quick debugging and answers.</p>
<p>For instance, I missed having a REPL when I had a simple question: can I typecast null to whatever object type I want (the answer is yes, by the way, which makes a lot of sense when you think about it)? I was in the midst of a fairly significant rewrite so I couldn&#8217;t just try it and run it. So I saw four choices: assume it would work and test it later, assume it wouldn&#8217;t work and rewrite it, look it up, or write a Java program to test it.</p>
<p>Turns out that there&#8217;s actually a fifth option: use the Java REPL. It&#8217;s called <a href="http://www.beanshell.org/">BeanShell</a> (or bsh), and I feel pretty much ridiculous for not having found it before. Maybe you&#8217;ll enjoy it.</p>
<p>Okay, back to work.</p>
]]></content:encoded>
			<wfw:commentRss>http://george.savetheband.net/2010/05/07/java-is-not-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

