My CS50 Section Slides

Fall of 2015 introduced the whirlwind that is Harvard’s CS50 to Yale, quickly becoming “the most popular course in Yale College.” Providing a strong support network, particularly one spearheaded by other students, is one of the key pedagogical backbones of the course. At Yale, this took the shape of a team of 29 students hosting nightly question and debugging sessions, weekly 90-minute teaching sections, and a slew of other activities like a hackathon and the CS50 Fair.

I’ve compiled all of my personal teaching slides from the Fall 2015 semester below.

Slides

Here’s a breakdown of what was covered:

  • Section 1 (Supersection): exploring the CS50 Appliance (a customized Cloud9 workspace), basic Unix commands, data types, operators, conditionals, loops, functions — Video
  • Section 2: arrays, strings, ASCII, functions, command-line arguments — Slides
  • Section 3: the GDB debugger, asymptotic notation and algorithmic complexity, binary search, sorting algorithms — Slides
  • Section 4: Unix pipes and redirection, file I/O, memory management, pointers — Slides
  • Section 5: linked lists, hashtables — Slides
  • Section 6: stacks, queues, linked lists, hashtables — Slides
  • Section 7: chmod, HTML, CSS, TCP/IP, HTTP — Slides
  • Section 8: PHP, SQL, MVC — Slides
  • Section 9: Javascript, the DOM, jQuery, AJAX — Slides

Configuring Let's Encrypt and Nginx on EC2

Let's Encrypt

Let’s Encrypt is a new Certificate Authority that offers free TLS/SSL certificates. Now that it’s entered its public beta stage, I decided to experiment with installing and manually configuring a Let’s Encrypt certificate on a EC2 instance running Ubuntu 14.04, Ruby on Rails, and Nginx.

To get started, download the Let’s Encrypt client and run the built-in installer.

$ git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
$ /opt/letsencrypt/letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory --help --debug

Update your Nginx configuration (probably /etc/nginx/sites-available/default) to allow web access to all files in the .well-known/ directory of your web root. This endpoint will be accessed by Let’s Encrypt to ensure that you actually have control over your domain.

location ~ /.well-known {
  allow all;
}

After updating your Nginx configuration, restart your server.

$ sudo service nginx restart

Add the following to /etc/letsencrypt/cli.ini. The webroot plugin will automatically generate the files necessary for the ACME protocol. Remember to use the correct web root directory (if you’re using Capistrano, this will probably be /home/deploy/yourapp/current/public) and domain names.

rsa-key-size = 4096
email = [email protected]
domains = yourapp.com www.yourapp.com
authenticator = webroot
webroot-path = /home/deploy/yourapp/current/public

We can now begin the certificate authorization process.

$ /opt/letsencrypt/letsencrypt-auto certonly --config /etc/letsencrypt/cli.ini --agree-tos

Update your Nginx configuration to take advantage of your newly-issued certificate.

listen 443;
server_name localhost;

ssl on;
ssl_certificate /etc/letsencrypt/live/yourapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourapp.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

After restarting your web server, your site should now be accessible via HTTPS.

Certificate Renewal

Let’s Encrypt certificates expire after 90 days to ensure security and to encourage automation. We can automate the certificate renewal process by creating a simple monthly cronjob in /etc/cron.monthly/letsencrypt.

#!/bin/sh
#
# Let's Encrypt renewal service

/opt/letsencrypt/letsencrypt-auto certonly --config /etc/letsencrypt/cli.ini --agree-tos --renew-by-default
service nginx restart

Test your renewal script. If you see a success message, you’re set!

$ sudo /etc/cron.monthly/letsencrypt

Flask and AngularJS Workshop (YHack 2015)

My friend Mike and I recently prepared a quick Flask and AngularJS workshop for YHack 2015 (the first YHack in which the two of us did not serve as directors!). Our talk teaches basic backend and frontend web development via the development of a basic blackjack game.

Slides

Code

You can follow along on your own using our workshop code.


Squirrel Watching

A squirrel perched on a branch

The following short story recently went viral in China. I’ve translated it into English, taking some artistic license in the process. You can read it in Chinese here (original author is unknown).

It’s a warm summer afternoon and a mother and her son are sitting side by side in the backyard. The son, at home from college, is buried in a book. The mother’s attention is fixed on the twin oak trees facing them, shading them from the sun’s unforgiving beams.

Suddenly, a squirrel hops down from the branches of the larger of the two oak trees, lands in the bed of mulch surrounding the tree, and promptly darts into the bushes. The mother turns to her son and asks him, “What is that?”

He looks up and murmurs, “A squirrel.” His gaze immediately turns back to the book.

The mother nods thoughtfully and watches the squirrel quiver in the bushes. A few moments later, she asks him again, “What is that?”

He reluctantly raises his head, follows his mother’s gaze over to the same bushes, and frowns. “Mom, I just told you. That’s a squirrel.”

Just as he is about to look away, the squirrel scurries over to the smaller oak tree. The mother points and asks yet again, “What is that?”

The son closes his book shut, “It’s a squirrel, Mom, a squirrel!”

Her eyes, fixed intently on the squirrel, do not notice her son’s annoyed glare. She smiles as the squirrel picks up an acorn and begins to nibble at it. Gingerly, she asks, “What is that?”

The son throws his arms in the air and cries out, “You’ve asked me the same thing like ten times already! It’s a squirrel, what don’t you understand?”

Without a word, she stands up and turns her back on her son. Confused, incredulous, and still fuming, he calls back, “What, you’re leaving?”

She holds her palm up, instructing him not to follow, and walks into the house. He turns back to the two oak trees. Amidst all the noise, the squirrel has scampered away. Sighing, he throws his book down in frustration.

A few moments later, the mother returns. In her hands is a small diary, corners frayed. She opens it up to a specific entry and hands it to him. “Read this.”

He reads:

December 17, 1995

Today, I took my two-year-old son to the park. While we were camped out in the grass, a squirrel scrambled near us. Twenty-one times he asked me, “What is that?” Twenty-one times I answered, “That’s a squirrel, honey.” And every time I answered him, I would hug him tightly… over and over and over. How could I possibly be annoyed by such pure innocence and curiosity…


Investigating the Relative Age Effect at Yale

An apple sitting on a pile of books

I just finished reading Malcolm Gladwell’s best-seller, Outliers. Naturally, I was curious about some of his claims and decided to do a little investigating of my own.

Gladwell starts the book by suggesting the existence of the following “iron law” of Canadian hockey: “in any elite group of hockey players — the very best of the best — 40 percent of the players will have been born between January and March, 30 percent between April and June, 20 percent between July and September, and 10 percent between October and December.”

Why would this be the case? It turns out that Canadian hockey leagues impose an eligibility cut-off date of January 1, meaning that a child born in January competes in the same league as a child born in December, almost an entire year later. These extra months of maturity, according to a study conducted by psychologist Roger Barnsley, give an unfair advantage to kids born earlier in the year — by virtue of being older, these kids tend to be larger, more coordinated, and more “talented” than their peers. Those that are deemed more talented go on to enjoy the rewards of better coaching, increased self-confidence, and more opportunities, creating a self-fulfilling prophecy that is driven entirely by an arbitrary cut-off.

This phenomenon is known as the relative age effect. And both Gladwell and Barnsley suggest that it occurs within academia and education as well. Like hockey leagues, schools have an eligibility cut-off date (usually, the end of summer) and often separate students based on relative merit (gifted student programs). To further this argument, Gladwell points to the research of economists Kelly Bedard and Elizabeth Dhuey, who have noted that “at four year colleges in the United States… students belonging to the relatively youngest group in their class are underrepresented by about 11.6 percent.”

With this knowledge in hand, I decided to poke around and see if I could find any interesting patterns at Yale, hoping to answer the following question: does the relative age effect impact your chances of making it to Yale?

Since I’m currently an undergrad at Yale, I have access to the walled-off Yale Facebook, a directory that contains basic biographical and contact information for all current undergraduate students. Here’s the scraped and compiled data, which includes the class of 2015 up to the class of 2019 (5565 students total, 5381 of which have their birthdays listed):

  • January: 475
  • February: 405
  • March: 468
  • April: 479
  • May: 461
  • June: 445
  • July: 446
  • August: 428
  • September: 443
  • October: 481
  • November: 425
  • December: 425

Birth months at Yale

It seems that the relative age effect doesn’t apply: Yale undergrads are born evenly throughout the year, with a range of 76, a mean of around 448, and a fairly low standard deviation of around 25. And the most unpopular birth month is February, which also happens to be the shortest month of the year. If we adjust for the 10 or so lost days of February between the classes of 2015 and 2019, the data would show even less variance than it does now.

However, it can’t hurt to point out that the graph has three local maximums, two of which might be relevant to the relative age effect: one around October (close to the start of school in the Northern hemisphere), one in March and April (close to the start of school in the Southern hemisphere) and one in January (which I don’t have a relavant explanation for).

It’s also worth noting that according to data compiled by Amitabh Chandra of Harvard University, the second half of September is the most common time of year for U.S.-born babies (approximately 81% of the Yale population hold U.S. citizenship or permanent resident status), providing an alternate explanation for that particular local maximum.

There are, unfortunately, some limitations to what we can do with this data. The Yale Facebook does not list birth years, which makes it impossible to filter out students who may have entered school a year early, or who may have skipped a grade or two. However, if we assume that these kids do exist in the pool, we might be able to say that the relative age effect did not play a role in their development — that is, for the truly precocious, relative age differences do not play a major role in their educational development. This isn’t a certain conclusion, however, since the other side of the coin in not having birth years is that we also are unable to filter out students who may have purposely “redshirted” before starting kindergarten or who may have taken a gap year in between high school and college, thus making them older than their peers by the time they enter college.

But empirically, at least, it appears that most early age biases at Yale have been erased or never existed in the first place. 1

Could it be that Yale admissions officers are familiar with the relative age effect and consciously adjust for this in their admissions process? This is possible, but probably unlikely.

Here’s another possibility: as mentioned earlier, 19% of Yale students are listed as international students. What if, out of this 19%, almost every student that attended school in the Southern hemisphere was born in the months of March and April, balancing out a presumably lower amount of students in the Northern hemisphere that were also born in those months? If true, this could have created the local maximum that we see in March and April. And while relying purely on geography is an imperfect filter for determining when school starts, it should at least give us a working estimate to play with.

When I went to test this hypothesis, I quickly discovered that this was not the case. Of the 83 students with addresses in the Southern hemisphere (Argentina, Australia, Botswana, Brazil, Chile, Indonesia, Kenya, Mauritius, New Zealand, Peru, Rwanda, Singapore, South Africa, Swaziland, Tanzania, Uganda, Zimbabwe), only 14 were born in March and April. The most common birth months were actually June and July.

The best explanation I’ve seen thus far comes from Maria Konnikova from The New Yorker. In her “Youngest Kid, Smartest Kid?” essay, Konnikova suggests that while older kindergarten students do benefit from their age, “by the time they get to eighth grade, any disparity has largely evened out — and, by college, younger students repeatedly outperform older ones in any given year.” Older students, she argues, become bored and complacent, while younger students embrace their underdog statuses and are forced to strive and push themselves harder, developing a work ethic that even Gladwell can appreciate.

Thanks to Jonathan Chang for reading a draft of this essay.

  1. Note: this experiment only tests for the relative age bias. I am positive that there are many other biases and barriers in this data set that can not be explained solely by age.