<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:posterous="http://posterous.com/help/rss/1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>CS50 Blog</title>
    <link>http://blog.cs50.net</link>
    <description>on the intellectual enterprises of computer science and the art of programming</description>
    <generator>posterous.com</generator>
    <link xmlns="http://www.w3.org/2005/Atom" href="http://posterous.com/api/sup_update#af598e6fd" type="application/json" rel="http://api.friendfeed.com/2008/03#sup" />
    
    
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/cs50blog" /><feedburner:info uri="cs50blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://posterous.superfeedr.com/" /><item>
      <pubDate>Sun, 24 Oct 2010 12:05:00 -0700</pubDate>
      <title>This is a job for cron!</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/DaztY7Knrus/this-is-a-job-for-cron</link>
      <guid isPermaLink="false">http://blog.cs50.net/this-is-a-job-for-cron</guid>
      <description>&lt;p&gt;
	&lt;p&gt;So it turns out that last screenshot of &lt;a href="http://cs50.tv/"&gt;cs50.tv&lt;/a&gt;'s guestmap in &lt;a href="http://blog.cs50.net/mapping-cs50"&gt;10/13's post&lt;/a&gt; should have had a lot more markers on it! Recall that we use &lt;a href="http://docs.google.com/"&gt;Google Spreadsheets&lt;/a&gt; to store visitors' names and hometowns. It turns out it's not sufficient to write (or talk about) a script that &lt;a href="http://en.wikipedia.org/wiki/Geocoding"&gt;gecodes&lt;/a&gt; those hometowns, saving the resulting GPS coordinates back in the spreadsheet itself. You actually have to remember to run that script!&lt;/p&gt;
&lt;p&gt;Truth be told, I thought I'd set up a "cronjob"on our server whose purpose in life was to execute that geocoding script nightly. Unfortunately, it seems I never did. (Or, in my defense, I did but set it up under a username that I later deleted. Though that probably still makes it my fault.) But no matter, what a perfect opportunity to talk about &lt;a href="http://en.wikipedia.org/wiki/Cron"&gt;&lt;tt&gt;cron&lt;/tt&gt;&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;tt&gt;cron&lt;/tt&gt; is a utility generally found on Linux systems (and others) that allows you to schedule the execution of commands. For instance, if you've written a command-line program called &lt;tt&gt;foo&lt;/tt&gt;, you can schedule &lt;tt&gt;foo&lt;/tt&gt; to be executed every 5 minutes without having to log into the server yourself every 5 minutes and run it manually. Alternatively, you could schedule foo to be executed once nightly, or once weekly, or, really, anytime you'd like, however often you'd like. &lt;tt&gt;cron&lt;/tt&gt; is often used by the system itself to, say, rotate logs (&lt;em&gt;i.e.&lt;/em&gt;, rename them so a file doesn't get too big). In &lt;a href="http://cs50.tv/"&gt;CS50&lt;/a&gt;, we use &lt;tt&gt;cron&lt;/tt&gt; (via &lt;a href="http://rsnapshot.org/"&gt;rsnapshot&lt;/a&gt;) in order to back up students' source code every 5 minutes to save them the inevitable anguish of accidentally deleting some file. (The disk space it's cost us to maintain so many backups has been well worth the tears saved!)&lt;/p&gt;
&lt;p&gt;Anyhow, using &lt;tt&gt;cron&lt;/tt&gt; is wonderfully simple. You essentially run a command like&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;crontab -e&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;that allows you to edit (per the &lt;tt&gt;-e&lt;/tt&gt;) a text file (otherwise known as a "cron table"), each of whose lines represents a scheduled command. In order to enable daily geocoding of our Google Spreadsheet, I added the one-liner below to the webserver's own crontab, where &lt;tt&gt;/path/to/geocode&lt;/tt&gt; is the full path to the command-line geocoding script I wrote:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;@daily /path/to/geocode&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;It turns out that my one-liner is actually short-hand notation for&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;0 0 * * *&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;which means, right to left, that this command (&lt;tt&gt;/path/to/geocode&lt;/tt&gt;) should be executed every  day of the week, every month, every day of the month, when the clock strikes 0 hours and 0 seconds, where &lt;tt&gt;*&lt;/tt&gt; denotes "every." In normal-people terms, it means "run this command every night at midnight."  To be honest, I almost always forget which number means which, but &lt;a href="http://en.wikipedia.org/wiki/Cron"&gt;Wikipedia&lt;/a&gt; has a wonderful cheatsheet. Allow me to excerpt:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;.---------------- minute (0 - 59) 
 |   .------------- hour (0 - 23)
 |   |   .---------- day of month (1 - 31)
 |   |   |   .------- month (1 - 12) OR jan,feb,mar,apr ... 
 |   |   |   |  .----- day of week (0 - 6) (Sunday=0 or 7)  OR sun,mon,tue,wed,thu,fri,sat 
 |   |   |   |  |
 *   *   *   *  *  command to be executed&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I should confess that I've actually told a little white lie in the interests of simplicity.  Our cronjob is actually&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;@daily /bin/nice /path/to/geocode&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;which means that the command should be "nice'd" before it's run.  Like &lt;tt&gt;cron&lt;/tt&gt; itself, &lt;tt&gt;nice&lt;/tt&gt; is a utility found on most Linux systems (and others) that allows you to raise and lower commands' priorities (&lt;em&gt;i.e.&lt;/em&gt;, how much CPU time they get).  By default, &lt;tt&gt;nice&lt;/tt&gt; lowers a command's priority, so our cronjob really tells the system to "run this command every night at midnight but run this command at a lower priority so it doesn't slow other, more important things (like file downloads) down."&lt;/p&gt;
&lt;p&gt;Odds are, if you have a shell account on a Linux system (that you can access via SSH), you have the ability to schedule cronjobs, at least if the system administrator allows you. If you instead have an account with a third-party Web host that only provides you with a Web-based panel, you may be able to schedule cronjobs via that panel's GUI in a slightly more user-friendly way.&lt;/p&gt;
&lt;p&gt;Anyhow, thanks to &lt;tt&gt;cron&lt;/tt&gt; (and my actually using it), &lt;a href="http://cs50.tv/"&gt;cs50.tv&lt;/a&gt;'s guestmap is indeed now updated nightly, and it currently looks like this!&lt;/p&gt;
&lt;p&gt;&lt;div class='p_embed p_image_embed'&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/temp-2010-10-24/oBywGbopxDqhEloszyxefvurEqBCtByttfJnvbEfBDAlkqejpsudEpssBiIr/Screen_shot_2010-10-24_at_3.03.51_PM.png.scaled1000.png"&gt;&lt;img alt="Screen_shot_2010-10-24_at_3" height="310" src="http://posterous.com/getfile/files.posterous.com/temp-2010-10-24/oBywGbopxDqhEloszyxefvurEqBCtByttfJnvbEfBDAlkqejpsudEpssBiIr/Screen_shot_2010-10-24_at_3.03.51_PM.png.scaled500.png" width="500" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/this-is-a-job-for-cron"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/this-is-a-job-for-cron#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/DaztY7Knrus" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
      <media:content type="image/png" height="532" width="859" url="http://getfile2.posterous.com/getfile/files.posterous.com/temp-2010-10-24/oBywGbopxDqhEloszyxefvurEqBCtByttfJnvbEfBDAlkqejpsudEpssBiIr/Screen_shot_2010-10-24_at_3.03.51_PM.png">
        <media:thumbnail height="310" width="500" url="http://getfile9.posterous.com/getfile/files.posterous.com/temp-2010-10-24/oBywGbopxDqhEloszyxefvurEqBCtByttfJnvbEfBDAlkqejpsudEpssBiIr/Screen_shot_2010-10-24_at_3.03.51_PM.png.scaled500.png" />
      </media:content>
    <feedburner:origLink>http://blog.cs50.net/this-is-a-job-for-cron</feedburner:origLink></item>
    <item>
      <pubDate>Sun, 03 Oct 2010 19:30:00 -0700</pubDate>
      <title>Mapping CS50</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/Ot8hxXvdHXg/mapping-cs50</link>
      <guid isPermaLink="false">http://blog.cs50.net/mapping-cs50</guid>
      <description>&lt;p&gt;
	&lt;p&gt;For a while, &lt;a href="http://cs50.tv/"&gt;cs50.tv&lt;/a&gt; (and its sister sites) have had a "guestmap," whereby visitors are invited to record their names and hometowns on a Google Map, if only for the fun of it.  To see the map, head to &lt;a href="http://cs50.tv/"&gt;http://cs50.tv/&lt;/a&gt; and click &lt;strong&gt;Guestmap&lt;/strong&gt; in the site's top-left corner.  (Feel free to add yourself!)  For the impatient, here's a screenshot of what it looks like at the moment:&lt;/p&gt;
&lt;p&gt;&lt;div class='p_embed p_image_embed'&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/ibAlayHDeGvlqxarwkctCdgybkzIEcGerkJkohzkCmrqqamycmjqocCadgxt/map.png.scaled1000.png"&gt;&lt;img alt="Map" height="332" src="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/ibAlayHDeGvlqxarwkctCdgybkzIEcGerkJkohzkCmrqqamycmjqocCadgxt/map.png.scaled500.png" width="500" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;When we decided (spontaneously one night) to implement this guestmap, we weren't sure if anyone would notice (or care!) if we did, so we didn't want to spend too much time on its implementation.  In particular, we didn't want to bother setting up an entire database (&lt;em&gt;e.g.&lt;/em&gt;, &lt;a href="http://en.wikipedia.org/wiki/MySQL"&gt;MySQL&lt;/a&gt;) just for this one application.  Simpler would have been to store folks' submissions in a local file (&lt;em&gt;e.g.&lt;/em&gt;, &lt;a href="http://en.wikipedia.org/wiki/Comma-separated_values"&gt;CSV&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/SQLite"&gt;SQLite&lt;/a&gt;, or &lt;a href="http://en.wikipedia.org/wiki/XML"&gt;XML&lt;/a&gt;).  But the plan was to start replicating &lt;a href="http://cs50.tv/"&gt;cs50.tv&lt;/a&gt;'s content across multiple servers, in which case we'd then have to keep copies of that file synchronized across multiple servers.  Doable, but somewhat annoying.  If we used a local file as our database, we'd also have to worry about concurrent writes (as when two visitors happen to submit their names and hometowns simultaneously, the result of which might be to lose one of the visitor's data).  Also doable, and not very hard (thanks to functions like &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;a href="http://php.net/manual/en/function.flock.php"&gt;flock&lt;/a&gt;&lt;/span&gt;).  But we'd still have to implement the form via which we ask for visitors' names and hometowns.  (And at this point in the story, it was probably already midnight or so.)&lt;/p&gt;
&lt;p&gt;If only there were someone to whom we could outsource both the form and the database...&lt;/p&gt;
&lt;p&gt;Turns out there was!  Odds are you're familiar with &lt;a href="http://docs.google.com/"&gt;Google Spreadsheets&lt;/a&gt;, which is essentially Google's web-based answer to &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Excel"&gt;Microsoft Excel&lt;/a&gt;.  It's actually wonderfully useful, in large part because it makes it so easy to share (and edit simultaneously) spreadsheets with other people.  But with Google Spreadsheets can you also create web-based &lt;a href="http://docs.google.com/support/bin/answer.py?hl=en&amp;amp;answer=87809"&gt;forms&lt;/a&gt; whose submissions end up in a Google Spreadsheet: each row represents a submission, and each column represents a visitor's answer to a particular question. And you can then share that spreadsheet with yourself (or others) in a variety of formats, among them CSV.&lt;/p&gt;
&lt;p&gt;Nice!  Even without writing any code, I was almost finished implementing the guestmap!  (Okay, admittedly, it took a few minutes to create the form and share it with myself as CSV, but way fewer minutes than it'd have taken to implement all that myself.)&lt;/p&gt;
&lt;p&gt;So, at this point in the story, I had two URLs: one for the form and one for the CSV file.  My plan was (1) to embed the former in an &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;a href="http://en.wikipedia.org/wiki/HTML_element#Frames"&gt;iframe&lt;/a&gt;&lt;/span&gt; on &lt;a href="http://cs50.tv/"&gt;cs50.tv&lt;/a&gt; so that folks could add themselves to the guestmap without leaving &lt;a href="http://cs50.tv/"&gt;cs50.tv&lt;/a&gt; itself and (2) query the latter anytime someone wanted to look at the map.  All that remained was to write the code that queries the CSV and generates the map.&lt;/p&gt;
&lt;p&gt;Thanks to the &lt;a href="http://code.google.com/apis/maps/documentation/javascript/"&gt;Google Maps API&lt;/a&gt;, this part, too, was amazingly easy.  To embed a Google Map in one of your own pages, you first need to include the API in your page's head, as with:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;script&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;src&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://maps.google.com/maps/api/js?sensor=false&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You then need to provide a container for it in your page's body, as with:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="an"&gt;id&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;style&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;height: 100%; width: 100%;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Lastly, you need to tell Google to transform that container into a map, as with:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="kw"&gt;new&lt;/span&gt; google.maps.Map(document.getElementById(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;), {
 &lt;span class="ke"&gt;center&lt;/span&gt;: &lt;span class="kw"&gt;new&lt;/span&gt; google.maps.LatLng(&lt;span class="fl"&gt;42.37411257777324&lt;/span&gt;, -&lt;span class="fl"&gt;71.11905097961426&lt;/span&gt;),
 &lt;span class="ke"&gt;disableDefaultUI&lt;/span&gt;: &lt;span class="pc"&gt;true&lt;/span&gt;,
 &lt;span class="ke"&gt;mapTypeControl&lt;/span&gt;: &lt;span class="pc"&gt;false&lt;/span&gt;,
 &lt;span class="ke"&gt;mapTypeId&lt;/span&gt;: google.maps.MapTypeId.HYBRID,
 &lt;span class="ke"&gt;navigationControl&lt;/span&gt;: &lt;span class="pc"&gt;true&lt;/span&gt;,
 &lt;span class="ke"&gt;zoom&lt;/span&gt;: &lt;span class="i"&gt;2&lt;/span&gt;
});&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Of course, that map won't have any markers on it until you plant them yourself.  Planting a marker, though, requires knowing the &lt;a href="http://en.wikipedia.org/wiki/Global_Positioning_System"&gt;GPS&lt;/a&gt; coordinates of each visitor's hometown.  Probably not something most people know.  So, how can we geocode (&lt;em&gt;i.e.&lt;/em&gt;, convert) each visitor's city, state, and country (that he or she inputted via the Guestmap's web-based form) into a latitude and longitude?&lt;/p&gt;
&lt;p&gt;Well, the Google Maps API does provide a JavaScript &lt;a href="http://code.google.com/apis/maps/documentation/javascript/services.html#Geocoding"&gt;geocoding service&lt;/a&gt;, but using that service would mean that every visitor's hometown would need to be geocoded every time someone pulls up the guestmap by that someone's own browser.  Certainly not the most efficient approach.  Plus, Google appears to limit the number of geocoding requests a browser can make in a short period of time, the result of which is that some visitors wouldn't end up marked on the map.  (We, um, learned that the hard way.)  Better to do the geocoding server-side and remember each visitor's coordinates so that we needn't query for them again.&lt;/p&gt;
&lt;p&gt;As luck would have it, Google also provides a web service with which you can do exactly that.  Via Google's &lt;a href="http://code.google.com/apis/maps/documentation/geocoding/"&gt;Geocoding API&lt;/a&gt; can you ask for the GPS coordinates of some location (e.g., &lt;a href="http://maps.google.com/maps?q=33+Oxford+Street,+Cambridge,+Massachusetts"&gt;33 Oxford Street, Cambridge, Massachusetts&lt;/a&gt;) with code like the below:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="lv"&gt;$o&lt;/span&gt; = json_decode(&lt;span class="pd"&gt;file_get_contents&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://maps.googleapis.com/maps/api/geocode/json?address=33+Oxford+Street,+Cambridge,+Massachusetts+02138&amp;amp;sensor=false&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;));&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;I called &lt;a href="http://php.net/manual/en/function.json-encode.php"&gt;&lt;tt&gt;json_encode&lt;/tt&gt;&lt;/a&gt; in the above because what's returned is a &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt; object like the below:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;{
  &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
  &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;results&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ {
    &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;street_address&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ],
    &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;formatted_address&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;33 Oxford St, Cambridge, MA 02138, USA&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
    &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;address_components&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;33&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;short_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;33&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;street_number&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]
    }, {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Oxford St&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;short_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Oxford St&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;route&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]
    }, {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Cambridge&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;short_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Cambridge&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;locality&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;political&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]
    }, {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Cambridge&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;short_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Cambridge&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;administrative_area_level_3&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;political&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]
    }, {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Middlesex&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;short_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Middlesex&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;administrative_area_level_2&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;political&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]
    }, {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Massachusetts&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;short_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;MA&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;administrative_area_level_1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;political&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]
    }, {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;United States&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;short_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;US&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;country&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;political&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]
    }, {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;02138&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;short_name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;02138&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: [ &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;postal_code&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]
    } ],
    &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;geometry&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: {
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;location&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: {
        &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;lat&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="fl"&gt;42.3787770&lt;/span&gt;,
        &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;lng&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: -&lt;span class="fl"&gt;71.1168170&lt;/span&gt;
      },
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;location_type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;ROOFTOP&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;viewport&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: {
        &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;southwest&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: {
          &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;lat&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="fl"&gt;42.3756294&lt;/span&gt;,
          &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;lng&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: -&lt;span class="fl"&gt;71.1199646&lt;/span&gt;
        },
        &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;northeast&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: {
          &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;lat&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: &lt;span class="fl"&gt;42.3819246&lt;/span&gt;,
          &lt;span class="ke"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;lng&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;: -&lt;span class="fl"&gt;71.1136694&lt;/span&gt;
        }
      }
    }
  } ]
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And so we can get at the GPS coordinates we want with code like the below:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="lv"&gt;$lat&lt;/span&gt; = &lt;span class="lv"&gt;$o&lt;/span&gt;-&amp;gt;results[&lt;span class="i"&gt;0&lt;/span&gt;]-&amp;gt;geometry-&amp;gt;location-&amp;gt;lat;
&lt;span class="lv"&gt;$lng&lt;/span&gt; = &lt;span class="lv"&gt;$o&lt;/span&gt;-&amp;gt;results[&lt;span class="i"&gt;0&lt;/span&gt;]-&amp;gt;geometry-&amp;gt;location-&amp;gt;lng;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And we can then store those coordinates somewhere.  (We happen to use the &lt;a href="http://code.google.com/apis/gdata/"&gt;Google Data Protocol&lt;/a&gt; in order to write them back to our own Google Spreadsheet in a column that the web-based form itself doesn't touch.)&lt;/p&gt;
&lt;p&gt;With all those pieces now assembled, we render the map itself with code like the below, wherein &lt;tt&gt;CSV&lt;/tt&gt; is the URL of our Google Spreadsheet:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="dt"&gt;&amp;lt;!DOCTYPE html &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;gt;&lt;/span&gt;

&lt;span class="ta"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="an"&gt;xmlns&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/1999/xhtml&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;style&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;height: 100%;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="ta"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;

    &lt;span class="ta"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="an"&gt;rel&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;stylesheet&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/css&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;href&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://yui.yahooapis.com/2.8.1/build/reset-fonts/reset-fonts.css&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="ta"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="an"&gt;http-equiv&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;content&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/html; charset=utf-8&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="ta"&gt;&amp;lt;script&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;src&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://yui.yahooapis.com/2.8.1/build/yahoo-dom-event/yahoo-dom-event.js&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="ta"&gt;&amp;lt;script&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;src&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://maps.google.com/maps/api/js?sensor=false&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="ta"&gt;&amp;lt;script&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;
    // &lt;span class="er"&gt;&amp;lt;&lt;/span&gt;![CDATA[

        YAHOO.util.Event.onDOMReady(function() {

            var gmap = new google.maps.Map(document.getElementById(&amp;quot;map&amp;quot;), {
             center: new google.maps.LatLng(42.37411257777324, -71.11905097961426),
             disableDefaultUI: true,
             mapTypeControl: false,
             mapTypeId: google.maps.MapTypeId.HYBRID,
             navigationControl: true,
             zoom: 2
            });

            // resize as needed
            YAHOO.util.Event.addListener(window, &amp;quot;resize&amp;quot;, function() {
                if (typeof(gmap) !== &amp;quot;undefined&amp;quot;)
                {
                    google.maps.event.trigger(gmap, &amp;quot;resize&amp;quot;);
                }
            });

            // prepare infowindow
            var infowindow = new google.maps.InfoWindow();

            &lt;span class="c"&gt;&amp;lt;?

                // get subscribers
                $rows = array();
                $handle = fopen(CSV, &amp;quot;r&amp;quot;);
                fgetcsv($handle);
                while ($row = fgetcsv($handle))
                    $rows[] = $row;
                fclose($handle);

            ?&amp;gt;&lt;/span&gt;

            &lt;span class="c"&gt;&amp;lt;? foreach ($rows as $row): ?&amp;gt;&lt;/span&gt;

                &lt;span class="c"&gt;&amp;lt;? if (!@$row[9] || $row[12]) continue; ?&amp;gt;&lt;/span&gt;

                var marker = new google.maps.Marker({
                 map: gmap,
                 position: new google.maps.LatLng(&lt;span class="c"&gt;&amp;lt;?= $row[10] ?&amp;gt;&lt;/span&gt;, &lt;span class="c"&gt;&amp;lt;?= $row[11] ?&amp;gt;&lt;/span&gt;)
                });
                google.maps.event.addListener(marker, &amp;quot;click&amp;quot;, function(e) {
                    infowindow.setContent(&amp;quot;&lt;span class="ta"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="an"&gt;style&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;width: 240px;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;&amp;quot; + &lt;span class="c"&gt;&amp;lt;?= json_encode(CapitalizeLastName($row[1])) ?&amp;gt;&lt;/span&gt; + &amp;quot;&lt;span class="ta"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;&amp;quot; + &amp;quot;&lt;span class="ta"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&amp;quot; + &lt;span class="c"&gt;&amp;lt;?= json_encode($row[9]) ?&amp;gt;&lt;/span&gt; + &amp;quot;&lt;span class="ta"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&amp;quot;);
                    infowindow.open(gmap, this);
                });

            &lt;span class="c"&gt;&amp;lt;? endforeach ?&amp;gt;&lt;/span&gt;

        });

    // ]]&lt;span class="er"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="ta"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

    &lt;span class="ta"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Map&lt;span class="ta"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

  &lt;span class="ta"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

  &lt;span class="ta"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="an"&gt;class&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;yui-skin-sam&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;style&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;height: 100%;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="ta"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="an"&gt;id&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;style&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;height: 100%; width: 100%;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="ta"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="ta"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/mapping-cs50"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/mapping-cs50#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/Ot8hxXvdHXg" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
      <media:content type="image/png" height="515" width="776" url="http://getfile3.posterous.com/getfile/files.posterous.com/temp-2010-10-03/ibAlayHDeGvlqxarwkctCdgybkzIEcGerkJkohzkCmrqqamycmjqocCadgxt/map.png">
        <media:thumbnail height="332" width="500" url="http://getfile3.posterous.com/getfile/files.posterous.com/temp-2010-10-03/ibAlayHDeGvlqxarwkctCdgybkzIEcGerkJkohzkCmrqqamycmjqocCadgxt/map.png.scaled500.png" />
      </media:content>
    <feedburner:origLink>http://blog.cs50.net/mapping-cs50</feedburner:origLink></item>
    <item>
      <pubDate>Wed, 11 Aug 2010 02:44:00 -0700</pubDate>
      <title>On downtime and backplanes</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/ZGy1zUAGal8/on-downtime-and-backplanes.html</link>
      <guid isPermaLink="false">http://blog.cs50.net/2010/08/on-downtime-and-backplanes.html</guid>
      <description>&lt;p&gt;
	&lt;p&gt;Note to self: get (even) better about actually posting.&lt;/p&gt;
&lt;p&gt;The irony is that at least once per day I think to myself, "Oh that would make for an interesting post."  Clearly my problem is with execution!  Unfortunately, sleep usually trumps execution.  Suffice it to say I don't have a diary.&lt;/p&gt;
&lt;p&gt;Those who follow &lt;a href="http://cs50.tv/"&gt;cs50.tv&lt;/a&gt; (and its sister sites &lt;a href="http://cs75.tv/"&gt;cs75.tv&lt;/a&gt;, &lt;a href="http://cs259.tv/"&gt;cs259.tv&lt;/a&gt;, and &lt;a href="http://computerscience1.tv/"&gt;computerscience1.tv&lt;/a&gt;) may have noticed some downtime over the past several days.  The server on which cs50.tv lives (nay, lived) is actually a pretty decent machine: a &lt;a href="http://www.dell.com/us/en/dfb/servers/pedge_2950/pd.aspx?refid=pedge_2950&amp;amp;cs=28&amp;amp;s=dfb"&gt;Dell PowerEdge 2950 III&lt;/a&gt; with two &lt;a href="http://en.wikipedia.org/wiki/Multi-core_processor"&gt;quad-core&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Xeon"&gt;Xeon&lt;/a&gt; CPUs, 32GB of RAM, and 6TB of disk space.  Most everything in the machine that can be redundant is redundant: it has two &lt;a href="http://en.wikipedia.org/wiki/Power_supply_unit_(computer)"&gt;PSUs&lt;/a&gt; so that if one of them (or the electrical circuit to which it's connected) dies, the other can take over the load; 6 HDDs in a &lt;a href="http://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_6"&gt;RAID6&lt;/a&gt; configuration, which means that as many as 2 &lt;a href="http://en.wikipedia.org/wiki/Hard_drive"&gt;HDDs&lt;/a&gt; can die without downtime or loss of data, and 2 &lt;a href="http://en.wikipedia.org/wiki/Network_Interface_Controller"&gt;NICs&lt;/a&gt; so that if one of them (or the switch to which it's connected) dies, we can move the other to our second switch.  Because they have moving parts, PSUs and HDDs are among the few components in modern computers that tend to fail these days, so these redundancies help mitigate that risk.&lt;/p&gt;
&lt;p&gt;Unfortunately, a server tends to have just one &lt;a href="http://en.wikipedia.org/wiki/Backplane"&gt;backplane&lt;/a&gt;, a circuit board into which important stuff connects (namely, in our case, HDDs).  And that's what keeled over this past Wednesday, for no particular reason.  The first symptoms were that the &lt;a href="http://en.wikipedia.org/wiki/Virtual_machine"&gt;VMs&lt;/a&gt; that lived on this box became suddenly unresponsive (i.e., cs50.tv "went down"); on at least one of their consoles was mention of "I/O errors," which generally mean RAM or disk problems.  We thus proceeded to look at the server's own console, which boasted, let's call it, a red screen of death.  (The server was running &lt;a href="http://en.wikipedia.org/wiki/VMware_ESX"&gt;VMware ESX&lt;/a&gt; 4.0, whose screen apparently turns red when really bad things happen.)  We thus rebooted the whole server and booted into the RAID controller's configuration utility (a tool with which you configure RAID6 and such), which informed us that disks 1 and 2 were "Failed" and, get this, disk 0 was "Missing."  I'll admit I wondered for a moment who had stolen my hard drive.&lt;/p&gt;
&lt;p&gt;Unfortunately, reseating the hard drives achieved nothing, nor did rebooting several times.  It was time to call Dell.  We were fortunate to reach an excellent technician (thanks, Fadi!) who concurred that the problem was most likely the server's backplane, the "Failed" disks, and/or the RAID controller (in descending order of probability).&lt;/p&gt;
&lt;p&gt;Within 24 hours, Dell was on site.  (Thanks, Tom!)  Sure enough, we were in need of a new backplane.  Once installed, all 6 of our HDDs started blinking green.  (Green is good.)  Drives 1 and 2 now appeared as "Foreign," which meant they were functional but unrecognized, presumably the result of the failed backplane.  Thanks to RAID6, no matter: we imported the drives back into the array, and we were back in business.&lt;/p&gt;
&lt;p&gt;Well, almost.  Unfortunately, on its way out the door, the backplane had taken some of our data with it: an assortment of files and directories were either corrupted or lost.  And so, despite all our redundancies, we had to restore from backups anyway.  (Thank you, &lt;a href="http://en.wikipedia.org/wiki/Murphy's_law"&gt;Mr. Murphy&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;If there's a silver lining in this particular episode, it's that we used it as an opportunity to upgrade (almost) all of CS50's servers to ESXi 4.1 in one fell swoop (which involved wiping some drives anyway), and we also transitioned &lt;a href="http://cs50.tv/"&gt;cs50.tv&lt;/a&gt; from &lt;a href="http://en.wikipedia.org/wiki/Lighttpd"&gt;lighttpd&lt;/a&gt; to &lt;a href="http://en.wikipedia.org/wiki/Nginx"&gt;nginx&lt;/a&gt;, the latter of which, we're hoping, will perform a bit better under load.&lt;/p&gt;
&lt;p&gt;This is CS50, behind the scenes.&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/2010/08/on-downtime-and-backplanes.html"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/2010/08/on-downtime-and-backplanes.html#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/ZGy1zUAGal8" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
    <feedburner:origLink>http://blog.cs50.net/2010/08/on-downtime-and-backplanes.html</feedburner:origLink></item>
    <item>
      <pubDate>Mon, 03 May 2010 04:00:00 -0700</pubDate>
      <title>Downloading Chrome and then some...</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/cB97HXVW9nA/downloading-chrome-and-then-some.html</link>
      <guid isPermaLink="false">http://blog.cs50.net/2010/05/downloading-chrome-and-then-some.html</guid>
      <description>&lt;p&gt;
	&lt;p&gt;Our thanks to Motiur Rahman for submitting this bug of the day, a screenshot he took while downloading Chrome on Ubuntu:&lt;/p&gt;
&lt;p&gt;&lt;div class='p_embed p_image_embed'&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/nlfskIcIeivnhygdgjwlmIDjqmArByqxEuusIHzjuEiBbgksFHqttcsldJkb/chrome.png.scaled1000.png"&gt;&lt;img alt="Chrome" height="375" src="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/nlfskIcIeivnhygdgjwlmIDjqmArByqxEuusIHzjuEiBbgksFHqttcsldJkb/chrome.png.scaled500.png" width="500" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Spot it yet?&lt;/p&gt;
&lt;p&gt;djm&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/2010/05/downloading-chrome-and-then-some.html"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/2010/05/downloading-chrome-and-then-some.html#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/cB97HXVW9nA" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
      <media:content type="image/png" height="480" width="640" url="http://getfile5.posterous.com/getfile/files.posterous.com/cs50/BJjAjDHshzpACIEDuakJEGvFxwkrHycjvAlGzAuvEEuHbhwrGqcnwwbAalnl/media_http2bpblogspot_bqJsH.png">
        <media:thumbnail height="375" width="500" url="http://getfile8.posterous.com/getfile/files.posterous.com/cs50/BJjAjDHshzpACIEDuakJEGvFxwkrHycjvAlGzAuvEEuHbhwrGqcnwwbAalnl/media_http2bpblogspot_bqJsH.png.scaled500.png" />
      </media:content>
      <media:content type="image/png" height="768" width="1024" url="http://getfile2.posterous.com/getfile/files.posterous.com/temp-2010-10-03/nlfskIcIeivnhygdgjwlmIDjqmArByqxEuusIHzjuEiBbgksFHqttcsldJkb/chrome.png">
        <media:thumbnail height="375" width="500" url="http://getfile5.posterous.com/getfile/files.posterous.com/temp-2010-10-03/nlfskIcIeivnhygdgjwlmIDjqmArByqxEuusIHzjuEiBbgksFHqttcsldJkb/chrome.png.scaled500.png" />
      </media:content>
    <feedburner:origLink>http://blog.cs50.net/2010/05/downloading-chrome-and-then-some.html</feedburner:origLink></item>
    <item>
      <pubDate>Mon, 03 May 2010 03:38:00 -0700</pubDate>
      <title>Creating Nodes with Style</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/gKCkbFOi2z4/creating-nodes-with-style.html</link>
      <guid isPermaLink="false">http://blog.cs50.net/2010/05/creating-nodes-with-style.html</guid>
      <description>&lt;p&gt;
	&lt;p&gt;Time passes...  An embarrassing number of days months has passed since the last post, and it turns out we're not very good at approving comments.  (Apologies to those whose comments were in limbo for so long!)  Unfortunately, it seems most every time we have an idea for a post, something comes up (including, sometimes, sleep) and out the window goes the idea.  But not this time!  For those who dabble in JavaScript, read on...&lt;/p&gt;
&lt;p&gt;&lt;a href="http://cs50.tv/"&gt;CS50&lt;/a&gt; has a suite of apps that (with a few exceptions) share a common navigation header.  Note the common drop-down in the top-right corner of &lt;a href="http://energy.cs50.net/"&gt;HarvardEnergy&lt;/a&gt;, &lt;a href="http://maps.cs50.net/"&gt;HarvardMaps&lt;/a&gt;, &lt;a href="http://news.cs50.net/"&gt;HarvardNews&lt;/a&gt;, &lt;a href="http://tweets.cs50.net/"&gt;HarvardTweets&lt;/a&gt;, and &lt;a href="http://shuttleboy.cs50.net/"&gt;Shuttleboy&lt;/a&gt;.  (Hm.  Which of those names is not like the others?)  Up until recently, that common header was the result of a whole lot of copy-paste, which was getting increasingly annoying to maintain, and so I decided to factor it out (like I probably should have from the get-go).  Within the &lt;tt&gt;body&lt;/tt&gt; element of each app's &lt;tt&gt;index.php&lt;/tt&gt; now is, essentially, a line like:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="pd"&gt;require&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/local/path/to/common.php&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;For purely aesthetic reasons, though, I wanted the links to the left of the drop-down to be crimson (&lt;tt&gt;#600&lt;/tt&gt;) and the links to the right of the drop-down to be black (except for the "50").  All of those stylizations are easy to do with inline CSS, as with the below:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="an"&gt;style&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;color: #600;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;API&lt;span class="ta"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;However, I also wanted the links to be underlined only when hovered over.  Half of that effect is easily achieved with similarly inline CSS:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="an"&gt;style&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;color: #600; text-decoration: none;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;API&lt;span class="ta"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Unfortunately, a &lt;a href="http://www.w3.org/TR/CSS2/selector.html#dynamic-pseudo-classes"&gt;pseudo-selector&lt;/a&gt; like &lt;tt&gt;:hover&lt;/tt&gt; can't be implemented in this same fashion.  (See &lt;a href="http://stackoverflow.com/questions/1033156/how-to-write-ahover-in-inline-css"&gt;Stack Overflow&lt;/a&gt; for a nice discussion.)  Of course, it's easy to include in an internal (or external) stylesheet:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;style&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/css&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--

a:hover
{
    text-decoration: underline;
}

--&amp;gt;&lt;/span&gt;
&lt;span class="ta"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;But, for a page to be considered valid &lt;a href="http://www.w3.org/TR/xhtml1/dtds.html"&gt;XHTML&lt;/a&gt;, any style elements must be children of a page's &lt;tt&gt;head&lt;/tt&gt;, not &lt;tt&gt;body&lt;/tt&gt;, element.  The implication is that I'd need to put that CSS inside a second file (e.g., &lt;tt&gt;style.php&lt;/tt&gt;) and then add, within the head element of each app's &lt;tt&gt;index.php&lt;/tt&gt; file, a line like:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="pd"&gt;require&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/local/path/to/style.php&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Or I could let HTTP grab that CSS by adding, within the head element of each app's &lt;tt&gt;index.php&lt;/tt&gt; file, a line like&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="an"&gt;href&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/remote/path/to/style.css&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;rel&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;stylesheet&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/css&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;whereby style.css contains only the CSS, not the XHTML tags.  I was annoyed by both solutions, though, since my goal was to simplify, ideally by centralizing all common code in just one file.&lt;/p&gt;
&lt;p&gt;It occurred to me that a lot of JavaScript libraries support "lazy-loading" of CSS rules, whereby you can incorporate additional CSS rules into a page via JavaScript (cf. &lt;a href="http://developer.yahoo.com/yui/get/"&gt;YUI 2's Get Utility&lt;/a&gt;), but I didn't want to have to include yet another JavaScript library in every app just to underline some links.  Fortunately, you can re-create that same functionality yourself quite easily!  Inside of &lt;tt&gt;common.php&lt;/tt&gt;, I essentially included the JavaScript below:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;script&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/javascript&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;
// &lt;span class="er"&gt;&amp;lt;&lt;/span&gt;![CDATA[

// wrap code in an anonymous function so that 
// variable (e) doesn't conflict with variables defined elsewhere
(function() {

    // create style element
    var e = document.createElement(&amp;quot;style&amp;quot;);

    // add attribute to element
    e.type = &amp;quot;text/css&amp;quot;;

    // define CSS rules in a text node
    var t = document.createTextNode(&amp;quot;div#apps a { text-decoration: none; } div#apps a:hover { text-decoration: underline; }&amp;quot;);

    // make text node a child of element
    e.appendChild(t);

    // make element a child of page's head element
    document.getElementsByTagName(&amp;quot;head&amp;quot;)[0].appendChild(e);

})();

// ]]&lt;span class="er"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="ta"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;As you may have gathered from its comments, that code instructs a browser to insert this node inside a page's &lt;tt&gt;head&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;style&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;text/css&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--

div#apps a
{ 
    text-decoration: none;
} 

div#apps a:hover 
{ 
    text-decoration: underline;
}

--&amp;gt;&lt;/span&gt;
&lt;span class="ta"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;(I added some whitespace to the above for clarity.)  Incidentally, the XHTML in &lt;tt&gt;common.php&lt;/tt&gt; is wrapped with&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="an"&gt;id&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;apps&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;and&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&lt;span class="ta"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;to ensure that my CSS rules are applied only to the elements within.  Ironically, it took me longer to write this post than it did to actually code that solution!  But a neat application of JavaScript &lt;a href="http://www.w3schools.com/jsref/"&gt;DOM functions&lt;/a&gt; that offers some insight into how libraries like YUI achieve their own magic!&lt;/p&gt;
&lt;p&gt;djm&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/2010/05/creating-nodes-with-style.html"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/2010/05/creating-nodes-with-style.html#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/gKCkbFOi2z4" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
    <feedburner:origLink>http://blog.cs50.net/2010/05/creating-nodes-with-style.html</feedburner:origLink></item>
    <item>
      <pubDate>Wed, 17 Feb 2010 04:54:00 -0800</pubDate>
      <title>America's Most Reliable Wireless Network</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/mRMiVYf8poE/americas-most-reliable-wireless-network.html</link>
      <guid isPermaLink="false">http://blog.cs50.net/2010/02/americas-most-reliable-wireless-network.html</guid>
      <description>&lt;p&gt;
	&lt;p&gt;Okay, the bugs in this screenshot (also courtesy of a student) are even more subtle at first glance than &lt;a href="http://cs50.posterous.com/2010/02/try-tasty-chicken.html"&gt;the last&lt;/a&gt;.  But we think our caption for this one is even wittier.&lt;/p&gt;
&lt;p&gt;&lt;div class='p_embed p_image_embed'&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/bcIEBitCwzpsBaCFJHufqnChpvDiAGpItovHAipsnGzaDnzjBJwpuqlahfGE/verizon.JPG.scaled1000.jpg"&gt;&lt;img alt="Verizon" height="446" src="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/bcIEBitCwzpsBaCFJHufqnChpvDiAGpItovHAipsnGzaDnzjBJwpuqlahfGE/verizon.JPG.scaled500.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Perhaps needless to say, someone forgot to &lt;a href="http://en.wikipedia.org/wiki/Variable_interpolation#Interpolation"&gt;interpolate&lt;/a&gt; his or her variables.&lt;/p&gt;
&lt;p&gt;djm&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/2010/02/americas-most-reliable-wireless-network.html"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/2010/02/americas-most-reliable-wireless-network.html#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/mRMiVYf8poE" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
      <media:content type="image/jpeg" height="571" width="640" url="http://getfile3.posterous.com/getfile/files.posterous.com/cs50/mGIeAAkJcgvxsBohCEvoezmgFAGtbaqzsbxJutbGmrHfAJHwCDeIlBFFbHam/media_http3bpblogspot_puBFa.jpeg">
        <media:thumbnail height="446" width="500" url="http://getfile7.posterous.com/getfile/files.posterous.com/cs50/mGIeAAkJcgvxsBohCEvoezmgFAGtbaqzsbxJutbGmrHfAJHwCDeIlBFFbHam/media_http3bpblogspot_puBFa.jpeg.scaled500.jpg" />
      </media:content>
      <media:content type="image/jpeg" height="926" width="1037" url="http://getfile2.posterous.com/getfile/files.posterous.com/temp-2010-10-03/bcIEBitCwzpsBaCFJHufqnChpvDiAGpItovHAipsnGzaDnzjBJwpuqlahfGE/verizon.JPG">
        <media:thumbnail height="446" width="500" url="http://getfile3.posterous.com/getfile/files.posterous.com/temp-2010-10-03/bcIEBitCwzpsBaCFJHufqnChpvDiAGpItovHAipsnGzaDnzjBJwpuqlahfGE/verizon.JPG.scaled500.jpg" />
      </media:content>
    <feedburner:origLink>http://blog.cs50.net/2010/02/americas-most-reliable-wireless-network.html</feedburner:origLink></item>
    <item>
      <pubDate>Wed, 17 Feb 2010 04:51:00 -0800</pubDate>
      <title>Sign up for a Bank of America account today.  Er, tomorrow.</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/2hcaJtP6J_I/sign-up-for-bank-of-america-account.html</link>
      <guid isPermaLink="false">http://blog.cs50.net/2010/02/sign-up-for-bank-of-america-account.html</guid>
      <description>&lt;p&gt;
	&lt;p&gt;So, after making fun of Domino's in class one night for their &lt;a href="http://cs50.posterous.com/2010/02/try-tasty-chicken.html"&gt;&lt;tt&gt;printf&lt;/tt&gt; fail&lt;/a&gt;, a student passed along this screenshot from their online bank account:&lt;/p&gt;
&lt;p&gt;&lt;div class='p_embed p_image_embed'&gt;
&lt;a href="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/gEchylnisCvaAAcErltqCmaFDxBhHwsahDbBFCbeewHCCgldGrfBdBgnBhav/boa.jpg.scaled1000.jpg"&gt;&lt;img alt="Boa" height="169" src="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/gEchylnisCvaAAcErltqCmaFDxBhHwsahDbBFCbeewHCCgldGrfBdBgnBhav/boa.jpg.scaled500.jpg" width="500" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Sorry, no account number or PIN in the screenshot!&lt;/p&gt;
&lt;p&gt;See the bug?  It's pretty subtle at first.  But it boils down to a difference in opinion with &lt;a href="https://www.bankofamerica.com/i"&gt;BoA&lt;/a&gt; as to what "today" means.&lt;/p&gt;
&lt;p&gt;We'll leave it to the reader (that's you) to noodle over why this bug happened around the time it did.&lt;/p&gt;
&lt;p&gt;djm&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/2010/02/sign-up-for-bank-of-america-account.html"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/2010/02/sign-up-for-bank-of-america-account.html#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/2hcaJtP6J_I" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
      <media:content type="image/jpeg" height="216" width="640" url="http://getfile9.posterous.com/getfile/files.posterous.com/cs50/fJIuosbbtoprGgxFnFFHFbhAGvwkmmypFjmpGvwFwDbzdsiAinfbsEuaddbb/media_http4bpblogspot_oCxAc.jpg">
        <media:thumbnail height="169" width="500" url="http://getfile1.posterous.com/getfile/files.posterous.com/cs50/fJIuosbbtoprGgxFnFFHFbhAGvwkmmypFjmpGvwFwDbzdsiAinfbsEuaddbb/media_http4bpblogspot_oCxAc.jpg.scaled500.jpg" />
      </media:content>
      <media:content type="image/jpeg" height="351" width="1041" url="http://getfile4.posterous.com/getfile/files.posterous.com/temp-2010-10-03/gEchylnisCvaAAcErltqCmaFDxBhHwsahDbBFCbeewHCCgldGrfBdBgnBhav/boa.jpg">
        <media:thumbnail height="169" width="500" url="http://getfile5.posterous.com/getfile/files.posterous.com/temp-2010-10-03/gEchylnisCvaAAcErltqCmaFDxBhHwsahDbBFCbeewHCCgldGrfBdBgnBhav/boa.jpg.scaled500.jpg" />
      </media:content>
    <feedburner:origLink>http://blog.cs50.net/2010/02/sign-up-for-bank-of-america-account.html</feedburner:origLink></item>
    <item>
      <pubDate>Wed, 17 Feb 2010 04:42:00 -0800</pubDate>
      <title>Try Tasty Chicken</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/uyK9zIaKmCA/try-tasty-chicken.html</link>
      <guid isPermaLink="false">http://blog.cs50.net/2010/02/try-tasty-chicken.html</guid>
      <description>&lt;p&gt;
	&lt;p&gt;So this is a screenshot that I took just before checking out from &lt;a href="http://dominos.com/"&gt;dominos.com&lt;/a&gt; one night. (I used to like their thin-crust pizza, but, frankly, I'm not a fan of their &lt;a href="http://www.google.com/search?q=domino%27s+new+recipe"&gt;new recipe&lt;/a&gt;.) At the time, I was teaching &lt;a href="http://cs75.tv/"&gt;Computer Science E-75: Building Dynamic Websites at Harvard Extension School&lt;/a&gt;, and it seemed a fun lecture example of a bug that someone at Domino's really should have caught. (It persisted for months until they replaced this last-second upsell attempt with an ad for "Chocolate Lava Crunch Cakes," whatever those are.)&lt;/p&gt;
&lt;p&gt;&lt;div class='p_embed p_image_embed'&gt;
&lt;img alt="Dominos2" height="307" src="http://posterous.com/getfile/files.posterous.com/temp-2010-10-03/vADBxaiFDovyCqsfcIFfEcqgCfgsntbxfzguezHFnkJntcHmbhhhtwdanmCm/dominos2.jpg.scaled500.jpg" width="430" /&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;See it yet?&lt;/p&gt;
&lt;p&gt;Indeed, the price of those Kickers should probably be $6.30, not $6.3. Of course, as &lt;a href="http://en.wikipedia.org/wiki/Floating_point"&gt;floating-point values&lt;/a&gt;, the two are arguably the same (imprecision of floats aside), but most people prefer their money formatted to two decimal places.&lt;/p&gt;
&lt;p&gt;How to fix? Without seeing the code, it's hard to say for sure, but odds are the bug relates to improper use of a function like &lt;a href="http://en.wikipedia.org/wiki/Printf"&gt;&lt;tt&gt;printf&lt;/tt&gt;&lt;/a&gt;, which allows programmers to format numbers as they see fit. For instance, if &lt;tt&gt;f&lt;/tt&gt; is a &lt;tt&gt;float&lt;/tt&gt;, it can be formatted like money with &lt;tt&gt;printf&lt;/tt&gt; in C as follows:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;printf(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;%.2f&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, f);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;tt&gt;.2&lt;/tt&gt; tells &lt;tt&gt;printf&lt;/tt&gt; to format the &lt;tt&gt;float&lt;/tt&gt; to two decimal places. Of course, the site's probably not implemented in C (in which much of &lt;a href="http://cs50.tv/"&gt;CS50&lt;/a&gt; is taught). In fact, a quick glance at the site's URLs suggests it's implemented in Java (c.f. &lt;a href="http://www.dominos.com/home/index.jsp"&gt;http://www.dominos.com/home/index.jsp&lt;/a&gt;) using &lt;a href="http://en.wikipedia.org/wiki/JavaServer_Pages"&gt;JSP&lt;/a&gt;, which has its &lt;a href="http://java.sun.com/javase/6/docs/api/java/io/Console.html#printf(java.lang.String,%20java.lang.Object...)"&gt;own version of &lt;/a&gt;&lt;tt&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/io/Console.html#printf(java.lang.String,%20java.lang.Object...)"&gt;printf&lt;/a&gt;&lt;/tt&gt; as well as alternatives, including &lt;tt&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/text/NumberFormat.html"&gt;java.text.NumberFormat&lt;/a&gt;&lt;/tt&gt;, &lt;tt&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/text/DecimalFormat.html"&gt;java.text.DecimalFormat&lt;/a&gt;&lt;/tt&gt;, and &lt;tt&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Currency.html"&gt;java.util.Currency&lt;/a&gt;&lt;/tt&gt;. Of course, because of the imprecision of floats, they really shouldn't be used for money at all, unless Domino's is willing to lose (lots of) pennies over time. Better to store prices as cents or use some &lt;a href="http://en.wikipedia.org/wiki/Fixed-point_arithmetic"&gt;fixed-point&lt;/a&gt; data type (e.g., MySQL offers a &lt;tt&gt;&lt;a href="http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html"&gt;DECIMAL&lt;/a&gt;&lt;/tt&gt; data type that might help in this case).&lt;/p&gt;
&lt;p&gt;Whatever the language or database in use, though, someone screwed up. And it shouldn't have been hard to fix! I suppose replacing Kickers with Chocolate Lava Crunch Cakes was, as they say, a workaround.&lt;/p&gt;
&lt;p&gt;djm&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/2010/02/try-tasty-chicken.html"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/2010/02/try-tasty-chicken.html#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/uyK9zIaKmCA" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
      <media:content type="image/jpeg" height="286" width="400" url="http://getfile3.posterous.com/getfile/files.posterous.com/cs50/EsDzrCyqxJothnumvqJvFpdxyeBnomGxjszdxvtBDHHtjEknrkcklnqsfjuH/media_http4bpblogspot_oyHHy.jpg">
        <media:thumbnail height="286" width="400" url="http://getfile5.posterous.com/getfile/files.posterous.com/cs50/EsDzrCyqxJothnumvqJvFpdxyeBnomGxjszdxvtBDHHtjEknrkcklnqsfjuH/media_http4bpblogspot_oyHHy.jpg.scaled500.jpg" />
      </media:content>
      <media:content type="image/jpeg" height="307" width="430" url="http://getfile8.posterous.com/getfile/files.posterous.com/temp-2010-10-03/vADBxaiFDovyCqsfcIFfEcqgCfgsntbxfzguezHFnkJntcHmbhhhtwdanmCm/dominos2.jpg">
        <media:thumbnail height="307" width="430" url="http://getfile0.posterous.com/getfile/files.posterous.com/temp-2010-10-03/vADBxaiFDovyCqsfcIFfEcqgCfgsntbxfzguezHFnkJntcHmbhhhtwdanmCm/dominos2.jpg.scaled500.jpg" />
      </media:content>
    <feedburner:origLink>http://blog.cs50.net/2010/02/try-tasty-chicken.html</feedburner:origLink></item>
    <item>
      <pubDate>Wed, 17 Feb 2010 04:11:00 -0800</pubDate>
      <title>This is CS50.</title>
      <link>http://feedproxy.google.com/~r/cs50blog/~3/BCzhcycK0bY/this-is-cs50.html</link>
      <guid isPermaLink="false">http://blog.cs50.net/2010/02/this-is-cs50.html</guid>
      <description>&lt;p&gt;
	&lt;p&gt;So this first post has been on the to-do list for quite some time, as we felt the inaugural post should really be something special. &amp;nbsp;Unfortunately, we keep coming up with some really good ideas for second and third posts but, having not yet posted the first, we haven't quite gotten around to posting those ideas either.&lt;/p&gt;
&lt;p&gt;So we're not very good at this blogging thing it seems.&lt;/p&gt;
&lt;p&gt;But that ends tonight. &amp;nbsp;We're finally crossing the first post off the to-do list. &amp;nbsp;Rather than aspire to be special, though, why don't we aim a bit lower and just explain the intent of this blog.&lt;/p&gt;
&lt;p&gt;I happen to teach a course (&lt;a href="http://cs50.tv/"&gt;CS50&lt;/a&gt;) at Harvard College as well as, like Dan, a few at Harvard Extension School, and, most every day of the week, it seems, some interesting technical question or topic comes up that's fun (for us, at least) to discuss. &amp;nbsp;Given that both of us learned most everything we know from others, we thought it'd be fun (and only fair) to have some of those discussions a bit more publicly in hopes that others might enjoy learning what we've learned from others. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Officially, this blog is "on the intellectual enterprises of computer science and the art of programming." &amp;nbsp;In the interests of full disclosure, we stole that from CS50's own &lt;a href="http://webdocs.registrar.fas.harvard.edu/courses/ComputerScience.html"&gt;catalogue description&lt;/a&gt;. &amp;nbsp;But it would appear to give us license to discuss most anything of technical interest, so that's why we chose it. &amp;nbsp;Admittedly, it's probably misleadingly lofty, since I wouldn't be surprised if our next post has a &lt;a href="http://en.wikipedia.org/wiki/Lolcat"&gt;lolcat&lt;/a&gt;. &amp;nbsp;But, overall, we do aspire for this blog to be educational (though occasionally silly) in nature. &amp;nbsp;So rather than just comment on technical things, we'll try to explain them along the way.&lt;/p&gt;
&lt;p&gt;In the interests of self-defense, I should say that both Dan and I used to cringe anytime we heard the word "blog," since we didn't quite understand why we'd want to read on a website what other people, oh, had for breakfast. &amp;nbsp;But these things seem here to stay, and a blog seems an apt forum to share technical thoughts publicly. &amp;nbsp;So thus was born the CS50 Blog.&lt;/p&gt;
&lt;p&gt;Actually, originally, this blog was to be about funny bugs we've encountered in real life, so the next few posts may be a bit screenshot-heavy as we clear out our backlog. &amp;nbsp;Rest assured they have nothing to do with the intellectual enterprises of computer science.&lt;/p&gt;
&lt;p&gt;Anyhow, Dan tells me he had yogurt + granola + nuts + berries for breakfast. &amp;nbsp;I had lunch.&lt;/p&gt;
&lt;p&gt;This is the CS50 Blog.&lt;/p&gt;
&lt;p&gt;djm&lt;/p&gt;
	
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cs50.net/2010/02/this-is-cs50.html"&gt;Permalink&lt;/a&gt; 

	| &lt;a href="http://blog.cs50.net/2010/02/this-is-cs50.html#comment"&gt;Leave a comment&amp;nbsp;&amp;nbsp;&amp;raquo;&lt;/a&gt;

&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/cs50blog/~4/BCzhcycK0bY" height="1" width="1"/&gt;</description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/780219/me4.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/3sTztdpJmXPr</posterous:profileUrl>
        <posterous:firstName>David J.</posterous:firstName>
        <posterous:lastName>Malan</posterous:lastName>
        <posterous:nickName>malan</posterous:nickName>
        <posterous:displayName>David J. Malan</posterous:displayName>
      </posterous:author>
    <feedburner:origLink>http://blog.cs50.net/2010/02/this-is-cs50.html</feedburner:origLink></item>
  </channel>
</rss>

