<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/"/>

<title>Jeff Epler's blog</title>
<modified>2012-02-28T03:19:16Z</modified>
<tagline>Photos, electronics, cnc, and more</tagline>
<author><name>Jeff Epler</name><email>jepler@unpythonic.net</email></author>
<entry>
<title>Every once in a while, Python is too slow</title>
<issued>2012-02-28T03:19:16Z</issued>
<modified>2012-02-28T03:19:16Z</modified>
<id>http://emergent.unpythonic.net/01330399156</id>
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/01330399156"/>
<content type="text/html" mode="escaped">

I recently acquired a USB-connected relay that controls a standard power outlet,
called the &amp;quot;USB NET POWER 8800&amp;quot;.  I'd ordered this with the knowledge that
there was a Python implementation of the control program that was said to run
on Linux.

&lt;p&gt;It does work, but I was stunned at how long it took to switch the outlet on
or off: a couple of seconds!  I should disclaim that it's running on a rather
underpowered machine (the OLPC XO-1 with a Geode x86 CPU @ 430MHz), but this
was way too long to be acceptable:
&lt;pre&gt;
$ time py-usbpower query
Power: on

real    0m2.690s
user    0m1.484s
sys     0m0.096s
&lt;/pre&gt;
With some detective work, I discovered that ctypes is doing things like running
the compiler, objdump(!) and ldconfig(!), several times (!!), at each
invocation of the program. (this is python2.5, but it looks like Python 2.7's
ctypes still does essentially the same thing, unfortunately)

&lt;p&gt;I set about to code this in C.  For my reward, I got a very fast-executing
program:
&lt;pre&gt;
$ time c-usbpower status
ON

real    0m0.007s
user    0m0.000s
sys     0m0.000s
&lt;/pre&gt;

&lt;p&gt;That's something like a 384x speedup.  Lesson?  ctypes has some very
substantial startup costs for loading a library.  It may be enough to make it
unsuitable for a short-lived program.

&lt;p&gt;In case it's useful to you, I enclose a copy of my usbpower program.  It's
under the terms of the GNU GPLv2.

&lt;p&gt;&lt;p&gt;&lt;b&gt;Files currently attached to this page:&lt;/b&gt;
&lt;table cellpadding=5&gt;&lt;col&gt;&lt;col style=&quot;text-align: right&quot;&gt;&lt;tr bgcolor=#eeeeee&gt;&lt;td&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01330399156/usbpower.c&quot;&gt;usbpower.c&lt;/a&gt;&lt;/td&gt;&lt;td&gt;3.4kB&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;
</content>
</entry>
<entry>
<title>sorttop: show the biggest values as a program runs</title>
<issued>2012-02-19T16:54:33Z</issued>
<modified>2012-02-19T16:54:33Z</modified>
<id>http://emergent.unpythonic.net/01329670473</id>
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/01329670473"/>
<content type="text/html" mode="escaped">
When I am looking for big disk users, I don't care about all the little items.
What would be great is to continuously see the biggest items encountered so
far.

&lt;p&gt;To this end, I've written a Python program I call 'sorttop'; it continually
reads stdin, sorts the first column according to magic (i.e., human numbers like from &amp;quot;du -h&amp;quot; work as expected), and shows the top items
read so far.  Example usage: &lt;tt&gt;du -hx / | python sorttop.py&lt;/tt&gt;

&lt;p&gt;&lt;b&gt;Update, Feb 20, 2012&lt;/b&gt;: Revised the script to work for more terminals;
fixes a traceback on the line 'bol = curses.tparm(ti_hpa, 0)' when TERM=screen.

&lt;p&gt;&lt;p&gt;&lt;b&gt;Files currently attached to this page:&lt;/b&gt;
&lt;table cellpadding=5&gt;&lt;col&gt;&lt;col style=&quot;text-align: right&quot;&gt;&lt;tr bgcolor=#eeeeee&gt;&lt;td&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01329670473/sorttop.py&quot;&gt;sorttop.py&lt;/a&gt;&lt;/td&gt;&lt;td&gt;3.3kB&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;</content>
</entry>
<entry>
<title>csql: perform sql queries on csv data</title>
<issued>2011-10-16T15:31:28Z</issued>
<modified>2011-10-16T15:31:28Z</modified>
<id>http://emergent.unpythonic.net/01318779088</id>
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/01318779088"/>
<content type="text/html" mode="escaped">

The websites I operate are flat-file based, so when I want to store
data it's easiest to write it in csv format.  But it's not particularly easy
to make queries on this data without additional software.

&lt;p&gt;I'd rather not fire up Open Office or try to figure out how to make awk
parse a quoted excel-format file, so I wrote 'csql', which reads a csv
file into an in-memory sql database, performs a query, and then writes
the result also in csv format.

&lt;p&gt;A short example:

&lt;p&gt;rsvp.csv:
&lt;blockquote&gt;&lt;pre&gt;
Buffy Summers,false,0
Xander Harris,true,2
Willow Rosenberg,true,1
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;rsvp.cols:
&lt;blockquote&gt;&lt;pre&gt;
name text
attend boolean
count integer
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Performing queries:
&lt;blockquote&gt;&lt;pre&gt;
$ csql rsvp.csv 'select sum(count) from t where attend=&quot;true&quot;'
3
$ csql rsvp.csv 'select name from t where attend=&quot;true&quot;'
Xander Harris
Willow Rosenberg
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;p&gt;&lt;b&gt;Files currently attached to this page:&lt;/b&gt;
&lt;table cellpadding=5&gt;&lt;col&gt;&lt;col style=&quot;text-align: right&quot;&gt;&lt;tr bgcolor=#eeeeee&gt;&lt;td&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01318779088/csql&quot;&gt;csql&lt;/a&gt;&lt;/td&gt;&lt;td&gt;3.4kB&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;

&lt;p&gt;</content>
</entry>
<entry>
<title>tnef2mime: automatically extract parts from winmail.dat</title>
<issued>2011-09-20T18:49:42Z</issued>
<modified>2011-09-20T18:49:42Z</modified>
<id>http://emergent.unpythonic.net/01316544582</id>
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/01316544582"/>
<content type="text/html" mode="escaped">

In her professional life, my fiancée routinely gets emails with attachments in
the 'winmail.dat' aka application/ms-tnef format.  It does her no good to
berate these prisoners of proprietary software, so I set out to provide her
with an easy-to-use solution that would work on her end.  Now, prompted by
&lt;a href=&quot;http://www.carbon-project.org/TNEF_or_how_to_lock_up_your_e_mails.html&quot;&gt;this blog entry&lt;/a&gt; I am posting it for others to use.

&lt;p&gt;There are a number of programs that can rescue data from this proprietary
attachment format, but I was not aware of a program that would automatically
convert the winmail.dat attachment to (a series of) regular mime attachments.
(it appears that &lt;a href=&quot;http://freshmeat.net/projects/ytnef_smtpd_py&quot;&gt;ytnef_smtpd&lt;/a&gt; may be such a program)

&lt;p&gt;So I wrote one, &lt;a href=&quot;http://media.unpythonic.net/emergent-files/01316544582/tnef2mime.py&quot;&gt;tnef2mime.py&lt;/a&gt;.   tnef2mime reads a message on
standard input, combs it for ms-tnef attachments, and uses the tnef(1) program
to extract their contents.  Then it takes the extracted files, adds them
as new MIME parts, and prints the whole resulting message.

&lt;p&gt;This is suitable for use in e.g. procmail:
&lt;blockquote&gt;&lt;pre&gt;
:0fw
| tnef2mime
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;Several steps are taken in order to minimize the chances for data loss:  Just
in case it did an imperfect job, it leaves the existing ms-tnef attachment
intact.  If any problem is encountered, the unmodified message is written.

&lt;p&gt;This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

&lt;p&gt;&lt;p&gt;&lt;b&gt;Files currently attached to this page:&lt;/b&gt;
&lt;table cellpadding=5&gt;&lt;col&gt;&lt;col style=&quot;text-align: right&quot;&gt;&lt;tr bgcolor=#eeeeee&gt;&lt;td&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01316544582/tnef2mime.py&quot;&gt;tnef2mime.py&lt;/a&gt;&lt;/td&gt;&lt;td&gt;3.1kB&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;
</content>
</entry>
<entry>
<title>CropGUI 0.1.1: now with gtk</title>
<issued>2009-07-24T02:19:06Z</issued>
<modified>2009-07-24T02:19:06Z</modified>
<id>http://emergent.unpythonic.net/01248401946</id>
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/01248401946"/>
<content type="text/html" mode="escaped">
&lt;div style=&quot;float:right;clear:right&quot;&gt;&lt;!-- cropgtk.png--&gt;&lt;div class=albumouter style=width:306px id=&gt;&lt;div class=albumimage style=&quot;width:306px;margin-left:0px;&quot;&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01248401946/cropgtk.png&quot; class=&quot;thickbox&quot; rel=&quot;album&quot; title=&quot;Gtk version of cropgui&quot;&gt;&lt;img src=&quot;http://media.unpythonic.net/emergent-files/01248401946/cropgtk-small.jpg&quot; width=300 height=259&gt;&lt;/a&gt;&lt;div &gt;&lt;div style=&quot;float: right&quot; &gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01248401946/cropgtk.png&quot;&gt;&lt;img class=zoom src=&quot;http://media.unpythonic.net/emergent-files/default/zoom.png&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01248401946/cropgtk.png&quot;&gt;Gtk version of cropgui&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a href=&quot;http://emergent.unpythonic.net/01235516977&quot;&gt;Earlier this year&lt;/a&gt;, I released a
program for lossless cropping of jpeg images.  This week, based on
feedback from Ingrid, I ported the program to gtk (it originally used
tkinter).</content>
</entry>
<entry>
<title>Remebering values between runs of emc</title>
<issued>2009-05-25T21:20:11Z</issued>
<modified>2009-05-25T21:20:11Z</modified>
<id>http://emergent.unpythonic.net/01243286411</id>
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/01243286411"/>
<content type="text/html" mode="escaped">This is a userspace hal component which stores values to disk so that it can be preserved from run to run.
&lt;h3&gt;Usage&lt;/h3&gt; &lt;pre&gt;loadusr -W remember v1 v2 f:floatv u:unsignedv&lt;/pre&gt;</content>
</entry>
<entry>
<title>Show recent e-mail in screen title bar or status bar</title>
<issued>2009-03-17T16:19:28Z</issued>
<modified>2009-03-17T16:19:28Z</modified>
<id>http://emergent.unpythonic.net/01237306768</id>
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/01237306768"/>
<content type="text/html" mode="escaped">
&amp;quot;lastmail&amp;quot; parses a procmail log file and extracts information about the
most recent received e-mail, printing it in the form
&lt;tt&gt;definbox: Logwatch for lamp (Linux)  (8 minutes ago)&lt;/tt&gt;.  This
is useful as a backtick substitution in screenrc:
&lt;pre style=&quot;margin-left:4ex&quot;&gt;
backtick 1 30 30 lastmail
hardstatus string &quot;%H %n%?: %t%? %h  %1`&quot;
&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Files currently attached to this page:&lt;/b&gt;
&lt;table cellpadding=5&gt;&lt;col&gt;&lt;col style=&quot;text-align: right&quot;&gt;&lt;tr bgcolor=#eeeeee&gt;&lt;td&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01237306768/lastmail&quot;&gt;lastmail&lt;/a&gt;&lt;/td&gt;&lt;td&gt;2.5kB&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;
</content>
</entry>
<entry>
<title>cropgui: A Linux GUI for Lossless JPEG Cropping</title>
<issued>2009-02-24T23:09:37Z</issued>
<modified>2009-02-24T23:09:37Z</modified>
<id>http://emergent.unpythonic.net/01235516977</id>
<link rel="alternate" type="text/html" href="http://emergent.unpythonic.net/01235516977"/>
<content type="text/html" mode="escaped">
&lt;div style=&quot;float:right;clear:right&quot;&gt;&lt;!-- cropgui.jpg--&gt;&lt;div class=albumouter style=width:306px id=&gt;&lt;div class=albumimage style=&quot;width:306px;margin-left:0px;&quot;&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01235516977/cropgui.jpg&quot; class=&quot;thickbox&quot; rel=&quot;album&quot; title=&quot;Cropping a tiny insect&quot;&gt;&lt;img src=&quot;http://media.unpythonic.net/emergent-files/01235516977/cropgui-small.jpg&quot; width=300 height=228&gt;&lt;/a&gt;&lt;div &gt;&lt;div style=&quot;float: right&quot; &gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01235516977/cropgui.jpg&quot;&gt;&lt;img class=zoom src=&quot;http://media.unpythonic.net/emergent-files/default/zoom.png&quot;&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href=&quot;http://media.unpythonic.net/emergent-files/01235516977/cropgui.jpg&quot;&gt;Cropping a tiny insect&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;b&gt;Update&lt;/b&gt;: See the &lt;a href=&quot;http://emergent.unpythonic.net/01248401946&quot;&gt;newer version of cropgui&lt;/a&gt;

&lt;p&gt;Of the pictures from my recent trip I'd like to put online, I've found
that in 75% of the cases where I want to retouch the photo, it's to crop
it and nothing else.  Since I shoot in jpeg, it's a lossy process to
load the jpeg in gimp, crop it, and write the result.

&lt;p&gt;But it turns out that debian's jpegtran has a &amp;quot;-crop&amp;quot; flag which
performs lossless cropping of jpeg images as long as the crop is to a
multiple of what the manpage calls the &amp;quot;iMCU boundary&amp;quot;, a (usually?) 8x8
block of pixels.  This feature was pioneered by Guido of &lt;a href=&quot;http://jpegclub.org/&quot;&gt;jpegclub.org&lt;/a&gt; some years ago.

&lt;p&gt;There's apparently a nice &lt;a href=&quot;http://www.softpedia.com/progScreenshots/Jpegcrop-Screenshot-91058.html&quot;&gt;Windows front-end to this program&lt;/a&gt;, but I didn't find a Linux one.  So I wrote one!  It's pretty basic,
but it gets the job done.  You can download it below.</content>
</entry>
</feed>

