<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>JP van Oosten</title>
 <link href="http://jpvanoosten.nl/atom.xml" rel="self"/>
 <link href="http://jpvanoosten.nl/"/>
 <updated>2013-03-24T18:47:30+01:00</updated>
 <id>http://jpvanoosten.nl/</id>
 <author>
   <name>JP van Oosten</name>
   <email>jp@jpvanoosten.nl</email>
 </author>

 
 <entry>
   <title>Custom Jinja2 filters when using bottle</title>
   <link href="http://jpvanoosten.nl/blog/2013/03/24/custom-jinja2-filters-when-using-bottle/"/>
   <updated>2013-03-24T00:00:00+01:00</updated>
   <id>http://jpvanoosten.nl/blog/2013/03/24/custom-jinja2-filters-when-using-bottle</id>
   <content type="html">&lt;p&gt;I have been experimenting with &lt;a href='http://bottlepy.org/'&gt;Bottle&lt;/a&gt; lately. I have done a bit of Django development and I&amp;#8217;ve always liked its template engine, especially the idea of template inheritance and the fact that it&amp;#8217;s not a layer on top of xml. So, when starting to experiment with Bottle, I wanted to use &lt;a href='http://jinja.pocoo.org/'&gt;Jinja2&lt;/a&gt; as that was inspired by the Django template engine.&lt;/p&gt;

&lt;p&gt;One of the nice features of Jinja2 (and its inspiration) are filters. For example, in a template, one can use &lt;code&gt;{{ name|capitalized }} &lt;/code&gt; which will output the value of &lt;code&gt;name&lt;/code&gt;, but then capitalized. As this is merely for presentation, I think this actually belongs in the template.&lt;/p&gt;

&lt;p&gt;You can even write your own filters, which are basically just python functions that are being called by the parser. However, I could not really find a clear explanation of how to automatically use my custom filters in the &lt;code&gt;@view(templatename)&lt;/code&gt; decorator offered by bottle. Here is the solution I came up with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;from bottle import jinja2_view
view = functools.partial(jinja2_view,
	template_settings={&amp;#39;filters&amp;#39;: filter_dict})&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;where &lt;code&gt;filter_dict&lt;/code&gt; is a dictionary with a name to function mapping. &lt;code&gt;functools.partial&lt;/code&gt; is a nice function (that is actually used in the bottle definition of &lt;code&gt;jinja2_view&lt;/code&gt; as well), that allows you to wrap a function such that certain (keyword) arguments already filled in. In other words: the above code creates a new function that calls &lt;code&gt;jinja2_view&lt;/code&gt; with the &lt;code&gt;template_settings&lt;/code&gt; argument already filled in. Now, you don&amp;#8217;t have to pass &lt;code&gt;template_settings&lt;/code&gt; each time you call &lt;code&gt;view&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To automate adding filters to the &lt;code&gt;filter_dict&lt;/code&gt; as much as possible, I wrote a simple &lt;code&gt;@filter&lt;/code&gt; decorator:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;filter_dict = {}
def filter(func):
	&amp;quot;&amp;quot;&amp;quot;Decorator to add the function to filter_dict&amp;quot;&amp;quot;&amp;quot;
	filter_dict[func.__name__] = func
	return func

# Usage:
@filter
def quote(s):
	return urllib.quote(s)&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Notes from the Debian packaging symposium</title>
   <link href="http://jpvanoosten.nl/blog/2012/12/22/notes-from-the-debian-packaging-symposium/"/>
   <updated>2012-12-22T00:00:00+01:00</updated>
   <id>http://jpvanoosten.nl/blog/2012/12/22/notes-from-the-debian-packaging-symposium</id>
   <content type="html">&lt;p&gt;A few weeks ago, Frank Brokken and Jurjen Bokma organised a &lt;a href='https://security.rc.rug.nl/debian-ubuntu/'&gt;Debian / Ubuntu packaging symposium&lt;/a&gt;, with special guest Tony Mancill. We learned a lot about creating Debian packages and creating repositories. I wrote this blog-post to make sure I don&amp;#8217;t forget the most important steps and maybe give others a chance to learn how to create packages as well.&lt;/p&gt;

&lt;p&gt;These notes are a combination of my own experiences and notes that can be found on the symposiums website. Please don&amp;#8217;t hesitate to contact me if you have any questions or remarks (jp at this domain).&lt;/p&gt;

&lt;h3 id='quick_overview_'&gt;Quick overview &lt;small&gt;(or: TL;DR)&lt;/small&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create COW chroot environment&lt;/li&gt;

&lt;li&gt;Configure &lt;code&gt;pbuilder&lt;/code&gt; and &lt;code&gt;git-buildpackage&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Run &lt;code&gt;dh_make&lt;/code&gt; to create the required &lt;code&gt;debian/&lt;/code&gt; directory&lt;/li&gt;

&lt;li&gt;Fill in the required fields in &lt;code&gt;debian/control&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;Run either &lt;code&gt;pdebuild&lt;/code&gt; or &lt;code&gt;git-buildpackage&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='required_packages'&gt;Required packages&lt;/h3&gt;

&lt;p&gt;Install the following packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build-essential&lt;/li&gt;

&lt;li&gt;dh-make&lt;/li&gt;

&lt;li&gt;devscripts&lt;/li&gt;

&lt;li&gt;cowbuilder&lt;/li&gt;

&lt;li&gt;pbuilder&lt;/li&gt;

&lt;li&gt;git-buildpackage&lt;/li&gt;

&lt;li&gt;debhelper&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='chroots_and_cowbuilder'&gt;Chroots and cowbuilder&lt;/h3&gt;

&lt;p&gt;It is a good idea to build your packages in a chroot. Besides giving you a clean and homogeneous environment, it is a convenient way to test whether your package builds and installs in a clean environment (i.e., all your dependencies are correctly specified).&lt;/p&gt;

&lt;p&gt;Cowbuilder is a tool to create &amp;#8220;copy-on-write&amp;#8221; chroot environments. This means that when you work in the chroot environment (building or testing your package), files that are changed are cleaned-up after you&amp;#8217;re finished. This means that you can set-up your clean environment once, and be confident it stays clean. The advantage over copying the entire environment everytime is that files are only copied when they are being written to.&lt;/p&gt;

&lt;p&gt;In order to create your cowbuilder environment, you can either use the &lt;a href='http://jurjenbokma.com/DebPackaging2/download/cowbuilder-create-base'&gt;cowbuilder-create-base script&lt;/a&gt; (&lt;a href='/debianpackaging/cowbuilder-create-base'&gt;mirror&lt;/a&gt;) Jurjen created, or use the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo cowbuilder --create --distribution=sid \
	--basepath=/var/cache/pbuilder/base-sid.cow&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make sure that, if you use Jurjens script, you create a symlink from &lt;code&gt;/var/cache/pbuilder/$DIST-base.cow&lt;/code&gt; to &lt;code&gt;/var/cache/pbuilder/base-$DIST.cow&lt;/code&gt; because some build-tools expect the COWs to be at the latter location.&lt;/p&gt;

&lt;p&gt;Tony suggested a couple of shell-functions for easy entering and saving changes in chroots:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cb-shell () {
	chr=$1 ; shift
	sudo cowbuilder \
		--bindmount $HOME \
		--login \
		--basepath=/var/cache/pbuilder/base-${chr}.cow $@
}

cb-shell-save () {
	cb-shell $@ --save-after-login
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;cb-shell-save&lt;/code&gt; function can be used to adjust your chroot a bit. Good practice is to put the name of your chroot in &lt;code&gt;/etc/debian_chroot&lt;/code&gt;, so that it will appear in your prompt (which is convenient to quickly see whether you are working in your chroot or not). You can also create a local user, which persists if you use &lt;code&gt;cb-shell-save&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id='configuring_your_environment'&gt;Configuring your environment&lt;/h3&gt;

&lt;p&gt;In this step, we will create the configuration files and environment variables necessary for the debhelper-scripts, &lt;code&gt;pbuilder&lt;/code&gt; and &lt;code&gt;git-buildpackage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, make sure you have a valid gpg key. If you don&amp;#8217;t have one, create one with &lt;code&gt;gpg --gen-key&lt;/code&gt;. It&amp;#8217;s good practice to actually use a (long) phrase as your passphrase. Since you must type it a couple of times, you can use an agent for convenience. Install &lt;code&gt;gnupg-agent&lt;/code&gt; and make sure &lt;code&gt;use-agent&lt;/code&gt; is specified in &lt;code&gt;~/.gnupg/gpg.conf&lt;/code&gt; if you want to use the agent. Make sure you also put the following in your shell start up scripts (&lt;code&gt;.bashrc&lt;/code&gt; or so):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if test -f $HOME/.gpg-agent-info &amp;amp;&amp;amp; kill -0 $(cut -d: -f 2 $HOME/.gpg-agent-info) 2&amp;gt;/dev/null; then
	eval $(cat $HOME/.gpg-agent-info)
else
	eval $(gpg-agent --daemon --write-env-file $HOME/.gpg-agent-info)
fi
GPG_TTY=$(tty)
# GPG_AGENT_INFO is set from within $HOME/.gpg-agent-info, but still needs to be exported
export GPG_TTY GPG_AGENT_INFO&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For &lt;code&gt;dh_make&lt;/code&gt; and the build-scripts, you need to specify the following environment variables:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export DEBEMAIL=john@sudoe.com
export DEBFULLNAME=&amp;quot;John Sudoe&amp;quot;
export DEBSIGN_KEYID=D1D9258A&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;DEBSIGN_KEYID&lt;/code&gt; is the id of the gpg key with which you want to sign your packages. You can find it using &lt;code&gt;gpg --list-secret-keys&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that if you use &lt;code&gt;git&lt;/code&gt;, it is a good idea to make sure you use the same name and email address to commit your debian-changes. Put the following in your &lt;code&gt;~/.gitconfig&lt;/code&gt; or in &lt;code&gt;&amp;lt;project&amp;gt;/.git/config&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[user]
		name = John Sudoe
		email = john@sudoe.com&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, we will configure &lt;code&gt;pbuilder&lt;/code&gt;. Its configuration file, &lt;code&gt;~/.pbuilderrc&lt;/code&gt;, is a shell-script. Jurjen suggests the following (I changed &lt;code&gt;${DIST}-base.cow&lt;/code&gt; to &lt;code&gt;base-${DIST}.cow&lt;/code&gt; to conform to &lt;code&gt;pbuilder&lt;/code&gt; defaults):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PDEBUILD_PBUILDER=cowbuilder

if [ -n &amp;quot;${DIST}&amp;quot; ]; then
	export DISTRIBUTION=$DIST

	AUTO_DEBSIGN=yes

	BASETGZ=&amp;quot;$(dirname $BASETGZ)/$DIST-base.tgz&amp;quot;

	export BASEPATH=/var/cache/pbuilder/base-${DIST}.cow
	export BUILDPLACE=/var/cache/pbuilder/${DIST}.cow

	install -d ../lastbuild/${DIST}
	export BUILDRESULT=../lastbuild/${DIST}

	if echo $@|grep -qe --create ; then
		BUILDPLACE=/var/cache/pbuilder/base-${DIST}.cow
		install -d ${BUILDPLACE}
	fi

	APTCACHE=&amp;quot;/var/cache/pbuilder/$DIST/aptcache/&amp;quot;

	case ${DIST} in
		&amp;#39;lenny&amp;#39;|&amp;#39;squeeze&amp;#39;|&amp;#39;wheezy&amp;#39;|&amp;#39;sid&amp;#39; )
			MIRRORSITE=http://ftp.nl.debian.org/debian
			;;
		&amp;#39;lucid&amp;#39;|&amp;#39;maverick&amp;#39;|&amp;#39;natty&amp;#39;|&amp;#39;oneiric&amp;#39;|&amp;#39;precise&amp;#39; )
			MIRRORSITE=http://nl.archive.ubuntu.com/ubuntu
			;;
	esac

fi&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally, we configure &lt;code&gt;git-buildpackage&lt;/code&gt; by putting the following in &lt;code&gt;~/.gbp.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[DEFAULT]
builder = /usr/bin/git-pbuilder
cleaner = fakeroot debian/rules clean
postbuild = lintian $GBP_CHANGES_FILE
pristine-tar = True
upstream-branch = upstream

[git-buildpackage]
export-dir = ../build-area/
tarball-dir = ../tarballs/

[git-import-orig]
dch = false&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='building_a_package'&gt;Building a package&lt;/h3&gt;

&lt;p&gt;There are a number of ways to build a package. If you only have a source tar-ball, you can use &lt;code&gt;dh_make&lt;/code&gt; and &lt;code&gt;pdebuild&lt;/code&gt;. The first tool creates the &lt;code&gt;debian/&lt;/code&gt; directory, with &lt;code&gt;debian/rules&lt;/code&gt; &amp;#8211; specifying how to build the package &amp;#8211; and &lt;code&gt;debian/control&lt;/code&gt; &amp;#8211; specifying the name, license, section, dependencies and description, among others. &lt;code&gt;pdebuild&lt;/code&gt; is a wrapper around a couple of other wrappers: &lt;code&gt;pdebuild&lt;/code&gt; uses &lt;code&gt;debuild&lt;/code&gt;, which in turn uses &lt;code&gt;dpkg-buildpackage&lt;/code&gt;, which use the &lt;code&gt;dh_*&lt;/code&gt; scripts to run &lt;code&gt;./configure&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt; and &lt;code&gt;make install&lt;/code&gt;. &lt;code&gt;pdebuild&lt;/code&gt; also can use &lt;code&gt;cowbuilder&lt;/code&gt; to run everything in the copy-on-write chroot to keep your environment clean.&lt;/p&gt;

&lt;h4 id='example'&gt;Example&lt;/h4&gt;

&lt;p&gt;The following example is from the exercises at the symposium.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;wget http://gnu.xl-mirror.nl/hello/hello-2.7.tar.gz
tar zxf hello-2.7.tar.gz
cd hello-2.7/
dh_make -f ../hello-2.7.tar.gz -s -c gpl3 &amp;amp;&amp;amp; rm debian/{*.ex,*.EX,README.*}
DIST=sid pdebuild&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;dh_make&lt;/code&gt; line uses &lt;code&gt;-f ../hello-2.7.tar.gz&lt;/code&gt; to specify the location of the original source archive, &lt;code&gt;-s&lt;/code&gt; to indicate we build a single binary, and &lt;code&gt;-c gpl3&lt;/code&gt; to specify the gpl3 license. After that, we remove the example and readme files that we don&amp;#8217;t need. Finally, we build the package for the sid distribution. This is done inside a clean copy of the &lt;code&gt;base-sid.cow&lt;/code&gt; chroot.&lt;/p&gt;

&lt;h4 id='building_packages_from_git_repositories'&gt;Building packages from git repositories&lt;/h4&gt;

&lt;p&gt;When creating debian packages from upstream sources, you can use &lt;code&gt;git&lt;/code&gt; to keep track of debian specific changes. A typical layout of your repository would be to have an &lt;code&gt;upstream&lt;/code&gt; branch, containing the actual upstream sources; a &lt;code&gt;pristine-tar&lt;/code&gt; branch, used to (re)create tar balls exactly (see below) and a &lt;code&gt;master&lt;/code&gt; branch, combining &lt;code&gt;upstream&lt;/code&gt; with your &lt;code&gt;debian/&lt;/code&gt; directory. With this layout, building the package can be done quickly with &lt;code&gt;DIST=sid
git-buildpackage&lt;/code&gt;. If you have configured &lt;code&gt;git-buildpackage&lt;/code&gt; as above, then your package will be located in &lt;code&gt;../build-area&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git-buildpackage&lt;/code&gt; expects to have &lt;code&gt;&amp;lt;package&amp;gt;_&amp;lt;version&amp;gt;.orig.tar.gz&lt;/code&gt; in &lt;code&gt;../tarballs/&lt;/code&gt;. A good way to keep the tarballs in your repository is using &lt;code&gt;pristine-tar&lt;/code&gt;, which commits a tarball and subsequent delta&amp;#8217;s so that you don&amp;#8217;t need to store complete tarballs for each release. Putting a tarball in version control can be done with &lt;code&gt;pristine-tar commit
&amp;lt;package&amp;gt;_&amp;lt;version&amp;gt;.orig.tar.gz&lt;/code&gt;. Creating it for use with, for instance, &lt;code&gt;git-buildpackage&lt;/code&gt;, can be done with &lt;code&gt;pristine-tar checkout
../tarballs/&amp;lt;package&amp;gt;_&amp;lt;version&amp;gt;.orig.tar.gz&lt;/code&gt;. The advantage is that you can keep copies of the tarballs, but don&amp;#8217;t have to waste space for files that don&amp;#8217;t change between versions.&lt;/p&gt;

&lt;h3 id='final_remarks'&gt;Final remarks&lt;/h3&gt;

&lt;p&gt;These are the basic steps to take when creating debian packages. The COWbuilder set-up is really convenient, especially if you create and test packages in a number of different settings (for example, you can have a default chroot for sid and wheezy and any Ubuntu release). Using &lt;code&gt;git&lt;/code&gt; and &lt;code&gt;git-buildpackage&lt;/code&gt;, you can keep track of your changes to the debian-specific files and automatically have it generate changelogs for you (using &lt;code&gt;git-dch&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;If you want these packages to appear in the debian repositories, you will probably have to contact someone willing to sponsor your upload. To get a sponsor, you usually have to make a request on the debian-mentors mailinglist (see the &lt;a href='http://wiki.debian.org/DebianMentorsFaq#What.27s_a_sponsor.2C_why_do_I_want_one.2C_and_how_do_I_get_one.3F'&gt;debian mentors FAQ&lt;/a&gt; for more information).&lt;/p&gt;

&lt;p&gt;If you would rather host your own repository, we briefly touched on how to manage repositories with reprepro, but that is a topic for another post.&lt;/p&gt;

&lt;p&gt;If you read this far, and didn&amp;#8217;t have your question answered, or have remarks about the post, you are welcome to e-mail me at jp at this domain, or contact me through twitter &lt;a href='https://twitter.com/jpvoosten/'&gt;@jpvoosten&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>FBB software (bobcat & bisonc++) on the mac</title>
   <link href="http://jpvanoosten.nl/blog/2011/07/23/fbb-software-bobcat-bisoncpp-on-the-mac/"/>
   <updated>2011-07-23T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2011/07/23/fbb-software-bobcat-bisoncpp-on-the-mac</id>
   <content type="html">&lt;p&gt;Installing software by Frank Brokken (FBB) on the mac used to be a bit of a hassle. The build software is somewhat tailored to Linux (specifically Debian). However, with &lt;a href='http://mxcl.github.com/homebrew/'&gt;homebrew&lt;/a&gt; installation on the mac is now almost as convenient as on Debian. I have prepared some formulae (that&amp;#8217;s what homebrew calls packages) for &lt;a href='http://icmake.sourceforge.net/'&gt;icmake&lt;/a&gt;, &lt;a href='http://yodl.sourceforge.net/'&gt;yodl&lt;/a&gt;, &lt;a href='http://bobcat.sourceforge.net/'&gt;bobcat&lt;/a&gt; and &lt;a href='http://bisoncpp.sourceforge.net/'&gt;bisonc++&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are two ways to install these packages: either by providing the URL of each formula on the command line to &lt;code&gt;brew install&lt;/code&gt; (in the correct order), or by downloading the formula in &lt;code&gt;/usr/local/Library/Formula&lt;/code&gt; (or whatever &lt;code&gt;brew
--prefix&lt;/code&gt; tells you instead of &lt;code&gt;/usr/local&lt;/code&gt;) and then issuing &lt;code&gt;brew install
bisonc++&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Either way, you will first have to install a recent g++. You can find &lt;a href='https://raw.github.com/Sharpie/homebrew-science/ceb4de17c5b44fc4570cd86b4cf069d3eaa89698/duplicates/gcc.rb'&gt;a formula for gcc4.6 on github&lt;/a&gt; (&lt;a href='/homebrew/formula/gcc.rb'&gt;mirror&lt;/a&gt;), which you can install with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;brew install --use-gcc --enable-cxx https://raw.github.com/Sharpie/homebrew-science/ceb4de17c5b44fc4570cd86b4cf069d3eaa89698/duplicates/gcc.rb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;--use-gcc&lt;/code&gt; option is required because by default homebrew will try to compile using the &lt;code&gt;llvm-gcc&lt;/code&gt; compiler. The &lt;code&gt;--enable-cxx&lt;/code&gt; makes sure g++-4.6 will also be installed. Compiling gcc will take some time though. On my machine (a MacBook, 2.2Ghz Core 2 Duo) it took about 50 minutes.&lt;/p&gt;

&lt;p&gt;Then you can proceed to install Frank&amp;#8217;s packages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;brew install http://jpvanoosten.nl/homebrew/formula/icmake.rb
brew install http://jpvanoosten.nl/homebrew/formula/yodl.rb
brew install http://jpvanoosten.nl/homebrew/formula/bobcat.rb
brew install http://jpvanoosten.nl/homebrew/formula/bisonc++.rb&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd `brew --prefix`/Library/Formula
wget http://jpvanoosten.nl/homebrew/formula/{icmake,yodl,bobcat,bisonc++}.rb
brew install bisonc++&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Either way, you can find my formula to Frank&amp;#8217;s packages here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='/homebrew/formula/icmake.rb'&gt;icmake formula&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='/homebrew/formula/yodl.rb'&gt;yodl formula&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='/homebrew/formula/bobcat.rb'&gt;bobcat formula&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='/homebrew/formula/bisonc++.rb'&gt;bisonc++ formula&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After installation, every package is installed into it&amp;#8217;s own &amp;#8216;keg&amp;#8217; in &lt;code&gt;/usr/local/Cellar/&lt;/code&gt; and symlinked into &lt;code&gt;/usr/local/bin&lt;/code&gt;. With homebrew you can easily remove the packages if needed.&lt;/p&gt;

&lt;p&gt;Hope this is useful for somebody. If you have any comments or questions, you can reach me by the address found below, or just poke me on twitter.&lt;/p&gt;

&lt;p&gt;(Thanks to Jelmer, Thieme and Jakob for reporting some issues with the Formulae. They should be fixed now.)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Can Markov properties be learned by hidden Markov modelling algorithms?</title>
   <link href="http://jpvanoosten.nl/blog/2010/09/21/can-markov-properties-be-learned-by-hidden-markov-modelling-algorithms/"/>
   <updated>2010-09-21T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2010/09/21/can-markov-properties-be-learned-by-hidden-markov-modelling-algorithms</id>
   <content type="html">&lt;p&gt;Recently I received my MSc degree in Artificial Intelligence. The topic of my final project and thesis was hidden Markov models (HMMs). The main questions were whether the properties of Markov processes could be reliably learned by the current hidden Markov modelling algorithms and whether the Markov property is important in language and handwriting recognition.&lt;/p&gt;

&lt;p&gt;Part of the thesis is an in-depth overview of the theory of hidden Markov models and the Baum-Welch algorithm, so if you are interested in HMMs in general, or in the conclusions of the research, please feel free to read my thesis: &lt;a href='/docs/AI-MAI-2010-J-P.van.Oosten.pdf'&gt;Can Markov properties be learned by hidden Markov modelling algorithms?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The abstract:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hidden Markov models (HMMs) are a common classification technique for time series and sequences in areas such as speech recognition, bio-informatics and handwriting recognition. HMMs are used to model processes which behave according to the Markov property: The next state is only influenced by the current state, not by the past. Although HMMs are popular in handwriting recognition, there are some doubts about their usage in this field.&lt;/p&gt;

&lt;p&gt;A number of experiments have been performed with both artificial and natural data. The artificial data was specifically generated for this study, either by transforming flat-text dictionaries or by selecting observations probabilistically under predefined modelling conditions. The natural data is part of the collection from the Queen&amp;#8217;s Office (Kabinet der Koningin), and was used in studies on handwriting recognition. The experiments try to establish whether the properties of Markov processes can be successfully learned by hidden Markov modelling, as well as the importance of the Markov property in language in general and handwriting in particular.&lt;/p&gt;

&lt;p&gt;One finding of this project is that not all Markov processes can be successfully modelled by state of the art HMM algorithms, which is strongly supported by a series of experiments with artificial data. Other experiments, with both artificial and natural data show that removing the temporal aspects of a particular hidden Markov model can still lead to correct classification. These and other critical remarks will be explicated in this thesis.&lt;/p&gt;
&lt;/blockquote&gt;</content>
 </entry>
 
 <entry>
   <title>Improve your writing with shell scripts</title>
   <link href="http://jpvanoosten.nl/blog/2010/07/26/improve-your-writing-with-shell-scripts/"/>
   <updated>2010-07-26T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2010/07/26/improve-your-writing-with-shell-scripts</id>
   <content type="html">&lt;p&gt;Currently, I&amp;#8217;m working on my Master&amp;#8217;s thesis on Hidden Markov Models. Matt Might wrote an article on &lt;a href='http://matt.might.net/articles/shell-scripts-for-passive-voice-weasel-words-duplicates/'&gt;three shell scripts to improve your writing&lt;/a&gt;, which I found interesting. The scripts help to detect the use of passive voice, weasel words (such as &amp;#8220;surprisingly low&amp;#8221;) and duplicate words (which are difficult to detect when a line break separates them).&lt;/p&gt;

&lt;p&gt;One of the remarks I repeatedly received was that my paragraphs were much too short. A couple of paragraphs were just one or two sentences, which I could usually just throw together.&lt;/p&gt;

&lt;p&gt;In the light of the Matt&amp;#8217;s scripts, I wrote my own version, in which I detect paragraphs with only two or three sentences and spanning only a few lines. It isn&amp;#8217;t perfect and not all small paragraphs need to be long, but it might warrant a closer inspection of your text.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='c'&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;sys&lt;/span&gt;
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;re&lt;/span&gt;

&lt;span class='n'&gt;SINGLE_COMMAND_RE&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;re&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;compile&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;r&amp;#39;^&lt;/span&gt;&lt;span class='se'&gt;\\&lt;/span&gt;&lt;span class='s'&gt;\w+\{[^}]+\}$&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;process&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;file&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
	&lt;span class='sd'&gt;&amp;quot;&amp;quot;&amp;quot;Ignores lines containing only a single command at the beginning of a&lt;/span&gt;
&lt;span class='sd'&gt;	paragraph (piece of text surrounded by blank lines).&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
	&lt;span class='n'&gt;paragraph&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='c'&gt;# [start, sentence count, linecount]&lt;/span&gt;
	&lt;span class='n'&gt;prev_line&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='bp'&gt;None&lt;/span&gt;
	&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='n'&gt;linenum&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt; &lt;span class='ow'&gt;in&lt;/span&gt; &lt;span class='nb'&gt;enumerate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;file&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
		&lt;span class='n'&gt;line&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;strip&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
		&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;SINGLE_COMMAND_RE&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='ow'&gt;not&lt;/span&gt; &lt;span class='n'&gt;prev_line&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
			&lt;span class='k'&gt;continue&lt;/span&gt;
		&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='ow'&gt;not&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt; &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]:&lt;/span&gt;
			&lt;span class='n'&gt;report_short_paragraph&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;filename&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
			&lt;span class='n'&gt;paragraph&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
		&lt;span class='k'&gt;else&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
			&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
				&lt;span class='n'&gt;paragraph&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;linenum&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
			&lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
			&lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;-=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
			&lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;linenum&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
		&lt;span class='n'&gt;prev_line&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;

&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;report_short_paragraph&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;filename&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
	&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt; &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
		&lt;span class='k'&gt;print&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;:&lt;/span&gt;&lt;span class='si'&gt;%d&lt;/span&gt;&lt;span class='s'&gt; paragraph of &lt;/span&gt;&lt;span class='si'&gt;%d&lt;/span&gt;&lt;span class='s'&gt; sentence(s) / &lt;/span&gt;&lt;span class='si'&gt;%d&lt;/span&gt;&lt;span class='s'&gt; lines&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;filename&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
				&lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='n'&gt;paragraph&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;__name__&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
	&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='n'&gt;filename&lt;/span&gt; &lt;span class='ow'&gt;in&lt;/span&gt; &lt;span class='n'&gt;sys&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;argv&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;:]:&lt;/span&gt;
		&lt;span class='nb'&gt;file&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;open&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;filename&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
		&lt;span class='n'&gt;process&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;file&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Creating MoinMoin pages programmatically</title>
   <link href="http://jpvanoosten.nl/blog/2010/05/13/creating-moinmoin-pages-programmattically/"/>
   <updated>2010-05-13T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2010/05/13/creating-moinmoin-pages-programmattically</id>
   <content type="html">&lt;p&gt;Recently, I installed a &lt;a href='http://moinmo.in/'&gt;MoinMoin&lt;/a&gt; wiki and a mailing list using &lt;a href='http://mlmmj.org/'&gt;mlmmj&lt;/a&gt; for a group of people, and I wanted to create a restricted page on the wiki with the subscribers of the list.&lt;/p&gt;

&lt;p&gt;Since this mailing list is not owned by the user the wiki runs as, the script had to be executed as root. As soon as the subscribers were collected, the effective user id was changed with a simple call to &lt;code&gt;os.seteuid&lt;/code&gt;. This also meant I could not create a macro and have the page update from within the wiki itself.&lt;/p&gt;

&lt;p&gt;The solution I found was to create a user which was privileged to edit a page with ACLs. The MoinMoin wiki has a &lt;a href='http://moinmo.in/MoinDev/Storage#Editing_pages_programatically'&gt;page which shows you how to edit pages programmatically&lt;/a&gt;, but for some reason I also had to set the &lt;code&gt;valid&lt;/code&gt; property of the user to &lt;code&gt;1&lt;/code&gt; (MoinMoin seems to use &lt;code&gt;valid = 0&lt;/code&gt; by default, not &lt;code&gt;False&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;It felt a bit like a hack, but it worked. As a nice bonus, the &lt;code&gt;PageEditor.saveText&lt;/code&gt; method throws a &lt;code&gt;PageEditor.Unchanged&lt;/code&gt; exception if the page is not changed, so only a new revision is filed when the page contents actually do change.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>LaTeX font installation messes up Mac OS X font cache</title>
   <link href="http://jpvanoosten.nl/blog/2010/02/25/latex-font-installation-messes-up-macosx-font-cache/"/>
   <updated>2010-02-25T00:00:00+01:00</updated>
   <id>http://jpvanoosten.nl/blog/2010/02/25/latex-font-installation-messes-up-macosx-font-cache</id>
   <content type="html">&lt;p&gt;A few days ago, I tried to install a new font for LaTeX from an OTF-file. I used the script &lt;a href='http://www.ece.ucdavis.edu/~jowens/code/otfinst/'&gt;otfinst.py&lt;/a&gt;, by John Owens. However, when I decided not to use the font after all, none of the regular LaTeX fonts (Computer Modern, by Knuth for example) seemed to work any more, everything was replaced by an ugly sans serif font.&lt;/p&gt;

&lt;p&gt;Thinking I must have messed up LaTeX, I set out to reinstall and undo all the changes I made. This was actually not the case; after searching the web a bit I found that sometimes the font cache would get corrupted. To interact with the font cache in Leopard (Mac OS X 10.5), one uses the &lt;code&gt;atsutil&lt;/code&gt; command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;atsutil databases -removeUser # clears the cache
atsutil server -shutdown      # restart the ATS server
atsutil server -ping          # see when the server is back up again&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You might want to issue the first command as root to clear the cache of all users.&lt;/p&gt;

&lt;p&gt;Be sure to restart any running programs such as Safari and Preview, or you will still see weird fonts.&lt;/p&gt;

&lt;p&gt;See &lt;a href='http://www.macworld.com/article/139383/2009/03/fontcacheclear.html'&gt;this article on Macworld&lt;/a&gt; for more information.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Gitosis: arguments to command look dangerous</title>
   <link href="http://jpvanoosten.nl/blog/2009/11/12/Gitosis-arguments-to-command-look-dangerous/"/>
   <updated>2009-11-12T00:00:00+01:00</updated>
   <id>http://jpvanoosten.nl/blog/2009/11/12/Gitosis-arguments-to-command-look-dangerous</id>
   <content type="html">&lt;p&gt;If you get the following error when trying to execute &lt;code&gt;git pull&lt;/code&gt;: &amp;#8220;Arguments to command look dangerous&amp;#8221;, then you might want to check whether the remote repository ends with a slash (&lt;code&gt;/&lt;/code&gt;). This tripped me and a friend over the other day. Since gitosis is not very verbose with its error-messages, I had to dig deep to find this out.&lt;/p&gt;

&lt;p&gt;In general, the path to the git repository needs to start with an alphanumeric character followed by zero or more alphanumeric characters, @, _ or -. Subdirectories have the same restrictions. So, paths cannot end in a slash.&lt;/p&gt;

&lt;p&gt;Just edit the corresponding remote section (usually this is origin and the section looks like &lt;code&gt;[remote &amp;quot;origin&amp;quot;]&lt;/code&gt;) in the file &lt;em&gt;.git/config&lt;/em&gt; and correct the path after the colon (&lt;code&gt;:&lt;/code&gt;), for example by removing the slash at the end.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>authn_dbd error "User not found"</title>
   <link href="http://jpvanoosten.nl/blog/2009/11/05/authn_dbd-user-not-found/"/>
   <updated>2009-11-05T00:00:00+01:00</updated>
   <id>http://jpvanoosten.nl/blog/2009/11/05/authn_dbd-user-not-found</id>
   <content type="html">&lt;p&gt;If you use apache and the DBD module for authentication, you need to be very careful with using quotes in your password query.&lt;/p&gt;

&lt;p&gt;I had the following configuration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;AuthBasicProvider dbd
AuthDBDUserPWQuery &amp;quot;SELECT password FROM users WHERE name=&amp;#39;%s&amp;#39;&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;but this yielded the very verbose message: &amp;#8220;user &lt;em&gt;user&lt;/em&gt; not found&amp;#8221;. After a while a friend commented he used the same query, minus the quotes around &lt;code&gt;%s&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, apparently, the &lt;em&gt;authn_dbd&lt;/em&gt; module does the correct quoting for you. Use the following query if you encounter this behaviour:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;AuthBasicProvider dbd
AuthDBDUserPWQuery &amp;quot;SELECT password FROM users WHERE name=%s&amp;quot;&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Python distutils woes</title>
   <link href="http://jpvanoosten.nl/blog/2009/10/21/python-distutils-woes/"/>
   <updated>2009-10-21T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2009/10/21/python-distutils-woes</id>
   <content type="html">&lt;p&gt;Today I was working on a setup script for &lt;a href='http://supermind.nl/submin/'&gt;submin&lt;/a&gt;, but I got some unexpected results while testing. Apparently, I had messed up a path by using string concatenation (pro-tip: always use &lt;code&gt;os.path.join&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Every time I tried something else, the same faulty paths were copied to the install directory. How did I fix it? By removing the &lt;code&gt;build/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;So, if you have weird problems with distutils, try removing the &lt;code&gt;build/&lt;/code&gt; directory. This directory contains the files which are copied to the final installation directory, and is not cleaned up properly after finishing the &lt;code&gt;install&lt;/code&gt; command.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Stripping file extensions in C</title>
   <link href="http://jpvanoosten.nl/blog/2009/09/14/stripping-extensions-in-c/"/>
   <updated>2009-09-14T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2009/09/14/stripping-extensions-in-c</id>
   <content type="html">&lt;p&gt;A very simple C-function to strip &lt;strong&gt;all&lt;/strong&gt; extensions from a filename. The function removes everything from the first dot.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;strip_extension&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;char&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='k'&gt;while&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;*++&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='sc'&gt;&amp;#39;.&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
		&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>C++ expected initializer</title>
   <link href="http://jpvanoosten.nl/blog/2009/04/13/c-expected-initializer/"/>
   <updated>2009-04-13T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2009/04/13/c-expected-initializer</id>
   <content type="html">&lt;p&gt;When I was developing a new feature for &lt;a href='http://www.flexcpp.org'&gt;Flexc++&lt;/a&gt;, I ran into a compiler error stating &amp;#8220;expected initializer before ‘const’&amp;#8221;.&lt;/p&gt;

&lt;p&gt;I was building a function which returned an object of an inner class. However, the outer class was a class template, and the template parameter was used in the inner class:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;template&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='k'&gt;typename&lt;/span&gt; &lt;span class='n'&gt;StreamInfo&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;ScannerTemplate&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='k'&gt;protected&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;
	&lt;span class='k'&gt;struct&lt;/span&gt; &lt;span class='n'&gt;BufferData&lt;/span&gt;
	&lt;span class='p'&gt;{&lt;/span&gt;
		&lt;span class='n'&gt;StreamInfo&lt;/span&gt; &lt;span class='n'&gt;d_streamInfo&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='p'&gt;};&lt;/span&gt;
	&lt;span class='k'&gt;public&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;
	&lt;span class='n'&gt;BufferData&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='n'&gt;switchBuffer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;StreamInfo&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;streamInfo&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;};&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The implementation of &lt;code&gt;switchBuffer&lt;/code&gt; looked like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;template&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='k'&gt;typename&lt;/span&gt; &lt;span class='n'&gt;StreamInfo&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
&lt;span class='kr'&gt;inline&lt;/span&gt; &lt;span class='n'&gt;ScannerTemplate&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;StreamInfo&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;::&lt;/span&gt;&lt;span class='n'&gt;BufferData&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt;       
	&lt;span class='n'&gt;ScannerTemplate&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;StreamInfo&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;::&lt;/span&gt;&lt;span class='n'&gt;switchBuffer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;StreamInfo&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;streamInfo&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='c1'&gt;// ...&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Why did I get the error that an initializer was expected?&lt;/p&gt;

&lt;p&gt;After some digging, I found that this is a (deprecated) implicit typename: At compile time, the compiler does not know what the instantiation of &lt;code&gt;ScannerTemplate&lt;/code&gt; looks like.&lt;/p&gt;

&lt;p&gt;To turn this into an explicit typename, just prefix &lt;code&gt;typename&lt;/code&gt; to the return type:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;template&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='k'&gt;typename&lt;/span&gt; &lt;span class='n'&gt;StreamInfo&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
&lt;span class='kr'&gt;inline&lt;/span&gt; &lt;span class='k'&gt;typename&lt;/span&gt; &lt;span class='n'&gt;ScannerTemplate&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;StreamInfo&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;::&lt;/span&gt;&lt;span class='n'&gt;BufferData&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt;       
	&lt;span class='n'&gt;ScannerTemplate&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;StreamInfo&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;::&lt;/span&gt;&lt;span class='n'&gt;switchBuffer&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;StreamInfo&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;streamInfo&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='c1'&gt;// ...&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For more information, look in the &lt;a href='http://www.icce.rug.nl/documents/cplusplus/cplusplus19.html#an2804'&gt;C++ Annotations&lt;/a&gt; as usual :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>istringstream::str not resetting eof</title>
   <link href="http://jpvanoosten.nl/blog/2008/10/27/istringstreamstr-not-resetting-eof/"/>
   <updated>2008-10-27T00:00:00+01:00</updated>
   <id>http://jpvanoosten.nl/blog/2008/10/27/istringstreamstr-not-resetting-eof</id>
   <content type="html">&lt;p&gt;Today I was implementing a c++-function which read single words from a file. Because the first few characters of each line needed to be stripped, I could not use simple string extraction from the filestream. This lead me to use the &lt;code&gt;istringstream&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, the &lt;code&gt;istringstream&lt;/code&gt; gave me a minor problem: it only seemed to extract words for the first line in each file!&lt;/p&gt;

&lt;p&gt;Because I wanted to reuse a single stream, I used the &lt;code&gt;istringstream::     str(string const &amp;text)&lt;/code&gt; method to fill the stream with the current line&amp;#8217;s content. From there I used the string extraction.&lt;/p&gt;

&lt;p&gt;After a bit, I remembered I had seen this problem before, and remembered I needed to reset something. After a bit of digging, I found out that when the extraction reached the end of the string, the &lt;code&gt;eof&lt;/code&gt;-bit would be set. Filling the stream with new data using the &lt;code&gt;str&lt;/code&gt; method, did not reset these bits, unfortunately.&lt;/p&gt;

&lt;p&gt;The fix was then easy: &lt;code&gt;istringstream::clear()&lt;/code&gt; does the job.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>FOAF</title>
   <link href="http://jpvanoosten.nl/blog/2008/09/04/foaf/"/>
   <updated>2008-09-04T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2008/09/04/foaf</id>
   <content type="html">&lt;p&gt;For a course on Semantic Web Technology, we needed to create a &lt;a href='http://www.foaf-project.org/'&gt;FOAF&lt;/a&gt;-file.&lt;/p&gt;

&lt;p&gt;You can use the link below, or you can use the link in the head-portion of my website.&lt;/p&gt;

&lt;p&gt;This is my entry, you can add me if you like: &lt;a href='http://jpvanoosten.nl/s/foaf.rdf'&gt;http://jpvanoosten.nl/s/foaf.rdf&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>tuple vs list</title>
   <link href="http://jpvanoosten.nl/blog/2008/08/04/tuple-vs-list/"/>
   <updated>2008-08-04T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2008/08/04/tuple-vs-list</id>
   <content type="html">&lt;p&gt;Everyone with a bit of python knowledge can intuitively feel that tuples are faster than lists. Of course: tuples are unmutable, and therefore &lt;em&gt;should&lt;/em&gt; be faster. I was wondering today, how much faster tuples were.&lt;/p&gt;

&lt;p&gt;Again, we use the &lt;code&gt;timeit&lt;/code&gt; module to measure runtime of a command.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ python -m timeit &amp;#39;[True]&amp;#39;
1000000 loops, best of 3: 0.206 usec per loop

$ python -m timeit &amp;#39;(True,)&amp;#39;
10000000 loops, best of 3: 0.118 usec per loop&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, using a tuple in such a simple case is almost 1.8 times faster!&lt;/p&gt;

&lt;p&gt;(I like the fact that I can test my intuition with &lt;code&gt;timeit&lt;/code&gt;)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>SumQuerySet</title>
   <link href="http://jpvanoosten.nl/blog/2008/07/18/sumqueryset/"/>
   <updated>2008-07-18T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2008/07/18/sumqueryset</id>
   <content type="html">&lt;p&gt;When implementing the model for a timetracking application, I was trying to sum the amount of hours for a certain queryset. Not succeeding by digging through the internals of django, I tried this &amp;#8211; very simple &amp;#8211; approach. It uses a custom &lt;code&gt;Manager&lt;/code&gt;, which in turn uses a custom &lt;code&gt;QuerySet&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At first, I tried to use the SQL-function &lt;code&gt;SUM&lt;/code&gt;, but it was hard to tell the Django-ORM to use this standard SQL-function. I then decided to let python do it&amp;#8217;s job instead.&lt;/p&gt;

&lt;p&gt;The model has a field called hours, in my case a CharField (because I wanted to save time information in a &amp;#8220;2:45&amp;#8221; kind of format).&lt;/p&gt;

&lt;p&gt;A custom &lt;code&gt;Manager&lt;/code&gt; is used to return a queryset:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class SumManager(models.Manager):
    def get_query_set(self):
        return SumQuerySet(self.model)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Nothing fancy. &lt;code&gt;get_query_set&lt;/code&gt; just returns a custom &lt;code&gt;SumQuerySet&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class SumQuerySet(QuerySet):
    def sum_hours(self):
        return sum(float(entry.hours) for entry in self)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, this queryset has an additional method sum_hours, which is very simple. It just returns the sum of all entry.hours in the current queryset. This enables one to use a filter and then ask the queryset to return the sum of all the hours.&lt;/p&gt;

&lt;p&gt;Then add the line &lt;code&gt;objects = SumManager()&lt;/code&gt; to the model and all&amp;#8217;s set!&lt;/p&gt;

&lt;p&gt;Bonus:&lt;br /&gt; You can also change the pagination-template to show the amount of hours in the current view in the admin:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;load&lt;/span&gt; &lt;span class='nv'&gt;admin_list&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;load&lt;/span&gt; &lt;span class='nv'&gt;i18n&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='x'&gt;&amp;lt;p class=&amp;quot;paginator&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nv'&gt;pagination_required&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='nv'&gt;i&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='nv'&gt;page_range&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='x'&gt;	&lt;/span&gt;&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;paginator_number&lt;/span&gt; &lt;span class='nv'&gt;cl&lt;/span&gt; &lt;span class='nv'&gt;i&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;endfor&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;endif&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='cp'&gt;{{&lt;/span&gt; &lt;span class='nv'&gt;cl.result_count&lt;/span&gt; &lt;span class='cp'&gt;}}&lt;/span&gt;&lt;span class='x'&gt; &lt;/span&gt;&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;ifequal&lt;/span&gt; &lt;span class='nv'&gt;cl.result_count&lt;/span&gt; &lt;span class='m'&gt;1&lt;/span&gt; &lt;span class='cp'&gt;%}{{&lt;/span&gt; &lt;span class='nv'&gt;cl.opts.verbose_name&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nf'&gt;escape&lt;/span&gt; &lt;span class='cp'&gt;}}{%&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='cp'&gt;%}{{&lt;/span&gt; &lt;span class='nv'&gt;cl.opts.verbose_name_plural&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nf'&gt;escape&lt;/span&gt; &lt;span class='cp'&gt;}}{%&lt;/span&gt; &lt;span class='k'&gt;endifequal&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nv'&gt;cl.query_set.sum_hours&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='x'&gt;&amp;amp;mdash; &lt;/span&gt;&lt;span class='cp'&gt;{{&lt;/span&gt; &lt;span class='nv'&gt;cl.query_set.sum_hours&lt;/span&gt; &lt;span class='cp'&gt;}}&lt;/span&gt;&lt;span class='x'&gt; hours total&lt;/span&gt;
&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;endif&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nv'&gt;show_all_url&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x'&gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;lt;a href=&amp;quot;&lt;/span&gt;&lt;span class='cp'&gt;{{&lt;/span&gt; &lt;span class='nv'&gt;show_all_url&lt;/span&gt; &lt;span class='cp'&gt;}}&lt;/span&gt;&lt;span class='x'&gt;&amp;quot; class=&amp;quot;showall&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;trans&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Show all&amp;#39;&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x'&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;span class='cp'&gt;{%&lt;/span&gt; &lt;span class='k'&gt;endif&lt;/span&gt; &lt;span class='cp'&gt;%}&lt;/span&gt;&lt;span class='x' /&gt;
&lt;span class='x'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This shows, if the sum_hours is available in the current queryset, the number of hours of the records shown. (For this to work, you need to tell the admin you want to use your own &lt;code&gt;SumManager&lt;/code&gt; as the default manager. Add the line &lt;code&gt;manager = SumManager()&lt;/code&gt; to your Admin-inner class.)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Flexc++ textmate language</title>
   <link href="http://jpvanoosten.nl/blog/2008/06/18/flexc-textmate-language/"/>
   <updated>2008-06-18T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2008/06/18/flexc-textmate-language</id>
   <content type="html">&lt;p&gt;While working on our replacement for &lt;em&gt;flex&lt;/em&gt; / &lt;em&gt;flex++&lt;/em&gt;, I was getting lost in all the comments and regular expressions in our lexer-file. I needed syntax highlighting badly.&lt;/p&gt;

&lt;p&gt;So, I opened up the bundle editor and wrote a language-file for &lt;em&gt;flexc++&lt;/em&gt;. Because it&amp;#8217;s basically the same syntax, it also works on lexers for &lt;em&gt;flex&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If someone&amp;#8217;s interested, drop me a line at jp@thisdomain, and I&amp;#8217;ll send the bundle to you (to save you some cut&amp;#8217;n&amp;#8217;paste work :)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{	scopeName = &amp;#39;source.flexc++&amp;#39;;
	fileTypes = ( );
	foldingStartMarker = &amp;#39;/\*\*|[^%]\{\s*$&amp;#39;;
	foldingStopMarker = &amp;#39;\*\*/|^\s*\}&amp;#39;;
	patterns = (
		{	name = &amp;#39;comment.block.flexc++&amp;#39;;
			begin = &amp;#39;\s*/\*&amp;#39;;
			end = &amp;#39;\*/\s*&amp;#39;;
		},
		{	name = &amp;#39;meta.codeblock.flexc++&amp;#39;;
			begin = &amp;#39;%\{&amp;#39;;
			end = &amp;#39;%\}&amp;#39;;
			patterns = ( { include = &amp;#39;source.c++&amp;#39;; } );
		},
		{	name = &amp;#39;constant.other.namedefinition.flexc++&amp;#39;;
			match = &amp;#39;^\s*[A-Z_0-9]+&amp;#39;;
		},
		{	name = &amp;#39;string.regexp.namedefinition.flexc++&amp;#39;;
			match = &amp;#39;(?&amp;lt;=[A-Z_0-9])\s+.+$&amp;#39;;
		},
		{	name = &amp;#39;meta.rulessection.flexc++&amp;#39;;
			begin = &amp;#39;^%%$&amp;#39;;
			end = &amp;#39;%%&amp;#39;;
			patterns = (
				{	name = &amp;#39;meta.blankline.flexc++&amp;#39;;
					match = &amp;#39;^$&amp;#39;;
				},
				{	name = &amp;#39;comment.block.rulessection.flexc++&amp;#39;;
					begin = &amp;#39;\s*/\*&amp;#39;;
					end = &amp;#39;\*/\s*&amp;#39;;
				},
				{	name = &amp;#39;entity.name.other.startconditionlist.flexc++&amp;#39;;
					match = &amp;#39;^\s*&amp;lt;[a-zA-Z_,]+&amp;gt;&amp;#39;;
				},
				{	name = &amp;#39;string.regexp.flexc++&amp;#39;;
					begin = &amp;#39;^\s*(?=[^\s\n])|(?&amp;lt;=&amp;gt;)(?=[^\s])&amp;#39;;
					end = &amp;#39;(?=\s|\n)&amp;#39;;
					patterns = (
						{	name = &amp;#39;string.regexp.characterclass.flexc++&amp;#39;;
							match = &amp;#39;\[.+\]&amp;#39;;
						},
						{	name = &amp;#39;string.regexp.escape.flexc++&amp;#39;;
							match = &amp;#39;\\.&amp;#39;;
						},
						{	name = &amp;#39;string.regexp.string.flexc++&amp;#39;;
							begin = &amp;#39;&amp;quot;&amp;#39;;
							end = &amp;#39;&amp;quot;&amp;#39;;
							patterns = (
								{	name = &amp;#39;string.regexp.string.escapechar.flexc++&amp;#39;;
									match = &amp;#39;\\.&amp;#39;;
								},
							);
						},
						{	name = &amp;#39;constant.other.name.flexc++&amp;#39;;
							match = &amp;#39;\{[A-Z_0-9]*[A-Z_][A-Z_0-9]+\}&amp;#39;;
						},
					);
				},
				{	name = &amp;#39;meta.actionblock.flexc++&amp;#39;;
					begin = &amp;#39;\{&amp;#39;;
					end = &amp;#39;\}&amp;#39;;
					patterns = (
						{	name = &amp;#39;entity.name.function.builtin.flexc++&amp;#39;;
							match = &amp;#39;\b(BEGIN)\b&amp;#39;;
						},
						{	name = &amp;#39;meta.actionblock.source.flexc++&amp;#39;;
							include = &amp;#39;source.c++&amp;#39;;
						},
					);
				},
				{	name = &amp;#39;entity.function.builtin.flexc++&amp;#39;;
					match = &amp;#39;\b(BEGIN)\b&amp;#39;;
				},
				{	name = &amp;#39;meta.action.flexc++&amp;#39;;
					contentName = &amp;#39;source.c++&amp;#39;;
					match = &amp;#39;(?&amp;lt;=[^\s\n])\s+.+$&amp;#39;;
					include = &amp;#39;source.c++&amp;#39;;
				},
			);
		},
		{	name = &amp;#39;entity.other.attribute-name.flexc++&amp;#39;;
			match = &amp;#39;^%[^ ]+&amp;#39;;
		},
	);
}&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>More on list.sort</title>
   <link href="http://jpvanoosten.nl/blog/2008/06/16/more-listsort/"/>
   <updated>2008-06-16T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2008/06/16/more-listsort</id>
   <content type="html">&lt;p&gt;As mentioned in the previous post, I found a new way to call &lt;code&gt;list.sort&lt;/code&gt; in python. I did some research with the timeit-module and these were my findings.&lt;/p&gt;

&lt;p&gt;Using the cmp-method, the timeit module returned 0.008760 sec/pass, while using the key-method gave me 0.001954 sec/pass. Wow, what a difference!&lt;/p&gt;

&lt;p&gt;Here is the code I used:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import timeit
import random

class A(object):
	def __init__(self, data):
		self.data = data
	def __repr__(self):
		return &amp;quot;A(%d)&amp;quot; % self.data

l = [A(x) for x in xrange(1000)]
def get_random_list():
	global l
	random.shuffle(l)
	return l

s = &amp;quot;&amp;quot;&amp;quot;import operator; get_random_list().sort(lambda a,b: cmp(a.data, b.data))&amp;quot;&amp;quot;&amp;quot;
t = timeit.Timer(stmt=s, setup=&amp;quot;from __main__ import get_random_list&amp;quot;)
s2 = &amp;quot;&amp;quot;&amp;quot;import operator; get_random_list().sort(key=operator.attrgetter(&amp;#39;data&amp;#39;))&amp;quot;&amp;quot;&amp;quot;
t2 = timeit.Timer(stmt=s2, setup=&amp;quot;from __main__ import get_random_list&amp;quot;)

ntries = 10000
print &amp;quot;cmp-method: %f sec/pass&amp;quot; % (t.timeit(number=ntries)/ntries)
print &amp;quot;key-method: %f sec/pass&amp;quot; % (t2.timeit(number=ntries)/ntries)&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Combining queries in Django</title>
   <link href="http://jpvanoosten.nl/blog/2008/06/16/combining-queries-django/"/>
   <updated>2008-06-16T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2008/06/16/combining-queries-django</id>
   <content type="html">&lt;p&gt;While implementing the code for this blog, I was wondering wether I should implement a &amp;#8220;Links&amp;#8221; application, where I would be able to add links I thought interesting. While investigating a method to combine the results for both this and the Post models, I found an interesting little feature in Python: &lt;code&gt;operator.attrgetter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, if I have a list containing results from the two models (obtained through, for example, &lt;code&gt;itertools.chain&lt;/code&gt;) I can sort them like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a.sort(key=operator.attrgetter(&amp;#39;date&amp;#39;)) &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It seems that this is more efficient on large datasets, than using&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a.sort(lambda a,b: cmp(a.date, b.date))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;but more interestingly, I think this is more in line with the way the STL works in C++.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import operator&lt;/code&gt; my new friend&lt;/p&gt;

&lt;p&gt;(Oh, if you have two querysets for the same model, it is obviously more efficient to use &lt;code&gt;q1 | q2&lt;/code&gt;.)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Perl oneliner to sum all lines</title>
   <link href="http://jpvanoosten.nl/blog/2008/06/15/perl-oneliner-sum-all-lines/"/>
   <updated>2008-06-15T00:00:00+02:00</updated>
   <id>http://jpvanoosten.nl/blog/2008/06/15/perl-oneliner-sum-all-lines</id>
   <content type="html">&lt;p&gt;As I&amp;#8217;m not such a big Perl-star, here is my first oneliner! This one sums all integers, presented at separate lines.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;perl -e &amp;#39;for (&amp;lt;STDIN&amp;gt;) { $sum += $_; } print $sum . &amp;quot;\n&amp;quot;;&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(I didn&amp;#8217;t know I could leave the &lt;code&gt;$sum = 0;&lt;/code&gt; out, but someone with more perl knowledge pointed this out to me)&lt;/p&gt;

&lt;p&gt;Very handy!&lt;/p&gt;</content>
 </entry>
 
 
</feed>
