<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-10678074</id><updated>2012-02-01T08:58:24.504Z</updated><category term='mobile'/><category term='nostalgia'/><category term='flash'/><category term='europython'/><category term='templates'/><category term='shitjs'/><category term='hotmail'/><category term='phones'/><category term='html5'/><category term='clojure'/><category term='web'/><category term='gadgets'/><category term='bugs'/><category term='HD'/><category term='hash'/><category term='short film'/><category term='art'/><category term='api'/><category term='pyweek'/><category term='theatre'/><category term='dbus'/><category term='ipython'/><category term='chrome'/><category term='jslint'/><category term='bazaar'/><category term='joypad'/><category term='py3k'/><category term='audio'/><category term='DOM'/><category term='iphone'/><category term='pyconuk'/><category term='css'/><category term='daemontools'/><category term='js'/><category term='git'/><category term='cython'/><category term='nginx'/><category term='app'/><category term='url encoding'/><category term='alsa'/><category term='vim'/><category term='xbox'/><category term='launchpad'/><category term='hg'/><category term='actionscript'/><category term='review'/><category term='laptop'/><category term='dj'/><category term='xml'/><category term='POST'/><category term='cheeseshop'/><category term='sqlobject'/><category term='threads'/><category term='setuptools'/><category term='tinypy'/><category term='camera'/><category term='security'/><category term='bzr'/><category term='store'/><category term='language'/><category term='cobra'/><category term='webgl'/><category term='wordpress'/><category term='galcon'/><category term='crud'/><category term='gpu'/><category term='dojo'/><category term='numpy'/><category term='android'/><category term='pyopengl'/><category term='the lonesome west'/><category term='gsoc2008'/><category term='desktop'/><category term='intel'/><category term='craft'/><category term='glsl'/><category term='ninja'/><category term='mac'/><category term='ssl'/><category term='pypi'/><category term='bars beijing'/><category term='design'/><category term='making'/><category term='switzerland'/><category term='genshi'/><category term='pygame.'/><category term='testing'/><category term='ubuntu'/><category term='GET'/><category term='blogging'/><category term='love'/><category term='pywebsite'/><category term='duck typing'/><category term='batching'/><category term='svn'/><category term='berlin'/><category term='google'/><category term='bugzilla'/><category term='dependencies'/><category term='wordnerd'/><category term='packaging'/><category term='javascript'/><category term='teevee'/><category term='midim python'/><category term='apple'/><category term='perl'/><category term='sony'/><category term='raspberrypi'/><category term='blender'/><category term='zine'/><category term='thumbnails'/><category term='wacom'/><category term='wine'/><category term='midi'/><category term='http'/><category term='osx'/><category term='unladenswallow'/><category term='pygamezine'/><category term='ctypes'/><category term='rsi'/><category term='node'/><category term='pys60'/><category term='randomshit'/><category term='cdb'/><category term='nokia'/><category term='opengl'/><category term='python'/><category term='wsgi'/><category term='zodb'/><category term='llvm'/><category term='graphing'/><category term='parallel'/><category term='compiz'/><category term='distutils'/><category term='london'/><category term='melbourne'/><category term='jit'/><category term='database'/><category term='linux'/><category term='apache'/><category term='screen'/><category term='drawing'/><category term='howto'/><category term='python3'/><category term='tutorial'/><category term='sqlite'/><category term='protocol buffers'/><category term='buildout'/><category term='multicore'/><category term='music'/><category term='games'/><category term='backups'/><category term='website'/><category term='goat'/><category term='samsung'/><category term='pickle'/><category term='asm'/><category term='bitbucket'/><category term='jquery'/><category term='gvim'/><category term='ludumdare'/><category term='lxml'/><category term='terminal'/><category term='sql'/><category term='cherrypy'/><category term='parrot'/><category term='play'/><category term='orm'/><category term='dictionary'/><category term='microsoft'/><category term='s60'/><category term='pygame'/><category term='SHA-1'/><category term='vj'/><category term='decimal'/><category term='pypy'/><title type='text'>making apps, making webs.</title><subtitle type='html'>About making apps, and web development.  Indie, shareware, open source, freelance are some of the topics I will bore you with.  So BEWARE!</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default?start-index=101&amp;max-results=100'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>265</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-10678074.post-4830659618935824068</id><published>2011-12-19T06:24:00.003Z</published><updated>2011-12-19T06:49:22.688Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>CherryPy - I love it because it's pyhon.</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tr valign="top"&gt;&lt;td&gt;&lt;a href="http://cherrypy.org/"&gt;CherryPy&lt;/a&gt; moved to bitbucket a while ago, and also got a website refresh.&lt;br /&gt;&lt;br /&gt;I love cherrypy, since I can use it with python 3 - not legacy python.&lt;br /&gt;&lt;br /&gt;I love cherrypy, because I can just use python objects.&lt;br /&gt;&lt;br /&gt;I love cherrypy because it has a clever name.&lt;br /&gt;&lt;br /&gt;I love cherrypy, because it just works.&lt;br /&gt;&lt;br /&gt;I love cherrypy, it is minimal.&lt;br /&gt;&lt;br /&gt;I love cherrypy.&lt;/td&gt;&lt;td valign="top"&gt;&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;a href="http://cherrypy.org/"&gt;&lt;img alt="" class="site" src="http://cherrypy.org/images/cherrypy.png" width="128" border="0" style="border:0"/&gt;&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4830659618935824068?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4830659618935824068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4830659618935824068' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4830659618935824068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4830659618935824068'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/12/cherrypy-i-love-it-because-its-pyhon.html' title='CherryPy - I love it because it&apos;s pyhon.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3399472465654317904</id><published>2011-12-07T15:11:00.001Z</published><updated>2011-12-07T15:12:25.623Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python3'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Thoughts on Python 3</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;It's awesome.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://getpython3.com/"&gt;Go get some!&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3399472465654317904?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3399472465654317904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3399472465654317904' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3399472465654317904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3399472465654317904'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/12/thoughts-on-python-3.html' title='Thoughts on Python 3'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7785466307175744528</id><published>2011-11-20T13:11:00.001Z</published><updated>2011-11-20T13:15:09.231Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='pygamezine'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='zine'/><title type='text'>PyGameZine issue0</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Today we are very excited to announce the launch of &lt;a href="http://www.pygamezine.com/"&gt;PyGameZine!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.pygame.org/"&gt;&lt;img border="0" src="http://www.pygame.org/pygamezine_cover_0.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There is more information about it on the &lt;a href="http://www.pygame.org/"&gt;http://www.pygame.org/ website&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7785466307175744528?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7785466307175744528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7785466307175744528' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7785466307175744528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7785466307175744528'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/11/pygamezine-issue0.html' title='PyGameZine issue0'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-5251903463987373382</id><published>2011-11-11T07:43:00.000Z</published><updated>2011-11-11T07:43:43.118Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='nokia'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame.'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Vintage in Paris</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;img border="0" height="80" src="http://4.bp.blogspot.com/-OIo_VLTedFg/TrQmXdvGfFI/AAAAAAAAANA/BwqrgKHZCQU/s320/vintage-in-paris-logo-360x90.png" width="320" /&gt;&lt;br /&gt;&lt;br /&gt;Our Vintage in Paris app has been published on the &lt;a href="http://store.nokia.com/content/217764"&gt;Nokia app store&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;&lt;img border="0" height="300" src="http://1.bp.blogspot.com/-qCcvKmOOgrY/TqVM6ShgKII/AAAAAAAAANk/L_yMg8uCM8o/s400/IMG_5805.JPG" width="400" /&gt;&lt;br /&gt;&lt;br /&gt;The process was pretty simple, since it was a very technically basic but content heavy app.&lt;br /&gt;&lt;br /&gt;The main difficulty in this app was walking around the streets of Paris taking pictures, and researching really good places to find Vintage.&lt;br /&gt;&lt;h2&gt;Why a Vintage in Paris app?&lt;/h2&gt;Finding cool second hand and retro clothes is a hobby of mine, and my partners.&amp;nbsp;&amp;nbsp; It's always fun finding interesting old styles, rummaging through clothes racks.&amp;nbsp; Especially in other countries, and especially when you find a bargain.&lt;br /&gt;&lt;br /&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/-BXcJyKUt1Yk/TqLaBtr4UKI/AAAAAAAAAFQ/WNj7hADIsr4/s400/IMG_4068.JPG" width="300" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's something special about wandering down some back alley, and finding an old shop stuffed to the rafters with old stuff.&amp;nbsp; It's like taking a journey back in time to some fantastical version of Paris you may have in your head.&amp;nbsp; If you like Art Deco stuff, then Paris is the place to get it.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What was the signup to the Nokia store like?&lt;/h2&gt;I have been signed up as a Nokia developer for quite a while already, so there hasn't been too much paper work, or forms to fill out.&amp;nbsp; I can't remember what I needed to do originally, so there might be more bureaucracy than I remember.&amp;nbsp; I'm sure there will be more forms for me to fill out in the future too.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Technical parts.&lt;/h2&gt;The app is available as a J2ME Java app, a Meego app, and a WRT app.&amp;nbsp; Nokia has so many different platforms now!&amp;nbsp; They are adding a couple more platforms too.&amp;nbsp; Luckily HTMLish apps "work" on all their platforms.&lt;br /&gt;&lt;br /&gt;Our Content Management System(CMS) is written in Python/JavaScript/C/SQLite and uses &lt;a href="http://www.pygame.org/"&gt;pygame&lt;/a&gt; for image processing.&amp;nbsp; The CMS part is still in development, but is slowly getting there.&lt;br /&gt;&lt;br /&gt;We use a form based system to define schemas.&amp;nbsp; I wrote about this in a "&lt;a href="http://renesd.blogspot.com/2010/04/validation-through-html-forms.html"&gt;Validation through html forms&lt;/a&gt;" blog post, and mainly in "&lt;a href="http://renesd.blogspot.com/2010/01/using-html-form-as-model.html"&gt;Using a html form as the model&lt;/a&gt;".&amp;nbsp; Basically this allows us to create a html form, and then that's it for the content type.&amp;nbsp; No need to mess around with schemas, or python models, just create a html form, and that is it.&amp;nbsp; Since I usually follow a design led approach, the html forms are usually done before anything else.&lt;br /&gt;&lt;br /&gt;The data is stored in a mini database system I built which I detailed in the blog post "&lt;a href="http://renesd.blogspot.com/2009/12/pywebsitesqlitepickle-sqlite-vs-pickle.html"&gt;sqlitepickle SQLite Vs pickle&lt;/a&gt;".&amp;nbsp; It lets you use a dict like interface to save python objects.&amp;nbsp; It's basically a very simple key value store built on python stdlib modules.&lt;br /&gt;&lt;br /&gt;We're using JavaScript on the server side as I detailed in a blog post "&lt;a href="http://renesd.blogspot.com/2011/10/server-side-jquery-ssjquery.html"&gt;server side jQuery&lt;/a&gt;" to generate the html.&amp;nbsp; The nice thing is I can use jQuery plugins on either the client side or server side depending on the need.&amp;nbsp; Including form validation, and other goodies.&amp;nbsp; I see it as a replacement for a templating language.&lt;br /&gt;&lt;br /&gt;This app as it stands doesn't need much of a CMS, but future apps we have in development require a beast of a system in order to process the vast amount of data - and squeeze it down onto various different formats ready for distribution on multiple channels.&lt;br /&gt;&lt;br /&gt;&lt;img border="0" height="300" src="http://4.bp.blogspot.com/-OzLwPhdVqnA/TqVDB1W-bKI/AAAAAAAAALs/jYEGx49_35Q/s400/IMG_4654.JPG" width="400" /&gt;&lt;br /&gt;&lt;br /&gt;Well it's out there now.&amp;nbsp; So hopefully it'll help some fellow vintage treasure hunters find some good stuff in Paris.&lt;br /&gt;&lt;br /&gt;This is part of a series of blog posts on "&lt;a href="http://renesd.blogspot.com/search/label/app"&gt;my journey getting published on various app stores&lt;/a&gt;".&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-5251903463987373382?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/5251903463987373382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=5251903463987373382' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5251903463987373382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5251903463987373382'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/11/vintage-in-paris.html' title='Vintage in Paris'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-OIo_VLTedFg/TrQmXdvGfFI/AAAAAAAAANA/BwqrgKHZCQU/s72-c/vintage-in-paris-logo-360x90.png' height='72' width='72'/><thr:total>0</thr:total><georss:featurename>Paris, France</georss:featurename><georss:point>48.856614 2.3522219</georss:point><georss:box>48.773036 2.1942934 48.940192 2.5101504</georss:box></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-531526245562315094</id><published>2011-10-28T09:04:00.000+01:00</published><updated>2011-10-28T09:04:02.649+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><title type='text'>Halloween pumpkin juggling published to intel appup</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So it looks like the little Halloween game we made has been published on the intel appup store.&lt;br /&gt;&lt;br /&gt;It is listed here:&lt;br /&gt;&lt;a href="http://www.appup.com/applications/applications-Halloween+Pumpkin+Juggling"&gt;http://www.appup.com/applications/applications-Halloween+Pumpkin+Juggling&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-531526245562315094?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/531526245562315094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=531526245562315094' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/531526245562315094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/531526245562315094'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/halloween-pumpkin-juggling-published-to.html' title='Halloween pumpkin juggling published to intel appup'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4541264602808004395</id><published>2011-10-21T10:13:00.000+01:00</published><updated>2011-10-21T10:13:25.551+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='samsung'/><title type='text'>Getting into the Samsung store</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So, I registered for the Samsung app store 'thingy' the other day.&lt;br /&gt;&lt;br /&gt;Samsung have a number of platforms themselves, not just one platform.&amp;nbsp; Including Bada, Android, Tizen, and windows mobile 7.&amp;nbsp; They have tablets, TVs, laptops, mobile phones... and probably other things too (maybe internet fridges?).&lt;br /&gt;&lt;br /&gt;It seems most of the platforms support web apps of some sort.&amp;nbsp; Either through wrapping with phonegap (Bada, Android, win7) or just accepting an archive of the files.&lt;br /&gt;&lt;br /&gt;Once joined you can distribute free apps through there.&amp;nbsp; Which is quite lovely really.&amp;nbsp; They have their own advertising program, and I'm not sure if you're allowed to do In App purchases with them.&lt;br /&gt;&lt;br /&gt;It seems for TV, you can only distribute to the US.&amp;nbsp; Not to other places around the world.&amp;nbsp; No idea when or if that is going to be possible.&amp;nbsp; Yes, their SDK does include support for 3D content.&amp;nbsp; After speaking briefly with someone(I didn't get their name) at a JavaScript meetup I found out you can try out apps on your own TV/DVD player without having to release to the store.&lt;br /&gt;&lt;br /&gt;In order to sell applications, you have to submit a bunch of company paperwork - and sign over your first born child*.&amp;nbsp; They don't currently charge you join though, which is nice compared to some other programs.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;sub&gt;* may be a joke.&lt;/sub&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4541264602808004395?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4541264602808004395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4541264602808004395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4541264602808004395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4541264602808004395'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/getting-into-samsung-store.html' title='Getting into the Samsung store'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7293980192847760903</id><published>2011-10-20T13:34:00.000+01:00</published><updated>2011-10-20T13:38:18.446+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='intel'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Android developer store, problem. No problem.</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So, I've got my app working on Android.&amp;nbsp; It's not even all that slow.&amp;nbsp; Ok, it is a little slow.&amp;nbsp; However the new webkit upgrade in Android 4.0 should get it going fast.&amp;nbsp; Note that Android 4.0 has approximately 0% of the android users on it at the moment - since they haven't really released it yet.&lt;br /&gt;&lt;br /&gt;I had to get touch events working with gamejs, which wasn't all that hard.&amp;nbsp; I had a little chat on the mailing list, about it, then implemented it not long after.&amp;nbsp; I will send a pull request soon to that project soon.&lt;br /&gt;&lt;br /&gt;I'd like to do a phonegap implementation of sound for shitsound too, but haven't got around to that.&amp;nbsp; This should get around the html5 Audio issues on the android browsers.&amp;nbsp; But the game is pretty much ready.&lt;br /&gt;&lt;br /&gt;So now that it's ready, I went to sign up to the Android market place so that I could try and release the application.&amp;nbsp; I went through the signup process, and paid my $25USD.&amp;nbsp; I even got sent a receipt.&amp;nbsp; But then something weird happened.&amp;nbsp; I followed the link, to try and login... but it just sent me back to the signup page again.&lt;br /&gt;&lt;br /&gt;The help suggested I try all sorts of things, including just signing up again with another credit card... and if all that fails finally to send them a support request.&amp;nbsp; So now I'm waiting on the famous Google Support to get back to me to fix up my account... or so I thought.&lt;br /&gt;&lt;br /&gt;I tried one more time, but this time with another browser.&amp;nbsp; Somehow it had gotten my personal account mixed up with my business account.&amp;nbsp; So I cancelled the registration that got mixed up, and then reapplied again after cleaning cache and clearing cookies. &lt;br /&gt;&lt;br /&gt;So anyway... long story short, my Android Market account seems to work now.&lt;br /&gt;&lt;br /&gt;I linked up my google checkout account to it - the same one I used for the google chrome web store.&amp;nbsp; Then it told me I can now sell apps on the android store.&lt;br /&gt;&lt;br /&gt;So now I have to actually try and release this game, and get it through the validation process.&amp;nbsp; Luckily I heard the android validation process is really quick.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7293980192847760903?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7293980192847760903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7293980192847760903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7293980192847760903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7293980192847760903'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/android-developer-store-problem-no.html' title='Android developer store, problem. No problem.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-8094642946273990606</id><published>2011-10-17T15:43:00.000+01:00</published><updated>2011-10-17T15:43:39.979+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='intel'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>notes on chome, and android.</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;One thing I forgot to mention was that my flash sound for chrome did not work after uploading to the chrome web store.&amp;nbsp; I made the change at the last minute to use flash for sound, because chrome sound was bad for me.&amp;nbsp; Of course, a change made at the last minute will be a bug!&amp;nbsp; Luckily the bug was reported to me, and I fixed it quickly.&amp;nbsp; This made me glad that the chrome webstore allowed very fast updating.&amp;nbsp; I can deploy updates there as quickly as uploading to a website.&amp;nbsp; It also made me remember the importance of testing from the users perspective.&amp;nbsp; Always check you changes on the live version that people use, rather than just on development servers or simulators.&amp;nbsp; You need to get into the users shoes and experience it the same way they do.&lt;br /&gt;&lt;br /&gt;I did a quick port to android, and tested it on my Advent Vega tablet with android 2.2.&amp;nbsp; Surprisingly the game ran fairly well.&amp;nbsp; There were a couple of modern javascript features I was using that did not work, but I quickly found those bugs (html5 data attributes was the main one).&lt;br /&gt;&lt;br /&gt;I also needed to add touch support to the game, since so far it only works with mouse and keyboard.&amp;nbsp; You can play it with the mouse emulation that the browsers support by tapping on the screen to move the player around.&amp;nbsp; However it would be much nicer if it worked by dragging your finger around.&lt;br /&gt;&lt;br /&gt;I have an android environment setup from some previous projects, so I'll be doing that port next.&amp;nbsp; I'm only going to release it for very modern androids that have a fast enough browser in it.&amp;nbsp; Canvas and javascript have changed so much in the last year, and last years android just isn't good enough (neither is todays really... we wait for android 4 for decent graphics and audio support).&amp;nbsp; The other point in favour of releasing on android next is that publishing to the android market is a very easy thing to do.&lt;br /&gt;&lt;br /&gt;I'm not sure about doing an iphone port yet, since Halloween is 13 days away - and I am doubtful I could get it through their store acceptance process in time.&amp;nbsp; But I'll make the decision on which store goes next after the android port is done.&lt;br /&gt;&lt;br /&gt;I decided to up the $ amount for the &lt;a href="http://www.ludumdare.com/compo/2011/09/28/announcing-october-challenge-2011/"&gt;Ludumdare October challenge&lt;/a&gt;, since the game has made over $1 now.&amp;nbsp; So my next personal challenge amount is now $1000 in October.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-8094642946273990606?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/8094642946273990606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=8094642946273990606' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8094642946273990606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8094642946273990606'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/notes-on-chome-and-android.html' title='notes on chome, and android.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4792560540569432514</id><published>2011-10-17T09:39:00.000+01:00</published><updated>2011-10-17T09:39:29.859+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='intel'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>beta testing intel appup apps</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So, I've been going around in circles the last few days with the validation our app on the intel appup store.&lt;br /&gt;&lt;br /&gt;The support people escalated my request, and it looks like they have fixed a problem with the validation program.&amp;nbsp; It looks like their automated validation program had a bug.&lt;br /&gt;&lt;br /&gt;In the mean time I've gone through the beta testing process.&amp;nbsp; This is where you can send your app to some beta testers and ask them to test for you.&amp;nbsp; If they already have the intel appup installed on their computer, your app appears in their "My Apps" section.&amp;nbsp; Then you can click on it, to try and download+install.&lt;br /&gt;&lt;br /&gt;Just like the Mac OSX Application stores, if the download fails halfway through the system fails.&amp;nbsp; This is 2011 mind you, so you'd hope that people had figured out that internet downloads could possibly fail, and might need resuming.&amp;nbsp; Especially on mobile netbooks which are using unreliable 3g wireless internet connections.&lt;br /&gt;&lt;br /&gt;As far as I can tell, there is no automated feedback collecting system in place.&amp;nbsp; Which means you will need to manage that feedback yourself.&amp;nbsp; Either by emailing your beta testers or using your own in game beta feedback forms.&amp;nbsp; If you're going to be releasing on multiple platforms, you'll want to create your own beta testing process anyway.&amp;nbsp; Since not all platforms make feedback easy, or possible at all.&lt;br /&gt;&lt;br /&gt;It took me quite a while to actually download anything on their store.&amp;nbsp; Even small programs took a while.&amp;nbsp; I guess they are having connectivity issues with their download servers.&amp;nbsp; A 0.42MB app took over 10 minutes and multiple tries to download successfully.&lt;br /&gt;&lt;br /&gt;The apps the html5 encapsulator by intel creates all include their own web browser.&amp;nbsp; Which means that every app is at least 10MB big, not even including your app data.&amp;nbsp; This is compared to other platforms, you mostly only need to include your actual data, or have a thin wrapper - like phonegap - which doesn't take up too much space. &lt;br /&gt;&lt;br /&gt;Anyway... fingers crossed it passes their validation process soon.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4792560540569432514?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4792560540569432514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4792560540569432514' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4792560540569432514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4792560540569432514'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/beta-testing-intel-appup-apps.html' title='beta testing intel appup apps'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-684128545855595258</id><published>2011-10-14T10:54:00.003+01:00</published><updated>2011-10-14T11:56:19.114+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>'Halloween Juggling Pumpkin' published to the chrome web store... I think.</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Well, I clicked the publish button, and it seems the '&lt;a href="https://chrome.google.com/webstore/detail/ndnpdjgfifincamlnbidkagoljbiagcb"&gt;Halloween Juggling Pumpkin&lt;/a&gt;' app has been published to the chrome web store.&amp;nbsp; I'm quite happy that it is up!&lt;br /&gt;&lt;br /&gt;Here is a screen shot of the menu screen.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://chrome.google.com/webstore/detail/ndnpdjgfifincamlnbidkagoljbiagcb"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-jzdfvj5Liz8/TpgFaFkmU8I/AAAAAAAAAMk/tU6wOIvr4yI/s1600/menu.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Well, that wasn't too hard to do after all.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is a screenshot of some game play.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://chrome.google.com/webstore/detail/ndnpdjgfifincamlnbidkagoljbiagcb"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-56NIkW7brlM/TpgFZNhg24I/AAAAAAAAAMc/ORzjqwnH6ok/s1600/gameplay1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here is the lovely store URL it gave me for the store:&lt;a href="https://chrome.google.com/webstore/detail/ndnpdjgfifincamlnbidkagoljbiagcb"&gt;https://chrome.google.com/webstore/detail/ndnpdjgfifincamlnbidkagoljbiagcb&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This was way less work compared to the intel appup store, which  I'm still having issues publishing it.  To be fair, their store is still in beta for html5 apps.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-684128545855595258?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/684128545855595258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=684128545855595258' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/684128545855595258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/684128545855595258'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/halloween-juggling-pumpkin-published-to.html' title='&apos;Halloween Juggling Pumpkin&apos; published to the chrome web store... I think.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-jzdfvj5Liz8/TpgFaFkmU8I/AAAAAAAAAMk/tU6wOIvr4yI/s72-c/menu.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-5913307933801521016</id><published>2011-10-14T08:37:00.000+01:00</published><updated>2011-10-14T11:56:36.459+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>encapsulator app 'binary validation failed' no other details.</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Just got a rejection notice for my intel appup app, with 'binary validation failed'.&amp;nbsp; There were no other details, which seems to be typical for this program.&lt;br /&gt;&lt;br /&gt;I've sent them some messages for more information, so I'm expecting a few days of waiting before anything happens.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-5913307933801521016?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/5913307933801521016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=5913307933801521016' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5913307933801521016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5913307933801521016'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/encapsulator-app-binary-validation.html' title='encapsulator app &apos;binary validation failed&apos; no other details.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7511247129091268488</id><published>2011-10-14T07:37:00.002+01:00</published><updated>2011-10-14T12:06:16.517+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>chrome audio sucks</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Chrome Audio is worse than firefox, safari, and internet explorer Audio.&lt;br /&gt;&lt;br /&gt;There are cracks, pops, and sounds cut short.&amp;nbsp; It seems there's also not many sounds that can be played at once.&lt;br /&gt;&lt;br /&gt;Luckily I can use &lt;a href="http://renesd.blogspot.com/2011/09/jqueryshitsoundjs-shit-sound-player-for.html"&gt;jquery.shitsound&lt;/a&gt; and soundmanager2 to prefer using flash audio over a javascript bridge.&amp;nbsp; This has a slight delay compared to firefox/safari html5 Audio, but is better than the built in chrome Audio.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7511247129091268488?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7511247129091268488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7511247129091268488' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7511247129091268488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7511247129091268488'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/chrome-audio-sucks.html' title='chrome audio sucks'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-66517369000085820</id><published>2011-10-13T14:44:00.001+01:00</published><updated>2011-10-14T11:57:04.265+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>export scripts for app</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So today I've been writing a couple of export scripts for my October challenge apps.&lt;br /&gt;&lt;br /&gt;I set the config in the main html file using html5 data attributes.&amp;nbsp; Then read that config on app startup.&amp;nbsp; This seems like a fairly easy way to customise the app depending on platform.&amp;nbsp; My export script selects the correct html for each platform on export.&lt;br /&gt;&lt;br /&gt;I have to create the correct data sets for each platform.&amp;nbsp; The right sound formats (ogg, mp3, wav), and the right sized images (From 1080 HD to 320x200 screen).&amp;nbsp; As well as select the correct fonts.&amp;nbsp; I can't just include all the assets for each platform, since there are size restrictions.&amp;nbsp; As well the source, full sized raw data can be over 5GB for one app (for my content heavy app).&lt;br /&gt;&lt;br /&gt;Then I have to package them up depending on platform, with manifest files and other strangeness.&amp;nbsp; Or I need to zip them up in a zip archive.&lt;br /&gt;&lt;br /&gt;I'm not completely automating the process yet.&amp;nbsp; I'll wait to see if the apps get any traction before investing time in complete automation.&amp;nbsp; Completely automating releases is essential for supporting lots of platforms.&amp;nbsp; Without it, your whole time can be spent releasing, rather than making the apps better.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-66517369000085820?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/66517369000085820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=66517369000085820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/66517369000085820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/66517369000085820'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/export-scripts-for-app.html' title='export scripts for app'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-6194454491039906759</id><published>2011-10-12T10:00:00.000+01:00</published><updated>2011-10-14T11:57:18.373+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='wine'/><title type='text'>Signed my app with certificate, and submitted for validation again.</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="entry"&gt;So, I managed to sign my app and submit it for validation on the appup store.&lt;br /&gt;It took at bit of messing around, converting certificates, and installing lots of microsoft software, but eventually got my msi signed, and submitted to the store.&lt;br /&gt;That made me happy.&amp;nbsp; Now I’m off to drink wine!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-6194454491039906759?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/6194454491039906759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=6194454491039906759' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6194454491039906759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6194454491039906759'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/signed-my-app-with-certificate-and.html' title='Signed my app with certificate, and submitted for validation again.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1844984430192786966</id><published>2011-10-12T06:30:00.000+01:00</published><updated>2011-10-14T11:57:32.166+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Intel appup progress. Got certificate, looking forward to webkit upgrade.</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="entry"&gt;Well, some good news on the intel appup front.&lt;br /&gt;I finally managed to get my certificate, so I should be able to now sign my apps to upload.&amp;nbsp; Unfortunately I used firefox to download the certificate, which means that I need to convert files in order to get into the microsoft fomat needed for code signing.&amp;nbsp; So I’d recommend anyone else use IE8 to save that hassle.&lt;br /&gt;As well, I’ve been reporting my problems with the webkit they use in their forums.&amp;nbsp; They just gotten back to me, and say they hope to use the latest webkit (which should include a year of webkit bug fixes and feature additions).&lt;br /&gt;So now, I’m going back to trying to submit my app again.&amp;nbsp; I hope that it gets through!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1844984430192786966?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1844984430192786966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1844984430192786966' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1844984430192786966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1844984430192786966'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/intel-appup-progress-got-certificate.html' title='Intel appup progress. Got certificate, looking forward to webkit upgrade.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7537496087888062977</id><published>2011-10-11T02:30:00.000+01:00</published><updated>2011-10-14T11:57:48.495+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='store'/><title type='text'>chrome web store</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="entry"&gt;We’ve started to look into distributing our app via the chrome web store.&lt;br /&gt;I’ve signed up for a developer account, and started reading the documentation on how to publish apps.&amp;nbsp; So far it has been easy.&amp;nbsp; All of their forms have worked, and so far the documentation is easy.&amp;nbsp; This time I’m trying to do as much of the administration up front.&amp;nbsp; Things like validating my account and setting up payments.&amp;nbsp; Only after that works will I actually attempt to publish my app.&lt;br /&gt;Let’s hope it’s easier than the intel appup program, which I’m still not able to publish my app through.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7537496087888062977?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7537496087888062977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7537496087888062977' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7537496087888062977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7537496087888062977'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/chrome-web-store.html' title='chrome web store'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-2222372830690921497</id><published>2011-10-10T09:30:00.000+01:00</published><updated>2011-10-14T11:58:05.255+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='ssl'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Applied for certificate, thinking about what to do next?</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="entry"&gt;I got an email back from Comodo about the code signing certificate, and now their form works.&amp;nbsp; Then I had to submit my company certificate, and then have to wait for up to 2 days to get the certificate.&lt;br /&gt;I probably should have realised I needed this certificate before, and applied earlier.&amp;nbsp; Oh well.&amp;nbsp; For some reason I didn’t remember this was needed.&lt;br /&gt;Next I’ll begin packaging it up for the google web chrome store, so maybe we can sell some on there too.&amp;nbsp; I don’t think that will take all that long to do.&lt;br /&gt;Finishing the iOS port might be hard since I’ve noticed the performance of JavaScript and canvas on old iOS devices is terrible.&amp;nbsp; I could just make it available for iOS 5, and the latest iphone 4 phones though… they might be fast enough.&amp;nbsp; I’ve been exploring possible optimizations for it too.&amp;nbsp; So I’ll see how that goes.&lt;br /&gt;I’m in the same situation with the android port.&amp;nbsp; The current web browsers on there are fairly garbage for canvas performance, so I’d need to do some performance work before it would work on there.&amp;nbsp; Making it available on the latest versions of Android is also one possibility.&amp;nbsp; I know an android application is likely to be accepted faster than an iOS one, so that might sway me to release there first.&lt;br /&gt;A Mac application is also possible I guess.&amp;nbsp; For that I’d need to figure out if there is a UIWebKit wrapper that is easy to use, and quick to integrate.&lt;br /&gt;The other option is to finish the other intel appup app I have in development.&amp;nbsp; But porting this game to other platforms seems easier I think.&amp;nbsp; Once the whole process is done I’ll have an idea of how long the other app would take to do for the appup platform.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-2222372830690921497?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/2222372830690921497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2222372830690921497' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2222372830690921497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2222372830690921497'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/applied-for-certificate-thinking-about.html' title='Applied for certificate, thinking about what to do next?'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7809097795285520579</id><published>2011-10-08T08:30:00.000+01:00</published><updated>2011-10-14T11:58:19.971+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Battling Intel Appup submission</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="entry"&gt;Well, I managed to prepare my app for submission to the intel appup store.&lt;br /&gt;I first had to figure out bugs: Sound doesn’t work. Also fonts don’t work. This was very disappointing considering that I’ve been working with a musician on sound effects and music. So we’re not able to use any of that work we did until they fix sound. I even tried to use a flash based sound player, and use the embed tag. None of it worked.&lt;br /&gt;Also the lovely font we selected does not work. Trying to use a font-face crashed the browser completely. So instead I had to use ‘Arial’. arg.&lt;br /&gt;I’m not sure what sort of html5 games and apps they expect if fonts and sounds aren’t working?&lt;br /&gt;It seems they are using a 1 year old webkit implementation, so I hope they will upgrade their encapsulator soon. One year in web browser years is about 70 human years.&lt;br /&gt;Anyway, we decided to submit the app anyway. The font makes it look a bit ugly, and without sounds it looses a lot – but at least the game play works.&lt;br /&gt;Then I filled out a few pages of forms, prepared images, wrote copy, and did all sorts of guff so that I could upload the app. For some reason they required silverlight or google gears to upload the file (weird). Not sure why they couldn’t use a normal html upload form, or even a flash upload form.&lt;br /&gt;Anyway… all that got done until I had to apply for a security certificate to sign the files. I fill out another form of my personal details, press submit and I’m greeted with a great error message: “An error has occurred. -1″&lt;br /&gt;Oh well. Sent off an email for support, and now I wait.&lt;br /&gt;Finally blocked after a couple of long days and nights – stopped by the error “-1″.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7809097795285520579?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7809097795285520579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7809097795285520579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7809097795285520579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7809097795285520579'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/battling-intel-appup-submission.html' title='Battling Intel Appup submission'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-8779942161462721629</id><published>2011-10-07T06:30:00.000+01:00</published><updated>2011-10-14T11:58:33.652+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='ludumdare'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>EULA we can use? (End User License Agreement)</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="entry"&gt;Hi,&lt;br /&gt;got my app up to the packaging stage now…&lt;br /&gt;Does anyone know of a decent (End User License Agreement) EULA we can use for our games?&amp;nbsp; If you know of ones we can use please leave a comment.&lt;br /&gt;cheers,&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-8779942161462721629?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/8779942161462721629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=8779942161462721629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8779942161462721629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8779942161462721629'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/eula-we-can-use-end-user-license.html' title='EULA we can use? (End User License Agreement)'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4501912346718787482</id><published>2011-10-06T13:21:00.000+01:00</published><updated>2011-10-14T11:58:46.617+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='app'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>I'm in</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="entry"&gt;October came around, and I started working on a game.&lt;br /&gt;It’s javascript/canvas based, instead of my usual pygame. But, I’m using gamejs which uses the pygame API, so I feel pretty much at home.&lt;br /&gt;We got most of our new graphics and sound into the game today, and all of the game play is done.&lt;br /&gt;It’s not running fast enough on my ipod touch 2g, but I think with some work it could be playable. So we’re aiming to release on the various web stores first. Then perhaps improve things for the mobile platforms.&lt;br /&gt;I had to work on improving a sound engine I call &lt;a href="http://renesd.blogspot.com/2011/09/jqueryshitsoundjs-shit-sound-player-for.html"&gt;jquery.shitsound&lt;/a&gt;, or just shitsound for short. Which uses various web browser sound APIs to work. I’ll have to get it using the phonegap framework to play audio too, since html5 Audio on mobile platforms is simply broken.&lt;br /&gt;We’re in, I should say. Since I’m doing a collaboration with &lt;a href="http://www.spencersternberg.com/"&gt;Spencer Sternberg&lt;/a&gt; ( &lt;a href="http://www.spencersternberg.com/"&gt;http://www.spencersternberg.com/&lt;/a&gt; ) video game audio and music productions.&lt;br /&gt;The second app I’m working on next after this one is released I’m doing as a &lt;a href="http://www.poweredbybees.com/"&gt;Powered By Bees&lt;/a&gt; production ( &lt;a href="http://www.poweredbybees.com/"&gt;http://www.poweredbybees.com&lt;/a&gt; ). It’s less game related, and more content related, but I still think it will count for this October Challenge.&lt;br /&gt;Thanks Ludumdare!&amp;nbsp; This October competition has really given me a big kick up the backside.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4501912346718787482?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4501912346718787482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4501912346718787482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4501912346718787482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4501912346718787482'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/october-came-around-and-i-started.html' title='I&apos;m in'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-8499619828224554227</id><published>2011-10-02T10:22:00.000+01:00</published><updated>2011-10-02T10:22:01.997+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='node'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Server Side jQuery - ssjquery</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;I've got a new server side jQuery project up.&amp;nbsp; It's an extension on some ideas and projects over the past couple of years.&amp;nbsp; It uses the node.js javascript interpreter, and node libraries like jsdom, and htmlparser to do all the work.&amp;nbsp; It can be used within various projects that are not javascript via a command line process or a web service.&lt;br /&gt;&lt;br /&gt;This is what the pipeline looks like on the server side.&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;json + html + server side jquery =&amp;gt; rendered html&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Instead you can run it on the client side so you don't need a server for development.&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: small;"&gt;json + html + ssjquery run on client first before other scripts =&amp;gt; rendered html&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;A webservice creates the json, and your server side jQuery scripts populate the html.&amp;nbsp; Think of it as an industrial strength templating language that millions of front end developers know how to use.&lt;br /&gt;&lt;br /&gt;Here are my &lt;a href="http://rene.f0o.com/%7Erene/ssjquery_talk/embedder.html#index.html"&gt;server side jQuery slides&lt;/a&gt; I gave at the reject.js conference in Berlin last week.&amp;nbsp; It wasn't a great talk, but I think it's helped me understand a little more on how to explain the concept to people.&amp;nbsp; I purposely did not put any code in that talk, so I'm providing it here.&amp;nbsp; Instead I concentrated on why you'd want to do it.&amp;nbsp; I might try and write up my talk notes as a separate blog post.&lt;br /&gt;&lt;br /&gt;Here is the project page: &lt;a href="https://bitbucket.org/illume/ssjquery"&gt;https://bitbucket.org/illume/ssjquery&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There is a python buildout script which downloads node.js, and all required libraries into a directory ready to run (with the npm package manager).&amp;nbsp; In there it creates a bin directory for the bin/ssjquery script for the command line version and bin/ssjqueryServer for the server version.&lt;br /&gt;&lt;br /&gt;As a bonus, I also install the uglifyjs binaries, and coffee script binaries - but they are not required.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is how you run the python buildout...&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ hg clone https://bitbucket.org/illume/ssjquery&lt;br /&gt;$ cd ssjquery/pythonbuildout&lt;br /&gt;$ python bootstrap -d&lt;br /&gt;$ ./bin/buildout&lt;br /&gt;$ cd ..&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is how the command line script ssjquery is called to output rendered html.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd js/example/&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;$ ../../pythonbuildout/bin/ssjquery ./ server.json index.html jquery.js yourServerSide.js yourServerSide2.js &amp;gt; renderedHtml.html&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is the ssjqueryServer script which listens as a webservice to render html.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd js/example/&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;$ ../../pythonbuildout/bin/ssjqueryServer ./ server.json index.html jquery.js yourServerSide.js yourServerSide2.js&amp;nbsp;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;Server running at http://127.0.0.1:8124/try url: http://localhost:8124/?basePath=./&amp;amp;serverJson=server.json&amp;amp;serverJs=jquery.js,,,yourServerSide.js,,,yourServerSide2.js&amp;amp;templateUrl=index.html&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That runs a web server which renders the files for you.&amp;nbsp; It's a bit quicker than calling a process each time you want to do things.&amp;nbsp; There is a possibility of embedding the javascript interpreter inside python (or php/java/etc) too.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Structure of html&lt;/h2&gt;The structure of your html is something like this:&lt;br /&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt; include jquery&lt;/li&gt;&lt;li&gt;include code which will be used on server side and client side. &lt;/li&gt;&lt;li&gt;include server side jquery, and run it if have not processed it server side.&lt;/li&gt;&lt;li&gt;include client side jquery&lt;/li&gt;&lt;/ul&gt;There is a minimal &lt;a href="https://bitbucket.org/illume/ssjquery/src/583c29da135e/js/example/index.html"&gt;index.html example here&lt;/a&gt; if you want to see what it looks like.&lt;br /&gt;&lt;br /&gt;This lets you use the same html in either server side processing mode, or client side processing mode and the results should be the same.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-8499619828224554227?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/8499619828224554227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=8499619828224554227' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8499619828224554227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8499619828224554227'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/10/server-side-jquery-ssjquery.html' title='Server Side jQuery - ssjquery'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-9158718766326053298</id><published>2011-09-27T11:22:00.000+01:00</published><updated>2011-09-27T14:36:07.764+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='raspberrypi'/><title type='text'>pygame on raspberrypi, pyconuk was awesome</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Thanks to &lt;a href="http://www.twitter.com/#%21ntoll"&gt;@ntoll&lt;/a&gt; I had a chance to play around with the &lt;a href="http://www.raspberrypi.org/"&gt;raspberrypi&lt;/a&gt; alpha board at the pyconuk conference (which was a great little community conference with a big heart).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-GZB8RNZE6mo/ToGInZ16bGI/AAAAAAAAAMQ/jp0LN5TQnv8/s1600/renedudfieldpyconuk2011.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-GZB8RNZE6mo/ToGInZ16bGI/AAAAAAAAAMQ/jp0LN5TQnv8/s320/renedudfieldpyconuk2011.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;That is it on the pink bubble wrap.&amp;nbsp; It's hooked up to a monitor via the digital HDMI video port, with a keyboard and mouse connected up via USB.&lt;br /&gt;&lt;br /&gt;We only had a few hours to play around with it, but managed to try a few things out.&amp;nbsp; Whilst we were there playing around with it, a whole bunch of people popped there heads in to have a look and ask questions.&amp;nbsp; Lots of enthusiasm for the project, and also the machine, but also a bit of cautiousness about the project.&lt;br /&gt;&lt;br /&gt;In another room, there was a talk going on about how the BBC was going to help bring a programming education project into the schools of the UK again - like they did with the bbc micro.&amp;nbsp; Tweets started to fly around on the tweet projection screen about it, but then at the end of the talk we found out it was a hoax.&amp;nbsp; Haha.&amp;nbsp; It was more a "wouldn't it be awesome if..." kind of talk.&lt;br /&gt;&lt;br /&gt;So, what did we find out in our exploration of the raspberrypi?&amp;nbsp; Firstly, the rasberrypi had a debian linux distribution running on it, and many packages were available to install.&amp;nbsp; Including an old version of pygame.&amp;nbsp; Sound wasn't working for us, there were none of the various sound systems running.&amp;nbsp; It turns out the analog output port is currently really terrible.&amp;nbsp; With a 1bit DAC, I guess it will sound something like a PC speaker or maybe slightly better.&amp;nbsp; However, digital audio is going to come from the HDMI port along with the video.&amp;nbsp; So that should sound really good, assuming it is hooked up to a TV with HDMI.&amp;nbsp; There's also the option of using a $3 USB sound card - which the project reccommends if you want audio input (eg, a microphone).&lt;br /&gt;&lt;br /&gt;One interesting thing is they have not put a real time clock on there.&amp;nbsp; So when you reboot the system it has the wrong date all the time, which really messes with things like the packaging system, and the file system.&amp;nbsp; However, once connected to the network it can grab the time from there.&amp;nbsp; You may be noticing a theme... they've cut back on components to keep the cost low.&amp;nbsp; I think that it's a great approach in order to get something useful at the price point they are aiming for.&lt;br /&gt;&lt;br /&gt;The alpha board had no WIFI hardware, but we found an ethernet cable and plugged it into my laptop, so we were able to share the laptops WIFI internet connection through it.&amp;nbsp; @ntoll had the pygame package already installed, but it was an old version that didn't include the example programs.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ntoll.org/article/baking-with-raspberrypipy" title="blog by @ntoll, baking with raspberrypi"&gt;&lt;img src="http://ntoll.org/images/99.jpg" /&gt;&lt;span style="font-size: x-small;"&gt; &lt;br /&gt;@ntoll has previously blogged about his raspberrypi&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So we set the debian package manager the task of installing the gcc compiler, and various other things needed to compile pygame from source(SDL, ffmpeg, portmidi, etc).&amp;nbsp; It was downloading packages over the network connection at about 1MB/s which is pretty fast for a 10/100 ethernet port (which seems to be attached via USB), and then out over my laptops wireless connection.&amp;nbsp; It did take a while to install the packages on the SD card though.&amp;nbsp; Perhaps a faster SD card could be used, or maybe the SD card driver could do with some speed improvements.&amp;nbsp; However, it wasn't too slow, definitely usable.&lt;br /&gt;&lt;br /&gt;All the dependencies installed with no issues... winning!&amp;nbsp; Then we started up the compiler, and we got pygame to compile with gcc after a fair wait.&amp;nbsp; This was quite impressive, compiling stuff on the raspberrypi itself, rather than having to use a cross compiler.&lt;br /&gt;&lt;br /&gt;So X was running, but so far there was no hardware acceleration of graphics.&amp;nbsp; I guess in time, someone will be working on the video drivers.&amp;nbsp; This little machine is designed around a GPU, so it is definitely capable of some fast video.&amp;nbsp; So web browsing with iceweasle (rebranded firefox) was a bit slow.&amp;nbsp; It was pretty much unusable whilst pygame was compiling, but usable when the machine wasn't doing much else.&lt;br /&gt;&lt;br /&gt;@ntoll got his xmas card pygame program he wrote for the london dojo last year running on the raspberrypi.&amp;nbsp; It was going a bit slow, but after a few tweaks it ran at an acceptable frame rate (if not exactly smooth).&amp;nbsp; So this is good news, because even though the graphics drivers are not hardware accelerated yet, the little machine can run simple programs at an acceptable speed.&lt;br /&gt;&lt;br /&gt;I also tried running a very CPU and graphics demanding pygame game &lt;a href="http://www.zanthor.org/"&gt;zanthor&lt;/a&gt;.&amp;nbsp; But it wasn't able to run above 1fps.&amp;nbsp; The zanthor game has trouble getting 30FPS on a 5 year old laptop with good graphics drivers, so this wasn't unexpected on an alpha board that doesn't even have its hardware acceleration available yet.&lt;br /&gt;&lt;br /&gt;We also ran the pygame test suite, and most everything passed except for the sound related tests (and things like the camera, and joystick tests, since it doesn't have a camera or joystick attached).&amp;nbsp; Apparently there are pins that could be used to attach a camera, since this is a mobile phone chip.&amp;nbsp; There's a lot of work that could be done to pygame to make it run better on the raspberrypi, but I'm happy that it's mostly working already.&lt;br /&gt;&lt;br /&gt;I also tried running an OpenGL demo, but it ran really slowly.&amp;nbsp; So I'm guessing that hardware accelerated OpenGL was also not working on the distribution that it came with.&amp;nbsp; But they have shown it working in other demos, so it is only time before it is working in X.&amp;nbsp; Also, I think the board supports OpenGL ES 2.0 which there is not currently a python wrapper for (please leave a comment if you know of a project for this).&lt;br /&gt;&lt;br /&gt;There seemed to be about 189MB of ram on this board according to 'top'.&amp;nbsp; I guess it was a 256MB ram model that had 60ish MB of ram taken up by the GPU.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://twitter.com/#%21tjguk"&gt;@tjguk&lt;/a&gt; was there too hacking on his quiz program.&amp;nbsp; It was interesting listening to him talk about his program, and what he was doing with it.&amp;nbsp; But I won't go into it here, since he might want to blog about it himself.&lt;br /&gt;&lt;br /&gt;Also at the conference was Garry Bulmer who was talking about the ARM board that he has made.&amp;nbsp; Previously he has been using the arduino micro controller platform as a robotics teaching platform for kids and adults.&amp;nbsp;&amp;nbsp;&amp;nbsp; I'd like to follow his project, and look forward to seeing it progress.&amp;nbsp; He talked about wanting more processing power to do things like process cd quality audio, which the arduino can not really do.&amp;nbsp; His arm cpu board was aimed at also teaching hardware related things, so his board has more usable GPIO inputs and output pins for controlling electronics.&amp;nbsp; Whereas the raspberrypi board is not currently designed to work well for arduino uses.&amp;nbsp; It is good to see competition in the cheap educational ARM board space, but I think the two projects have slightly different use cases.&lt;br /&gt;&lt;br /&gt;One concern some people had about the raspberrypi project is there seems to be a link between the broadcom employee and the chips they use on the raspberrypi board.&amp;nbsp; This could be seen as a conflict of interest.&amp;nbsp; However, maybe it doesn't matter.&amp;nbsp; Perhaps it is even a good thing!&amp;nbsp; Since then there might be better support from the company because an employee might have better access to docs, and such things.&amp;nbsp; At least there will be someone on the project who has access to the tools needed to fix bugs.&amp;nbsp; There were also concerns about the lack of source code for the chips 18MB binary blob firmware.&amp;nbsp; What does that code do really?&amp;nbsp; I think the project wants to open that source code, but so far it is not available because the company does not want to open it.&amp;nbsp; As a pragmatic option, I still think the raspberrypi is ok.&amp;nbsp; It's not completely open hardware, but it's open enough to be useful for an educational project for creating software.&amp;nbsp; The projects goals are to provide a cheap PC to children, so they can use it themselves to learn - it is not about creating an open hardware platform.&lt;br /&gt;&lt;br /&gt;I'd love to get a development board, but the raspberrypi foundation only made 50 and they are all distributed to developers so I'll have to wait like everyone else until they are up for general sale.&amp;nbsp; I think they are aiming to make them available in a few months.&lt;br /&gt;&lt;br /&gt;There were plenty of other interesting things going on at pyconuk this year too.&amp;nbsp; Including talks about testing(mocks, extending unittest and such things), a realtime web socket game (kwizzle) that uses tornado and mongodb, fluiddb (kinda wikipedia for databases), a visual programming environment (The Larch Environment), a django work shop, and the always good 5 minute lightning talks - where random people get up and talk about something for 5 minutes.&amp;nbsp; Amongst plenty of other things going on.&amp;nbsp; The volunteers put on a great conference again, with very little resources.&amp;nbsp; I wish I could have talked with more people at more length, but there's not really enough time to do so.&amp;nbsp; There's always a creative buzz at these things.&amp;nbsp; So many creative, passionate people talking about their projects in one spot is quite inspirational.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-9158718766326053298?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/9158718766326053298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=9158718766326053298' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/9158718766326053298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/9158718766326053298'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/09/pygame-on-rasberrypi-pyconuk-was.html' title='pygame on raspberrypi, pyconuk was awesome'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-GZB8RNZE6mo/ToGInZ16bGI/AAAAAAAAAMQ/jp0LN5TQnv8/s72-c/renedudfieldpyconuk2011.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-2392734728847557253</id><published>2011-09-21T12:55:00.001+01:00</published><updated>2011-09-21T12:57:25.346+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>jquery.shitsound.js - a shit sound player for web browsers</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="document"&gt;&lt;div class="section" id="shitsound"&gt;Yesterday, I made the first release of shitsound.&lt;/div&gt;&lt;div class="section" id="shitsound"&gt;&lt;/div&gt;&lt;div class="section" id="shitsound"&gt;jquery.shitsound.js is a shit sound player for web browsers.&lt;br /&gt;&lt;blockquote&gt;&lt;ul class="simple"&gt;&lt;li&gt;Listen (demo): &lt;a class="reference external" href="http://rene.f0o.com/%7Erene/shitsound"&gt;http://rene.f0o.com/~rene/shitsound&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Source code: &lt;a class="reference external" href="https://www.bitbucket.org/illume/shitsound"&gt;https://www.bitbucket.org/illume/shitsound&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;Used like this:&lt;br /&gt;&lt;pre class="literal-block"&gt;$.snd.init({}, function () {&lt;br /&gt;        // we are ready to play sounds!  Brilliant.&lt;br /&gt;        $.snd.play('hello');&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;dl class="docutils"&gt;&lt;dt&gt;shitsound only does a few things with sound::&lt;/dt&gt;&lt;dd&gt;play, stop, stopAll&lt;/dd&gt;&lt;dt&gt;jquery.awesound.js might do:&lt;/dt&gt;&lt;dd&gt;changing volume, pitch, playing with a different tempo, playing in stereo, 3d sound, etc.&lt;/dd&gt;&lt;/dl&gt;jquery.shitsound can not do any of this fancy stuff.  It can just play sounds, and stop playing them.&lt;br /&gt;shitsound detects which implementation to use at init time.&lt;br /&gt;&lt;blockquote&gt;&lt;ul class="simple"&gt;&lt;li&gt;html5, using the html5 audio tag.&lt;/li&gt;&lt;li&gt;embed, for using the embed tag.&lt;/li&gt;&lt;li&gt;soundmanager1, for old flash 7.&lt;/li&gt;&lt;li&gt;soundmanager2, for modern flash (8,9,10+).&lt;/li&gt;&lt;li&gt;empty, pretend implementation that does nothing.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;It currently requires jquery, since I use jquery.  However it could quite easily drop the jquery dependency with some work.  Other dependencies are soundmanager 1 and soundmanager 2, as well as (optionally) swfobject.  These are all bundled in ready to use though.&lt;br /&gt;Each implementation is kept separate in the code base, and it is fairly easy to extend with other implementation.  The html5 implementation is separate from the soundmanager1 implementation for example.  I plan on implementing a phonegap implementation in the future.&lt;br /&gt;If you'd like to see another JavaScript audio engine supported, please let me know.&lt;br /&gt;&lt;br /&gt;Yes, it does support netscape navigator 3+.  As well as old versions of internet explorer that don't have flash installed, or have old versions of flash installed.&lt;/div&gt;&lt;div class="section" id="preparing-your-audio"&gt;&lt;h2&gt;preparing your audio&lt;/h2&gt;Because sound support on the web is shit, you need to prepare your audio in various different formats for it to work cross platform.&lt;br /&gt;You need a .wav file, a .mp3 file, and an .ogg file to support all platforms.&lt;br /&gt;It might not be a good idea to include big .wav files for large amounts of audio like songs though.  Because they can be 10 times larger than a lossily compressed mp3 or ogg file.  But if you want full browser support, then .wav files are required.&lt;br /&gt;The ffmpeg is quite a common powerhouse of a multimedia tool.  It is available on OSX through brew, or macports. It can even convert audio for you.&lt;br /&gt;&lt;blockquote&gt;&lt;ul class="simple"&gt;&lt;li&gt;ffmpeg -i file.wav file.mp3&lt;/li&gt;&lt;li&gt;ffmpeg -i file.wav file.ogg&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div class="section" id="preparing-your-webserver"&gt;&lt;h2&gt;preparing your webserver&lt;/h2&gt;&lt;dl class="docutils"&gt;&lt;dt&gt;If you use nginx you might need to modify your /etc/nginx/mime.types file for oggs::&lt;/dt&gt;&lt;dd&gt;audio/ogg ogg;&lt;/dd&gt;&lt;/dl&gt;Other web servers may also need mime types being added.&lt;/div&gt;&lt;div class="section" id="future"&gt;&lt;h2&gt;future&lt;/h2&gt;Maybe these things will be done in the future.&lt;br /&gt;&lt;blockquote&gt;&lt;ul class="simple"&gt;&lt;li&gt;volume control.  This is possible with all backends.&lt;/li&gt;&lt;li&gt;Better browser detection, and blacklisting of bad html5 audio engines.&lt;/li&gt;&lt;li&gt;wider testing and debugging.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-2392734728847557253?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/2392734728847557253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2392734728847557253' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2392734728847557253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2392734728847557253'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/09/jqueryshitsoundjs-shit-sound-player-for.html' title='jquery.shitsound.js - a shit sound player for web browsers'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1053541414916770428</id><published>2011-09-14T18:51:00.000+01:00</published><updated>2011-09-14T18:53:02.026+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pyconuk'/><title type='text'>pygame sprint at pyconuk, and virtually.  Friday 23rd to Sunday 25th of September</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top"&gt;There is going to be a pygame sprint at this years &lt;a href="http://pyconuk.org/"&gt;pyconuk&lt;/a&gt;.We're going to tackle whatever the participants who turn up want to hack on.  That might be porting to a new platform like the $25 &lt;a href="http://www.raspberrypi.org/"&gt;rasberrypi&lt;/a&gt; computer(there's going to be a couple at pyconuk), or improving the pygame android support.  Or it might be polishing off one of the new modules like the new freetype font module, or perhaps implementing a brand new module.&amp;nbsp; Or maybe it's jazzing up the documentation, or working on a new import pygame.examples.I'm getting there on Friday, so I hope to do some hacking then, and we might be able to get some sprint space for the Friday(conference propper starts Saturday, but some people are getting there early) - otherwise it will have to be in a cafe or something.&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;a href="http://pyconuk.org/"&gt;&lt;img border="0" height="280" src="http://pyconuk.org/media/img/pycon_fail.png" width="159" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Also going on during the conference is the python core sprint and CKAN sprint.&amp;nbsp; It should be fun to join in on those sprints too.&amp;nbsp; Of course there will be talks, work shops, an unconference room, lightning talks (5 minute talks) and coffee fueled hallway conversations.&amp;nbsp; There's even going to be a Code Dojo - london style, and of course - most importantly: lunch/dinner.&lt;br /&gt;&lt;br /&gt;pygame recently migrated to mercurial and bitbucket: &lt;a href="https://bitbucket.org/pygame/pygame"&gt;https://bitbucket.org/pygame/pygame&lt;/a&gt;&amp;nbsp; We'll be able to commit changes to there or work off branches and submit pull requests later.&amp;nbsp; There is a &lt;a href="http://www.pygame.org/wiki/Hacking"&gt;pygame hacking guide&lt;/a&gt; which we will make notes on any questions people have with working on the pygame code base.&lt;br /&gt;&lt;br /&gt;It will also run as a virtual sprint in the &lt;a href="http://www.pygame.org/wiki/info"&gt;irc chat room&lt;/a&gt; (freenode #pygame), so if anyone wants to join in remotely they can.&amp;nbsp; If you only write python code, there are plenty of parts of pygame that can be worked on.&amp;nbsp; For anyone who turns up I can show them the basics of CPython modules if they already know C.&lt;br /&gt;&lt;br /&gt;We'll try and tweet sprint goings on via the &lt;a href="http://twitter.com/#%21/pygame_org"&gt;@pygame_org twitter account&lt;/a&gt;.&amp;nbsp; Hope to see you there.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1053541414916770428?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1053541414916770428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1053541414916770428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1053541414916770428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1053541414916770428'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/09/pygame-sprint-at-pyconuk-and-virtually.html' title='pygame sprint at pyconuk, and virtually.  Friday 23rd to Sunday 25th of September'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-18629477717679539</id><published>2011-08-24T01:51:00.012+01:00</published><updated>2011-08-25T10:15:00.359+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='shitjs'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Let's make a shit JavaScript interpreter!  Part Three.</title><content type='html'>&lt;a href="http://www.poweredbybees.com/"&gt;&lt;img src="http://1.bp.blogspot.com/_eJJgehXCsQ4/TCx_WVZ1VSI/AAAAAAAAAH0/osU9dhr4xTs/s1600/lets-make-a-shit-javascript-interpreter.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let's put the Research into R&amp;amp;D.  I guess it should be called Shit Research to go along with the name of this &lt;a href="http://renesd.blogspot.com/2010/06/lets-make-shit-javascript-interpreter.html"&gt;series (p1)&lt;/a&gt; of &lt;a href="http://renesd.blogspot.com/2010/07/lets-make-shit-javascript-interpreter.html"&gt;articles (p2)&lt;/a&gt; I started one year ago.  It takes a lot of time to read over hundreds of thousands of lines of undocumented C++ and java code, so part three took much longer than expected.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Let's explore existing JavaScript implementations.&lt;/h2&gt;  In this part we are going to take a small digression to look over other JavaScript implementations.  I'll provide a short description of how each JavaScript implementation is made. We can use the Architectural knowledge from each implementation to inspire our own implementation.&lt;br /&gt;&lt;br /&gt;Another benefit of researching each implementation is that we can find all the different tools they use.  For example different test suites.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Make sure to read the URL's for each implementation to find out more information about each one.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/List_of_ECMAScript_engines"&gt;There is a list of ECMAScript implementations at wikipedia&lt;/a&gt;.  We will not cover all of the ones listed there.  If like me, you may spend a few hours or even days reading through the links from there.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;narcissus - js in js.&lt;/h2&gt;  Narcissus is a javascript implementation written in javascript (with some SpiderMonkey language extensions).  It is written by the same author as the original JavaScript implementation back in 2005-2007 (&lt;a href="http://brendaneich.com/"&gt;Brendan Eich&lt;/a&gt;).  In mid 2010 the Narcissus code has been taken up again by the Mozilla project to make researching JavaScript changes easier.&lt;br /&gt;&lt;br /&gt;It is a good implementation to study, since it is fairly small, and is meant to be easy enough to read.&lt;br /&gt;&lt;br /&gt;It uses a hand written parser, not a generated one.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mxr.mozilla.org/mozilla/source/js/narcissus/"&gt;The original narcissus source repository&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The new &lt;a href="https://github.com/mozilla/narcissus/"&gt;repository of narcissus&lt;/a&gt;, and &lt;a href="http://mozillalabs.com/zaphod/2010/09/18/28/"&gt;two&lt;/a&gt; &lt;a href="http://blog.mozilla.com/dherman/2010/09/22/zaphod-a-browser-language-lab-for-js/%20"&gt;articles&lt;/a&gt; about it.&lt;br /&gt;&lt;br /&gt;There is a port to python of the narcissus parser called &lt;a href="http://code.google.com/p/pynarcissus/"&gt;pynarcissus&lt;/a&gt;.  The authors of pynarcissus found it difficult to port the rest of the interpreter since it relies on JavaScript features itself.&lt;br /&gt;&lt;br /&gt;It weighs in at about 7000 lines of code counted with wc -l.  I had to count lines in this way since my SLOC counter does not seem to count javascript.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Spider monkey.&lt;/h2&gt;  &lt;a href="http://www.mozilla.org/js/spidermonkey/"&gt;Spider Monkey&lt;/a&gt; is the original JavaScript implementation used by Netscape, and the Mozilla project.&lt;br /&gt;&lt;br /&gt;SpiderMonkey is a production grade, high quality JavaScript implementation.&lt;br /&gt;&lt;br /&gt;It also has excellent documentation.  Especially the &lt;a href="http://mxr.mozilla.org/mozilla/source/js/src/README.html"&gt;js/src/README.html&lt;/a&gt; file which includes a design walk through.&lt;br /&gt;&lt;br /&gt;"""&lt;em&gt;The compiler consists of a recursive-descent parser and a random-logic rather than table-driven lexical scanner. Semantic and lexical feedback are used to disambiguate hard cases such as missing semicolons, assignable expressions ("lvalues" in C parlance), etc. The parser generates bytecode as it parses, using fixup lists for downward branches and code buffering and rewriting for exceptional cases such as for loops. It attempts no error recovery. The interpreter executes the bytecode of top-level scripts, and calls itself indirectly to interpret function bodies (which are also scripts). All state associated with an interpreter instance is passed through formal parameters to the interpreter entry point; most implicit state is collected in a type named JSContext. Therefore, all API and almost all other functions in JSRef take a JSContext pointer as their first argument.&lt;br /&gt;&lt;br /&gt;The decompiler translates postfix bytecode into infix source by consulting a separate byte-sized code, called source notes, to disambiguate bytecodes that result from more than one grammatical production.&lt;/em&gt;"""&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Google V8.&lt;/h2&gt; Written in C++, javascript and assembler.  Uses hidden classes, and generates machine code at run time.&lt;br /&gt;&lt;br /&gt;The parser is hand written parser in C++.  It's not generated.&lt;br /&gt;&lt;br /&gt;'Preparses', which creates tokens.  Then creates an AST by parsing.  Finally compiling the AST.  parser.css is where all the parsing happens.&lt;br /&gt;&lt;br /&gt;The projects documentation is quite limited - so reading the source is the best way to get in there.  There are some videos which describe the architecture, and engineering decisions behind the choices taken.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/v8/"&gt;http://code.google.com/p/v8/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;V8 weighs in at a mighty 605,962 SLOC.  Making it the largest, biggest, badest V8 JavaScript engine around.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;JSLint.&lt;/h2&gt; JSLint is written in JavaScript and uses a TDOP approach to the parser like we are using.  I won't discuss this, since it is documented well elsewhere.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Rhino&lt;/h2&gt; Rhino can run as either an interpreter or a java byte code generator.  It's hosted by the mozilla project (who make firefox).  It complements their C++ implementation (spidermonkey) and their JavaScript implementation (narcissus).&lt;br /&gt;&lt;br /&gt;There are a few things which show it is a very mature as well as modern implementation.  The project was started in 1999, and has been developed ever since.  It has partial support for JavaScript 1.8, and ECMAScript 5 standards. Weighing in at 50,551 source lines of Java code (SLOC), it can be considered a very large code base.  Another modern feature is that it supports the CommonJS javascript module standard.  Despite still being hosted in cvs, it's still being maintained, and features are being added regularly.&lt;br /&gt;&lt;br /&gt;The Rhino JavaScript team maintains a library of tests and other documentation for JavaScript.  Tests are being shared with the other JavaScript implementations within the mozilla spidermonkey project.  There have also been parts which have been ported from spidermonkey - such as the hand written parser.&lt;br /&gt;&lt;br /&gt;A handwritten scanner they call TokenStream creates tokens, and then parses those into an AST.  Despite being mostly hand written, some parts are generated.  Specifically the stringToKeyword method, which detects keywords is generated somehow.&lt;br /&gt;&lt;br /&gt;The documentation of the architecture of the project is limited.  There is however some API documentation.  With a couple of modifications to some ant build files I was able to build it, as well as even make a few small modifications.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://en.wikipedia.org/wiki/Rhino_%28JavaScript_engine%29"&gt;wikipedia Rhino&lt;/a&gt; page has some great information on the rhino javascript engine.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;KJS&lt;/h2&gt; &lt;a href="http://en.wikipedia.org/wiki/KJS_%28KDE%29"&gt;KJS&lt;/a&gt; is the KDE JavaScript implementation for the konqueror browser.  It was the parent of the JavaScript implementations done by Apple Computer, inc.  I won't go into any detail on this one, since I'll cover JavaScriptCore instead.  KJS is written in C++, for the QT library.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;JavaScriptCore, Squirrelfish, Nitro&lt;/h2&gt; You can browse the source here: &lt;a href="http://trac.webkit.org/browser/trunk/Source/JavaScriptCore"&gt;http://trac.webkit.org/browser/trunk/Source/JavaScriptCore&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This uses a hand written lexer(tokeniser), and a hand written parser.  The code structure of the parser and lexer looked eerily familiar.  The code base is mostly written in C++ and is quite massive.  140,837 SLOC&lt;br /&gt;&lt;br /&gt;There is lots of platform specific code, but it also has a jit, uses byte code, and an interpreter.  There is also lots of development code in there for things like debuggers, and profilers.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Closed source JavaScript implementations&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;There are a few JavaScript implementations that are closed source.  The two main ones in widespread use are the ones from Microsoft, and the ones from Opera.&lt;br /&gt;&lt;br /&gt;They have however published papers and blog posts about their implementations.  I won't cover them any more, because not as much can be learned without the source code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;pypy javascript&lt;/h2&gt; The pypy project started a javascript interpreter now too.&lt;br /&gt;&lt;a href="https://bitbucket.org/pypy/lang-js/src/de89ec32a7dc/js/javascript-interpreter.txt"&gt;https://bitbucket.org/pypy/lang-js/src/de89ec32a7dc/js/javascript-interpreter.txt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The description of the project mentions it's currently using the spider monkey parser, but it appears to generate one using a parser generator provided by pypy.  Using a EBNF grammar file.  It also creates an AST.&lt;br /&gt;&lt;br /&gt;It works for some simple javascript programs that don't use the javascript standard library.  I'm not sure of the future of the project, since it appears it was a GSOC project which has now finished, so there might not be any full time developers left on it.&lt;br /&gt;&lt;br /&gt;It's written in RPython (a restricted subset of python) and python.  Running on top of pypy, it should theoretically be able to take advantage of that platforms jit and garbage collector.&lt;br /&gt;&lt;br /&gt;This project makes use of some JavaScript tests and benchmarks from other projects.  Specifically some benchmarks from v8, and the language shootout website.  It also includes the "ECMA 262 Edition 1" tests.&lt;br /&gt;&lt;br /&gt;It weighs in at 5452 Source Lines of Code (SLOC).  Which is much smaller, but the implementation is also not complete, so that is to be expected.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;So what have we learned then?&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;We see that most of the implementations use a hand written parser.  We also see that the implementations in js and python are much smaller.  So despite them being incomplete, I think it proves that it should be feasible to make our shit interpreter in python.  We don't need half a million lines of C++ to do our project.&lt;br /&gt;&lt;br /&gt;We have also learned that there are test suites available, which should help us out a lot.  In fact, many of the implementations share the test suites.  Having a test suite already available makes it way easier to write an implementation of something yourself.  It acts as a guide to development, and also reduces the time for testing since a lot of it can be automated.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Exercise for next time&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Choose One(1) of the implementations, build it, run it, and modify it slightly to do something different.  Try and run the tests that come with it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Further reading.&lt;/h2&gt;  This whole article is "further reading", but we can never have too much to read.  Can we!?&lt;br /&gt;&lt;br /&gt;This time, instead of reading it on the train or in the bath tub - may I suggest reading these on a couch?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.tuenti.com/dev/functions-and-execution-contexts-in-javascript-2/"&gt;Functions and execution contexts in JavaScript&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://nedbatchelder.com/blog/201104/a_javascript_lexer_in_python_and_the_saga_behind_it.html"&gt;jslex, a javascript lexer written in python&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ruslanspivak.com/2011/05/02/slimit-a-javascript-minifier-to-be-is-released/"&gt;http://ruslanspivak.com/2011/05/02/slimit-a-javascript-minifier-to-be-is-released/&lt;/a&gt; (&lt;a href="http://pypi.python.org/pypi/slimit"&gt;pypi slimit&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/mishoo/UglifyJS"&gt;UglifyJS&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/closure/compiler/"&gt;Closure Compiler&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-18629477717679539?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/18629477717679539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=18629477717679539' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/18629477717679539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/18629477717679539'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/08/lets-make-shit-javascript-interpreter.html' title='Let&apos;s make a shit JavaScript interpreter!  Part Three.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_eJJgehXCsQ4/TCx_WVZ1VSI/AAAAAAAAAH0/osU9dhr4xTs/s72-c/lets-make-a-shit-javascript-interpreter.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-8918026815185952501</id><published>2011-08-21T14:56:00.004+01:00</published><updated>2011-08-22T11:17:08.720+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugzilla'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='bitbucket'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>bugzilla bugs to bitbucket issues</title><content type='html'>As part of the pygame move to bitbucket, we are converting a bug database stored in bugzilla.&lt;br /&gt;&lt;br /&gt;Work is progressing on the issues migration:&lt;br /&gt;    &lt;a href="https://bitbucket.org/illume/bugzilla_bitbucket"&gt;https://bitbucket.org/illume/bugzilla_bitbucket&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bugzilla is more comprehensive compared to bitbucket. So not all things can be migrated from the bugzilla bugs to the bitbucket issues.&lt;br /&gt;&lt;br /&gt;Also, the bitbucket API is limited in what it can do.  You can't add user comments or add attachments.&lt;br /&gt;&lt;br /&gt;To get around the attachments part, I made the migration script create a directory of attachments, and then link to them in the bug text.  Then I've extracted the attachments from bugzilla and put them online.&lt;br /&gt;&lt;br /&gt;To hack around the lack of comment adding in the bitbucket API, I'm just combining all of the comments into the content text.&lt;br /&gt;&lt;br /&gt;Other features bitbucket issues API does not have are priorities, and platforms.  The issues features _does_ support priorities, but it doesn't look like the API is set up yet.  You can't add platforms (like 'Windows XP SP2') at all it seems.  You also can not add free form tags of any sort.  Another couple of basic things you can not set with bitbucket issues are the date, and the bug id.&lt;br /&gt;&lt;br /&gt;So there you have it.  This code worked ok for us.&lt;br /&gt;&lt;br /&gt;This code might be a useful start for anyone else wanting to start on a migration.  Feel free to go fork it yourself: &lt;a href="https://bitbucket.org/illume/bugzilla_bitbucket"&gt;https://bitbucket.org/illume/bugzilla_bitbucket&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-8918026815185952501?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/8918026815185952501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=8918026815185952501' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8918026815185952501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8918026815185952501'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/08/bugzilla-bugs-to-bitbucket-issues.html' title='bugzilla bugs to bitbucket issues'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-518271702993261652</id><published>2011-07-17T10:27:00.004+01:00</published><updated>2011-07-17T11:24:38.842+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bzr'/><category scheme='http://www.blogger.com/atom/ns#' term='launchpad'/><category scheme='http://www.blogger.com/atom/ns#' term='bitbucket'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='hg'/><title type='text'>bye bye launchpad</title><content type='html'>I'm starting to move most of my projects off launchpad onto bitbucket.&lt;br /&gt;&lt;br /&gt;launchpad just hasn't gone in the direction that is useful for me, or my projects.&lt;br /&gt;&lt;br /&gt;It still has some nice features, such as packaging farms (PPAs) and of course bzr integration.  However, github and bitbucket have just been moving more towards making it easy for developers compared to launchpad which is more geared towards for distributors who work with an upstream.  Last year &lt;a href="http://renesd.blogspot.com/2010/03/why-bzr-and-launchpad-launchpad-is-open.html"&gt;I hoped launchpad would improve&lt;/a&gt; after it went open source, and it has improved.  Just not really in the direction useful for my projects.&lt;br /&gt;&lt;br /&gt;Many people these days are able to use hg, or git... but still very many people have never even heard of bzr.  I feel bzr+launchpad was holding one project back a little from gaining collaborators because of this.  By that logic, I should be using svn for it... but I don't want to do that :)&lt;br /&gt;&lt;br /&gt;The documentation to &lt;a href="http://mercurial.selenic.com/wiki/ConvertExtension#Converting_from_Bazaar"&gt;convert repositories to mecurial&lt;/a&gt; is on the hg wiki.  The conversion seems to mostly have worked ok for me on my &lt;a href="https://bitbucket.org/illume/newsletter"&gt;python newsletter&lt;/a&gt; project.  Except it did not put the correct email address attached to each of the commits.  Oh well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-518271702993261652?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/518271702993261652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=518271702993261652' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/518271702993261652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/518271702993261652'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/07/bye-bye-launchpad.html' title='bye bye launchpad'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-8693202980875787317</id><published>2011-07-04T20:50:00.006+01:00</published><updated>2011-07-04T21:03:55.458+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='webgl'/><category scheme='http://www.blogger.com/atom/ns#' term='glsl'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>shadertoy.py opengl shading language toy shader</title><content type='html'>A couple of months ago I made a python port of the &lt;a href="http://www.iquilezles.org/apps/shadertoy/"&gt;WebGL shadertoy&lt;/a&gt;.  The shadertoy website is written in JavaScript and the opengl shading language.&lt;br /&gt;&lt;br /&gt;Here is the python port: &lt;a href="http://rene.f0o.com/~rene/stuff/shadertoy.py"&gt;http://rene.f0o.com/~rene/stuff/shadertoy.py&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Maybe it'll be useful for someone learning shading languages through python.  Or not.&lt;br /&gt;&lt;br /&gt;It's a fun demo anyway.  Press the 'Anykey' to change between shader.  You'll find the 'Anykey' on your keyboard.  If the Anykey you press is Escape, then the program will 'quit'.&lt;br /&gt;&lt;br /&gt;Requires 1 tsp of pygame, and a cup of pyopengl.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-8693202980875787317?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/8693202980875787317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=8693202980875787317' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8693202980875787317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8693202980875787317'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/07/shadertoypy-opengl-shading-language-toy.html' title='shadertoy.py opengl shading language toy shader'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-2396177262585039032</id><published>2011-07-02T10:50:00.008+01:00</published><updated>2011-07-02T11:26:23.913+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cherrypy'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='daemontools'/><title type='text'>cherrypy daemontools</title><content type='html'>Cherrypy and daemontools work nicely together.  However, I have not found any instructions on how to use them together on the interwebs... so I've written up some basic notes for people who love cherrypy and daemontools.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://cr.yp.to/daemontools/"&gt;daemontools&lt;/a&gt; is a collection of tools for managing UNIX services.  It can be used to automatically start, and restart processes on a unix system.&lt;br /&gt;&lt;br /&gt;The instructions to run services in daemontools are here: &lt;a href="http://cr.yp.to/daemontools/faq/create.html#run"&gt;http://cr.yp.to/daemontools/faq/create.html#run&lt;/a&gt;.  I'm assuming you have daemontools set up already.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cherrypy.org/"&gt;Cherrypy&lt;/a&gt; is a python library for making website applications.  There are many ways to deploy cherrypy apps, but I will describe how to deploy cherrypy apps with daemontools.&lt;br /&gt;&lt;br /&gt;Firstly, you do not need the &lt;a href="http://docs.cherrypy.org/dev/deployguide/cherryd.html"&gt;cherryd&lt;/a&gt; tool to use with daemontools.  Daemontools does the daemonising for you.  But cherryd can be used if you want, since it provides some nice options (just don't use the -d daemonize flag).  You may want to use cherryd with daemontools if you'd like to use FastCGI or SCGI.  I won't cover cherryd any further in this post.&lt;br /&gt;&lt;br /&gt;I'll now show you how to setup daemontools for an example cherrypy application.&lt;br /&gt;&lt;br /&gt;Here is a normal helloworld cherrypy app... which I'll put in the file exampleapp.py&lt;br /&gt;&lt;pre&gt;import cherrypy&lt;br /&gt;&lt;br /&gt;class HelloWorld(object):&lt;br /&gt;    def index(self):&lt;br /&gt;        return "Hello World!"&lt;br /&gt;    index.exposed = True&lt;br /&gt;&lt;br /&gt;cherrypy.quickstart(HelloWorld())&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This runs on 127.0.0.1 on port 8080 by default.  It also runs in development mode (which you should not deploy with, but only use for testing).&lt;br /&gt;&lt;br /&gt;Now create a 'theservicedir' directory somewhere.&lt;br /&gt;Also create the following directories: 'theservicedir/log' and 'theservicedir/log/main'&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then create a 'theservicedir/run' file.&lt;br /&gt;&lt;pre&gt;#!/bin/sh&lt;br /&gt;exec setuidgid rene /usr/bin/python /home/rene/cherrypydaemontools/exampleapp.py&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that I specified full paths to python and to your python script.  Also see that I got the app to run with the setuidgid program as the user 'rene'.&lt;br /&gt;&lt;br /&gt;Then create a 'theservicedir/run' file for logging.&lt;br /&gt;&lt;pre&gt;#!/bin/sh&lt;br /&gt;exec setuidgid rene multilog t ./main&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now to start it up we symlink the file into the service directory.&lt;br /&gt;&lt;pre&gt;sudo ln -s /home/rene/cherrypydaemontools/theservicedir /service/theservicedir&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To stop it:&lt;br /&gt;&lt;pre&gt;svc -d /service/theservicedir&lt;/pre&gt;&lt;br /&gt;To restart it:&lt;br /&gt;&lt;pre&gt;svc -t /service/theservicedir&lt;/pre&gt;&lt;br /&gt;To start it:&lt;br /&gt;&lt;pre&gt;svc -u /service/theservicedir&lt;/pre&gt;&lt;br /&gt;Your app should start up the next time your server reboots.  Happy cherrypy and daemontools usage.  Please leave any related tips or fixes to these instructions in the &lt;a href="http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2396177262585039032"&gt;comments&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-2396177262585039032?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/2396177262585039032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2396177262585039032' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2396177262585039032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2396177262585039032'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/07/cherrypy-daemontools.html' title='cherrypy daemontools'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-9028579886215284975</id><published>2011-06-18T12:11:00.005+01:00</published><updated>2011-06-18T12:19:07.328+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='mobile'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>hello jquery.mobile</title><content type='html'>Was playing around with jquery mobile the other day, which has planned it's first beta release sometime next week.&lt;br /&gt;&lt;br /&gt;jQuery mobile is what jquery+jquery-ui are to desktop browsers.  It abstracts a lot of the parts away so that you can write your code without having to figure out all the different mobile browser quirks yourself.  It offers a structure to make web apps which are cross platform across current mobile devices and which as a bonus work in desktop web browsers as well.&lt;br /&gt;&lt;br /&gt;Mobile style events are provided as well. Like touch and swipe which work across the various mobile browsers is a nice touch.&lt;br /&gt;&lt;br /&gt;Another great thing it provides is media queries.  CSS media queries are buggy on some browsers so this abstracts out a lot of the bugs on the various different devices.&lt;br /&gt;&lt;br /&gt;Supported are most of the mobile devices.  Some are supported better than others, and some provide certain features that others do not provide.  For example, the ajax style page loading is not done on opera mini.  But works on android, and safari mobile browsers.&lt;br /&gt;&lt;br /&gt;I'm quite looking forward to the feature complete beta release.  It's been a long time baking, and smells quite nice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-9028579886215284975?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/9028579886215284975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=9028579886215284975' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/9028579886215284975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/9028579886215284975'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/06/hello-jquerymobile.html' title='hello jquery.mobile'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7217073116525117316</id><published>2011-05-17T09:48:00.002+01:00</published><updated>2011-05-17T10:00:33.474+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='js'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jslint'/><title type='text'>Running jslint on saving JavaScript with vim</title><content type='html'>&lt;pre&gt;autocmd BufWritePost,FileWritePost *.js !jslint &amp;lt;afile&amp;gt;&lt;/pre&gt;This will run &lt;a href="http://www.jslint.com/"&gt;jslint&lt;/a&gt; on your JavaScript files after you save them.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://vimdoc.sourceforge.net/htmldoc/autocmd.html"&gt;http://vimdoc.sourceforge.net/htmldoc/autocmd.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://vimdoc.sourceforge.net/htmldoc/autocmd.html#FileWritePost"&gt;http://vimdoc.sourceforge.net/htmldoc/autocmd.html#FileWritePost&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can add the command to your ~/.vimrc&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7217073116525117316?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7217073116525117316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7217073116525117316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7217073116525117316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7217073116525117316'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/05/running-jslint-on-saving-javascript.html' title='Running jslint on saving JavaScript with vim'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4589710246203183813</id><published>2011-04-29T15:59:00.012+01:00</published><updated>2011-07-17T07:35:18.984+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hotmail'/><category scheme='http://www.blogger.com/atom/ns#' term='sony'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='xbox'/><title type='text'>Hotmail, xbox and microsoft live have been hacked.</title><content type='html'>&lt;b&gt;update:&lt;/b&gt; hotmail have added a &lt;a href="http://windowsteamblog.com/windows_live/b/windowslive/archive/2011/07/14/hey-my-friend-s-account-was-hacked.aspx"&gt;my friend has been hacked&lt;/a&gt; button, so people can report when one of their friends accounts have been hacked.  Also I got my account back after 5 days or so. I don't think any of my contacts lost any money from the scam.  Other people who got their accounts hijacked have not been so lucky.&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;br /&gt;Many people have been having their hotmail accounts been broken into and stolen.&lt;br /&gt;&lt;br /&gt;Microsoft writes about it on their &lt;a href="http://windowslivehelp.com/solution.aspx?solutionid=1fe6ed3e-eef6-4c57-933f-f3c408f1c5c1"&gt;security blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I've meet a few people over the last week who know of people who have had their accounts stolen.&lt;br /&gt;&lt;br /&gt;The fraudsters are sending everyone in their contact list and telling people they have been robbed - and to send money.  They say they are in a hotel and the hotel will not let them leave.&lt;br /&gt;&lt;br /&gt;A friend told me about how some people call up, and someone answers pretending to be the hotel manager mentioned in the scam email.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I haven't read any media coverage of this, but have heard first hand of people who it has happened to.  Could this be related to the &lt;b&gt;Sony break-in&lt;/b&gt; the other week?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately Microsoft do not seem to answer when contacted about accounts being used for fraud.  Their account reset procedure is so slow that by the time an account is recovered the damage could very well be done.&lt;br /&gt;&lt;br /&gt;Microsoft are also recommending people create new hotmail accounts rather than go through the verification process to recover a stolen account.  Unfortunately this is a rather dangerous attitude to take, since many people have been sent emails and all of the people in the contact list could be victims of crimes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The xbox live network uses the same authentication as hotmail and other Microsoft online properties and stores.  Microsoft uses a single sign on system - so this is a very big security break down.&lt;br /&gt;&lt;br /&gt;I have no idea how large the break-in is.  However, if I hear about multiple people in real life having their accounts stolen then I think this is MASSIVE.&lt;br /&gt;&lt;br /&gt;Sony took their system offline whilst they investigated the hackers.  I'm not sure what if anything Microsoft has done.&lt;br /&gt;&lt;br /&gt;Please spread the word, and warn others about this break-in.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Example scam email&lt;/h2&gt;Here is an example of one of the emails they are sending out:&lt;br /&gt;&lt;pre&gt;Subject: My Plight!!! Help&lt;br /&gt;&lt;br /&gt;I'm sorry for this odd request because it might get to you too urgent but it's &lt;br /&gt;because of the situation of things right now, I am stuck in United Kingdom . &lt;br /&gt;we were robbed at the park of the hotel where we stayed,all cash,credit card and &lt;br /&gt;cell were stolen off us but luckily for us we still have our passports with us.&lt;br /&gt;&lt;br /&gt;We've been to the embassy and the Police here but they're not helping issues at all&lt;br /&gt; and our flight leaves today but we're having problems settling the hotel bills and &lt;br /&gt;the hotel manager won't let us leave until we settle the bills.&lt;br /&gt;&lt;br /&gt;I need a quick loan?? promise to refund it back once i get home.&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4589710246203183813?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4589710246203183813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4589710246203183813' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4589710246203183813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4589710246203183813'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/04/hotmail-xbox-and-microsoft-live-have.html' title='Hotmail, xbox and microsoft live have been hacked.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4470885299169683935</id><published>2011-04-10T11:26:00.011+01:00</published><updated>2011-04-10T14:41:07.176+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='shitjs'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Let's make a shit JavaScript interpreter!  Part Two.</title><content type='html'>&lt;a href="http://www.poweredbybees.com/"&gt;&lt;img src="http://1.bp.blogspot.com/_eJJgehXCsQ4/TCx_WVZ1VSI/AAAAAAAAAH0/osU9dhr4xTs/s1600/lets-make-a-shit-javascript-interpreter.png" border="0" height="253.5" width="384" /&gt;&lt;/a&gt;  &lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Let's make a shit javascript interpreter!  Part two.&lt;/h1&gt;    As a learning exercise, I've begun writing a &lt;strike&gt;&lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt;&lt;/strike&gt; &lt;a href="http://en.wikipedia.org/wiki/ECMAScript"&gt;ECMAScript&lt;/a&gt; interpreter in &lt;a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29"&gt;python&lt;/a&gt;.  It doesn't even really exist yet, and when it does it will run really slowly, and not support all js features.  &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Homework from part One - A simple tokeniser.&lt;/h3&gt;We ended "&lt;a href="http://renesd.blogspot.com/2010/06/lets-make-shit-javascript-interpreter.html"&gt;Let's make a shit JavaScript interpreter! Part One.&lt;/a&gt;" by setting some homework to create a tokeniser for simple expressions like "1 + 2 * 4".  Two readers sent in their versions of the tokenisers (ps, put a link to your home work results from Part One in the comments, and I'll link to it here). &lt;ul&gt;&lt;li&gt;&lt;a href="http://pastebin.com/P0sXjr65"&gt;http://pastebin.com/P0sXjr65&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://gist.github.com/460197"&gt;http://gist.github.com/460197&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Our simple tokeniser&lt;/h3&gt;&lt;pre&gt;operators = ['/', '+', '*', '-']&lt;br /&gt;class ParseError(Exception):&lt;br /&gt;    pass&lt;br /&gt;def is_operator(s):&lt;br /&gt;    return s in operators&lt;br /&gt;def is_number(s):&lt;br /&gt;    return s.isdigit()&lt;br /&gt;&lt;br /&gt;def tokenise(expression):&lt;br /&gt;    pos = 0&lt;br /&gt;    for s in expression.split():&lt;br /&gt;        t = {}&lt;br /&gt;        if is_operator(s):&lt;br /&gt;            t['type'] = 'operator'&lt;br /&gt;            t['value'] = s&lt;br /&gt;        elif is_number(s):&lt;br /&gt;            t['type'] = 'number'&lt;br /&gt;            t['value'] = float(s)&lt;br /&gt;        else:&lt;br /&gt;            raise ParseError(s, pos)&lt;br /&gt; &lt;br /&gt;        t.update({'from': pos, 'to': pos + len(s)})&lt;br /&gt;        pos += len(s) + 1&lt;br /&gt;        yield t&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; pprint(list(tokenise("1 + 2 * 4")))&lt;br /&gt;[{'from': 0, 'to': 1, 'type': 'number', 'value': 1.0},&lt;br /&gt; {'from': 2, 'to': 3, 'type': 'operator', 'value': '+'},&lt;br /&gt; {'from': 4, 'to': 5, 'type': 'number', 'value': 2.0},&lt;br /&gt; {'from': 6, 'to': 7, 'type': 'operator', 'value': '*'},&lt;br /&gt; {'from': 8, 'to': 9, 'type': 'number', 'value': 4.0}]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3&gt;Code for shitjs.&lt;/h3&gt;You can follow along with the code for shit js at: &lt;ul&gt;&lt;li&gt;&lt;a href="http://pypi.python.org/pypi/shitjs"&gt;http://pypi.python.org/pypi/shitjs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;pip install shitjs&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://bitbucket.org/illume/shitjs"&gt;https://bitbucket.org/illume/shitjs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;hg clone https://illume@bitbucket.org/illume/shitjs&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;  After you have installed it, shitjs.part1 is the package for the part1 homework.  &lt;h3&gt;What next?  Parsing with the tokens of our simple expression.&lt;/h3&gt;Since we have some tokens from the input, we can now move onto the parser.  Remember that we are not making a parser for all of javascript to start with, we are starting on a simple expressions like "1 + 2 * 4".  As mentioned in Part One, we are using an algorithm called "Top Down Operator precedence".  Where actions are associated with tokens, and &lt;a href="http://en.wikipedia.org/wiki/Order_of_operations"&gt;an order of operations&lt;/a&gt;.  Here you can see the precedence rule (order of operations) with parenthesis around the (1 + 2) addition changes the result. &lt;br /&gt;&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; 1 + 2 * 4&lt;br /&gt;9 &lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; (1 + 2) * 4&lt;br /&gt;12 &lt;/pre&gt;&lt;br /&gt;A number is supplied for the left, and the right of each token.  These numbers are used to figure out which order the operators are applied to each other.   So we take our token structure  from tokenise() above, and we create some Token objects from them, and depending on their binding powers evaluate them.  &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What's new is old is new.&lt;/h3&gt;  &lt;img src="http://www.ukgirlthing.co.uk/Content/ProductImages/4382/images/0001.jpg" border="0"/&gt;&lt;br /&gt;The "Top Down Operator precedence" paper is from the 70's.  In the 70's lisp programmers loved to use three letter variable names, and therefore the algorithm and the variable names are three letter ones.   They also wore flares in the 70's (which are back in this season) and I'm not wearing them, and I'm not using three letter variable names!   &lt;br /&gt;&lt;br /&gt;Sorry, I digress...   So we call 'nud' prefix, and 'led' infix.  We also call rbp  right_binding_power, and lbp left_binding_power.     &lt;br /&gt;&lt;br /&gt;nud - prefix     &lt;br /&gt;led - infix     &lt;br /&gt;rbp - right_binding_power     &lt;br /&gt;lbp - left_binding_power  &lt;br /&gt;&lt;br /&gt;Prefix is to the left, and infix is to the right.   &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Manually stepping through the algorithm.&lt;/h3&gt;  Let's manually step through the algorithm for the simple expression "1 + 2 * 4". &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    &gt;&gt;&gt; pprint(list(tokenise("1 + 2 * 4")))&lt;br /&gt;    [{'from': 0, 'to': 1, 'type': 'number', 'value': 1.0},&lt;br /&gt;     {'from': 2, 'to': 3, 'type': 'operator', 'value': '+'},&lt;br /&gt;     {'from': 4, 'to': 5, 'type': 'number', 'value': 2.0},&lt;br /&gt;     {'from': 6, 'to': 7, 'type': 'operator', 'value': '*'},&lt;br /&gt;     {'from': 8, 'to': 9, 'type': 'number', 'value': 4.0}]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Let's give left binding powers to each of the token types. &lt;ul&gt;&lt;li&gt;number - 0&lt;/li&gt;&lt;li&gt;+ operator - 10&lt;/li&gt;&lt;li&gt;* operator - 20&lt;/li&gt;&lt;/ul&gt; Ok, so first we have a number token, with the value of 1.0.  This is because in our shitjs so far all numbers are floats.  Here is a log obtained by stepping through the expression.&lt;br /&gt;&lt;pre&gt;('token', Literal({'to': 1, 'type': 'number', 'value': 1.0, 'from': 0}))&lt;br /&gt;('expression right_binding_power: ', 0)&lt;br /&gt;   ('token', OperatorAdd({'to': 3, 'type': 'operator', 'value': '+', 'from': 2}))&lt;br /&gt;   ('left from prefix of first token', 1.0)&lt;br /&gt;   ('token', Literal({'to': 5, 'type': 'number', 'value': 2.0, 'from': 4}))&lt;br /&gt;   ('expression right_binding_power: ', 10)&lt;br /&gt;       ('token', OperatorMul({'to': 7, 'type': 'operator', 'value': '*', 'from': 6}))&lt;br /&gt;       ('left from prefix of first token', 2.0)&lt;br /&gt;       ('token', Literal({'to': 9, 'type': 'number', 'value': 4.0, 'from': 8}))&lt;br /&gt;       ('expression right_binding_power: ', 20)&lt;br /&gt;           ('token', End({}))&lt;br /&gt;           ('left from prefix of first token', 4.0)&lt;br /&gt;           ('leaving expression with left:', 4.0)&lt;br /&gt;       ('left from previous_token.infix(left)', 8.0)&lt;br /&gt;       right_binding_power:10: token.left_binding_power:0:&lt;br /&gt;       ('leaving expression with left:', 8.0)&lt;br /&gt;   ('left from previous_token.infix(left)', 9.0)&lt;br /&gt;   right_binding_power:0: token.left_binding_power:0:&lt;br /&gt;   ('leaving expression with left:', 9.0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can see that it is a recursive algorithm.  Each indentation is where it is entering a new expression.&lt;br /&gt;&lt;br /&gt;Also, see how it manages to use the binding powers to make sure that the multiplication of 2 and 4 is done first before the addition.  Otherwise the answer might be (1 + 2) * 4 == 12! Not the correct answer 9 that it gives at the end.&lt;br /&gt;&lt;br /&gt;The operations are ordered this way because the + operator has a lower left binding power than the * operator.&lt;br /&gt;&lt;br /&gt;You should also be able to see from that trace that a tokens infix and prefix operators are used.  The OperatorAdd for example, takes what is on the left and adds it to the expression of what is on the right with it's prefix operator.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here is an example Operator with prefix(left) and infix(right) methods.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;class OperatorAdd(Token):&lt;br /&gt;    left_binding_power = 10&lt;br /&gt;    def prefix(self):&lt;br /&gt;        return self.context.expression(100)&lt;br /&gt;    def infix(self, left):&lt;br /&gt;        return left + self.context.expression(self.left_binding_power)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pretty simple right?  You can see the infix method takes the value in from the left, and adds it to the expression of what comes on the right.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Exercises for next time&lt;/h3&gt; Make this work:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; evaluate("1 + 2 * 4")&lt;br /&gt;9.0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(ps... if you want to cheat the code repository has my part 2 solution in it if you want to see.  The code is very short).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Until next time... Further reading (for the train, or the bathtub). &lt;/h3&gt; &lt;img src="http://img.photobucket.com/albums/v30/kiyone/ami-mizuno-sailor-mercury-reading.jpg" border="0"/&gt;&lt;br /&gt;Below is some further reading about parsers for JavaScript, and parsers in python. &lt;ul&gt;&lt;li&gt;&lt;a href="http://simpleparse.sourceforge.net/"&gt;simpleparse&lt;/a&gt; and &lt;a href="http://blog.dowski.com/2010/07/21/a-json-parser-using-simpleparse/"&gt;a json parser using simpleparse&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://jaredforsyth.com/blog/2010/jul/8/announcing-codetalker/"&gt;codetalker&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jaredforsyth.com/blog/2010/jul/17/comparing-parser-generators-python/"&gt;comparing python parser generators&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form%20"&gt;Extended Backus–Naur Form (EBNF)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;   After following some of those links you may realise that we could probably make this shitjs interpreter in an easier way by reusing libraries.  However if we wanted to do that, we'd just use an existing JavaScript implementation!  Also our JavaScript wouldn't be shit, or from scratch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4470885299169683935?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4470885299169683935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4470885299169683935' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4470885299169683935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4470885299169683935'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/07/lets-make-shit-javascript-interpreter.html' title='Let&apos;s make a shit JavaScript interpreter!  Part Two.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_eJJgehXCsQ4/TCx_WVZ1VSI/AAAAAAAAAH0/osU9dhr4xTs/s72-c/lets-make-a-shit-javascript-interpreter.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-6270560681343706278</id><published>2011-04-01T14:41:00.001+01:00</published><updated>2011-04-01T14:41:53.315+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pyweek'/><title type='text'>Pyweek April 2011, this weekend.</title><content type='html'>&lt;b&gt;&lt;a href="http://pyweek.org/12/"&gt;Pyweek 12 – April 3rd-April 10th&lt;/a&gt;&lt;/b&gt;  &lt;p&gt;&lt;a href="http://pyweek.org/s/rules/"&gt;&lt;img src="http://media.pyweek.org/static/pyweek.png" /&gt;&lt;br /&gt;&lt;br /&gt;Find out more about PyWeek&lt;/a&gt; - "&lt;i&gt;Invites entrants to write a game in one week from scratch either as an individual or in a team.  Is intended to be challenging and fun.  Will hopefully increase the public body of game tools code and expertise.  Will let a lot of people actually finish a game.  May inspire new projects (with ready made teams!)&lt;/i&gt;"&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-6270560681343706278?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/6270560681343706278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=6270560681343706278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6270560681343706278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6270560681343706278'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/04/pyweek-april-2011-this-weekend.html' title='Pyweek April 2011, this weekend.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4825769644816687454</id><published>2011-03-22T20:55:00.005Z</published><updated>2011-03-22T21:16:42.604Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Hammering nails - the hard way.</title><content type='html'>Do the following 1000 hammering tasks, and you will have learned how to use a hammer the hard way.  You can do them from your bedroom.  These are just like these guitar tasks that I do - in my spare time as a rock star.  Well not really a rock star... but I sure can do some awesome guitar solos.  They're also like katas I practice for my martial arts... in my spare time as a ninja.&lt;br /&gt;&lt;br /&gt;"pssst..."  "the world doesn't like guitar solos any more - and playing in your bedroom will never be like playing to real people.  Also martial arts practitioners who use katas loose to fighters who practice fighting in real fights."&lt;br /&gt;&lt;br /&gt;"pssst... you there..."  "The pros don't use hammers.  They use nail guns."&lt;br /&gt;&lt;br /&gt;MOTHER FUCKING NAIL GUNS.  MOTHER FUCKER.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://programming-motherfucker.com/programming-motherfuckers.jpg"/&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You don't need a book to learn python the hard way.  To learn python the hard way, do some real world projects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;sub&gt;This pay out brought to you by the awesome &lt;a href="http://programming-motherfucker.com/"&gt;Programming, Motherfuckers manifesto&lt;/a&gt;.&lt;/sub&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4825769644816687454?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4825769644816687454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4825769644816687454' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4825769644816687454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4825769644816687454'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/03/hammering-nails-hard-way.html' title='Hammering nails - the hard way.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1279876286468763835</id><published>2011-03-14T17:11:00.012Z</published><updated>2011-03-15T19:49:37.578Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Hacking on android and pygame.</title><content type='html'>For the last couple of weeks I've been hacking on my new android tablet in my spare time.&lt;br /&gt;&lt;br /&gt;It's one of those cheap 25cm ones (10 inches).  Dual core, nvidia graphics, and all of that stuff.  Not a bad little device really.&lt;br /&gt;&lt;br /&gt;One project has been to port an old game of mine to it using &lt;a href="http://pygame.renpy.org/"&gt;PyGame subset for android(pgs4a)&lt;/a&gt;.  It's a package of a subset of the pygame modules - along with a bundled port of CPython for android.  You can either package your apps standalone, or simply install the launcher from the android market, then upload your game to your SD card.  Simples.&lt;br /&gt;&lt;br /&gt;So far it's been pretty fun, and the other weekend I got something running.  Next up is to work on the UI parts.  Already it supports keyboard, mouse, mouse+keyboard, and also joystick mode.  However, none of them really work with the touch screen on my tablet.  I'm not a very big fan of the touch joypad approach.  Where they make a virtual joypad on each side of the screen to touch.  There are two main actions in [TheGame]... move, and shoot.  You can click somewhere, and [MainCharactor] will try and move there.  You can also charge up your steam cannon to fire a cannon ball - which requires aiming.  There's a few interfaces which could work I think... I'll just have to try them out and see which I like best.&lt;br /&gt;&lt;br /&gt;I hacked on the game to the point where I needed to add some missing python modules into the mix, so had to compile the pgs4a myself.  That's taken a few days getting used to the tools, coming up against errors and then trying again the next day.  The other day I got it compiling... now the next step is to try uploading the creation to the device.&lt;br /&gt;&lt;br /&gt;The game in question is &lt;a href="http://zanthor.org/"&gt;Zanthor&lt;/a&gt;, and for it I've done some major refactoring in order to modernise the packaging of it a little bit.  Now there is a make, and configure script.  The code is in the zanthor directory rather than a lib directory, and of course packaged it so it can run on android... the list of packaging changes is quite large but worthwhile.  I hope to use it as a test case to improve packaging for games on python.  The idea is to automate packaging for multiple platforms from any of the platforms.  So that you can create a package for all supported platforms from any of them.  This is a project that I've been talking about for *years*... but releasing an actual game with it is the only way to make it actually happen I think.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-SmS3Boz5pW0/TX--uhvnTDI/AAAAAAAAAJs/mkJoRTmTo1k/s1600/IMG_5048.JPG"&gt;&lt;img src="http://3.bp.blogspot.com/-SmS3Boz5pW0/TX--uhvnTDI/AAAAAAAAAJs/mkJoRTmTo1k/s320/IMG_5048.JPG" alt="" id="BLOGGER_PHOTO_ID_5584391769504042034" border="0" /&gt;&lt;/a&gt;&lt;pre&gt;  zanthor on my android tablet&lt;/pre&gt;I also started messing around with a &lt;a href="http://jackaudio.org/"&gt;jack&lt;/a&gt; sound driver for SDL 1.3.  Jack is the "professional" low latency sound system for linux(+osx).  So far I've got it compiling, but still have a bunch more work to do on that.  My todo list for that is still quite long.  It's going to be tricky.  Jack clients have high requirements to not pull down a jack server if they misbehave.   I think I probably need to read through the &lt;a href="http://jackaudio.org/files/docs/html/index.html"&gt;jack developer documentation&lt;/a&gt; a few more times.   One difficulty will be loading the modules dynamically... even though usually they are linked in with the "pkg-config --libs jack" tool at compilation time.  Not too hard though, since SDL provides some nice cross platform dynamic library loading code.&lt;br /&gt;&lt;br /&gt;Whilst on the pygame audio side, a really nice patch was posted to the pygame mailing list for  the midi module by Christopher Arndt.  It cleans up the the midi module  some more, fixes some bugs, and adds some more documentation for the C  level API.   I still have to push his change up to the portmidi repository... which is a todo I've got for this weekend.  This is the sort of polish that I hope we can apply to the other  modules in the 1.9.2 release.&lt;br /&gt;&lt;br /&gt;A pygame release is planned for soonish. The focus will be a polish release.  Hopefully mainly polishing up existing stuff, and finishing off modules that are in an experimental or unfinished state.  My main task is to get the documentation under control.&lt;br /&gt;There's over 400 comments on the documentation to work through, so I expect this will take at least 40 hours time.  I'm going to improve the comment system on the website to improve  the work flow.  To add the ability to mark a comment as 'dealt with', or  'example'.  So when  going through them, the options are 'delete', 'dealt with' or ignore for  later.&lt;br /&gt;&lt;br /&gt;I've ordered a new dedicated webserver to help out with pygame.org tasks.  This should allow us to do some more things than with just the current host.  I paid for a year up front, so hopefully don't have to worry about it again for a while.  It has an old nvidia graphics card in it, so I hope to do some graphical webserver tasks on it, as well as take some other heavy processing tasks off the main web host.&lt;br /&gt;&lt;br /&gt;The new webserver should help us work in some countries where our current web host for pygame.org is blocked too.  Our current host does some things governments don't like... so I think that's why pygame is banned there.  Or else governments find the zombies on the website scary.&lt;br /&gt;&lt;br /&gt;Lenard Lindstrom has been working on some cleanups over the last number of months on some pygame modules.  Especially the numpy integration, which is much improved and is finally up to a similar speed compared to the old Numeric implementation.  Lenard has also explored converting our documentation system to use a different one.  He's started a conversion tool for this, so if it turns out good we should be able to convert our docs over easily.&lt;br /&gt;&lt;br /&gt;New binary installers for pygame on OSX is another task I've been working on.   I mainly did this for a few people who were attending the &lt;a href="http://renesd.blogspot.com/2011/01/london-python-dojo-pygame-write-up.html"&gt;London Python Dojo&lt;/a&gt; - who wanted pygame working on their Apple supplied python.  However there are still a few bugs in it that I need to fix up.  The main one being that SDL_image now does not link to libpng and libjpeg by default.  That is sort of awesome... in that it can reduce file size.  However, it's also sort of not awesome... since OSX does not support a few types of png files that are commonly used in pygame applications.  Also pygame uses those libraries to save to png and save to jpeg.  The other major change is that this package I made works with the Apple supplied version of python.  Increasingly people on OSX don't bother getting the python from python.org.   So now we're going to have multiple packages for OSX.  One for Apple python on x864, and one for 10.4 ppc/x86 python.org python.  I'd also like to allow including the frameworks in the site-packages/pygame/Frameworks/ directory rather than in the system or users Framework directory.  This will make installing better, since we won't need to ask for a password, and people should be able to bundle pygame more easily... since it won't be spread all over the file systems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1279876286468763835?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1279876286468763835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1279876286468763835' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1279876286468763835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1279876286468763835'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/03/hacking-on-android-and-pygame.html' title='Hacking on android and pygame.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-SmS3Boz5pW0/TX--uhvnTDI/AAAAAAAAAJs/mkJoRTmTo1k/s72-c/IMG_5048.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3175742648469831271</id><published>2011-02-23T10:52:00.007Z</published><updated>2011-02-23T11:41:45.189Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='london'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><title type='text'>london clojure dojo</title><content type='html'>(Last night I went to the London &lt;a href="http://clojure.org/"&gt;clojure&lt;/a&gt; dojo.)&lt;pre&gt;(. javax.swing.JOptionPane (showMessageDialog nil &lt;/pre&gt;&lt;pre&gt;  (reduce str ["Hello" "London" "Clojure" "Dojo"])))&lt;/pre&gt;&lt;div&gt;This dojo was hosted by &lt;a href="http://twitter.com/#!/otfrom"&gt;@otfrom&lt;/a&gt; and &lt;a href="http://twitter.com/#!/rrees"&gt;@rrees&lt;/a&gt; at the ThoughtWorks offices (many thanks to them).  They put on a nice spread of quiche and sandwiches.  Here's some of the quiche... which was nicer than it looks in this photo.) (&lt;/div&gt;&lt;br /&gt;&lt;img src="http://s3.amazonaws.com/twitpic/photos/large/246320763.jpg?AWSAccessKeyId=0ZRYP5X5F6FSMBCCSE82&amp;amp;Expires=1298459655&amp;amp;Signature=QWu1pc5N82vE8p8%2F%2BKU29GFpV4k%3D" /&gt;&lt;br /&gt;-- quiche picture credit to @otfrom (used without permission ;))&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There was a github repo setup &lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;a href="https://github.com/ldnclj/footpad" target="_blank" style="color: rgb(51, 51, 204); "&gt;https://github.com/ldnclj/&lt;wbr&gt;footpad&lt;/a&gt;&lt;/span&gt; before the session with the code from previous weeks.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After grazing, and drinking of softdrinks - the night started with a mini talk on &lt;a href="https://github.com/ninjudd/cake"&gt;cake&lt;/a&gt; (the tasty build tool + enhanced repl(interpreter) + kitchen sink  for clojure) by the co-organiser of the dojo (&lt;span class="Apple-style-span" style="color: rgb(68, 68, 68); font-family: Arial, 'Helvetica Neue', sans-serif; font-size: 15px; line-height: 18px; "&gt;Robert Rees from &lt;a href="http://www.thoughtworks.com/"&gt;ThoughtWorks&lt;/a&gt;)&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A programmer from Deutsche bank was there recruiting clojure programmers, and getting involved in the dojo too.  It kind of reminded me of python in the early days... where you could count the number of python jobs around on one hand (and two feet worth of toes).  People were talking about how they got a chance to use clojure at their work for a small project, or how they were thinking of sneaking a little bit of clojure into their projects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Anyone who's been to the London python dojo would be familiar with the format (@otfrom is involved in that one too).&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We were split into teams of five, and then huddled around the keyboard... then began to scratch our heads. I'd only started learning clojure earlier that day (well I think I've read about it before, but not in depth) (so there was a lot to learn. Luckily a few of the people in my group had more experience with clojure.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;During these sessions, it's great to see how other people work in their environments.  It's also interesting to see how people think in clojure.  Everyone in our group got a chance to type at the keyboard, and we almost got our task done.  In our group we used some tests, map+reduce and doall functions as well as list, array and map data structures.  We even used a few cake commands (autotest and killall).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At the end of an hour or so of coding each group did a mini presentation and demo of what they made.  Each group got a fair way towards getting the task done, and we got to see how they coded things.  It's fun seeing what others got up to, the approach they took and the challenges they faced.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;... at the end we left through the dungeon below the building.  Those who survived had a few drinks at the pub afterwards. )&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3175742648469831271?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3175742648469831271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3175742648469831271' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3175742648469831271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3175742648469831271'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/02/london-clojure-dojo.html' title='london clojure dojo'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1375554113735351666</id><published>2011-01-17T13:21:00.007Z</published><updated>2011-01-17T14:41:42.292Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>JQuery 1.5 promises a better future.</title><content type='html'>One of the new features of the unreleased JQuery 1.5 is a new $.ajax module.&lt;br /&gt;&lt;br /&gt;Apart from many bug fixes, the most interesting, and useful part for me is that it now uses &lt;a href="http://en.wikipedia.org/wiki/Promise_%28programming%29"&gt;promises&lt;/a&gt;.  Those familiar with python and twisted, or the JavaScript library mockikit, Dojo Deferred, or java.util.concurrent.Future might know these as deferreds or futures.   jQuery is using promises, and not futures.  They are similar but slightly different.  It's a very commonly used technique in concurrency libraries now - so it is good that jQuery has hopped on board.&lt;br /&gt;&lt;br /&gt;Since jQuery always returns a promise, you can now add callbacks even after you have done the call... or even change the callback later.&lt;br /&gt;&lt;pre&gt;jQuery.getJSON( url ).error( errorCallback )&lt;/pre&gt;&lt;h3&gt;Pluggable ajax lets us test more easily&lt;/h3&gt;The other great thing(from a testing perspective) is that jQuery now allows you to use plug in mock implementations.  This lets you make a fake ajax implementation for your unit tests more easily.&lt;br /&gt;&lt;br /&gt;This pluggable architecture could also lead to people making other plugins that act the same as the ajax interface.  Which could come in handy if you had a strange requirement, or you want to develop an alternative communication method - and be able to reuse much of the jQuery code.&lt;br /&gt;&lt;h3&gt;Subclassing jQuery object&lt;/h3&gt;Another new area where jQuery helps extensibility, is the ability to subclass the jQuery object, and override methods - without it breaking the public interface to jQuery.&lt;br /&gt;&lt;br /&gt;This is useful if you want to make a plugin that changes a few parts of jQuery for it's own uses, and not be worried that it will break 17 other plugins.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(function(globaljQuery, $) {&lt;br /&gt; // private functions&lt;br /&gt; $.fn.privateFunction = function(){ };&lt;br /&gt;&lt;br /&gt; // overwrite an existing function without breaking other plugins&lt;br /&gt; //   which use the global jQuery function.&lt;br /&gt; $.fn.popularExistingFunction = function(){ };&lt;br /&gt;&lt;br /&gt; // Expose some public functions&lt;br /&gt; globaljQuery.fn.myPublicFunction = function(){ };&lt;br /&gt;&lt;br /&gt;})(jQuery, jQuery.subClass());&lt;/pre&gt;&lt;br /&gt;You can try the &lt;a href="http://blog.jquery.com/2011/01/14/jquery-1-5-beta-1-released/"&gt;jQuery 1.5 beta 1&lt;/a&gt; yourself if you want to have a play.  I'm sure they will appreciate any bug reports.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1375554113735351666?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1375554113735351666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1375554113735351666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1375554113735351666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1375554113735351666'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/01/jquery-15-promises-better-future.html' title='JQuery 1.5 promises a better future.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4127115090043611656</id><published>2011-01-14T15:43:00.011Z</published><updated>2011-01-15T01:16:09.249Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='london'/><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='dojo'/><title type='text'>London python dojo pygame write up.</title><content type='html'>Last night I went to the London python dojo at the Fry IT offices.&lt;br /&gt;&lt;br /&gt;The night started with pizza, beer, and nerdy chats with everyone.&lt;br /&gt;&lt;br /&gt;Then two lightning talks.  The first by &lt;a href="http://twitter.com/tomviner"&gt;@tomviner&lt;/a&gt; (Tom), on some funny and useful python modules.  `pip install oo &amp;amp;&amp;amp; python -moo`  Python goes moo (dad joke).  `pip install e &amp;amp;&amp;amp; python -me 1+2`&lt;br /&gt;&lt;br /&gt;Next up was &lt;a href="http://twitter.com/otfrom"&gt;@otfrom&lt;/a&gt; (Bruce).  He has a cunning plan to work on an engine that could be used later in a cross language dojo to display a game world. @otfrom is trying to see if other language dojos in london are interested in having a bot war tournament in the future.  So far the clojure dojo, and perhaps the scala dojo are interested in participating.&lt;br /&gt;&lt;br /&gt;@otfrom also announced the London dojos mailing list at: http://groups.google.com/group/london-dojos  A group for people interested in programming dojos in london (not just python).&lt;br /&gt;&lt;br /&gt;Then 30 of us took an open source game from &lt;a href="http://www.pygame.org/"&gt;pygame.org&lt;/a&gt;, forked it and hacked on it!&lt;br /&gt;&lt;br /&gt;I brought along a big bag of joypad controllers - 30 of them.  The idea was to hand out one to each person who turned up.  Unfortunately, they were two controllers joined together with one USB cable.  Which meant that not everyone got a controller, but 15 people got two!&lt;br /&gt;&lt;br /&gt;But first let's rewind to the night before... [[insert tape rewinding sound]] where &lt;a href="http://twitter.com/ntoll"&gt;@ntoll&lt;/a&gt; and I were discussing what to do... continue on with the xmas card demo we made last time?  Or instead, hack on something a bit more complete?&lt;br /&gt;&lt;br /&gt;The more complete game chosen is an over head dungeon crawller type game.  It's not at all finished, and is a work progress one.   @ntoll selected it from the thousands on &lt;a href="http://pygame.org/"&gt;pygame.org&lt;/a&gt; It seemed to have fairly clean modular code, and be roughly what we were aiming to build.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;@ntoll github crawlr page: &lt;a href="https://github.com/ntoll/crawlr"&gt;https://github.com/ntoll/crawlr&lt;/a&gt;&lt;/li&gt;&lt;li&gt;original crawlr page: &lt;a href="https://github.com/axedcode/crawlr"&gt;https://github.com/axedcode/crawlr&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;As is usual of the london python dojos, we split up into groups.  Five teams of six people this time.  &lt;em&gt;'Pair programming on steroids - and not in a good way'&lt;/em&gt; is how the london python dojo has been described.  The room was packed, and most teams split up into two groups of three, with 2-4 laptops per group - some laptops hooked up to larger screens so people a bit further away could have a look.&lt;br /&gt;&lt;br /&gt;At the beginning we each got 'Quests', which were little tasks made up by @ntoll.&lt;br /&gt;&lt;br /&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 84px;" src="http://1.bp.blogspot.com/_eJJgehXCsQ4/TTCGUvEIEQI/AAAAAAAAAJA/W8NBHidEIb8/s320/Screenshot-1.png" alt="" id="BLOGGER_PHOTO_ID_5562093230591840514" border="0" /&gt;&lt;ol&gt;&lt;li&gt;Add NPC characters that walk randomly around the world&lt;/li&gt;&lt;li&gt;Add music and sfx for particular events&lt;/li&gt;&lt;li&gt;Allow the maps to be pre-defined rather than (as is the case) randomly generated each time.&lt;/li&gt;&lt;li&gt;Add static objects to the game world such as gold or food that get added to the players inventory/energy/score/whatever when they bump into them...&lt;/li&gt;&lt;li&gt;Two player mode (sharing the same keyboard or with two controllers)&lt;/li&gt;&lt;li&gt;Menu system (Start Game, Help, Set-up, Quit)&lt;/li&gt;&lt;/ol&gt;  Each group took their Quests, and got stuck into it.  I had the pleasure of going around to each group to see how they were going, and to help out where I could with work arounds for pygame issues.  I spent a time with most groups... but couldn't work my way into to where one group was, as they were surrounded by other people completely... and I would have had to climb over the top of people.&lt;br /&gt;&lt;br /&gt;After coding stopped (@ntoll had to turn the lights off a few times to try and get people to stop)... the groups presented their work.  It's a time for reflection and to show off what you did.&lt;br /&gt;&lt;br /&gt;Each group managed to accomplish something.  However some tasks were a bit harder than others - and they turned into reverse engineering tasks.&lt;br /&gt;&lt;br /&gt;So by the end, we had:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;joypad control of the main character, starting the game and exiting it.&lt;/li&gt;&lt;li&gt;A start on multiple player abstraction, from single player.  With a small issue that the second player was not displayed on screen for some reason.  A separate image is loaded and everything... it's just not displayed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;An Non Player Character (NPC), that could move and change direction (currently in two separate code bases).&lt;/li&gt;&lt;li&gt;A start on collision detection of the main character with things on the ground (like mush rooms).  As this group was demoing their work, they 'lived coded' up some missing parts of the solution.&lt;/li&gt;&lt;li&gt;Music, which is different for the main menu screen and the in game music.&lt;/li&gt;&lt;li&gt;Sound effects, for different actions in the game... and some 'ambient' screams of FEAR and TERROR as the character walks through the forrest.&lt;/li&gt;&lt;li&gt;Loading and saving of maps into a text based format.  Originally the maps are randomly generated, so this needed reverse engineering to figure out how that worked too.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;A bloody good result really.  Especially since it was &lt;strong&gt;code no one there had seen&lt;/strong&gt; (except ntoll, and me a tiny bit), and the groups only had &lt;strong&gt;an hour and a half&lt;/strong&gt; to hack on things,  groups with &lt;strong&gt;people they never worked with before&lt;/strong&gt;, using &lt;strong&gt;unfamiliar libraries&lt;/strong&gt; that some hadn't even installed until the dojo (eg, pygame).&lt;br /&gt;&lt;br /&gt;I think some people were a little frustrated with their tasks, especially some which were more of a challenge than others.  But most seemed to enjoy it.&lt;br /&gt;&lt;br /&gt;Overall I think this Dojo was about something which the organiser didn't intend.  It was about quickly figuring out a code base, and modifying it.  Reading, and modifying other peoples code is a great skill to master - and if nothing this Dojo gave us some experience with that, and let us see how other people do that too.&lt;br /&gt;&lt;br /&gt;I saw some people using class browsers I hadn't seen, some using an API from the interpreter, others weilding their custom made code search scripts - to hunt down variables.&lt;br /&gt;&lt;br /&gt;At the end of the dojos we usually decide on what we do next.  We decided to continue on with the game idea in future dojos - so we can use it in a cross language dojo bot war.  We also decided that 'someone' would try and merge all our bits of code together, and that &lt;a href="http://www.twitter.com/tjguk"&gt;@tjguk&lt;/a&gt; (Tim) would present an over view of the code base if he has time at the next dojo.&lt;br /&gt;&lt;br /&gt;Unforuntately I couldn't go to the pub afterwards - hopefully next time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Tim &lt;a href="http://ramblings.timgolden.me.uk/2011/01/14/fear-and-screaming-at-the-london-python-dojo/"&gt;wrote about the dojo on his blog&lt;/a&gt; too.&lt;br /&gt;* &lt;a href="http://twitter.com/r4vi"&gt;@r4vi&lt;/a&gt; uploaded some videos &lt;a href="http://www.youtube.com/view_play_list?p=63C1FD922FB37B43"&gt;http://www.youtube.com/view_play_list?p=63C1FD922FB37B43&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4127115090043611656?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4127115090043611656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4127115090043611656' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4127115090043611656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4127115090043611656'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/01/london-python-dojo-pygame-write-up.html' title='London python dojo pygame write up.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_eJJgehXCsQ4/TTCGUvEIEQI/AAAAAAAAAJA/W8NBHidEIb8/s72-c/Screenshot-1.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-6767108797460524159</id><published>2011-01-10T15:35:00.005Z</published><updated>2011-01-10T15:48:24.892Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Pyramid does 22, but how do you do zero lines of python?</title><content type='html'>There is an article talking about how in a certain configuration the Pyramid python framework uses &lt;a href="http://plope.com/pyroptimization"&gt;22 lines of python&lt;/a&gt; for a hello world app.&lt;br /&gt;&lt;br /&gt;How would your python web app run zero lines of code for a hello world?  By pre-generating the html at startup - or at deploy time, and serving the generated data.&lt;br /&gt;&lt;br /&gt;Beat that Pyramid! ;)  &lt;em&gt;&lt;a href="http://www.imdb.com/title/tt0129387/quotes?qt0410938"&gt;6 minute Abs&lt;/a&gt;&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is a silly blog post - but also slightly serious.  Uploading static data to serve is a very valid approach for a web framework.  It's performance, security, and complexity benefits are quite big.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-6767108797460524159?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/6767108797460524159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=6767108797460524159' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6767108797460524159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6767108797460524159'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2011/01/pyramid-does-22-but-how-do-you-do-zero.html' title='Pyramid does 22, but how do you do zero lines of python?'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-5452629647002359905</id><published>2010-12-28T18:52:00.010Z</published><updated>2010-12-28T20:52:26.705Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='HD'/><category scheme='http://www.blogger.com/atom/ns#' term='teevee'/><title type='text'>Why HD looks weird.</title><content type='html'>Very often I'm sitting next to a HD teevee, and people say 'that looks weird'.&lt;br /&gt;&lt;br /&gt;Why?&lt;br /&gt;&lt;br /&gt;There's a number of reasons, but the two main ones are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;when compared to SD digital teevee&lt;/strong&gt; is: &lt;em&gt;Poor colour depth compared to the number of pixels&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;For &lt;strong&gt;a person used to analog teevee (PAL, or NTSC)&lt;/strong&gt; - and not digital teevee, a major weirdness is the digital compression used.  &lt;em&gt;Digital teevee is compressed&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Compared to SD digital teevee - No increase in colour richness.&lt;/h3&gt;They increased the number of pixels shown per cm (or inch), but did not increase the richness of colour displayed.&lt;br /&gt;&lt;br /&gt;On PAL for example, you may have 422 colour depth - which is 8 bit colour.  If you come from the computer world you may think that is 8 bits per channel colour (RGB 888).  However in the broadcast world they use the YUV colour space, and this is usually only 8 or 10 bits per pixel.  4 bits Y, 2 bits U, 2 bits V == 8 bits per pixel.&lt;br /&gt;&lt;br /&gt;If the colour depth is the same, then why does it look weirder in HD?  Imagine a rainbow going from Left-&gt;Right.  PAL would have 768 pixels wide, and 'HD' 1920 pixels wide.&lt;br /&gt;&lt;br /&gt;The same number of colours would be on the rainbow line, only the HD one would be kind of zoomed in.&lt;br /&gt;&lt;br /&gt;The error is zoomed in - or enhanced.&lt;br /&gt;&lt;br /&gt;There's other issues like how blue ray only does 8bit colour, and then there are cameras that only output 8bit colour... or worse.  Then the equipment in various distribution centers, or the center which puts the little logo in left hand side of the screen, might have different resolutions (say one operates in YUV 422... 8bit).  Then you have the compression codecs, and settings being used by the broadcasters.  Then the link from your broadcast box to your LCD can down-sample to 8bit.  Finally the LCD internally may only do 8 bit, or the display only 8bit.  If any one link in the chain from the camera to the LCD is 8 bit, then the final result will be 8bit (or possibly even worse, if the conversions are done badly... eg a fast YUV422-&gt;RGB-&gt;YUV422 conversion are not lossless).  Or the camera natively uses bayer colour space, which is converted to YUV422 by the interface, and then to RGB888 in the computer, then back to YUV422 in the encoder, through to the teevee which is shown in bayer colour space again right at the end.  Each conversion to a different colour space is lossy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Other reasons why it looks weird are enhancing the error of the frame intervals.  Eg, film at 24fps somehow shown on a screen that only does 50hz.  We've gotten used to things been shown at one frame rate compared to another.  The movement is different - and human beings can easily tell the difference.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Teevee is now very complex, and a lot of factors complicate what is being shown to you.  Everything, from the speed of things being shown to you, to the colour depth used, the bandwidth used per teevee channel, to the size of the display to the type of technology being used to show you... even the glass on the screen is different.&lt;br /&gt;&lt;br /&gt;Why does HD look weird?&lt;br /&gt;&lt;br /&gt;All of those things have an affect, however the lack of enough extra colour depth is one of the main things.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Compared to analog teevee - digital compression.&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;For &lt;strong&gt;a person used to analog teevee (PAL, or NTSC)&lt;/strong&gt; - and not digital teevee, a major weirdness is the digital compression used.  &lt;em&gt;Digital teevee is compressed&lt;/em&gt;, so they can fit more channels in the space available to them.  The compression changes the image so to the human eye... little detail is lost.  &lt;br /&gt;&lt;br /&gt;That's the aim anyway.  However, compression is never perfect - and many people can see the weirdness in the compressed images.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The world of teevee is weird - but digital teevee is even weirder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-5452629647002359905?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/5452629647002359905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=5452629647002359905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5452629647002359905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5452629647002359905'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/12/why-hd-looks-weird.html' title='Why HD looks weird.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-773114379948114472</id><published>2010-10-12T23:20:00.010+01:00</published><updated>2010-10-23T18:35:23.419+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>iphone web app development, from the trenches.</title><content type='html'>&lt;font face="Courier New, Courier, monospace"&gt;&lt;br /&gt;Dear reader,&lt;br /&gt;&lt;br /&gt;I joined the iOS web developers for adventure and a chance to see the world but instead I am working in a mud hole, freezing my arse off, with a constant fear of death.  I am writing this note in hope that it makes it out of the trenches.  In case I do not.&lt;br /&gt;&lt;br /&gt;It's bloody here in the iOS trenches and I feel my days are numbered.  With these thoughts on my mind, I hope to share this with you.&lt;br /&gt;&lt;br /&gt;Some of this stuff is not documented in the standard issue manual, or disseminated via the standard propaganda channels.  I feel it ought be of use to you.&lt;br /&gt;&lt;br /&gt;Unfortunately it has been very hectic here, so the words will likely be rushed and detail will be lacking.  I apologise for this, but I still think it will be useful (no brain rockets, just some Damn Useful Information).&lt;br /&gt;&lt;br /&gt;In case I don't make it,&lt;br /&gt;Your friend from the trenches,&lt;br /&gt;René Dudfield.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ps.  if you find this note, please consider &lt;a href="http://renesd.blogspot.com/2010/10/iphone-web-app-development-from.html"&gt;commenting on the back&lt;/a&gt; with any other useful information your fellow iOS trench mates might find useful.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-------------- -------------- --------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Going full screen requires a cache manifest on the iphone.  Otherwise the files do not save.  The cache manifest is a horrible beast, that has quite a few gotchas.  It will only go fullscreen when run as a web app, not when run through safari.&lt;br /&gt;&lt;br /&gt;You can detect with javascript if your app is running through safari, or as a web app.  This is most useful for asking the user if they want to put your app on their home screen.&lt;br /&gt;&lt;br /&gt;Changing css opacity quickly is really slow on the iphone.  This makes some jquery things slow - like show/hide.&lt;br /&gt;&lt;br /&gt;Use the css animations, and transitions if you can.  Just like animating opacity is slow with javascript on iphone, so is animating other css attributes.&lt;br /&gt;&lt;br /&gt;There is a 5MB limit on the overall app cache size.  Big files will not cache (like music and videos).&lt;br /&gt;&lt;br /&gt;If you are using cache busting urls, it stuffs up the cache manifest.  eg, mystyles.css?v=234 in your html, will make the cache not work correctly.  I guess since the cache has just mystyles.css not mystyles.css?v=234.&lt;br /&gt;&lt;br /&gt;For cache manifest to work on iphone you need a html 5 doctype, and a html 5 tag without a xmlns attribute.&lt;br /&gt;&lt;br /&gt;Google chrome can be a good debugging tool for the cache manifest file.  Since it shows you problems in the console.&lt;br /&gt;&lt;br /&gt;Restarting the iphone can help clear the safari cache.&lt;br /&gt;&lt;br /&gt;Safari 4, and iOS 4 have the audio tag - not earlier.  Calling play on an Audio object after calling load does not really work.  However if you set the autoplay attribute to true then it plays as soon as it can.&lt;br /&gt;&lt;br /&gt;The audio can stutter a little bit if you are doing many other things at the time, or if the network slows, and it's not all loaded yet.&lt;br /&gt;&lt;br /&gt;iphone can not play video inline on a webpage.  It can only play fullscreen.  iPad can play the video inline.&lt;br /&gt;&lt;br /&gt;SVG on iphone is pretty quick.  Canvas is not so quick... but you can still do basic things ok.&lt;br /&gt;&lt;br /&gt;CSS media queries let you supply a different CSS if you are on an iphone/ipad/android etc.&lt;br /&gt;&lt;br /&gt;Mouse events are a bit slow to react.  You can use mouse events, but learning how to use the touch events will allow you to develop a much better experience.  The touch start event, and the touch end event both come before a mouse event arrives.  This means that it will always respond faster by using the touch events.&lt;br /&gt;&lt;br /&gt;Make touchable things(buttons) big, and make them a similar size.  If you have a really small button next to a really big button it might be impossible for the person to press on the really small button.  They can zoom in and out, and if the buttons are all a similar size, then they will be zoomed in at the right level to be able to press on the buttons.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-773114379948114472?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/773114379948114472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=773114379948114472' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/773114379948114472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/773114379948114472'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/10/iphone-web-app-development-from.html' title='iphone web app development, from the trenches.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7980435029507814869</id><published>2010-09-29T10:29:00.003+01:00</published><updated>2010-10-07T16:29:21.701+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Tweeting python packaging tips.</title><content type='html'>I've begun 'tweeting' &lt;a href="http://twitter.com/renedudfield"&gt;python packaging tips&lt;/a&gt;.  I'm hoping to go up to 100 useful python packaging tips.  If you're a twit too, &lt;a href="http://twitter.com/renedudfield"&gt;please feel free to join in on the conversations&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;b&gt;update&lt;/b&gt;: I wrote a little script to download all the python packaging related tweets from twitter.  For some reason twitter is only giving me 32 of them... but I've written about 40 so far.  Going to run through these at the london python dojo tonight in a mini talk.&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;br /&gt;setup.py build_ext --inplace to compile your extensions inside the source directory.  Good for developing inplace&lt;br /&gt;&lt;br /&gt;distribute 'setup.py develop' Installed pkg points to dev copy, quicker changes during dev. develop -u to remove&lt;br /&gt;&lt;br /&gt;For pyrex/cython/swig packages, include the generated C code so people do not need to install cython/pyrex/swig.&lt;br /&gt;&lt;br /&gt;For debugging info set DISTUTILS_DEBUG. os.environ['DISTUTILS_DEBUG'] = "on" OR export DISTUTILS_DEBUG=on&lt;br /&gt;&lt;br /&gt;Don't put code in package/__init__.py file. Makes debugging/editing harder as there are lots of __init__.py files&lt;br /&gt;&lt;br /&gt;Name the folder your package lives in after the package name, not src or lib.  eg ./mypackage/&lt;br /&gt;&lt;br /&gt;Make quick and dirty .deb .rpm packaging of any python package with checkinstall&lt;br /&gt;&lt;br /&gt;Create man pages(unix docs) for scripts and command line programs you make available.  See rst2man and help2man.&lt;br /&gt;&lt;br /&gt; Install scripts (cmd line programs) with pkg http://docs.python.org/distutils/setupscript.html#installing-scripts&lt;br /&gt;&lt;br /&gt;Including a short summary of changes at end of 'description' metadata lets people quickly see changes on pypi.&lt;br /&gt;&lt;br /&gt;put a #hashtag in your description metadata, and your package will turn up on twitter under that.&lt;br /&gt;&lt;br /&gt;Read other peoples python packages to see what they do well.  Especially packages you use.&lt;br /&gt;&lt;br /&gt;Distutils2 is the future of packaging.  It's not ready yet though.  http://pypi.python.org/pypi/Distutils2&lt;br /&gt;&lt;br /&gt;setup.cfg is an (optional) setup config file. http://docs.python.org/distutils/configfile.html&lt;br /&gt;&lt;br /&gt;Test on multiple python versions before release.  Each py version is different (2.6,3,pypy,ironpython,jython).&lt;br /&gt;&lt;br /&gt;Tests are good.  See what you are not testing with the coverage package. http://nedbatchelder.com/code/coverage/&lt;br /&gt;&lt;br /&gt;Check your package quality with Cheesecake. 'pip install Cheesecake'  'cheesecake_index -v -n yourpackage'.&lt;br /&gt;&lt;br /&gt;Give credit, ♥, and props to your contributors in a thanks.txt file.&lt;br /&gt;&lt;br /&gt;pep 386 specifies version scheme for Distutils - use it.  http://www.python.org/dev/peps/pep-0386/&lt;br /&gt;&lt;br /&gt;1 eg. #django package is not at http://pypi.python.org/pypi/django . It is at http://pypi.python.org/pypi/Django&lt;br /&gt;&lt;br /&gt;Packages are caseSensitive. Refer to it the same way it's installed, otherwise confusion installing &amp; finding.&lt;br /&gt;&lt;br /&gt;Check your package name is available on pypi, and that it follows the pep8 naming convention. All lowercase, etc.&lt;br /&gt;&lt;br /&gt; No changes metadata field. Put in long_description field and CHANGES.txt so people know what's new or changed.&lt;br /&gt;&lt;br /&gt;MANIFEST.in controls files to include/exclude (.bak .swp) http://docs.python.org/distutils/sourcedist.html&lt;br /&gt;&lt;br /&gt;bdist_mpkg is the package required to make Mac OSX installers.&lt;br /&gt;&lt;br /&gt;1 In your setup.py  from distutils.command.build import build;build.sub_commands.append(('test', None))&lt;br /&gt;&lt;br /&gt;Running tests after build helps catch errors in distro packaged versions, and turns all users into testers.&lt;br /&gt;&lt;br /&gt;Great guide http://diveintopython3.org/packaging.html Slightly dated (2009) since py packaging moves fast.&lt;br /&gt;&lt;br /&gt;pep 345, latest spec for adding metadata to Python distributions. http://www.python.org/dev/peps/pep-0345/&lt;br /&gt;&lt;br /&gt;readme.txt - Use .txt extension. Be reStructuredText. Use windows carriage returns/newlines because notepad sux.&lt;br /&gt;&lt;br /&gt;The debian/ dir should only be in the Debian packaging repository.  The debian maintainer takes care of it.&lt;br /&gt;&lt;br /&gt;_module.so _module.dll _module.dynlib - compiled extensions should be named with a leading underscore.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7980435029507814869?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://twitter.com/renedudfield' title='Tweeting python packaging tips.'/><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7980435029507814869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7980435029507814869' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7980435029507814869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7980435029507814869'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/09/tweeting-python-packaging-tips.html' title='Tweeting python packaging tips.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1509166219512705030</id><published>2010-09-26T17:46:00.008+01:00</published><updated>2010-09-26T18:32:05.737+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='gadgets'/><category scheme='http://www.blogger.com/atom/ns#' term='berlin'/><title type='text'>Pokket mixer.  A sound mixer from Berlin.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_eJJgehXCsQ4/TJ95drNmKyI/AAAAAAAAAIs/UzJywhItGQY/s1600/IMG_4780.JPG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_eJJgehXCsQ4/TJ95drNmKyI/AAAAAAAAAIs/UzJywhItGQY/s400/IMG_4780.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5521265218902436642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.pokketmixer.com/"&gt;pokket mixer&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I went to the big market at the Berlin park today, and saw this little sound mixer there. This dude and his girlfriend who were at the stall make them!  They are his design too.  Really cool buying electronics from the people who make them.&lt;br /&gt;&lt;br /&gt;Did I mention I like buying small things that can fit in my pocket, and in my carry-on luggage?&lt;br /&gt;&lt;br /&gt;It's passive - so it does not need to be powered.  It's also very small.  Seems to work quite well.  The eq seems to work ok.  It has the normal Hi, Mid, Lo for each of the two channels.  The sound quality seems pretty good (even when going out to high quality studio speakers).  I've bought more expensive mixers with worse audio quality.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1509166219512705030?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1509166219512705030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1509166219512705030' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1509166219512705030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1509166219512705030'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/09/pokket-mixer-sound-mixer-from-berlin.html' title='Pokket mixer.  A sound mixer from Berlin.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_eJJgehXCsQ4/TJ95drNmKyI/AAAAAAAAAIs/UzJywhItGQY/s72-c/IMG_4780.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1133148850104714044</id><published>2010-08-09T17:53:00.004+01:00</published><updated>2010-08-23T09:42:29.680+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>3g modems in finland?  Any plans for a month or one week?</title><content type='html'>Dear Lazy web,&lt;br /&gt;&lt;br /&gt;Are there any 3G usb modem plans available in Finland that I can get for one week or a month?  I'd need to buy the modem too.&lt;br /&gt;&lt;br /&gt;Hopefully it should work two hours drive from Oulu.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Update: used a modem by Elisa.  Worked well, even 3g.  Closing comments because this post is getting spams every day - and blogger.com spam protection seems broken.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1133148850104714044?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1133148850104714044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1133148850104714044' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1133148850104714044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1133148850104714044'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/08/3g-modems-in-finland-any-plans-for.html' title='3g modems in finland?  Any plans for a month or one week?'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1257312367272640767</id><published>2010-07-26T01:37:00.007+01:00</published><updated>2010-07-26T12:42:52.168+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='templates'/><title type='text'>javascript (and jquery) templating</title><content type='html'>I just put up some code for doing templating with javascript(and jquery).  Either on the server side or on the client side.  If you open the html in your browser, it runs on the client side.  If you first process it server side... then it runs server side(but not on the client side).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/illume/nodejs_jquery_templating"&gt;http://github.com/illume/nodejs_jquery_templating&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a followup from &lt;a href="http://renesd.blogspot.com/2010/05/you-are-using-wrong-templating-system.html"&gt;you are using the wrong templating language&lt;/a&gt; - as a proof of concept.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Why is this useful?&lt;/h3&gt; &lt;ul&gt;&lt;li&gt;No need for a server to process the templates.  Either process them server side or client side.&lt;/li&gt;&lt;li&gt;Data can be stored in a json file.  No need for a database for testing.  Just create json files in a text file.&lt;/li&gt;&lt;li&gt;Can reuse knowledge of javascript libraries (like jquery), rather than learning one of 798394 different templating languages.&lt;/li&gt;&lt;li&gt;Can keep one html file which front end web developers can edit without them needing a new template file.&lt;/li&gt;&lt;li&gt;Can use jquery plugins on server side too(validation, etc).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Seems to work ok so far... but it still needs a lot of polish before it'll be useful.  If it works out ok, I'll try it out on some real projects (where the main server side language is python).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1257312367272640767?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1257312367272640767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1257312367272640767' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1257312367272640767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1257312367272640767'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/07/javascript-templating.html' title='javascript (and jquery) templating'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-5407577362108984877</id><published>2010-06-09T10:15:00.028+01:00</published><updated>2010-07-01T16:02:35.449+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='goat'/><category scheme='http://www.blogger.com/atom/ns#' term='shitjs'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Let's make a shit JavaScript interpreter!  Part one.</title><content type='html'>&lt;a href="http://www.poweredbybees.com/"&gt;&lt;img src="http://1.bp.blogspot.com/_eJJgehXCsQ4/TCx_WVZ1VSI/AAAAAAAAAH0/osU9dhr4xTs/s1600/lets-make-a-shit-javascript-interpreter.png" border="0"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Let's make a shit javascript interpreter!  Part one.&lt;/h1&gt;    As a learning exercise, I've begun writing a &lt;strike&gt;&lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;javascript&lt;/a&gt;&lt;/strike&gt; &lt;a href="http://en.wikipedia.org/wiki/ECMAScript"&gt;ECMAScript&lt;/a&gt; interpreter in &lt;a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29"&gt;python&lt;/a&gt;.  It doesn't even really exist yet, and when it does it will run really slowly, and not support all js features.&lt;br /&gt;&lt;br /&gt;So... let's make a "from scratch", all parsing, all dancing, shit interpreter of our very own!&lt;br /&gt;&lt;br /&gt;Teaching something is a great way to learn.  Also writing things on my blog always gets good 'comments', hints, tips, plenty of heart, and outright HATE from people.  All useful and entertaining :)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Tokenising&lt;/h2&gt;  So to start with, we need something to turn the .js files into a list of tokens.  This type of program is called a tokeniser.&lt;br /&gt;&lt;br /&gt;From some &lt;i&gt;javascript&lt;/i&gt; like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;function i_can_has_cheezbrgr () {return 'yum';};&lt;/pre&gt;&lt;/blockquote&gt;Into a &lt;i&gt;Token list&lt;/i&gt; something like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;[&lt;br /&gt;{"type":"name",&lt;br /&gt;"value":"function",&lt;br /&gt;"from":0,&lt;br /&gt;"to":8},&lt;br /&gt;{"type":"name",&lt;br /&gt;"value":"i_can_has_cheezbrgr",&lt;br /&gt;"from":9,&lt;br /&gt;"to":28},&lt;br /&gt;{"type":"operator",&lt;br /&gt;"value":"(",&lt;br /&gt;"from":29,&lt;br /&gt;"to":30},&lt;br /&gt;{"type":"operator",&lt;br /&gt;"value":")",&lt;br /&gt;"from":30,&lt;br /&gt;"to":31},&lt;br /&gt;{"type":"operator",&lt;br /&gt;"value":"{",&lt;br /&gt;"from":32,&lt;br /&gt;"to":33},&lt;br /&gt;{"type":"name",&lt;br /&gt;"value":"return",&lt;br /&gt;"from":33,&lt;br /&gt;"to":39},&lt;br /&gt;{"type":"string",&lt;br /&gt;"value":"yum",&lt;br /&gt;"from":40,&lt;br /&gt;"to":45},&lt;br /&gt;{"type":"operator",&lt;br /&gt;"value":";",&lt;br /&gt;"from":45,&lt;br /&gt;"to":46},&lt;br /&gt;{"type":"operator",&lt;br /&gt;"value":"}",&lt;br /&gt;"from":46,&lt;br /&gt;"to":47},&lt;br /&gt;{"type":"operator",&lt;br /&gt;"value":";",&lt;br /&gt;"from":47,&lt;br /&gt;"to":48}&lt;br /&gt;]&lt;/pre&gt;&lt;/blockquote&gt;Wikipedia has a page on &lt;a href="http://en.wikipedia.org/wiki/Parsing"&gt;Parsing&lt;/a&gt; (also see &lt;a href="http://en.wikipedia.org/wiki/List_of_unusual_articles"&gt;List_of_unusual_articles&lt;/a&gt; for some other background information).&lt;br /&gt;&lt;br /&gt;"&lt;i&gt;Tokenization&lt;/i&gt; is the process of demarcating and possibly  classifying sections of a string of input characters. The resulting  tokens are then passed on to some other form of processing. The process  can be considered a sub-task of &lt;a href="http://en.wikipedia.org/wiki/Parsing" title="Parsing"&gt;parsing&lt;/a&gt;  input."  -- &lt;a href="http://en.wikipedia.org/wiki/Lexical_analysis#Token"&gt;wikipedia Lexical_analysis#Token&lt;/a&gt; page.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;We can has vegetarian cheeseburger... but how can we parse javascript?&lt;/h3&gt;To the rescue, comes uncle Crockford the javascript guru of &lt;a href="http://www.jslint.com/"&gt;jslint&lt;/a&gt; fame.  He wrote this lovely article: &lt;a href="http://javascript.crockford.com/tdop/tdop.html"&gt;http://javascript.crockford.com/tdop/tdop.html&lt;/a&gt;.  The ideas come from a 1973 paper called &lt;a href="http://portal.acm.org/citation.cfm?id=512931"&gt;"Top Down Operator Precedence"&lt;/a&gt;.  The Crockford article is great, since it is free, short, and well written javascript.  Unlike the 1973 paper it gets the ideas from... which is behind a paywall, long, and uses a 1973 language called &lt;a href="http://en.wikipedia.org/wiki/Lisp"&gt;"(l,(i,(s,(p))))"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As well as being short and simple... &lt;a href="http://www.philhassey.com/blog/"&gt;Phil Hassey&lt;/a&gt; used "Top Down Operator Precedence" and this article on his journey &lt;a href="http://www.philhassey.com/blog/category/tinypy/page/3/"&gt;making tinypy&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Goat driven development&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=5AiS4ZoZhlY"&gt;&lt;img src="http://1.bp.blogspot.com/_eJJgehXCsQ4/TCyswPI6joI/AAAAAAAAAH8/RJIShlBAY2M/s1600/goat-driven-development.png" border="0" width="251" height="202"&gt;&lt;/a&gt;&lt;br /&gt;Just as Phil did with tinypy, I'm going to use &lt;b&gt;Goat Driven Development&lt;/b&gt;.  Well, I'm not even sure what Goat Driven Development is... so maybe not.&lt;br /&gt;&lt;br /&gt;Another python using dude, Fredrik Lundh, wrote some articles on "&lt;a href="http://effbot.org/zone/simple-top-down-parsing.htm"&gt;Simple Top-Down Parsing in Python&lt;/a&gt;" and &lt;a href="http://effbot.org/zone/tdop-index.htm"&gt;Top-Down Operator Precedence Parsing&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Also see &lt;a href="http://eli.thegreenplace.net/2010/01/02/top-down-operator-precedence-parsing/"&gt;Eli Bendersky's article&lt;/a&gt; on Top Down Operator Precedence.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;So where to begin?&lt;/h3&gt;    After reading those articles a few times... scratching my head 13 times, making 27 hums, a few haaarrrrs, one hrmmmm, and four lalalas...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;blink&gt;light bulb:  A brilliant plan!&lt;/blink&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Eli Bendersky implements a full tokeniser, and parser for simple expressions like "1 + 2 * 4".&lt;br /&gt;&lt;br /&gt;Let's copy this approach, but simplify it even more.  Our first step is to make a tokeniser for a such an expression.  That should be easy right?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;A Token data structure.&lt;/h3&gt;    Uncle Doug Crockford uses this structure for a token.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Produce an array of simple token objects from a string.&lt;br /&gt;// A simple token object contains these members:&lt;br /&gt;//      type: 'name', 'string', 'number', 'operator'&lt;br /&gt;//      value: string or number value of the token&lt;br /&gt;//      from: index of first character of the token&lt;br /&gt;//      to: index of the last character + 1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here's an example token from above:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{"type":"name",&lt;br /&gt;"value":"i_can_has_cheezbrgr",&lt;br /&gt;"from":9,&lt;br /&gt;"to":28}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Writing the tokeniser&lt;/h3&gt;    Often a tokeniser is generated... or written by hand.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://effbot.org/zone/simple-top-down-parsing.htm#introducing-the-algorithm"&gt;Fredrik Lundh&lt;/a&gt; writes a simple tokeniser using a regular expression.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; import re&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; program = "1 + 2"&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; [(number, operator) for number, operator in &lt;br /&gt;...  re.compile("\s*(?:(\d+)|(.))").findall(program)]&lt;br /&gt;[('1', ''), ('', '+'), ('2', '')]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is a valid approach... but regexen blow up minds.  Instead I'm going to write one using a state machine, in a big while loop with lots of ifs and elses.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Our homework&lt;/h3&gt;    Write a tokeniser for simple expressions like "1 + 2 * 4".  Output a list of tokens like the javascript one does... eg.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{"type":"name",&lt;br /&gt;"value":"i_can_has_cheezbrgr",&lt;br /&gt;"from":9,&lt;br /&gt;"to":28}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Until next time...&lt;/h3&gt;Really, I have no idea what I'm doing... but that's never stopped me before!  It's going to be a shit javascript, but it will be &lt;i&gt;&lt;b&gt;our shit javascript&lt;/b&gt;&lt;/i&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-5407577362108984877?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/5407577362108984877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=5407577362108984877' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5407577362108984877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5407577362108984877'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/06/lets-make-shit-javascript-interpreter.html' title='Let&apos;s make a shit JavaScript interpreter!  Part one.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_eJJgehXCsQ4/TCx_WVZ1VSI/AAAAAAAAAH0/osU9dhr4xTs/s72-c/lets-make-a-shit-javascript-interpreter.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7889843634788070399</id><published>2010-06-06T15:29:00.006+01:00</published><updated>2010-06-19T10:38:09.880+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>My javascript reading list over the last few months</title><content type='html'>Over the last few months I've been fairly deep into javascript land.  Both in my full time job, and in most of my coding side projects - I've been mostly doing javascript.  Of course, like most web programmers I've been dabbling in javascript over the years... but never so intensely.  On the way I've been collecting a 'reading list' of videos, articles, books, and projects.&lt;br /&gt;&lt;br /&gt;Here are some of the good links from the last few months.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Crockford on javascript videos:&lt;br /&gt;  &lt;a href="http://www.yuiblog.com/blog/2010/04/08/video-crockonjs-5/?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+YahooUserInterfaceBlog+%28Yahoo%21+User+Interface+Blog%29" target="_blank"&gt;http://www.yuiblog.com/blog/&lt;wbr&gt;2010/04/08/video-crockonjs-5/?&lt;wbr&gt;utm_source=feedburner&amp;amp;utm_&lt;wbr&gt;medium=feed&amp;amp;utm_campaign=Feed%&lt;wbr&gt;3A+YahooUserInterfaceBlog+%&lt;wbr&gt;28Yahoo!+User+Interface+Blog%&lt;wbr&gt;29&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;akihabara arcade:&lt;br /&gt;  &lt;a href="http://www.kesiev.com/akihabara/" target="_blank"&gt;http://www.kesiev.com/&lt;wbr&gt;akihabara/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;canvas &lt;span class="il"&gt;javascript&lt;/span&gt; games:&lt;br /&gt;  &lt;a href="http://www.benjoffe.com/code/" target="_blank"&gt;http://www.benjoffe.com/code/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="il"&gt;javascript&lt;/span&gt; 3d engine:&lt;br /&gt;  &lt;a href="http://github.com/mrdoob/three.js" target="_blank"&gt;http://github.com/mrdoob/&lt;wbr&gt;three.js&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Aves Engine: HTML/&lt;span class="il"&gt;JavaScript&lt;/span&gt; Game Engine (&lt;a href="http://youtube.com/" target="_blank"&gt;youtube.com&lt;/a&gt;)&lt;br /&gt;  &lt;a href="http://www.youtube.com/watch?v=Ol3qQ4CEUTo" target="_blank"&gt;http://www.youtube.com/watch?&lt;wbr&gt;v=Ol3qQ4CEUTo&lt;/a&gt;&lt;br /&gt;   &lt;a href="http://ajaxian.com/archives/aves-game-engine?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+ajaxian+%28Ajaxian+Blog%29" target="_blank"&gt;http://ajaxian.com/archives/&lt;wbr&gt;aves-game-engine?utm_source=&lt;wbr&gt;feedburner&amp;amp;utm_medium=feed&amp;amp;&lt;wbr&gt;utm_campaign=Feed%3A+ajaxian+%&lt;wbr&gt;28Ajaxian+Blog%29&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;css animations and transitions&lt;br /&gt;  &lt;a href="http://webkit.org/blog/130/css-transforms/" target="_blank"&gt;http://webkit.org/blog/130/&lt;wbr&gt;css-transforms/&lt;/a&gt;&lt;br /&gt;   &lt;a href="http://webkit.org/blog/138/css-animation/" target="_blank"&gt;http://webkit.org/blog/138/&lt;wbr&gt;css-animation/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3d video navigation on iphone&lt;br /&gt;  &lt;a href="http://ajaxian.com/archives/iads" target="_blank"&gt;http://ajaxian.com/archives/&lt;wbr&gt;iads&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;apple  web app documentation&lt;br /&gt;  &lt;a href="http://developer.apple.com/safari/library/referencelibrary/GettingStarted/GS_iPhoneWebApp/index.html#//apple_ref/doc/uid/TP40008134" target="_blank"&gt;http://developer.apple.com/&lt;wbr&gt;safari/library/&lt;wbr&gt;referencelibrary/&lt;wbr&gt;GettingStarted/GS_&lt;wbr&gt;iPhoneWebApp/index.html#//&lt;wbr&gt;apple_ref/doc/uid/TP40008134&lt;/a&gt;&lt;br /&gt;   &lt;a href="http://developer.apple.com/safari/library/samplecode/FingerTips/Introduction/Intro.html" target="_blank"&gt;http://developer.apple.com/&lt;wbr&gt;safari/library/samplecode/&lt;wbr&gt;FingerTips/Introduction/Intro.&lt;wbr&gt;html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;apple visual effects guide&lt;br /&gt;  &lt;a href="http://developer.apple.com/safari/library/documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008032" target="_blank"&gt;http://developer.apple.com/&lt;wbr&gt;safari/library/documentation/&lt;wbr&gt;InternetWeb/Conceptual/&lt;wbr&gt;SafariVisualEffectsProgGuide/&lt;wbr&gt;Introduction/Introduction.&lt;wbr&gt;html#//apple_ref/doc/uid/&lt;wbr&gt;TP40008032&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;apple multi touch events&lt;br /&gt;  &lt;a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW22" target="_blank"&gt;http://developer.apple.com/&lt;wbr&gt;safari/library/documentation/&lt;wbr&gt;AppleApplications/Reference/&lt;wbr&gt;SafariWebContent/&lt;wbr&gt;HandlingEvents/HandlingEvents.&lt;wbr&gt;html#//apple_ref/doc/uid/&lt;wbr&gt;TP40006511-SW22&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;android, and APIs&lt;br /&gt;   &lt;a href="http://www.thesearethedroids.com/2009/12/15/creating-android-apps-with-html-css-and-javascript/" target="_blank"&gt;http://www.thesearethedroids.&lt;wbr&gt;com/2009/12/15/creating-&lt;wbr&gt;android-apps-with-html-css-&lt;wbr&gt;and-&lt;span class="il"&gt;javascript&lt;/span&gt;/&lt;/a&gt;&lt;br /&gt;  &lt;a href="http://www.phonegap.com/" target="_blank"&gt;http://www.phonegap.com/&lt;/a&gt;&lt;br /&gt;  &lt;a href="http://developer.android.com/resources/articles/using-webviews.html" target="_blank"&gt;http://developer.android.com/&lt;wbr&gt;resources/articles/using-&lt;wbr&gt;webviews.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Safari on iPhone Graphics, Media, and Visual Effects Coding How-To's:&lt;br /&gt;  &lt;a href="http://developer.apple.com/safari/library/codinghowtos/Mobile/GraphicsMediaAndVisualEffects/index.html" target="_blank"&gt;http://developer.apple.com/&lt;wbr&gt;safari/library/codinghowtos/&lt;wbr&gt;Mobile/&lt;wbr&gt;GraphicsMediaAndVisualEffects/&lt;wbr&gt;index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Preparing Your Web Content for iPad:&lt;br /&gt;  &lt;a href="http://developer.apple.com/safari/library/technotes/tn2010/tn2262.html" target="_blank"&gt;http://developer.apple.com/&lt;wbr&gt;safari/library/technotes/&lt;wbr&gt;tn2010/tn2262.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;gamequery&lt;br /&gt;  &lt;a href="http://gamequery.onaluf.org/" target="_blank"&gt;http://gamequery.onaluf.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="il"&gt;javascript&lt;/span&gt; collision detection&lt;br /&gt;  &lt;a href="http://www.lukewallin.co.uk/?go=engine" target="_blank"&gt;http://www.lukewallin.co.uk/?&lt;wbr&gt;go=engine&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;box2d physics &lt;span class="il"&gt;javascript&lt;/span&gt;:&lt;br /&gt;  &lt;a href="http://box2d-js.sourceforge.net/index2.html" target="_blank"&gt;http://box2d-js.sourceforge.&lt;wbr&gt;net/index2.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;render  engine &lt;span class="il"&gt;javascript&lt;/span&gt; game engine&lt;br /&gt;  &lt;a href="http://www.renderengine.com/" target="_blank"&gt;http://www.renderengine.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;vector maths library&lt;br /&gt;  &lt;a href="http://sylvester.jcoglan.com/" target="_blank"&gt;http://sylvester.jcoglan.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;wii &lt;span class="il"&gt;javascript&lt;/span&gt;&lt;br /&gt;  &lt;a href="http://en.wikipedia.org/wiki/Wii_Opera_SDK" target="_blank"&gt;http://en.wikipedia.org/wiki/&lt;wbr&gt;Wii_Opera_SDK&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;game js, pygame alike.&lt;br /&gt;  &lt;a href="http://code.google.com/p/gamejs/" target="_blank"&gt;http://code.google.com/p/&lt;wbr&gt;gamejs/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;physics:&lt;br /&gt;  &lt;a href="http://www.queness.com/post/3296/8-amazing-javascript-experiments-of-physic-and-gravity-simulation" target="_blank"&gt;http://www.queness.com/post/&lt;wbr&gt;3296/8-amazing-&lt;span class="il"&gt;javascript&lt;/span&gt;-&lt;wbr&gt;experiments-of-physic-and-&lt;wbr&gt;gravity-simulation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;how to detect html5 things:&lt;br /&gt;  &lt;a href="http://diveintohtml5.org/everything.html" target="_blank"&gt;http://diveintohtml5.org/&lt;wbr&gt;everything.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;javascript audio synth&lt;br /&gt;  &lt;a href="http://acko.net/blog/javascript-audio-synthesis-with-html-5" target="_blank"&gt;http://acko.net/blog/&lt;wbr&gt;&lt;span class="il"&gt;javascript&lt;/span&gt;-audio-synthesis-&lt;wbr&gt;with-html-5&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;audio  with js:&lt;br /&gt;  &lt;a href="http://www.phon.ucl.ac.uk/home/mark/audio/play.htm" target="_blank"&gt;http://www.phon.ucl.ac.uk/&lt;wbr&gt;home/mark/audio/play.htm&lt;/a&gt;&lt;br /&gt;      - best one.&lt;br /&gt;  &lt;a href="http://www.javascripter.net/faq/sound/play.htm" target="_blank"&gt;http://www.javascripter.net/&lt;wbr&gt;faq/sound/play.htm&lt;/a&gt;&lt;br /&gt;   &lt;a href="http://simplythebest.net/sounds/sound_guide.html" target="_blank"&gt;http://simplythebest.net/&lt;wbr&gt;sounds/sound_guide.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;using flash from js for sound&lt;br /&gt;  &lt;a href="http://www.schillmania.com/content/projects/soundmanager2/" target="_blank"&gt;http://www.schillmania.com/&lt;wbr&gt;content/projects/&lt;wbr&gt;soundmanager2/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;cross browser css image rotation&lt;br /&gt;  &lt;a href="http://samuli.hakoniemi.net/cross-browser-rotation-transformation-with-css/" target="_blank"&gt;http://samuli.hakoniemi.net/&lt;wbr&gt;cross-browser-rotation-&lt;wbr&gt;transformation-with-css/&lt;/a&gt;&lt;br /&gt;   &lt;a href="http://snook.ca/archives/html_and_css/css-text-rotation" target="_blank"&gt;http://snook.ca/archives/html_&lt;wbr&gt;and_css/css-text-rotation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;open source iphone game:&lt;br /&gt;  &lt;a href="http://ajaxian.com/archives/golingo-a-great-titanium-mobile-web-game-open-sourced-for-you?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+ajaxian+%28Ajaxian+Blog%29" target="_blank"&gt;http://ajaxian.com/archives/&lt;wbr&gt;golingo-a-great-titanium-&lt;wbr&gt;mobile-web-game-open-sourced-&lt;wbr&gt;for-you?utm_source=feedburner&amp;amp;&lt;wbr&gt;utm_medium=feed&amp;amp;utm_campaign=&lt;wbr&gt;Feed%3A+ajaxian+%28Ajaxian+&lt;wbr&gt;Blog%29&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;jsdom.&lt;br /&gt;  &lt;a href="http://github.com/tmpvar/jsdom" target="_blank"&gt;http://github.com/tmpvar/jsdom&lt;/a&gt;&lt;br /&gt;   &lt;a href="http://www.yuiblog.com/blog/2010/05/20/video-insua/?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+YahooUserInterfaceBlog+%28Yahoo%21+User+Interface+Blog%29" target="_blank"&gt;http://www.yuiblog.com/blog/&lt;wbr&gt;2010/05/20/video-insua/?utm_&lt;wbr&gt;source=feedburner&amp;amp;utm_medium=&lt;wbr&gt;feed&amp;amp;utm_campaign=Feed%3A+&lt;wbr&gt;YahooUserInterfaceBlog+%&lt;wbr&gt;28Yahoo!+User+Interface+Blog%&lt;wbr&gt;29&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;a number of interesting projects&lt;br /&gt;  &lt;a href="http://www.bramstein.com/projects/" target="_blank"&gt;http://www.bramstein.com/&lt;wbr&gt;projects/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;image editor&lt;br /&gt;  &lt;a href="http://pixlr.com/" target="_blank"&gt;http://pixlr.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;chrome web development extensions&lt;br /&gt;  &lt;a href="https://chrome.google.com/extensions/featured/web_dev" target="_blank"&gt;https://chrome.google.com/&lt;wbr&gt;extensions/featured/web_dev&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;html5 ipad app&lt;br /&gt;  &lt;a href="http://mir.aculo.us/2010/06/04/making-an-ipad-html5-app-making-it-really-fast/" target="_blank"&gt;http://mir.aculo.us/2010/06/&lt;wbr&gt;04/making-an-ipad-html5-app-&lt;wbr&gt;making-it-really-fast/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;particles&lt;br /&gt;   &lt;a href="http://spielzeugz.de/html5/liquid-particles.html"&gt;http://spielzeugz.de/html5/liquid-particles.html&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7889843634788070399?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7889843634788070399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7889843634788070399' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7889843634788070399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7889843634788070399'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/06/my-javascript-reading-list-over-last.html' title='My javascript reading list over the last few months'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4116195574575028555</id><published>2010-05-14T09:57:00.007+01:00</published><updated>2010-05-14T13:54:59.464+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='templates'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>You are using the wrong #templating system for #html.</title><content type='html'>Use javascript + json + DOM for html templating.&lt;br /&gt;&lt;br /&gt;Front end developers know how to use this technology.  They know this technology very well, so will be way productive.&lt;br /&gt;&lt;br /&gt;No weird new template language to learn and install on every single project.&lt;br /&gt;&lt;br /&gt;No dependency on a rapidly changing server side backend... or database, or 3rd party API required.&lt;br /&gt;&lt;br /&gt;No taking the html, and turning it into &lt;b&gt;[$%%WEIRD TEMPLATE LANG%%$$]&lt;/b&gt; step.  Instead you can use javascript, json and the DOM.&lt;br /&gt;&lt;br /&gt;Being able to use the templating system either via the browser, or via the server side means there is no dependency between the front end and the back end.  Front end developers just need an example json file to work from.  Then the back end developer just needs to create the json file.&lt;br /&gt;&lt;br /&gt;It does mean you are dependent on a DOM+javascript implementation on the server side if you want to do things like server side caching, and supporting Agents(browsers, bots etc) that do not use javascript on the client side.&lt;br /&gt;&lt;br /&gt;Just json files.  Just javascript.  Just the DOM.&lt;br /&gt;&lt;br /&gt;You are (currently) using the wrong templating system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4116195574575028555?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4116195574575028555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4116195574575028555' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4116195574575028555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4116195574575028555'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/05/you-are-using-wrong-templating-system.html' title='You are using the wrong #templating system for #html.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1259458952632859275</id><published>2010-04-14T06:29:00.002+01:00</published><updated>2010-05-13T14:35:40.463+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Validation through html forms.</title><content type='html'>Continuing on from a previous article I wrote earlier in the year... '&lt;a href="http://renesd.blogspot.com/2010/01/using-html-form-as-model.html"&gt;Using a html form as the model&lt;/a&gt;', this post describes using validation.&lt;br /&gt;&lt;br /&gt;With html 5 comes a whole bunch of validation you can use in your forms.  This makes a html form even more useful as a schema than the html 4 forms.  Since you can use types like email, telephone, time, date, and such.  You can also use things like minimum, and maximum length.  As well as the ever useful 'required' field.&lt;br /&gt;&lt;br /&gt;You can read about &lt;a href="http://dev.w3.org/html5/spec/forms.html"&gt;html 5 forms here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1259458952632859275?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1259458952632859275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1259458952632859275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1259458952632859275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1259458952632859275'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/04/validation-through-html-forms.html' title='Validation through html forms.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1704829182472112093</id><published>2010-04-06T16:37:00.005+01:00</published><updated>2010-04-06T16:47:52.392+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='rsi'/><title type='text'>UX, rsi. ctrl+c considered harmful. If not done properly.</title><content type='html'>Ctrl+c, as well as a single handed touchpad move is considered harmful.&lt;br /&gt;&lt;br /&gt;Try and do combinations of keys, mouse moves, and gestures one finger at a time.&lt;br /&gt;&lt;br /&gt;Why?  RSI.  RSI hurts people.&lt;br /&gt;&lt;br /&gt;Please consider people when designing your user interfaces.  Either avoid single handed moves, or warn against them.&lt;br /&gt;&lt;br /&gt;Thanks.&lt;br /&gt;&lt;br /&gt;When using computers, consider resting regularly, stopping when you hurt(and before you hurt).  Also consider using one hand or finger for each action.  So rather than shift+A done with one hand, try doing it with two hands.  Also consider moving your hand away from qwerty middle keys do get a less stretchy press of the shift/ctrl/alt/cmd keys.&lt;br /&gt;&lt;br /&gt;Thanks.&lt;br /&gt;&lt;br /&gt;For more details on RSI, and RSI prevention, please see: &lt;a href="http://www.rsi.deas.harvard.edu/spread.html"&gt;http://www.rsi.deas.harvard.edu/spread.html&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1704829182472112093?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1704829182472112093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1704829182472112093' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1704829182472112093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1704829182472112093'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/04/ux-rsi-ctrlc-considered-harmful-if-not.html' title='UX, rsi. ctrl+c considered harmful. If not done properly.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-798926029183821903</id><published>2010-03-15T21:02:00.001Z</published><updated>2010-03-15T21:02:35.834Z</updated><title type='text'>better search engine</title><content type='html'>&lt;a href="http://duckduckgo.com/"&gt;http://duckduckgo.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-798926029183821903?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://duckduckgo.com/' title='better search engine'/><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/798926029183821903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=798926029183821903' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/798926029183821903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/798926029183821903'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/03/better-search-engine.html' title='better search engine'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7981061079612882083</id><published>2010-03-12T11:28:00.010Z</published><updated>2010-03-13T09:23:58.866Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Memory usage of processes from python?</title><content type='html'>Is there a way to find the memory usage of python processes?&lt;br /&gt;&lt;br /&gt;Trying to find some portable way of doing this.  However, so far I think a new module might be needed...&lt;br /&gt;&lt;br /&gt;I've got linux mostly covered, but maybe you know how with freebsd, OSX, windows(9x-7)?&lt;br /&gt;&lt;br /&gt;So is there something built into python already?  Is there a X-platform third party module already?  Or a module just for one platform available?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;update: here's the linux code I found and cleaned up a bit &lt;a href="http://rene.f0o.com/~rene/stuff/memory_usage.py"&gt;memory_usage.py&lt;/a&gt; if anyone is interested.  bytes_resident = memory_usage.resident().  It reads /proc/PID/status... eg, like "$ cat /proc/PID/status | grep VmRSS" would.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/pympler/"&gt;pympler&lt;/a&gt;: 'Pympler is a development tool to measure, monitor and analyze the memory behavior of Python objects in a running Python application.'&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/psutil/"&gt;psutil&lt;/a&gt;: 'psutil is a module providing an interface for retrieving information on running processes and system utilization (CPU, memory) in a portable way by using Python, implementing many functionalities offered by tools like ps, top and Windows task manager.' &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.aminus.net/wiki/Dowser"&gt;dowser&lt;/a&gt;: 'Dowser is a CherryPy application that displays sparklines of Python object counts, and allows you to trace their referents. This helps you track memory usage and leaks in any Python program, but especially CherryPy sites.'&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jeetworks.org/programs/syrupy"&gt;syrupy&lt;/a&gt;: 'Syrupy is a Python script that regularly takes snapshots of the memory and CPU load of one or more running processes, so as to dynamically build up a profile of their usage of system resources.'&lt;br /&gt;&lt;br /&gt;Some non-pythony memory tools: &lt;a href="http://valgrind.org/info/tools.html"&gt;valgrind memcheck, massif and cachegrind&lt;/a&gt; (linux), &lt;a href="http://developer.apple.com/Mac/library/documentation/Performance/Conceptual/ManagingMemory/Articles/FindingLeaks.html"&gt;MallocDebug&lt;/a&gt; (osx)&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7981061079612882083?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7981061079612882083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7981061079612882083' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7981061079612882083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7981061079612882083'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/03/memory-usage-of-processes-from-python.html' title='Memory usage of processes from python?'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-6783292354278427643</id><published>2010-03-10T08:10:00.005Z</published><updated>2010-03-10T08:21:15.321Z</updated><title type='text'>how I recovered a friends MacOSX drive</title><content type='html'>MacOSX can sometimes corrupt a drive (like most OSen).&lt;br /&gt;&lt;br /&gt;I've seen it happen a few times, in a couple of different ways.  One way is if you interrupt some file transfers.  Like by pressing 'stop' on a big transfer - this can trash your partition table.  You'll likely see vfs errors in your log at this point.  Anyway... linux, ubuntu and 'testdisk' came to the rescue.  testdisk found the partition for me, and wrote it back... luckily it worked and my friend and I did a happy dance. &lt;br /&gt;&lt;br /&gt;The HFS+ partition was saved.&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-6783292354278427643?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/6783292354278427643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=6783292354278427643' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6783292354278427643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6783292354278427643'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/03/how-i-recovered-friends-macosx-drive.html' title='how I recovered a friends MacOSX drive'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-5909724999354296799</id><published>2010-03-07T07:56:00.006Z</published><updated>2010-03-07T09:59:09.825Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='dbus'/><title type='text'>gnome multimedia keys via dbus-python</title><content type='html'>Ever wanted to get your multi media keys to do something other that play multi media?  You could get these key events any number of ways.  One way is through dbus.  Here is an example: &lt;a href="http://rene.f0o.com/%7Erene/stuff/dbus/gnome_multimedia_keys.py"&gt;gnome_multimedia_keys.py&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/%7Erene/stuff/dbus/our_own_mainloop.py"&gt;Here is a version&lt;/a&gt; which does not block your mainloop.  So it's useful for integrating with other libraries (like pygame :)  I made a &lt;a href="http://rene.f0o.com/%7Erene/stuff/dbus/pygame_dbus.py"&gt;dbus with pygame&lt;/a&gt; example too.  &lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-5909724999354296799?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/5909724999354296799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=5909724999354296799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5909724999354296799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5909724999354296799'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/03/gnome-multimedia-keys-via-dbus-python.html' title='gnome multimedia keys via dbus-python'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1262780354261221692</id><published>2010-03-06T12:14:00.014Z</published><updated>2010-03-06T15:02:20.866Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Ideas for Super Surfaces in pygame.</title><content type='html'>pygame already has a sub-surface, which is part of a larger surface.  Sub-surfaces refer to the same pixels as the surface they come from, and share the same Interface as a Surface.   It's good for doing sprite sheets, where you save one file with many smaller images - but then being able to manipulate them as if you loaded the images as smaller separate surfaces.&lt;br /&gt;&lt;br /&gt;However, sometimes we would like to operate on a whole bunch of smaller surfaces stuck together.  This is what I'd like to call a Super Surface - a collection of smaller surfaces which can act as one big surface.  It's a complementary idea to the sub-surface, and intuitively it should be there... but it's not yet.&lt;br /&gt;&lt;br /&gt;Unfortunately it's a lot harder to code a Super Surface compared to a sub-surface. Since a Super Surface would need to have all the surface affecting routines changed to work with it.&lt;br /&gt;&lt;br /&gt;For example, everything in the draw modules would need to be redone. So would all of the surface methods.  So when you draw a line on a super surface, it should affect all of the sub-surfaces.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;How can Super Surfaces be implemented.&lt;/h4&gt;Still trying to think of a simple/clever way of implementing it efficiently, without having to recode all of the drawing/blitting routines.  However, just like how sub-surfaces in pygame can simplify code immensely - so too will Super Surfaces.&lt;br /&gt;&lt;br /&gt;One method, might be to do a rect translation, and then broadcast the translated method calls over the sub surfaces of the Super Surface.  So we translate the rects into the sub-surface coordinate space from the Super Surfaces coordinate space.&lt;br /&gt;&lt;br /&gt;I'm not so sure if we can get a function pointer to a method from within the function pointer itself with the python C API.  This would simplify it, because the translate-and-broadcast functionality could be implemented in one place and reused within all of the various surface affecting routines automatically.  Something to research...&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Common methods for implementing tiling engines.&lt;/h4&gt;Super Surfaces share a lot of the same properties a tiling engine.  So how are tiling engines implemented?&lt;br /&gt;&lt;br /&gt;A common way for tiling engines to work is to have the images being placed in a grid, and for each of the sub-surfaces to be the same size.  So the image at [0][0] in the array is at those coordinates.  This simplifies the implementation, but is not very flexible.  A slightly more complex way to implement it is to have each sub surface have its position stored relative to the super surface.  This complicates the clipping a little, and for speedy use it really requires a spatial hash... like a quadtree.&lt;br /&gt;&lt;br /&gt;So I'm thinking of doing the more free form implementation... probably just a naive implementation to start with... then perhaps a quatree version as an improvement.  It would be better to use a spatial hash more efficient at moving elements - but that could be a third improvement.&lt;br /&gt;&lt;h4&gt;Use cases for Super Surfaces&lt;/h4&gt;Use cases include viewing massive images.  Much graphics hardware has texture size limits, so it is common to combine many smaller textures when drawing larger images.&lt;br /&gt;&lt;br /&gt;Another common use case is for 'tile engines'.  Where tile engines show a larger image made up of many smaller images.&lt;br /&gt;&lt;br /&gt;To allow using different image formats for different parts of an image is another use case.  For example, a piece of the image which is just black only needs a few bytes to represent the image... it does not need 32bits per pixel.  Whereas the part of the image which includes a persons face with 50% transparency will require 32bits per pixel for sure.  This will save memory, and increase speed.  It increases speed, because it is possible less memory bandwidth means faster operations.  Also, less complicated blending - or more optimized blitting can happen (eg, fast 8 bit Run Length Encoding blitters).  This should be possible with no extra effort from the programmer too.&lt;br /&gt;&lt;br /&gt;Finally, by using smaller sub-surfaces it in effect becomes a tiling engine automatically.  Tiling in graphics is used to split operations up easily.  This gives memory, and speed advantages.  By processing a tile at a time - you only need to have those tiles in memory at that time.  It also gives easy parallelism, since the separate tiles are a form of data parallelism (which is the easiest type).  For some hardware, it is possible to use parallelism when the surfaces are kept separate.&lt;br /&gt;&lt;br /&gt;I'm interested in any &lt;a href="https://www.blogger.com/comment.g?blogID=10678074&amp;amp;postID=1262780354261221692"&gt;comments&lt;/a&gt;, especially if you've made a tiling engine like this before?&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1262780354261221692?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1262780354261221692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1262780354261221692' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1262780354261221692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1262780354261221692'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/03/super-surfaces-for-pygame-in-effect.html' title='Ideas for Super Surfaces in pygame.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4541277793467454872</id><published>2010-03-03T08:15:00.002Z</published><updated>2010-03-03T12:57:34.567Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='bzr'/><category scheme='http://www.blogger.com/atom/ns#' term='launchpad'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Why bzr and launchpad?  launchpad is open source</title><content type='html'>Why bzr and launchpad?  Bzr AND Launchpad are open source.&lt;br /&gt;&lt;br /&gt;launchpad: open source&lt;br /&gt;github: closed source&lt;br /&gt;sourceforge: closed source (was open source in the past)&lt;br /&gt;bitbucket: closed source&lt;br /&gt;googlecode: closed source&lt;br /&gt;&lt;br /&gt;You can submit changes to launchpad at: &lt;a href="https://dev.launchpad.net/"&gt;dev.launchpad.net&lt;/a&gt;.  As well as (&lt;a href="https://bugs.launchpad.net/launchpad"&gt;submit launchpad bugs&lt;/a&gt;) and feature requests against it if you don't want to make the patch yourself.&lt;br /&gt;&lt;br /&gt;When there is a good open source alternative, I always choose the good open source option.  I initially had problems with bzr a couple of years ago... but it has been quite good to me over the last couple of months.  So I'm moving over all of my projects from other version control hosting services to launchpad.&lt;br /&gt;&lt;br /&gt;Of course bzr and launchpad are also written in python (with selected optional C optimizations), so that makes for happy hacking :)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;update: &lt;a href="https://bugs.launchpad.net/launchpad/+bug/531323"&gt;reported a bug here&lt;/a&gt; about the 'can not find source code easily on launchpad' issue.  Any other issues with launchpad?&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4541277793467454872?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4541277793467454872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4541277793467454872' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4541277793467454872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4541277793467454872'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/03/why-bzr-and-launchpad-launchpad-is-open.html' title='Why bzr and launchpad?  launchpad is open source'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7540264181854943105</id><published>2010-03-01T18:22:00.002Z</published><updated>2010-03-01T18:24:28.857Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>London code dojo - 4th March '10 18:30 – 21:30 (ish).</title><content type='html'>Details, and booking here: &lt;a href="http://ldnpydojo.eventwax.com/7th-london-python-code-dojo"&gt;http://ldnpydojo.eventwax.com/7th-london-python-code-dojo&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;"""What is a coding dojo? This is a &lt;a href="http://codingdojo.org/"&gt;coding dojo&lt;/a&gt;.    &lt;p&gt;Last time we attempted to refactor the various adventure game solutions from the January dojo. Whilst interesting, perhaps refactoring isn’t &lt;strong&gt;that&lt;/strong&gt; exciting an activity for a dojo :-). Nevertheless, people seemed to be having fun and we did achieve our goal of a “one true” adventure game code base that allows us to define and navigate around a game world. The code can be found here: &lt;a href="http://github.com/ntoll/code-dojo/tree/master/adventure/week2/"&gt;http://github.com/ntoll/code-dojo/tree/master/adventure/week2/&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;After discussion at the end of the February dojo (and later in the pub) we decided that this time round we’re going to try another small-groups based exercise with a “show and tell” at the end as we continue to build the world’s greatest adventure game. Problems we might want to tackle include: a command parser, keeping track of game state/score/objects, NPCs/AI, authoring tools, turning it into a &lt;span class="caps"&gt;MUD&lt;/span&gt; (and so the list goes on…)&lt;/p&gt;    &lt;p&gt;Photos from all the dojos so far can be found here: &lt;a href="http://divvyshot.com/event/IsJtx/"&gt;http://divvyshot.com/event/IsJtx/&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Free pizza and beer will be provided&lt;/strong&gt;.&lt;/p&gt;    &lt;p&gt;Participants get the chance to &lt;strong&gt;win a cool book&lt;/strong&gt; (thanks O’Reilly)."""&lt;/p&gt;&lt;p&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7540264181854943105?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7540264181854943105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7540264181854943105' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7540264181854943105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7540264181854943105'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/03/london-code-dojo-4th-march-10-1830-2130.html' title='London code dojo - 4th March &apos;10 18:30 – 21:30 (ish).'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4552128950900763676</id><published>2010-02-25T16:27:00.008Z</published><updated>2010-02-26T09:17:09.453Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>uh0h, I made a logo.  What do you think?</title><content type='html'>Made a quick little logo for a website called...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img src="http://4.bp.blogspot.com/_eJJgehXCsQ4/S4Vbmdz3wbI/AAAAAAAAAGQ/VTKE5BovaSM/S1600-R/uh0h.png" border="0"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Tried a few different versions... showed my girl friend a few, and stuck with this one in the end.  Made it with a simple DejaVu Sans Mono Bold font.  Ya for the &lt;a href="http://dejavu-fonts.org/"&gt;DejaVu font&lt;/a&gt; project.  Modified the zero(0) a bit, then inverted the colors (ya! negative space). Played around with the letter spacing... applied an old school guassian blur filter to the right side, resized for web... and done!&lt;br /&gt;&lt;br /&gt;What do you think?&lt;br /&gt;&lt;br /&gt;&lt;form action="http://rene.f0o.com/~rene/stuff/is-it-ok/"&gt;&lt;input name="whatreckon" value="shit logo pal" type="submit"&gt;&lt;/form&gt;&lt;form action="http://rene.f0o.com/~rene/stuff/is-it-ok/"&gt;&lt;input name="whatreckon" value="it is ok" type="submit"&gt;&lt;/form&gt;&lt;form action="http://rene.f0o.com/~rene/stuff/is-it-ok/"&gt;&lt;input name="whatreckon" value="awesome" type="submit"&gt;&lt;/form&gt;&lt;form action="http://rene.f0o.com/~rene/stuff/is-it-ok/"&gt;&lt;input name="whatreckon" value="ROBOT" type="submit"&gt;&lt;/form&gt;&lt;br /&gt;&lt;br /&gt;The brief is 'something quick for yet-another-culture blog/zine called uh0h... as in uh oh I dropped a hammer on my foot.'.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;update: Added some results in this image below.  Which is updated with a pygame/freetype script. The idea is that the results in the image can be updated without the rss feed getting updated.  Hoping to clean the script up and add it to pywebsite.  The same technique seems to be used by some wordpress blogs with their 'comments:3' image links - so I think it will be useful for all sorts of things shown on blogs where frequent updates are required without having to update the post.&lt;br /&gt;&lt;img src="http://rene.f0o.com/~rene/stuff/is-it-ok/results.png"&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4552128950900763676?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4552128950900763676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4552128950900763676' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4552128950900763676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4552128950900763676'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/02/uh0h-i-made-logo-what-do-you-think.html' title='uh0h, I made a logo.  What do you think?'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_eJJgehXCsQ4/S4Vbmdz3wbI/AAAAAAAAAGQ/VTKE5BovaSM/s72-Rc/uh0h.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4569110155452135984</id><published>2010-02-24T19:17:00.006Z</published><updated>2010-02-24T19:59:31.680Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>svn merging is easy...</title><content type='html'>Subversion(svn) merging is easy...  iff you are using a modern svn version (1.6.x).  &lt;br /&gt;Here it is in short:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ cd /dir/of/your-branch&lt;br /&gt;$ svn merge ^/trunk&lt;/pre&gt;Where ^/trunk is the url of the branch you want to merge from.  For more details, have a look in the svn book &lt;a href="http://svnbook.red-bean.com/nightly/en/svn.branchmerge.basicmerging.html"&gt;basic merging&lt;/a&gt; section.&lt;br /&gt;&lt;br /&gt;Also this article on &lt;a href="http://www.javaworld.com/javaworld/jw-01-2008/jw-01-svnmerging.html"&gt;svn merging&lt;/a&gt; explains it fairly well.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://subversion.apache.org/docs/release-notes/1.6.html"&gt;svn 1.6 release notes&lt;/a&gt; and &lt;a href="http://subversion.apache.org/docs/release-notes/1.5.html#merge-tracking"&gt;1.5 release notes&lt;/a&gt; also talk about various svn updates including merge enhancements amongst other goodies (like improved python bindings).&lt;br /&gt;&lt;br /&gt;Really, merging is not too bad in subversion now.  I know this post won't stop everyone from using 2004 reasons arguing over version control systems... but what ever.&lt;br /&gt;&lt;br /&gt;Ok, bzr, hg, and git all have lots of nice features - but merging in svn is pretty easy now so please bash(zsh) it for other reasons if you must.&lt;br /&gt;&lt;br /&gt;Now, let's move back to the vi VS emacs argument ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4569110155452135984?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4569110155452135984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4569110155452135984' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4569110155452135984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4569110155452135984'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/02/svn-merging-is-easy.html' title='svn merging is easy...'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4235307140350157448</id><published>2010-02-19T06:14:00.002Z</published><updated>2010-02-19T10:36:47.689Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='joypad'/><title type='text'>The secret to my web development productivity...</title><content type='html'>Can you see the secret to my web development productivity in this photo?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img src="http://rene.f0o.com/%7Erene/stuff/my-secret-to-web-development-productivity.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;No it's not the red cup of coffee.&lt;br /&gt;&lt;br /&gt;It's not the pieces of sticky tape on my laptop.&lt;br /&gt;&lt;br /&gt;Follow the cable from my laptop...&lt;br /&gt;&lt;br /&gt;and have a look under the desk.&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;... I'll wait whilst you have a look before telling you the answer.&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;That's right!!!&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;it's a joypad.&lt;br /&gt;&lt;br /&gt;Using python and pygame, I've made a little app which listens for joystick events, and then deploys the website I'm working on. &lt;br /&gt;&lt;br /&gt;With a mash, kick or prod of my foot, up goes my website.  Deployed.&lt;br /&gt;&lt;br /&gt;Deploy is just a fancy word for 'upload my website, do database migrations, restart app servers, run tests, rollback if there are failures... etc'.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For 5 british pounds, $7.8 USD, or 5.74 euros, you can get one of these joypads delivered to most places these days.&lt;br /&gt;&lt;br /&gt;It's giving me too much pleasure pressing it every time I want to upload a new version of the website.  Most live updates EVER today - and I have the joypad to thank for it.&lt;br /&gt;&lt;br /&gt;The joypad is the secret to my web development productivity.  Please don't tell anyone. &lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;update: here's a slightly cleaned up, and slightly silly version of 'Joy to Deploy'...&lt;br /&gt;&lt;br /&gt;Check out using bzr revision control:&lt;br /&gt;&lt;pre&gt;    bzr co lp:joytodeploy&lt;/pre&gt;Or you can &lt;a href="http://bazaar.launchpad.net/~illume/joytodeploy/trunk/annotate/head%3A/joytodeploy.py"&gt;view joytodeploy.py source code&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;joytodeploy.py deployment_program&lt;br /&gt;&lt;br /&gt;for example:&lt;br /&gt;    joytodeploy.py deploy.sh with great justice&lt;br /&gt;&lt;br /&gt;    joytodeploy.py echo 'ninjas are better than pirates'&lt;/pre&gt;&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4235307140350157448?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4235307140350157448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4235307140350157448' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4235307140350157448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4235307140350157448'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/02/secret-to-my-web-development.html' title='The secret to my web development productivity...'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7315050570792138153</id><published>2010-02-18T14:06:00.005Z</published><updated>2010-02-18T14:32:26.508Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='genshi'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='templates'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Genshi templates - header/footer templates, and including templates.</title><content type='html'>How to include a Genshi template inside of another genshi template?&lt;br /&gt;&lt;br /&gt;Use "py:match" inside the template you want to include into other pages (eg. a sitelayout.html).&lt;br /&gt;&lt;br /&gt;Then you can use "xi:include" in the pages you want the files included in. (eg. best_picture_of_my_cat_today.html)&lt;br /&gt;&lt;br /&gt;Now, it's not a "simple include this template here" kind of thing.  The py:match can find various parts of the file, and then replace them how they like.  For example, a page layout template will match the header and footer with "py:match".&lt;br /&gt;&lt;br /&gt;It is best explained with examples, and in the documentation:&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.pylonshq.com/display/pylonscookbook/Genshi+templates"&gt;pylons genshi example&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://genshi.edgewall.org/wiki/Documentation/xml-templates.html#id10"&gt;Includes section of the genshi documentation&lt;/a&gt; where it explains "xi:include".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Genshi documentation where it explains &lt;a href="http://genshi.edgewall.org/wiki/Documentation/xml-templates.html#id5"&gt;py:match&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;Hopefully this explains the genshi way of including a template into a template.&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7315050570792138153?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7315050570792138153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7315050570792138153' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7315050570792138153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7315050570792138153'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/02/genshi-templates-headerfooter-templates.html' title='Genshi templates - header/footer templates, and including templates.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7227223801907459029</id><published>2010-02-17T08:42:00.007Z</published><updated>2010-02-17T09:43:05.908Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='cherrypy'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>My fling with engine X.</title><content type='html'>Projects that have X in the name are cool.  Engines are cool (especially steam powered ones).  Spelling engine 'ngin' gains 17.5 l33t points too.  All combined, this makes the name &lt;a href="http://nginx.org/"&gt;nginx&lt;/a&gt; super schwet!&lt;br /&gt;&lt;br /&gt;I've been using nginx for a while now, and have found it quite good so far.  Been moving a couple of websites to it, fooling around with it a lot.&lt;br /&gt;&lt;br /&gt;So far I've been able to use it for everything I've tried.  Some of my apache configs are fairly long... so that is saying quite a bit.  On my low memory (512MB) server it has saved quite a bit of memory - even though I've only moved over a couple of websites.  Along with the cherrypy memory reduction work I did recently, my server has a bit more room to breathe... (and for me to waste memory on hosting other websites!  ya!).&lt;br /&gt;&lt;br /&gt;Nginx has a good reputation as being rock solid - so I hope it holds true for me.  Then perhaps I can get rid of apache completely (on this one server).  I've tried to replace apache with other web servers before... but always come up with a reason to move back to apache.  Either some application uses a feature that the other server does not support, or the other server is just not as robust as apache.  I don't like fixing, or looking at servers... I just want them to work without hassle.  I'm not afraid of working, and learning about a new webserver to work... It's just that some webservers are too high maintenance.&lt;br /&gt;&lt;br /&gt;Fastcgi is one way nginx allows you to host php and python websites.  Nginx can also be used as a reverse proxy server.  Personally I like to host python websites with cherrypy and a reverse proxy, and use fastcgi with php.  The nginx proxy_pass configuration seems to work quite well... as does its simple-to-setup load balancing.&lt;br /&gt;&lt;br /&gt;Like all good software, I love to check out how it was made.  Reading the nginx source code is breath of fresh air.  Despite Igor[the main author] being Russian, the code is written in english C(with tiny smatterings of asm/perl)... with very few comments.  It is a modular, and very clean code base.  It doesn't seem to have any unittests... but it's still quality software.&lt;br /&gt;&lt;br /&gt;Our relationship is still a fling really.  Before I invite nginx to meet my parents, I'll give it few more months.  Ok, my love letter to nginx is done now.&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7227223801907459029?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7227223801907459029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7227223801907459029' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7227223801907459029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7227223801907459029'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/02/my-fling-with-engine-x.html' title='My fling with engine X.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-2960097123511915656</id><published>2010-02-04T10:52:00.008Z</published><updated>2010-02-04T15:02:51.588Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ctypes'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pyopengl'/><category scheme='http://www.blogger.com/atom/ns#' term='numpy'/><category scheme='http://www.blogger.com/atom/ns#' term='cython'/><title type='text'>python - unifying c types from different packages.</title><content type='html'>Python already has a number of objects to represent c types.  However, there is a need to improve interoperability between systems using these c types.  Below I explain the need, and discuss existing efforts to address this need.  Then ways to transparently translate between the various type systems without each system needing to know about each other are also discussed.&lt;br /&gt;&lt;br /&gt;In the ctypes library - you can represent an unsigned 32bit integer with ctypes.c_unit32.&lt;br /&gt;&lt;br /&gt;In the array, and struct modules there are different array type codes.  For example, 'L' represents unsigned int with a minimum of 4 bytes on 32bit systems and 8 on 64bit systems.&lt;br /&gt;&lt;br /&gt;numpy, cython, pyopengl and other python extensions have their own types representing c types too.  Most extensions which link up to languages which use static typing represent basic c types to python in some way.&lt;br /&gt;&lt;br /&gt;Not only libraries, but various compilers and translation tools also use c types.  For example tinypyC++, cython, swig, etc.  Also type inference is done from things like shedskin, and rpython - but they represent types internally with their own type objects.&lt;br /&gt;&lt;br /&gt;Standardising on one set of c type objects or string codes would give some compatibility advantages.  However, that will be hard to change for backwards compatibility reasons.  A mapping between the various types should provide plenty of the advantages.  For example, to be able to translate from a ctypes to a numpy type should be fairly simple.&lt;br /&gt;&lt;br /&gt;Here you can see that numpy, ctypes and the python.array module already have integration:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; import numpy, cython, ctypes, OpenGL.GL&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; numpy.array([1,2,3,4.2], ctypes.c_uint32)&lt;br /&gt;array([1, 2, 3, 4], dtype=uint32)&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; numpy.array([1,2,3,4.2], numpy.uint32)&lt;br /&gt;array([1, 2, 3, 4], dtype=uint32)&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; numpy.array([1,2,3,4.2], 'L')&lt;br /&gt;array([1, 2, 3, 4], dtype=uint32)&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; numpy.array([1,2,3,4.2], OpenGL.GL.GLuint)&lt;br /&gt;array([1, 2, 3, 4], dtype=uint32)&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; numpy.array([1,2,3,4.2], cython.uint)&lt;br /&gt;------------------------------------------------------------&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt; File "&lt;ipython console=""&gt;", line 1, in &lt;module&gt;&lt;br /&gt;TypeError: data type not understood&lt;br /&gt;&lt;/module&gt;&lt;/ipython&gt;&lt;/pre&gt;&lt;br /&gt;Pretty cool hey?  Numpy already knows about many of the type variables available in the python ecosystem.  With the notable exception of cython.&lt;br /&gt;&lt;br /&gt;I think there is a need to try and standardise use of c type variables - so that more code can interoperate without each system needing to know about each other systems type objects.  Alternatively a translation layer can be made in place.&lt;br /&gt;&lt;br /&gt;For example an adaptor something like this:&lt;br /&gt;&lt;pre&gt;# this registers two types which are the same.&lt;br /&gt;&gt;&gt;&gt; type_registry.register_types(numpy.uint32, &lt;br /&gt;...                              cython.uint)&lt;br /&gt;&lt;br /&gt;# here numpy.array does not know about cython directly,&lt;br /&gt;#   but can look at the registered type we just did to get it from there.&lt;br /&gt;&gt;&gt;&gt; numpy.array([1,2,3,4.2], cython.uint)&lt;br /&gt;array([1, 2, 3, 4], dtype=uint32)&lt;/pre&gt;&lt;br /&gt;# if numpy does not know about the adaptor registry then we can still&lt;br /&gt;#   use the registry, if only in a more ugly - non transparent way&lt;br /&gt;#   by calling a translate function directly:&lt;br /&gt;&gt;&gt;&gt; numpy.array([1,2,3,4.2],&lt;br /&gt;...             type_registry.translate(cython.uint))&lt;br /&gt;array([1, 2, 3, 4], dtype=uint32)&lt;br /&gt;&lt;br /&gt;Instead of an adaptor, a magic variable could be used which would contain the 'standard c type variable' from python.  For example - cython.uint.__ctype__ == ctype.c_unit32.  Then numpy could look for a __ctype__ variable and use that - without having to be extended for every system that is made.  One problem with a magic variable over registered types is that some python objects can not have those magic variables assigned.  For example, try adding a __ctype__ variable to an int instance - it won't work.&lt;br /&gt;&lt;br /&gt;Either the adaptor, or the magic variable would let cython - and other systems use their own type objects and still have a way to translate the types to the standard python c type variables (when/if they are chosen).&lt;br /&gt;&lt;br /&gt;A simple mapping (with a dict) from a package to the standard c type objects/type codes is another method that could be used.  This will allow a package to fairly easily hook into the eco system.  For example cython could have a __c_type_mappings__ magic variable at the top level of its package.  Then another package looking to translate the type could look to the package for this __c_type_mappings__ variable.  The advantage of this is that many times variables can be injected into a package but not into extension types in the package.  On the other hand this feels icky.&lt;br /&gt;&lt;br /&gt;The c types from the ctype package seem to be a fairly good choice for this.  PyopenGL 3.x series uses the ctypes as its types.  eg, OpenGL.GL.GLuint == ctypes.c_uint32.  Except ctypes is a fairly big dependency just for a few types.  &lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.python.org/dev/peps/pep-3118/"&gt;buffer pep 3118&lt;/a&gt; being introduced into python/numpy to make buffer sharing between libraries is a similar use case.  However it involves sharing instances of differently typed buffers - and has quite clever semantics for many use cases.  The formats from that pep could also probably be used to share type information.&lt;br /&gt;&lt;br /&gt;The buffer protocol pep specifies extra format strings over the ones specified in the python.array module.  So as to be able to specify a more complete set of type, and memory layouts.  So rather than using the ctypes types, it probably makes sense to use the new buffer protocol format codes specified in pep 3118.  As they are just strings without any further dependencies on the rest of the ctypes machinery (eg libffi etc).  Of course, if you are using ctypes already - then depending on it is not a problem.&lt;br /&gt;&lt;br /&gt;Of course ctypes.c_uint32 is more descriptive than 'L' to many people, so the format codes (eg 'L') should just be used for specification.  People should still use their own type objects - but provide a translation to their format codes as specified in &lt;a href="http://www.python.org/dev/peps/pep-3118/"&gt;pep 3118 the new buffer protocol&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The codes specified in pep 3118 will probably need to be expanded as more c types need to be described.  For example bit fields and bit depths of types are not described in the pep.  Many systems specify the bit depth of the type - numpy, ctypes, opengl, etc.  For example they use 'uint32' rather than 'unsigned int'.  Also &lt;a href="http://en.wikipedia.org/wiki/C_syntax#Bit_fields"&gt;bit fields&lt;/a&gt; are becoming more common in C so they should be added to the type code formats in someway too.&lt;br /&gt;&lt;br /&gt;In conclusion there is a need for interoperability of c types from various python extensions, libraries and python compilers.  The pep 3118 format codes, and ctypes types are good candidates to work with for standard c type objects/codes.  Adaptor registries, simple mappings, and/or magic variable names could be used to enhance interoperability.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-2960097123511915656?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/2960097123511915656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2960097123511915656' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2960097123511915656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2960097123511915656'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/02/python-unifying-c-types-from-different.html' title='python - unifying c types from different packages.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1158054071258105523</id><published>2010-01-17T18:15:00.002Z</published><updated>2010-01-17T18:23:54.469Z</updated><title type='text'>good bye Vivienne</title><content type='html'>will miss my little sister. wish we had more time together. so sad. shit&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1158054071258105523?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1158054071258105523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1158054071258105523' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1158054071258105523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1158054071258105523'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/good-bye-vivienne.html' title='good bye Vivienne'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-6457045821411188487</id><published>2010-01-15T10:59:00.003Z</published><updated>2010-01-15T11:17:24.595Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>Jquery 1.4</title><content type='html'>Another quality jquery release... &lt;a href="http://jquery14.com/day-01/jquery-14"&gt;jquery 1.4&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Some very handy changes, my favourite probably being able to use functions to set values.  In short, some of the changes are:&lt;br /&gt;&lt;br /&gt;&lt;li&gt;setting values with functions&lt;/li&gt;&lt;li&gt;html5 form support&lt;/li&gt;&lt;li&gt;better JSON/JSONP and ajax functionality&lt;/li&gt;&lt;li&gt;easier element construction (just pass a dict of attributes)&lt;/li&gt;&lt;li&gt;reverse indexing like in python, where -1 is the last item.&lt;/li&gt;&lt;li&gt;better animation for multiple attributes at once&lt;/li&gt;&lt;li&gt;performance improvements, code cleanups, and bug fixing&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;Full details in the &lt;a href="http://jquery14.com/day-01/jquery-14"&gt;jquery 1.4 release notes&lt;/a&gt;.&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-6457045821411188487?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/6457045821411188487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=6457045821411188487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6457045821411188487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6457045821411188487'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/jquery-14.html' title='Jquery 1.4'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1613347404638663044</id><published>2010-01-13T06:40:00.000Z</published><updated>2010-01-13T06:40:00.135Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='batching'/><category scheme='http://www.blogger.com/atom/ns#' term='threads'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='parallel'/><title type='text'>worker pool optimization - batching apis, for some tasks.</title><content type='html'>&lt;h4&gt;What are worker pools anyway?&lt;/h4&gt;Worker pools are an optimization to the problem of processing many things in parallel.  Rather than have a worker for every item you want to process, you spread the load between the available workers.  As an example, creating 1,000,000 processes to add 1,000,000 numbers together is a bit heavy weight.  You probably want to divide it up between 8 processes for your 8 core machine.  This is the optimization worker pools do.&lt;br /&gt;&lt;br /&gt;With a usual worker pool there is a queue of jobs/data for the workers to work on.  The workers are usually threads, processes or separate machines which do the work passed to them.&lt;br /&gt;&lt;br /&gt;So for 1000 items on that queue, there are around 1000 accesses to that queue.  Usually the queue has to be thread safe or process safe, so that pieces of data are not sent to many workers at once.&lt;br /&gt;&lt;br /&gt;This can be an efficient method to use for some types of data.  For example, if each job can take different amounts of time, like IO tasks over the internet... this is not optimal, but pretty good.&lt;br /&gt;&lt;h4&gt;Problem work loads for typical worker pools.&lt;/h4&gt;Let's assume that the tasks are fairly easy to measure the average(or median if you like) time of each task.  So either not IO tasks, or fairly equal length tasks.  Then the central queue idea starts to fall down for the following reasons.&lt;br /&gt;&lt;br /&gt;What if the cost of starting a new job is quite high?  Like if starting each job happened over a machine with a 200ms network latency (say using a HTTP call to the other side of the planet).  Or if a new process needs to be spawned for each task ( say with exec or fork ).&lt;br /&gt;&lt;br /&gt;Or if the cost of accessing the queue is quite high?  Like if you have a lock on the queue (eg a GIL) and lots of workers.  Then the contention on that lock will be quite high.&lt;br /&gt;&lt;br /&gt;What if there are a lot more items than 1000?  Like if there are 10,000,000 items?  With so many items, it is worth trying to reduce or avoid that cost of accessing the queue all together.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;How to optimize the worker pool for these problems?&lt;/h4&gt;The obvious solution is to divide the items up into chunks first, and then feed those big chunks of work to each worker.  Luckily the obvious solution works quite well!  It's trivial to divide a whole list of things into roughly equal size chunks quite quickly ( a python one liner *1). &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;An example of how to improve your worker pool.&lt;/h4&gt;Here is some example code to transform a pygame.threads.tmap command that uses a worker pool to do its work off a central worker queue, into one that first divides the work into roughly equal parts.  Mentally replace pygame.threads.tmap with your own worker pool map function to get the same effect.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#file: divide_and_map.py&lt;br /&gt;import operator&lt;br /&gt;&lt;br /&gt;# Here's our one liner divider, as two lines.&lt;br /&gt;def divide_it(l, num_parts):&lt;br /&gt;    return [ l[i:i+num_parts] for i in xrange(0, len(l), num_parts)]&lt;br /&gt;&lt;br /&gt;# Here is our_map which transforms a map into &lt;br /&gt;#   one which takes bigger pieces.&lt;br /&gt;def our_map(old_map, f, work_to_do, num_workers):&lt;br /&gt;    bigger_pieces = divide_it(work_to_do, len(work_to_do)//num_workers+1)&lt;br /&gt;    parts = old_map(lambda parts: map(f, parts), bigger_pieces)&lt;br /&gt;    return reduce(operator.add, parts)&lt;br /&gt;&lt;br /&gt;# now an example of how it can speed things up.&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;    import pygame, pygame.threads, time&lt;br /&gt;&lt;br /&gt;    # use 8 worker threads for our worker queue.&lt;br /&gt;    num_workers = 8&lt;br /&gt;    # Use the pygame threaded map function as our &lt;br /&gt;    #    normal worker queue.&lt;br /&gt;    old_map = pygame.threads.tmap&lt;br /&gt;    pygame.threads.init(num_workers)&lt;br /&gt;&lt;br /&gt;    # make up a big list of work to do.&lt;br /&gt;    work_to_do = list(range(100000))&lt;br /&gt;&lt;br /&gt;    # a minimal function to run on all of the items of data.&lt;br /&gt;    f = lambda x:x+1&lt;br /&gt;&lt;br /&gt;    # We time our normal worker queue method.&lt;br /&gt;    t3 = time.time()&lt;br /&gt;    r = pygame.threads.tmap(f, work_to_do)&lt;br /&gt;    t4 = time.time()&lt;br /&gt;&lt;br /&gt;    # We use our new map function to divide the data up first.&lt;br /&gt;    t1 = time.time()&lt;br /&gt;    r = our_map(old_map, f, work_to_do, num_workers)&lt;br /&gt;    t2 = time.time()&lt;br /&gt;    del r&lt;br /&gt;&lt;br /&gt;    print "dividing the work up time:%s:" % (t2-t1)&lt;br /&gt;    print "normal threaded worker queue map time:%s:" % (t4-t3)&lt;br /&gt;&lt;br /&gt;$ python divide_and_map.py &lt;br /&gt;dividing the work up time:0.0565769672394:&lt;br /&gt;normal threaded worker queue map time:6.26608109474:&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For our contrived example we have 100,000 pieces of data to work through.  If you created a thread for each piece of data it would surely take for ever.  Which is why people often use a worker queue.  However a normal worker queue can still be improved apon.  &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Results for this contrived example made to make this technique look good?&lt;/h4&gt;We get a &lt;b&gt;100x speedup&lt;/b&gt; by dividing the work up in this way.  This won't work for all types of data and functions... but for certain cases as mentioned above, it is a great improvement.  Not bad for something that could be written in one line of python!*1&lt;br /&gt;&lt;br /&gt;It's an interesting case of how massaging your data to use &lt;a href="http://renesd.blogspot.com/2007/07/europython-2007-batching-apis-as.html"&gt;Batching API design&lt;/a&gt; techniques gives good results.  It also shows how writing parallel code can be sped up with knowledge of the data you are processing.&lt;br /&gt;&lt;br /&gt;*1 - Well it could be done in one line if we were functional ninjas... but for sane reading it is split up into 12 lines.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1613347404638663044?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1613347404638663044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1613347404638663044' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1613347404638663044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1613347404638663044'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/worker-pool-optimization-batching-apis.html' title='worker pool optimization - batching apis, for some tasks.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7094086859611059474</id><published>2010-01-12T07:34:00.005Z</published><updated>2010-01-12T08:04:26.521Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='language'/><title type='text'>mini languages that non programmers can understand</title><content type='html'>There are hopefully a number of mini text based programming languages that non-programmers can understand.  But what are they?&lt;br /&gt;&lt;br /&gt;One that I've used in the past is something like this:&lt;br /&gt;&lt;input size="90" value="name: Bob gender:male/female, age:22" type="text"&gt;&lt;br /&gt;Which would parse into a python/javascript data structure like this:&lt;br /&gt;&lt;pre&gt;{name: 'Bob',&lt;br /&gt;gender: 'male/female',&lt;br /&gt;age:'22'&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;It's suprisingly common in things like search engines.  Grandmas who occasionally check their email might not get it (but many do I'm sure!)... but I think a lot of others do.  For things like search it is ok, if people know the magic 'terms'.  If they do not know the terms, then they can just enter text to search normally.  The mini language is used by advanced users.&lt;br /&gt;&lt;br /&gt;This is quite good for single line free form data entry.  Since people only need to know the concept that you have 'key:value'.  It's slightly easier than using urls, since separators can be different things.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;csv files&lt;/h4&gt;&lt;br /&gt;Next up are comma separated files - csv.&lt;br /&gt;For example:&lt;br /&gt;&lt;pre&gt;name,gender,age&lt;br /&gt;Bob,female,22&lt;/pre&gt;These are like spread sheets.  Many people seem to be able to edit these quite fine.  Especially if they have a spread sheet program to do the editing.&lt;br /&gt;&lt;h4&gt;URLS&lt;/h4&gt;URLs are a mini language.  With things like # anchors, query strings, and even paths being used by people all the time.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;?name=Bob&amp;amp;age=22&amp;amp;gender=female&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;ini files&lt;/h4&gt;Common as configuration files.&lt;br /&gt;&lt;pre&gt;[heading]&lt;br /&gt;key=value&lt;/pre&gt;&lt;h4&gt;subsitution templates&lt;/h4&gt;Common for web sites, and email systems.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Hi ${name},&lt;br /&gt;&lt;br /&gt;${age} ${gender}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;basic html and other mark up languages&lt;/h4&gt;Quite a lot of people know bits of html. 'How do I do a new line?  oh, that's right:  brrrrrrrr.'&lt;br /&gt;&lt;br /&gt;However, I think that html is on the edge of too complicated.  Modern html is especially complicated.&lt;br /&gt;&lt;br /&gt;Things like markdown, bbcode, and wiki languages all fall into this category.  The languages can sometimes have only 5-10 elements - which make them easy to learn the basics.&lt;br /&gt;&lt;br /&gt;Older Wiki language text could look just like text someone would write in notepad.  However modern ones - like html - now have all sorts of ${}[]==++ characters with special meanings.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Are there any other mini languages which are easy to understand for non-programmers?&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" width="32" height="24" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7094086859611059474?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7094086859611059474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7094086859611059474' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7094086859611059474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7094086859611059474'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/mini-languages-that-non-programmers-can.html' title='mini languages that non programmers can understand'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-9143736244813481943</id><published>2010-01-10T13:06:00.008Z</published><updated>2010-01-11T13:10:09.062Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pypy'/><title type='text'>pypy svn jit cheat sheet.</title><content type='html'>A quick cheat sheet for trying out pypy jit.  This is for a ubuntu/debian 32bit machine translating the jit version of pypy-c.&lt;br /&gt;&lt;pre&gt;# install dependencies for debian/ubuntu.&lt;br /&gt;sudo apt-get install python-dev libz-dev libbz2-dev libncurses-dev libexpat1-dev libssl-dev libgc-dev libffi-dev&lt;br /&gt;&lt;br /&gt;# download from svn.&lt;br /&gt;svn co http://codespeak.net/svn/pypy/trunk pypy-trunk&lt;br /&gt;&lt;br /&gt;# Translate/compile the jit.  This part can take a while.&lt;br /&gt;#   Don't worry. Relax have a home brew.&lt;br /&gt;cd pypy-trunk/pypy/translator/goal&lt;br /&gt;./translate.py -Ojit targetpypystandalone.py&lt;br /&gt;&lt;br /&gt;# Or for the low memory pypy-c use this translate instead...&lt;br /&gt;#./translate.py --gcremovetypeptr targetpypystandalone --objspace-std-withsharingdict&lt;br /&gt;&lt;/pre&gt;The pypy &lt;a href="http://codespeak.net/pypy/dist/pypy/doc/getting-started.html"&gt;getting started&lt;/a&gt; documentation has more about it if you're interested.&lt;br /&gt;&lt;br /&gt;pypy has most standard modules up to python2.5... and some from newer versions.&lt;br /&gt;&lt;br /&gt;I didn't need any external compiled extension modules... just sqlite, and cherrypy.  So for this project I could use pypy!  *happy dance*&lt;br /&gt;&lt;br /&gt;Didn't take long to port my code to it.  I only had a couple of issues, which people in the &lt;a href="irc://irc.freenode.net/pypy/"&gt;#pypy&lt;/a&gt; channel on freenode helped me with.&lt;br /&gt;&lt;br /&gt;There is an alpha version of the sqlite3 which uses ctypes included with pypy as the 'pysqlite2' module.  Seemed to work well enough for me, and passed all my tests.&lt;br /&gt;&lt;pre&gt;import sqlite3&lt;br /&gt;# for pypy, since the sqlite3 package is empty... but they have a pysqlite2.&lt;br /&gt;if not hasattr(sqlite3, "register_converter"):&lt;br /&gt;from pysqlite2 import dbapi2 as sqlite3&lt;/pre&gt;Another issue I had, was I was using 'x is not y' to compare two integers in one function.   In cpython they use a hack so that the first 100 numbers or so share the same identity.  Since the numbers were always less than 100, this code was working fine in cpython.  However, pypy doesn't have that problem/feature - so I just used the != instead.&lt;br /&gt;&lt;br /&gt;I think those were the only two things I had to change.  All my tests were passing, and it was the end of the day, so I went down the pub to see a friend visiting from Tokyo who was having a birthday.&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" width="32" height="24" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-9143736244813481943?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/9143736244813481943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=9143736244813481943' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/9143736244813481943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/9143736244813481943'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/pypy-svn-jit-cheat-sheet.html' title='pypy svn jit cheat sheet.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-8530429530208897738</id><published>2010-01-08T11:58:00.014Z</published><updated>2010-01-09T18:38:53.674Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='unladenswallow'/><title type='text'>Unladen swallow review.  Still needs work.</title><content type='html'>Tried out unladen swallow on two work loads today.  After the announcement they are going to try and bring it into core.  So I finally got around to trying it (last time the build failed).  An hour or so later, the build finally finished and I could try it out.  The C++ llvm takes ages to compile, which is what took most of the extra time.  What follows is a review of unladen swallow - as it stands today.&lt;br /&gt;&lt;br /&gt;The good part?  Extensions work(mostly)!  w00t.  I could compile the C extension pygame, and run things with it.&lt;br /&gt;&lt;br /&gt;Now to run code I care about, my work loads - to see if their numbers hold true for me.&lt;br /&gt;&lt;pre&gt;cherrypy webserver benchmark: crash&lt;br /&gt;pygame tests: some crashes, mostly work.&lt;br /&gt;pygame.examples.testsprite : random pauses in the animation.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The crashes I've found so far seem to be thread related I guess.  The cherrypy one, and some of the pygame ones both use threads, so I'm guessing that's it.&lt;br /&gt;&lt;br /&gt;Random pauses for applications is a big FAIL.  Animations fail to work, and user interactions pause or stutter.  Web requests can take longer for unknown reasons etc.  I'm not sure what causes the pauses, but they be there(arrrr, pirate noise).&lt;br /&gt;&lt;br /&gt;LLVM is a big, fast moving dependency written with another language, and a whole other runtime (C++).  Unladen swallow uses a bundled version of it, since they often need the latest... and they need the latest fixes to it.  This might make it difficult for OS packagers.  Or LLVM might stabalise soon, and it could be a non-issue.  Depending on C++ is a &lt;a href="http://bigissue.com/"&gt;big issue&lt;/a&gt; for some people.  Since some applications and environments can not use C++.&lt;br /&gt;&lt;br /&gt;The speed of unladen swallow?  Slower than normal python for *my* benchmarks.  Well, I couldn't benchmark some things because they crash with unladen... so eh.  I might be able to track these problems down, but I just can't see the benefit so far.  My programs I've tried do not go faster, so I'm not going to bother.&lt;br /&gt;&lt;br /&gt;Python 3 seems to be 80% of the speed for IO type programs like web  servers (cherrypy) (&lt;a href="http://renesd.blogspot.com/2009/12/python32svn-python27svn-and-new-gil.html"&gt;see benchmarks in my previous post&lt;/a&gt;).  However unladen-swallow only seems to be 10-20% slower for pygame games, but the random pauses make it unusable.&lt;br /&gt;&lt;br /&gt;Python2.x + psyco are way faster still on both these work loads.  20%-100% faster than python2.6 alone.  Psyco, and stackless are both still being developed, and both seem to be giving better results than unladen swallow.  Using selective optimisation with tools like shedskin, tinypyC++, rpython, cython will give you 20x speedups.  So for many, writing code in a subset of python to get the speedups is worth it.  Other people will be happy to write the 1% of their program that needs the speed in C.  This is the good thing about unladen swallow... you should be able to keep using any C/C++/fortran extensions.&lt;br /&gt;&lt;br /&gt;Unladen-swallow has a google reality distortion bubble around it.  They only benchmark programs they care about, and others are ignored.  There are other peoples reports of their programs going slower, or not faster.  However the response seems to be 'that is not our goal'.  This is fine for them, as they are doing the work, and they want their own work loads to go faster.  However, I'm not sure if ignoring the rest of the python communities work loads is a good idea if they are considering moving it into trunk.&lt;br /&gt;&lt;br /&gt;It's too early to declare unladen-swallow done, and good imho.  I also think better research needs to go into it before declaring it an overall win at all.  Outside review should be done to see if it actually makes things quicker/better for people.  For my workloads, and for other peoples workloads it is worse.  It also adds dependencies to C++ libraries - which is a nono for some python uses.  Extra dependencies also increase the startup time.  Startup time with unladen swallow is 33% slower compared to python for me (time python -c "import time"). &lt;br /&gt;&lt;br /&gt;Let's look at one of their benchmarks - html5lib.  See the issue &lt;a href="http://code.google.com/p/unladen-swallow/issues/detail?id=105#c11"&gt;  &lt;span class="h3"&gt;html5lib no quicker or slower than CPython&lt;/span&gt;  &lt;/a&gt;.  They arranged the benchmark so unladen-swallow is run 10 times, to allow unladen swallow to warm up.  Since Cpython is faster the first time through.&lt;br /&gt;&lt;img src="http://chart.apis.google.com/chart?cht=lc&amp;amp;chs=350x200&amp;amp;chxt=x,y&amp;amp;chxr=1,13.84,19.89&amp;amp;chco=FF0000,0000FF&amp;amp;chdl=/opt/local/bin/python2.6%7C../hg/fc-obj-rel/python.exe&amp;amp;chds=13.84,19.89&amp;amp;chd=t:16.1,16.35,16.36,16.29,16.25,16.44,16.44,16.34,16.36,16.3%7C18.89,16.22,15.31,15.38,15.05,15.36,15.21,14.84,14.98,15.15&amp;amp;chxl=0:%7C1%7C2%7C4%7C6%7C8%7C10" /&gt;&lt;br&gt;&lt;i&gt;blue - unladen-swallow,  red - cpython 2.6. Time(y) for 10 runs(x).&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Notice, how jumpy the performance is of unladen on the other runs?  This might be related to the random pauses unladen swallow has.  I don't like this style of benchmark which does not account for the first run.  Many times you only want to run code on a set of data once.&lt;br /&gt;&lt;br /&gt;When looking at their benchmark numbers, consider how they structure their benchmarks.  &lt;b&gt;It's always good to try benchmarking on your own workloads&lt;/b&gt;, rather than believing benchmarks from vendors.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Memory usage is higher with unladen swallow&lt;/b&gt;.  It takes around two times as much memory just to start the interpreter.  The extra C++ memory management libraries, the extra set of byte code, and then extra machine code for everything has its toll.  Memory usage is very important for servers, and for embedded systems.  It is also important for most other types of programs.  The main bottleneck is not the cpu, but memory, disk, and other IO.  So they are trading better cpu speed (theoretically) for worse memory.  However since memory is often the bottleneck - and not the cpu, the runtimes will often be slower for lots of work loads.&lt;br /&gt;&lt;br /&gt;It seems python2.6 will still be faster than unladen swallow for many peoples work loads.  If they do not get other peoples programs and workloads working faster, or working at all, it will not be a carrot.  As peoples programs work, and go faster with python2.6/2.7 it will be a stick*.&lt;br /&gt;&lt;br /&gt;Unladen swallow has not (yet) got to it's 5x faster goal, and for many work loads it is still slower or the same speed.  For these reasons, I think it's too early to think about incorporating unladen swallow into python.&lt;br /&gt;&lt;br /&gt;* (ps... ok, that made no sense, sorry.  Sticks and carrots?!?... donkeys like carrots, but so do ponies.  I don't think we should hit people with sticks.  Also people don't like carrots as much as perhaps chocolate or beer.  Perhaps all this time hitting people with sticks and trying to get them to do things with carrots is the problem.  Python 3 has heaps of cool things in it already... but more cool things always helps!  Beer and chocolate would probably work best.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-8530429530208897738?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/8530429530208897738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=8530429530208897738' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8530429530208897738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8530429530208897738'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/unladen-swallow-review-still-needs-work.html' title='Unladen swallow review.  Still needs work.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7174511350795139940</id><published>2010-01-07T06:31:00.001Z</published><updated>2010-01-07T06:31:00.031Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='pywebsite'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Using a html form as the model.</title><content type='html'>I've mentioned this technique before, but I think it is worth repeating more clearly.  Without any other code clouding the main message: '&lt;i&gt;All you need is &lt;strike&gt;love&lt;/strike&gt; html&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;A HTML form can describe a model of your data quite well.  This lets you go from HTML form design to a working Create Read Update Delete (CRUD) system.  A CRUD can be thought of as a nice admin interface to edit your data (or a CMS if you prefer that acronym).&lt;br /&gt;&lt;br /&gt;For example: &lt;pre&gt;&amp;lt;form action='savepage' method='post'&amp;gt;&lt;br /&gt;title:&amp;lt;input type='text' name='title'&amp;gt;&lt;br /&gt;&amp;lt;br&amp;gt;textarea:&lt;br /&gt;&amp;lt;textarea name='content'&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;&amp;lt;input type='submit' name='submit'&amp;gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/pre&gt;That's all you need to create a CRUD.  Things like validation can be defined in the html easily enough then implemented in your code to be checked server side, and client side.  Parse the form to get the model, and go from there.&lt;br /&gt;&lt;br /&gt;The benefits are simplicity, and that designers can make a form, and then pretty quickly go to a working system.  No need to edit sql, java, php, python, etc - just normal html forms.&lt;br /&gt;&lt;br /&gt;Another benefit is more Rapid Application Design (RAD).  From the html design you can quickly move to a working app.  Especially in a work flow where the designers and clients mock up various forms - this is quicker.  It also stops blockages in the production pipeline. Blockages that happen when waiting for a python/php/java programmer to implement the model.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7174511350795139940?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7174511350795139940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7174511350795139940' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7174511350795139940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7174511350795139940'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/using-html-form-as-model.html' title='Using a html form as the model.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7645408978962964375</id><published>2010-01-07T01:48:00.006Z</published><updated>2010-01-07T01:57:29.467Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='cherrypy'/><category scheme='http://www.blogger.com/atom/ns#' term='pywebsite'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Multiple file uploads with html 5, cherrypy 3.2 and firefox 3.6beta5.</title><content type='html'>Here's an example for uploading multiple files with HTML 5 and newer browsers, like the firefox 3.6 beta5.  You can shift/ctrl select multiple files, and even drag and drop them in.  Makes for a much nicer user experience uploading files - rather than having to select one at a time, or having to load some java/flash thing.&lt;br /&gt;&lt;br /&gt;It uses the unreleased cherrypy 3.2, with it's new request entity parsing tool hooks.  See &lt;a href="http://www.cherrypy.org/wiki/RequestBodies"&gt;http://www.cherrypy.org/wiki/RequestBodies&lt;/a&gt; for details about the new control allowed over the whole process.  It's a lot easier to make custom request entity parsing behaviour now, and in a much less hacky way than before.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/%7Erene/stuff/cherry_multi_fileupload.tar.gz"&gt;http://rene.f0o.com/~rene/stuff/cherry_multi_fileupload.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;With the tool in there, files come in as a list of files instead.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7645408978962964375?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7645408978962964375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7645408978962964375' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7645408978962964375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7645408978962964375'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/multiple-file-uploads-with-cherrypy-32.html' title='Multiple file uploads with html 5, cherrypy 3.2 and firefox 3.6beta5.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-6626285407632099697</id><published>2010-01-06T06:42:00.002Z</published><updated>2010-01-06T18:24:20.492Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='nostalgia'/><title type='text'>Oldest python file in your home directory?</title><content type='html'>Feeling just a little nostalgic this time of year.&lt;br /&gt;&lt;br /&gt;Just made a little script to find the oldest python files on your hard drive.&lt;br /&gt;&lt;a href="http://rene.f0o.com/%7Erene/stuff/oldest_python.py"&gt;http://rene.f0o.com/~rene/stuff/oldest_python.py&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;oldest_python.py [path]&lt;br /&gt;oldest_python.py mystuff/python&lt;br /&gt;oldest_python.py&lt;br /&gt;oldest_python.py ~&lt;br /&gt;&lt;/pre&gt;&lt;i&gt;Update: Lennart mentions a unixy way in the &lt;a href="https://www.blogger.com/comment.g?blogID=10678074&amp;postID=6626285407632099697"&gt;comments&lt;/a&gt; of finding oldest files with this: &lt;pre&gt;find . -name '*.py' -printf "%T+ %p \n" | sort | more&lt;/pre&gt;&lt;/i&gt;&lt;br /&gt;With that I found some really old python files of mine... woh!  the oldest ones dated in &lt;b&gt;1998&lt;/b&gt;.  There are older C, C++, haskel, javascript, java, pascal, prolog, asm, sql, perl, etc, etc and heaps of other old junk files, but those are the first ones I could find written in python.&lt;br /&gt;&lt;br /&gt;I guess that means &lt;b&gt;I've been programming python for around 12 years now&lt;/b&gt;.  Python was at version 1.4 or so, and 1.5 was released not long after.  New style objects did not exist, and it was not all too uncommon to be able to segfault the interpreter (ping could easily crash linux &amp;amp; windows in those days, so python was doing pretty good).&lt;br /&gt;&lt;br /&gt;So what did some of the older python files do? &lt;br /&gt;&lt;br /&gt;Cut up writing was the oldest tool I found.  Cutup writing was a technique used a lot in the 90s (before then and to this day as well).  The idea is that you cutup various pieces of writing, and move the pieces around to get ideas.&lt;br /&gt;&lt;br /&gt;After that came a script to randomly ping different web hosts (by http) every few minutes.  In 1998 it was common for ISPs to disconnect you from your modem if you were idle for a while.  So this script seems to ping one of a random selection of hosts and then go back to sleep.  I remember this being the first thing I wrote in python.  It took me less than an hour to learn enough python do this little script.  That one hour probably saved me $300/year or so in telephone bills.&lt;br /&gt;&lt;br /&gt;After that there is a script to convert all file names to lower case.  Useful for bringing the contents of FAT drives onto a linux box.&lt;br /&gt;&lt;br /&gt;Then there was some thread testing code.  Threads these days are way better, with lots better tools, better implementations, and more known about how to use them appropriately.  Using threads in those days for IO was pretty crazy... but apache used processes!  Python had a wicked set of async IO servers in its toolbox.  Which were pretty darn cool in the day.&lt;br /&gt;&lt;br /&gt;Finally there were some mp3 making tools - to convert my massive collection of CDs.  This was when some machines could barely play mp3s without crackling.  Seems my tool would use various linux tools to make my job easier.  Rip cds, get their names, convert them to mp3s.  Using some old scsi drives I could go about my business without my machine slowing down completely and becoming unusable.&lt;br /&gt;&lt;br /&gt;What are your oldest python files?   &lt;a href="http://rene.f0o.com/%7Erene/stuff/oldest_python.py"&gt;http://rene.f0o.com/~rene/stuff/oldest_python.py&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-6626285407632099697?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/6626285407632099697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=6626285407632099697' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6626285407632099697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6626285407632099697'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/oldest-python-file-in-your-home.html' title='Oldest python file in your home directory?'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-2221868822747539776</id><published>2010-01-05T16:10:00.007Z</published><updated>2010-01-05T16:17:35.320Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='london'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Fifth London code dojo 6.30pm Thursday 7th of Jan.</title><content type='html'>Here's the &lt;a href="http://www.google.com/calendar/embed?src=ZTdydWJpbWdjcHViNDhwY3JscmZ2ZWhldnNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ"&gt;london dojo google calendar&lt;/a&gt; for much of 2010.&lt;br /&gt;&lt;br /&gt;More details, and signup here: &lt;a href="http://ldnpydojo.eventwax.com/5th-london-python-code-dojo/"&gt;http://ldnpydojo.eventwax.com/5th-london-python-code-dojo/&lt;/a&gt;.  The idea is to practice, learn and teach python skills.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-2221868822747539776?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/2221868822747539776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2221868822747539776' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2221868822747539776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2221868822747539776'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2010/01/fifth-london-code-dojo-630pm-thursday.html' title='Fifth London code dojo 6.30pm Thursday 7th of Jan.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3079305133782539228</id><published>2009-12-25T10:52:00.013Z</published><updated>2010-06-28T17:12:10.336+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python3'/><category scheme='http://www.blogger.com/atom/ns#' term='cherrypy'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>python3.2(svn) python2.7(svn) and the new GIL, cherrypy as a test.</title><content type='html'>I've done some quick benchmarks for the unreleased python3.2 on the unreleased cherrypy webserver for python 3.  Also with the unreleased python2.7.&lt;br /&gt;&lt;br /&gt;Here are the results...&lt;br /&gt;&lt;h4&gt;python3.1&lt;/h4&gt;&lt;pre&gt;Client Thread Report (1000 requests, 14 byte response body, 10 server threads):&lt;br /&gt;&lt;br /&gt;threads | Completed | Failed | req/sec | msec/req | KB/sec |&lt;br /&gt;   25 |    1000.0 |    0.0 |  533.32 |    1.875 |  93.75 |&lt;br /&gt;   50 |    1000.0 |    0.0 |  525.86 |    1.902 |  92.69 |&lt;br /&gt;  100 |    1000.0 |    0.0 |  522.96 |    1.912 |   92.1 |&lt;br /&gt;  200 |    1000.0 |    0.0 |  523.83 |    1.909 |  92.25 |&lt;br /&gt;  400 |    1000.0 |    0.0 |  506.92 |    1.973 |  89.27 |&lt;br /&gt;Average |    1000.0 |    0.0 | 522.578 |   1.9142 | 92.012 |&lt;br /&gt;&lt;/pre&gt;&lt;h4&gt;python3.2&lt;/h4&gt;&lt;pre&gt;Client Thread Report (1000 requests, 14 byte response body, 10 server threads):&lt;br /&gt;&lt;br /&gt;threads | Completed | Failed | req/sec | msec/req | KB/sec |&lt;br /&gt;   25 |    1000.0 |    0.0 |  555.72 |    1.799 |  97.78 |&lt;br /&gt;   50 |    1000.0 |    0.0 |  558.86 |    1.789 |  98.52 |&lt;br /&gt;  100 |    1000.0 |    0.0 |  552.87 |    1.809 |  97.45 |&lt;br /&gt;  200 |    1000.0 |    0.0 |  546.09 |    1.831 |  96.27 |&lt;br /&gt;  400 |    1000.0 |    0.0 |  548.64 |    1.823 |  96.53 |&lt;br /&gt;Average |    1000.0 |    0.0 | 552.436 |   1.8102 |  97.31 |&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So here you can see a small improvement in the 400 threads version with the new GIL in python3.2.&lt;br /&gt;&lt;br /&gt;Python 3.2 threads seem more scalable in this benchmark compared to python 3.1.  Also faster overall (20-40 requests per second faster).&lt;br /&gt;&lt;h4&gt;python2.6&lt;/h4&gt;Python2.6 still beats python3.2 for cherrypy benchmarks.  These are a network IO heavy, string processing heavy, with big python thread thread usage.  So an ok benchmark for the new GIL work in my opinion.&lt;br /&gt;&lt;br /&gt;Note that both python3.2, and cherrypy for python 3 are not released.&lt;br /&gt;&lt;pre&gt;Client Thread Report (1000 requests, 14 byte response body, 10 server threads):&lt;br /&gt;&lt;br /&gt;threads | Completed | Failed | req/sec | msec/req |  KB/sec |&lt;br /&gt;   25 |    1000.0 |    0.0 |  660.54 |    1.514 |  116.43 |&lt;br /&gt;   50 |    1000.0 |    0.0 |  671.01 |     1.49 |  118.28 |&lt;br /&gt;  100 |    1000.0 |    0.0 |  663.84 |    1.506 |  117.12 |&lt;br /&gt;  200 |    1000.0 |    0.0 |  664.85 |    1.504 |  117.19 |&lt;br /&gt;  400 |    1000.0 |    0.0 |   651.9 |    1.534 |   114.8 |&lt;br /&gt;Average |    1000.0 |    0.0 | 662.428 |   1.5096 | 116.764 |&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;python2.7&lt;/h4&gt;Python2.7 is faster still.&lt;br /&gt;&lt;pre&gt;Client Thread Report (1000 requests, 14 byte response body, 10 server threads):&lt;br /&gt;&lt;br /&gt;threads | Completed | Failed | req/sec | msec/req | KB/sec |&lt;br /&gt;    25 |    1000.0 |    0.0 |  695.33 |    1.438 | 122.79 |&lt;br /&gt;    50 |    1000.0 |    0.0 |   684.6 |    1.461 | 121.12 |&lt;br /&gt;   100 |    1000.0 |    0.0 |  688.99 |    1.451 | 121.67 |&lt;br /&gt;   200 |    1000.0 |    0.0 |  682.94 |    1.464 | 120.49 |&lt;br /&gt;   400 |    1000.0 |    0.0 |  641.01 |     1.56 | 112.78 |&lt;br /&gt;Average |    1000.0 |    0.0 | 678.574 |   1.4748 | 119.77 |&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It's also worth noting that 100-120%(out of 200%) of the two cores cpus are during the run of each version of python tested.  Even though the GIL is released for many parts with python and cherrypy, and even though the benchmark is very IO heavy, both cores are not loaded.  It's generally a good thing for a webserver to not load up the CPUs - but in a benchmark you want them to go full speed.&lt;br /&gt;&lt;br /&gt;Also, during the tests the benchmarking tool 'ab' is run on the same machine skewing results.  However ab seems to only use 1% of the CPU during the tests (according to top).&lt;br /&gt;&lt;br /&gt;1.6ghz core 2 duo, ubuntu (save the) karmic koala 32bit version.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Shrinking the stack to save some memory.&lt;/h3&gt;&lt;br /&gt;So how do we reduce the memory usage of threaded programs?  Reducing the stack size is one idea.  Since threads do not share a stack with each other, each thread takes up a nice big stack.  On ubuntu karmic koala it seems to default to 8MB or so.&lt;br /&gt;&lt;br /&gt;Note, this is dangerous and can segfault your interpreter if you do not have enough stack space for some operations.  So make sure you test things well before doing this.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In 2.6 you do:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;import thread&lt;br /&gt;thread.stack_size(32768*2)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Whereas in python 3.x you do:&lt;br /&gt;&lt;pre&gt;import threading&lt;br /&gt;threading.stack_size(32768)&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;3.2&lt;br /&gt;----&lt;br /&gt;(default stack)  * 110MB virt, 10MB resident&lt;br /&gt;(adjusted stack) *  15MB virt, 10MB resident&lt;br /&gt;&lt;br /&gt;2.6&lt;br /&gt;----&lt;br /&gt;(default stack)  * 107MB virt, 8MB resident&lt;br /&gt;(adjusted stack) * 12MB virt, 8MB resident&lt;/pre&gt;&lt;br /&gt;Note, the python3.x versions start using up 2 gigabytes of memory in the benchmark.  Compared to a peak of 600MB or so with python2.6.  Showing some sort of memory leak in either python or cherrypy (note, both are pre-release).&lt;br /&gt;&lt;br /&gt;It seems python3.2 worked with a smaller stack compared to python2.6.  python2.6 segfaulted with 32768, but worked with a stack sized 32768*2.  However python3.x used more resident memory, and virtual memory.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;update:&lt;br /&gt;I've uploaded profile(python cProfile), results and scripts here: &lt;a href="http://rene.f0o.com/%7Erene/stuff/cherrypy_benchmarks"&gt;http://rene.f0o.com/~rene/stuff/cherrypy_benchmarks&lt;/a&gt;.  Strangely using python2.7 with the benchmark and cProfile did not finish (well it was still going 30 minutes later). So I guess that is a bug somewhere.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" border="0" width="32" height="24" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3079305133782539228?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3079305133782539228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3079305133782539228' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3079305133782539228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3079305133782539228'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/python32svn-python27svn-and-new-gil.html' title='python3.2(svn) python2.7(svn) and the new GIL, cherrypy as a test.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-2634520809022548830</id><published>2009-12-23T11:33:00.002Z</published><updated>2009-12-23T11:35:55.876Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Invent with python - a new pygame/python book.</title><content type='html'>&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://inventwithpython.com/images/cover_thumb.png" width="200" height="259"&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;a href="http://inventwithpython.com/"&gt;Invent with python&lt;/a&gt; 'Teach yourself how to program by making computer games!' is a free book now in its second edition.  It is released under the creative commons licence &lt;i&gt;Attribution-Noncommercial-Share Alike 3.0 United States&lt;/i&gt; - and the author just asks for a donation if you liked reading it.&lt;br /&gt;&lt;br /&gt;The book takes the fun approach of teaching programming through making games... the way many of us learnt(and are still learning) to program.&lt;br /&gt;&lt;br /&gt;As a bonus it uses python 3 - which pygame has supported for a while.&lt;br /&gt;&lt;br /&gt;Congratulations to Albert Sweigart for finishing his second edition of the book.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-2634520809022548830?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/2634520809022548830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2634520809022548830' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2634520809022548830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2634520809022548830'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/invent-with-python-new-pygamepython.html' title='Invent with python - a new pygame/python book.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3620905978953067431</id><published>2009-12-22T10:16:00.013Z</published><updated>2009-12-24T14:50:02.070Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='cdb'/><category scheme='http://www.blogger.com/atom/ns#' term='packaging'/><category scheme='http://www.blogger.com/atom/ns#' term='pywebsite'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>structuring modules/packages and the cdb database for websites and python packages</title><content type='html'>Integrated modules are nice, but so are modular packages.&lt;br /&gt;&lt;br /&gt;How can we have both?  That is, keep all things for a module(or sub package) in one directory, but also have a nice integrated system built on top of that?&lt;br /&gt;&lt;br /&gt;Often for one package I will have a file layout like so:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/setup.py&lt;br /&gt;/[package_name]&lt;br /&gt;/[package_name]/[package_module].py&lt;br /&gt;/[package_name]/tests/[package_module]_test.py&lt;br /&gt;/[package_name]/examples/[package_module].py&lt;br /&gt;/[package_name]/docs/[package_module].py&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then each module has its tests, docs, and examples all mixed in the one directory.  This is nice if you want to have all of the tests together, and all of the docs, and examples together.&lt;br /&gt;&lt;br /&gt;However then all of the modules are mixed in together.  Meaning it is harder to separate them, and keep one module in its own directory.  Having everything for one thing together is nicer for developers I think.&lt;br /&gt;&lt;br /&gt;Using namespace packages through &lt;strike&gt;setuptools&lt;/strike&gt; distribute is one way.  There is a draft pep around to put namespace packages into python as well.  However, this feels way too heavyweight for me.  Especially since they add multiple paths to the interpreter... meaning python has to do stat, and open, calls for every single path - which slows down the startup and import speed of python even when not using those packages.&lt;br /&gt;&lt;br /&gt;Another way is to use a sub-package for each module.  This turns each module into a sub-package.&lt;br /&gt;&lt;br /&gt;However, some people put all of their stuff in an __init__.py file.  Which is kind of hard to find, and not very descriptive.  Also if you are editing a dozen __init__.py files for a project, it is really quite annoying.  It is much better to have it in a 'modulename.py' file, and then import that in the __init.py file.  Still slower than using modules directly though, since there are still extra stat calls, and extra file opens and reads.&lt;br /&gt;&lt;br /&gt;Using the __init__.py file is still annoying in that you need the extra file, and have to remember what this magic file does.&lt;br /&gt;&lt;br /&gt;This one liner can put all of the sub packages modules into the name space:&lt;br /&gt;&lt;pre&gt;import os,sys&lt;br /&gt;for f in os.listdir('somepackage'):&lt;br /&gt;  if os.path.isdir(os.path.join('somepackage',f)):&lt;br /&gt;      sys.path.insert(0,os.path.join('somepackage',f))&lt;br /&gt;&lt;/pre&gt;This is magic itself, and has a pretty bad code smell.&lt;br /&gt;&lt;br /&gt;Other issues are playing nicely with things like cx_freeze, py2app, py2exe and the many other tools for managing python packages and modules... who don't know about namespace packages, or my custom magic.&lt;br /&gt;&lt;br /&gt;I could write an import hook, or try out importlib in python3.1, but those would probably have similar issues to other non-standard ways.&lt;br /&gt;&lt;br /&gt;So in the end, I think I'll stick with a fairly standard method of doing it... using a __init__.py file which imports the proper module into its namespace.&lt;br /&gt;&lt;br /&gt;This lets me do import somepackage.somemodule and have it work.  I can also "cd somepackage/somemodule/; python somemodule.py" and have it work.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/setup.py&lt;br /&gt;/[package_name]&lt;br /&gt;/[package_name]/[package_module]/&lt;br /&gt;/[package_name]/[package_module]/[package_module]_test.py&lt;br /&gt;/[package_name]/[package_module]/[package_module]_example.py&lt;br /&gt;/[package_name]/[package_module]/[package_module]_docs.txt&lt;br /&gt;&lt;/pre&gt;This is how I'll structure pywebsite.  With a separate directory for each sub module.  This gives modularity, making it scalable to many modules, and it will simplify contributors lives.  Since it uses standard packaging it should be compatible with most tools.  Another bonus is that from within the source download I can just do:&lt;br /&gt;&lt;pre&gt;import pywebsite&lt;/pre&gt; without having to call the setup.py script or install it.  If a module changes from a .py file to a .so or a .dll or the other way around I won't have any issues either.&lt;br /&gt;&lt;br /&gt;It is now a little harder for sub-packages within a package to refer to other sub-packages, but can be done with newer versions of python.&lt;br /&gt;&lt;br /&gt;Sub-packages are more heavyweight than just using modules in your package... but it does seem cleaner and more extensible.  However it is not as heavyweight as using namespace packages.&lt;br /&gt;&lt;br /&gt;Any other issues with this approach?&lt;br /&gt;&lt;h2&gt;namespace packages&lt;/h2&gt;&lt;br /&gt;Using the method outlined above, still does not allow me to split up a package into multiple separate files.  This is ok though, since to start with I want to keep most of the modules in the one place... in the one repository, with the one bug tracker.  However designing for extensibility from the start is useful, so we consider how it can be done.&lt;br /&gt;&lt;br /&gt;This is where namespace packages are useful.&lt;br /&gt;&lt;br /&gt;There is this draft pep: &lt;a href="http://www.python.org/dev/peps/pep-0382/"&gt;pep-0382&lt;/a&gt;, and also the &lt;strike&gt;setuptools&lt;/strike&gt; distribute namespace packages (which is what everyone is using to do them).  Here is the &lt;strike&gt;setuptools&lt;/strike&gt; &lt;a href="http://packages.python.org/distribute/setuptools.html#namespace-packages"&gt;distribute documentation for namespace packages&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It should be possible to use some sort of hack, so that once you import a package, it searches for other packages with the same namespace.  &lt;br /&gt;&lt;br /&gt;You can use a packages __path__ attribute to tell it to look in other paths for importing modules.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; import pywebsite&lt;br /&gt;&gt;&gt;&gt; pywebsite.__path__&lt;br /&gt;['pywebsite']&lt;br /&gt;&gt;&gt;&gt; pywebsite.__path__.append('lala')&lt;br /&gt;&gt;&gt;&gt; import pywebsite.bla&lt;br /&gt;&gt;&gt;&gt; pywebsite.bla.__file__&lt;br /&gt;'lala/bla.py'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using __path__ is outlined in the &lt;a href="http://docs.python.org/tutorial/modules.html"&gt;Packages in Multiple Directories&lt;/a&gt; part of the python tutorial.&lt;br /&gt;&lt;br /&gt;As an example, say I had a 'otherpackage' package, and then someone else wanted to maintain part of that package, or we wanted to separate part of it out.  Let's call this namespace package: 'otherpackage_doit'.  It could install itself as a directory and package called 'otherpackage_doit'.  Then import otherpackage_doit would work fine.  However import pywebsite.doit would not work.  You can't just call the package 'otherpackage.doit' either - since python will first look in the otherpackage package for the doit package, making import otherpackage.doit fail.&lt;br /&gt;&lt;br /&gt;From a users discovery perspective, I would expect otherpackage.doit to be in otherpackage/doit.  So that's where I'd look first.  Installing into that directory would probably be best then.  However that is not a very good method.  After that, I'd probably do "print(otherpackage.doit.__file__)".  Or I might do a "locate otherpackage.doit" command.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Really I just wish python3.2 could be changed so that 'otherpackage.doit' package is automatically a namespace package - without having to mess around with weird magic .pth files or declaring things in setup files like setuptools does.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;So how can we retrofit(hack) existing pythons to do this for us?  We need to get the python import machinery to search for otherpackage.* packages outside of the otherpackage directory.  I'm sure it's possible with python somehow...  Inserting 'otherpackage.doit' into sys.path does not work.  You can't even have a package name with a '.' in it.&lt;br /&gt;&lt;br /&gt;So I'll give up on namespace packages for now until a suitable option presents itself... or I have more time for research.  Separate packages will have to live in the same file, but can still be separate with source control tools - like bzr, svn, github etc.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Still not fast enough... cdb databases for websites and python packages&lt;/h2&gt;&lt;br /&gt;However, the standard python package method is not the fastest.  Supporting cgi operations for a web library is a good idea.  This is because many webhosting platforms still only support python through cgi.  So loading heaps of files for every cgi request is not an option.  It is possible to get acceptable performance out of cgi and python... just many of the large frameworks have poorly optimized loading.  Many frameworks rely on long running processes to avoid the slow load times.  Using django via cgi in an &lt;a href="http://bec-systems.com/web/content/view/46/9/"&gt;embedded 130mhz arm with a limit of 10MiB&lt;/a&gt; is not going to work very well (or at all).&lt;br /&gt;&lt;br /&gt;So how to make it faster for embedded/cgi apps?&lt;br /&gt;&lt;br /&gt;Firstly an executable can be made.  Using tools like py2exe.  This can pack all of your data inside the executable.&lt;br /&gt;&lt;br /&gt;One common method people try is to use the zip format.  This works fairly well but is not optimal.  Zip files are nice as they are supported by OS level tools, and file managers - so this will be one option to use.  The downside, is that it makes the files harder to edit.  I see .zip files as an optimisation that hinders usability.  Especially .egg files(which are just .zip files) are bad, as it makes it harder to debug or change programs.  So like .pyc files I think the zip file should be generated as needed - but having the full source tree there to change is very useful.  If someone changes the source, the zip file should be regenerated as needed.&lt;br /&gt;&lt;br /&gt;Another option is a constant database (&lt;a href="http://cr.yp.to/cdb.html"&gt;cdb&lt;/a&gt;).  cdb is a very simple constant database format used in things like djbdns, qmail and for other things.  cdb happens to be one of the fastest(if not the fastest for constant databases [&lt;a href="http://tokyocabinet.sourceforge.net/benchmark.pdf"&gt;benchmarks pdf&lt;/a&gt;]).  cdb is perfect for python packages that are not meant to change since they are so quick.&lt;br /&gt;&lt;br /&gt;cdb is also pretty good for serving data from websites.  Since often with websites much of the data is mostly static(constant) - a cdb key/value database is a nice optimisation over files on the file system.  There are less syscalls, and less latency issues.&lt;br /&gt;&lt;br /&gt;Zip files can also be used as .jar files by some browsers(firefox), to reduce latency on websites too.  See the &lt;a href="http://docs.sun.com/source/819-0913/author/jar.html#jarprotocol"&gt;jar url scheme&lt;/a&gt; for details on how to put all your static files into a zip file(jar file).&lt;br /&gt;&lt;br /&gt;There are some of my python module_experiments in:&lt;br /&gt;&lt;i&gt;bzr co http://rene.f0o.com/~rene/stuff/module_experiments&lt;/i&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/%7Erene/stuff/module_experiments.tar.gz"&gt;http://rene.f0o.com/~rene/stuff/module_experiments.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So I have now refactored pywebsite to use a sub-package for each module, so that all the tests, docs and examples for that module are within its own sub-package.  Using a zip/cdb file for imports will be left for later, as will namespace packages.  &lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3620905978953067431?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3620905978953067431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3620905978953067431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3620905978953067431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3620905978953067431'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/structuring-modulespackages-and-cdb.html' title='structuring modules/packages and the cdb database for websites and python packages'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-8109981032730183266</id><published>2009-12-21T12:49:00.013Z</published><updated>2010-01-04T19:17:37.895Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SHA-1'/><category scheme='http://www.blogger.com/atom/ns#' term='pywebsite'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>hashing urls for authorisation, and pywebsite.signed_url</title><content type='html'>Using a hash with a salt is one way of validating urls.  With it you can tell that it is quite likely the url was generated by someone with a secret.  That is, generated by someone authorised to make that url.  This post describes using this technique with the hmac python module applied to urls(and object method calls).&lt;br /&gt;&lt;br /&gt;Generating thumbnail urls is a good example.  If you have a url which can generate a thumbnail of an image at a specified size that is pretty cool.  Except then you can have someone generating images at all sorts of other weird sizes by exploiting the width, and height parameters (eg making 100,000 pixel wide thumbnails).  Or perhaps you want to limit it to a certain set of images.&lt;br /&gt;&lt;br /&gt;You could always code in your thumb nail generating routine which variables are valid... but this has problems.  First it makes your routine less flexible.  Separating authorisation is always a nice idea.&lt;br /&gt;&lt;br /&gt;Another way (with HMAC like using pywebsite.signed_url) is to generate the urls and add a hash to them with a secret salt.  This way you can be fairly sure that it was generated by someone with access to the secret salt.&lt;br /&gt;&lt;br /&gt;This system is not as secure as using PKI, but it is a lot quicker to implement and is faster running.&lt;br /&gt;&lt;br /&gt;One problem with using hashes is when you have to change the salt or hash scheme... then all your old urls are invalidated.  Very annoying (sad panda).&lt;br /&gt;&lt;br /&gt;Below is a little example of how you would hash protect some object methods, so only methods which are generated by authorised people are allowed.  Note that it only uses a hash with a length of 6 characters, this is to keep urls short.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;from pywebsite import signed_url, imageops&lt;br /&gt;&lt;br /&gt;class SignedImages(object):&lt;br /&gt;    salt = 'somesecret'&lt;br /&gt;    root_dir = '/tmp/'&lt;br /&gt;&lt;br /&gt;    def thumb(self, hash, width, height, rotate, gallery, image):&lt;br /&gt;        """ serves a thumb nail&lt;br /&gt;        http://localhost:9942/thumb/XXXahashXXX/1000/1000/0/test/colorpicker.jpg&lt;br /&gt;        """&lt;br /&gt;        salt = self.salt&lt;br /&gt;        keys = None&lt;br /&gt;        length_used = 6&lt;br /&gt;        values = [width, height, rotate, gallery, image]&lt;br /&gt;        if not signed_url.verify(values, salt, hash, keys, length_used = length_used):&lt;br /&gt;            raise ValueError('not a valid url')&lt;br /&gt;        cache_dir = os.path.join(self.root_dir, "cache/")&lt;br /&gt;        path_to_galleries = os.path.join(self.root_dir,  "galleries/")&lt;br /&gt;        iops = imageops.ImageOps(cache_dir, path_to_galleries)&lt;br /&gt;        path = iops.resize(gallery, image, width, height, rotate)         &lt;br /&gt;        return cherrypy.lib.static.serve_file(path)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    def gen_thumb_url(self, width, height, gallery, image):&lt;br /&gt;        values = [ width, height, '0', gallery, image]&lt;br /&gt;        salt = self.salt&lt;br /&gt;        keys = None&lt;br /&gt;        length_used = 6&lt;br /&gt;        hash = signed_url.sign(values, salt, keys = keys, length_used = length_used)&lt;br /&gt;        url = "/".join(["thumb", hash] + values)&lt;br /&gt;        return url&lt;br /&gt;&lt;br /&gt;   thumb.exposed = True&lt;br /&gt;   gen_thumb_url.exposed = True&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;See the &lt;a href="http://bazaar.launchpad.net/~illume/pywebsite/trunk/annotate/head%3A/trunk/pywebsite/signed_url/signed_url.py"&gt;signed_url.py&lt;/a&gt; on launchpad file browser, or &lt;i&gt;bzr co lp:pywebsite&lt;/i&gt;.  Also see pywebsite.signed_url.signed_url_test for the unit tests.  It is quite a simple module, and you could roll your own quite easily (with the python hmac module).  Well, maybe not well easily... eg, consider the &lt;a href="http://vnhacker.blogspot.com/2009/09/flickrs-api-signature-forgery.html"&gt;flickr exploits&lt;/a&gt;  This code is also probably vulnerable( eg, &lt;a href="http://renesd.blogspot.com/2009/05/sha-1-fail.html"&gt;SHA-1 is now vulnerable&lt;/a&gt; to collisions), but at least it will stop basic fiddling with unauthorised urls and shouldn't have the same vulnerabilities as the flickr API used to(and the facebook API might still have).  &lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;updates: been through a number of changes... the name has changed from hash_url to signed_url.sign, signed_url.verify.  It has also moved into its own sub-package (like all pywebsite modules now live in their own self contained sub-package).  Fixes for timing attack(unit tested).  Uses hmac.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-8109981032730183266?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/8109981032730183266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=8109981032730183266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8109981032730183266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8109981032730183266'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/hashing-urls-for-authorisation-and.html' title='hashing urls for authorisation, and pywebsite.signed_url'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3101968635197920983</id><published>2009-12-21T06:15:00.004Z</published><updated>2009-12-21T06:44:20.346Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='london'/><category scheme='http://www.blogger.com/atom/ns#' term='switzerland'/><title type='text'>In Switzerland.  Lots of snow!</title><content type='html'>In Switzerland.  Had fun visiting an old friend and his new girl friend.  Lots of snow came whilst we're here which was fun.  However, the planes didn't like it, and they got cancelled.  So going back to London today instead(if the planes work).&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_eJJgehXCsQ4/Sy8TqlK1jXI/AAAAAAAAAF4/n70doAlbTQM/s1600-h/IMG_3010.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_eJJgehXCsQ4/Sy8TqlK1jXI/AAAAAAAAAF4/n70doAlbTQM/s320/IMG_3010.JPG" alt="" id="BLOGGER_PHOTO_ID_5417570499002994034" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3101968635197920983?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3101968635197920983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3101968635197920983' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3101968635197920983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3101968635197920983'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/in-switzerland-lots-of-snow.html' title='In Switzerland.  Lots of snow!'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_eJJgehXCsQ4/Sy8TqlK1jXI/AAAAAAAAAF4/n70doAlbTQM/s72-c/IMG_3010.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-8871419988943733373</id><published>2009-12-17T06:40:00.001Z</published><updated>2009-12-17T06:40:00.629Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='multicore'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pypy'/><category scheme='http://www.blogger.com/atom/ns#' term='unladenswallow'/><title type='text'>Python the GIL, unladen swallow, reference counting, and atomic operations.</title><content type='html'>The unladen swallow project comments on the global interpreter lock and suggests long term dropping reference counting in favour of GC.  &lt;a href="http://code.google.com/p/unladen-swallow/wiki/ProjectPlan#Global_Interpreter_Lock"&gt;http://code.google.com/p/unladen-swallow/wiki/ProjectPlan#Global_Interpreter_Lock&lt;/a&gt;.  They are also now favouring an incremental GIL removal from python.&lt;br /&gt;&lt;br /&gt;However, confusing getting rid of the GIL, with requiring using garbage collection is wrong.  This mini-essay will explain why reference counting is good for python, and why you do not need to get rid of it for multiple CPU systems.  Then there will be descriptions of other improvements to python for multiple CPU systems that can be made.&lt;br /&gt;&lt;br /&gt;Reference counting has a number of advantages over various GC schemes see &lt;a href="http://en.wikipedia.org/wiki/Reference_counting#Advantages_and_disadvantages"&gt;http://en.wikipedia.org/wiki/Reference_counting#Advantages_and_disadvantages&lt;/a&gt;.  As a python programmer, optimizing for the programmer is what is most important... and reference counting makes it easier for the programmer.  It makes programs much more deterministic, meaning that reference counting code is much easier to think about in our human heads.&lt;br /&gt;&lt;br /&gt;Below are two real world examples of atomic reference counting.  This makes reference counting thread safe, by using atomic operations.&lt;br /&gt;&lt;br /&gt;Here are two mainstream open source object systems that have implemented it:&lt;br /&gt;&lt;br /&gt;QT: from qt 4 released June 2005:&lt;br /&gt;&lt;a href="http://doc.trolltech.com/qq/qq14-threading.html#atomicreferencecounting"&gt;http://doc.trolltech.com/qq/qq14-threading.html#atomicreferencecounting&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;glib: released august 2005.&lt;br /&gt;&lt;a href="http://mail.gnome.org/archives/gnome-announce-list/2005-August/msg00048.html"&gt;http://mail.gnome.org/archives/gnome-announce-list/2005-August/msg00048.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It is possible to make reference counting thread safe in a performant, cross platform manner.  Using the argument against reference counting just because of the GIL and thread safeness is a bad argument - as proved by at least these two highly portable, highly performant, open source pieces of code.  Not just research papers, but real life code that has been used for a number of years now.&lt;br /&gt;&lt;br /&gt;There has been a lot of research and real life code which improves reference counting, which python could take advantage of - rather than moving to a GC.&lt;br /&gt;&lt;br /&gt;Simple Direct Media Layer also has a cross platform atomic operations API in SDL 1.3.&lt;br /&gt;&lt;br /&gt;Locality of memory is much more important than using GC or reference counting.  That is operating on memory worrying about if it is in the caches (L1,L2,L3 etc), also about locality to certain cpus/cores.  This is why modern memory allocators have a per thread heap... to help memory allocated on one heap be accessed more easily by threads.  See NUMA for details.  NUMA factors play a BIG part in modern cpus already... even on single cpu systems.  Designing for cache friendliness can give big speedups.&lt;br /&gt;&lt;br /&gt;Reference counting can be a problem for cache friendly systems... but it doesn't need to be.  There are techniques for reducing, or removing NUMA issues with reference counting memory management.&lt;br /&gt;&lt;br /&gt;Reducing memory usage of objects will also mean for faster threaded python programs. &lt;br /&gt;From the pypy project: &lt;i&gt;"The total amount of RAM used on a 32-bit[ED:pypy] Linux is 247 MB, completing in 10.3 seconds. On CPython, it consumes 684 MB and takes 89 seconds to complete... This nicely shows that our GCs are much faster at allocating objects, and that our objects can be much smaller than CPython's."&lt;/i&gt;&lt;br /&gt;More details here: &lt;a href="http://morepypy.blogspot.com/2009/10/gc-improvements.html"&gt;http://morepypy.blogspot.com/2009/10/gc-improvements.html&lt;/a&gt;.  As you can see reducing the memory size of objects can have a massive effect on runtime.&lt;br /&gt;&lt;br /&gt;Another memory optimization for python can come from reducing the amount of allocations done by python at run time.  Many real time systems have a policy of zero run time memory allocations.  For python this is hard, however there are probably a number of places where memory allocations could be removed, or reduced in python.  The pypy project tried to reduce the runtime memory allocations and found a number of them which sped things up.&lt;br /&gt;&lt;br /&gt;Intelligent sizing of the stack is another memory optimization python could do.  Each new thread has a copy of its own stack.  So by having a very large stack, python can use less threads than is optimal.  An optimization could be to try and use a very small stack, and then resize it if necessary.  See the &lt;a href="http://docs.python.org/library/thread.html"&gt;http://docs.python.org/library/thread.html&lt;/a&gt; for the thread.stack_size([size]) function.&lt;br /&gt;&lt;br /&gt;Also speeding up GIL holding/removing will be good for those parts of python that already remove the GIL - especially on single CPU systems.  Currently grabbing the GIL is a fairly costly operation.  Using a method like that used by QT with atomic operations would be MUCH more efficient.&lt;br /&gt;&lt;br /&gt;An incremental technique of GIL removal was taken by VMs like linux and *bsds (eg freebsd, dragonfly bsd) (and glib, qt).  The idea is you make more fine grained locks on individual systems.  Then you can slowly remove the GIL from parts incrementally... and you can test them.  Removing the GIL all at once is silly... removing it piece by piece is a much better idea.  I think the unladen swallow project is now preferring an incremental approach to GIL removal... which is nice.&lt;br /&gt;&lt;br /&gt;A plan which approaches GIL removal incrementally is much more sane over all.&lt;br /&gt;&lt;br /&gt;Designing APIs to work in manners better for threaded programs is another area python can get better performance on multi cpu systems.  For example, by finding calls which block and making sure they release the GIL.  Also by making &lt;a href="http://rene.f0o.com/%7Erene/stuff/europython2007/Batching%20APIs,%20as%20applied%20to%20web%20applications.pdf"&gt;batching APIs&lt;/a&gt;, allows not only avoiding the high cost of python function calls, but also makes that code embarrassingly easy to achieve parallelism.&lt;br /&gt;&lt;br /&gt;One API that could be easily turned into a batching API is the import command.  When you import 10 modules at the top of your program, much of that work could be shared or done in parallel.  Likewise making the libraries be able to easily use&lt;br /&gt;&lt;br /&gt;Documenting which calls release the GIL, or have fine grained locking/lock free programming can also help programmers more easily take advantage of multiple cpus.&lt;br /&gt;&lt;br /&gt;Documenting which objects are safe to pickle will help people use the multiprocessing module, which does not work with objects unless the objects can be pickled.  Likewise using forking can allow you to use multiple processes on data that can not be pickled.  Since when you fork, the OS does the memory copying for you.  The advantage over the multiprocessing library, is that with forking you only need the results to be able to be pickled... not the inputs.&lt;br /&gt;&lt;br /&gt;Using wise madvise calls for mmap can also mark data which is read only... making multi processing much more efficient.  Using madvise well, can mean much better copy on write behaviour.  Improving copy on write behaviour is good for multiple processes... not just multiple threads.  Likewise talking to the OS about what the program needs in other ways will also help.  For example, if you know your program is going to use 1GB of data... then tell the OS that at the start.  If you know it will eventually need 50 threads... then tell it at the start.  If you know it needs a very small stack size... then tell it at the start.&lt;br /&gt;&lt;br /&gt;Modern CPUs have memory prefetching commands, which can help out with telling the CPU which memory you are likely to access next.  Likewise telling python, and the CPU that you want to only read or write to memory can help a lot with performance.&lt;br /&gt;&lt;br /&gt;Apart from memory, there are many other OS level tweaks that can make your multi process python code go quicker.  For example, setting the process/thread priorities.  You can even ask your code to run with real time priority if it needs it.  This can reduce the latency of processing, and also speed up the throughput.  Easily gaining a 20% increase in throughput, or a very big drop in latency.  If you do not care how fast your python program goes, then telling the OS so will help other processes in the system go faster.&lt;br /&gt;&lt;br /&gt;Improving the performance of the built in primitives like the Queue/Mutex can also help python a lot.  I've found that avoiding the python thread safe Queue can give you pretty good performance increases.  Instead just using a list and using its python level atomic operations (documenting which python primitives are atomic would also help programmers a lot).  A multi thread safe event queue can be quite nice.  Especially if you can pass things into the queue at C level... avoiding the GIL entirely.  There are a number of these available for python already (eg pygame.fastevent).&lt;br /&gt;&lt;br /&gt;In fact for python 3.2 the GIL has been reworked: &lt;a href="http://mail.python.org/pipermail/python-dev/2009-October/093321.html&lt;br /&gt;"&gt;http://mail.python.org/pipermail/python-dev/2009-October/093321.html&lt;/a&gt; and the RLock primitive has been rewritten in C.  This 'newgil' work has already been put into py3k trunk.  However I think there is still quite a lot of room for improvement in the python GIL.&lt;br /&gt;&lt;br /&gt;Another API design improvement are optimizations available for worker queues.  One is sending similar tasks and data to the same cpus/cores... to take advantage of NUMA effects/cache (eg, always sending the url "/dojob1" to the same cpu). &lt;br /&gt;&lt;br /&gt;Another worker queue optimisation is to reduce contention on the worker queue, by sending batches of tasks/data to the worker threads/processes.  Rather than one task/piece of data at a time... divide the work up into many pieces and then send that across to the worker queues. eg, sending a list of 1000 images to each of the cpus to process rather than have each cpu ask for a single image to process.  Dividing the work up into 16 parts of 100 each requires 16 interactions with the worker queue.  Having them take one thing at a time means 16000 interactions with the worker queue - that is 16000 * 16 more opportunities for GIL locking and thread contention.&lt;br /&gt;&lt;br /&gt;Many operations in the python stdlib could be made to use multiple threads/processes internally at the library level.  Then people wouldn't need to know if the library is using async IO, threads, processes, or alien magic.  eg, a url downloader might be given a list of URLs to GET... and return the responses.  Underneath the covers it could use an async library, or even multiple threads to get the job done.  This library level parallelism can happen if the APIs are given a batching design... that is given multiple inputs, and expecting multiple outputs.  Then it is possible for library authors to try and choose the best technique.  Taking single inputs, and giving single outputs does not let the library authors implement parallel algorithms as easily.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In conclusion, there is a lot we can do to improve python on multi cpu systems without removing the GIL entirely.  An incremental approach to removing it from parts of python is a good idea as shown by other projects doing the same.  Removing reference counting from python is not needed, as there are good, proven ways of using reference counting in multi CPU systems. &lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-8871419988943733373?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/8871419988943733373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=8871419988943733373' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8871419988943733373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/8871419988943733373'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/python-gil-unladen-swallow-reference.html' title='Python the GIL, unladen swallow, reference counting, and atomic operations.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3875995593049765506</id><published>2009-12-16T11:25:00.005Z</published><updated>2009-12-16T12:01:37.107Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python3'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='py3k'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Writing for the latest python is FUN.</title><content type='html'>Writing for the latest python version is just simply... fun.  Even the name 'python 3000' or py3k is amusing.&lt;br /&gt;&lt;br /&gt;It's been a joy over the last week plugging away at a few personal website and game projects using the latest python version.  Over the last year I've been involved in upgrading existing code to the latest versions of python... but not really in writing it JUST for the latest versions.&lt;br /&gt;&lt;br /&gt;No need to consider backwards compatibility problems... &lt;i&gt;older pythons be damned when programming for fun!&lt;/i&gt;  I'm able to take advantage of the latest python features in deep architectural ways.  To fiddle around with the new deep magic python internals.   But the new deep magic parts aren't the best bits though... it's all the elegant little improvements that make a difference.&lt;br /&gt;&lt;br /&gt;It is of great delight finding python 3 compatible modules.  It turns out that the modules available for python 3 are often of quite good quality - and well maintained.  There's not all that many of them around, so it can be good just to browse through those python 3 packages that are available.&lt;br /&gt;&lt;br /&gt;All of this fun makes me reminisce to the days of playing around with python ten years ago.  Perhaps I'm romanticising it a little bit(well I definitely am!).  However when first getting into python all those years ago was quite a thing.  It was probably the small community, and the idea that optimizing for the programmer was more important than optimizing for the computer(no more squiggly braces :).  Like the halcyon days of python2, there is a smaller community of python 3 programmers, and there are a bunch of new techniques and tricks available from python 3.  These two factors remind me about what it was like to get into python all those years ago.&lt;br /&gt;&lt;br /&gt;Most of the programmers doing python 3 stuff are either doing it for fun, or doing it for the good of the python ecosystem over all, that is to make python better for people rather than better for the machine.&lt;br /&gt;&lt;br /&gt;So if you need a reason to get into python 3 it is this:  python 3 makes python fun again.&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3875995593049765506?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3875995593049765506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3875995593049765506' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3875995593049765506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3875995593049765506'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/writing-for-latest-python-is-fun.html' title='Writing for the latest python is FUN.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-2678731605212147134</id><published>2009-12-09T14:18:00.006Z</published><updated>2009-12-09T16:17:57.568Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python3'/><category scheme='http://www.blogger.com/atom/ns#' term='sqlite'/><category scheme='http://www.blogger.com/atom/ns#' term='pywebsite'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pickle'/><title type='text'>pywebsite.sqlitepickle.   sqlite VS pickle</title><content type='html'>The &lt;a href="http://docs.python.org/3.1/library/sqlite3.html"&gt;sqlite&lt;/a&gt; and &lt;a href="http://docs.python.org/3.1/library/pickle.html"&gt;pickle&lt;/a&gt; modules that come with python are quite useful.  So lets mix them together and see what comes out.&lt;br /&gt;&lt;h4&gt;&lt;span style="color: rgb(0, 204, 204);"&gt;SQLITE&lt;/span&gt; Vs &lt;span style="color: rgb(255, 153, 255);"&gt;PICKLE&lt;/span&gt;&lt;/h4&gt;pywebsite.sqlitepickle is a little module I just made which combines sqlite and pickle for persistence.  Useful since it works with python3, and both pickle and sqlite are included with pythons (including pypy).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Import the module.&lt;br /&gt; &gt;&gt;&gt; from pywebsite import sqlitepickle&lt;br /&gt;&lt;br /&gt;An in memory db.&lt;br /&gt; &gt;&gt;&gt; db = sqlitepickle.SQLPickle()&lt;br /&gt; &gt;&gt;&gt; db.save('key', 'value')&lt;br /&gt; &gt;&gt;&gt; db.get('key')&lt;br /&gt; 'value'&lt;br /&gt;&lt;br /&gt;Can also save to a file.  So we first get a temp file name.&lt;br /&gt; &gt;&gt;&gt; import tempfile&lt;br /&gt; &gt;&gt;&gt; f = tempfile.NamedTemporaryFile()&lt;br /&gt; &gt;&gt;&gt; fname = f.name&lt;br /&gt;&lt;br /&gt; &gt;&gt;&gt; db = sqlitepickle.SQLPickle(fname)&lt;br /&gt; &gt;&gt;&gt; db.save('key', 'value')&lt;br /&gt; &gt;&gt;&gt; db.get('key')&lt;br /&gt; 'value'&lt;br /&gt;&lt;br /&gt; &gt;&gt;&gt; db.close()&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The issues with this are that sqlite does not like sharing connections from multiple threads.  To get around that I just create a new connection in each thread, or do db stuff from one thread.  Also using pickles in persistent data can be a &lt;a href="http://renesd.blogspot.com/2006/09/python-pickle-and-web-framework.html"&gt;security issue&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Speed?  ok speed.  Pickle isn't the fastest, and neither is sqlite... but they are both kind of ok.&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;&lt;span style="font-size:-2;"&gt;&lt;br /&gt;&lt;a href="http://pypi.python.org/pypi/pywebsite"&gt;http://pypi.python.org/pypi/pywebsite&lt;/a&gt;&lt;br /&gt;&lt;a href="https://launchpad.net/pywebsite"&gt;https://launchpad.net/pywebsite&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.pywebsite.org/"&gt;http://www.pywebsite.org/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-2678731605212147134?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/2678731605212147134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2678731605212147134' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2678731605212147134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2678731605212147134'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/pywebsitesqlitepickle-sqlite-vs-pickle.html' title='pywebsite.sqlitepickle.   sqlite VS pickle'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-6656340714971247005</id><published>2009-12-08T15:26:00.008Z</published><updated>2009-12-08T16:28:58.843Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='art'/><category scheme='http://www.blogger.com/atom/ns#' term='making'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='craft'/><title type='text'>Play cards.  Not business cards.</title><content type='html'>Play cards.  They're like business cards, but take 30 minutes to make five.  Also, they are for handing out to people you want to play with, rather than to people you want to do business with.  Well it could be used for both... but I think the normal style business card is a bit boring to give to friends.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 244px;" src="http://1.bp.blogspot.com/_eJJgehXCsQ4/Sx5wS1VFW_I/AAAAAAAAAFs/0_1XAxdv0G8/s400/IMG_2282.JPG" alt="play cards" title="play cards" id="BLOGGER_PHOTO_ID_5412887271001381874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Made some of these the other day.  Based on an earlier version I designed a few years ago.  They're about the size of a finger, but unfold to show other details (eg, email, website, etc).&lt;br /&gt;  &lt;br /&gt;-- &lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-6656340714971247005?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/6656340714971247005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=6656340714971247005' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6656340714971247005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/6656340714971247005'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/play-cards.html' title='Play cards.  Not business cards.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_eJJgehXCsQ4/Sx5wS1VFW_I/AAAAAAAAAFs/0_1XAxdv0G8/s72-c/IMG_2282.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3087922517484268068</id><published>2009-12-06T06:33:00.002Z</published><updated>2009-12-30T08:17:19.365Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='buildout'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='numpy'/><title type='text'>buildout project that uses numpy</title><content type='html'>Here is an example buildout project that uses numpy:&lt;br /&gt;&lt;a href="https://launchpad.net/numpybuildout/"&gt;https://launchpad.net/numpybuildout/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you have bazaar, you can check it out like so:&lt;br /&gt;&lt;i&gt;&lt;code&gt;&lt;br /&gt;cd /tmp/&lt;br /&gt;bzr branch lp:numpybuildout&lt;br /&gt;cd numpybuildout/trunk/&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;To use &lt;a href="http://pypi.python.org/pypi/distribute"&gt;distribute&lt;/a&gt; instead of setuptools use the -d flag of bootstrap.py.&lt;br /&gt;&lt;i&gt;&lt;code&gt;python bootstrap.py -d&lt;br /&gt;./bin/buildout&lt;br /&gt;./bin/py&lt;br /&gt;&gt;&gt;&gt; import numpy&lt;br /&gt;&gt;&gt;&gt; numpy.__file__&lt;br /&gt;'/tmp/numpybuildout/trunk/eggs/numpy-1.4.0-py2.6-linux-i686.egg/numpy/__init__.pyc'&lt;br /&gt;&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;There you have it, a simple project that can download and build numpy off of the python package index and install it in it's own private directory for use.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;update: It was broken for python2.6 and numpy 1.3.  However it works again with numpy 1.4&lt;/i&gt;&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3087922517484268068?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3087922517484268068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3087922517484268068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3087922517484268068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3087922517484268068'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/buildout-project-that-uses-numpy.html' title='buildout project that uses numpy'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-780986212501143723</id><published>2009-12-05T08:45:00.000Z</published><updated>2009-12-05T08:45:00.454Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>gvim and karmic ubuntu... with a fix for you.</title><content type='html'>gvim in ubuntu karmic koala is really annoying.  It prints out a bunch of gtk warnings each time you call it.  However thanks to someone making a patch, you can clean it up.  It seems that the fix isn't going to come out until the next ubuntu.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;** (gvim:13354): CRITICAL **: gtk_form_set_static_gravity: assertion `static_gravity_supported' failed&lt;br /&gt;&lt;br /&gt;** (gvim:13354): CRITICAL **: gtk_form_set_static_gravity: assertion `static_gravity_supported' failed&lt;br /&gt;&lt;br /&gt;** (gvim:13354): CRITICAL **: gtk_form_set_static_gravity: assertion `static_gravity_supported' failed&lt;br /&gt;&lt;br /&gt;** (gvim:13354): CRITICAL **: gtk_form_set_static_gravity: assertion `static_gravity_supported' failed&lt;br /&gt;&lt;br /&gt;** (gvim:13354): CRITICAL **: gtk_form_set_static_gravity: assertion `static_gravity_supported' failed&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Very annoying to see that every time you edit a file.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/vim/+bug/402188"&gt;https://bugs.launchpad.net/ubuntu/+source/vim/+bug/402188&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So instead of switching to arch linux, or gentoo linux... or one of the other developer centric distros there is a patch!  ya for patches people make and share :)&lt;br /&gt;&lt;br /&gt;Grab the debdiff to apply the patch.  Check a look at the packaging guide for details on how to build with a debdiff patch.&lt;br /&gt;&lt;a href="https://wiki.ubuntu.com/UbuntuPackagingGuide/BuildFromDebdiff"&gt;https://wiki.ubuntu.com/UbuntuPackagingGuide/BuildFromDebdiff&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;NOTE: please back up your system before trying anything here.  Also DO NOT TRY THIS AT HOME AS SOMETHING MAY GO HORRIBLY WRONG!!!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I'll run through what to do here:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;code&gt;cd ~&lt;br /&gt;$ mkdir vim-gnome&lt;br /&gt;$ cd vim-gnome&lt;br /&gt;&lt;br /&gt;$ wget http://launchpadlibrarian.net/35716623/vim_7.2.245-2ubuntu2.1.debdiff&lt;br /&gt;&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;code&gt;$ md5sum vim_7.2.245-2ubuntu2.1.debdiff&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;abdb13517ec59a1a0b74b55b977e0139  vim_7.2.245-2ubuntu2.1.debdiff&lt;br /&gt;&lt;br /&gt;Check that your md5sum is the same as this.  Hey, why not look at the patch to review it for goodness?  Well you don't have to, but it can be interesting looking at bug fixes.&lt;br /&gt;&lt;br /&gt;We need to install all the tools required for building ubuntu packages...&lt;br /&gt;&lt;i&gt;&lt;code&gt;$ sudo apt-get install build-essential fakeroot devscripts&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Then grab the source for vim-gnome (or vim-gtk if you don't want to use the gnome version... replace vim-gnome with vim-gtk in all things below if you want that instead).&lt;br /&gt;&lt;i&gt;&lt;code&gt;$ apt-get source vim-gnome&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;When I installed the libraries needed to build the source package...&lt;br /&gt;&lt;i&gt;&lt;code&gt;sudo apt-get build-dep vim-gnome&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;I got a 'Segmentation fault'.  eek.  Well, time for a restart...  It seems Karmic isn't all that stable for me with apt-get, dpkg and friends.&lt;br /&gt;&lt;br /&gt;Ok, back from the restart of the computer.&lt;br /&gt;Let us try it again...&lt;br /&gt;&lt;i&gt;&lt;code&gt;sudo apt-get build-dep vim-gnome&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ya! it's working.  I have to download about 100MB of packages. ... wait 10 minutes... then everything is downloaded and installed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Apply the patch...&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;code&gt;$ cd vim-7.2.245/&lt;br /&gt;$ patch -p1 &lt; ../vim_7.2.245-2ubuntu2.1.debdiff&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ok, lets build it again after we've applied this patch.  This build step can take a long while!&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;code&gt;$ debuild -uc -us&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ok, there's no test step... since ubuntu doesn't really have a way to run automated test suites (that I know of).&lt;br /&gt;&lt;br /&gt;At least lintian is run and tells you something.&lt;br /&gt;&lt;br /&gt;It should produce a bunch of .deb files for you.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;vim_7.2.245-2ubuntu2.1_i386.deb         vim-gtk_7.2.245-2ubuntu2.1_i386.deb&lt;br /&gt;vim-common_7.2.245-2ubuntu2.1_i386.deb  vim-gui-common_7.2.245-2ubuntu2.1_all.deb&lt;br /&gt;vim-dbg_7.2.245-2ubuntu2.1_i386.deb     vim-nox_7.2.245-2ubuntu2.1_i386.deb&lt;br /&gt;vim-doc_7.2.245-2ubuntu2.1_all.deb      vim-runtime_7.2.245-2ubuntu2.1_all.deb&lt;br /&gt;vim-gnome_7.2.245-2ubuntu2.1_i386.deb   vim-tiny_7.2.245-2ubuntu2.1_i386.deb&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now to install the relevant packages...&lt;br /&gt;&lt;i&gt;&lt;code&gt;$ sudo dpkg -i vim_7.2.245-2ubuntu2.1_i386.deb vim-common_7.2.245-2ubuntu2.1_i386.deb vim-gui-common_7.2.245-2ubuntu2.1_all.deb vim-runtime_7.2.245-2ubuntu2.1_all.deb vim-gnome_7.2.245-2ubuntu2.1_i386.deb&lt;/code&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ya! no more annoying message :)&lt;br /&gt;&lt;br /&gt;Now, if someone made a PPA other people on different architectures could also easily update their binaries.  Or perhaps the ubuntu folks will make it nice for gvim developers, and apply the patch themselves.&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-780986212501143723?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/780986212501143723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=780986212501143723' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/780986212501143723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/780986212501143723'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/gvim-and-karmic-ubuntu-with-fix-for-you.html' title='gvim and karmic ubuntu... with a fix for you.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-5138556652816625499</id><published>2009-12-04T09:15:00.008Z</published><updated>2009-12-04T10:36:57.543Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='london'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='berlin'/><title type='text'>From Berlin, back to London again... and python dojo!</title><content type='html'>Arrived back in London a few days ago, after a month living in Berlin.&lt;br /&gt;&lt;br /&gt;I really enjoyed Berlin, and thought about staying there for longer... but in the end decided against it for now.  Would really like to visit in the summer, when it's apparently quite a different place!&lt;br /&gt;&lt;br /&gt;&lt;span id="blocks" onmouseover="atext_mouseover(style);" onmouseout="atext_mouseout(style);"&gt;&lt;span style="display: block;" id="text7"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span id="blocks" onmouseover="atext_mouseover(style);" onmouseout="atext_mouseout(style);"&gt;&lt;span style="display: block;" id="text7"&gt;&lt;/span&gt;&lt;/span&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_eJJgehXCsQ4/SxjgBjGMlmI/AAAAAAAAAFk/V4KddxViIBI/s1600-h/IMG_2004.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 150px;" src="http://1.bp.blogspot.com/_eJJgehXCsQ4/SxjgBjGMlmI/AAAAAAAAAFk/V4KddxViIBI/s200/IMG_2004.JPG" alt="" id="BLOGGER_PHOTO_ID_5411321269491373666" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_eJJgehXCsQ4/SxjgBTQ_J7I/AAAAAAAAAFc/J2tlBj4O68k/s1600-h/IMG_1947.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 150px;" src="http://3.bp.blogspot.com/_eJJgehXCsQ4/SxjgBTQ_J7I/AAAAAAAAAFc/J2tlBj4O68k/s200/IMG_1947.JPG" alt="" id="BLOGGER_PHOTO_ID_5411321265241663410" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_eJJgehXCsQ4/SxjgBE5VF-I/AAAAAAAAAFU/QXhFx22quvM/s1600-h/IMG_2000.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 150px;" src="http://4.bp.blogspot.com/_eJJgehXCsQ4/SxjgBE5VF-I/AAAAAAAAAFU/QXhFx22quvM/s200/IMG_2000.JPG" alt="" id="BLOGGER_PHOTO_ID_5411321261384341474" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;Some pictures from Berlin&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Finding the bustle and life on the streets of London quite refreshing.  I think I'll be based in London for the next six months or so at this point(probably longer).&lt;br /&gt;&lt;br /&gt;Going to the &lt;a href="http://ldnpydojo.eventwax.com/4th-london-python-dojo--meetup"&gt;london python dojo&lt;/a&gt; again on the 10th.  This is an interesting format for a get together.  People take turns pair programming with a projector, whilst the rest of the people in the room offer comments.  This time there's going to be a few short interactive presentations too.  It was nice meeting python people from around London last time.  &lt;a href="http://www.fry-it.com/"&gt;Fry-it&lt;/a&gt; are the hosts, who offer their office, pizza(+salad) and beer(+wine) for everyone at each dojo.&lt;a href="http://rene.f0o.com/"&gt;&lt;img id="renef0o" src="http://rene.f0o.com/renef0o.gif" height="24" width="32" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-5138556652816625499?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/5138556652816625499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=5138556652816625499' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5138556652816625499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5138556652816625499'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/12/from-berlin-back-to-london-again-and.html' title='From Berlin, back to London again... and python dojo!'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_eJJgehXCsQ4/SxjgBjGMlmI/AAAAAAAAAFk/V4KddxViIBI/s72-c/IMG_2004.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1082028356285133209</id><published>2009-11-27T17:03:00.005Z</published><updated>2009-11-27T17:45:27.936Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='distutils'/><title type='text'>pythons distutils install race condition</title><content type='html'>Pythons distutils has a race condition where it starts to copy files into the python path whilst installing.&lt;br /&gt;&lt;br /&gt;This is a &lt;a href="http://en.wikipedia.org/wiki/Race_condition"&gt;race condition&lt;/a&gt;, since python programs can be importing the package whilst the package is being installed.&lt;br /&gt;&lt;br /&gt;It would be good for distutils to install things in an atomic manner.  Where things can be installed, or not installed.  Like, on unix by moving the files in from a temporary directory. This would also help reduce breakages.  Since if a package breaks half way installing a package then the broken version will not over write the existing version.&lt;br /&gt;&lt;br /&gt;It's not a very serious problem, since most people don't install things on live important systems.  Also some packaging tools fix the issues with the source installs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1082028356285133209?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1082028356285133209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1082028356285133209' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1082028356285133209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1082028356285133209'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/11/pythons-distutils-install-race.html' title='pythons distutils install race condition'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3790671105116749639</id><published>2009-11-22T18:48:00.004Z</published><updated>2009-11-22T18:55:12.542Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='py3k'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>2to3c: an implementation of Python's 2to3 for C code</title><content type='html'>"2to3c: an implementation of Python's 2to3 for C code"&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://dmalcolm.livejournal.com/3935.html"&gt;http://dmalcolm.livejournal.com/3935.html&lt;/a&gt; for a description of this tool.&lt;br /&gt;&lt;br /&gt;It works on C modules.  So it should be easier for people to do ports to py3k for their C modules.&lt;br /&gt;&lt;br /&gt;The 2to3c tool uses &lt;a href="http://coccinelle.lip6.fr/"&gt;Coccinelle&lt;/a&gt; for transformations on the C code.  This program has been used for linux, and other software... for updating code when their APIs change.&lt;br /&gt;&lt;br /&gt;The perfect fit for the python C API changes!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3790671105116749639?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3790671105116749639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3790671105116749639' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3790671105116749639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3790671105116749639'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/11/2to3c-implementation-of-pythons-2to3.html' title='2to3c: an implementation of Python&apos;s 2to3 for C code'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-2583167037261338039</id><published>2009-11-05T21:14:00.006Z</published><updated>2009-11-05T22:01:30.620Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><title type='text'>rakarrack is a decent effects rack for linux</title><content type='html'>&lt;a href="http://rakarrack.sourceforge.net/"&gt;rakarrack&lt;/a&gt; is a decent effects rack for linux.  &lt;br /&gt;&lt;br /&gt;It's not packaged for ubuntu(of course), but is fairly easy to compile.  I've been using the cvs version (yes, people are still quite happily using cvs it seems).&lt;br /&gt;&lt;br /&gt;Once you get it set up you have access to 80 presets of realtime guitar effects(2-40ms depending on your computer sound card setup).&lt;br /&gt;&lt;br /&gt;It works with the jack audio system, so you can route audio into it, and route its audio out to other programs easily enough.  You can also control it with midi(alsa, or jack).  Meaning you can hook it up to a midi controller of some sort.  I've been using it with an maudio axiom 25 controller, and with python scripts via pygame.midi.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://renesd.blogspot.com/2009/11/rakarrack-is-decent-effects-rack-for.html"&gt;&lt;img src="http://1.bp.blogspot.com/_eJJgehXCsQ4/SvNGJ6HUP3I/AAAAAAAAAEs/XSY-5Aaro68/s400/rackarrack.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5400737514180067186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It even has a very nice help manual integrated into the program... I wish more programs had a good help section.  It details the 17 different effects that come with the program.&lt;br /&gt;&lt;br /&gt;One thing which is a bit funny is that it doesn't use &lt;a href="http://www.ladspa.org/"&gt;LADSPA&lt;/a&gt; or &lt;a href="http://lv2plug.in/"&gt;lv2&lt;/a&gt; plugins.  You can of course still use these other plugins through other jack programs if you want.  However the ones it comes with are all fairly good quality from my tinkering.  There is a lot you can do with the various plugins in different orders with different settings in each one.  The 80 presets show a good variations of sounds you can get out of it.&lt;br /&gt;&lt;br /&gt;I've been using it in conjunction with the &lt;a href="http://www.mixxx.org/"&gt;mixxx&lt;/a&gt; mixing program and the &lt;a href="http://www.hydrogen-music.org/"&gt;hydrogen&lt;/a&gt; drum machine.  So you don't need to use it just with guitars... any program or audio input will do.&lt;br /&gt;&lt;br /&gt;If you are using guitars it also has a tuner which might come in handy... if you've never quite got the hang of playing that song called Tuning that you hear at the start of every gig.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-2583167037261338039?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/2583167037261338039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=2583167037261338039' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2583167037261338039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/2583167037261338039'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/11/rakarrack-is-decent-effects-rack-for.html' title='rakarrack is a decent effects rack for linux'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_eJJgehXCsQ4/SvNGJ6HUP3I/AAAAAAAAAEs/XSY-5Aaro68/s72-c/rackarrack.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-1672966660592232185</id><published>2009-11-02T15:33:00.004Z</published><updated>2009-11-03T08:54:30.102Z</updated><title type='text'>Ich bin in Berlin</title><content type='html'>Berlin seems like a fun and laid back place.  Arrived here the other day... haven't had much time to look around so far.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-1672966660592232185?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/1672966660592232185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=1672966660592232185' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1672966660592232185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/1672966660592232185'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/11/ich-bin-in-berlin.html' title='Ich bin in Berlin'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-369974258291432603</id><published>2009-10-23T18:13:00.004+01:00</published><updated>2009-10-24T09:40:40.763+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='review'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Karmic Koala Ubuntu 9.10 beta review.</title><content type='html'>This is for the beta release, and most(I think all) of these bugs have been reported in the bug tracker.  (Note the bug tracker is currently reporting errors... so I can not link to bugs).&lt;br /&gt;&lt;br /&gt;I do like a lot of things about the release... these are mainly things I don't like.  So please don't take this as a bad view of Ubuntu 9.10 overall... just some criticism.&lt;br /&gt;&lt;br /&gt;Hibernation seems to not work correctly all the time(for me)... when I close the lid, and open it later it does not seem restore properly.  It shows the screen, but does not respond to input on the keyboard/trackpad.  Then after a bit the screen goes black.  Then I need to press the power button, and then the login box comes back up - and I can log in again.  This has worked for the last two ubuntu releases, so it's annoying.&lt;br /&gt;&lt;br /&gt;Booting seems slower... and is actually slower(timed it) for me.  Perhaps I need to install from scratch for it to be faster or something.  Pete Shinners has some benchmarks on his blog of ubuntu booting faster for him... &lt;a href="http://shredwheat.blogspot.com/2009/10/ubuntu-910-karmic-koala-boot-benchmark.html"&gt;boot benchmarks&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;pulseaudio was installed again, stuffing up my sound settings.  However after removing pulseaudio, the multimedia keys on my keyboard do not work... as they used to work in the previous release without pulseaudio.  Apparently the ubuntu mixer applet only works with pulseaudio now.  Yuk.  If you go to the sound preferences dialog, it only works if you use pulseaudio.&lt;br /&gt;&lt;br /&gt;So pulseaudio is using 3% of your cpu when no sound is playing, or pulseaudio does not work with your screen reader... or many other reasons you do not want to use pulseaudio, and you want to remove it ubuntus gui mixer fails.&lt;br /&gt;&lt;br /&gt;The main pulseaudio author even says the ubuntu implementation of &lt;a href="http://0pointer.de/blog/projects/pa-in-ubuntu.html"&gt;pulseaudio is bad on his blog&lt;/a&gt;... so I hope this is fixed before the official release.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Changing the speed of the CPUs/cores now requires a authentication... and typing in a password... annoying!!  So now I end up leaving them at full cpu... wasting power, as I need full cpu in some situations.  The usability is not considered here... I think people will just use more power.&lt;br /&gt;&lt;br /&gt;Some of my icons were messed up, along with applets I was using.  eg, my firefox icon got changed into a red circled crossed with a line through it.&lt;br /&gt;&lt;br /&gt;I leave a memory card in the memory card holder... and now ubuntu pops a message up telling me it's there each time I open the lid.  Even if I press the ignore button.  Annoying.  The last ubuntu did not ignore my request.&lt;br /&gt;&lt;br /&gt;Newer versions of many software packages are available... which is nice.  The graphics do seem to be faster on my intel machine...  again nice :)  New gcc, etc etc.&lt;br /&gt;&lt;br /&gt;Still no jack/pulseaudio compatibility stuff.  Still no OSSv4 sound system packaged :(  Ubuntu have made it hard to have alsa, jack and pulseaudio all used side by side.  The authors of those systems have worked to make the situation better, but ubuntus implementation is not good.  Better to install audio stuff yourself for this release too.&lt;br /&gt;&lt;br /&gt;Ubuntu has old SDL, and pygame releases... unlike a lot of other platforms which have the latest stable releases.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So expect Ubuntu karmic koala 9.10 to still have bad sound, and bad support for games.  I have hopes that bugs will get fixed before the beta finishes... but I don't have very strong hopes.&lt;br /&gt;&lt;br /&gt;update: Pete Shinners has some benchmarks on his blog of ubuntu booting faster for him... &lt;a href="http://shredwheat.blogspot.com/2009/10/ubuntu-910-karmic-koala-boot-benchmark.html"&gt;boot benchmarks&lt;/a&gt;.  Added link to pulseaudio authors blog about poor pulseaudio on ubuntu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-369974258291432603?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/369974258291432603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=369974258291432603' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/369974258291432603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/369974258291432603'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/10/karmic-koala-ubuntu-910-beta-review.html' title='Karmic Koala Ubuntu 9.10 beta review.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3621309114539267522</id><published>2009-10-20T14:22:00.002+01:00</published><updated>2009-10-20T15:07:17.568+01:00</updated><title type='text'>web design for robots</title><content type='html'>More robots are reading websites than humans - so should we be designing the websites for robots?&lt;br /&gt;&lt;br /&gt;Thanks to the search engine wars, most visitors to most websites are by robots.  But has anyone asked what these robots enjoy?&lt;br /&gt;&lt;br /&gt;There's often a divide in artists between introverted, and extroverted artists.&lt;br /&gt;"Fuck you - I make art for myself and not for others."  OR "I make art for people to enjoy, I'm not so selfish and self indulgent that I just make art for myself".&lt;br /&gt;&lt;br /&gt;So I decided to interview a few robots to find out what some of their favourite websites are.  But where to find a robot to ask questions of?&lt;br /&gt;&lt;br /&gt;I had to look no further than an internet enabled fridge.  So with my notebook in hand I pull a chair up to the fridge and ask it some questions.  I open with a flurry of questions, trying to provoke a response.&lt;br /&gt;&lt;br /&gt;"Do you have any favourite websites?" I ask.  No answer.  Obviously this robot does not know english.  I give it another ten minutes of questioning - then give up.  I leave my card for the robot in case it feels like answering questions later, and pull away my chair.  The fridge seems relieved I have gone.&lt;br /&gt;&lt;br /&gt;Luckily I can just query some robots brains directly.  No need for tricky questions to extract the information I'm after.  I stuff a proxy in between the fridge and the internet.  A week later I study the statistics of its favourite websites.&lt;br /&gt;&lt;br /&gt;As we all know, just because you go to a website five times a day - does not mean you enjoy it.  However, it might give us an idea of what this robot does like.  First I noticed it occasionally calls home to it's place of manufacture.  I guess to send details back home of what it's up to.  However, I guess its family has moved on - 404 - page not found for where its trying to send it's details.  I wonder for how many years this will go on?  It would be like you sending a post card home to your family for 20 years, and never knowing that your family moved house 19 years ago.  Oh well, we keep sending the post cards anyway.&lt;br /&gt;&lt;br /&gt;First rule for web design for robots - they are really dumb, and will possibly forever, keep looking at the same urls.  Robots do not change with the world around them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Egyptians knew about mixing colors around 4500 years ago.  Do robots know how to mix colors, and do they care about colors?  Some of those early Egyptian paintings and scupltures, and poems are really interesting - and still provide joy, and insight.  By designing for robots today, will robots in the future still appreciate our work?&lt;br /&gt;&lt;br /&gt;A robot mind can often not change once set.  Well, until it is updated by the programmer.  What happens when the robot programmer moves on to another project?  Will the robot ever be updated again?  Will the robot gain a split personality?  The result of many different programmers updating its brain, must surely be a variety of personalities mixed in there.&lt;br /&gt;&lt;br /&gt;Continuing these thoughts - thinking about how robots think - is not really interesting to me.  I am now forcing myself to continue writing, in a workman like fashion.  Sorry (you should probably stop reading my robot friends).&lt;br /&gt;&lt;br /&gt;What if the robot has some way of asking people to tell it what is nice, good, sane, and lawful?  What if the robot can ask the people to tell it things... and reward them in some way for their work?  Provide the robot brain programmers with some value, and the robot will evolve - for free.&lt;br /&gt;&lt;br /&gt;Oh, so the robots are driven by the programmers - and what the robots can sense about the world around them.  Can the robots also be driven by positive and negative feedback?  Well certainly, it's possible.  Is it possible?  Then robots need to process the input - the signals - and make sense of them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Signals are processed by the robots, but what signals do the robots enjoy the most?  Signals that fall into easily recognized patterns surely.&lt;br /&gt;&lt;br /&gt;Maybe robots will like other robots art the best?  Robots that make things for other robots?  Well, robots can make things all by themselves this is true.&lt;br /&gt;&lt;br /&gt;What if the robot masters try to tell the robots - "do not care about what the robots make - only care for what the humans make".  Well, then the robots try to appear human.  There are robots who try to become human, and robots that try find out the difference between a human and a robot.&lt;br /&gt;&lt;br /&gt;Signal - human.   Signal - robot.   Robot, human, robot, robot... 101010101...&lt;br /&gt;&lt;br /&gt;We shall call this test the Robot Turing test.  The Turing test is the test to see if people can see if a signal is from a human or a robot.  An idea from a man dead - at the hands of government lives on in our brains, and in robot brains.  Shifting signals henceforth into patterns recognised a long time ago.&lt;br /&gt;&lt;br /&gt;Robots can use the human brains as a resource.  Humans can use the robots as a resource.  Who is in control in the end?&lt;br /&gt;&lt;br /&gt;ROBOTS?  HUMANS?   ROBOTS?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Is anything in control?  Or is it stuck in an infinite loop?  Are the humans and robots just sending post cards, even though their family has moved house?  &lt;br /&gt;&lt;br /&gt;Should someone tell them all to stop sending postcards?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3621309114539267522?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3621309114539267522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3621309114539267522' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3621309114539267522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3621309114539267522'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/10/web-design-for-robots.html' title='web design for robots'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7445520489326387813</id><published>2009-10-14T10:47:00.004+01:00</published><updated>2009-10-14T12:56:31.992+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='review'/><title type='text'>game review - Tonk Tanks</title><content type='html'>&lt;a href="http://pygame.org/project-Arcade+Tonk+Tanks-1078-2271.html"&gt;Tonk Tanks&lt;/a&gt; is a really small, and fun game.  All game play is on one screen, and the controls are simple.&lt;br /&gt;&lt;br /&gt;You have arrow keys to move your tank around, and a button to shoot the other tanks.  It's like one of those old atari 2600 tank games, but a more modern version.  Once you die, you teleport to a different respawn positions around the map.  &lt;br /&gt;&lt;br /&gt;The game is quite playable single player - but the author is working on a networked multiplayer version.  Another nice addition would be multiplayer on one machine - especially with joysticks or mice support (since &lt;a href="http://www.sjbaker.org/wiki/index.php?title=Keyboards_Are_Evil"&gt;keyboards are evil&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pygame.org/project-Arcade+Tonk+Tanks-1078-2271.html"&gt;&lt;img src="http://www.pygame.org/thumb/3ad9a863a72f25492fb7f9b8f411bc3f.png"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The tank AI seems different and varied enough, that I have not worked it out from playing it ten times or so.  Usually my games only last about five minutes before I move onto something else.  It's one of those games I can play for little while when I want a short break.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pygame.org/project-Arcade+Tonk+Tanks-1078-2271.html"&gt;Tonk Tanks&lt;/a&gt; works well on linux, windows and Mac (and probably other platforms supported by python+pygame).  There's a windows .exe available, otherwise you need to have python+pygame installed to play.  I don't think it's packaged for any linux/*bsd distributions yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7445520489326387813?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7445520489326387813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7445520489326387813' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7445520489326387813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7445520489326387813'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/10/game-review-tonk-tanks.html' title='game review - Tonk Tanks'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-7868527182888423872</id><published>2009-10-09T12:32:00.002+01:00</published><updated>2009-10-09T12:53:01.843+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drawing'/><title type='text'>Obama wins Nobel Peace Prize 2009 - 30 minute drawing competition.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_eJJgehXCsQ4/Ss8kDc39FpI/AAAAAAAAAEk/maievARb-HE/s1600-h/obama-nobel-peace-prize.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://4.bp.blogspot.com/_eJJgehXCsQ4/Ss8kDc39FpI/AAAAAAAAAEk/maievARb-HE/s320/obama-nobel-peace-prize.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5390566920694863506" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-7868527182888423872?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/7868527182888423872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=7868527182888423872' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7868527182888423872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/7868527182888423872'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/10/obama-wins-nobel-peace-prize-2009-30.html' title='Obama wins Nobel Peace Prize 2009 - 30 minute drawing competition.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_eJJgehXCsQ4/Ss8kDc39FpI/AAAAAAAAAEk/maievARb-HE/s72-c/obama-nobel-peace-prize.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3723371663919329870</id><published>2009-09-29T16:56:00.002+01:00</published><updated>2009-09-29T16:59:44.297+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Spam detection on websites?</title><content type='html'>Assume you have a user content site - or you're using software that can somehow get spam links inserted into it.  &lt;br /&gt;&lt;br /&gt;How do you find out if your website has spam put on it?&lt;br /&gt;&lt;br /&gt;It seems a common enough problem these days... people putting spam links on websites.  Surely there must be a service or piece of software to detect such a thing?&lt;br /&gt;&lt;br /&gt;I can think of a few ways to go about writing one fairly easily (using existing spam detection tools... but applying them to a spiders crawl of your website).  It would be much nicer if there's already a tool which does such a thing though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3723371663919329870?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3723371663919329870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3723371663919329870' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3723371663919329870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3723371663919329870'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/09/spam-detection-on-websites.html' title='Spam detection on websites?'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4550343959466761770</id><published>2009-09-26T17:16:00.001+01:00</published><updated>2009-09-26T13:21:11.899+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='midim python'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='alsa'/><title type='text'>Alsa midi, timidity, fluidsynth and jack.</title><content type='html'>If you don't have a midi output on linux(cause your laptop has crappy audio hardware) you can use timidity or fluidsynth to emulate it.&lt;br /&gt;&lt;pre&gt;timidity -iA -B2,8 -Os -EFreverb=0&lt;/pre&gt;&lt;br /&gt;Well, &lt;a href="http://lau.linuxaudio.org/TiMidity-howto.html"&gt;this piece of html&lt;/a&gt; has a bunch of incantations for using timidity on linux... and also gives insight into how to use alsa midi tools.&lt;br /&gt;&lt;br /&gt;Like listing midi ports, and connection midi ports with these two commands:&lt;br /&gt;&lt;code&gt;$ pmidi -l&lt;br /&gt; Port     Client name                       Port name&lt;br /&gt; 14:0     Midi Through                      Midi Through Port-0&lt;br /&gt; 20:0     USB Axiom 25                      USB Axiom 25 MIDI 1&lt;br /&gt;128:0     TiMidity                          TiMidity port 0&lt;br /&gt;128:1     TiMidity                          TiMidity port 1&lt;br /&gt;128:2     TiMidity                          TiMidity port 2&lt;br /&gt;128:3     TiMidity                          TiMidity port 3&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To connect the midi input from my usb Axiom 25 keyboard to the timidity synth the aconnect is the command to use.&lt;br /&gt;&lt;code&gt;aconnect 20:0 128:0&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://alsa.opensrc.org/index.php/AlsaMidiOverview"&gt;AlsaMidiOverview&lt;/a&gt; has more information on things.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;#remove all connections...&lt;br /&gt;$ aconnect -x&lt;br /&gt;&lt;br /&gt;# list all the connections(without using pmidi)&lt;br /&gt;$ aconnect -o&lt;br /&gt;&lt;br /&gt;# a gui for connections&lt;br /&gt;# aconnectgui&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Another synth that can be driven by midi is &lt;a href="http://fluidsynth.resonance.org/trac"&gt;fluidsynth&lt;/a&gt;.  &lt;a href="http://qsynth.sourceforge.net/qsynth-index.html"&gt;qsynth&lt;/a&gt; is the graphical interface for fluidsynth which makes it easier to tweak.  You can use it in pretty much the same way as timidity.  It opens up a port (which you can list with pmidi -l), and then connect it to your keyboard with aconnect.  fluidsynth is probably a bit nicer than timidity... and you can use &lt;a href="http://en.wikipedia.org/wiki/SoundFont"&gt;soundfonts&lt;/a&gt; with it.  Heaps of free sound fonts are available from &lt;a href="http://sounds.resonance.org/patches.py?Action=browse"&gt;resonance.org&lt;/a&gt; and &lt;a href="http://www.hammersound.net/"&gt;hammersound.net&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This plugin is *very* useful:&lt;br /&gt;&lt;a href="http://alsa.opensrc.org/index.php/Jack_(plugin)"&gt;http://alsa.opensrc.org/index.php/Jack_(plugin)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It allows all your alsa using programs to be routed through your jack server.  This means you can use all of your normal audio programs with low latency, good mixing and synchonised audio - even over the network (with netjack).&lt;br /&gt;&lt;br /&gt;Ubuntu does not have the alsa jack plugin included for some brain dead reason... even though debian has had it packaged for a year or so.  However building from source is simple.  &lt;a href="http://www.alsa-project.org/main/index.php/Download"&gt;http://www.alsa-project.org/main/index.php/Download&lt;/a&gt; (./configure &amp;&amp; make &amp;&amp; make install).  I've gone back to removing pulse audio, as this system works very nicely for me.&lt;br /&gt;&lt;br /&gt;Here's my old jackd script, I put in a ~/bin/jack_mine and &lt;a href="http://renesd.blogspot.com/2009/09/screen-for-ghetto-servers-and-startup.html"&gt;start with screen&lt;/a&gt; at boot.&lt;br /&gt;&lt;code&gt;jackd -R -P 70 -d alsa -p 256 -n 3 -r 44100&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I can now use various synths, samplers, and effects racks from my python scripts.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Jamin is a mastering program with a eq, compressors etc.  I don't think I'll need it for live work.  However it might be useful for lots of instruments.  I don't see any reason why it couldn't be controlled by another person with a midi controller.&lt;br /&gt;&lt;br /&gt;Next up I need to see if multiple sound cards can work... unfortunately that apparently doesn't work the best.  You can create a virtual sound card from multiple sound cards, but they have trouble syncing.  It's funny that it's currently easier to sync sound cards on multiple machines than on the same machine... from what I know so far.&lt;br /&gt;&lt;br /&gt;For my use I don't think sync will matter too much... that is listening with headphones with one card, and outputting to sound system with another channel.  My inbuilt sound card has two output lines already, and one line input(which can also be used for output).&lt;br /&gt;&lt;br /&gt;Dell inspirion 1525... the channels are:&lt;br /&gt;1(l) - 2(r) - first headphone plug, or speakers if headphone not in plug 0.&lt;br /&gt;5(r) - 6(l) - second headphone plug.&lt;br /&gt;3(l) - 4(r) - third headphone plug.&lt;br /&gt;7(x) - 8(x) - unused... (not soldered on?)&lt;br /&gt;&lt;br /&gt;So looks like 6 usable channels... nice for a crappy cheap latop :)  This is much nicer than what windows vista allows me to do, and also way nicer than the pulseaudio/gnome combination.  I've used this setup to output 6 channel audio with various different playback libraries including pygame.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4550343959466761770?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4550343959466761770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4550343959466761770' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4550343959466761770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4550343959466761770'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/09/alsa-midi-timidity-fluidsynth-and-jack.html' title='Alsa midi, timidity, fluidsynth and jack.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3485373595085921191</id><published>2009-09-25T12:22:00.009+01:00</published><updated>2009-09-25T15:45:37.351+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='screen'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>screen for ghetto servers and startup scripts.</title><content type='html'>&lt;a href="http://www.gnu.org/software/screen/"&gt;GNU screen&lt;/a&gt; is a good little tool for server administration, or running things on your own remote machines.  It's even good for running things locally.&lt;br /&gt;&lt;br /&gt;I hope this is useful for people who want to run scripts every time they login, or reboot... and who need interactive access to those scripts.  Or useful for those people who are already using screen, but would like to make their setup a bit better:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;scripting sessions, rather than doing them manually at each login or reboot, &lt;/li&gt;&lt;li&gt;finding your screen sessions more easily. &lt;/li&gt;&lt;li&gt;restarting scripts at reboot,  &lt;/li&gt;&lt;li&gt;monitoring,  &lt;/li&gt;&lt;li&gt;logging, &lt;/li&gt;&lt;li&gt;resource control&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Running things as daemons is cool... but if you'd also like interactive control occasionally, running things with screen is useful.&lt;br /&gt;&lt;br /&gt;Most servers have screen, watch and crontab(osx is lacking watch though) - including most linux distros, *bsd, osx, windows(with cygwin).  Most OSes also have their own style init scripts(scripts to run things at boot or logon).  So this screen, watch, crontab combination is ok if you want to use multiple different types of computers - but reuse your scripts.  If you want something robust, and good this isn't for you.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Scripting sessions&lt;/i&gt;&lt;br /&gt;You can make a shell script to script your screen sessions.  So you don't need to do them manually each time you login.  This can save you a *lot* of time, and can make you less afraid of a reboot :).&lt;br /&gt;&lt;br /&gt;-- /home/me/bin/my_screens.sh --&lt;br /&gt;&lt;code&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;# start up your 'app1' to be restarted 2 seconds after it dies, every time it dies.&lt;br /&gt;screen -d -m -S app1 -t "my web app one descriptive name" /opt/local/bin/watch -n 2  /home/me/someapp1/run_app.py &gt; /home/me/logs/app1stdout &gt;&gt; /home/me/logs/app1stderr&lt;br /&gt;&lt;br /&gt;# start running an application.&lt;br /&gt;screen -d -m -S proxy -t "proxy server" /home/me/someapp2/run_app.py&lt;br /&gt;&lt;br /&gt;# connect to my my server setup with ssh keys.&lt;br /&gt;screen -d -m -S server1 -t "my server" ssh myserver.example.com&lt;br /&gt;&lt;br /&gt;# monitoring run time test of my app1 every 67 seconds&lt;br /&gt;screen -d -m -S monitor1 -t "my monitor script" /opt/local/bin/watch -n 67 /home/me/bin/app1_monitor.py&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Finding screen sessions easily&lt;/i&gt;:  you can run these commands:&lt;br /&gt;&lt;code&gt;screen -d -r app1&lt;br /&gt;screen -d -r server1&lt;br /&gt;screen -d -r proxy&lt;/code&gt;&lt;br /&gt;This will let you connect to that screen from any shell.  It detatches any session that's open.  This is good as you can easily remember things with just the short names you choose, eg 'app1' 'proxy' etc.  Normally you have to do 'screen -ls' look at the output, find the session you want to connect to, then finally 'screen -r random_sessionname'.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;At Reboot&lt;/i&gt;: Then you can add this to your crontab with crontab -e (be careful not to use -r!!! which is right next to e on a qwerty keyboard).  Or your crontab web interface with your hosting account( for example cpanel/whm, webmin, plex etc).  Note that each user has a crontab.  So to run your apps as different users, just login and change each ones crontab(or use sudo, or 'su username -l -c' from the roots crontab).&lt;br /&gt;&lt;code&gt;@reboot /home/me/bin/my_screens.sh&lt;br /&gt;# this line below can be used from a root account to run as the user 'me'.&lt;br /&gt;@reboot su me -l -c /home/me/bin/my_screens.sh&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Restarting&lt;/i&gt;: Of course your app might crash or something... Look at the first one... that one has a watch -n 2... which means "run this process, wait for it to finish, then start it again after 2 seconds."  It's kind of like a ghetto daemontools.  Not as good as something like daemontools... but good enough for some purposes.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Monitoring&lt;/i&gt;: You can have a separate tool monitoring your scripts if you like... then if your app has frozen, or is overloaded... just send it some term, then kill signals... and watch will start another one up when it dies.  Consider each script a 'runtime test'.  If the 'runtime test' fails, then kill the app and restart it.  The app could be a ssh proxy for your vpn - in which case the 'runtime test' would see if you can ping the network, and if not kill the ssh connection... so it restarts.  A webserver runtime test might see if it can do a GET request... if not kill the server.  A ghetto monitoring system for sure... but simple.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Logging&lt;/i&gt;: It's pretty easy to add some stderr and stdout redirection with &gt; /home/me/logs/app1stdout &gt;&gt; /home/me/logs/app1stderr.  This way you can have ghetto logging too.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Resource control&lt;/i&gt;: You can use ulimit in your scripts to limit how many resources your server can use.  Then if it uses too much, it will die and be restarted in two seconds.  Say you think your python web server should never *ever* take up 500MB of ram, then run it from a .sh file, and put ulimit -m 500000 before it.  See ulimit -a for a list of things you can limit.  Ghetto-quick resource control.  Similarly you can use nice and ionice to make things behave more nicely :).&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Debugging&lt;/i&gt;: screen doesn't give you an error message with -d -m.  So you can either look in your logs or try out your command first with "screen cmd".  eg "screen python".  You can try out your @reboot command, not just by rebooting but by setting it to run in 10 minutes from now.  See cron help pages for how to do that.  You might want to use a sh -l in front of your command so it's a 'login shell'.  This will setup your paths and environment variables like your login.  Or setup explicitly for each app/script which paths and environment variables they need.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Again this isn't for everyone... but some ideas here might be useful for your own ghetto screen usage for servers and startup scripts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3485373595085921191?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3485373595085921191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3485373595085921191' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3485373595085921191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3485373595085921191'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/09/screen-for-ghetto-servers-and-startup.html' title='screen for ghetto servers and startup scripts.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-3365673854150120506</id><published>2009-09-23T19:57:00.018+01:00</published><updated>2009-09-24T00:23:27.088+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pygame'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='audio'/><category scheme='http://www.blogger.com/atom/ns#' term='randomshit'/><category scheme='http://www.blogger.com/atom/ns#' term='dj'/><category scheme='http://www.blogger.com/atom/ns#' term='vj'/><title type='text'>Linux sound is getting better.</title><content type='html'>No I'm not talking about the &lt;a href="http://www.gnu.org/music/free-software-song.au"&gt;free software song sung by Richard Stallman&lt;/a&gt;(very funny, but in a low quality .au format).  Or the &lt;a href="http://www.youtube.com/watch?v=5IfHm6R5le0"&gt;pronouciation of Linus and linux&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To start on this long-journey-of-a-rambling-diatribe-of-words, there's two good audio patches in the SDL bug tracker for the upcoming SDL 1.2.14 release.&lt;br /&gt;&lt;br /&gt;One patch is for the pulse audio driver, and the other is for the alsa backend.  These solve some of the high latency or scratchy sound issues some have.&lt;br /&gt;&lt;br /&gt;That's right a &lt;b&gt;new SDL release very soon&lt;/b&gt;... it's over a year since the last 1.2.13 release, and it seems like forever since the SDL 1.3 series begun.  Most new development has been happening on the SDL 1.3 tree in the last year... so the 1.2 releases have slowed to an almost stop.&lt;br /&gt;&lt;br /&gt;There's a good article on a x-platform atomic operation API for SDL &lt;a href="http://www.thegrumpyprogrammer.com/node/16"&gt;http://www.thegrumpyprogrammer.com/node/16&lt;/a&gt;.  That's one of the features that's been evolving over a few years, and is being implemented in svn.&lt;br /&gt;&lt;br /&gt;In python terms, SDL 1.3 is like python3000.  A refinement, and a promise to break backwards compatibility with the ABI.  Note, not so much the API... the API is fairly backwards compatible... but some things must change.  Also SDL 1.3 has lots of cool features I'm looking forward to.&lt;br /&gt;&lt;br /&gt;Even though the SDL 1.3 tree is improving, and many people are now switching over to it, the SDL 1.2 series has a lot of life left in it.&lt;br /&gt;&lt;br /&gt;So the SDL 1.2.14 release is all about fixing bugs, and applying patches.  There's a lot of bug reports, and also a lot of patches in the main SDL bug tracker.&lt;br /&gt;&lt;br /&gt;With free software and open source there is the mantra 'release early, release often' (&lt;i&gt;the other mantra is 'release early, then abandon on sourceforge'&lt;/i&gt;).  A stable version, that's used by people needs plenty of bug fixes, and people send in patches.   Whereas a development version doesn't get the same kind of attention as released-and-used-by-people software.  Many of these fixes done on the stable 1.2 tree will also be ported to the 1.3 tree too.&lt;br /&gt;&lt;br /&gt;Now enough SDL 1.3 love... what else is improving in linux audio world?  &lt;i&gt;now for something completely different.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Well, &lt;a href="http://www.pulseaudio.org/"&gt;pulse audio&lt;/a&gt; is frantically making releases.  Three releases in september... so far, and five for 2009.  Pulse and jack are also playing nicer together now(&lt;i&gt;well, not packaged in ubuntu yet... grrrr, see bugs &lt;a href="https://bugs.launchpad.net/ubuntu/+bug/198048"&gt;198048&lt;/a&gt; and &lt;a href="https://bugs.launchpad.net/ubuntu/+source/pulseaudio/+bug/109659"&gt;109659&lt;/a&gt; this is critical for allowing many high end audio programs to work along side the 'beep' sound your terminal makes.  Hopefully they'll get a good &lt;a href="http://webapps.ubuntu.com/employment/canonical_DASE/"&gt;desktop architect (sound experience)&lt;/a&gt; from their job posting to fix things&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jackaudio.org/"&gt;Jack&lt;/a&gt; is the low latency, synchronised audio system used by many professional audio programs on linux.  Think unix pipes applied to audio,  but in a way that works with the audio latency requirements.  Both jack, and pulse audio have been ported to lots of other operating systems these days.  Which can only be good for them getting more developer support... and making the linux audio world better along with it.  You can see in their change logs, and repository commits that developers on different platforms other than linux are contributing quite a lot.&lt;br /&gt;&lt;br /&gt;Even trusty old &lt;a href="http://www.opensound.com/"&gt;Open Sound System&lt;/a&gt;(OSS) has gotten better.  OSS was removed from the kernel, replaced with alsa a while ago... but OSS kept going anyway.  OSS4 has lots of things fixed compared to OSSv3 that most people remember using a long time ago.  Including a fast transparent high quality in kernel mixer(good for crappy cards that only support one program outputing sound at a time).  It also has a "record-what-you-hear" feature... for recording what is coming out of your sound card (&lt;i&gt;a feature MS disabled in vista... booo!&lt;/i&gt;)   The commercial version is now available as open source with a mecurial repository too!  OSS is also quite x-platform.&lt;br /&gt;&lt;br /&gt;What about sound applications?&lt;br /&gt;&lt;br /&gt;The drum machine &lt;a href="http://www.hydrogen-music.org/"&gt;Hydrogen&lt;/a&gt; got a new release for the first time in three years... and this time it's not just linux only too.&lt;br /&gt;&lt;img src="http://www.hydrogen-music.org/images/hydrogen1.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A great DJ program called &lt;a href="http://www.mixxx.org/"&gt;mixxx&lt;/a&gt; is another high quality multiplatform audio program.  It's probably my most favourite audio program... just because it's so fun.  You can even hook up real vinyl decks to it for scratch control(and midi ones).  Unfortunately you can't pipe music in from other audio programs or in from a sound card... so you can't use the vinyl decks in that way.  You have to use specially encoded records which the program then reads to figure out where the record is moving.  The latest version features javascript scripting of midi and other parts of the program.&lt;br /&gt;&lt;img src="http://www.mixxx.org/images/screenshots/mixxx_170_1_th.png" /&gt;&lt;br /&gt;(&lt;i&gt;go on, download it and become a dj ninja&lt;/i&gt;)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://guitarix.sourceforge.net/"&gt;Guitarix&lt;/a&gt; is an amp emulator... it tries to sounds like various vintage guitar amps.  Pretty fun to play around with.&lt;br /&gt;&lt;img src="http://guitarix.sourceforge.net/images/guitarix.png" width="342" height="282" /&gt;&lt;br /&gt;(&lt;i&gt;plenty of knobs to play with&lt;/i&gt;)&lt;br /&gt;&lt;br /&gt;Especially in combination with many of the effect plugins available through the hundreds of &lt;a href="http://www.ladspa.org/"&gt;LADSPA&lt;/a&gt;(guitarix is a LADSPA plugin too) and &lt;a href="http://lv2plug.in/"&gt;LV2&lt;/a&gt; plugins.  Other plugins available include vocoders and all sorts of weirdness.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://git.savannah.gnu.org/cgit/lash.git"&gt;Lash&lt;/a&gt; uptake has been good, and now lash talks dbus... letting it mix in nicely with the rest of the linux desktop ecosystem.  Lash is a session system for linux audio programs.  It lets you open your 12 different linux audio programs(&lt;i&gt;remember audio in linux is like pipes... pipes with audio running through them instead of water... let's call them wires... but digital... maybe fiber optics... but not using light... ok whatever... why am I explaining it this way?... you're not five... too many dots.  sorry.&lt;/i&gt;) and save your settings for later.  The alternative is to each time open your 12 programs, set up the wiring between six of them, start messing around and finally... 2 hours later... realise you were supposed to be setting them up in a certain way rather than making stupid minimal beep noises to a house vocals mixed with a recording of a fart noise - filtered down to retro 8bit samples.  Without lash, you couldn't save that brilliant setup and play with it later.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://audacity.sourceforge.net/"&gt;Audacity&lt;/a&gt;, the simple(yet advanced) audio editing work horse is moving towards a 2.0 by the end of the year.  Audacity has been around for ages, and has been multi platform for ages.  The 1.3 series seems to have been going on forever... but they do regular beta releases, and nightly builds.  So it's pretty easy to get fresh versions.  Do proper releases matter that much when new releases are pushed out every day?  I guess so.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lives.sourceforge.net/"&gt;LiVES&lt;/a&gt; reached 1.0 earlier in the year after a long time in development... (since 2002!).  LiVES is a video editor(which includes audio).  It's actually quite useful for editing video!  The other cool part of it, is that it's a VJ tool.  So you can do those awesome projections you saw the last time you were in a club rushing around the place.  You can control much of LiVES with midi too, which is mice.&lt;br /&gt;&lt;img src="http://lives.sourceforge.net/images/livesmt2.png" /&gt;&lt;br /&gt;(&lt;i&gt;Make home movies of your loved ones.  Like grandpa Nelson here.&lt;/i&gt;)&lt;br /&gt;&lt;br /&gt;In fact lots of audio programs available for linux can be controlled by midi.  Which is mice for me since you can easily do midi with python and &lt;a href="http://www.pygame.org/docs/ref/midi.html"&gt;pygame.midi&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Speaking of things midi and pythony... The vj program &lt;a href="http://freej.dyne.org/"&gt;freej&lt;/a&gt; now has python wrappers!  There are even five tutorials which use pygame.  Unfortunately this is not in release form yet... but all this good stuff happening in the git repos.&lt;br /&gt;&lt;img src="http://freej.org/pics/mask_sospesa_psico_mini.jpg" /&gt;(&lt;i&gt;you too can make video art like this with freej...&lt;/i&gt;  &lt;i&gt;All you need is a crazy mask&lt;/i&gt;)&lt;br /&gt;&lt;br /&gt;Both LiVES and freej use the &lt;a href="http://www.piksel.org/frei0r"&gt;frei0r&lt;/a&gt; video plugins.  Which has nothing to do with linux sound getting better really.  So there.  Jerk(&lt;i&gt;why did this guy even write this?  I wish I didn't waste my time reading it.&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.blogger.com/comment.g?blogID=10678074&amp;amp;postID=3365673854150120506"&gt;Comments?&lt;/a&gt;  Important typos I should fix? Interesting linux audio things you're doing?   Want to tell me how your tomatoes are growing in your garden?  Gott a picture of your cat you'd like to share with me?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-3365673854150120506?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/3365673854150120506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=3365673854150120506' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3365673854150120506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/3365673854150120506'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/09/linux-sound-is-getting-better.html' title='Linux sound is getting better.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-4859167033709236267</id><published>2009-09-22T10:19:00.004+01:00</published><updated>2009-09-22T11:13:44.949+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python3'/><category scheme='http://www.blogger.com/atom/ns#' term='py3k'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Where did the 'new' module go in python 3?</title><content type='html'>Anyone know where the 'new' module went in python 3?&lt;br /&gt;&lt;br /&gt;2to3 can't seem to find 'new', and I can't find anywhere with my favourite search engine either... filed bug at: &lt;a href="http://bugs.python.org/issue6964"&gt;issue6964&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A complete 2to3 tool should know about all modules that are missing at least.  It needs to actually know what to do with those modules, but should be able to at least tell you which modules are missing.  I'm not sure how to get a complete top level module list sanely... I guess by scanning the libs directory of python.  &lt;br /&gt;&lt;br /&gt;Or maybe there is a module to find all python modules?  &lt;br /&gt;&lt;br /&gt;Each platform would be slightly different of course... and there'd be differences based on configure.  Also some modules have probably stopped importing or compiling at all these days.&lt;br /&gt;&lt;br /&gt;Then you could just find the intersection and differences with the lovely set module :)&lt;br /&gt;# find the difference between the modules.&lt;br /&gt;top_level_modules_not_in_3 = set(top_level_modules3series) - set(top_level_modules1_2series)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Well maybe the 2to3 tool could work a different way.  Instead it could find all the modules it *does know about*, and warn you if it encounters modules it doesn't know about.  You can already list fixes with: 2to3-3.1 -l&lt;br /&gt;&lt;br /&gt;But what about packages with submodules?  It seems hard to pin down exactly what's included with python.  Or maybe there is an easy way to find out.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;update:&lt;/i&gt; it is printed as a warning with python2.6 -3 -c "import new" .  The types module is the one to use instead.  A reminder to always use the python2.6 -3 to warn you of things the 2to3 tool can not fix.  python2.6 -3 is a good thing to do on your current code base for preparation for a python 3 future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-4859167033709236267?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/4859167033709236267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=4859167033709236267' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4859167033709236267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/4859167033709236267'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/09/where-did-new-module-go-in-python-3.html' title='Where did the &apos;new&apos; module go in python 3?'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-10678074.post-5594871641299163321</id><published>2009-09-16T11:00:00.013+01:00</published><updated>2009-09-16T17:54:20.016+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python3'/><category scheme='http://www.blogger.com/atom/ns#' term='py3k'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>py3k(python3) more than one year on - 0.96 % packages supporting py3k.</title><content type='html'>Python3 was released more than a year ago so far, and the release candidates and beta releases much before then.&lt;br /&gt;&lt;br /&gt;How successful has the transition been to python3 so far?&lt;br /&gt;&lt;br /&gt;One way to measure that is to look at how many python packages have been ported to py3k.  One way to measure what packages are released is to look at the &lt;a href="http://pypi.python.org/"&gt;python package index(aka cheeseshop, aka pypi)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Not all packages ported to python3 are listed on pypi, and not all packages are listed on pypi.  Also there are many packages which haven't been updated in a long time.  However it is still a pretty good way to get a vague idea of how things are going.&lt;br /&gt;&lt;br /&gt;73 packages are listed in the python3 section of pypi, and 7568 packages in total.  That's 0.96% of python packages having been ported to python3.&lt;br /&gt;&lt;br /&gt;Another large project index for python is the &lt;a href="http://www.pygame.org/"&gt;pygame.org&lt;/a&gt; website.  Where there are currently over 2000 projects which use pygame.  I think there are 2 projects ported to python3 on there(but I can't find them at the moment).  This shows a section of the python community using it in projects.  Most of the things listed on pypi are packages - not projects.  It's showing what people are using for their projects - not what their libraries support.  In a similar way, it could be good to see how many websites are running on top of python3.  I think a lot of the people who have ported to python3 aren't really using it for their projects, but have done the porting work as a good will measure towards moving python forward.&lt;br /&gt;&lt;br /&gt;Another way to measure the success of the migration, is to pick a random sampling of some popular packages and see if their python3 support exists.&lt;br /&gt;&lt;br /&gt;Pygame(yes), Pyopengl(no), pyglet(no), numpy(no), PIL python imaging library(no), cherrypy(yes), Twisted(no), zope.interface(no), buildout(not sure, I think no), setuptools(no, patches available), django(no), plone(no), psyco(no), cython(yes), swig(yes), sqlalchemy(no).&lt;br /&gt;&lt;br /&gt;With some packages being used by 1000s or 10,000s of projects, those popular projects hold back the py3k migration significantly.  It would seem that some applied efforts to the right projects would help the py3k migration a lot.  Perhaps a py3k porting team could be made to help port important libraries to py3k.&lt;br /&gt;&lt;br /&gt;How about other python implementations supporting python3 features?  None have full python3 support as of yet.  For example jython(no), pypy(no), ironpython(no), tinypy(no), python-on-a-chip(no), unladenswallow(no), shedskin(no).  However some implementations support some new python3 features.&lt;br /&gt;&lt;br /&gt;How about wsgi?  wsgi is the python specification for web gateways... that it specifies how different web frameworks, web servers and applications can talk to each other and out to http.  The wsgiref module in python3 is somewhat broken, and the amendments for python3 have not made it into a new wsgi spec.  However work is being done towards it with a couple of major wsgi users supporting python3(cherrypy and mod_wsgi).&lt;br /&gt;&lt;br /&gt;Another question to ask is: 'are many projects planning to support py3k soon?  Or have they decided not to work on py3k at all yet?'.  It seems many projects have decided not to put in the work yet.  At this point, for many projects they don't see enough benefit towards moving to py3k.  Or their dependencies have not been ported, and they are waiting on those to be ported before beginning to port themselves.&lt;br /&gt;&lt;br /&gt;How well have the python developers themselves developed the support material for people upgrading their code?  It looks like the cporting guide is still incomplete and hasn't been updated in a while.  However the CPython API using projects have taken up the slack... so there are now a number of extensions for people to look at for guidance.  It's possible to make CPython extensions which support both 2.x and 3.x APIs.&lt;br /&gt;&lt;br /&gt;There is now a 3to2 script being worked on.  This allows projects to write their code in python3 code, and have it translated into python2 code.  The python developers realised that having a 2to3 script was backwards in a way - requiring developers to stick with their python 2 code.  However, many projects seem to not use the translation script, since it hasn't worked for them.  Instead they seem to have either made separate branches, or made their code so that it works in both 2.x and 3.x.&lt;br /&gt;&lt;br /&gt;Support for python3 was dropped, and python3.1 is the new python3.  However python3 still exists in some distributions (like ubuntu).&lt;br /&gt;&lt;br /&gt;So how are the various OS distributions going with their python3 support?  The latest version of OSX to be released (snow leopard) uses a version of python2.6.1.  Most unix distributions are using python2.6 as their main python at the moment.  However most of them have also packaged python3.x as well.  So it's fairly easy for people to try out python3 alongside their python2.x installation(s).  macports currently has py25(286 ports), py26(206 ports), py30(0 ports... since py3.0 isn't supported by python.org), and py31(4 ports).  So for macports, it has 1.9% of py31 packages ported compared to py25.  This shows similar percentage to the ratio of ported packages in the pypi index(0.96%).&lt;br /&gt;&lt;br /&gt;This is not mirrored by the number of windows downloads from python.org.  Python2.6.2 windows installer had 786400 downloads, python2.5.4(104291), python 3.1(241363) 3.1.1(214871) for a total of 456234 for 3.x.  This is around 58% comparing 2.6 and (3.0+3.1).  Strangely about the same amount of people are downloading 3.0 as 3.1 - even though it states that 3.1 is the new py3k and 3.0 is not supported anymore.  This is just windows download counts for August... if you compare it to most unix distributions, they almost all come with python2.5 or python2.6.&lt;br /&gt;&lt;br /&gt;So, is the python3 migration going along swimmingly?  Or has it failed to reach its goals(what were its goals if any)?  What can we do to help?  Should we even help at this point?  &lt;a href="https://www.blogger.com/comment.g?blogID=10678074&amp;postID=5594871641299163321"&gt;comments&lt;/a&gt;?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10678074-5594871641299163321?l=renesd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://renesd.blogspot.com/feeds/5594871641299163321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=10678074&amp;postID=5594871641299163321' title='32 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5594871641299163321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/10678074/posts/default/5594871641299163321'/><link rel='alternate' type='text/html' href='http://renesd.blogspot.com/2009/09/py3kpython3-more-than-one-year-on-096.html' title='py3k(python3) more than one year on - 0.96 % packages supporting py3k.'/><author><name>notme</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/_eJJgehXCsQ4/TE10SeUr1qI/AAAAAAAAAIE/SzR-BlSvV1I/s1600-R/rd.png'/></author><thr:total>32</thr:total></entry></feed>
