<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>newthink.net &#187; Ash Christopher</title>
	<atom:link href="http://www.newthink.net/author/ash/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.newthink.net</link>
	<description>Less Talk. More Do.</description>
	<lastBuildDate>Sat, 18 Dec 2010 03:52:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Multi-Threaded Django Dev Server</title>
		<link>http://www.newthink.net/2010/12/17/multi-threaded-django-dev-server/</link>
		<comments>http://www.newthink.net/2010/12/17/multi-threaded-django-dev-server/#comments</comments>
		<pubDate>Sat, 18 Dec 2010 03:52:11 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.newthink.net/?p=322</guid>
		<description><![CDATA[When using django, most of us use the &#8216;runserver&#8217; that comes with Django. For the most part, it&#8217;s great and allows us to get things done quickly.
Where it starts to run into problems is when working on web-apps that make a lot of ajax calls or load media. 
Ajax calls are especially important as the [...]]]></description>
			<content:encoded><![CDATA[<p>When using django, most of us use the &#8216;runserver&#8217; that comes with Django. For the most part, it&#8217;s great and allows us to get things done quickly.</p>
<p>Where it starts to run into problems is when working on web-apps that make a lot of ajax calls or load media. </p>
<p>Ajax calls are especially important as the built-in &#8216;runserver&#8217;, which runs in a single thread, guarentees that the order the ajax calls is made is the order they get returned. In the real world, we know this doesn&#8217;t happen, and any good developer should plan for this.</p>
<p>Introducing <strong>django-concurrent-server</strong> (a fork of an existing project which I have updated). Now even better than the original &#8211; you can use PIP to install it!</p>
<p><a href="https://github.com/ashchristopher/django-concurrent-server" class='software-link'><img src="http://www.newthink.net/wp-content/uploads/2010/12/octocat.png" alt="" title="octocat" width="64" height="49" class="alignnone size-full wp-image-327" />django-concurrent-server</a> </p>
<p>This multi-threaded development server not only increases the performance of your development box, but will also allow you to test in less pristine conditions.</p>
<p>It works essentially exactly the same as Django&#8217;s own &#8216;runserver&#8217; command &#8211; taking the same arguments and everything.</p>
<pre class="code">
(secretproj)ash@dev:~/sandbox/secret-project/source$ python manage.py runcserver 0.0.0.0:8000
Validating models...
0 errors found

Django version 1.2.3, using settings 'source.settings'
Concurrent Development server is running at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2010/12/17/multi-threaded-django-dev-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Central Git Repository</title>
		<link>http://www.newthink.net/2009/09/20/simple-central-git-repository/</link>
		<comments>http://www.newthink.net/2009/09/20/simple-central-git-repository/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 23:09:29 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[source control]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://www.newthink.net/?p=154</guid>
		<description><![CDATA[I have a new project that I am starting, and instead of using the familiar subversion for source control, I figured this was a great time to check out Git. An added bonus is we are looking at switching over to it at work &#8211; two birds.
The first thing you need to do is install [...]]]></description>
			<content:encoded><![CDATA[<p>I have a new project that I am starting, and instead of using the familiar subversion for source control, I figured this was a great time to check out Git. An added bonus is we are looking at switching over to it at work &#8211; two birds.</p>
<div id="attachment_165" class="wp-caption aligncenter" style="width: 311px"><img class="size-full wp-image-165  " title="Distributed Source Control" src="http://www.newthink.net/wp-content/uploads/2009/09/drawing1.jpg" alt="" width="301" height="177" /><p class="wp-caption-text">Users can push and pull from other users or from a central repository. </p></div>
<p>The first thing you need to do is install git on both your clients and server. I am using Ubuntu, so you will have to figure out the equivalent commands and package names.</p>
<pre style="padding-left: 30px;">(client)$ sudo apt-get install git git-core

(server)$ sudo apt-get install git git-core</pre>
<p>Now that we have git on our server and client, we can start creating the git repository we want under source control.</p>
<p>The first thing we will do is create a git project. This can either be an existing code base you are already working on, or you can start a project from scratch. For the purposes of this example, we will start a new project.</p>
<pre style="padding-left: 30px;">(client)$ mkdir project
(client)$ cd project
(client)$ git init</pre>
<p>Git should reply with the message &#8216;<strong>Initialized empty Git repository in .git/</strong>&#8216;. Make a note of the .git directory created in our project &#8211; we will need it shortly.</p>
<p>I ran into my first issue here &#8211; the version of git I am using doesn&#8217;t seem to like to clone empty repositories. In order to allow me to clone (as you will see further down the page), we must have an initial commit.</p>
<pre style="padding-left: 30px;">(client)$ touch README
(client)$ git add README
(client)$ git commit -m "Initial commit." README</pre>
<p>We want this new project to be available on a central Git repository (centralized decentralized version control system &#8211; the irony is not lost on me). The easiest way is to just <strong>scp </strong>the .git directory to the server and place them in the directory you plan on containing your repositories. In my case, I created a <strong>git </strong>directory off of <strong>/</strong> on the server.</p>
<pre style="padding-left: 30px;">(server)$ sudo mkdir /git

(client)$ git clone --bare project project.git
(client)$ scp -r project.git user@server:/git/</pre>
<p>Essentially, we are finished adding the repository to the central server. We can now access the git repo from all clients so long as those users have ssh access to the central server. By default, we can access the repo from the clients using the ssh interface.</p>
<pre style="padding-left: 30px;">(client)$ git pull user@server:/git/project.git master</pre>
<p>And we can push changes to the repo in a similar fashion.</p>
<pre style="padding-left: 30px;">(client)$ git push user@server:/git/project.git master</pre>
<p>This is about as simple a set up as you can have. The Git server is really quite dumb. The real magic happens on the client side (which is left for another post when I have done a bit more research).</p>
<p>By default, this git server is private. Only users that have shell access to the server have access to push and pull changes. Push access requires private access, but for projects which you want public access, you can set up a <a href="http://www.kernel.org/pub/software/scm/git/docs/git-daemon.html">git-daemon</a> to serve git clone requests from the public. Rather than run it as a persistent process, you can quite simply tie it into <strong>xinetd </strong>with this simple configuration (remember, I am using Ubuntu).</p>
<pre style="padding-left: 30px;">(server)$ touch /git/project.git/git-daemon-export-ok
(server)$ sudo apt-get install xinetd
(server)$ sudo vi /etc/xinetd.d/git</pre>
<pre style="padding-left: 60px;">service git
{
    disable = no
    type = UNLISTED
    port = 9418
    socket_type = stream
    wait = no
    user = nobody
    server = /usr/bin/git-daemon
    server_args = --inetd --export-all --base-path=/git
}</pre>
<pre style="padding-left: 30px;">(server)$ sudo /etc/init.d/xinetd restart</pre>
<p>This now gives us a public git repository url we can distribute to others.</p>
<pre style="padding-left: 30px;">(client)$ git clone git://server/project.git</pre>
<p>Just remember that you still need to push changes to the repo via ssh.</p>
<h2><strong>UPDATE</strong></h2>
<p>Talked to one of the guys in #git on irc.freenode.net and he informed me that the usual practice is to create the git repo on the central server first, then clone it to the client and push changes from the client.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2009/09/20/simple-central-git-repository/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The API is the Application</title>
		<link>http://www.newthink.net/2008/10/20/the-api-is-the-application/</link>
		<comments>http://www.newthink.net/2008/10/20/the-api-is-the-application/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 13:09:32 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.newthink.net/?p=90</guid>
		<description><![CDATA[&#8220;web servers can be clustered such that the architecture can be horizontally scaled with money. You can fix scaling issues by throwing hardware at it.&#8220;

The API, or Application Programming Interface, in simple terms, is a set of libraries which can be called which provide linked or shared functionality. In the past, this API was available [...]]]></description>
			<content:encoded><![CDATA[<h2 style="padding-left: 30px;"><em><strong>&#8220;web servers can be clustered such that the architecture can be horizontally scaled with money. You can fix scaling issues by throwing hardware at it.</strong><strong>&#8220;</strong></em></h2>
<p style="padding-left: 30px;">
<p>The API, or Application Programming Interface, in simple terms, is a set of libraries which can be called which provide linked or shared functionality. In the past, this API was available as binaries or source code which would be compiled into, or released with (in the form of shared libraries) your program.</p>
<p>With the increased popularity of specialized web software, the original idea of the API has evolved (and some argue bastardized). The original, mainstream, bloated and cumbersome SOAP and XMLRPC web API technologies are out in favor of the new hotness &#8211; RESTful API&#8217;s.</p>
<h2><strong><span style="text-decoration: underline;">RESTful API</span></strong></h2>
<p>REST, or <em>Representational state transfer</em>, is the style of software architecture which the word wide web was based on. Like all world wide web traffic, RESTful API&#8217;s are inherently stateless. They receive a request via a GET or POST, process it, then return a response. The next request is not affected by the previous, nor will future requests be affected by the requests processed in the past.</p>
<p>The great thing about the REST architecture is that it&#8217;s horizontally scalable. Assuming an infinite pipe, the web servers can be clustered such that the architecture can be horizontally scaled with money. You can fix scaling issues by throwing hardware at it.</p>
<div id="attachment_122" class="wp-caption aligncenter" style="width: 296px"><img class="size-medium wp-image-122" title="Clustered Web Servers." src="http://www.newthink.net/wp-content/uploads/2008/10/diag1-286x300.jpg" alt="Servers can be added to the cluster and scaled horizontally due to the RESTful nature of the HTTP protocol." width="286" height="300" /><p class="wp-caption-text">Servers can be added to the cluster and scaled horizontally due to the RESTful nature of the HTTP protocol.</p></div>
<h2><strong><span style="text-decoration: underline;">RESTful API as the Application</span></strong></h2>
<p>Although websites are still the main way users interact with internet-based applications, many web applications don&#8217;t rely on a web browser at all! An emerging trend is to allow users the ability to access remote resources via an API which provides data for any number of applications &#8211; web based or not. Twitter for example, is increasingly accessed via third-party applications such as <a title="twhirl link" href="http://www.twhirl.org/">Twhirl</a> using their RESTful interface.</p>
<p>With the new popularity of web applications that don&#8217;t use browsers, I propose changing how these web applications are created. Instead of developing websites followed by the API, or even the API in tandem, why not create the API as the application in and of itself, then write the web application using the RESTful API? Lets think of the website as been just another application making use of remote resources.</p>
<p>By taking advantage of the nature of RESTful API&#8217;s we should in theory be able to create a system that scales horizontally. The added bonus is you won&#8217;t waste your time creating a website which may not be used by the end users in the future. Mobile and location based applications by their very nature will be using website access less and less.</p>
<p>Another advantage is that you maintain a clear separation of resources throughout your application. It forces developers to decouple the business layer from the display layer. Its very nature stops logic code from creeping into the display (as is the case with numerous PHP web applications).</p>
<p>It also provides many options and avenues when dealing with application management in startups and established businesses. By separating the display in this way, it makes it much easier to farm out display work to third party companies which can focus 100% on that task, decreasing your time to market.</p>
<p>At the recent DevHouseWaterloo meet-up, I proposed this plan to a group of software professionals and tech-savvy students, and they seemed to think this was an excellent way to create new internet based applications. I have been taking this approach with my latest project, and so far I am quite pleased. The biggest advantage I have found is that I can focus on the application. I know I am not a very good website designer nor do I pretend to be. I am much more interested in writing the core software and farming out the work to someone who can give the user interface the care it deserves.</p>
<p>What are the rest of the communities thoughts on this approach to software development? Do you have examples of other companies that take this approach? Are there any reasons not to pursue this development plan?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2008/10/20/the-api-is-the-application/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PostRank Python API</title>
		<link>http://www.newthink.net/2008/07/14/postrank-python-api/</link>
		<comments>http://www.newthink.net/2008/07/14/postrank-python-api/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 15:22:00 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[AideRSS]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[PostRank]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2008/07/14/postrank-python-api/</guid>
		<description><![CDATA[What is PostRank?
PostRank is a scoring system developed by AideRSS to rank any kind of online content, such as RSS feed items, blog posts, articles, or news stories. PostRank is based on social engagement, which refers to how interesting or relevant people have found an item or category to be.
Public-facing RESTful API&#8217;s are becoming more [...]]]></description>
			<content:encoded><![CDATA[<h3>What is PostRank?</h3>
<blockquote><p>PostRank is a scoring system developed by AideRSS to rank any kind of online content, such as RSS feed items, blog posts, articles, or news stories. PostRank is based on social engagement, which refers to how interesting or relevant people have found an item or category to be.</p></blockquote>
<p>Public-facing <a href="http://en.wikipedia.org/wiki/RESTful">RESTful</a> API&#8217;s are becoming more popular as a way to allow access to services by third-parties. <a href="http://www.aiderss.com">AideRSS</a> recently decoupled their PostRank service and offered it as a stand-alone service allowing any developer to use <a href="http://www.postrank.com">PostRank</a> within their application. I am in the process of updating this website/blog and I am planning to make use of the PostRank service not only as a tool to measure my engagement with the public, but increase the usefulness of my posts.</p>
<h3>What is PostRank Python API and what does it do?</h3>
<p>This is an api accessor for python that allows a developer to quickly access all of the services offered by PostRank. It is loosely modeled after <a href="http://mike.verdone.ca/twitter/">Mike Verdone&#8217;s Python Twitter Tools</a> in that it is simple to use, and it uses the same arguments as those documented on the <a href="http://postrank.com/developers.html">PostRank API</a> page.</p>
<h3>What are the requirements?</h3>
<ul>
<li>Python 2.5 <em>(haven&#8217;t tested with &lt;2.4)</em></li>
<li>simplejson python library <em>(if using json output)</em></li>
</ul>
<h3>How do I use it?</h3>
<p>Using the PostRank Python API is very easy. The first step should be to look at the API documentation provided by the PostRank website.</p>
<p><img src="http://newthink.net/wp-content/uploads/2008/07/feed_id_api_doc1.png" alt="feed_id API Doc" /></p>
<p>We can see what options the api needs in order to satisfy the request. We just need to specify the resource that we want to use, then we can add all the arguments we want passed along to PostRank.</p>
<p><img src="http://newthink.net/wp-content/uploads/2008/07/feed_id_usage_example.png" alt="feed_id usage example." /></p>
<p>If you have selected JSON as your format, the api will return to you a simplejson object which can be accessed just like a multi-dimensional array. When using JSON, it is extremely simple to get at the information provided by PostRank.</p>
<p><img src="http://newthink.net/wp-content/uploads/2008/07/using_json_object.png" alt="Using the json object." /></p>
<p>There is a bit of a trick when using the &#8216;<a href="http://postrank.com/api/postrank.html">postrank</a>&#8216; resource but it certainly isn&#8217;t difficult to use.  It works the exact same way &#8211; the PostRank API says it wants an array of urls (url[]) so we will pass in an array of urls as an argument (same thing for the feed_id[]).</p>
<p><img src="http://newthink.net/wp-content/uploads/2008/07/post_rank_api_doc.png" alt="post_rank API Doc" /></p>
<p>Following the same pattern as before, we just pass in the resource we want to use and the API arguments.</p>
<p><img src="http://newthink.net/wp-content/uploads/2008/07/postrank_usage_example.png" alt="postrank usage example." /></p>
<p>There really isn&#8217;t much more to it.  For now, you can find the python library here: <a href="http://newthink.net/~ash/software/postrankapi/">http://newthink.net/~ash/software/postrankapi/</a> When my new website is done, I plan to find a more permanent place for this (and future software).  Next step, creating an egg and integrating with ez_install.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2008/07/14/postrank-python-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>fcgi and mod_fcgid on CentOS4</title>
		<link>http://www.newthink.net/2008/03/09/fcgi-and-mod_fcgid-on-centos4/</link>
		<comments>http://www.newthink.net/2008/03/09/fcgi-and-mod_fcgid-on-centos4/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 00:27:25 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[RPM]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2008/03/09/fcgi-and-mod_fcgid-on-centos4/</guid>
		<description><![CDATA[I decided recently that I wanted to be able to run Ruby on Rails applications from my webserver. For those who don&#8217;t know me, RPM database integrity is a huge issue for me (I do not just install from source on my server!).
Since I had some time this weekend, I decided it was about time [...]]]></description>
			<content:encoded><![CDATA[<p>I decided recently that I wanted to be able to run Ruby on Rails applications from my webserver. For those who don&#8217;t know me, RPM database integrity is a huge issue for me (I do not just install from source on my server!).</p>
<p>Since I had some time this weekend, I decided it was about time I rolled some RPM&#8217;s so I could run Rails. Of course, it being over two years since I was last rolling RPM&#8217;s for work at Pason, it took me a bit to get back in the swing of things.</p>
<p>I followed the <a href="http://wiki.rubyonrails.org/rails/pages/Rails+on+CentOS+4.6+with+Apache+and+FastCGI+Simply">guide</a> found via the Ruby on Rails wiki, and modified it a bit for my server. The two main pieces of software that needed RPM&#8217;s were fastCGI and mod_fcgid (slightly different than mod_fastcgid).</p>
<p>Below you can download the RPM&#8217;s and the SRPM&#8217;s though I will be the first to acknowledge that I cheated a bit. I should have modified the Makefile on each of these programs to make use of an install_dir directive, but since I was building on a clean CentOS4.6 vmware OS, I decided not to go through the hassle. If someone really wants to do it properly, have at it &#8211; that&#8217;s what SRPMS are for.</p>
<p><strong>RPMS:</strong><br />
<a href="http://www.newthink.net/files/mod_fcgid-1.09-1.i386.rpm">mod_fcgid-1.09-1.i386.rpm</a><br />
<a href="http://www.newthink.net/files/fcgi-2.4.0-1.i386.rpm">fcgi-2.4.0-1.i386.rpm</a></p>
<p><strong>SRPMS:</strong><br />
<a href="http://www.newthink.net/files/mod_fcgid-1.09-1.src.rpm">mod_fcgid-1.09-1.src.rpm</a><br />
<a href="http://www.newthink.net/files/fcgi-2.4.0-1.src.rpm">fcgi-2.4.0-1.src.rpm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2008/03/09/fcgi-and-mod_fcgid-on-centos4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Interview</title>
		<link>http://www.newthink.net/2008/02/18/google-interviews-have-kept-me-busy/</link>
		<comments>http://www.newthink.net/2008/02/18/google-interviews-have-kept-me-busy/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 03:01:21 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Interview]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2008/02/18/google-interviews-have-kept-me-busy/</guid>
		<description><![CDATA[
First off, I&#8217;ll spare you the suspense. I did NOT get offered a job at Google&#8230; but I did have a lot of fun!
I was first contacted back in December by a Google talent recruiter. Mike had been in the middle of his Google interviews, so it was an exciting time.
Was I interested? Definitely! There [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://newthink.net/wp-content/uploads/2008/02/google_logo_sm.jpg" alt="Google" width="512" height="214" /></p>
<p>First off, I&#8217;ll spare you the suspense. I did <strong>NOT</strong> get offered a job at Google&#8230; but I did have a lot of fun!</p>
<p>I was first contacted back in December by a Google talent recruiter. <a href="http://mike.verdone.ca/blog">Mike</a> had been in the middle of his Google interviews, so it was an exciting time.</p>
<p>Was I interested? Definitely! There are few in the software industry that wouldn&#8217;t jump at a chance to work for Google &#8211; one might call them the Mecca of the software industry (but only if it doesn&#8217;t offend anyone; if it does, let&#8217;s just call it a pretty neat place to work).</p>
<p>I first received an email from the recruiter asking if I was interested, and where I wanted to look for a position. She told me that she thought there was a good fit for me for a Java position in Mountain View, but I asked her about looking for a job in Waterloo. Was it a mistake? Maybe, but she did mention that I could look into a position in Mountain View if the Waterloo position didn&#8217;t work out.</p>
<p>Over the Christmas holidays, the recruited emailed me to let me know that the Waterloo position was a C++ position, and that perhaps I would have a better chance finding interest in Mountain View, but the next day she emailed me back to let me know that the Waterloo offices were interested.</p>
<p>I was excited. One of my goals, new years resolutions if you will, was to step out of my comfort zone with regards to software development. It seems that every script I needed to write was being written in Perl and Bash script and every piece of software I was writing professionally was in Java. I wanted get out of the habbit of relying on Java/Perl/Bash. This seemed like a good opportunity as C++ is one of many languages I wanted to work on this year.</p>
<p>Well, I guess what you really want to know is what sorts of things I was asked on my interviews. Well, before that, there are a lot of things that need to be reviewed; first and foremost, <strong>asymptotic notation and complexity</strong>. The interview questions consisted of asking me to come up with a semi-high level algorithm and then to explain the asymptotic complexity of each part as I went along, and then what the final complexity of the algorithm would be.</p>
<p>The next thing that should be reviewed is your basic sorting algorithms and their respective complexities. I made sure to know heap sort, bubble sort, selection sort, binary sort, merge sort, quick sort and insertion sort. Also important, you should know the memory requirements that each algorithm uses to run (in big-O notation). I was asked in my first interview to not only minimize the runtime, but also the memory footprint (ie. insertion sort although is O(n^2) in runtime, it is O(1) with regards to memory).</p>
<p>The next thing I reviewed was memory structures. Hash&#8217;s, binary trees, n-tier trees, etc and the properties that each one possesses. If the interviewer asks you about a binary tree, make sure you know the properties that make a binary tree special so that you can leverage it in your solution.</p>
<p>Now, on to the interviews.</p>
<p>The first interview started with a quick introduction from Steve about where he worked within Google (Google NYC) and what he worked on there (Google maps). Then it was right down to business. The first questions (from my memory, so don&#8217;t blame me if it isn&#8217;t 100% correct) was as follows:</p>
<p><strong><em>Given a binary tree, and two leaves, can you find the lowest common node of those leaves?</em></strong></p>
<p>I won&#8217;t give you the answer here. I&#8217;ll let you work it out for a bit and perhaps if there is enough discussion in the comments, I&#8217;ll leave the answer there. When giving my answer to the interviewer, I think I could have been a lot clearer. I was nervous; very nervous. I really didn&#8217;t know what to expect, even though Mike prepared me the night before. The answer I gave was right (as far as a solution and its complexity) however, about 10 minutes after completing my interview, I figured out a way to better leverage the binary tree structure which would have also given a much clearer answer. Also, I was asked to minimize both the runtime and memory usage in my solution.</p>
<p>The next interview I had was about 2 weeks later and it was with Chris (also from the Google NYC offices) but he worked for Google&#8217;s blog search. This one started a little different; he asked about what I had worked on at my previous companies and more specifically what I felt the coolest project was. I had so many to choose from at Pason, but I went with the biggest and more complex, the DataStream project. After that, he asked me my ideal problem to solve was if I could leverage all that is Google. This really caught me off guard. I should have known it was going to come; I even read about someone who was asked a similar questions. I spent so much time preparing for the technical part of the interview, I forgot about the lighter part. I wish I could have done it over. My answer was a lame scheduling mash-up for Google maps. I really needed to think bigger&#8230; hell, my friends and I have talked for years about cool stuff that we could do if only we had a company that was as big as Google.</p>
<p>I felt like an idiot, but what can you do. No sense dwelling on that. There were two technical questions that comprised this part of the interview. The first was:</p>
<p><strong><em>If you were designing the Vector class in Java, how would you code the add(Object) method?</em></strong></p>
<p>Deceptive; not hard per se, but there are a few things that need to be worried about when solving this question.</p>
<p>The next question was the algorithm question:</p>
<p><strong><em>If you were given an unordered set of plane tickets which represented legs in a trip, can you figure out the order in which to use the tickets?</em></strong></p>
<p>This was a really fun problem to work on, and again, I&#8217;ll save the answer for the comments. Remember that they want you to come up with the lowest runtime algorithm that you can.</p>
<p>Three days after I completed this interview, I got my letter letting me know that they were not going to be offering me a position. Was I disappointed? Sure. I have to admit that I thought about how neat it would be to work at Google, but it wasn&#8217;t all bad. It helped me fulfill another one of my new years resolutions &#8211; to get back into studying the &#8220;science&#8221; of computer science, and although stressful, the whole experience was a lot of fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2008/02/18/google-interviews-have-kept-me-busy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Running Subversion From xinetd</title>
		<link>http://www.newthink.net/2007/11/29/running-subversion-from-xinetd/</link>
		<comments>http://www.newthink.net/2007/11/29/running-subversion-from-xinetd/#comments</comments>
		<pubDate>Thu, 29 Nov 2007 21:45:34 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2007/11/29/running-subversion-from-xinetd/</guid>
		<description><![CDATA[Now that we have Subversion installed on our server, we really need some way to have it always available. We could run subversion in daemon mode but we would have to write init.d scripts which can get rather complex (especially if you are writing one properly, and not just hacking one together).
Instead, we will add [...]]]></description>
			<content:encoded><![CDATA[<p>Now that we have Subversion installed on our server, we really need some way to have it always available. We could run subversion in daemon mode but we would have to write init.d scripts which can get rather complex (especially if you are writing one properly, and not just hacking one together).</p>
<p>Instead, we will add subversion to xinetd. The benefit of this is that subversion is only running when we need access to the repository rather than running all the time. By default, subversion is not set up in xinetd, so the following is how I set it up:</p>
<p>First make sure that xinetd is installed.<br />
<code><br />
# yum install xinetd<br />
</code><br />
Next we want to add the following to our /etc/xinetd.d/svnserve<br />
<code><br />
# default: off<br />
# description: svnserve is the server part of Subversion.<br />
service svn<br />
{<br />
&nbsp;&nbsp;disable	= no<br />
&nbsp;&nbsp;port	= 3690<br />
&nbsp;&nbsp;socket_type   = stream<br />
&nbsp;&nbsp;protocol      = tcp<br />
&nbsp;&nbsp;wait          = no<br />
&nbsp;&nbsp;user          = root<br />
&nbsp;&nbsp;server        = /usr/bin/svnserve<br />
&nbsp;&nbsp;server_args   = -i -r /svn<br />
}<br />
</code><br />
Finally, lets restart xinetd:<br />
<code><br />
/etc/init.d/xinetd restart<br />
</code><br />
Now xinetd will start the subversion repository server every time a subversion request is made.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2007/11/29/running-subversion-from-xinetd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting Up Subversion On Fedora 8</title>
		<link>http://www.newthink.net/2007/11/28/setting-up-subversion-on-fedora-8/</link>
		<comments>http://www.newthink.net/2007/11/28/setting-up-subversion-on-fedora-8/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 22:14:59 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2007/11/28/setting-up-subversion-on-fedora-8/</guid>
		<description><![CDATA[After fighting with the corporate firewall (ssh tunnels were not successfully able to navigate to a SVN repo on a shared host) I decided I should set subversion up on my home server. Since I am a little paranoid about throwing caution to the wind with regard to server changes, I decided to set it [...]]]></description>
			<content:encoded><![CDATA[<p>After fighting with the corporate firewall (ssh tunnels were not successfully able to navigate to a SVN repo on a shared host) I decided I should set subversion up on my home server. Since I am a little paranoid about throwing caution to the wind with regard to server changes, I decided to set it up on my Fedora 8 vmware partition.</p>
<p>Here was my process.<br />
<code><br />
# yum install subversion<br />
</code><br />
Ok, that was pretty easy. I now have subversion installed on my system; both from a client and user&#8217;s perspective. Next I need to create a subversion repository location on my disk (/svn can be replaced with any location on your server).<br />
<code><br />
# svnadmin create /svn<br />
</code><br />
In /svn/conf/passwd add the following (it is in plaintext, but I am sure there is an encrypted solution):<br />
<code><br />
[users]<br />
achristopher = <em>some secret, yet plaintext password</em><br />
</code><br />
In the /svn/conf/svnserve.conf, you should set the following:<br />
<code><br />
[general]<br />
anon-access = read<br />
auth-access = write</p>
<p>password-db = passwd</p>
<p>realm = Test Repo<br />
</code><br />
There, our subversion repository has been set up. Now all we have to do is start the subversion daemon.<br />
<code><br />
# svnserv -r /svn -d<br />
</code><br />
We can test the subversion repo:<br />
<code><br />
# mkdir /tmp/test</p>
<p># svn import /tmp/test svn://localhost/svn/test -m "Initial creation."<br />
Committed revision 1.</p>
<p># svnlook tree /svn<br />
/<br />
 svn/<br />
  test/<br />
</code><br />
We have just added a directory to our subversion repository. Now lets checkout this project, and get to work:<br />
<code><br />
# rm -Rf /tmp/test<br />
# svn checkout svn://localhost/svn/test<br />
Checked out revision 1.<br />
</code></p>
<p>I cheated a little there, because I had entered my password before I created this posting, so you can expect to see something like the following:<br />
<code><br />
Authentication realm: <svn ://localhost:3690> Test Repo<br />
Password for 'achristopher':<br />
</svn></code><br />
Just enter your password (the one entered in plain text above) and continue working.</p>
<p><strong>To follow: How to set subversion to work with xinetd (it isnt that exciting, but definitely new post worthy).</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2007/11/28/setting-up-subversion-on-fedora-8/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>A Few Weeks With Rails</title>
		<link>http://www.newthink.net/2007/11/05/a-few-weeks-with-rails/</link>
		<comments>http://www.newthink.net/2007/11/05/a-few-weeks-with-rails/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 16:30:00 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2007/11/05/a-few-weeks-with-rails/</guid>
		<description><![CDATA[ It&#8217;s been a few weeks since I started using Ruby on Rails, and so far it has been pretty good. That isn&#8217;t to say I havent run into a few hickups.
I am quite familiar with PHP, so I set out to try to do the same things in rails as I would in PHP. [...]]]></description>
			<content:encoded><![CDATA[<p><img src='http://newthink.net/wp-content/uploads/2007/11/rails.png' alt='Ruby on Rails' align='left' style='margin-right: 10px' /> It&#8217;s been a few weeks since I started using Ruby on Rails, and so far it has been pretty good. That isn&#8217;t to say I havent run into a few hickups.</p>
<p>I am quite familiar with PHP, so I set out to try to do the same things in rails as I would in PHP. Everything seemed to transfer over without effort&#8230; except file upload inputs. These kept me busy for quite some time, and had me wanting to pull out my hair.</p>
<p>I tried to make use of the community; exploring the wiki, reading through the rails cookbook, seeking out blogs that addressed the issue, visiting <strong>#rubyonrails</strong> on <strong>irc.freenode.net</strong> on a regular basis. Infact, the IRC community was referring me to the wiki article (<a href="http://wiki.rubyonrails.org/rails/pages/HowtoUploadFiles">HowtoUploadFiles</a>). No matter how I tried, the upload just wouldnt work. I had narrowed the problem down to the <em>multipart => &#8220;true&#8221;</em> definition, but that was about as far as I could get without help. Luckily, I know a few rails nunjas (gurus) who helped me figure out what to do.</p>
<p>As it turns out, the rails wiki was incorrect. Since the project is opensource, it was easy enough for me to fix the documentation (perhaps the documentation was for a previous version of rails, and hadn&#8217;t been updated), but it was still a frustrating week (I was actually only working on it maybe and hour a night, but still) especially since it was such a simple task I was trying to complete.</p>
<p>Hopefully there are no more hiccups like this as I go forward. I am already thinking about a cool new idea which I am excited to work on once I complete this test application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2007/11/05/a-few-weeks-with-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What Is This Rails Thing?</title>
		<link>http://www.newthink.net/2007/10/01/what-is-this-rails-thing/</link>
		<comments>http://www.newthink.net/2007/10/01/what-is-this-rails-thing/#comments</comments>
		<pubDate>Mon, 01 Oct 2007 15:18:20 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2007/10/01/what-is-this-rails-thing/</guid>
		<description><![CDATA[A few weeks ago, I downloaded an eBook on Ruby on Rails and gave the first few chapters a read. It was decently interesting, and it sounded like something I would like to get into. I am not a fan of eBooks, so I decided I would spring for a physical copy.

The book covers Rails [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, I downloaded an eBook on Ruby on Rails and gave the first few chapters a read. It was decently interesting, and it sounded like something I would like to get into. I am not a fan of eBooks, so I decided I would spring for a physical copy.</p>
<p><a href="http://www.amazon.ca/Agile-Development-Rails-Dave-Thomas/dp/0977616630/ref=sr_1_1/702-0097744-5236026?ie=UTF8&#038;s=books&#038;qid=1191254859&#038;sr=8-1"><img src='http://newthink.net/blog/wp-content/uploads/2007/10/51yzkk7c2wl__ss500_.jpg' alt='Agile Web Development with Rails' /></a></p>
<p>The book covers Rails development from the beginners level to the fairly advanced. It offers an easy tutorial which one can follow along, and gives a decent amount of information about most of the features they have available.</p>
<p>One of the biggest features that the Rails framework offers is migration. Although it is a fairly small part of Rails, it is a technology which I know is useful to many companies. At Pason, we created our own technology that basically does the same task as migration. It would have been nice to just use the Rails&#8217; migration instead of developing our own.</p>
<p>The biggest issue I am having now, is getting back into the Python-style of coding. Ruby and Python are fairly similar&#8230; and very much different from Java and C++ which I am more familiar with. There are also a few speedbumps I am noticing when working on my first Rails project, but I hope to overcome them soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2007/10/01/what-is-this-rails-thing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SMARTHOST Authentication With Sendmail</title>
		<link>http://www.newthink.net/2007/05/18/smarthost-authentication-with-sendmail/</link>
		<comments>http://www.newthink.net/2007/05/18/smarthost-authentication-with-sendmail/#comments</comments>
		<pubDate>Fri, 18 May 2007 13:10:15 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Sendmail]]></category>
		<category><![CDATA[SMTP]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2007/05/18/smarthost-authentication-with-sendmail/</guid>
		<description><![CDATA[Rogers, one of Canada&#8217;s biggest ISP&#8217;s has this nasty habit of making life difficult for it&#8217;s customers. First they throttle BitTorrent traffic, and now in an attempt to curb spam, they block all outbound connections from port 25.
While this may not seem like a huge deal to most users, what this means is that you [...]]]></description>
			<content:encoded><![CDATA[<p>Rogers, one of Canada&#8217;s biggest ISP&#8217;s has this nasty habit of making life difficult for it&#8217;s customers. First they throttle BitTorrent traffic, and now in an attempt to curb spam, they block all outbound connections from port 25.</p>
<p>While this may not seem like a huge deal to most users, what this means is that you can&#8217;t connect to any other mail server when attempting to send emails because Rogers has blocked access. Jenna can&#8217;t send emails using her McMaster email from a Rogers account.</p>
<p>When I initially looked at setting up Internet, this was the first question I asked Rogers. They assured me that traffic shaping was the only limitation they put on the account. The customer service agent assured me that their literature even mentions this. Their literature is wrong.</p>
<p>As a way around this problem, you are going to want to set up a SMARTHOST on a linux box within the home network which is attached to the Rogers connection.</p>
<p>I did some testing and determined that Rogers doesn&#8217;t block all traffic over port 25, but only traffic that isn&#8217;t going to a Rogers controlled mail server.</p>
<p><code><br />
9:44 ash@galactica:[~]&gt; telnet smtp.broadband.rogers.com 25<br />
Trying 206.190.36.18...<br />
Connected to smtp.broadband.rogers.com (206.190.36.18).<br />
Escape character is '^]'.<br />
220 smtp107.rog.mail.re2.yahoo.com ESMTP<br />
</code></p>
<p>What we can do now, is set up a SMARTHOST in sendmail to basically forward emails from the server to Rogers SMTP server, then on to it&#8217;s destination. The following assumes you are the <em>root</em> user.</p>
<p>In your /etc/mail/sendmail.mc file, we need to add the following:<br />
<code><br />
define(`SMART_HOST',`smtp.broadband.rogers.com')<br />
</code></p>
<p>This defines what server we are going to use as a SMARTHOST. The other problem we are going to run into is that unlike other ISP&#8217;s which allow you to send via the SMARTHOST based on what your domain is (basically if you are connected on an ISP&#8217;s network, you can send using their server) Rogers requires that users authenticate.</p>
<p>To do this, we need to add the following to the /etc/mail/access file:</p>
<p><code><br />
AuthInfo:smtp.broadband.rogers.com "U:&lt;username&gt;" "P:&lt;password&gt;" "M:PLAIN"<br />
</code></p>
<p>I then changed the permissions to the file since I had my plaintext password in it:</p>
<p><code>chmod 660 /etc/mail/access</code></p>
<p>Next, we will regenerate the sendmail.cf and access.db files.</p>
<p><code><br />
m4 /etc/mail/sendmail.mc &gt; /etc.mail/sendmail.cf<br />
makemap hash /etc/mail/access &lt; /etc/mail/access<br />
</code></p>
<p>Now, restart sendmail, and you should be ready to go.</p>
<p>What you can do now, is set up all of your mail clients to point to the linux server as your outgoing mail server and it will forward all of your emails to Rogers and then on to it&#8217;s destination.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2007/05/18/smarthost-authentication-with-sendmail/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Solving The HTTP Double-Post Dilema</title>
		<link>http://www.newthink.net/2007/03/06/solving-the-double-post-dilema/</link>
		<comments>http://www.newthink.net/2007/03/06/solving-the-double-post-dilema/#comments</comments>
		<pubDate>Wed, 07 Mar 2007 03:20:03 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2007/03/06/solving-the-double-post-dilema/</guid>
		<description><![CDATA[Everyone who has done any sort of web development, and made use of the HTTP POST has run into this problem. If you haven&#8217;t, are you sure you are doing proper QA?
Basically, the problem comes from having the POST information still resident after an HTTP POST. If the user were to refresh their browser, that [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone who has done any sort of web development, and made use of the <strong>HTTP POST</strong> has run into this problem. If you haven&#8217;t, are you sure you are doing proper QA?</p>
<p>Basically, the problem comes from having the POST information still resident after an <strong>HTTP POST</strong>. If the user were to refresh their browser, that POST information will be resent, resulting in a double post. There are many ways to solve this problem, but the one I will outline (in PHP) seemed like the best for my situation.</p>
<p>Let us assume we have a text input and a button and that our form.php file will process our form as well as present it to the user (yes, I know this isn&#8217;t a good idea, but it is just an example).<br />
<span id="more-14"></span></p>
<blockquote><p>
&lt;form method=&#8221;post&#8221; action=&#8221;form.php&#8221;&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;input name=&#8221;mytext&#8221; /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;input name=&#8221;submitBtn&#8221; type=&#8221;submit&#8221; /&gt;<br />
&lt;/form&gt;
</p></blockquote>
<p>When we load the page, we are going to check whether the <strong>$_POST</strong> variable is set. If it is, then we are going to do something with it.</p>
<blockquote><p>
session_start();</p>
<p>if(isset($_POST['mytext']))<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;saveToDatabase($_POST['mytext']);<br />
}
</p></blockquote>
<p>Now that we are doing something with this <strong>$_POST['mytext']</strong> variable, we can see the double-post problem materialize. Since the <strong>HTTP POST</strong> is still populated, when the user presses refresh on their browser, the <strong>$_POST['mytext']</strong> will be saved to the database twice.</p>
<p>What we need to do is get rid of the <strong>$_POST</strong> variable after we are done using it.</p>
<p>At the beginning of the form.php file I am going to create a server-side session to store any post information we get. Then I have a check to see whether the $_POST array has been populated.</p>
<p>If the <strong>$_POST</strong> has been populated, we are going to store the post information in the server-side session we have started and we send a blank header back out (which removes the <strong>HTTP POST</strong>).</p>
<blockquote><p>
if (isset($_POST['myText']))<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;$_SESSION['myText'] = $_POST['myText'];<br />
&nbsp;&nbsp;&nbsp;&nbsp;header(&#8220;Location: form.php&#8221;);<br />
}</p></blockquote>
<p>Now, we have gotten rid of the POST which removes the double-post problem, and have stored the information from the <strong>$_POST</strong> for use. We can then access the POST information stored in the session. Once we have copied the POST information from the session, we will unset the session so that the information doesn&#8217;t stay resident.</p>
<blockquote><p>
if (isset($_SESSION['myText']))<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;$myEnteredText = $_SESSION['myText'];<br />
&nbsp;&nbsp;&nbsp;&nbsp;unset($_SESSION['myText']);<br />
}
</p></blockquote>
<p>Now you can use the POST information without running the risk of a double post.</p>
<p>If you would like to see this tutorial in action, create a form.php file on your webserver, and paste the following:</p>
<blockquote><p>
&lt;?<br />
&nbsp;&nbsp;&nbsp;&nbsp;session_start();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;if (isset($_SESSION['myText']))<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$myEnteredText = $_SESSION['myText'];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset($_SESSION['myText']);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;if (isset($_POST['myText']))<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$_SESSION['myText'] = $_POST['myText'];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;header(&#8220;Location: form.php&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
?&gt;</p>
<p>&lt;html&gt;<br />
&lt;head&gt;</p>
<p>&lt;/head&gt;<br />
&lt;body&gt;</p>
<p>&lt;form action=&#8221;form.php&#8221; method=&#8221;POST&#8221;&gt;</p>
<p>&lt;?<br />
&nbsp;&nbsp;&nbsp;&nbsp;if (isset($myEnteredText))<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &#8220;&lt;p&gt;The message you entered was \&#8221;".$myEnteredText.&#8221;\&#8221;&lt;/p&gt;&#8221;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
?&gt;</p>
<p>&lt;input name=&#8221;myText&#8221; type=&#8221;text&#8221; /&gt;<br />
&lt;input name=&#8221;submitBtn&#8221; type=&#8221;submit&#8221; value=&#8221;ok&#8221; /&gt;</p>
<p>&lt;/form&gt;<br />
&lt;/body&gt;</p>
<p>&lt;/html&gt;
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2007/03/06/solving-the-double-post-dilema/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Converting TV Shows To Play On Your iPod In Linux</title>
		<link>http://www.newthink.net/2007/03/02/converting-tv-shows-to-play-on-your-ipod-in-linux/</link>
		<comments>http://www.newthink.net/2007/03/02/converting-tv-shows-to-play-on-your-ipod-in-linux/#comments</comments>
		<pubDate>Fri, 02 Mar 2007 20:30:40 +0000</pubDate>
		<dc:creator>Ash Christopher</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[iPod]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://newthink.net/blog/2007/03/02/converting-tv-shows-to-play-on-your-ipod-in-linux/</guid>
		<description><![CDATA[There are numerous Windows programs out there to convert video for use in your mobile devices. The problem however, is that unless you have a new dual-core machine your PC is more or less unusable until the conversion is complete.
Now, I know not everyone has a Linux machine just lying around, but I do, and [...]]]></description>
			<content:encoded><![CDATA[<p>There are numerous Windows programs out there to convert video for use in your mobile devices. The problem however, is that unless you have a new dual-core machine your PC is more or less unusable until the conversion is complete.</p>
<p>Now, I know not everyone has a Linux machine just lying around, but I do, and maybe in the future it might be enough to convince you to build your own file-server for your home (for media perhaps?).</p>
<p>Before starting, you need to make sure you have the <strong>ffmpeg</strong> binary installed on your Linux box. As of this posting, I have ffmpeg-0.4.9-0.3.20051207.2.el4.rf installed on my CentOS4 machine. I will leave it as an exercise to you to figure out how to install it if you don&#8217;t have it.</p>
<blockquote><p>ash@galactica:[/tmp]> ffmpeg -vcodec xvid -b 500 -qmin 1 -qmax 7 -bufsize 4096 -g 300 -acodec aac -ab 96 -i doctor.who.102.the.end.of.the.world.avi -s 320&#215;240 -aspect 16:9 doctor.who.102.the.end.of.the.world.mp4</p></blockquote>
<p>Here is a run down of what the switches mean and how they affect your converted video:</p>
<blockquote><p><em>-vcodec</em> &#8212; this is the video codec you want the converted video to use. For iPod use, I suggest xvid. It is basically the same codec as mpeg4 (except open source) and you don&#8217;t run into buffer-underflow problems as often.</p>
<p><em>-b</em> &#8212; this is the video bitrate in kbit/s (higher bitrate means higher quality).</p>
<p><em>-qmin &#038; -qmax</em> &#8212; this controls the quality when dealing with VBR (variable bit rate). Basically a range to keep the quality between.</p>
<p><em>-acodec</em> &#8212; the audio codec to use. When converting to iPod video, this must be aac since that is the only format the iPod supports.</p>
<p><em>-ab</em> &#8212; this is the audio bitrate in kbit/s. 96 kbit/s offers decent audio quality for iPod use.</p>
<p><em>-i</em> &#8212; input file (obviously?).</p>
<p><em>-s</em> &#8212; size of the output video. The iPod supports 320&#215;240, 480&#215;480 and with the newest firmware, now supports 640&#215;480. If you want to retain the source aspect ratio, make sure you calculate the new size to follow the sources aspect ratio.</p>
<p><em>-aspect</em> &#8212; aspect ratio for the converted video. This is especially important if your input video is 16:9 and you want to keep the ratio and replace the extra space with black bars. The aspect ratio is usually 4:3 or 16:9.</p></blockquote>
<p>Now,after you have run this command, your video should begin to be converted. The time it takes to convert depends greatly on the hardware being used. I often offload this task to a P-III 800 machine, and it seems to be able to encode a video in the same time it would take to watch it. Again, the nice thing about offloading this task is that you can now use your main system for other fun tasks.</p>
<p>Might I suggest maybe using your main machine to whip up a quick script to encode a list of videos, perhaps at night when spare cpu cycles are pleniful? The nice thing about batching up video conversions like this, is that it is also compatible with mac&#8217;s running OSX. Sure, you could use the mac-GUI program to do it, but that is going to require a whole lot more human interaction to convert 10 shows.</p>
<p>For mor information of supported codecs, see the <a href="http://ffmpeg.mplayerhq.hu/ffmpeg-doc.html#SEC24">FFMPEG Documentation</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.newthink.net/2007/03/02/converting-tv-shows-to-play-on-your-ipod-in-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

