A TextExpander snippet for Amazon affiliate links

Earlier this evening, Casey Liss tweeted a link to a post by Stoyan Stefanov with a bookmarklet for creating Amazon affiliate links. It’s short, clean and functional. I like it, but it still needs you to copy and paste the link into your document. I wanted to cut out that step.

Stefan’s post has a succinct explanation of the four components of an Amazon affiliate link:

  • http://www.amazon.com/ - self-explanatory, I think
  • /dp/ - standing for “details product” or maybe “details page”1
  • /1847194141/ - a 10 character product code, aka ASIN code, Amazon Standard Identification Number
  • ?tag=affiliatecode-20 - your affiliate code, or tag

A typical Amazon link includes all of this information, but also includes a lot of extraneous junk:

http://www.amazon.co.uk/Special-Topics-Calamity-Physics-Marisha/dp/0141024321/ref=sr_1_1?ie=UTF8&qid=1409346826&sr=8-1&keywords=calamity+physics

By splitting at the slashes, we can extract what we want and throw away the rest. We can then use this to construct an affiliate URL.

I’ve wrapped this idea in a Python script, which I can use in TextExpander:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
import sys

FRONT_URL      = "%snippet:;furl%"
AFFILIATE_CODE = "123-abc-456"

if re.match('[www\.]?amazon', FRONT_URL) is None:
    print FRONT_URL
    sys.exit()

components  = FRONT_URL.split('/')
amazon_site = filter(lambda x: 'amazon' in x, components)[0]
if 'dp' in FRONT_URL:
    asin_code   = components[components.index('dp') + 1]
elif 'gp' in FRONT_URL:
    idx = components.index('gp') + 1
    if components[idx + 1] == 'product':
        asin_code = components[idx + 2]
    else:
        asin_code = components[idx + 1]

aff_link = 'http://{amazon}/dp/{asin}/?tag={aff_code}'.format(
    amazon   = amazon_site,
    asin     = asin_code,
    aff_code = AFFILIATE_CODE
)

print aff_link

This is saved as a shell script snippet in TextExpander, and I have it bound to the abbreviation ;az.

The %snippet:;furl% component gets the front URL from the running browser, using a snippet I originally got from Dr. Drang. Then I put my affiliate code in at the top of the script.

Then I use a simple regex to check that it’s an Amazon page. If not, I just print the URL.

Next I split the URL at the slashes, and extract the domain name for that particular Amazon site, and the ASIN as the next component after /dp/. Older links have /gp/product (see footnote), so we treat those separately. Finally, I combine these pieces into an affiliate URL, and print it out. Then TextExpander types this link into my front document.

Now all I need to do is actually write a post that requires an Amazon affiliate link.


  1. According to Aaron Shepard, dp and its predecessor gp are programs used on Amazon’s backend to generate product pages, although I’ve been unable to verify that. 


A quick Alfred workflow for opening recent screenshots

I’m a big fan of the productivity app Alfred. It’s one of the first apps I install on any new Mac, and I use it dozens of times a day. Here’s a quick worflow I whipped up this morning.

When I take a screenshot, I usually want to use it immediately. I could navigate to my screenshots directory in Alfred, or find it in Finder,1 but it’s such an easy task to automate.

We can use AppleScript to get the most recently created file in the screenshots directory, which should be the latest screenshot:

set screenshotFolder to ("/Users/alexwlchan/screenshots" as POSIX file)
set screenshots to (get every file of folder screenshotFolder)
set latestScreenshot to item 1 of reverse of (sort screenshots by creation date)

In the final line, we can replace item 1 by item n, for an integer n, to get the nth most recent screenshot.

I then put this into a very simple workflow in Alfred. The input is a keyword (I used “screenshot”), with an optional argument to determine which screenshot you want. This is connected to a “Run NSAppleScript” action with the following script:

on alfred_script(q)
    tell application "Finder"
        if q is "" then set q to 1
        set screenshotFolder to ("/Users/alexwlchan/screenshots" as POSIX file)
        set screenshots to (get every file of folder screenshotFolder)
        set latestScreenshot to item q of reverse of (sort screenshots by creation date)
    end tell
    search (POSIX path of (latestScreenshot as alias))
end alfred_script

Here q is the argument passed by the Keyword input. If we don’t supply an argument, then Alfred gives an empty string, so we default to using 1, for the most recent screenshot. Then we pass the path to this file as a string to the search command, which opens the image in the Alfred file browser. From there, I can apply any one of my Alfred workflows to the image, although normally I just open it in Preview for editing.

If you like, you can download the workflow here:

Download “Open Recent Screenshots” workflow

You’ll need to set the path for your own screenshots folder before using it, but that’s all the setup it needs.

I’ll be sharing more of my Alfred workflows here in the future. It’s an incredibly versatile app, and I highly recommend checking it out.


  1. Although Mavericks has developed an interesting bug in which new screenshots don’t always show up in the Finder. To make them appear, I have to look them up with the “Reveal in Finder” command in Alfred. 


Thoughts on Overcast

On Wednesday, Marco Arment released his long-awaited podcast app, Overcast. I’ve only been using it for a few days, but it’s already displaced Pocket Casts as my podcast app of choice.

I was surprised by how much I liked Smart Speed. Like Marco (and many other people), I don’t enjoy listening to podcasts played at faster speeds, because the quality takes a nosedive. Smart Speed not only makes podcasts go faster, it makes them sound better for doing so. Conversations are tighter and more coherent, and I already miss the feature when I go back to another app.

Smart Speed alone would keep me using Overcast, but the little details are just as important. Overcast is packed with nice touches and polish. Here are a few of my favourites:

Listing alternative podcast apps

In the Settings screen, there’s a list of Overcast’s competitors (randomly ordered to avoid any bias). Tapping one opens an App Store page for that app.

This is a super classy move on Marco’s part.

Onboarding screen and subtitles

Overcast has the best onboarding screen for any app that I’ve ever seen. When you first launch the app, you’re prompted to create an account, with a prominent link to a Skeptic’s FAQ that explains why a podcast app needs an account. The FAQ is very friendly and well-written, unlike the legalese you often encounter in similar pages.

The next screen, which encourages you to add your first podcast, is really nice as well:

A screenshot of Overcast with a large button 'Add a Podcast' and the subtitle '(Otherwise, this may not be useful)'

There are several other subtitles like this throughout the app: friendly and well-written, they remain helpful without being patronising or annoying.

Normalising RSS feeds

In a list of podcasts, Overcast makes the “author”1 of a podcast fairly prominent.

But not all podcasts list their author list in the same way. There are two prevailing styles:

  • With an “and” between the final two items: e.g., “Guy English and Rene Ritchie” (Debug)
  • Without the “and”: e.g. “Marco Arment, Casey Liss, John Siracusa” (ATP)

In Overcast, the “and” is removed and authors are always shown in the second style, regardless of how the feed is formatted. Everything looks neat and consistent. It doesn’t affect the functionality of the app, but it’s another nice touch.

I don’t know what else Marco is doing to normalise feeds, but this one leapt out at me because the author information is so prominent, and I happen to maintain a feed which does include the “and”.

Update, 25 July 2014

Marco chimed in on Twitter to highlight one other aspect of his server-side normalisation of feeds:
@alexwlchan I’m also stripping common prefixes from episode titles within a feed, so:

Episode 1: A
Episode 2: B
->
1: A
2: B

Overcast (@OvercastFM) Jul 20 2014 9:15 PM

At the beginning of the latest episode of ATP, Marco talked a little more about the server-side parsing, the motivation behind using a server rather than processing RSS feeds client side, and dealing with malformed or incorrect XML.

Granular skip buttons in Control Centre

In the Settings screen, you can set choose how many seconds you want to skip back or forward when listening to a podcast.

What’s particularly nice is when you change this from the default, then look carefully at the buttons in Control Centre (or the lock screen controls):

Toggle screenshots

The text is quite small, but you can see that the buttons are labelled with the number of seconds that will be skipped. (Toggle the screenshot to see blown up versions of buttons.) Those labels get updated to reflect your skip settings.

I was a bit confused that the same buttons weren’t being used on the Now Playing screen in Overcast itself, but apparently that’s coming in a future update.

Sharing links to a specific timestamp

Although this isn’t supported in the iOS app yet2, the website lets you share a link to a specific point within a podcast. For example, I can link to the point in the latest ATP when they started discussing Overcast, half an hour in.

I’d be surprised if this wasn’t in part inspired by Hypercritical and ATP. In the final episode of Hypercritical, John lamented that the amount of followup at the beginning of each episode made it hard to share shows. Telling somebody to skip the followup at the start of the show makes it much more likely that they just won’t bother. ATP has the same problem — a glut of followup at the start of each show.

This is an easy way to link to an episode and skip all the followup. I think I’m going to be using this feature a lot.

Conclusion

Overcast definitely has a couple of rough edges, but overall it’s a solid 1.0. It’s already become my new podcast app of choice.

If you’ve never listened to a podcast before, then I think it would make a good starting point. If you already have a dozen subscriptions, then you might really appreciate the audio processing features.

It’s free to try on the App Store (with a $5 in-app purchase to unlock the full feature set), so I think you should definitely give it a go.


  1. Since the term “author” really means “writer”, I don’t really like using this the term for podcasts, but it’s the term that seems to have been settled upon. 

  2. I think I’ve read that this feature is coming to the iOS app, but I can’t find a reference for it now. 


Getting plaintext LaTeX from Wolfram Alpha

Although I don’t write numerical equations very often, I couldn’t help but smile at this post by Dr. Drang. Building on a post by Eddie Smith which shows how to use WolframAlpha to evaluate a LaTeX expression for a numerical answer, he shows off a way to automate getting the equation from BBEdit, to save a tedious copy/paste step. Read their posts before you carry on.

Dr. Drang’s script gets the LaTeX equation out of BBEdit and loads Wolfram Alpha, but you still need to click the “Copyable plaintext” link. He ended the post as follows:

What I’d really like is to automate the copying and pasting of the answer. Wolfram’s page structure doesn’t make that easy, but it’s something I want to explore.

I tried to parse the Wolfram Alpha page structure in the past, and it was a bit of a mess. It’s much easier to use the Wolfram Alpha Developer API, which provides this very easily. I think I can use this to get the final piece.

If you don’t already have a (free) Wolfram ID, then signing up for one takes about a minute. Then you can register an API key, and make queries in the form

http://api.wolframalpha.com/v2/query?input=\pi&appid=XXXXXX-YYYYYYYYYY

rather than going to the website. This returns an XML object with your results, which saves you unpicking the page structure yourself.

The Wolfram Alpha output is divided into “pods” (which correspond roughly to the rectangles in the web output), and we can pick out the pod which gives the decimal representation of an expression. Within this pod, the plaintext key gives us the text we’d get from the “Copyable plaintext” link. That’s what we want.

I’ve wrapped this in a script, which incorporates part of what Dr. Drang wrote:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
from urllib import quote_plus
import xml.etree.ElementTree as ET

appid = 'XXXXXX-YYYYYYYYYY'

def get_plaintext_query(latex):    
    r = requests.get('http://api.wolframalpha.com/v2/query?input=%s&appid=%s' % (quote_plus(latex), appid))
    root = ET.fromstring(r.text.encode('utf8'))

    for pod in root:
        if pod.attrib.get('title', '') in ['Decimal approximation', 'Definite integral']:
            subpod = pod.find('subpod')
            result = subpod.find('plaintext').text

            if pod.attrib.get('title', '') == 'Definite integral':
                return result.split('~~')[1]
            else:
                return result

if __name__ == '__main__':
    from sys import stdin
    print get_plaintext_query(stdin.read())

You’ll need to add your own App ID in line 8. The URL encoding is handled by quote_plus, taken from Dr. Drang’s script, and then ElementTree handles the XML decoding.

It takes a few seconds to run, but it’s still faster than opening a web page and doing the copy/paste yourself.

Right now it evaluates raw expressions, such as \frac{\pi + \sqrt{3}}{\exp(2)}, and definite integrals, such as \int_0^5 x^2 dx. There may be other forms of input for which this is useful, but I couldn’t think of them when I wrote this.

If we have the plaintext number in a script, then we can also do some nice formatting. For example, if we’re working with currency units, then we might want to trim all but the last two decimal places:

>>> x = get_plaintext_query('\pi')
3.1415926535897932384626433832795028841971693993751058...
>>> y = eval(x.replace('...', ''))
>>> round(y, 2)
3.14

Alternatively, I remember in school being told to round to a particular number of significant figures. Here’s a quick function for rounding to significant figures:

def get_sig_figs(num, n):
    div = 1
    while int(num / div) > 0: div *= 10
    return round(num / div, n) * div

And there are probably plenty of other things you could do with this. But since I don’t work with this sort of numerical equation on a regular basis (yet), I don’t know how useful this would actually be, so I think I’ll just stop there.

This script won’t work every time. Complicated expressions will probably still need a trip to Wolfram Alpha to check that it’s been interpreted correctly, or if you need a different part of the output. But for simple stuff, this should be fine.


Skeletor!

My favourite podcast is The Incomparable, which just posted its 200th episode. It’s always a fun and insightful discussion into the topic, and it’s clear that the panel always really enjoy what they’re talking about.1 I started listening around episode 60, and I’ve enjoyed it ever since.

But if you haven’t listened to the 200th episode yet, look away now. Spoilers!

HOOOOOOOOOOOOOOOOOONK

Towards the end of the epiosde, Jason pulled out two listener clips to continue Steve Lutz’s long-running joke to construct a recursive clip loop of the “patron saint of vaguely threatening TV villains, Skeletor” (Listener Étienne). By picking himself from the previous year’s clip show, Steve hopes to eventually take over the annual clip show (and presumably, the world) with clips pointing back to the original Skeletor reference.

Afterwards, John Siracusa suggested making an image chart to track the progress of the clip loop. Although I’m not very good at illustrations, I decided to have a go:

I’ve made a permanent page to track updates to the clip loop as they come along. I’m not expecting anything new until the 2014 Clip Show, but I’ll be listening carefully, just in case.

And to Steve, Jason and all the other Incomparable panellists: thanks for 200 great episodes. Here’s to the next 200.


  1. The Star Wars prequels and Mira Grant novels aside. 


Catching instapaper:// URLs from ReadKit

I use ReadKit to manage my Instapaper queue on my Mac. Although Instapaper’s web interface is much nicer than it used to be, I still prefer ReadKit for processing lots of items at once. But sometimes I try to open an item in Safari, and I get an error:


There is no application set to open the URL instapaper://private-content/480777221.
Search the App Store for an application that can open this document, or choose an existing application on your computer.

These are items that I’ve added to Instapaper by email, which don’t have a URL associated with them in Instapaper’s database. (Email newsletters are one example.) Instead, the URL refers to an Instapaper database entry, which Safari can’t open. If I was on iOS, an instapaper:// URL would be redirected to the Instapaper iOS app.

But the item does exist in the Instapaper web interface, which can be opened in Safari. It has a URL that looks like this:

https://instapaper.com/read/480777221

(Of course, that link doesn’t work unless Safari is logged into my account, but I always am.)

I wanted a way to catch these instapaper:// links, and redirect to the appropriate item in the web interface without hitting an alert.

I started with this AppleScript:

on open location instapaperURL

    set py_script to "python -c 'import sys; print sys.argv[1][29:]' \"" & instapaperURL & "\""
    set instapaper_id to (do shell script py_script)

    tell application "Safari"
        open location "https://www.instapaper.com/read/" & instapaper_id
        activate
    end tell

end open location

It gets passed a URL, and then extracts the item’s ID with a Python one-liner. (I’d use AppleScript, but jumping through the hoops of AppleScript text delimiters is unnecessarily verbose here.) Once AppleScript has the ID, it constructs the URL for the web interface, and passes that to Safari.

This gets saved as an app, not as a script. When it gets run, it’s supposed to be passed a URL, and then it runs the script above.

So I needed to register the app as able to open instapaper:// URLs. I edited the Info.plist file in the app bundle (right click > Show Package Contents…) to add the following lines:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>Instapaper</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>instapaper</string>
        </array>
    </dict>
</array>

Now any instapaper:// URLs get passed to this small app, which processes them using the script above and opens the web interface in Safari. It’s only a small annoyance, but it’s another little thing that I don’t need to think about again.


Finding untagged posts on Tumblr, redux

One of the most popular posts on this site is Finding untagged posts on Tumblr, but it’s not exactly… friendly. Asking people to download a script and register an API key can look sufficiently daunting that a lot of people probably don’t try.

I wanted a simple turnkey solution. My idea was that people could go to a website, type in their Tumblr URL and click a single button to get a list of all your untagged posts. And now, that exists:

http://finduntaggedtumblrposts.com/

If you go to that URL, then you should get a nice list of all your untagged posts. I hope it’s useful.

If you find any bugs, or a page it doesn’t seem to work for, then please get in touch.

The legal stuff

I’m not affiliated with nor endorsed by Tumblr themselves; I just wrote this because I thought it would be useful, and my existing solution was crummy.

I don’t keep a list of URLs looked up with the site, but I do use Google Analytics to track basic information about visitors. Full details are in the privacy policy.

The technical stuff

Functionally, the site does exactly the same as the original Python script, but I’m using JavaScript instead, so that all the heavy lifting can be done locally in the user’s browser.

About a year ago, I did some work experience with the Cambridge Maths Education Project, or CMEP for short. I was working on a small web app called Mathmo, which is an interactive problem generator for A-level Maths. Mathmo is written with the AngularJS framework, and since that was the last time I did any serious JavaScript, I used the same framework here (although this is obviously much simpler than Mathmo).

All of the source code is in a GitHub repo, and the site itself is hosted (like this one) with GitHub Pages.


Some site updates

If you visit the site regularly, you’ll have noticed that things have changed quite a lot recently. I’ve been meaning to write about what I’ve done, but revision has been getting in the way. Since my exams finished last week, I’ve finally been able to take time to write everything down.

The move to Pelican

The biggest visual change is the new design, which is tied to a big change in how the site is built.

The first version of this site was generated with Octopress, a static blogging engine written in Ruby. I really liked Octopress, but it just wasn’t for me. I also don’t really use Ruby, so my installation is frequently out-of-date or broken, which meant I had to fix that before posting to the site.

As a side project during exam revision, I decided to look at static blogging engines written in Python (which I use on a regular basis, so I always have a working installation). I eventually settled on Pelican, which is fairly lightweight and suits my needs well. As a bonus, it was able to import the Markdown files from my original posts, so everything from the first site carried over near seamlessly.

When I rewrote the site, I also tried to refresh the design. I started with Giulio Fidente’s svbhack theme, and then tweaked until I found a design I was happy with. I made most of the text reader, removed the sidebar, and added this charming shade of red. I think the new design is much cleaner and lighter than the previous site.

At the same time, I switched from using Heroku to using GitHub Pages for hosting the site. I wasn’t unhappy with Heroku; I just found it easier to set up Pelican on GitHub than try to reproduce my existing Heroku setup. As a side effect, a copy of this site is now available as a GitHub repo.

Working DNS. Finally.

I prefer URLs that don’t include the www prefix. I don’t have a good reason; I just think they look nicer.

So when I uprooted the entire site, I tried to drop the www prefix from my URLs, but the change didn’t go smoothly. I didn’t configure my DNS records correctly, so for a long time www.alexwlchan.net URLs would simply fail to resolve. I think I’ve finally fixed this mistake, so it shouldn’t matter whether you include the www prefix or not.

Google Analytics

I decided to install Google Analytics about a month ago, but I didn’t include a privacy policy or any disclosure on this site. That’s a breach of their Terms and Conditions (section 7), but it also feels dishonest. Especially given the recent discussions about privacy in the context of mysterious Government agencies, I feel bad that I was collecting this information without any form of disclosure. I’m sorry for the mistake.

I’ve written a privacy policy for the site. This is linked in the footer of every page, and also on the site’s “About” page.


Some Part IA exam advice

About a fortnight ago, I gave a talk to the first-year maths students1 as part of a session about preparing for exams. For the benefit of anybody who missed the session, didn’t take notes, or future students, I decided to post my notes here.

This is my personal advice, and other people may say different things. And details may change as Tripos evolves; I only affirm that this is correct for the 2014 exams.

Academic

The first section is advice for how to prepare for the exam, and what to do once you’re in the exam. Most of this could be described as “obvious”, but enough people seem to forget it that it’s probably worth restating anyway.

Revision requires quality, not quantity

Some subjects benefit from continuous hours of intensive revision, but maths isn’t one of them. You’re better off doing a few hours of good revision a day – whether that’s Tripos questions, looking at supervision work or reading lecture notes – than doing passive reading into the small hours of the night (more on this below).

Do a three-hour mock

For a lot of IA students, your first three-hour exam was STEP, a year ago. It’s worth doing a couple of timed papers, just to get back into the feel of a three-hour paper, pacing and the like. You could also use this to think about your question strategy.

Look at supervision work and examples sheets

As you look through past papers, you’ll find questions on this year’s examples sheets. Sometimes you get lucky, and ideas from examples sheets show up in exam questions. This is also a good way to make sure you have good coverage of material in the course.

Don’t ignore Section I questions

A lot of people go straight to the harder Section II questions (which unlock more marks), but the Section I questions are worth trying as well. A solid short question may be a better use of time than struggling with a long question.

Personally, I prefer to start off with an easy Section I question. It gives me a good start to the exam, and makes me feel better about going on to tackle a harder question.

Read the rubric

Every year, there are students who misread the number of questions they can do. They do too many questions, which costs them time in the exam (and potentially marks). Read it carefully: it’s printed on the front of past papers, the exam on the day, and I’ve reprinted it below.

Candidates may attempt all four questions from Section I and at most five questions from Section II. In Section II, no more than three questions on each course may be attempted.

Don’t waste time on questions that aren’t going to score you any extra marks.

Examiners are around for the whole exam

If you think you’ve found a mistake in the paper, you can call an examiner and have them check the paper. In most subjects, an examiner is present for the first thirty minutes, but after that you’re on your own. This is not the case with maths; examiners will be present for all three hours.

In practice, there are very few mistakes in first-year papers (normally zero or one per year), so you probably shouldn’t worry about this, but it’s nice to know.

Health

The advice in this section comes partially from my DoS, Dr. Gog, and partially from experience. It’s easy to just focus on revision, and forget to look after yourself in exam term. I stand guilty as charged on that one.

Have regular meals

It’s easy to slip into poor habits with meals (I’m particularly bad for having meals late into the evening). Even if you don’t usually have three meals a day, it’s good practice in exam term.

If you have morning exams, then it’s especially important to have a good breakfast. Personally I’m a scrambled eggs on toast person, but what you have doesn’t really matter; it’s just important to have a good meal before your exam.

Get some decent sleep

Mathmos, like all students, aren’t well known for having a good sleep schedule. But sleep is a key part of “cementing” your revision, and it’s important to get good sleep every night. Like I said above, maths revision values quality over quantity: your nights are better spent sleeping than trying to cram in a few more facts. Doubly so the night before an exam.

Take a break

When you’re working on a tricky problem, you often find that if you step away for a while, the solution becomes obvious when you come back. Your brain works on the problem in the background, but it needs that breathing room to work.

Revision is exactly the same. Sometimes you need to step away and let the dust settle. Taking time to do something other than maths makes the revision really count, and stops you becoming overwhelmed. You should build regular breaks into your revision plan.

Keep perspective

While these exams are important, they’re not the be-all-and-end-all. Getting through your exams with your mental health intact is more important than any grade. Every year, there are people who overwork during exam term, and it hurts their grades and their health. Try to be sensible with how much work you do, and how stressed out you get.

Look out for yourself, and for other people. It’s easier if we all work together to keep our stress levels down. Personally, I find it nice to put aside time with some friends every week where we don’t mention the R or the E words, and remind ourselves that there’s important stuff beyond exams.

If you do find yourself overwhelmed, then you can, and should, get help. Go to a friend, your tutor, your DoS or the University Counselling Service. It’s much better to let stress out than to bottle it up inside and let it gnaw away at you.

Finally…

Good luck with all of your exams!


  1. There’s a session for first-year students to talk about exams about a fortnight into exam term. Since I was the student rep to the Faculty Teaching Committee, I was asked to come along and give a student’s perspective. 


Brief advice for Part II

I got a very nice email this afternoon from a IB student1 pointing out some mistakes in my Linear Algebra notes, and asking if I had any Part II notes that they could study over the summer. Unfortunately I don’t (yet), but I have some thoughts on what you could work on over the summer break. Rather than lock them up in an email, I’m posting them here.

A good starting point is the course schedules, which explain the courses which are available in Part II. If you want something to study over the summer, then a C course is probably a safe option. C courses are supposed to be “straightforward and accessible, and of general interest”, which is good if you’re working through the material on your own.

I worked on Number Theory and Coding and Cryptography over my summer vacation. Both of them are very friendly courses with lots of interesting material. If you’re feeling slightly more ambitious, then the Graph Theory course is also a nice standalone, with some very pretty results. The section on Ramsey theory is particularly fun.

On the applied side, I’ve heard good things about Mathematical Biology2, Asymptotic Methods and Fluid Dynamics, but I haven’t studied them myself, so I don’t know how easy they’d be somebody working on their own over the summer.

Here are some good places for Part II lecture notes:

  • Gareth Taylor’s site has lots of excellent notes;
  • The student reps website a very large collection of links;
  • Quite a few Part II lecturers make their own notes, which are usually posted on their own websites;
  • The Archimedeans have a page of Part II notes, but it’s a bit out-of-date.

You could also get a head start on CATAM (once next year’s questions are posted). There are usually a handful of questions with no specific pre-requisites that you can dive straight into.

Finally, if you want to do extra study over the summer, then you should definitely consult your Director of Studies. They’ll be able to give you much more specific advice about what third year courses you might enjoy, and how you’d be best placed spending your time.


  1. The Cambridge Maths degree has four parts, with one split into two sub-parts. Part IA is first year, IB is second year, II is third year, and Part III is the fourth year (similar to a Master’s degree at other universities). 

  2. Disclosure: the current lecturer is also my Director of Studies. 

Copyright © 2012–14 Alex Chan. Built using Pelican. Privacy policy.