<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

	<title type="text" xml:lang="en"></title>
	<link type="application/atom+xml" href="http://matthias-endler.de/feed/" rel="self"/>
 	<link type="text" href="http://matthias-endler.de" rel="alternate"/>
	<updated>2013-05-03T04:20:01-07:00</updated>
	<id>http://matthias-endler.de</id>
	<author>
		<name>Matthias Endler</name>
	</author>
	<rights>Copyright (c) Matthias Endler; all rights reserved.</rights>

	
	<entry>
		<title>Tools</title>
		<link href="http://matthias-endler.de/2011/Tools"/>
		<updated>2011-10-30T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2011/Tools</id>
		<content type="html">&lt;p&gt;As long as I can think, Computer Science has been infected by religious flamewars. Having arguments about technical topics can be healthy but flamewars are not. I&amp;#8217;m sick of it. I&amp;#8217;m fed up by people telling me that their work environment is oh-so better, faster and so on. That&amp;#8217;s fine but it doesn&amp;#8217;t matter. Your equipment only plays a supporting role. You don&amp;#8217;t even need a computer to do programming. Donald Knuth wrote algorithms on a notepad. Alan Turing wrote the first chess computer on a piece of paper. And it worked. Beat that!&lt;/p&gt;

&lt;p&gt;For an average user, the next best system is probably good enough. Just a few bucks and you get a fine piece of hardware which is completely sufficient to surf the web, chat, archive photos, write documents, listen to music and watch movies. You can do that with a Pentium IV, 256 MB RAM and any recent Operating System (you will likely get that one for free). Heck, you can use your old Commodore for most of that. Computers have been mature and reliable enough to do all that for ages. There&amp;#8217;s really no need to upgrade your system for Farmville, just like there&amp;#8217;s no reason to buy a new car if the old one works perfectly fine. When it comes to software, many of us still use Office 2000 or Photoshop 8 or VisiCalc without feeling the urge to upgrade.&lt;/p&gt;

&lt;p&gt;Professionals find themselves in a similar situation. Well, maybe we invest a bit more money but still our hardware is incredibly cheap compared to our salary (hopefully). Nothing is perfect, but most of the time &lt;em&gt;it&amp;#8217;s good enough&lt;/em&gt;. That compiler you were using a decade ago? Still does the job. We are still using slightly modified descendents of programming languages from computing stone-age. Even if you&amp;#8217;re doing numerical computing for NASA, your basic work environment is a black box running a text editor or an IDE.&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t care what &lt;em&gt;you&lt;/em&gt; are using to get things done. Find an environment that suits &lt;em&gt;your&lt;/em&gt; needs and be happy with it. Maybe you use Emacs on a Lemote Yeelong netbook (hello Richard Stallman) or Vim on your workstation. It&amp;#8217;s basically the same thing: A text editor running on a piece of metal. You&amp;#8217;re not a worse programmer for using Nano, ed or TextMate. Notepad works just fine, too. It loads files, saves files and lets you edit them in between. That&amp;#8217;s a hell lot more functionality than Bill Gates and Paul Allen had when they wrote a BASIC interpreter for the Altair. If you find something you&amp;#8217;re happy with, just stick with it but don&amp;#8217;t start arguing. It really isn&amp;#8217;t worth your time.&lt;/p&gt;

&lt;p&gt;Don&amp;#8217;t feed the trolls. When it comes to software, don&amp;#8217;t fall into the old FreeBSD vs. Linux vs. Windows vs. mum cliche. Instead talk about your code. Let&amp;#8217;s look at your problem solving skills. Let&amp;#8217;s be pragmatic here.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;Talk is cheap. Show me the code.&amp;#8221; - &lt;a href='http://lkml.org/lkml/2000/8/25/132'&gt;Linus Torvalds&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I don&amp;#8217;t care which programming language you are using. Java? Fine. Visual Basic? Great! Scala, Cobol, PHP, C++? All fine. Write in Assembler or lolcode. Don&amp;#8217;t mourn about the fact that language X is missing feature Y. Write a library or use something different. Stop saying JavaScript is a toy language. It just doesn&amp;#8217;t fit your needs. Instead show me your Lisp adventure game. Write an interpreter for Brainfuck. Do something. Move things.&lt;/p&gt;

&lt;p&gt;Concerning PHP, &lt;a href='http://news.ycombinator.com/item?id=2282523'&gt;nir&lt;/a&gt; wrote on Hackernews:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any idiot can write a snarky comment about PHP. Very few get to write code that has anywhere near the impact it had.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Will you fall off your chair when I admit that I &lt;em&gt;like&lt;/em&gt; the PHP syntax? OK, it has its rough edges (do we really need the $ sign?) but what&amp;#8217;s more important is how much I can get done with it. PHP was my long time go-to language for off the hook, one time scripts. It looks a bit ugly but it runs on any server and comes with an enormous amount of built-in functionality. It&amp;#8217;s great for rapid prototyping and gluing things together. In fact, when you write a piece of software, what you should strive for is to produce &lt;em&gt;quite good&lt;/em&gt; software and what you really need to accomplish is &lt;em&gt;good enough&lt;/em&gt; software to make your users happy.&lt;/p&gt;

&lt;p&gt;Zed A. Shaw puts it quite nicely in the afterword to &lt;a href='http://learnpythonthehardway.org/'&gt;Learn Python the hard way&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I have been programming for a very long time. So long that it is incredibly boring to me. At the time that I wrote this book I knew about 20 programming languages and could learn new ones in about a day to a week depending on how weird they were. Eventually though this just became boring and couldn&amp;#8217;t hold my interest. What I discovered after this journey of learning was that the languages didn&amp;#8217;t matter, it was what you did with them. Actually, I always knew that, but I&amp;#8217;d get distracted by the languages and forget it periodically. Now I never forget it, and neither should you.The programming language you learn and use does not matter. Do not get sucked into the religion surrounding programming languages as that will only blind you to their true purpose of being your tool for doing interesting things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don&amp;#8217;t get emotional for any tool you use. An iPhone - I&amp;#8217;m sorry to disappoint you - is just a phone. No magic. No &amp;#8220;think different&amp;#8221;. &amp;#8220;But it&amp;#8217;s evil!&amp;#8221;, the ether says, &amp;#8220;it&amp;#8217;s not open source&amp;#8221;. Well, Android just exists because Google needed to rapidly develop a mobile platform. It&amp;#8217;s simply part of their business. There is no moral behind that. Google is a yet another company just like Microsoft or Apple.&lt;/p&gt;

&lt;p&gt;My MacBook serves me as a good tool but if something &amp;#8220;better&amp;#8221; comes around I will happily kick it out. I&amp;#8217;ve ditched Firefox after five years just because Chrome is faster and I will get rid of Chrome when I find a worthy successor. Vim is &lt;em&gt;quite good&lt;/em&gt; in my opinion but if there&amp;#8217;s a faster way to do things I&amp;#8217;m not afraid to dump it. Instead get your hands dirty and fix the problems or craft something new.&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>Are You A Programmer?</title>
		<link href="http://matthias-endler.de/2011/Are-You-A-Programmer"/>
		<updated>2011-10-20T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2011/Are-You-A-Programmer</id>
		<content type="html">&lt;p&gt;My geography teacher once told the story of her first university lecture. As an introduction, her professor asked the class to draw a map of Germany without any help and as accurate as possible. To her surprise she was not able to fill the map with much detail. Even the shape of the country was a bit vague.&lt;/p&gt;

&lt;p&gt;She had seen thousands of images of Germany (her mother country) but wasn&amp;#8217;t able to reproduce it from her blurry memory. She would have to look it up.&lt;/p&gt;

&lt;p&gt;Doesn&amp;#8217;t this sound familiar? We rely on machines to manage large potions of our knowledge. There&amp;#8217;s &lt;a href='http://www.matthias-endler.de/2011/On-hard-work/'&gt;hard work&lt;/a&gt; involved to learn something by heart.&lt;/p&gt;

&lt;p&gt;Here is a similar test for programmers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using a programming language of your choice, write a correct sorting algorithm with an average runtime complexity of O(n*log n) (Heapsort, Quicksort, Bucketsort, you name it) on a piece of paper without the help of any external tools.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And by &lt;em&gt;correct&lt;/em&gt; I mean it must be free of bugs without any modifications when you type it in.&lt;/p&gt;

&lt;p&gt;You would be surprised by the large percentage of professional software engineers who &lt;a href='http://www.codinghorror.com/blog/2007/02/why-cant-programmers-program.html'&gt;can&amp;#8217;t pull this off&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some might argue that knowledge about details of programming language syntax is unimportant: &amp;#8220;Why learn all the little nitpicks when you know how to use a search engine? Why start from a blank sheet when you can easily copy, paste and modify an example from a tutorial? Every few years/months I have completely relearn the syntax for a different language anyway.&amp;#8221;&lt;/p&gt;

&lt;p&gt;But that is a myth. If you know only one programming language &lt;strong&gt;really&lt;/strong&gt; well - even if it is something outdated like Fortran or COBOL - you could easily earn a fortune with that knowledge. Suppose you started with C in 1975. You could still use the same syntax today - almost four decades later. Same for text editors. Emacs and Vim are both decades old. They are battle-hardened. I don&amp;#8217;t care which one you prefer but you will spend most of your life with these tools so invest the time to use them really well.&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;If you don&amp;#8217;t know how to use your tools without a manual, you are a bad craftsman. If you need a dictionary to write a simple letter, you will have a hard time being a writer because it would already be challenging for you to form elegant, fluent sentences &amp;#8211; let alone engaging and original stories. I don&amp;#8217;t want to read these books.&lt;/p&gt;

&lt;p&gt;What makes a programmer?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;She has at least one programming language she knows inside out.&lt;/li&gt;

&lt;li&gt;She is able to implement standard algorithms (i.e. for sorting, searching) and data-structures (i.e. trees, linked lists) which are robust and reasonably fast on the fly.&lt;/li&gt;

&lt;li&gt;She has at least a basic understanding of complexity theory and programming concepts like recursion and pointers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But, to be a good programmer, you should&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be able to code in at least two fundamentally different programming paradigms (i.e. declarative, functional).&lt;/li&gt;

&lt;li&gt;Have experience with big software architectures.&lt;/li&gt;

&lt;li&gt;Be familiar with your programming environment like the operating system and a sophisticated text editor of your choice. Preferably one, that is easily extendable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that is just the tip of the iceberg. &amp;#8220;There&amp;#8217;s too much to learn!&amp;#8221;, I hear some of you say. Start slowly. You need only three commands to start with Vim: &lt;code&gt;i&lt;/code&gt;, &lt;code&gt;ESC&lt;/code&gt;, &lt;code&gt;:wq&lt;/code&gt;. That&amp;#8217;s enough for day one.&lt;/p&gt;

&lt;p&gt;I realize that most of these essentials won&amp;#8217;t be taught during lectures. You have to learn a huge portion on your own. But let&amp;#8217;s face it: If you don&amp;#8217;t know this stuff, you are &lt;em&gt;not&lt;/em&gt; a programmer, you&amp;#8217;re a freshman.&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;It seems that very few people strive for perfection in anything they do. They happily settle for &amp;#8220;good enough&amp;#8221;. This can have many different reasons and I&amp;#8217;m not blaming anybody for not doing his homework but maybe I&amp;#8217;m not alone with that observation.&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
	</entry>
	
	<entry>
		<title>On hard work</title>
		<link href="http://matthias-endler.de/2011/On-hard-work"/>
		<updated>2011-10-13T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2011/On-hard-work</id>
		<content type="html">&lt;p&gt;Great people get shaped by their achievements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There&amp;#8217;s Thomas Edison who developed countless protoypes before selling a single light bulb.&lt;/li&gt;

&lt;li&gt;The unemployed Joanne K. Rowling writing Harry Potter in a Café while caring for her child.&lt;/li&gt;

&lt;li&gt;Steve Wozniak creating the first personal computer in his spare time while working at HP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What do they have in common?&lt;/p&gt;

&lt;p&gt;They all lived through frustration and contempt but still reached their goals, even though the chances for success were low. These people are stemming their strong will from an intrinsic curiosity.&lt;/p&gt;

&lt;h3 id='dedication'&gt;Dedication&lt;/h3&gt;

&lt;p&gt;Sure, I love what I do. I want to be a programmer for the rest of my life, but sometimes it seems simply too hard to finish a project. I get scared by the big picture and fear that I won&amp;#8217;t finish on time. What I need is a different mindset.&lt;/p&gt;

&lt;p&gt;Dhanji R. Prasanna, a former Google Wave team member &lt;a href='http://rethrick.com/#mmm'&gt;made this observation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And this is the essential broader point&amp;#8211;as a programmer you must have a series of wins, every single day. It is the Deus Ex Machina of hacker success. It is what makes you eager for the next feature, and the next after that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While Google Wave has not been commercially successful, it sure was a technical breakthrough &amp;#8211; and it was a drag to push it out into public. We always have to see our goal right in front of us, as we take a billion baby steps to reach it. This is true for any profession. Winners never give up.&lt;/p&gt;

&lt;h3 id='direction'&gt;Direction&lt;/h3&gt;

&lt;p&gt;Today it is easier to accomplish something meaningful than ever before.&lt;/p&gt;

&lt;p&gt;If you are reading this, you have access to a powerful instrument &amp;#8211; a computer with an Internet connection. We live in a time where a single person can accomplish miracles without hard physical labor. A time where billions of people can grow a business from their desk, get famous in minutes, publish books in seconds and have instant access to large amounts of data. The most powerful development over the last 100 years has been the reduction of communication costs. Transferring a bit of information to the other end of the world is virtually free and takes fractions of a second. While proper education was a privilege of a lucky few well into the 20th century, learning new things is now mostly a question of will.&lt;/p&gt;

&lt;p&gt;&lt;img src='/media/pictures/work.jpg' alt='Laptop on a pillow next to a book' /&gt;&lt;/p&gt;

&lt;p class='caption'&gt;Photo by &lt;a href='http://www.flickr.com/photos/zitona/5021203226/'&gt;Zitona&lt;/a&gt; (CC BY 2.0)&lt;/p&gt;

&lt;p&gt;Nevertheless, learning is still a tedious task, requiring patience and determination &lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;. As the amount of information has increased, so have the kinds of distraction. Losing focus is just a click away.&lt;/p&gt;

&lt;h3 id='devotion'&gt;Devotion&lt;/h3&gt;

&lt;p&gt;Everybody can start something. Few will finish anything. That&amp;#8217;s because getting things done is hard, even if you love what you&amp;#8217;re doing &lt;sup id='fnref:2'&gt;&lt;a href='#fn:2' rel='footnote'&gt;2&lt;/a&gt;&lt;/sup&gt;. No matter what they tell you, achieving anything sustainable means hustling. It means making sacrifices. It means pushing through. It means selling something even though it isn&amp;#8217;t perfect. Your elegant project might turn into an ugly groundhog in the end. Put makeup on it and get it out the door.&lt;/p&gt;

&lt;p&gt;On a report about &lt;a href='http://www.bluesnews.com/abrash/chap70.shtml'&gt;Quake&amp;#8217;s 3D-Engine&lt;/a&gt;, developer Michael Abrash says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By the end of a project, the design is carved in stone, and most of the work involves fixing bugs, or trying to figure out how to shoehorn in yet another feature that was never planned for in the original design. All that is a lot less fun than starting a project, and often very hard work&amp;#8211;but it has to be done before the project can ship. As a former manager of mine liked to say, “After you finish the first 90% of a project, you have to finish the other 90%.” It’s that second 90% that’s the key to success. [&amp;#8230;] A lot of programmers get to that second 90%, get tired and bored and frustrated, and change jobs, or lose focus, or find excuses to procrastinate. There are a million ways not to finish a project, but there’s only one way to finish: Put your head down and grind it out until it’s done. Do that, and I promise you the programming world will be yours.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That last part has influenced me a lot. The dedication, the urgency to reach your aims must come from within you. It&amp;#8217;s your raw inner voice speaking &amp;#8211; don&amp;#8217;t let it fade away. And when you are close to giving up, stop thinking so hard. Just try to push forward and make a tiny step in the right direction. You can&amp;#8217;t lose.&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;If you allow me to dream for a second, I presume that during the next few decades, this last hurdle might also be eliminated. Learning would simply be a matter of uploading files onto an organic storage device. Naturally, automatic learning will be a privilege of rich and adventurous people in the beginning. But just as space tourism, I am convinced that it will be accessible to everybody in the long run. On the other hand, mere knowledge is useless. It is applying and adapting knowledge to new situations (creativity), which sets us apart from machines.&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:2'&gt;
&lt;p&gt;Watch the beginnings of &lt;em&gt;There Will Be Blood&lt;/em&gt; and &lt;em&gt;Primer&lt;/em&gt; for a definition of &lt;em&gt;hard work&lt;/em&gt;.&lt;/p&gt;
&lt;a href='#fnref:2' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
	</entry>
	
	<entry>
		<title>An open letter to Apple</title>
		<link href="http://matthias-endler.de/2011/An-Open-Letter-To-Apple"/>
		<updated>2011-10-01T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2011/An-Open-Letter-To-Apple</id>
		<content type="html">&lt;p&gt;Since I work on a computer for most of the day I like to have the darn best thing I can afford to get my stuff done. For the last five years I have exclusively used a MacBook and afterwards a MacBook Pro and I have no doubt I paid a premium price for a premium product. Yeah, I&amp;#8217;m also paying a premium price for every RAM extension, Mini Display Port - DVI adapter and keyboard made by Apple, too&amp;#8230;and I&amp;#8217;m totally fine with it.&lt;/p&gt;

&lt;p&gt;Most of the time MacBooks are great machines, fun to work with and well worth the higher price tag. Some parts of it just stink, though.&lt;/p&gt;

&lt;p&gt;Today I had a nice conversation with an Apple advisor (as they call them) because my power supply is broken. Again.&lt;/p&gt;

&lt;p&gt;So here is a picture of the power supply:&lt;/p&gt;

&lt;p&gt;&lt;img src='/media/pictures/power_supply1.jpg' alt='Damaged power supply' /&gt;&lt;/p&gt;

&lt;p&gt;You can clearly see where the cable is broken. It&amp;#8217;s right at the spot where the protective sheath is ending.&lt;/p&gt;

&lt;p&gt;I know this is the place where the cable is bent when it gets rolled up. The advisor basically told me that I have to pay the price for being too stupid to roll up a cable. But I think that&amp;#8217;s the way the cable is &lt;em&gt;supposed&lt;/em&gt; to be rolled up according to all their advertisement images.&lt;/p&gt;

&lt;p&gt;&lt;img src='/media/pictures/power_supply2.jpg' alt='Damaged power supply' /&gt;&lt;/p&gt;

&lt;p&gt;Let me clarify: My current machine is a MacBook Pro bought in April 2010, so I&amp;#8217;m out of warranty. Apple is not obliged to compensate. A replacement would be a gesture of good will. On the other hand I consider this a manufacturing error and a security risk.&lt;/p&gt;

&lt;p&gt;Oh and while we&amp;#8217;re at it, the new L-shaped magsafe plug is also badly designed. The whole purpose of that thing is to prevent damages when somebody stumbles over the cord. But unfortunately the protection mechanism won&amp;#8217;t work if the person is coming from the wrong side. Here&amp;#8217;s a picture that explains what happens:&lt;/p&gt;

&lt;p&gt;&lt;img src='/media/pictures/Macbook-Magsafe.jpg' alt='Stumbling over the cable from left to right pulls the laptop off the table' /&gt;&lt;/p&gt;

&lt;p&gt;Come on Apple. Hardware defects and design issues are normal. This shit can happen. But when it&amp;#8217;s clearly your fault don&amp;#8217;t blame your clients. I&amp;#8217;ve invested a lot of money into your products during the last few years (both for private and corporate use) and I don&amp;#8217;t hope you want to loose me as a customer.&lt;/p&gt;

&lt;p&gt;Seems like I need to buy a new one. The fourth power supply for only two laptops. But nevertheless I&amp;#8217;m sending my power supply back to you. Do with it what you want. Rant over.&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>My experiences with Feedback Roulette</title>
		<link href="http://matthias-endler.de/2011/Feedback-Roulette"/>
		<updated>2011-08-12T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2011/Feedback-Roulette</id>
		<content type="html">&lt;p&gt;&lt;a href='http://www.feedbackroulette.com'&gt;Feedback Roulette&lt;/a&gt; is awesome. The page reviews are honest and detailed. Here are a few comments I received so far:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The site is slow, not sure if it&amp;#8217;s my connection, but response time is high.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This tip helped me dig a little deeper into SEO (despite I passionately hate the term). I&amp;#8217;ve minified the CSS and Javascript files, used spriting and am now using a CDN, namely &lt;a href='https://www.cloudflare.com/login.html'&gt;Cloudflare&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Was expecting the penguin to click and lead me to the home page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was a quick and easy fix that can be done in a couple of minutes. I didn&amp;#8217;t realize that and was happy when somebody pointed it out.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On your movies page you could link to Amazon with an affiliate code, that way if people buy the movie on amazon you get some money.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I see where this is coming from but on my private homepage I&amp;#8217;m not out for the quick buck. I was thinking about creating a wiki for the genre, though.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;Projects&amp;#8221; areas are always tough when you when you only have a few active projects. May be add a github activity feed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since then I&amp;#8217;ve added some more projects but the activity stream is definitely something to think about.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The site doesn&amp;#8217;t load quite right in Opera. It&amp;#8217;s hard to explain, but above the link for &amp;#8220;Blog&amp;#8221; it says &amp;#8220;Blog&amp;#8221; again in another box. This box stays across all the other pages (but it&amp;#8217;s always &amp;#8220;Blog&amp;#8221;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This behaviour is quite weird. Until now I couldn&amp;#8217;t find out what causes it. It may well be an Opera bug but since I&amp;#8217;m not an Opera user and this is a tiny private homepage I didn&amp;#8217;t bother too much.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The links appear on the right-hand side and then the search box appears, pushing them to the left.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &amp;#8220;pushing&amp;#8221; is caused by an ajax call to Google search: As soon as the search script got loaded, the search box gets added to the DOM. Naturally the solution was pretty simple. I swapped the search box and the links.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I think the text in the articles should be a bit smaller, I just find it slightly too large for a lot of reading.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I like big text. Nevertheless I had to admit that it was just a little too big.&lt;/p&gt;

&lt;p&gt;All these comments came from real users and it would have been hard to find such responses by asking my friends. So the bottom line is this: If you have a little webdesign project and want some quick user reviews without all the hassle of A/B testing, Feedback Roulette may be what you are looking for.&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>Digg &ndash; a case study for the social web</title>
		<link href="http://matthias-endler.de/2010/Digg-a-case-study-for-the-social-web"/>
		<updated>2010-10-27T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2010/Digg-a-case-study-for-the-social-web</id>
		<content type="html">&lt;p&gt;We are only at the beginning of a personal web. Presently social communities are humble experiments with lots of room for improvement. Twitter, Facebook, MySpace they all made failures along the way. They test different approaches to filter, personalize and rate the endless stream of information and it&amp;#8217;s just natural that they don&amp;#8217;t get it right the first time.&lt;/p&gt;

&lt;p&gt;The tricky part is to gain new users while making sure that longtime members won&amp;#8217;t opt-out. A few minor changes can lead to a hazardous outcry and a persistent loss of faith in the platform. Just recently the social-bookmarking site &lt;a href='http://www.digg.com'&gt;Digg&lt;/a&gt; suffered from these powerful group dynamics.&lt;/p&gt;

&lt;h3 id='taking_the_wrong_way'&gt;Taking the wrong way&lt;/h3&gt;

&lt;p&gt;In the beginning the site had a strong focus on tech news. It played an important role for the geek and hacker culture. People posted the &lt;a href='http://en.wikipedia.org/wiki/AACS_encryption_key_controversy'&gt;AACS encryption key&lt;/a&gt; on that page and &lt;a href='http://www.zdnet.com/blog/web2explorer/interview-with-digg-founder-kevin-rose-part-1/108'&gt;shared photos from Paris Hilton&amp;#8217;s hacked phone&lt;/a&gt;. But in order to grow, they opened up to a broader audience featuring news about sports and politics. Diggs&amp;#8217; reputation as an authority on tech news suffered from that move&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Experiencing high pressure from a close-knit community they strived to innovate, creating a huge plan to reinvent web-publishing which turned out to be a misguided strategy. They&amp;#8217;ve made the rating system too complex and opaque, removed important features (like the &lt;em&gt;upcoming&lt;/em&gt; section and the &lt;em&gt;bury&lt;/em&gt;-button) ignoring their loyal user base that favored grassroots democracy and disliked the extensive modifications.&lt;/p&gt;

&lt;p&gt;That said, Diggs intentions were honorable. In order to deal with the ever-increasing demand, they&amp;#8217;ve created a sophisticated distributed system powered by a non-relational database (Cassandra) and a personal front-end called &lt;em&gt;My news&lt;/em&gt;. When &lt;a href='http://www.youtube.com/watch?v=jk0RS_x37uk&amp;amp;fmt=35'&gt;Kevin Rose explained the new system&lt;/a&gt;, I was quite enthusiastic. But the (database) transition was not flawless and the focus on &lt;em&gt;mainstream outlets&lt;/em&gt; was in my opinion a bit misguided. Some former power users even &lt;a href='http://ltgenpanda.tumblr.com/post/1403230157/did-digg-game-its-own-system-to-benefit-publisher'&gt;speculated whether Digg became a promotion platform for newspapers&lt;/a&gt;. While these accusations &lt;a href='http://about.digg.com/blog/info-site-changes-and-test-accounts'&gt;may be wrong&lt;/a&gt;, it shows the core problem: Proficient users don&amp;#8217;t trust Digg anymore.&lt;/p&gt;

&lt;p&gt;On the Digg comment thread to the above story, &lt;a href='http://digg.com/news/technology/did_digg_game_its_own_system_to_benefit_publisher_partners/20101026024734:93bb47f471bc4cd297c0bec69ea49bb5#20101026060300:141ffa4c70b94f75a1b279036d230bcf'&gt;&lt;em&gt;endersgame&lt;/em&gt; put it like this&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since the launch of v4, Digg has lost all credibility and believe it or not that is very important. The reason Reddit is so successful is because the users feel like they are a part of the site. They feel like they have direct control over how the site works.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Take away the upper twenty percent of contributors to any &lt;em&gt;social&lt;/em&gt; web-app and all that remains is a wasteland of shallow stories and comments &amp;#8212; web mediocracy. On an aggregate news site like Digg, this could mean that the stories are already a few days old when they hit the front page. Therefore lively discussions &amp;#8211; the main product of crowd sourcing &amp;#8211; take place on other websites. Fewer comments lead to fewer visits which lead to even fewer comments. A vicious circle that eventually destroys a great community. So maybe Digg took the wrong way but I really hope they can recover. A lighter, more transparent version might be the answer.&lt;/p&gt;

&lt;h3 id='up_next'&gt;Up next&lt;/h3&gt;

&lt;p&gt;After seeing all this happen to Digg I&amp;#8217;m curious if &lt;a href='http://www.reddit.com'&gt;Reddit&lt;/a&gt; and &lt;a href='http://news.ycombinator.com'&gt;Hacker news&lt;/a&gt; can cope with the upcoming traffic explosion&lt;sup id='fnref:2'&gt;&lt;a href='#fn:2' rel='footnote'&gt;2&lt;/a&gt;&lt;/sup&gt;. While the former is a respectable bookmarking platform, I personally prefer the latter for the profound discussons on technical topics. Basically it&amp;#8217;s a single table with links to great ideas and inspiring projects. In contrast to many other social bookmarking sites, there is a lot less &lt;em&gt;comment noise&lt;/em&gt; (although the babel/visitors ratio may be roughly as high as on &lt;a href='http://www.reddit.com/r/programming/'&gt;/r/programming&lt;/a&gt;). The hive mind recognizes most trolling attempts. The filter systems are not perfect but quite good.&lt;/p&gt;

&lt;h3 id='lessons_learned'&gt;Lessons learned&lt;/h3&gt;

&lt;p&gt;All websites are constantly exposed to the whims of their users but tech sites &amp;#8211; with a lot of their regular visitors being geeks and hackers &amp;#8211; have a particularly difficult position. Hacking is all about learning from others and making contributions to the community. It is about game mechanics, curiosity and reputation &amp;#8211; not money. A hacker notices when his skills are abused &amp;#8211; and moves on. These are the reasons why hackers are happy to answer questions on &lt;a href='http://www.stackoverflow.com'&gt;StackOverflow&lt;/a&gt; but shy away from &lt;a href='http://www.experts-exchange.com/'&gt;ExpertsExchange&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a fair, simple, open system and hackers will bring the rest. That&amp;#8217;s what Paul Graham did with Hacker News. He looked at some existing social bookmarking sites like Reddit, ripped out all the superfluous parts and iterated from there. Revenue was never on the todo list. No shiny design, no pictures, no videos, no media outlets. It has the flair of an early &lt;a href='http://www.slashdot.com'&gt;Slashdot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s an &lt;em&gt;Anti-Digg&lt;/em&gt; if you want. It makes &lt;a href='http://www.codinghorror.com/blog/2010/09/go-that-way-really-fast.html'&gt;lots of minor changes&lt;/a&gt; instead of abruptly releasing a whole new system like Digg did with v4. It&amp;#8217;s pure &lt;a href='http://en.wikipedia.org/wiki/KISS_principle'&gt;KISS&lt;/a&gt;. A minimalist approach to social bookmarking. It does not &lt;em&gt;try&lt;/em&gt; to be popular. In fact most regular visitors would be happy if it stays small&lt;sup id='fnref:3'&gt;&lt;a href='#fn:3' rel='footnote'&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;But rest assured there are roadblocks ahead. While the community will grow, quality of content is endangered to go south. Let&amp;#8217;s see how long this will work out&lt;sup id='fnref:4'&gt;&lt;a href='#fn:4' rel='footnote'&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;Facebook was in a similar situation when they opened for non-students. But in contrast to Digg the outcome was not fatal (actually quite fertile).&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:2'&gt;
&lt;p&gt;Subreddits are quite nice to canalize the information overflow. I propose such a system for HN looking at the increasing number of news that make the front page.&lt;/p&gt;
&lt;a href='#fnref:2' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:3'&gt;
&lt;p&gt;It was initially a side project to test an experimental programming language called Arc.&lt;/p&gt;
&lt;a href='#fnref:3' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;li id='fn:4'&gt;
&lt;p&gt;Presently I&amp;#8217;m quite happy even though I&amp;#8217;m spending more and more time on &lt;a href='http://hckrnews.com/'&gt;alternative&lt;/a&gt; &lt;a href='http://metaoptimize.com/projects/autotag/hackernews/'&gt;interfaces&lt;/a&gt;.&lt;/p&gt;
&lt;a href='#fnref:4' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
	</entry>
	
	<entry>
		<title>Importing old Wordpress backups into Intense Debate</title>
		<link href="http://matthias-endler.de/2010/intense-debate"/>
		<updated>2010-10-14T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2010/intense-debate</id>
		<content type="html">&lt;p&gt;My new blog is pretty much up and running now. The only thing I was missing were my old comments I had lying around in a &lt;code&gt;MySQL&lt;/code&gt; dump from my old Wordpress blog I made quite a few years ago.&lt;/p&gt;

&lt;p&gt;An entry of the dump looks like this (in fact there&amp;#8217;s one database entry per line which makes parsing easier):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sql'&gt;&lt;span class='k'&gt;INSERT&lt;/span&gt; &lt;span class='k'&gt;INTO&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;wp_comments&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;VALUES&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;41&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;mre&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
&lt;span class='s1'&gt;&amp;#39;matthias-endler@gmx.net&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;http://www.matthias-endler.de&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
&lt;span class='s1'&gt;&amp;#39;89.51.251.189&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;2006-09-20 17:09:38&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;2006-09-20 15:09:38&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
&lt;span class='s1'&gt;&amp;#39;Thx. Took me about three hours to get everything together. &lt;/span&gt;
&lt;span class='s1'&gt;Good to see that it was worthwhile.&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Mozilla/5.0 &lt;/span&gt;
&lt;span class='s1'&gt;(X11; U; Linux i686; de; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
&lt;span class='s1'&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(I can&amp;#8217;t believe how long ago it is. I was using Firefox 1.5 at that time&amp;#8230;at least it was faster back than ^^)&lt;/p&gt;

&lt;p&gt;At present &lt;a href='http://www.intensedebate.com'&gt;Intense Debate&lt;/a&gt; only offers a comment import feature for &lt;em&gt;existing&lt;/em&gt; Wordpress blogs. But luckily Jay Graves over at &lt;a href='http://www.socialistsoftware.com'&gt;Socialist Software&lt;/a&gt; offers a nice Python script that can &lt;a href='http://www.socialistsoftware.com/post/intense-debate-import-hack/'&gt;send the comments to their system&lt;/a&gt;. I&amp;#8217;ve created a Python 3.1 version of it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;urllib&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='nn'&gt;urllib.request&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='nn'&gt;urllib.error&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='nn'&gt;urllib.parse&lt;/span&gt;

&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;postComment&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;blogpostid&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;acctid&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;anonName&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;anonEmail&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
                &lt;span class='n'&gt;anonURL&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='c'&gt;# &amp;quot;127889&amp;quot; # id test page blogpostid&lt;/span&gt;
    &lt;span class='c'&gt;# &amp;quot;1762&amp;quot; # id test page acctid&lt;/span&gt;

    &lt;span class='n'&gt;server&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;http://www.intensedebate.com/js/commentAction/&amp;quot;&lt;/span&gt;
    &lt;span class='n'&gt;data&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;{&amp;quot;request_type&amp;quot;:&amp;quot;0&amp;quot;, &amp;quot;params&amp;quot;:{    &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;firstCall&amp;quot;:true,                      &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;src&amp;quot;:0,                               &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;blogpostid&amp;quot;:&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;,                       &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;acctid&amp;quot;:&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;,                           &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;parentid&amp;quot;:0,                          &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;depth&amp;quot;:0,                             &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;type&amp;quot;:0,                              &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;token&amp;quot;:&amp;quot;&amp;quot;,                            &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;anonName&amp;quot;:&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;,                       &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;anonEmail&amp;quot;:&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;,                      &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;anonURL&amp;quot;:&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;,                        &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;userid&amp;quot;:undefined,                    &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;token&amp;quot;:&amp;quot;undefined&amp;quot;,                   &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;mblid&amp;quot;:&amp;quot;&amp;quot;,                            &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;tweetThis&amp;quot;:&amp;quot;F&amp;quot;,                       &lt;/span&gt;&lt;span class='se'&gt;\&lt;/span&gt;
&lt;span class='s'&gt;        &amp;quot;comment&amp;quot;:&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;}}&amp;#39;&lt;/span&gt;                      \
        &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;blogpostid&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;acctid&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;anonName&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;anonEmail&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;anonURL&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;params&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;urllib&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;parse&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;urlencode&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='n'&gt;data&lt;/span&gt;&lt;span class='p'&gt;})&lt;/span&gt;
    &lt;span class='k'&gt;try&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
        &lt;span class='n'&gt;f&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;urllib&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;request&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;urlopen&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;?&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;server&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='k'&gt;except&lt;/span&gt; &lt;span class='ne'&gt;IOError&lt;/span&gt; &lt;span class='k'&gt;as&lt;/span&gt; &lt;span class='n'&gt;error&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
        &lt;span class='k'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='si'&gt;%s&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;%&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;error&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;code&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;error&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;read&lt;/span&gt;&lt;span class='p'&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally I wrote a parser for the &lt;code&gt;SQL&lt;/code&gt; dump of my old blog and used the code above to send the extracted comments to Intense Debate:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;intensedebate&lt;/span&gt;

&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt;&lt;span class='p'&gt;():&lt;/span&gt;
    &lt;span class='nb'&gt;file&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;open&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;dump.sql&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;encoding&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; 
    
    &lt;span class='n'&gt;id_old&lt;/span&gt;  &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;123&lt;/span&gt;       &lt;span class='c'&gt;# Post id from old Wordpress blog&lt;/span&gt;
    &lt;span class='n'&gt;id_new&lt;/span&gt;  &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;12345678&lt;/span&gt;  &lt;span class='c'&gt;# Intense Debate post id found in firebug DOM&lt;/span&gt;
    &lt;span class='n'&gt;id_acct&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;123456&lt;/span&gt;    &lt;span class='c'&gt;# Intense Debate account id. Get it with firebug&lt;/span&gt;
    
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='n'&gt;comment&lt;/span&gt; &lt;span class='ow'&gt;in&lt;/span&gt; &lt;span class='n'&gt;comments&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;file&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;id_old&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    	&lt;span class='n'&gt;intensedebate&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;postComment&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;blogpostid&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;id_new&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;acctid&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;id_acct&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  \
            &lt;span class='n'&gt;anonName&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;author&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='n'&gt;anonEmail&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;email&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;   \
            &lt;span class='n'&gt;anonURL&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt; &lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
       	&lt;span class='k'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Posted &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        
&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;comments&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;file&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;id&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
    &lt;span class='sd'&gt;&amp;#39;&amp;#39;&amp;#39; &lt;/span&gt;
&lt;span class='sd'&gt;    Returns next (non-spam) comment &lt;/span&gt;
&lt;span class='sd'&gt;    from a wordpress database sql dump &lt;/span&gt;
&lt;span class='sd'&gt;    &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
    
    &lt;span class='c'&gt;# Field names of the wp_comments table inside the SQL dump file&lt;/span&gt;
    &lt;span class='n'&gt;marker&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;post_id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;author&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;email&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;url&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;ip&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; \
    &lt;span class='n'&gt;date&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;date_gmt&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;content&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;karma&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;spam&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;range&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;11&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
   
    
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt; &lt;span class='ow'&gt;in&lt;/span&gt; &lt;span class='nb'&gt;file&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
        &lt;span class='c'&gt;# Split the line into its field values&lt;/span&gt;
        &lt;span class='n'&gt;field&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;split&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;8&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        
        &lt;span class='c'&gt;# The comment needs some extra treatment&lt;/span&gt;
        &lt;span class='c'&gt;# because it can contain commas inside the text:&lt;/span&gt;
        &lt;span class='c'&gt;# Extract comment from last field in line dump&lt;/span&gt;
        &lt;span class='n'&gt;last_field&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;pop&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;split&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;&amp;#39;,&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='n'&gt;comment&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;last_field&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;pop&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='c'&gt;# Filter spam comments&lt;/span&gt;
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;spam&amp;quot;&lt;/span&gt; &lt;span class='ow'&gt;in&lt;/span&gt; &lt;span class='s'&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;last_field&lt;/span&gt;&lt;span class='p'&gt;):&lt;/span&gt;
            &lt;span class='k'&gt;continue&lt;/span&gt; 
        &lt;span class='c'&gt;# Put the valid comment into our field list&lt;/span&gt;
        &lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        
        &lt;span class='c'&gt;# Remove whitespace and unwanted characters&lt;/span&gt;
        &lt;span class='n'&gt;field&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;value&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;strip&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot; &amp;#39;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='n'&gt;value&lt;/span&gt; &lt;span class='ow'&gt;in&lt;/span&gt; &lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
        
        &lt;span class='k'&gt;try&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
            &lt;span class='c'&gt;# Check if line is entry of wp_comments table&lt;/span&gt;
            &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;wp_comments&amp;quot;&lt;/span&gt; &lt;span class='ow'&gt;in&lt;/span&gt; &lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;marker&lt;/span&gt;&lt;span class='p'&gt;]:&lt;/span&gt;
                &lt;span class='c'&gt;# Check if comment is for the right blog post&lt;/span&gt;
                &lt;span class='n'&gt;current_id&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;int&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;post_id&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt;
                &lt;span class='k'&gt;if&lt;/span&gt;  &lt;span class='n'&gt;current_id&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='nb'&gt;id&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
                    &lt;span class='c'&gt;# Return the useful field values&lt;/span&gt;
                    &lt;span class='c'&gt;# as a dictionary&lt;/span&gt;
                    &lt;span class='k'&gt;yield&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
                        &lt;span class='s'&gt;&amp;quot;author&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;   &lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;author&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
                        &lt;span class='s'&gt;&amp;quot;email&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;    &lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;email&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
                        &lt;span class='s'&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;      &lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;url&lt;/span&gt;&lt;span class='p'&gt;],&lt;/span&gt;
                        &lt;span class='s'&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;  &lt;span class='n'&gt;field&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;content&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
                    &lt;span class='p'&gt;}&lt;/span&gt;
        &lt;span class='k'&gt;except&lt;/span&gt; &lt;span class='ne'&gt;IndexError&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
            &lt;span class='k'&gt;pass&lt;/span&gt; &lt;span class='c'&gt;# Just ignore invalid comments&lt;/span&gt;

&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;__name__&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt;
    &lt;span class='n'&gt;main&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That did the trick.&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>Why I love text files</title>
		<link href="http://matthias-endler.de/2010/why-i-love-text-files"/>
		<updated>2010-10-10T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2010/why-i-love-text-files</id>
		<content type="html">&lt;p&gt;Text files are the single most important way we can communicate with computers. It&amp;#8217;s no coincidence that they are also the most important way to communicate with other human beings. What we can achieve with text files is invaluable: Write it once and refer to it whenever you want to get the message across in the future. Write a program (it&amp;#8217;s just text), save it and let the machine execute it whenever you like. Write another text file which contains the rules for the execution of your program and the computer runs your program exactly as you specified (&lt;code&gt;cron&lt;/code&gt; files do that on Unix).&lt;/p&gt;

&lt;p&gt;Text files can be structured in any way you can possibly imagine. Some flavours are &lt;a href='http://www.json.org/'&gt;JSON&lt;/a&gt;, &lt;a href='http://daringfireball.net/projects/markdown/'&gt;Markdown&lt;/a&gt; and &lt;a href='http://www.w3.org/Graphics/SVG/'&gt;SVG&lt;/a&gt;. It&amp;#8217;s all just text. There exist literally a billion of programs and algorithms to access, modify and distribute text files. You can write them with &lt;em&gt;Emacs&lt;/em&gt;, print them on a terminal, pipe them through &lt;em&gt;sed&lt;/em&gt; and send them via email to a friend who publishes them on the web. Because text files are so important we have good support for them on any computing system. On Unix everything is a file and &lt;em&gt;HTML&lt;/em&gt; is just structured text. It&amp;#8217;s a simple and powerful tool to make a contribution to society that outlasts our lifes.&lt;/p&gt;

&lt;p&gt;I have a single text file in my mac dockbar which is called &lt;code&gt;TODO.txt&lt;/code&gt;. I open it every day and after years of experimenting with different task management apps from simple command line tools to sophisticated online information storage systems I always came back to plain text files. And the explanation is simple: If mankind will still be around a thousand years from now, chances are that plain text files are one of the very few file formats that will still be readable by then&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;They are an incremental part of how we can modify our environment without even leaving our desk. They have no overhead and can contain a single thought or the complete knowledge of our species. Distributing textual information is so vital for us that we permanently develop faster distribution networks &amp;#8211; the fastest by now being the internet.&lt;/p&gt;

&lt;p&gt;On the web you have instant access to a virtually endless amount of information and data distributed as plain text files. New web services made accessing the data even easier offering &lt;code&gt;APIs&lt;/code&gt; and &lt;code&gt;feeds&lt;/code&gt;. You can pull down the data from their servers and make statistics with a programming language of your choice. As you may have noticed, my affinity to text files partially comes from my programming background. As &lt;a href='http://matt.might.net/articles/console-hacks-exploiting-frequency/'&gt;Matt Might&lt;/a&gt; correctly points out on his blog:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The continued dominance of the command line among experts is a testament to the power of linguistic abstraction: when it comes to computing, a word is worth a thousand pictures.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whenever you like a text on the web just link to it and create a wonderful chain of ideas. Want to read it later or recommend it to a friend? Just share the text or print it on paper. The fact that we all take such things for granted is a testament for the power of text files and their importance for the &lt;a href='http://en.wikipedia.org/wiki/Information_Age'&gt;information age&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='links'&gt;Links&lt;/h3&gt;

&lt;ul class='blocklist'&gt;
&lt;li&gt;&lt;a href='http://oreilly.com/openbook/utp/'&gt;Unix Text Processing (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;[EDIT] I admit that this paragraph is a bit misleading. I would be happy if my todo file was so important that it has to be readable in a thousand years from now but that&amp;#8217;s not the case. I just like to be sure that &lt;em&gt;I&lt;/em&gt; can access it without any special (proprietary) software whenever I want. My &lt;code&gt;TODO.txt&lt;/code&gt; is just a personal, transient, disposable storage system (&lt;code&gt;cat TODO.txt | wc -l&lt;/code&gt; prints 174 at the moment&amp;#8230;).&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
	</entry>
	
	<entry>
		<title>What about Microsoft?</title>
		<link href="http://matthias-endler.de/2010/what-about-microsoft"/>
		<updated>2010-10-09T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2010/what-about-microsoft</id>
		<content type="html">&lt;p&gt;Roughly ten years ago, on October 29, 2001, &lt;a href='http://www.microsoft.com/presspass/ofnote/10-29digitaldecade.mspx'&gt;Bill Gates shared a precise picture of the future of computing&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the Digital Decade, you&amp;#8217;ll no longer think of the PC as a tool you use only to carry out specific tasks it will become something you come to rely on all the time. The power of the PC will be as ubiquitous and reliable as electricity, and vastly more useful than any single device we use today.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While previously &lt;a href='http://www.scribd.com/doc/881657/The-Internet-Tidal-Wave'&gt;underestimating the web as a hype&lt;/a&gt;, Gates predicted &lt;em&gt;magic&lt;/em&gt; things like the &lt;em&gt;iPod&lt;/em&gt;, the &lt;em&gt;iPhone&lt;/em&gt; and the &lt;em&gt;Blackberry&lt;/em&gt; to soon be part of our lives. These are all mobile devices you carry around without ever noticing the embedded computer. You use them just like any other everyday object. Their very nature hides most of the underlying technical details (the operating system) from the user and has a strong focus on apps and content. They just work.&lt;/p&gt;

&lt;h3 id='monopoly_on_the_desktop'&gt;Monopoly on the desktop&lt;/h3&gt;

&lt;p&gt;In the early 2000s, smart-phones and mass appeal of the web were the logical next steps and Microsoft had every reason to be excited about that. They had &lt;a href='http://www.microsoft.com/presspass/press/2001/Jan01/01-18Q01-2er.mspx'&gt;record breaking revenues&lt;/a&gt; and absolute market domination in both operating systems and office products. While the quality of their products has always been a reason for debates they were brilliant when it came down to business: Create decent software, integrate it with other company products and sign persistent contracts with the distributors. That&amp;#8217;s also how they won the &lt;a href='http://en.wikipedia.org/wiki/Browser_wars'&gt;Browser Wars&lt;/a&gt; against Netscape making &lt;em&gt;Internet Explorer&lt;/em&gt; the de facto gate to web content. For the last 15 years the company grew from a tiny software startup to a billion dollar global player &amp;#8212; and they wanted to be darn sure it stayed that way.&lt;/p&gt;

&lt;h3 id='harsh_beginnings'&gt;Harsh beginnings&lt;/h3&gt;

&lt;p&gt;When the net really started to gain momentum Microsoft was a bit late to the party like a cumbersome tech guy who&amp;#8217;s watching all the hipsters gettin&amp;#8217; the phone numbers. To tackle the new rivals Microsoft started to mimic the behavior of the already successful guys.&lt;/p&gt;

&lt;p&gt;As a reaction on Netscapes JavaScript, the Internet Explorer promoted ActiveX, a proprietary browser plugin that allowed Microsoft to run their own languages JScript and VBScript on every website to offer loyal Windows-Developers a simple development platform for interactive websites. Because of some major security flaws and the fact that it was a Windows-only product, ActiveX soon had a bad reputation amongst developers. Furthermore Microsoft extended the HTML and CSS standards with vendor specific extensions like &lt;code&gt;filters&lt;/code&gt; and the &lt;code&gt;marquee&lt;/code&gt; element. While other vendors like Mozilla or Opera did the same, the &lt;a href='http://blogs.msdn.com/b/ie/archive/2008/09/08/microsoft-css-vendor-extensions.aspx'&gt;extensions from Microsoft&lt;/a&gt; were not HTML and CSS 2.1 compliant, provoking &lt;a href='http://msdn.microsoft.com/en-us/library/ms537634(VS.85).aspx'&gt;syntax validation errors and much anger&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='the_platform'&gt;The platform&lt;/h3&gt;

&lt;p&gt;The central concept has always been to build an exclusive &lt;em&gt;platform&lt;/em&gt;. An area of total control (much like Apple recently). Microsoft was never ashamed to borrow a good idea from its rivals and sell a (locked down) version of its own. They have a track record in creating new document types and protocols (often times inferior to open standards) in order to strengthen the platform. While it seems unethical and has been the bone of contention for quite a few antitrust cases, it&amp;#8217;s totally understandable from a companies&amp;#8217; point of view. By bundling Internet Explorer with every copy of Windows, they made it very hard for Netscape to compete, eventually pushing them out of the market.&lt;/p&gt;

&lt;h3 id='playing_catchup'&gt;Playing catch-up&lt;/h3&gt;

&lt;p&gt;In parallel they worked on a web portal called MSN (Microsoft Network) &amp;#8212; just like AOL. They later built their own search engine &amp;#8212; to rival Yahoo and created a proprietary chat application named Microsoft Messenger that is much like the successful ICQ. The list goes on and on. Whatever got their attention, they wanted a piece of the cake.&lt;/p&gt;

&lt;p&gt;But as hard as Microsoft tried, the new startups had the fresher ideas, the smarter apps, the bigger user-base. Microsoft suddenly was in the role of the underdog. They tried to fight on many fronts at once while constantly failing to use their own creativity to outsmart the antagonists. One piece in the puzzle was always missing: &lt;em&gt;innovation&lt;/em&gt;. While the technology was quite mature, some solutions still looked like dull, inferior, blatant copies of successful websites and web-apps that missed the final polish. This mentality lead to many setbacks and dead ends: Their social network &lt;a href='http://www.msnbc.msn.com/id/15011765'&gt;Wallop&lt;/a&gt; was a stillbirth, just like MSN Music. More recently the company located in Redmond &lt;a href='http://news.cnet.com/8301-10805_3-10292031-75.html'&gt;shutdown Soapbox and launched MSN Movies to compete with YouTube&lt;/a&gt; and other streaming sites but at the moment the site struggles to gain traction.&lt;/p&gt;

&lt;h3 id='a_new_development_approach'&gt;A new development approach&lt;/h3&gt;

&lt;p&gt;Obviously the web has a lot of characteristics that make Microsoft nervous: Open standards, rapid distribution of software and content, free alternatives to established desktop programs. Part of their initial resentment might come from the fear that the Windows platform &amp;#8211; the operating system including all third-party vendors &amp;#8211; might &lt;em&gt;rapidly&lt;/em&gt; become irrelevant. They would have to start anew. So their strategy was (and still seems to be) to make the web more like an extension to their platform, just another part of the Microsoft universe. But their competitive advantage on the desktop is negligible on the internet. Some might even say &lt;em&gt;Microsoft never really grokked the web&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A solution might be to look outside the box and support open standards (like OAuth) and show more commitment to free software. Much like Google which contributes to many important open source projects (Linux and Python) or Facebook which built a free PHP compiler called HipHop, Microsoft could be an active part of the community instead of constantly infiltrating it.&lt;/p&gt;

&lt;p&gt;But what are the advantages for Microsoft to rapidly change the development process and give up their precious proprietary platform to create an open environment for the web and mobile devices? This can increase the development speed of large systems and lower the costs, as demonstrated by Google with the open Android platform or Apples WebKit which is used on many browsers (not just their own Safari).&lt;/p&gt;

&lt;p&gt;As a site note it&amp;#8217;s interesting to see how Apple gained popularity within the last ten years by gradually moving all their services to the cloud and offering a seamless interface on all their mobile devices. By recruiting droves of loyal developers for iOS development they now have the platform that Microsoft urgently needs. They have made the jump into the web by increasingly blurring the line between local apps and the web.&lt;/p&gt;

&lt;p&gt;Keep in mind that success is never guaranteed. Google stopped Wave and Apple had a false start with Ping. But because of the &lt;em&gt;agile&lt;/em&gt; development process and the wide variety of innovative products, these roadblocks aren&amp;#8217;t fatal but often times vital. Microsoft needed 14 years to bring Internet Explorer to version 6, Google needed just two for Chrome (and it&amp;#8217;s already faster than IE8&amp;#8230;). Currently Google Instant makes Bing! look like a rusty piece of metal. Sure all that doesn&amp;#8217;t mean Microsoft will disappear any time soon but without innovation any company is doomed to drift into insignificance.&lt;/p&gt;

&lt;h3 id='an_open_future'&gt;An open future&lt;/h3&gt;

&lt;p&gt;But maybe Microsoft is already working on a more open policy: With their new Internet Explorer 9, &lt;a href='http://edition.cnn.com/2009/TECH/11/19/cnet.internet.explorer.nine/'&gt;Microsoft still has a strong focus on proprietary web technologies like Direct2D&lt;/a&gt; and &lt;a href='http://en.wikipedia.org/wiki/Silverlight'&gt;Silverlight&lt;/a&gt; but they also pass the Acid3 test for standard compliance and support the new HTML5 &lt;code&gt;canvas&lt;/code&gt; and &lt;code&gt;video&lt;/code&gt; elements. They have the money and the manpower to shape the next big thing but it will be a hard piece of work and it takes a step back to see that the web is all about open standards and collaboration.&lt;/p&gt;

&lt;h3 id='links'&gt;Links&lt;/h3&gt;

&lt;ul class='blocklist'&gt;
&lt;li&gt;&lt;a href='http://www.fernstrategy.com/2010/10/18/is-microsoft-in-trouble/'&gt;Michael Fern is writing on the same topic&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://news.ycombinator.com/item?id=1805621'&gt;Comments on Hackernews&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
	</entry>
	
	<entry>
		<title>Exporting posts from posterous</title>
		<link href="http://matthias-endler.de/2010/exporting-posts-from-posterous"/>
		<updated>2010-09-17T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2010/exporting-posts-from-posterous</id>
		<content type="html">&lt;p&gt;&lt;a href='http://matthiasendler.posterous.com'&gt;Posterous&lt;/a&gt; is awesome for great looking blogs without the hassle. It was great to have it for posting my thoughts when my old blog was all messed up. Now that I&amp;#8217;ve redesigned it I want to host all my old posts on my new blog, too. Therefore I needed to export them somehow. It&amp;#8217;s a bit strange that the guys from posterous don&amp;#8217;t offer an export button on the configuration page but they help you out with a nice &lt;em&gt;RESTful&lt;/em&gt; API that can be used with just about any language.&lt;/p&gt;

&lt;p&gt;Here is how a response to a query looks like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='xml'&gt;&lt;span class='nt'&gt;&amp;lt;post&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://post.ly/NWNC&lt;span class='nt'&gt;&amp;lt;/url&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;link&amp;gt;&lt;/span&gt;http://matthiasendler.posterous.com/.../link&amp;gt; 
  &lt;span class='nt'&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Overkill: Java as a first programming language&lt;span class='nt'&gt;&amp;lt;/title&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;id&amp;gt;&lt;/span&gt;11579710&lt;span class='nt'&gt;&amp;lt;/id&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;body&amp;gt;&lt;/span&gt; 
    &lt;span class='cp'&gt;&amp;lt;![CDATA[&amp;gt;&amp;lt;p&amp;gt;I recently...]]&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;/body&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;date&amp;gt;&lt;/span&gt;Fri, 12 Feb 2010 08:12:00 -0800&lt;span class='nt'&gt;&amp;lt;/date&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;views&amp;gt;&lt;/span&gt;505&lt;span class='nt'&gt;&amp;lt;/views&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;private&amp;gt;&lt;/span&gt;false&lt;span class='nt'&gt;&amp;lt;/private&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;author&amp;gt;&lt;/span&gt;Matthias Endler&lt;span class='nt'&gt;&amp;lt;/author&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;authorpic&amp;gt;&lt;/span&gt;http://files.posterous.com/.../unix_thumb.jpg&lt;span class='nt'&gt;&amp;lt;/authorpic&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;commentsenabled&amp;gt;&lt;/span&gt;true&lt;span class='nt'&gt;&amp;lt;/commentsenabled&amp;gt;&lt;/span&gt; 
  &lt;span class='nt'&gt;&amp;lt;commentsCount&amp;gt;&lt;/span&gt;0&lt;span class='nt'&gt;&amp;lt;/commentsCount&amp;gt;&lt;/span&gt; 
&lt;span class='nt'&gt;&amp;lt;/post&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id='grab_your_posts'&gt;Grab your posts&lt;/h3&gt;

&lt;p&gt;So off we go with this little PHP snippet that gives you ten of my latest blog posts:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='php'&gt;&lt;span class='cp'&gt;&amp;lt;?php&lt;/span&gt;

  &lt;span class='c1'&gt;// Posterous PHP export. Requires PHP 5.1.0 or newer&lt;/span&gt;
  &lt;span class='c1'&gt;// Documentation on http://posterous.com/api/reading&lt;/span&gt;

  &lt;span class='c1'&gt;// Set timezone for posterous blog&lt;/span&gt;
  &lt;span class='nb'&gt;date_default_timezone_set&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;America/Los_Angeles&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

  &lt;span class='c1'&gt;// Query options&lt;/span&gt;
  &lt;span class='nv'&gt;$site_id&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;                &lt;span class='c1'&gt;// Either use id of the site...&lt;/span&gt;
  &lt;span class='nv'&gt;$hostname&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;matthiasendler&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='c1'&gt;// ...or a posterous subdomain.&lt;/span&gt;
  &lt;span class='nv'&gt;$num_posts&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;10&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;                  &lt;span class='c1'&gt;// Number of posts to read.&lt;/span&gt;
  &lt;span class='nv'&gt;$page&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;                              &lt;span class='c1'&gt;// Get specific page.&lt;/span&gt;
  &lt;span class='nv'&gt;$tag&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;                     &lt;span class='c1'&gt;// Grab posts with these tags.&lt;/span&gt;

  &lt;span class='c1'&gt;// Create query string&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$site_id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;$query&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;site_id=&amp;quot;&lt;/span&gt;  &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$site_id&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='k'&gt;else&lt;/span&gt;          &lt;span class='nv'&gt;$query&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;hostname=&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$hostname&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$num_posts&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='nv'&gt;$query&lt;/span&gt; &lt;span class='o'&gt;.=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;amp;num_posts=&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$num_posts&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$page&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;      &lt;span class='nv'&gt;$query&lt;/span&gt; &lt;span class='o'&gt;.=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;amp;page=&amp;quot;&lt;/span&gt;      &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$page&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$tag&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;       &lt;span class='nv'&gt;$query&lt;/span&gt; &lt;span class='o'&gt;.=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;amp;tag=&amp;quot;&lt;/span&gt;       &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$tag&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

  &lt;span class='c1'&gt;// Request&lt;/span&gt;
  &lt;span class='nv'&gt;$url&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;http://posterous.com/api/readposts?&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$query&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='nv'&gt;$xml&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;simplexml_load_file&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$url&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='nv'&gt;$post_count&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;count&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$xml&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;post&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

  &lt;span class='c1'&gt;// Cumbersome way to walk post entries. &lt;/span&gt;
  &lt;span class='c1'&gt;// See php.net/manual/de/function.simplexml-load-file.php#86471&lt;/span&gt;
  &lt;span class='k'&gt;for&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nv'&gt;$i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='nv'&gt;$post_count&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='nv'&gt;$i&lt;/span&gt;&lt;span class='o'&gt;++&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; 
    &lt;span class='nv'&gt;$post&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$xml&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;post&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nv'&gt;$i&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt; 
    &lt;span class='c1'&gt;// Now we can use $post-&amp;gt;title, $post-&amp;gt;date, $post-&amp;gt;body...&lt;/span&gt;
    &lt;span class='nx'&gt;write_markdown&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$post&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='cp'&gt;?&amp;gt;&lt;/span&gt;&lt;span class='x' /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id='put_it_into_jekyll'&gt;Put it into jekyll&lt;/h3&gt;

&lt;p&gt;I wanted to import the posts into jekyll so I used the function &lt;code&gt;write_markdown()&lt;/code&gt; to do so.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='php'&gt;&lt;span class='cp'&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class='sd'&gt;/**&lt;/span&gt;
&lt;span class='sd'&gt; * Formats a posterous post as markdown to use it with jekyll&lt;/span&gt;
&lt;span class='sd'&gt; * array  $post   The post that gets processed&lt;/span&gt;
&lt;span class='sd'&gt; * string $layout The liquid template to use &lt;/span&gt;
&lt;span class='sd'&gt; */&lt;/span&gt;
 &lt;span class='k'&gt;function&lt;/span&gt; &lt;span class='nf'&gt;write_markdown&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$post&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nv'&gt;$layout&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='c1'&gt;// Extract relevant data from $post&lt;/span&gt;
	&lt;span class='nv'&gt;$date&lt;/span&gt;  &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;date&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Y-m-d&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;strtotime&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$post&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;date&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
	
	&lt;span class='c1'&gt;// Create filename&lt;/span&gt;
	&lt;span class='nv'&gt;$extension&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;.mkdn&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='nv'&gt;$filename&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nv'&gt;$date&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nx'&gt;strtolower&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$post&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;title&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	
	&lt;span class='c1'&gt;// Remove whitespace and special characters from filename&lt;/span&gt;
	&lt;span class='nv'&gt;$patterns&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;array&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;/\s/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/:/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;/\(/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;/\)/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/]/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; 
	&lt;span class='s1'&gt;&amp;#39;/\[/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/!/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/\?/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/\+/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/=/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;/\./&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/\&amp;quot;/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/,/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='nv'&gt;$filename&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;preg_replace&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$patterns&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nv'&gt;$filename&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	
	&lt;span class='c1'&gt;// Replace multiple dashes with single dash&lt;/span&gt;
	&lt;span class='nv'&gt;$filename&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;preg_replace&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;/--+/&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nv'&gt;$filename&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	
	&lt;span class='c1'&gt;// Remove possible dash at the end of filename&lt;/span&gt;
	&lt;span class='nv'&gt;$filename&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;trim&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$filename&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	
	&lt;span class='c1'&gt;// We&amp;#39;re good to go. Create a new markdown file&lt;/span&gt;
	&lt;span class='nv'&gt;$jekyll_post&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;fopen&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$filename&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$extension&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$jekyll_post&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
		&lt;span class='c1'&gt;// Jekyll requires a yaml front matter&lt;/span&gt;
		&lt;span class='nv'&gt;$yaml&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;---&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt;
			&lt;span class='s2'&gt;&amp;quot;layout: &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$layout&lt;/span&gt;       &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt;
			&lt;span class='s2'&gt;&amp;quot;title:  &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='nv'&gt;$post&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;title&lt;/span&gt;  &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt;
			&lt;span class='s2'&gt;&amp;quot;---&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
				
		&lt;span class='c1'&gt;// Write front matter, post data and close file&lt;/span&gt;
		&lt;span class='nb'&gt;fwrite&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$jekyll_post&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nv'&gt;$yaml&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
		&lt;span class='nb'&gt;fwrite&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$jekyll_post&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nv'&gt;$post&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;&lt;span class='na'&gt;body&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
		&lt;span class='nb'&gt;fclose&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;$jekyll_post&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='p'&gt;}&lt;/span&gt;
 &lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='cp'&gt;?&amp;gt;&lt;/span&gt;&lt;span class='x' /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s generally a good idea to use an HTML to Markdown converter for the post body. There is a nice one for PHP called &lt;a href='http://sourceforge.net/projects/markdownify/'&gt;Markdownify&lt;/a&gt; and a python script named &lt;a href='http://www.aaronsw.com/2002/html2text/'&gt;html2text&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='download'&gt;Download&lt;/h3&gt;

&lt;p&gt;You can download the whole script here. Simply execute it by typing &lt;code&gt;php grab.php&lt;/code&gt;.&lt;/p&gt;
&lt;a href='https://raw.github.com/mre/mre.github.com/master/downloads/grab.php'&gt;
&lt;div class='download'&gt;Download the package.&lt;/div&gt;&lt;/a&gt;
&lt;h3 id='errata'&gt;Errata&lt;/h3&gt;

&lt;p&gt;Thanks to &lt;a href='http://www.algertsula.com'&gt;Algert Sula&lt;/a&gt; for pointing out an error in the above script.&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>Sorting speed of STL vectors and lists</title>
		<link href="http://matthias-endler.de/2010/sorting-speed-of-stl-vectors-and-lists"/>
		<updated>2010-02-12T00:00:00-08:00</updated>
    <id>http://matthias-endler.de//2010/sorting-speed-of-stl-vectors-and-lists</id>
		<content type="html">&lt;p&gt;This snippet is an addition to my &lt;a href='http://0.0.0.0:4000/2010/howto-sort-a-vector-or-a-list-in-c-using-stl/'&gt;previous article about sorting STL containers&lt;/a&gt;. I&amp;#8217;ve tested the sorting speed of &lt;code&gt;std::vector&lt;/code&gt; vs. &lt;code&gt;std::list&lt;/code&gt; on my MacBook. As we can see by the results below, vectors are much faster than lists when it comes to sorting (almost 8 times faster on my machine).&lt;/p&gt;

&lt;p&gt;Thx to Dean H. for commenting.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='cpp'&gt;&lt;span class='cp'&gt;#include &amp;lt;algorithm&amp;gt;   &lt;/span&gt;&lt;span class='c1'&gt;// Needed for sort() method&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;vector&amp;gt;      &lt;/span&gt;&lt;span class='c1'&gt;// STL vector class&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;list&amp;gt;        &lt;/span&gt;&lt;span class='c1'&gt;// STL list class&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;iostream&amp;gt;    &lt;/span&gt;&lt;span class='c1'&gt;// Needed for cout,endl&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;sys/time.h&amp;gt;  &lt;/span&gt;&lt;span class='c1'&gt;// Needed for rand,timeval&lt;/span&gt;
&lt;span class='k'&gt;using&lt;/span&gt; &lt;span class='k'&gt;namespace&lt;/span&gt; &lt;span class='n'&gt;std&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;   &lt;span class='c1'&gt;// Save us some typing&lt;/span&gt;

&lt;span class='kt'&gt;bool&lt;/span&gt; &lt;span class='n'&gt;comp&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;num1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;num2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
   &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;num1&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;num2&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;


&lt;span class='c1'&gt;// Prints the difference between to time values to std::out&lt;/span&gt;
&lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='n'&gt;printDiff&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='n'&gt;timeval&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='n'&gt;timeval&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;start&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;timeval&lt;/span&gt; &lt;span class='n'&gt;diff&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;diff&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_sec&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_sec&lt;/span&gt;  &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;start&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_sec&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;diff&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_usec&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_usec&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;start&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_usec&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;diff&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_usec&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='n'&gt;diff&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_sec&lt;/span&gt;&lt;span class='o'&gt;--&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
        &lt;span class='n'&gt;diff&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_usec&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;1000000&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;Elapsed time: &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;diff&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_sec&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;seconds, &amp;quot;&lt;/span&gt;
         &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;diff&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tv_usec&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot; microseconds.&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;endl&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;

&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;main&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;vector&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;              &lt;span class='c1'&gt;// Vector containing integers&lt;/span&gt;
    &lt;span class='n'&gt;vector&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;::&lt;/span&gt;&lt;span class='n'&gt;iterator&lt;/span&gt; &lt;span class='n'&gt;vIt&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;  &lt;span class='c1'&gt;// Iterator navigating through vector&lt;/span&gt;

    &lt;span class='n'&gt;list&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;                &lt;span class='c1'&gt;// List containing integers&lt;/span&gt;
    &lt;span class='n'&gt;list&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;::&lt;/span&gt;&lt;span class='n'&gt;iterator&lt;/span&gt; &lt;span class='n'&gt;lIt&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;    &lt;span class='c1'&gt;// Iterator navigating through list&lt;/span&gt;


    &lt;span class='c1'&gt;// Insert a 100 million integer values into both containers&lt;/span&gt;
    &lt;span class='n'&gt;srand&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt; &lt;span class='n'&gt;time&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;NULL&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='c1'&gt;// Initialize random number generator&lt;/span&gt;
    &lt;span class='n'&gt;generate_n&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;back_inserter&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='mi'&gt;100000000&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;rand&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;generate_n&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;back_inserter&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='mi'&gt;100000000&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;rand&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

    &lt;span class='c1'&gt;// Measure sorting time&lt;/span&gt;
    &lt;span class='n'&gt;timeval&lt;/span&gt; &lt;span class='n'&gt;start&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;

    &lt;span class='c1'&gt;// Sort vector&lt;/span&gt;
    &lt;span class='n'&gt;gettimeofday&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;start&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;sort&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;begin&lt;/span&gt;&lt;span class='p'&gt;(),&lt;/span&gt; &lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;(),&lt;/span&gt; &lt;span class='n'&gt;comp&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;gettimeofday&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;VECTOR: &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;printDiff&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;start&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

    &lt;span class='c1'&gt;// Sort list&lt;/span&gt;
    &lt;span class='n'&gt;gettimeofday&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;start&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sort&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;comp&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;gettimeofday&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;LIST: &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
    &lt;span class='n'&gt;printDiff&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;start&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

    &lt;span class='cm'&gt;/* Output:&lt;/span&gt;
&lt;span class='cm'&gt;     * VECTOR: Elapsed time: 99seconds, 566816 microseconds.&lt;/span&gt;
&lt;span class='cm'&gt;     * LIST:  Elapsed time: 770seconds, 216836 microseconds&lt;/span&gt;
&lt;span class='cm'&gt;     */&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
	</entry>
	
	<entry>
		<title>Overkill: Java as a first programming language</title>
		<link href="http://matthias-endler.de/2010/overkill-java-as-a-first-programming-language"/>
		<updated>2010-02-12T00:00:00-08:00</updated>
    <id>http://matthias-endler.de//2010/overkill-java-as-a-first-programming-language</id>
		<content type="html">&lt;p&gt;I recently talked to a student in my neighborhood about his first programming experiences. They started learning &lt;em&gt;Java&lt;/em&gt; at school and it soon turned out to be horrible.&lt;/p&gt;

&lt;p&gt;A lot of us learned coding in languages like &lt;em&gt;BASIC&lt;/em&gt; or &lt;em&gt;Pascal&lt;/em&gt;. There was no object orientation, no sophisticated file I/O and almost no modularization&amp;#8230;and it was great. In &lt;em&gt;BASIC&lt;/em&gt; you could just write&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='n'&gt;PRINT&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;HELLO WORLD&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and you were done. This was actually a running program solving a basic and reoccurring problem: Output some text on a screen.&lt;/p&gt;

&lt;p&gt;If you wanted to do the same thing in &lt;em&gt;Java&lt;/em&gt; you simply write:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Main&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; 
  &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;static&lt;/span&gt; &lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Hello, world!&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt; 
  &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Do you see how much knowledge about programming you must have to achieve the easiest task one could think of? Describing the program to a novice programmer may sound like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a Main class containing a main-method returning void expecting a string array as single argument using the &lt;code&gt;println&lt;/code&gt; method of the &lt;code&gt;out&lt;/code&gt; object of class &lt;code&gt;PrintStream&lt;/code&gt; passing your text as single argument.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&amp;#8212; please just don&amp;#8217;t forget your brackets. This way your first programming hours are guaranteed to be great fun.&lt;/p&gt;

&lt;p&gt;OK. So what are the alternatives? I admit that nobody wants to write &lt;em&gt;BASIC&lt;/em&gt; anymore because of its lack of a sophisticated standard library for graphics (&lt;em&gt;Java&lt;/em&gt; doesn&amp;#8217;t have one either) and its weak scalability. The language has to be simple and clean. It should be fast enough for numerical tasks but not as wordy as the rigid C-type bracket languages (sorry C++ guys). It should have a smooth learning-curve and provide direct feedback (compiled languages often suck at that point). It should encourage clean code and reward best practices. One language that provides all that is &lt;em&gt;&lt;em&gt;Python&lt;/em&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And &lt;em&gt;Python&lt;/em&gt; has even more: hundreds of libraries that help you with almost everything, good integration into common IDEs (PyDev in Eclipse, IDLE&amp;#8230;), a precise and elegant syntax.&lt;/p&gt;

&lt;p&gt;Here is our program from above written in &lt;em&gt;Python&lt;/em&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='k'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Hello World&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There&amp;#8217;s no need to know about object orientation, scopes and function arguments at this point. No house-holding or book-keeping. Yes, it&amp;#8217;s an interpreted language but that&amp;#8217;s not a deal breaker for beginners.&lt;/p&gt;

&lt;p&gt;If you aren&amp;#8217;t convinced yet, printing and formatting text output in &lt;em&gt;Java&lt;/em&gt; is relatively easy for an advanced programmer but the really ugly stuff begins with file input:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='java'&gt;&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.io.BufferedReader&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; 
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.io.FileNotFoundException&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; 
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.io.FileReader&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; 
&lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='nn'&gt;java.io.IOException&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; 
 
&lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;fileIO&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; 
    &lt;span class='kd'&gt;public&lt;/span&gt; &lt;span class='kd'&gt;static&lt;/span&gt; &lt;span class='kt'&gt;void&lt;/span&gt; &lt;span class='nf'&gt;main&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;String&lt;/span&gt;&lt;span class='o'&gt;[]&lt;/span&gt; &lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; 
        &lt;span class='n'&gt;String&lt;/span&gt; &lt;span class='n'&gt;filename&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;test.txt&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; 
        &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; 
            &lt;span class='n'&gt;BufferedReader&lt;/span&gt; &lt;span class='n'&gt;myFile&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
                &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nf'&gt;BufferedReader&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='n'&gt;FileReader&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;filename&lt;/span&gt;&lt;span class='o'&gt;));&lt;/span&gt; 
            
            &lt;span class='k'&gt;while&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;myFile&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;readLine&lt;/span&gt;&lt;span class='o'&gt;())&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; 
                &lt;span class='n'&gt;System&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;out&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;println&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;);&lt;/span&gt;
            &lt;span class='o'&gt;}&lt;/span&gt; 
        &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;FileNotFoundException&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; 
            &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt; 
        &lt;span class='o'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;IOException&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt; 
            &lt;span class='n'&gt;e&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='na'&gt;printStackTrace&lt;/span&gt;&lt;span class='o'&gt;();&lt;/span&gt; 
        &lt;span class='o'&gt;}&lt;/span&gt; 
    &lt;span class='o'&gt;}&lt;/span&gt; 
&lt;span class='o'&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I hear you say: &amp;#8220;Dude, file I/O is pretty complex. It&amp;#8217;s just the way it is&amp;#8221;. That&amp;#8217;s true&amp;#8230; &lt;em&gt;internally&lt;/em&gt; . But the user should get an easy interface. &lt;em&gt;Python&lt;/em&gt; shows how it&amp;#8217;s done:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='python'&gt;&lt;span class='nb'&gt;file&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;open&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;test.txt&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;text&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;file&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;read&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
&lt;span class='k'&gt;print&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;text&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code goes hand in hand with the natural understanding of how the process works: &amp;#8220;The computer opens a file, reads it and prints it&amp;#8221;. Even a five year old kid can understand that. Nobody would start to explain: &amp;#8220;Before you can read a file you need a BufferedReader that works on a FileReader&amp;#8230;&amp;#8221; even if this is exactly how it works &lt;em&gt;internally&lt;/em&gt;. You want to explain the big picture at first. The elementary principles of teaching a computer how to do useful stuff. Otherwise you will start frustrating beginners and fool them into thinking that they are not bright enough for programming. Programming is fun and starting with it is the most important step. So don&amp;#8217;t spoil that experience with layers of unneeded abstraction.&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>Sorry Apple, that iPad sucks!</title>
		<link href="http://matthias-endler.de/2010/sorry-apple-that-ipad-sucks"/>
		<updated>2010-01-27T00:00:00-08:00</updated>
    <id>http://matthias-endler.de//2010/sorry-apple-that-ipad-sucks</id>
		<content type="html">&lt;p&gt;When Steve Jobs held it in his hands my first thought was: &amp;#8220;That thing is fat and it somehow looks like a giant iPod&amp;#8221;. Just like somebody lost his Apple phone on a bus and a million people sat on it. Obviously it looks like we all expected. A black glossy surface with aluminium highlights here and there. On the bottom is that compulsive &amp;#8220;help me!&amp;#8221; button and that&amp;#8217;s about it. Oh! And it&amp;#8217;s thin. Yay!&lt;/p&gt;

&lt;p&gt;From a hardware point of few nothing to fall in love with. It can&amp;#8217;t cope with the sophisticated elegance of the iPod that takes full advantage of its size with its zoom and pan functions and it doesn&amp;#8217;t sport the versatility of a full-fledged MacBook Pro with all its ports and gizmos.&lt;/p&gt;

&lt;p&gt;Unfortunately the software side is even more unimpressive. That iPhone OS with its tiny icons, its useless dockbar, its single-tasking core looks lost and abused on this 10 inch display. It fits well for a phone where display size is limited but on that fancy new &amp;#8220;web device&amp;#8221; a lot of potential is wasted. Why not design a new web-oriented interface with a calender and facebook as a desktop. With recommended YouTube videos and new mails at your finger tips. Instead you don&amp;#8217;t even get Flash. You can&amp;#8217;t install Firefox. Eww.&lt;/p&gt;

&lt;p&gt;Apple wants to keep its babies separate. Your iPhone for calls and navigation, your laptop for &amp;#8220;hard stuff&amp;#8221; aka &amp;#8220;work&amp;#8221; your iPod for media and your iPad for&amp;#8230;umm&amp;#8230;surfing? What you get is a hybrid device that does essentially nothing.For hard number crunching you&amp;#8217;re better off with your desktop workstation or notebook. For music an iPod fits your needs. Chatting and phone calls are reserved to the iPhone. SMS too. On the other end your iPad does not even have a webcam.&lt;/p&gt;

&lt;p&gt;So you&amp;#8217;re left with that overpriced eBook-reader that includes a web browser and 14.000 apps that were designed for a 320x480 pixel screen. Oh and for eBooks we&amp;#8217;ve got the Amazon Kindle which is cheaper and doesn&amp;#8217;t hurt them eyes while reading because of that fancy E-Inc technology. Btw you get two days battery lifetime, too. Out of the box the iPad may be the most expensive book you&amp;#8217;ll ever buy. It may soon go the way of the Macbook Air and the Apple TV. Nice idea but irrelevant.&lt;/p&gt;

&lt;p&gt;Another tricky part is writing text on that device. Everything that&amp;#8217;s longer than an URL is a pain on that glass surface. On top of that you need to put it on the table and bend over the device to use all your fingers for typing. Just hope the sun does not shine.&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t say this won&amp;#8217;t become a huge success for Apple when there will be new apps and hackers to get their hands dirty on that device. A pirated version may do all sorts of crazy stuff but that&amp;#8217;s illegal and you&amp;#8217;ll loose your warranty. There is a long way to go for Apple. They just don&amp;#8217;t understand that &lt;em&gt;web&lt;/em&gt; also means &lt;em&gt;open&lt;/em&gt;.&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>Howto sort a vector or a list in C++ using STL</title>
		<link href="http://matthias-endler.de/2010/howto-sort-a-vector-or-a-list-in-c-using-stl"/>
		<updated>2010-01-27T00:00:00-08:00</updated>
    <id>http://matthias-endler.de//2010/howto-sort-a-vector-or-a-list-in-c-using-stl</id>
		<content type="html">&lt;p&gt;A little code snippet that people need very often:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='cpp'&gt;&lt;span class='cm'&gt;/*&lt;/span&gt;
&lt;span class='cm'&gt; * Howto sort a vector or a list in C++ using STL&lt;/span&gt;
&lt;span class='cm'&gt; */&lt;/span&gt;

&lt;span class='cp'&gt;#include &amp;lt;algorithm&amp;gt;	&lt;/span&gt;&lt;span class='c1'&gt;// Needed for sort() method&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;vector&amp;gt;	&lt;/span&gt;&lt;span class='c1'&gt;// STL vector class&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;list&amp;gt;		&lt;/span&gt;&lt;span class='c1'&gt;// STL list class&lt;/span&gt;
&lt;span class='cp'&gt;#include &amp;lt;iostream&amp;gt;	&lt;/span&gt;&lt;span class='c1'&gt;// Needed for cout,endl&lt;/span&gt;
&lt;span class='k'&gt;using&lt;/span&gt; &lt;span class='k'&gt;namespace&lt;/span&gt; &lt;span class='n'&gt;std&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;	&lt;span class='c1'&gt;// Save us some typing&lt;/span&gt;


&lt;span class='cm'&gt;/*&lt;/span&gt;
&lt;span class='cm'&gt; * This is a comparison function. It can be used to tell sort()&lt;/span&gt;
&lt;span class='cm'&gt; * how to order the elements in our container (the vector or list).&lt;/span&gt;
&lt;span class='cm'&gt; * You can write a comparator for every data type (i.e. double, string...).&lt;/span&gt;
&lt;span class='cm'&gt; */&lt;/span&gt;
&lt;span class='kt'&gt;bool&lt;/span&gt; &lt;span class='n'&gt;comp&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;num1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='k'&gt;const&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt; &lt;span class='n'&gt;num2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;num1&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;num2&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='n'&gt;main&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
	&lt;span class='c1'&gt;// SORTING WITH VECTORS //&lt;/span&gt;
	&lt;span class='n'&gt;vector&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='c1'&gt;// A vector containing integers&lt;/span&gt;
	&lt;span class='n'&gt;vector&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;::&lt;/span&gt;&lt;span class='n'&gt;iterator&lt;/span&gt; &lt;span class='n'&gt;vIt&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='c1'&gt;// A pointer to a vector element&lt;/span&gt;
	&lt;span class='c1'&gt;// Insert some values&lt;/span&gt;
	&lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push_back&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push_back&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;12&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push_back&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='cm'&gt;/*&lt;/span&gt;
&lt;span class='cm'&gt;     * The generic STL sort function uses three parameters:&lt;/span&gt;
&lt;span class='cm'&gt;     * v.begin()  Iterator pointing at the _beginning_ of the container&lt;/span&gt;
&lt;span class='cm'&gt;     * v.end()    Iterator pointing at the _end_ of it&lt;/span&gt;
&lt;span class='cm'&gt;     * comp       [Optional] A comparison function (see above)&lt;/span&gt;
&lt;span class='cm'&gt;     *&lt;/span&gt;
&lt;span class='cm'&gt;     * The above mentioned iterators must be random access iterators because&lt;/span&gt;
&lt;span class='cm'&gt;     * sort() takes advantage of clever tricks that require direct access to&lt;/span&gt;
&lt;span class='cm'&gt;     * all elements of the vector. This makes it really fast.&lt;/span&gt;
&lt;span class='cm'&gt;     * (Currently introsort is used with O(n*log n) even in worst case).&lt;/span&gt;
&lt;span class='cm'&gt;     *&lt;/span&gt;
&lt;span class='cm'&gt;     * Unfortunately calling sort like that does not look very object oriented.&lt;/span&gt;
&lt;span class='cm'&gt;     */&lt;/span&gt;
	&lt;span class='n'&gt;sort&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;begin&lt;/span&gt;&lt;span class='p'&gt;(),&lt;/span&gt; &lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;(),&lt;/span&gt; &lt;span class='n'&gt;comp&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;Vector: &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;vIt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;begin&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='n'&gt;vIt&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='n'&gt;vIt&lt;/span&gt;&lt;span class='o'&gt;++&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
		&lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;vIt&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
		&lt;span class='c1'&gt;// Print current element to standard output&lt;/span&gt;
	&lt;span class='p'&gt;}&lt;/span&gt;
	&lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;endl&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='c1'&gt;// SORTING WITH LISTS //&lt;/span&gt;
	&lt;span class='n'&gt;list&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='c1'&gt;// A list containing integers&lt;/span&gt;
	&lt;span class='n'&gt;list&lt;/span&gt;&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='kt'&gt;int&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;::&lt;/span&gt;&lt;span class='n'&gt;iterator&lt;/span&gt; &lt;span class='n'&gt;lIt&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='c1'&gt;// A pointer to a list element&lt;/span&gt;
	&lt;span class='c1'&gt;// Insert some values&lt;/span&gt;
	&lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push_back&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push_back&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;12&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push_back&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='cm'&gt;/*&lt;/span&gt;
&lt;span class='cm'&gt;     * Here is the major difference between vectors and lists in general:&lt;/span&gt;
&lt;span class='cm'&gt;     * Vectors offer fast random access to every element&lt;/span&gt;
&lt;span class='cm'&gt;     * but inserting a new element at the beginning or in the middle is slow.&lt;/span&gt;
&lt;span class='cm'&gt;     * On the other hand inserting into a list is fast but searching for&lt;/span&gt;
&lt;span class='cm'&gt;     * a specific element is slow. Vectors behave much like an array&lt;/span&gt;
&lt;span class='cm'&gt;     * while lists only allow slow sequential access.&lt;/span&gt;
&lt;span class='cm'&gt;     * Therefore we need a different function to sort all elements that does&lt;/span&gt;
&lt;span class='cm'&gt;     * not need random access iterators.&lt;/span&gt;
&lt;span class='cm'&gt;     *&lt;/span&gt;
&lt;span class='cm'&gt;     * comp       [Optional] A comparison function (see above)&lt;/span&gt;
&lt;span class='cm'&gt;     *&lt;/span&gt;
&lt;span class='cm'&gt;     * Note that sort() is specific for the list and is implemented as a&lt;/span&gt;
&lt;span class='cm'&gt;     * member function of list&amp;lt;&amp;gt;. This is much more object orientated.&lt;/span&gt;
&lt;span class='cm'&gt;     */&lt;/span&gt;
	&lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sort&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;comp&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
	&lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;List: &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;lIt&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;begin&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='n'&gt;lIt&lt;/span&gt; &lt;span class='o'&gt;!=&lt;/span&gt; &lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;end&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt; &lt;span class='n'&gt;lIt&lt;/span&gt;&lt;span class='o'&gt;++&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
		&lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;lIt&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s'&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='p'&gt;}&lt;/span&gt;
	&lt;span class='n'&gt;cout&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;endl&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
	&lt;span class='cm'&gt;/* Output:&lt;/span&gt;
&lt;span class='cm'&gt;     * Vector: 12 5 1&lt;/span&gt;
&lt;span class='cm'&gt;     * List: 12 5 1&lt;/span&gt;
&lt;span class='cm'&gt;     */&lt;/span&gt;
	&lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
	</entry>
	
	<entry>
		<title>Web-Development with jQuery</title>
		<link href="http://matthias-endler.de/2009/web-development-with-jquery-a-list-of-development-environments"/>
		<updated>2009-11-25T00:00:00-08:00</updated>
    <id>http://matthias-endler.de//2009/web-development-with-jquery-a-list-of-development-environments</id>
		<content type="html">&lt;p&gt;I&amp;#8217;ve searched for some IDEs to create jQuery code more quickly. Hacking the files into a text-editor (like &lt;em&gt;Textmate&lt;/em&gt;) and doing some &amp;#8220;real- life&amp;#8221; bug testing by simply opening Firefox and running the site is not very handy. So here is a list of alternatives I came up with. It&amp;#8217;s just an overview loosely ordered by interest.&lt;/p&gt;

&lt;h3 id='aptana'&gt;&lt;a href='http://www.aptana.com/'&gt;Aptana&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Standalone and Eclipse plugin. OpenSource with code completion, syntax highlighting&amp;#8230;&lt;/p&gt;

&lt;h3 id='komodo_edit'&gt;&lt;a href='http://www.activestate.com/komodo_edit/'&gt;Komodo Edit&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;OSX, Linux, Windows. Open source.&lt;/p&gt;

&lt;h3 id='glimmer'&gt;&lt;a href='http://visitmix.com/lab/glimmer'&gt;Glimmer&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Microsoft jQuery Dev. Environment. Has wizards for common tasks. Free.&lt;/p&gt;

&lt;h3 id='firebug'&gt;&lt;a href='http://getfirebug.com/'&gt;FireBug&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Firefox plugin for debugging. Actually not an IDE.&lt;/p&gt;

&lt;h3 id='ixedit'&gt;&lt;a href='http://www.ixedit.com/'&gt;IxEdit&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Edit within browser. WYSIWYG. Free public beta.&lt;/p&gt;

&lt;h3 id='spket_ide'&gt;&lt;a href='http://spket.com/'&gt;Spket IDE&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;JavaScript Toolkit. Eclipse Plugin.&lt;/p&gt;

&lt;h3 id='jslint'&gt;&lt;a href='http://www.jslint.com/'&gt;JsLint&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Online JavaScript parser and debugger.&lt;/p&gt;

&lt;h3 id='codelobster'&gt;&lt;a href='http://www.codelobster.com/'&gt;CodeLobster&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;For PHP/HTML/CSS/JavaScript development. Trial.&lt;/p&gt;

&lt;h3 id='scintilla'&gt;&lt;a href='http://www.scintilla.org/'&gt;Scintilla&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;GTK based professional IDE&lt;/p&gt;

&lt;p&gt;Others include Visual Studio, NetBeans, Dreamweaver and another &lt;a href='http://eclipse-plugins.2y.net/eclipse/plugin_details.jsp;jsessionid=22BE8F306691F47871593491AAA22C72?id=368'&gt;JQuery Eclipse plugin&lt;/a&gt;. &lt;a href='http://www.jaxer.org/'&gt;Jaxer&lt;/a&gt; looks also interesting.&lt;/p&gt;

&lt;p&gt;And finally here is a cool website with tons of material &lt;a href='http://ajaxian.com/'&gt;ajaxian&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Did I miss one?&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>Running legacy code</title>
		<link href="http://matthias-endler.de/2009/running-legacy-code"/>
		<updated>2009-11-08T00:00:00-08:00</updated>
    <id>http://matthias-endler.de//2009/running-legacy-code</id>
		<content type="html">&lt;p&gt;This short article deals with a serious problem in software development. When switching to a new platform (for instance from Windows XP to Windows Vista/7) the programmers need to make sure that old bits of code run flawlessly. There are several ways to achieve this goal that will be discussed during the next paragraphs:&lt;/p&gt;

&lt;h3 id='porting_the_code'&gt;Porting the code&lt;/h3&gt;

&lt;p&gt;This is generally considered a hard path to follow. For non-trivial legacy code-blocks chances are high that they contain side-effects and hacks in order to make them work in different environments. Porting code means replacing parts of the program that use functions and methods that don&amp;#8217;t exist anymore with new ones which make use of the modern libraries&amp;#160; and routines of the new platform. The major advantages are maintainable software and sometimes faster running programs. But it may be needed to hack the new platform libraries in order to preserve the whole functionality of an old program. When changing an algorithm inside legacy code the ported version may become unstable. Thus there may be better ways of mainting obsolete code today.&lt;/p&gt;

&lt;h3 id='emulators'&gt;Emulators&lt;/h3&gt;

&lt;p&gt;Emulators work much the same like porting the code. You replace old function calls with new ones in order to make everything work again. &lt;br /&gt;However you don&amp;#8217;t alter the old codebase itself (because you may not have the sourcecode available) but you create a new compatibility layer that &amp;#8220;translates&amp;#8221; the communication between the underlying operating system and software (our new platform) and our old software. Emulation can also be very fast and run stable for many years but writing an emulator can be even harder than porting the code because an educational guess may be needed to figure out how the program works internally. Additionaly the emulator itself may become obsolete in the future and might eventually&amp;#160; be replaced by a new one.&lt;/p&gt;

&lt;h3 id='virtual_machines'&gt;Virtual machines&lt;/h3&gt;

&lt;p&gt;During the last years a new approach was rising up. The idea is simple: Don&amp;#8217;t touch anything. Take the whole platform and copy it in order to run old software. The old software runs on top of the old operating system within a virtual machine that runs on the new platform.&lt;/p&gt;

&lt;p&gt;From a sane software developers view this method is ridiculous. A lot of resources are wasted along the way. The system is busier switching contexts from an old platform to the new one and back than running the actual legacy program. However with cheap and capable hardware everywhere this idea gets more and more interesting. As Steve Atwood coined it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Always try to spend your way out of a performance problem first by throwing faster hardware at it.&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And he&amp;#8217;s right. The Microsoft developers did the same on their new NT 6.0 platform (Vista, Windows 7, Windows Server 2008&amp;#8230;): Windows XP is running inside a virtual machine. This way everything behaves just like one would run the software on the old system. And by optimizing the performance bottlenecks (input/output, context switches) one gets a fast and stable, easy to maintain product.&lt;/p&gt;

&lt;p&gt;Every method has its major advantages and disadvantages. It&amp;#8217;s on the devoloper to select the appropriate strategy.&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;&lt;a href='http://www.codinghorror.com/blog/archives/001198.html'&gt;Article on Coding Horror&lt;/a&gt;&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
	</entry>
	
	<entry>
		<title>A short Review on ReactOS 0.3.3</title>
		<link href="http://matthias-endler.de/2007/a-short-review-on-reactos-0-3-3"/>
		<updated>2007-09-18T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2007/a-short-review-on-reactos-0-3-3</id>
		<content type="html">&lt;p&gt;FreeWin95 has come a long way since it has been renamed in 1998 and is now called ReactOS.&lt;/p&gt;

&lt;p&gt;The new version 0.3.3 of the Windows 2000 clone already has a lot to offer and has significantly evolved in almost all areas compared to the last release. The developers have made a lot of progress in the lower system area (i. e. the NT Kernel) as well as in the application segment. Let&amp;#8217;s have a look at some new features!&lt;/p&gt;

&lt;h3 id='setup'&gt;Setup&lt;/h3&gt;

&lt;p&gt;Due to the fact that I&amp;#8217;ve tested ReactOS using the pre-configured VMWare Virtual Appliance (VMWare Fusion Version 1.0 (51348) on a MacBook 1.83 GHz to be precise) I can&amp;#8217;t say much about the installation process of the new version using &amp;#8220;real&amp;#8221; hardware. However I&amp;#8217;ve tried to install it with the Install CD that can be downloaded on the &lt;a href='http://www.reactos.org'&gt;project homepage&lt;/a&gt;. Unfortunately I wasn&amp;#8217;t very successful. Somehow ReactOS was not able to allocate the free space on my virtual hard disk&amp;#8230;The last time I used the Install-CD on an old 300 MHz Computer I simply wiped my old partition out, created a new one (&lt;a href='http://www.reactos.org/wiki/index.php/Installing_ReactOS'&gt;fat32 only&lt;/a&gt; guys :), formatted it and started the Installer. I had no problems. On the other hand it can be dangerous to install ReactOS on the same disk as Windows or Linux. Maybe the Installer doesn&amp;#8217;t care and assimilates all disk space (&lt;a href='http://www.youtube.com/watch?v=qItugh-fFgg'&gt;All your system are belong to us&lt;/a&gt;). But: Hey! MS does the same with all competitors, and maybe ReactOS simply aims to clone that approach ;) However the Virtual Appliance worked very smooth on my system. During the test I didn&amp;#8217;t have much problems setting up and using the virtualized OS.&lt;/p&gt;

&lt;h3 id='bootup'&gt;Bootup&lt;/h3&gt;

&lt;p&gt;When I fire up the machine a nice bootloader appears and you may select between the normal and the debugging mode. Pushing &lt;code&gt;F8&lt;/code&gt; gives you another menu where you can select more booting options - like a command prompt-only version or the infamous &lt;code&gt;last good&lt;/code&gt; option. For the moment I simply waited eight seconds until the normal boot process started.&lt;/p&gt;

&lt;p&gt;The developers have changed the bootup screen a bit by adapting the XP look and feel. Generally said the bootup process is very streamlined and offers a whole variety of options for the advanced user. But even the normal &lt;a href='http://en.wikipedia.org/wiki/Pebcac#Acronyms_and_other_names_for_a_user_error'&gt;PEBCAC&lt;/a&gt; can easily reach the desktop interface. Presently the ReactOS kernel (which aims to be compatible with WinNT 5.2) offers about 25 to 30 percent of the &lt;a href='http://en.wikipedia.org/wiki/ReactOS#Functionality'&gt;functionality it will finally have in 1.0&lt;/a&gt;. As a result of the broad kernel redesign in 0.2 to 0.3 the current release faces a lot of regressions in some applications that were already useable in 0.2.&lt;/p&gt;

&lt;h3 id='software'&gt;Software&lt;/h3&gt;

&lt;p&gt;ReactOS actually comes with a small amount of pre-installed software packages. Taking a closer look the team is working hard to offer a free replacement of commonly used Win Software. Naturally it has the &lt;a href='http://www.reactos.org/media/screenshots/2007/ros_033_qemu_vnc_fun.png'&gt;Command Prompt&lt;/a&gt; as well as Regedit, Notepad and WordPad. It also features a scientific Calculator as well as the not-so-well-known Windows commandline classics like &lt;code&gt;shutdown.exe&lt;/code&gt;, &lt;code&gt;regsvr32.exe&lt;/code&gt; or &lt;code&gt;telnet&lt;/code&gt;. Most of these basic programs were borrowed from the wine project. Together with the relatively stable kernel ReactOS already has a solid basis for further software development. Such Bluescreens are (really!) an exception: If you need a package that is not installed by default you can upgrade your system by installing software just as you would on Windows. There are many packages that run out of the box without further tweaking. Just look at the &lt;a href='http://www.reactos.org/support/'&gt;list of supported software&lt;/a&gt; on the interwebs! The newly integrated Downloading-Tool - simply called &lt;strong&gt;Download!&lt;/strong&gt; - can help you to install compatible software with just one click. Because it&amp;#8217;s work in progress there are not so many programs available. You can select between the categories &lt;strong&gt;Internet &amp;#38; Network&lt;/strong&gt;, &lt;strong&gt;Development&lt;/strong&gt;, &lt;strong&gt;Games &amp;#38; Fun&lt;/strong&gt; and &lt;strong&gt;Tools&lt;/strong&gt;. Some cool open source apps like Firefox, Thunderbird, &lt;a href='http://svn.reactos.org/videos/ros_030_smb.html'&gt;Samba&lt;/a&gt;, OpenTTD, 7zip and &amp;#956;Torrent are already ready to use. In later versions it will be possible to update the list of preconfigured packages. That&amp;#8217;s why I see the &lt;strong&gt;Download!&lt;/strong&gt; feature as a promising invention.&lt;/p&gt;

&lt;h3 id='hardware_acceleration'&gt;Hardware acceleration&lt;/h3&gt;

&lt;p&gt;Despite the fact that 0.3.3 has all the necessary drivers on board to run on almost every machine without any need for configuration it may be quite interesting to see ReactOS on full speed using original hardware drivers. In my case I just needed to install the VMWare toolset that offers a major speed burst when installed. I&amp;#8217;ve added a CD-Rom Drive to my virtual machine and clicked on &lt;strong&gt;Virtual Machine&lt;/strong&gt; &amp;gt; &lt;strong&gt;Install VMWare Tools&lt;/strong&gt; while ReactOS was powered on. To my surprise almost everything worked like a charm and I could install the VGA and the audio drivers to tune my system. After a reboot - my system was messed up. The VGA resolution was down to 320-something pixels which made using the OS an impossible task. I had no chance to adjust the resolution with the common &lt;strong&gt;Display Properties&lt;/strong&gt; window nor did it work to use Regedit and adjust the screen values manually. My second thought was &amp;#8220;No problem&amp;#8221;. In case of an emergency we have the Debug Mode on board. Well, what can I say: It didn&amp;#8217;t work. It has the same screen resolution as the normal mode. Maybe there is a &lt;a href='http://www.reactos.org/forum/viewtopic.php?p=23479'&gt;workaround to fix it&lt;/a&gt; but I was too lazy to figure it out and so I simply reset my virtual machine (There you have it, bastard!). The free Windows clone would be quite a usable system for a normal user if some of the configuration tools were already integrated. There is no printing implementation and you can&amp;#8217;t presently use USB or firewire devices. The latest release offers only rudimentary network support. That said the team has worked hard to offer accessibility features as well as localization adjustments. At the moment one can select between 90 (!) supported languages&lt;/p&gt;

&lt;h3 id='stability'&gt;Stability&lt;/h3&gt;

&lt;p&gt;ReactOS still is (and will be for a long time) an experimental System. It&amp;#8217;s normal for an unstable pre-release of an alpha software to randomly freeze or hang or kill your machine or whatsoever. Don&amp;#8217;t panic when you have to restart - it&amp;#8217;s (presently) normal. Don&amp;#8217;t expect ReactOS to run all your .exe files it is a long and painful procedure to reach this aim. That said ReactOS 0.3.3 is surprisingly stable compared to older versions. Yes it occasionally hangs and it takes a nap from time to time when all of your ram gets pwned. But don&amp;#8217;t be afraid: Just feel free to hang around a bit dazzling with the software - actually having FUN using your computer. 0.3.3 is the first version that doesn&amp;#8217;t almost certainly crash after two minutes of use or a wrong click in the system configuration menu (o_O). ReactOS has grown up from a pure hacker playground to a mature, promising open source alternative for proprietary M$ desktop products. Certainly you&amp;#8217;ll find a bug and maybe want to help the developers. In this case just go to their site and fill out a bug report and you can say to yourself that you&amp;#8217;ve just supported free software. The thing a good developer (and good engineer in general) likes most is when somebody says &lt;strong&gt;Thanks for all the great work!&lt;/strong&gt; That&amp;#8217;s what I also like to say to the ROS team. Keep up the good work! According to Wikipedia the next major release (i.e. 0.4) will offer basic USB support and a complete SMB interface (making it fully compatible with the Windows network subsystem). After that ReactOS will enter beta status and we will see all the fancy &lt;strong&gt;user-world&lt;/strong&gt; stuff like NTFS support or DirectX 7-9 support. So there is a long way to go and a lot to explore!&lt;/p&gt;

&lt;ul class='blocklist'&gt;
&lt;li&gt;&lt;a href='http://www.reactos.org'&gt;Project Homepage&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wikipedia.org/wiki/ReactOS'&gt;ReactOS on Wikipedia (en)&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=eIGACCx-Z0U'&gt;Firefox 2 Installing on Reactos 0.3.3 rc2&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=zQx_u_rWzCc&amp;amp;mode=related&amp;amp;search='&gt;Unreal Tournament on Reactos 0.3.3 with real Hardware&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
	</entry>
	
	<entry>
		<title>Linux needs to evolve - now!</title>
		<link href="http://matthias-endler.de/2007/linux-needs-to-evolve-now"/>
		<updated>2007-01-04T00:00:00-08:00</updated>
    <id>http://matthias-endler.de//2007/linux-needs-to-evolve-now</id>
		<content type="html">&lt;p&gt;It was a brilliant idea to create an operating system that is free for everyone to use and to edit. Thousands of hackers around the globe share the dream of open source information technology without monopolism. Everybody who is into computing has heard of Linux and lots of them are using it for daily work. Even inexperienced users try out Linux by testing distributions like &lt;a href='http://www.ubuntu.com/' title='Linux for human beeings - Canonical'&gt;Ubuntu&lt;/a&gt;, &lt;a href='http://en.opensuse.org/Welcome_to_openSUSE.org' title='German distribution by Novel'&gt;openSuse&lt;/a&gt; or &lt;a href='http://www.knopper.net/knoppix/index-en.html' title='Live Distri. Klaus Knopper'&gt;Knoppix&lt;/a&gt; because they are easy to use and to install. But that&amp;#8217;s not the complete truth.&lt;/p&gt;

&lt;h3 id='hardware_woes'&gt;Hardware woes&lt;/h3&gt;

&lt;p&gt;This so called &amp;#8220;out-of-the-box&amp;#8221; experience can instead be very tricky and much to complicated for a normal user. When you insert the Ubuntu LiveCD you will be welcomed by a smart boot menu that lets you try out all the functionalities of a full-fledged Distribution without installing.&lt;/p&gt;

&lt;p&gt;The window manager has a fresh, clean-looking &lt;a href='http://ubuntuforums.org/showthread.php?t=234297'&gt;aqua&lt;/a&gt;-style interface. You click on install and almost everything is pre-configured and runs automatically. In most cases a distribution like Ubuntu auto-detects your hardware and installs the right modules. Hopefully. Sometimes it happens though that your printer is not working or your wireless connection was not recognized. This is mostly the case when you have shiny new hardware that linux hackers were not able to test yet. This can be a brand new inkjet printer (&lt;a href='http://catb.org/~esr/writings/luxury-part-deux.html'&gt;cups&lt;/a&gt; and gimp-print have a long way to go) or the high-end graphics card.&lt;/p&gt;

&lt;h3 id='hacker_perception'&gt;Hacker perception&lt;/h3&gt;

&lt;p&gt;Not a problem you might think. Look for a new development driver on Google, do a quick &lt;a href='http://www.debian.org/doc/manuals/apt-howto/index.en.html'&gt;apt-get&lt;/a&gt;, set-up your network connection and off you go! BUT explain that to &lt;a href='http://lwn.net/2002/0117/a/aunt-tillie.php3'&gt;Aunt Tillie&lt;/a&gt; sitting in front of her PC thinking that a Wlan card is a trading card her six year old nephew Gregory wants for Christmas. I don&amp;#8217;t have to add that she never opened a PC because she simply doesn&amp;#8217;t bother what&amp;#8217;s in there. You might say that it&amp;#8217;s also hard to configure your network a Windows PC. Well maybe it is - but it&amp;#8217;s already configured when you buy the PC - and that makes a big difference. Installing new software packages can be painful for normal users. Have you ever tried to explain to a non-geek why it&amp;#8217;s handy to use a terminal for daily work? At best you get an answer like &amp;#8221;I&amp;#8217;ve used DOS and that was a piece of crap&amp;#8221; or maybe he just says &amp;#8220;You are still sitting in front of a black text-mode only window entering cryptical commands to configure your system? This is not 1969!&amp;#8221;. Many people don&amp;#8217;t understand why typing chmod is smarter than clicking through ten windows opening the &amp;#8220;properties&amp;#8221; submenu with a right mouse click on a file and finally adjusting the access rights. Why should somebody use &amp;#8216;dmesg | tail&amp;#8217; to get some system information. The problem is: When somebody refuses to learn those shell-commands they won&amp;#8217;t understand 90 percent of the system. They can&amp;#8217;t see what went wrong when there is some internal dependency error. Linux will only be easy when you understand what you are doing.&lt;/p&gt;

&lt;h3 id='software_woes'&gt;Software woes&lt;/h3&gt;

&lt;p&gt;Even if you know how to work with a command line you can&amp;#8217;t be safe from so-called &amp;#8221;&lt;a href='http://en.wikipedia.org/wiki/Dependency_hell'&gt;dependency hell&lt;/a&gt;&amp;#8221;. You want to install a new office suite called &amp;#8220;OfficeSuite&amp;#8221; and download the packages directly from the developers site. But sadly it won&amp;#8217;t run because you don&amp;#8217;t have those three other packages installed which are all needed by &amp;#8220;OfficeSuite&amp;#8221;. OK. So you install those packages as well but they depend on three other libraries that you don&amp;#8217;t have as well. As a result you end up downloading and installing six packages in order to run &amp;#8220;OfficeSuite&amp;#8221; - now that&amp;#8217;s what I call productivity from the very beginning. The big problem behind this mess is the fact that there are no real standards in the Linux world. There are thousands of different flavors and to some extent this is great and it&amp;#8217;s exactly what free software has to look like but to get more traction we urgently need better standards to focus developing power. Don&amp;#8217;t get me wrong: There must be different package formats (like &lt;a href='http://www.rpm.org/'&gt;rpm&lt;/a&gt;, &lt;a href='http://en.wikipedia.org/wiki/Deb_(file_format)'&gt;deb&lt;/a&gt;, &lt;a href='http://www.gzip.org/'&gt;tgz&lt;/a&gt;&amp;#8230;) or various window managers (&lt;a href='http://www.kde.org/'&gt;KDE&lt;/a&gt;, &lt;a href='http://www.gnome.org/'&gt;Gnome&lt;/a&gt;, &lt;a href='http://fluxbox.sourceforge.net/'&gt;fluxbox&lt;/a&gt;, &lt;a href='http://www.icewm.org/'&gt;icewm&lt;/a&gt;&amp;#8230;) but they all must have a mutual basis to build up on. As we have seen the biggest problem is usability. Other Unix-like systems such as &lt;a href='http://www.apple.com/macosx/leopard/index.html'&gt;Mac OS X&lt;/a&gt; show how it can be done. Common guys! We can do better than that!&lt;/p&gt;

&lt;h3 id='why_it_matters'&gt;Why it matters&lt;/h3&gt;

&lt;p&gt;Some of the brightest Linux advocates don&amp;#8217;t realize that non- techies want a system where they don&amp;#8217;t need to know anything about bash, emacs or vi to successfully configure hardware drivers and network sharing (&lt;a href='http://forums.fedoraforum.org/showthread.php?p=681613'&gt;samba&lt;/a&gt;&amp;#8230;urgh). Those who say &amp;#8220;Screw it. If Linux is too hard for you, just don&amp;#8217;t use it&amp;#8221; are misguided. It is vital for open technologies to reach a critical mass and receive widespread adoption. Otherwise big companies like AMD and NVidia and EA have little interest to invest development time into open source projects.&lt;/p&gt;</content>
	</entry>
	
	<entry>
		<title>Howto switch from Linux to Windows - a users experience</title>
		<link href="http://matthias-endler.de/2006/howto-switch-from-linux-to-windows"/>
		<updated>2006-09-20T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2006/howto-switch-from-linux-to-windows</id>
		<content type="html">&lt;p&gt;I&amp;#8217;ve read articles like &amp;#8220;Switching from Windows to Linux in five easy steps&amp;#8221; or &amp;#8220;How changing your operating system can be fun with Linux&amp;#8221; or &amp;#8220;Why you should give Linux a chance&amp;#8221; for five years now but there are always people who say Linux is difficult to learn and Windows has much easier install routines and so on. But what if the first OS you&amp;#8217;ve ever used wasn&amp;#8217;t MS Dos or Win95 but some kind of Unix-based free system like BSD or Linux?&lt;/p&gt;

&lt;p&gt;This is a text about a guy who has always used Linux and learned working with it when he was a young man when he had to use it at work. Imagine Linux is the standard OS and Microsoft is a small company offering so called MS Windows XP. This text is meant to be &lt;em&gt;satiric&lt;/em&gt; so &lt;em&gt;don&amp;#8217;t take that too seriously&lt;/em&gt;! It is a fictional story that ought to be fun. So repeat after me: I will not take it seriously or otherwise not read it at all.&lt;/p&gt;

&lt;h3 id='my_first_steps_with_windows_xp'&gt;My first steps with Windows XP&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;ve heard of a new Operating System called &lt;a href='http://www.microsoft.com'&gt;Microsoft Windows&lt;/a&gt; the other day and wanted to give it a try because it is said to be easy to use and intuitive. Unfortunately the author offers no live-cd to test everything before I have to install. Instead of downloading it from the Internet as I always do I had to go to the computer store and buy it for a price of $150. There is also a so called &lt;em&gt;Professional Edition&lt;/em&gt; but it would cost even more. The first thing when I came home was to open the box, put the included CD into my DVD-Drive and start my PC. The install screen consisted of a simple blue background and an easy-to-use menu. I wanted to backup my data at first so I tried to open a virtual terminal but the normal &lt;a href='http://www.linuxjournal.com/article/5303'&gt;&lt;code&gt;CTRL-ALT-F1&lt;/code&gt;&lt;/a&gt; didn&amp;#8217;t work (WTF?). I had to reboot, make a copy and restart the installation all over again. The menu presented an option called &amp;#8220;Install Windows XP&amp;#8221; and I selected it.&lt;/p&gt;

&lt;p&gt;Then there was a strange message that said &amp;#8220;End-User License Agreement&amp;#8221; and that I have to accept it in order to continue. I have never heard about something like this on Linux so I read most of the long text. I am not allowed to distribute this product and I may not make copies for my friends. This was somehow the extreme opposite of a license I&amp;#8217;ve previously heard of that is called &lt;a href='http://www.gnu.org/copyleft/gpl.html'&gt;Gnu GPL&lt;/a&gt;. After I accepted it with &lt;code&gt;F8&lt;/code&gt; the installation continued. Windows didn&amp;#8217;t recognize that I had ext3 and reiserfs partitions on my system and told me that it had found an &amp;#8220;unknown filesystem&amp;#8221;. I always thought that they were standard but maybe I was wrong. There was an option to erase the whole harddisk and install WinXP and I selected it. The next curious thing was that Windows doesn&amp;#8217;t create a separate partition for my precious data but only one big system partition instead. &amp;#8220;Maybe Windows has a highly secure file-system that makes automatic backups in case of data loss&amp;#8221; I thought. Because I have a relatively big disk I wasn&amp;#8217;t able to select Fat32 and had to cope with NTFS. It took a while to format my disk.&lt;/p&gt;

&lt;p&gt;Unfortunately I wasn&amp;#8217;t allowed to select any packages from a list as I always do on Linux - Windows selected everything alone instead. The only adjustments I could make were entering the correct system-time, my username and something called registration key. This is a 25-digit number I had to enter manually before setup continued. After another reboot Windows was finally up and ready - well almost. Windows wanted to be activated at first. Within this procedure Microsoft tries to access the web to verify all registration data. No way! I canceled and Windows told me that I have a 30-days trial until I must register. That sucks!&lt;/p&gt;

&lt;p&gt;The new user interface appeared and I began to forget all the initial difficulties. It was a bit strange that there was no prompt to enter a default user for daily work. At the moment I was in administrator mode and had root access. That made me feel a bit uncomfortable because my little sister would have the same rights on that system. There also was no option to adjust file rights (something like chmod) manually and this could be another possible threat on a workstation. I&amp;#8217;ve looked for system documentation material to start adjust my new system just as I want it but I couldn&amp;#8217;t find anything usable (&lt;code&gt;F1&lt;/code&gt; is really no help). Suddenly an ugly yellow pop up appeared in the bottom right corner. It said something like &amp;#8220;New device found.&amp;#8221; A window in the middle of my screen told me that I should insert the device driver CD for my printer and click on &amp;#8220;Continue&amp;#8221;. At first I didn&amp;#8217;t know what that meant but suddenly I knew that a device driver was something like a module. I remember getting a CD together with my printer and I found it in a box on my attic. I clicked on &amp;#8220;Continue&amp;#8221;. My new system warned me that the device driver has not passed the hardware compatibility test and that I should try to find another driver. I was a bit afraid to click on &amp;#8220;Continue&amp;#8221; but finally I brought myself to do it and - everything ran flawlessly. I was a bit irritated why this stupid message annoyed me but I didn&amp;#8217;t have time to fuss. Afterwards I installed all the other hardware and was ready for surfing.&lt;/p&gt;

&lt;p&gt;There was no firewall or anti-virus software installed and I felt a bit insecure when I first entered the web. I surfed for maybe two minutes before I received a message from &amp;#8220;Al Dick&amp;#8221; who offered a six-year-ration of Viagra. Despite the fact that I don&amp;#8217;t need such things (really!) it was unbelievably annoying. I found a howto on the net to turn off such messages. The Internet Explorer doesn&amp;#8217;t have a popup filter and seems to attract ads and after fifteen minutes my taskbar looked like a battlefield full of spam. I had to close every window manually. My former Browser Firefox had tab-functionality included but IE seems to have own browsing rules and standards. But that was just the beginning: When I wanted to chat with my friends I found out that &lt;a href='http://get.live.com/messenger/overview'&gt;Windows Messenger&lt;/a&gt; didn&amp;#8217;t support ICQ, AIM, TOM and Jabber. I was forced to create a so called MSN-Account to continue but I refused. When I wanted to watch a newly bought DVD I got from France &lt;a href='http://www.microsoft.com/windows/windowsmedia/download/'&gt;Windows Media Player&lt;/a&gt; told me that I may not use my DVD on my PC because of a so called &amp;#8220;region code&amp;#8221;. I was a bit confused about all this and asked a friend what to do. He told me that there is data transfer from a PC running Windows directly to Microsoft in order to check my hardware specifications and to make a genuine check of my software. I was shocked. I was paying a lot of money to own a stable, secure system that respects my privacy and not a buggy, talkative piece of crap open to others like a barn door. I wanted to take a look at the source code to see if those recriminations were right but I couldn&amp;#8217;t because there was no source included! I don&amp;#8217;t want to talk about the so called &amp;#8220;file hierarchy&amp;#8221; of XP where the systems config files can be accessed via &lt;code&gt;C:\Windows\system&lt;/code&gt; instead of &lt;code&gt;/etc&lt;/code&gt;. You don&amp;#8217;t want to know what defragmentation is (there&amp;#8217;s no need for it on a linux box), I won&amp;#8217;t speak about the lousy terminal called &amp;#8220;command&amp;#8221; and why you should never ever open email attachments with Outlook Express.&lt;/p&gt;

&lt;p&gt;After the system crashed when I wanted to burn a CD with the &lt;a href='http://www.theregister.co.uk/2001/12/18/roxio_easycd_and_windows_xp/'&gt;skinny burning tool&lt;/a&gt; included while doing some spreadsheet analysis with Microsoft&amp;#8217;s miserable OpenOffice alternative called &amp;#8220;Office XP&amp;#8221; that cost me another $119 (I got it a bit cheaper because I&amp;#8217;m a student) I put everything back into the nice green box and took it back to my trader. At the same day I installed Linux again giving a review on a half-baked, single-user operating system called Windows XP that may be ready for desktop use in about five years. Until then I enjoy freedom with &lt;a href='http://www.freebsd.org/'&gt;BSD&lt;/a&gt;, &lt;a href='http://www.opensolaris.org/os/'&gt;OpenSolaris&lt;/a&gt; and &lt;a href='http://www.distrowatch.com'&gt;Linux&lt;/a&gt;.&lt;/p&gt;

&lt;ul class='blocklist'&gt;
&lt;li&gt;&lt;a href='http://cafcom.free.fr/spip.php?article18'&gt;French translation by Jacques Bon&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://inquietamente.wordpress.com/2008/12/06/como-pasarse-de-gnulinux-a-windows-humor/'&gt;Spanish translation by Tux Azteca and Alberto March&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.kletskous.com/2006/10/11/overstappen-van-linux-naar-windows-een-gebruikerservaring/'&gt;Dutch translation by Catharina Bethlehem&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
	</entry>
	
	<entry>
		<title>Linux games</title>
		<link href="http://matthias-endler.de/2006/linux-games"/>
		<updated>2006-08-30T00:00:00-07:00</updated>
    <id>http://matthias-endler.de//2006/linux-games</id>
		<content type="html">&lt;p&gt;Here are some linux &lt;a href='http://de.wikipedia.org/wiki/FLOSS'&gt;floss&lt;/a&gt; games I&amp;#8217;ve tried (ordered by personal rating):&lt;/p&gt;

&lt;h3 id='mania_drive_'&gt;Mania Drive &lt;div class='game onRight'&gt;(9/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;m totally fascinated. It is almost too simple but it makes so much fun (especially when you play with a friend) that you can&amp;#8217;t stop until you&amp;#8217;ve played all levels. Mania Drive can be understood as a tribute to &lt;a href='http://www.trackmania-the-game.de'&gt;TrackMania&lt;/a&gt; - a freeware game (well partly). I actually did a level myself than can soon be played via internet. It is called &amp;#8220;Super Clio Brothers 3 !&amp;#8221; and it beats SCB 1 and 2 in its craziness. Try it! &lt;a href='http://maniadrive.raydium.org/'&gt;Here is the official Mania Drive homepage&lt;/a&gt; and &lt;a href='http://www.matthias-endler.de/download/SuperClioBros3.mni'&gt;here is the &quot;Super Clio Brothers 3 !&quot; track&lt;/a&gt;. Feel free to share this link.&lt;/p&gt;

&lt;h3 id='pingus_'&gt;Pingus &lt;div class='game onRight'&gt;(9/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;You know Lemmings. This game is a clone but with much better graphics, sound and level design. It uses the &lt;a href='http://www.libsdl.org/'&gt;SDL library&lt;/a&gt; and is therefore highly portable. It runs on Windoze and Linux (and maybe OS X) but I haven&amp;#8217;t tried it yet. Give it a try - you won&amp;#8217;t be disappointed. &lt;a href='http://pingus.seul.org/'&gt;Here is the offical homepage&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='super_tux_'&gt;Super Tux &lt;div class='game onRight'&gt;(9/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;Can&amp;#8217;t help but I have to give another nine out of ten points. This time Tux follows Super Marios footsteps and jumps through (partly very tough) levels. Here is the &lt;a href='http://supertux.berlios.de/'&gt;project page&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='klotski_'&gt;Klotski &lt;div class='game onRight'&gt;(9/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;how I love and hate it. The only thing to do is to move some bricks to finally get one out of a box. Sounds easy? &lt;a href='http://phil.freehackers.org/klotski/'&gt;Try! &lt;/a&gt;&lt;/p&gt;

&lt;h3 id='neverball_'&gt;Neverball &lt;div class='game onRight'&gt;(8/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;Neverball is a game where you have to control a little ball over various platforms and mechanisms without letting it fall down. This can be harder than you think! Neverball has comic-like graphics and nice shadows and reflections. There is another game that can run on older PCs and doesn&amp;#8217;t have bombastic graphic effects but makes the same fun: &lt;a href='http://trackballs.sourceforge.net/'&gt;Trackballs&lt;/a&gt;. &lt;a href='http://www.icculus.org/neverball'&gt;Download Neverball here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='nexuiz_'&gt;Nexuiz &lt;div class='game onRight'&gt;(7/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;This is a shooter with nice graphics and balanced gameplay. I often play shooters and there are a lot of them out there available for free. It&amp;#8217;s a pity that there are no bots in the game so it can only be played on lan parties or via internet. &lt;a href='http://www.alientrap.org/nexuiz/'&gt;Look here to download&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='cube_'&gt;Cube &lt;div class='game onRight'&gt;(7/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;And again we have a shooter here. This time it is a fast and dynamic shooter that has its focus on lan gamers and simple gameplay. It has the highest framerate of those three mentioned and it is optimized for speed. One may like it or not. &lt;a href='http://www.cubeengine.com/'&gt;Download here&lt;/a&gt;! There is also a new engine still in developement: &lt;a href='http://sauerbraten.org/'&gt;Sauerbraten/Cube2&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='warzone_2100_'&gt;Warzone 2100 &lt;div class='game onRight'&gt;(7/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;Strategy game like Starcraft or Command and Conquer. It is in 3d and runs fast on my machine. The battles can really make fun and the AI is sometimes very clever. It has previously been developed by Pumpkin Studios and published by Eidos before it was GPLed. &lt;a href='http://warzone2100.strategyplanet.gamespy.com/'&gt;Look here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='tremolous_'&gt;Tremolous &lt;div class='game onRight'&gt;(6/10)&lt;/div&gt;&lt;/h3&gt;

&lt;p&gt;Another shooter that wants to bring in some new ideas into the genre. Don&amp;#8217;t expect to much because it is in an early stage. You can already play via network but there should be single player mode. It is based on &lt;a href='http://www.icculus.org/quake3/'&gt;Quake3&lt;/a&gt; and it was the first game using its source code since it now is published under GnuGPL. &lt;a href='http://www.tremulous.net/'&gt;Here is the offical page&lt;/a&gt;.&lt;/p&gt;
&lt;script type='text/javascript'&gt;
$(document).ready(function() {
	$('.game').ratingbar({		
		textMarkup: &quot;&lt;div class='ratingbar_text onLeft' /&gt;&quot;,
		animate:	true,
		duration:	1000,
		ease:		&quot;easeOutBounce&quot;
	});
});
&lt;/script&gt;</content>
	</entry>
	
</feed>
