Downloading Chrome and then some...

1 comments
Our thanks to Motiur Rahman for submitting this bug of the day, a screenshot he took while downloading Chrome on Ubuntu:


Spot it yet?

djm

Creating Nodes with Style

0 comments
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...

CS50 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 HarvardEnergyHarvardMapsHarvardNewsHarvardTweets, and Shuttleboy.  (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 body element of each app's index.php now is, essentially, a line like:

require("/local/path/to/common.php");

For purely aesthetic reasons, though, I wanted the links to the left of the drop-down to be crimson (#600) 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:

<a style="color: #600;">API</a>

However, I also wanted the links to be underlined only when hovered over.  Half of that effect is easily achieved with similarly inline CSS:

<a style="color: #600; text-decoration: none;">API</a>

Unfortunately, a pseudo-selector like :hover can't be implemented in this same fashion.  (See Stack Overflow for a nice discussion.)  Of course, it's easy to include in an internal (or external) stylesheet:

<style type="text/css">
<!--

a:hover
{
    text-decoration: underline;
}

-->
</style>

But, for a page to be considered valid XHTML, any style elements must be children of a page's head, not body, element.  The implication is that I'd need to put that CSS inside a second file (e.g., style.php) and then add, within the head element of each app's index.php file, a line like:

require("/local/path/to/style.php");

Or I could let HTTP grab that CSS by adding, within the head element of each app's index.php file, a line like

<link href="/remote/path/to/style.css" rel="stylesheet" type="text/css" />

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.

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. YUI 2's Get Utility), 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 common.php, I essentially included the JavaScript below:

<script type="text/javascript">
// <![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("style");

    // add attribute to element
    e.type = "text/css";

    // define CSS rules in a text node
    var t = document.createTextNode("div#apps a { text-decoration: none; } div#apps a:hover { text-decoration: underline; }");

    // make text node a child of element
    e.appendChild(t);

    // make element a child of page's head element
    document.getElementsByTagName("head")[0].appendChild(e);

})();

// ]]>
</script>

As you may have gathered from its comments, that code instructs a browser to insert this node inside a page's head:

<style type="text/css">
<!--

div#apps a
    text-decoration: none;

div#apps a:hover 
    text-decoration: underline;
}

-->
</style>

(I added some whitespace to the above for clarity.)  Incidentally, the XHTML in common.php is wrapped with 

<div id="apps">

and

</div>

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 DOM functions that offers some insight into how libraries like YUI achieve their own magic!

djm

America's Most Reliable Wireless Network

4 comments
Okay, the bugs in this screenshot (also courtesy of a student) are even more subtle at first glance than the last.  But we think our caption for this one is even wittier.




Perhaps needless to say, someone forgot to interpolate his or her variables.


djm

Sign up for a Bank of America account today. Er, tomorrow.

1 comments
So, after making fun of Domino's in class one night for their printf fail, a student passed along this screenshot from their online bank account:


Sorry, no account number or PIN in the screenshot!

See the bug?  It's pretty subtle at first.  But it boils down to a difference in opinion with BoA as to what "today" means.

We'll leave it to the reader (that's you) to noodle over why this bug happened around the time it did.

djm

Try Tasty Chicken

2 comments
So this is a screenshot that I took just before checking out from dominos.com one night.  (I used to like their thin-crust pizza, but, frankly, I'm not a fan of their new recipe.)  At the time, I was teaching Computer Science E-75: Building Dynamic Websites at Harvard Extension School, 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.)


See it yet?

Indeed, the price of those Kickers should probably be $6.30, not $6.3.  Of course, as floating-point values, the two are arguably the same (imprecision of floats aside), but most people prefer their money formatted to two decimal places.

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 printf, which allows programmers to format numbers as they see fit.  For instance, if f is a float, it can be formatted like money with printf in C as follows:

printf("%.2f", f);

The .2 tells printf to format the float to two decimal places.  Of course, the site's probably not implemented in C (in which much of CS50 is taught).  In fact, a quick glance at the site's URLs suggests it's implemented in Java (c.f. http://www.dominos.com/home/index.jsp) using JSP, which has its own version of printf as well as alternatives, including java.text.NumberFormat, java.text.DecimalFormat, and java.util.Currency.  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 fixed-point data type (e.g., MySQL offers a DECIMAL data type that might help in this case).

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.

djm

This is CS50.

1 comments
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.  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.


So we're not very good at this blogging thing it seems.


But that ends tonight.  We're finally crossing the first post off the to-do list.  Rather than aspire to be special, though, why don't we aim a bit lower and just explain the intent of this blog.


I happen to teach a course (CS50) 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.  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.  


Officially, this blog is "on the intellectual enterprises of computer science and the art of programming."  In the interests of full disclosure, we stole that from CS50's own catalogue description.  But it would appear to give us license to discuss most anything of technical interest, so that's why we chose it.  Admittedly, it's probably misleadingly lofty, since I wouldn't be surprised if our next post has a lolcat.  But, overall, we do aspire for this blog to be educational (though occasionally silly) in nature.  So rather than just comment on technical things, we'll try to explain them along the way.


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.  But these things seem here to stay, and a blog seems an apt forum to share technical thoughts publicly.  So thus was born the CS50 Blog.


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.  Rest assured they have nothing to do with the intellectual enterprises of computer science.


Anyhow, Dan tells me he had yogurt + granola + nuts + berries for breakfast.  I had lunch.


This is the CS50 Blog.


djm