<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Codebright&#039;s Blog</title>
	<atom:link href="http://codebright.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://codebright.wordpress.com</link>
	<description>Random thoughts on code</description>
	<lastBuildDate>Thu, 20 Sep 2012 12:45:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='codebright.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Codebright&#039;s Blog</title>
		<link>http://codebright.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://codebright.wordpress.com/osd.xml" title="Codebright&#039;s Blog" />
	<atom:link rel='hub' href='http://codebright.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Linear Algebra Review and numpy</title>
		<link>http://codebright.wordpress.com/2011/10/07/linear-algebra-review-and-numpy/</link>
		<comments>http://codebright.wordpress.com/2011/10/07/linear-algebra-review-and-numpy/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 22:23:56 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=203</guid>
		<description><![CDATA[I&#8217;ve signed up for the Machine Learning course from Stanford. One of the first week&#8217;s subject areas is a Linear Algebra Review, and the recommended software is GNU Octave. However, I&#8217;d prefer to use numpy and Python. Here&#8217;s my notes &#8230; <a href="http://codebright.wordpress.com/2011/10/07/linear-algebra-review-and-numpy/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=203&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve signed up for the <a href="http://www.ml-class.org" title="Machine Learning">Machine Learning</a> course from Stanford.  One of the first week&#8217;s subject areas is a Linear Algebra Review, and the recommended software is <a href="http://www.gnu.org/software/octave/" title="GNU Octave">GNU Octave</a>.  However, I&#8217;d prefer to use <a href="http://numpy.scipy.org/" title="numpy">numpy</a> and Python.  Here&#8217;s my notes so far.</p>
<p>After installing numpy, you can define a matrix in one of the following ways:<br />
<pre class="brush: python;">
from numpy import matrix

A = matrix( ( (3,4),(2,16)))
# or
A = matrix(&quot;3 4; 2 16&quot;)
# or even
A = matrix( (3,4,2,16) )
A.resize( (2,2) )
</pre></p>
<p>You can produce the transpose of A, written A<sup>T</sup> with:<br />
<pre class="brush: python;">
print(&quot;transpose of A = \n%s&quot; % A.transpose() )
</pre><br />
producing output:<br />
<pre class="brush: plain;">
transpose of A =
[[ 3  2]
 [ 4 16]]
</pre></p>
<p>or if you already have a numpy.array, you can create it from that.  We&#8217;ll see later why you need to use numpy.matrix and not numpy.array:</p>
<p><pre class="brush: python;">
from numpy import matrix, array

A2 = array( ( (3,4),(2,16)))
A = matrix(A2)

print(&quot;A[1,0]=%s&quot; % A[1,0])
</pre></p>
<p>This produces<br />
<pre class="brush: plain;">
A[1,0]=2
</pre></p>
<p>Note that, when referring to individual elements of the matrix, numpy is 0-based, so A[1,0] is the 2nd row, 1st column.</p>
<p>Adding two matrices and multiplying a matrix by scalar is straightforward.  Taking the inverse of a matrix is a little less obvious.  The example uses matrix A as defined above:</p>
<p><pre class="brush: python;">
from numpy import linalg
inverseOfA = linalg.inv(A)
print(&quot;inverseOfA =\n%s&quot; % inverseOfA)
print(&quot;A * inverseOfA =\n%s&quot; % (A * inverseOfA) )
</pre></p>
<p>shows the inverse, written A<sup>-1</sup>, and shows that multiplying A and A<sup>-1</sup> produces the identity matrix:<br />
<pre class="brush: plain;">
inverseOfA =
[[ 0.4   -0.1  ]
 [-0.05   0.075]]
A * inverseOfA =
[[ 1.  0.]
 [ 0.  1.]]
</pre></p>
<p>Finally, matrix multiplication is the reason to use numpy.matrix, and numpy.array.  Here&#8217;s an example:</p>
<p><pre class="brush: python;">
arrayA = array( ( (3,4),(2,16)))
matrixA = matrix(arrayA)

print &quot;Multiplication as array = \n%s&quot; % (arrayA * arrayA)
print &quot;Multiplication as matrix = \n%s&quot; % (matrixA * matrixA)
</pre></p>
<p>outputs:<br />
<pre class="brush: plain;">
Multiplication as array =
[[  9  16]
 [  4 256]]
Multiplication as matrix =
[[ 17  76]
 [ 38 264]]
</pre></p>
<p>In the array multiplication, Result<sub>ij</sub> = A<sub>ij</sub> * A<sub>ij</sub>, which is not what is needed for matrix multiplication!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/203/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/203/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=203&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2011/10/07/linear-algebra-review-and-numpy/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>Tuple Trivia</title>
		<link>http://codebright.wordpress.com/2011/07/05/tuple-trivia/</link>
		<comments>http://codebright.wordpress.com/2011/07/05/tuple-trivia/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 22:30:24 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=160</guid>
		<description><![CDATA[A couple of minor points regarding tuples. When you take a slice of a tuple, there are 3 parameters: &#8211; the start index &#8211; the end index &#8211; the step which produces: It doesn&#8217;t matter that, in the second instance, &#8230; <a href="http://codebright.wordpress.com/2011/07/05/tuple-trivia/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=160&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A couple of minor points regarding tuples.  When you take a slice of a tuple, there are 3 parameters:<br />
  &#8211; the start index<br />
  &#8211; the end index<br />
  &#8211; the step</p>
<p><pre class="brush: python;">
aTuple = (1, 2, 3, 4, 5)
print (aTuple[1:3])
print (aTuple[0:7])
print(aTuple[3:1:-1])
</pre><br />
which produces:<br />
<pre class="brush: plain;">
(2, 3)
(1, 2, 3, 4, 5)
(4, 3)
</pre></p>
<p>It doesn&#8217;t matter that, in the second instance, the end index is beyond the last index of the string.  Also, the end index is excluded.</p>
<p>If you want to go to the start of the tuple, then you need to set the end index to -1:</p>
<p><pre class="brush: python;">
print(aTuple[3:-1:-1])
</pre></p>
<p>But this doesn&#8217;t produce the expected result.<br />
<pre class="brush: plain;">
( )
</pre></p>
<p>This is because negative indexes are from the end of the tuple.  So -1 is the last element in the tuple.</p>
<p><pre class="brush: python;">
print(aTuple[2:-1])
</pre></p>
<p>produces:<br />
<pre class="brush: plain;">
(3, 4)
</pre></p>
<p>Again, this excludes the final index.  To include either the start or the end of the tuple as the final element of the result, the end index should be left empty:</p>
<p><pre class="brush: python;">
print(aTuple[2:])
print(aTuple[2::-1])
</pre><br />
giving:<br />
<pre class="brush: plain;">
(3, 4, 5)
(3, 2, 1)
</pre></p>
<p>Finally, in most cases where you can use a tuple, you can use a list instead:</p>
<p><pre class="brush: python;">
aList = list(aTuple)

print (aList[1:3])
print (aList[0:7])
print(aList[3:1:-1])
print(aList[3:-1:-1])
print(aList[2:-1])
print(aList[2:])
print(aList[2::-1])
</pre></p>
<p>producing similar results as before, but lists instead of tuples:<br />
<pre class="brush: plain;">
[2, 3]
[1, 2, 3, 4, 5]
[4, 3]
[]
[3, 4]
[3, 4, 5]
[3, 2, 1]
</pre></p>
<p>But this doesn&#8217;t work for the  % operator:</p>
<p><pre class="brush: python;">
print(&quot;aTuple[0]=%s, aTuple[1]=%s, aTuple[2]=%s, aTuple[3]=%s, aTuple[4]=%s&quot; % aTuple)
print(&quot;aList[0]=%s, aList[1]=%s, aList[2]=%s, aList[3]=%s, aList[4]=%s&quot; % aList)
</pre></p>
<p><pre class="brush: plain;">
aTuple[0]=1, aTuple[1]=2, aTuple[2]=3, aTuple[3]=4, aTuple[4]=5
Traceback (most recent call last):
  File &quot;c:/prr/cgibin/data/prr/codebright/tuple.py&quot;, line 29, in &lt;module&gt;
    print(&quot;aList[0]=%s, aList[1]=%s, aList[2]=%s, aList[3]=%s, aList[4]=%s&quot; % aList)
TypeError: not enough arguments for format string
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/160/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=160&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2011/07/05/tuple-trivia/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>globals and __main__: a Python gotcha</title>
		<link>http://codebright.wordpress.com/2011/06/15/globals-and-__main__-a-python-gotcha/</link>
		<comments>http://codebright.wordpress.com/2011/06/15/globals-and-__main__-a-python-gotcha/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 21:57:59 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=154</guid>
		<description><![CDATA[One of the good features is the lack of gotchas. I define gotchas as traps for the unwary programmer, where something unexpected happens. Thankfully these are rare in Python. But the following is one that is worth knowing about. Consider &#8230; <a href="http://codebright.wordpress.com/2011/06/15/globals-and-__main__-a-python-gotcha/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=154&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>One of the good features is the lack of gotchas.  I define gotchas as traps for the unwary programmer, where something unexpected happens.  Thankfully these are rare in Python.  But the following is one that is worth knowing about.  Consider two Python modules, named main_module.py and sub_module.py.</p>
<p>First main_module.py:<br />
<pre class="brush: python;">
g_main_value = None

def get_main_value():
    return g_main_value


def main_test():
    print(&quot;sub_value = %s&quot; % get_sub_value())


from sub_module import get_sub_value, sub_test, sub_init

def main_init():
    global g_main_value

    g_main_value = 23


if __name__ == &quot;__main__&quot;:
    main_init()
    sub_init()

    main_test()
    sub_test()

    print(&quot;main_value (in main_module) = %s&quot; % get_main_value() )
</pre></p>
<p>Then sub_module.py:<br />
<pre class="brush: python;">
g_sub_value = None

def get_sub_value():
    return g_sub_value


def sub_test():
    print(&quot;main_value (in sub_module) = %s&quot; % get_main_value())


def sub_init():
    global g_sub_value

    g_sub_value = 31


from main_module import get_main_value
</pre></p>
<p>The output is:<br />
<pre class="brush: plain;">
sub_value = 31
main_value (in sub_module) = None
main_value (in main_module) = 23
</pre></p>
<p>What&#8217;s happening?  A global with 2 different values?  Add the following code to the bottom of main_module:</p>
<p><pre class="brush: python;">
def show_globals(module_name):
    mod = __import__(module_name)
    print(module_name)
    for k in dir(mod):
        if k.startswith(&quot;g_&quot;):
            print(&quot;  %s: %s&quot; % (k, getattr(mod, k)))
    print(&quot;&quot;)


if __name__ == &quot;__main__&quot;:
    print(&quot;&quot;)
    show_globals(&quot;__main__&quot;)
    show_globals(&quot;main_module&quot;)
    show_globals(&quot;sub_module&quot;)
</pre></p>
<p>The output is:<br />
<pre class="brush: plain;">
__main__
  g_main_value: 23

main_module
  g_main_value: None

sub_module
  g_sub_value: 31
</pre></p>
<p>This gives us a clue as to what&#8217;s happening: the __main__ module may be loaded twice if used by another module.  If you wanted to set a global in the __main__ module that is usable by other modules, then one way to do it is:</p>
<p>Add the following to main_module.py<br />
<pre class="brush: python;">
mod = __import__(&quot;main_module&quot;)
setattr(mod, &quot;g_main_value2&quot;, 34)

if __name__ == &quot;__main__&quot;:
    print(&quot;&quot;)
    show_globals(&quot;__main__&quot;)
    show_globals(&quot;main_module&quot;)
    show_globals(&quot;sub_module&quot;)
</pre></p>
<p>And the output will be<br />
<pre class="brush: plain;">

__main__
  g_main_value: 23
  g_main_value2: None

main_module
  g_main_value: None
  g_main_value2: 34

sub_module
  g_sub_value: 31
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=154&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2011/06/15/globals-and-__main__-a-python-gotcha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>Edge case for split / explode</title>
		<link>http://codebright.wordpress.com/2011/04/01/edge-case-for-split-explode/</link>
		<comments>http://codebright.wordpress.com/2011/04/01/edge-case-for-split-explode/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 06:02:03 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=150</guid>
		<description><![CDATA[During recent coding, using PHP, I found that the explode function behaves in a non-ideal way (for me) when trying to split an empty string: produces: I was expecting (needing?) an empty array. After thinking about it a bit more, &#8230; <a href="http://codebright.wordpress.com/2011/04/01/edge-case-for-split-explode/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=150&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>During recent coding, using PHP, I found that the explode function behaves in a non-ideal way (for me) when trying to split an empty string:</p>
<p><pre class="brush: php;">
&lt;?php

$res = explode(&quot;,&quot;, &quot;&quot;);
print_r($res);

?&gt;
</pre></p>
<p>produces:</p>
<p><pre class="brush: plain;">
Array
(
    [0] =&gt;
)
</pre></p>
<p>I was expecting (needing?) an empty array.  After thinking about it a bit more, it is clear that returning a single empty string is a logical return value.  However, different languages have different returns for this special case.  Python (2.6.4 and 3.1.2) are both like PHP (5.3.5), but Perl (5.10.1) behaves differently:</p>
<p>For PHP:</p>
<p><pre class="brush: php;">
&lt;?php
function test_explode($txt)
{
    print(&quot;Exploding '$txt' to give [&quot; );
    $sep = &quot;&quot;;
    $res = explode(&quot;,&quot;, $txt);
    foreach ($res as $elt)
    {
        print &quot;$sep'$elt'&quot;;
        $sep = &quot;, &quot;;
    }
    print &quot;]\n&quot;;

}

test_explode(&quot;a,b&quot;);
test_explode(&quot;,&quot;);
test_explode(&quot;&quot;);

?&gt;
</pre></p>
<p>produces:</p>
<p><pre class="brush: plain;">
Exploding 'a,b' to give ['a', 'b']
Exploding ',' to give ['', '']
Exploding '' to give ['']
</pre></p>
<p>For Python:</p>
<p><pre class="brush: python;">
def test_split(txt):
    print(&quot;Splitting '%s' to give %s&quot; % (txt, txt.split(&quot;,&quot;)))

test_split(&quot;a,b&quot;)
test_split(&quot;,&quot;)
test_split(&quot;&quot;)
</pre></p>
<p>produces:</p>
<p><pre class="brush: plain;">
Splitting 'a,b' to give ['a', 'b']
Splitting ',' to give ['', '']
Splitting '' to give ['']
</pre></p>
<p>For Perl:</p>
<p><pre class="brush: perl;">

sub test_split
{
    my $txt = shift;
    my @res = split(&quot;,&quot;, $txt);
    print(&quot;Splitting '$txt' to give [&quot;);
    my $sep = &quot;&quot;;
    foreach my $elt (@res)
    {
        print &quot;$sep'$elt'&quot;;
        $sep = &quot;, &quot;;
    }
    print &quot;]\n&quot;;
}


test_split(&quot;a,b&quot;);
test_split(&quot;,&quot;);
test_split(&quot;&quot;);

</pre></p>
<p>produces:</p>
<p><pre class="brush: plain;">
Splitting 'a,b' to give ['a', 'b']
Splitting ',' to give []
Splitting '' to give []
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/150/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/150/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=150&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2011/04/01/edge-case-for-split-explode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>Reading gzip files in Python &#8211; fast!</title>
		<link>http://codebright.wordpress.com/2011/03/25/139/</link>
		<comments>http://codebright.wordpress.com/2011/03/25/139/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 07:02:54 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=139</guid>
		<description><![CDATA[I have been doing lots of parsing of Apache log files recently with Python. Speed is of the essence, so I was interested to know if the speed issues mentioned in http://bugs.python.org/issue7471 are still relevant. So I set out to &#8230; <a href="http://codebright.wordpress.com/2011/03/25/139/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=139&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I have been doing lots of parsing of Apache log files recently with Python.  Speed is of the essence, so I was interested to know if the speed issues mentioned in <a href="http://bugs.python.org/issue7471">http://bugs.python.org/issue7471</a> are still relevant.  So I set out to time it, under Python (v2.6.4 and v3.1.2, both on Fedora 13).</p>
<p>My test data consists of 950,000 lines in 5 gzipped Apache log files.  I compared the times using the Python gzip module, and the zcat method suggested in <a href="http://bugs.python.org/issue7471">http://bugs.python.org/issue7471</a>.</p>
<p>A quick summary of results: yes, the issue is still relevant.   The average times are:</p>
<p>For Python 2.6.4
<ul>
<li>gzip.open &#8211; 9.5 seconds</li>
<li>zcat and pipe &#8211; 2.3 seconds</li>
</ul>
<p>For Python 3.1.2
<ul>
<li>gzip.open &#8211; 11.6 seconds</li>
<li>zcat and pipe &#8211; 2.7 seconds</li>
</ul>
<p>Below are the details. First, the source code to time the tests:</p>
<p><pre class="brush: python;">
import os
import sys

if sys.version.startswith(&quot;3&quot;):
    import io
    io_method = io.BytesIO
else:
    import cStringIO
    io_method = cStringIO.StringIO

import gzip
import subprocess
import time

dirname = &quot;test&quot;
fl = os.listdir(dirname)

fl.sort()

ttime = [0, 0]
runs = 5

for i in range(2 * runs):
    st = time.time()

    for fn in fl:
        if not fn.endswith(&quot;.gz&quot;):
            continue

        cc = 0
        lc = 0
        sz = 0

        fullfn = os.path.join(dirname, fn)
        sz += os.stat(fullfn)[6]
        if i % 2 == 0:
            fh = gzip.GzipFile(fullfn, &quot;r&quot;)
        else:
            p = subprocess.Popen([&quot;zcat&quot;, fullfn], stdout = subprocess.PIPE)
            fh = io_method(p.communicate()[0])
            assert p.returncode == 0

        for line in fh:
            lc += 1
            cc += len(line)

    et = time.time()
    dt = et - st

    ttime[i % 2] += dt
    print(&quot;time-taken = %0.2f seconds, 1000 characters per second = %0.0f, file size per second = %0.0f, character count=%s, line count=%s file size = %s&quot; % (dt, 0.001 * cc / dt, 0.001 * sz / dt, cc, lc, sz))

print(&quot;\nAverages&quot;)
print(&quot;  gzip.open - %0.1f seconds&quot; % (ttime[0] / runs))
print(&quot;  zcat and pipe - %0.1f seconds&quot; % (ttime[1] / runs))
</pre></p>
<p>Timings for Python 2.6.4:<br />
<pre class="brush: plain;">
time-taken = 9.71 seconds, 1000 characters per second = 5237, file size per second = 480, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.28 seconds, 1000 characters per second = 22300, file size per second = 2044, character count=50859394, line count=194151 file size = 4661207
time-taken = 9.48 seconds, 1000 characters per second = 5363, file size per second = 492, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.24 seconds, 1000 characters per second = 22750, file size per second = 2085, character count=50859394, line count=194151 file size = 4661207
time-taken = 9.44 seconds, 1000 characters per second = 5389, file size per second = 494, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.30 seconds, 1000 characters per second = 22156, file size per second = 2031, character count=50859394, line count=194151 file size = 4661207
time-taken = 9.42 seconds, 1000 characters per second = 5397, file size per second = 495, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.26 seconds, 1000 characters per second = 22516, file size per second = 2064, character count=50859394, line count=194151 file size = 4661207
time-taken = 9.61 seconds, 1000 characters per second = 5293, file size per second = 485, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.31 seconds, 1000 characters per second = 22033, file size per second = 2019, character count=50859394, line count=194151 file size = 4661207

Averages
  gzip.open - 9.5 seconds
  zcat and pipe - 2.3 seconds
</pre></p>
<p>Timings for Python 3.1.2:<br />
<pre class="brush: plain;">
time-taken = 11.65 seconds, 1000 characters per second = 4364, file size per second = 400, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.87 seconds, 1000 characters per second = 17691, file size per second = 1621, character count=50859394, line count=194151 file size = 4661207
time-taken = 11.66 seconds, 1000 characters per second = 4362, file size per second = 400, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.56 seconds, 1000 characters per second = 19834, file size per second = 1818, character count=50859394, line count=194151 file size = 4661207
time-taken = 11.54 seconds, 1000 characters per second = 4408, file size per second = 404, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.64 seconds, 1000 characters per second = 19295, file size per second = 1768, character count=50859394, line count=194151 file size = 4661207
time-taken = 11.58 seconds, 1000 characters per second = 4393, file size per second = 403, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.59 seconds, 1000 characters per second = 19659, file size per second = 1802, character count=50859394, line count=194151 file size = 4661207
time-taken = 11.68 seconds, 1000 characters per second = 4354, file size per second = 399, character count=50859394, line count=194151 file size = 4661207
time-taken = 2.97 seconds, 1000 characters per second = 17123, file size per second = 1569, character count=50859394, line count=194151 file size = 4661207

Averages
  gzip.open - 11.6 seconds
  zcat and pipe - 2.7 seconds
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/139/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=139&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2011/03/25/139/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>Python Standard Library</title>
		<link>http://codebright.wordpress.com/2011/03/13/python-standard-library/</link>
		<comments>http://codebright.wordpress.com/2011/03/13/python-standard-library/#comments</comments>
		<pubDate>Sun, 13 Mar 2011 15:40:13 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=131</guid>
		<description><![CDATA[There are some gems in the Python standard library which, once found, get regular use &#8211; at least by me. Here are some of them. 1. enumerate A built-in function, which allows you to replace code like this: with the &#8230; <a href="http://codebright.wordpress.com/2011/03/13/python-standard-library/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=131&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There are some gems in the Python standard library which, once found, get regular use &#8211; at least by me.  Here are some of them.</p>
<p>1. <strong>enumerate</strong></p>
<p>A built-in function, which allows you to replace code like this:</p>
<p><pre class="brush: python;">
day_list = [&quot;Monday&quot;, &quot;Tuesday&quot;, &quot;Wednesday&quot;, &quot;Thursday&quot;, &quot;Friday&quot;, &quot;Saturday&quot;, &quot;Sunday&quot;]
for day_index in range(len(day_list)):
    day_name = day_list[day_index]
    print(day_index, day_name)
</pre></p>
<p>with the more succinct:</p>
<p><pre class="brush: python;">
day_list = [&quot;Monday&quot;, &quot;Tuesday&quot;, &quot;Wednesday&quot;, &quot;Thursday&quot;, &quot;Friday&quot;, &quot;Saturday&quot;, &quot;Sunday&quot;]
for day_index, day_name in enumerate(day_list):
    print(day_index, day_name)
</pre><br />
&nbsp;</p>
<p>2. <strong>gzip.GzipFile</strong></p>
<p>I used this whilst processing Apache log files last week.  It offers compression to less than 10% of the original uncompressed size, but seems to take the same length of time to read/write, implying a good trade-off between processor use and hard-disk activity.  Having changed the open code from </p>
<p><pre class="brush: python;">
fh = open(&lt;logfile&gt;, &quot;r&quot;)
</pre></p>
<p>to:</p>
<p><pre class="brush: python;">
import gzip
...
fh = gzip.GzipFile(&lt;logfile&gt;, &quot;r&quot;)
</pre></p>
<p>the rest of the code runs unchanged.</p>
<p>Note: if you are running on Linux, then the issue of speed, documented at <a href="http://bugs.python.org/issue7471">http://bugs.python.org/issue7471</a>, is relevant, and the zcat approach is faster.<br />
&nbsp;</p>
<p>3. <strong>collections.defaultdict</strong></p>
<p>This provides a dictionary, which initialises a key on first read using a method.  </p>
<p>For instance:<br />
<pre class="brush: python;">
import collections
...
zerodict = collections.defaultdict(int)
print(zerodict[&quot;key&quot;], zerodict[4])
</pre></p>
<p>produces: </p>
<p><pre class="brush: plain;">
0 0
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/131/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=131&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2011/03/13/python-standard-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>Python regular expression surprise</title>
		<link>http://codebright.wordpress.com/2011/02/19/python-regular-expression-surprise/</link>
		<comments>http://codebright.wordpress.com/2011/02/19/python-regular-expression-surprise/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 07:19:08 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=117</guid>
		<description><![CDATA[I came across this regular expression anomaly recently in Python. The regular expression was more complex, but this example illustrates the idea. Try and predict the outcome (should work with Python 2.5 &#8211; Python 3.1) This produces: a, bc, d &#8230; <a href="http://codebright.wordpress.com/2011/02/19/python-regular-expression-surprise/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=117&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I came across this regular expression anomaly recently in Python.  The regular expression was more complex, but this example illustrates the idea.</p>
<p>Try and predict the outcome (should work with Python 2.5 &#8211; Python 3.1)</p>
<p><pre class="brush: python;">
import re

abcd = &quot;abcd&quot;
ad = &quot;ad&quot;

cre = re.compile(r&quot;^(a)(bc)?(d)$&quot;)

mos1 = cre.match(abcd)
print(cre.sub(r&quot;\1, \2, \3&quot;, abcd))

mos2 = cre.match(ad)
print(cre.sub(r&quot;\1, \2, \3&quot;, ad))
</pre></p>
<p>This produces:</p>
<pre>a, bc, d
Traceback (most recent call last): 
  File "&lt;filename&gt;", line &lt;linenumber&gt;, in &lt;module&gt;
    print(cre.sub(r"\1, \2, \3", ad))
  File "C:\programs\Python25\lib\re.py", line 266, in filter
    return sre_parse.expand_template(template, match)
  File "C:\programs\Python25\lib\sre_parse.py", line 793, in expand_template
    raise error, "unmatched group"
sre_constants.error: unmatched group</pre>
<p>(Line numbers vary with different versions of Python &#8211; this is Python 2.5)</p>
<p>Adding the following code illustrates the problem:</p>
<p><pre class="brush: python;">
print(mos1.group(1), mos1.group(2), mos1.group(3) )
print(mos2.group(1), mos2.group(2), mos2.group(3) )
</pre></p>
<p>For Python 2.5, this outputs</p>
<pre>('a', 'bc', 'd')
('a', None, 'd')</pre>
<p>So now it is clear why it is failing, what is the solution.  First fix was:<br />
<pre class="brush: python;">
cre2 = re.compile(r&quot;^(a)((bc)?)(d)$&quot;)
print(cre2.sub(r&quot;\1, \2, \4&quot;, ad))
</pre></p>
<p>This fix works, but it has side-effects &#8211; the last group number has changed.  So a better solution might be:</p>
<p><pre class="brush: python;">
cre3 = re.compile(r&quot;^(a)((?:bc)?)(d)$&quot;)
print(cre3.sub(r&quot;\1, \2, \3&quot;, ad))
</pre></p>
<p>Using the non-capturing group notation, (?:&#8230;) the problem is fixed without side-effects.</p>
<p>I&#8217;m not entirely happy that the problem occurs in the first place, but it does.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/117/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/117/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=117&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2011/02/19/python-regular-expression-surprise/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>PHP and Python</title>
		<link>http://codebright.wordpress.com/2010/10/20/php-and-python/</link>
		<comments>http://codebright.wordpress.com/2010/10/20/php-and-python/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 13:05:32 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=112</guid>
		<description><![CDATA[My new job involves a lot more PHP, which seems closely related to Perl. There are a number of observations that I would make in the comparison between PHP and Python. 1. PHP is more verbose. In particular, PHP requires &#8230; <a href="http://codebright.wordpress.com/2010/10/20/php-and-python/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=112&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>My new job involves a lot more PHP, which seems closely related to Perl.  There are a number of observations that I would make in the comparison between PHP and Python.</p>
<p>1. PHP is more verbose.  In particular, PHP requires braces around code blocks, semi-colons, $ on variable names.  Python requires only the colon at the end of certain lines.</p>
<p>2. Both have good libraries.  However, the ability of Python to easily interface to shared libraries written in any language, and not specifically written for Python, is a big advantage, in my opinion.</p>
<p>3. PHP has more unexpected gotchas.  I hadn&#8217;t noticed this when writing in Python (the absence of a problem is less noticeable than the presence of the same problem).  One example I came across today:</p>
<p>is_file() tests for the existence of a file, as you would expect by the name.  But it is cached.  So if you are waiting for a file to disappear, and you repeatedly call is_file to test this, then you will wait for a long time.  You need to call clearstatcache() between each call to get an honest answer.  </p>
<p>Of course, the documentation states this.  But it also states that file_exists (an equivalent function) is also cached.  But it appears not to be (PHP v5.3.3):</p>
<p><pre class="brush: php;">
&lt;?php

print &quot;Waiting for test.txt to appear\n&quot;;
while (!is_file(&quot;test.txt&quot;))
{
}

print &quot;Waiting for test.txt to disappear\n&quot;;
while (True)
{
    sleep(.2);
    if (!is_file(&quot;test.txt&quot;))
    {
        print &quot;is_file detected disappearance\n&quot;;
        exit(0);
    }
    elseif (!file_exists(&quot;test.txt&quot;))
    {
        print &quot;file_exists detected disappearance\n&quot;;
        exit(0);
    }
}

?&gt;
</pre></p>
<p>Running this code (and creating, then deleting file test.txt) invariably results in the detection by file_exists, even though I have biased it to let is_file test it first.</p>
<p>So ideally you need accurate documentation.  But I think even better is to write in a way that requires minimal documentation.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/112/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=112&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2010/10/20/php-and-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>SendKeys in Linux</title>
		<link>http://codebright.wordpress.com/2010/06/27/sendkeys-in-linux/</link>
		<comments>http://codebright.wordpress.com/2010/06/27/sendkeys-in-linux/#comments</comments>
		<pubDate>Sun, 27 Jun 2010 20:37:30 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=108</guid>
		<description><![CDATA[SendKeys is a useful function in the Windows API which enables a program to send keystrokes. I was looking for an equivalent in Linux, first in Ubuntu at home, and then in Fedora 13 at work. For Ubuntu (Hardy Heron, &#8230; <a href="http://codebright.wordpress.com/2010/06/27/sendkeys-in-linux/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=108&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>SendKeys is a useful function in the Windows API which enables a program to send keystrokes.  I was looking for an equivalent in Linux, first in Ubuntu at home, and then in Fedora 13 at work.</p>
<p>For Ubuntu (Hardy Heron, 8.04), I found <a href="http://hoopajoo.net/projects/xautomation.html">xautomation</a>, which worked fine.  For many (but not all) of the non alpha-numeric keystrokes, you need to use the name of the key &#8211; there is a <a href="http://www.tcl.tk/man/tcl8.4/TkCmd/keysyms.htm">helpful list here</a>.</p>
<p>I tried xautomation with Fedora 13, but it was not happy.  So I had a look around for an alternative.  One possibility (I found them hard to find) was <a href="http://www.semicomplete.com/projects/xdotool/">xdotool</a>.  Of course, the syntax for sending keystrokes is slightly different!  It is slightly more consistent in that non-alphanumerics all need to be sent using the name of the key, so the helpful list (above) is still helpful!</p>
<p>I&#8217;ll try to post some examples at a later date.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/108/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/108/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=108&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2010/06/27/sendkeys-in-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
		<item>
		<title>Strange behaviour using ctypes in IronPython</title>
		<link>http://codebright.wordpress.com/2010/06/23/strange-behaviour-using-ctypes-in-ironpython/</link>
		<comments>http://codebright.wordpress.com/2010/06/23/strange-behaviour-using-ctypes-in-ironpython/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 22:16:35 +0000</pubDate>
		<dc:creator>codebright</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codebright.wordpress.com/?p=97</guid>
		<description><![CDATA[I came across some slightly unexpected behaviour with ctypes in IronPython. Maybe this is the wrong way to look at it &#8211; I should be amazed that ctypes works at all in IronPython. But I thought I would document it &#8230; <a href="http://codebright.wordpress.com/2010/06/23/strange-behaviour-using-ctypes-in-ironpython/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=97&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I came across some slightly unexpected behaviour with ctypes in IronPython.  Maybe this is the wrong way to look at it &#8211; I should be amazed that ctypes works at all in IronPython.  But I thought I would document it here.</p>
<p>This deals with DLLs, and so is Windows-centric.  I need to find out how / if ctypes works on Linux.</p>
<p>Start with a trivial DLL.  It contains a single function, nAdd, which takes an array of integers, and a length of the array, and returns the sum of the array elements:</p>
<p><pre class="brush: cpp;">
#ifdef __cplusplus
extern &amp;quot;C&amp;quot;
{
#endif


int nAdd(int * pnData, int nDataLen)
{
    int nTotal = 0;
    for (int i = 0; i &amp;lt; nDataLen; ++i)
    {
        nTotal = nTotal + pnData[i];
    }

    return nTotal;
}


#ifdef __cplusplus
}
#endif
</pre></p>
<p>and build it using MSYS / MinGW:</p>
<p><pre class="brush: cpp;">
gcc -c strange.cpp
gcc -fPIC -shared -o strange.dll strange.o
</pre></p>
<p>Now lets call the function in the DLL, using ctypes:<br />
<pre class="brush: python;">
import ctypes
import sys

# define an array of 3 integers 
array3type = ctypes.c_int * 3
array3 = array3type()
array3[0] = 4
array3[1] = 5
array3[2] = 21

# define an array of 2 integers 
array2type = ctypes.c_int * 2
array2 = array2type()
array2[0] = 65
array2[1] = 34


def call3then2_noTypes():
    print(&amp;quot;call3then2_noTypes&amp;quot;)
    dll = ctypes.cdll.LoadLibrary(&amp;quot;strange.dll&amp;quot;)

    dll.nAdd.restype = ctypes.c_int
    #dll.nAdd.argtypes = (ctypes.POINTER(ctypes.c_int), ctypes.c_int)

    try:
        print(&amp;quot;  %d&amp;quot; % dll.nAdd(array3, 3))
        print(&amp;quot;  %d&amp;quot; % dll.nAdd(array2, 2))
    except Exception:
        e = sys.exc_info()[1]
        print(&amp;quot;  %s&amp;quot; % e)
    print(&amp;quot;&amp;quot;)


def call2then3_noTypes():
    print(&amp;quot;call2then3_noTypes&amp;quot;)
    dll = ctypes.cdll.LoadLibrary(&amp;quot;strange.dll&amp;quot;)

    #dll.nAdd.restype = ctypes.c_int
    #dll.nAdd.argtypes = (ctypes.POINTER(ctypes.c_int), ctypes.c_int)

    try:
        print(&amp;quot;  %d&amp;quot; % dll.nAdd(array2, 2))
        print(&amp;quot;  %d&amp;quot; % dll.nAdd(array3, 3))
    except Exception:
        e = sys.exc_info()[1]
        print(&amp;quot;  %s&amp;quot; % e)
    print(&amp;quot;&amp;quot;)
    
    
call3then2_noTypes()
call2then3_noTypes()
</pre></p>
<p>For Python 2.5+ and Python 3.x, this correctly prints the following:<br />
<pre class="brush: plain;">
call3then2_noTypes
  30
  99

call2then3_noTypes
  99
  30
</pre></p>
<p>So the question is, what will it do in IronPython 2.6?</p>
<p>The answer is unexpected (at least, to me):<br />
<pre class="brush: plain;">
call3then2_noTypes
  30
  expected c_long_Array_3, got c_long_Array_2

call2then3_noTypes
  99
  expected c_long_Array_2, got c_long_Array_3
</pre><br />
It seems to be trying to learn the signature of the function from the first call, but unfortunately, in this case, getting it wrong.  Note that the first call to the function was successful in each case &#8211; it is the second call that is failing.</p>
<p>Two of the following three methods work for Python 2.5+, Python 3.x and IronPython 2.6:<br />
<pre class="brush: python;">
import ctypes
import sys

# define an array of 3 integers 
array3type = ctypes.c_int * 3
array3 = array3type()
array3[0] = 4
array3[1] = 5
array3[2] = 21

# define an array of 2 integers 
array2type = ctypes.c_int * 2
array2 = array2type()
array2[0] = 65
array2[1] = 34

def call():
    print(&amp;quot;call&amp;quot;)
    dll = ctypes.cdll.LoadLibrary(&amp;quot;strange.dll&amp;quot;)

    dll.nAdd.restype = ctypes.c_int
    dll.nAdd.argtypes = (ctypes.POINTER(ctypes.c_int), ctypes.c_int)

    try:
        print(&amp;quot;  %d&amp;quot; % dll.nAdd(array3, 3))
        print(&amp;quot;  %d&amp;quot; % dll.nAdd(array2, 2))
    except Exception:
        e = sys.exc_info()[1]
        print(&amp;quot;  %s&amp;quot; % e)
    print(&amp;quot;&amp;quot;)


def call_voidPointer():
    print(&amp;quot;call_voidPointer&amp;quot;)
    dll = ctypes.cdll.LoadLibrary(&amp;quot;strange.dll&amp;quot;)

    dll.nAdd.restype = ctypes.c_int
    dll.nAdd.argtypes = (ctypes.c_void_p, ctypes.c_int)

    print(&amp;quot;  %d&amp;quot; % dll.nAdd(array3, 3))
    print(&amp;quot;  %d&amp;quot; % dll.nAdd(array2, 2))
    print(&amp;quot;&amp;quot;)


def call_voidPointer_addressOf():
    print(&amp;quot;call_voidPointer_addressOf&amp;quot;)
    dll = ctypes.cdll.LoadLibrary(&amp;quot;strange.dll&amp;quot;)

    dll.nAdd.restype = ctypes.c_int
    dll.nAdd.argtypes = (ctypes.c_void_p, ctypes.c_int)

    print(&amp;quot;  %d&amp;quot; % dll.nAdd(ctypes.addressof(array3), 3))
    print(&amp;quot;  %d&amp;quot; % dll.nAdd(ctypes.addressof(array2), 2))
    print(&amp;quot;&amp;quot;)


call()
call_voidPointer()
call_voidPointer_addressOf()
</pre></p>
<p>Extra hint: the output for IronPython 2.6 is as follows:<br />
<pre class="brush: plain;">
call3then2
  expected c_long, got c_long_Array_3

call_voidPointer
  30
  99

call_voidPointer_addressOf
  30
  99
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codebright.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codebright.wordpress.com/97/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codebright.wordpress.com&#038;blog=13795092&#038;post=97&#038;subd=codebright&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codebright.wordpress.com/2010/06/23/strange-behaviour-using-ctypes-in-ironpython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/003c9b6392f17e091afd9461fbdd2347?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">codebright</media:title>
		</media:content>
	</item>
	</channel>
</rss>
