Waterloo’s Jobmine process and my first co-op internship

May 5, 2014

I just finished my first internship — since it’s my first ever “real” full-time job, I feel it’s a rite of passage of some sort.

The internship, or co-op work term, lasted 4 months from January to April. My position was titled “Software Developer”, and the company I worked for was TutorJam, a small educational startup in Kitchener.

The Jobmine Process

Like most students at Waterloo, I found my job through Jobmine. The process was intimidating at first: the whole slew of resumes, interviews, jobmine cycles, ranking systems, etc, were a lot to take in. But as I brushed up my resume and tentatively submitted a few cover letters, I began to relax a little.

In the end, I applied to 25 jobs (the limit is 50 applications). Most of these were in the Kitchener-Waterloo area, mainly because I leased a house here and didn’t want to relocate. Out of these 25 positions, 5 of them were cancelled before the interview stage. Out of the 20 jobs remaining, I got interviewed for 10 of them.

The interviews came and went, and in the end, 4 of the 10 companies that interviewed me gave me an offer. So I had the good fortune to take my pick between 4 jobs, any one of which I’d be happy working for. I ended up simply picking the job that looked the most interesting.

The Internship

During the 4 months, I worked on a site called YuJa. It’s an “online video collaboration platform”, but I like to describe it to my friends as “kind of like D2L but with lots of videos”. Here’s a picture of the login page of the website:

The team was very small — there were 2 co-op students and 2 full time developers, so essentially we had 4 programmers and 1 manager working on the entire project. As a result, I was entrusted with developing whole features by myself, both the frontend and backend — something rather unusual for a first time co-op.

The project is built with the standard HTML/CSS/Javascript/jQuery on the frontend, and used WildFly on the backend (basically a Java based server). When I started, I was proficient with the Java programming language, but had very little experience with web development (like HTML/CSS/JS). Initially the learning curve was quite steep, but I quickly picked up the skills I was missing.

In the first week, I fixed minor bugs and implemented small improvements, in order to “learn the ropes”. In the second week, I was assigned my first major feature. Essentially it allowed a professor to quickly send a group message to everyone in a class, and the students would receive it by email and SMS. Before the end of the month, my feature was complete.

Here’s a picture of my office (my computer is on the right, the guy on the left is Samson, another co-op student):

There were only the two of us physically present in this room in Kitchener — the company is spread out between several cities across North America. Thus all of our communications were done remotely, via Google talk. Another consequence of this was that in order to keep everyone in the same time zone, we were required to work from noon to 8pm.

Conclusion

All in all, my first internship was a positive experience, as I learned a lot and worked with very smart people. I learned how to work my way around a large codebase, also got a taste of what a startup is like. I suppose the only downside was that there was almost no social activity.

Hopefully I haven’t violated any company NDA by writing this post.

This sums up my co-op experience. Starting this week, I will be doing another 4 month study term (2B Computer Science) until August.


A Simple Shorthand Musical Notation

March 23, 2014

Anyone who’s played piano, or any other musical instrument, would be familiar with the “standard” musical notation. It’s clear, unambiguous, accepted worldwide, and has been basically unchanged since Bach. It looks like this:

Now there’s a reason this notation has survived this long — it’s good. It’s easy to read, and allows a musician to read and play a piece he’s never heard before.

But when you try to write music, you find that the notation is actually quite cumbersome to write. The notes are positioned on groups of 5 lines, so you’d better either have sheets of these lines printed, or be prepared to tediously draw these lines with a ruler. The timing of notes is very precise, so if you slightly exceed the allowed time for a bar, sorry, your notation is not valid anymore.

Principles of Shorthand Notation

To solve these frustrations, I created an alternate system of recording music, with the primary goal of being easy to write. It’s possible to jot down a melody in 30 seconds, with just a pencil and normal (not printed sheet) paper.

I do not claim my notation to be better than the standard notation. Rather, I achieve a different goal, sacrificing information for the ease of writing.

Standard notation is good for recording a song so that a musician can play it without having heard it before.

My notation is good for reminding a musician how to play a song he has heard before.

A common use case would be reminding yourself the notes of a song you’re playing, or accompanying a recording of the song. In a way, its purpose is similar to that of guitar tablature.

Here’s my justification for doing this. Most people can produce rhythm intuitively — that is, after hearing a passage a few times, he can clap back the rhythm. It’s much more difficult to find the correct notes after hearing the passage — I stumble upon it by trial and error.

So if you write down the notes but leave out the rhythm, it would often be enough information to play the song.

The tradeoff should become clear if you compare the same passage written side by side (from Bach’s Minuet in G Major):

Rules of Writing Shorthand Notation

Start by writing the notes in a line, and separate bars with a vertical | line. Indicate the key signature at the beginning of the page, if needed. Feel free to liberally clump notes together or space them apart based on rhythm.

Next is the rule for jumps. When the melody goes upwards by a perfect fourth or more (like from C->F), write the jumped note on an elevated line.

Remain on the elevated line as long as the melody is still increasing or stays the same. But as soon as the melody descends, immediately drop back down to the neutral line.

Here’s an example:

As long as the melody consists of small intervals (like C->E->C), we stay on the neutral line. Only when the jump is large (C->F) do we go to the elevated line.

Typically in music, a large jump in one direction is followed by a small step backwards. This means that we spend most of our time on the neutral line. It’s very rare for a melody to have multiple jumps in the same direction.

Here’s another example (Twinkle twinkle little star):

The melody does a large jump on the third note (C->G), so the third note (G) is on the elevated line. On the seventh note, the melody descends one note from A->G, so we immediately drop back to the neutral line. It does not matter that the same G was on the elevated line before.

You do not always have to start on the neutral line. It might be useful to start on an elevated or depressed line. Here’s an example (Harry Potter):

Reasoning behind the Jump Rule

You might be wondering, why make this jump rule so complicated? Why have a jump rule at all?

Well, we need some way of indicating octaves. Otherwise, a interval like C->F would be ambiguous: are we going up a perfect fourth, or going down a perfect fifth?

On the other hand, if we decreased the jump threshold, say a major third (C->E) is a jump, then the melody would be littered with jumps up and down, which would be a nightmare to handle. Setting the threshold to the perfect fourth is a good balance.

The complexities of the jump rule ensures that when you’re shifting upwards, the melody is actually going upwards. It would be confusing to the reader if there was a situation where we return from the elevated line down to the neutral line, while the melody is going upwards!

Another distinct alternative to the jump rule is to divide all the notes into distinct octaves: for instance, put any notes between C4 (middle C) and C5 on the neutral line, everything between C5 and C6 on the elevated line, and so on. I experimented with this, but found it very awkward when the melody straddles on the boundary between two octaves.

And that’s how the jump rule was created. So please experiment with this system, see if you like it!


Improving the (physical) Bookmark

June 5, 2013

If you’re an avid reader like me, you might have experienced this frustration with bookmarks.

You open up your book to the bookmarked page, but you aren’t sure where on the page you left off. So you go to the beginning of the page and start reading. But soon you realize that you’ve already read this paragraph, and the next…

A minor annoyance, fair enough. But I’d like to share a trick that neatly solves this problem.

Take any bookmark. (This doesn’t work as well if the bookmark has lots of contrasting colors)

Draw a line through the bookmark at somewhere around the 2/3 or 3/4 mark. Do this only on one side.

We’re done.

Now every time you stop reading, orienting and aligning the bookmark stores enough information that you can start exactly where you left off the next time you start reading. Examples:

I’m not sure whether I’m the first to come up with this or if it’s common knowledge elsewhere, but this trick has saved me a great deal of time and frustration. Hopefully you will find it useful!


Fix for Digsby’s Facebook authentication error and broken Facebook support

January 26, 2012

To all Digsby users (ignore this post if you don’t use Digsby):

If you use Digsby with Facebook, you might have noticed that things behave strangely — the program pops up a window looking like this when it tries to connect to Facebook:

Then after you give it your credentials, Digsby still thinks you’re not logged in, and so on.

If you found this page via a google search, there’s a simple hack / workaround you can use to patch up this problem. Basically, instead of using the Facebook protocol to connect, we let Digsby use the Jabber protocol as a ‘proxy’ to connect to Facebook:

  1. Go to Digsby -> My Accounts and in the Add Accounts section at the top, select the Jabber icon.
  2. You should get a window that looks like this:
  3. In the Jabber ID box, put your.id@chat.facebook.com, and in the password field, put your facebook password. For example, if your facebook page is at facebook.com/yourname, your Jabber id is yourname@chat.facebook.com.
  4. Remove the facebook account from Digsby

At this point, you’re done: Digsby should give you no more problems about Facebook.

Warning: the following is unnecessary and experimental! It might screw up the entire Digsby installation, forcing you to reinstall!

However, you can replace the Jabber icon with the Facebook one (this is for purely cosmetic purposes):

  1. Go to C:\Program Files (x86)\Digsby\res\skins\default\serviceicons (that’s the default installation path on my machine, yours may be different)
  2. Delete jabber.png, duplicate facebook.png, and rename it jabber.png
  3. Restart Digsby

There you have it — hack accomplished:


Calling for a new file host for this blog — and how drop.io failed me

March 31, 2011

Back when I created this blog in February 2010, I chose WordPress to host the text of the blog, Imgur to host my images, and drop.io to host all my downloadable files — as a free user of WordPress my abilities to store media directly on WordPress servers are limited. Here’s a screenshot of drop.io in 2010:

So far, WordPress has not corrupted a single one of my posts, neither has Imgur lost any of my many hastily photoshopped images. But some time in December, readers started emailing me telling me that my download links were broken. WHAAT?

Sure enough, when I clicked one of my own download links, all I got was a blank page telling me that their service had shut down last week without notice, and all the files have been deleted. Fml. I thought I could count on you, drop.io!

Well — not exactly without notice. In October, a month before closing down, they announced their closing down in a blog post. If only I had known this before everything was deleted.

I can’t say I’ve ever anticipated that such a popular service suddenly closing down, so I never made backups or mirrors or anything. Fortunately I had most of the files stored on my computer, but at least one or two of the files are lost forever :(

With drop.io gone, I need a new file host:

  • I only upload relatively small files (<1MB usually)
  • They should store files indefinitely (not automatically delete them after 6 months, or a month without 20 downloads, or whatever)
  • I have to be able to link files from my blog
  • Preferably painless (I dislike captchas and 60 second waits but I suppose I can live with that)
I’m thinking of Mediafire, but I’m open to suggestions.

Unimportant people

October 8, 2010

This post is inspired by a series of Facebook discussions.

In this blog post I shall assume importance, interest and notability to mean the same thing. I shall also assume that lists are always well-ordered — that is, of any two elements in the list, one must come before the other.

Claim 1. It is not possible to rank the world’s people by importance.
Proof. Suppose the contrary, that there is a list of all of the world’s people ranked by importance. Then there must be some person at the end of the list (ie, the least interesting person). But this person is at the end of a list, which must give him some notability. Hence this person is no longer the least important person in the world. By contradiction, the list cannot exist.

Claim 2. It is indeed possible to rank the world’s people according to importance.
Proof. We show this by counterexample. Suppose the world has one person. Then there is only one possible list.

Objection 1. Then the list is impossible if the world has more than one person.
Reply. This is untrue. Suppose the world has two people: one person of very high importance, and the other of far less importance. Now we put them in a list. Clearly it does not matter that the less important person is at the end of the list. The same can apply if the world contained 3 people: two people of high importance and one person of low importance: nobody cares that the person is at the end of the list: it is true but that does not remove him from being at the end of the list. This works for 4 people, 5 people, n people, n+1 people.

Objection 2. You have not defined what importance means.
Reply. Importance is usually defined as a combination of wealth, power, achievements, and such. But it does not matter how we define importance. The only requirement is that the definition of importance of a person is affected at least partially by his position on the list: otherwise there is no contradiction.

Objection 3. How is the list constructed, then, if to give a person a rank on the list, one has to already know his position on the list?
Reply. The list can be constructed sequentially – that is, constructed using all factors but the list factor (the position on the list affecting notability). Then the list is rearranged when the list factor comes in and affects the notability. This is repeated until no more conflicts occur.

Objection 4. This is wrong. Suppose that there are three people in the world: one of great importance and two equally boring people. Of the second and third people (the two boring people), one has to be at the end of the list and the other at the middle. Then by the fact that the third person is at the end of the list, he is more notable than the second person, thus going up a place in the list. Then the situation plays out in reverse, forever vibrating between the two states. The list cannot exist.
Reply. Then the list can be constructed declaratively instead of procedurally – like solving a system of equations. If you put the person of great importance in the middle and the boring people at the two ends, then the list no longer vibrates.

Objection 5. But the point is that one person has greater importance than the other two, thus it doesn’t make sense to put him in the middle of the list.
Reply. Then we redefine the definition of importance and notability to be affected only by a person’s position in the list. This way, the list is stable.

Concluding objection. What is the point of such a list then?


My somewhat botched method of solving the Rubik’s cube

August 20, 2010

The Rubik’s cube is a pretty cool and amazing toy, one that I’ve been spending a considerable amount of time playing with recently.

Methods for solving the cube vary. Beginner methods are easy to learn, but the downside is that they’re inefficient, usually taking a hundred moves or more to solve the cube. On the other hand, speedcubing methods often enable the cube to be assembled in fifty or sixty moves, but requires memorization of up to hundreds of move sequences, or algorithms.

The most common speedcubing method, usually called the CFOP or Fridrich method, requires memorization of about 70 different algorithms. Naturally, I didn’t want to do so much memorizing.

I learned to solve the Rubik’s cube from this site, which I think is a very good beginner tutorial. For the rest of this article, I will assume that the reader already solves the cube using this method, and furthermore I will use their notation and conventions. That is, this article would be a sort of extension to the tutorial.

The method provided is basically as follows:

  1. Solve the first two layers
  2. Orient the edges
  3. Permute the corners
  4. Orient the corners
  5. Permute the edges

The site gives 7 algorithms to solve the last layer (5 algorithms plus 2 mirror ones). As a result, any of steps 2-5 may require two sub-steps to do.

Here I provide 9 additional algorithms, making it possible to solve each of steps 2-5 in a single step. This makes a 4-step last layer with a total of 16 algorithms.

I will not be listing the original 7 algorithms: they are already available on the linked site.

Orienting the edges

In this step we want to form a yellow cross, that is, all four yellow edges are oriented so that yellow is facing up.

In addition to the three cases already covered, here’s a special algorithm for the fourth case:

R U2 R2 F R F’ U2 R’ F R F’

Permuting the corners

Next we make it so the corners are in the right place (although not necessarily the right orientation). The usual method for this is switching two corner pieces. However, in one case both corner pieces have to be swapped.

You can apply the algorithm twice, or you can use this algorithm:

L U2 R’ U L’ U’ R L U2 L’

Orienting the corners

Now we want the corners to all be oriented, that is: have yellow facing up on all of them. The only algorithm here that’s really needed is the one that rotates groups of 3 pieces clockwise (or counterclockwise) 120 degrees all at once. Any case can be solved with at most a combination of two of these.

The first two cases are when exactly three of the corners are facing incorrectly. The two algorithms needed are already covered.

Next, there are two similar looking cases where all four pieces are facing incorrectly:

R U R’ U R U’ R’ U R U2 R’

The other case is similar, but a little bit different:

R U2 R2 U’ R2 U’ R2 U2 R U2

There is one case where two diagonal corners are oriented incorrectly:

L B’ D2 B L’ U2 L B’ D2 B L’ U2

Finally there are two cases where the two adjacent corners are oriented incorrectly. Here’s one:

R’ U’ R U’ R’ U2 R2 U R’ U R U2 R’

The other one, which is basically the reverse:

R U2 R’ U’ R U’ R2 U2 R U R’ U R

Permuting the edges

The final step now is permuting the edges. There are two algorithms already, to rotate a group of three edges clockwise (or counterclockwise). The other two cases can be done in a combination of two substeps.

The first one, where edges need to be swapped oppositely:

R2 L2 D R2 L2 U2 R2 L2 D R2 L2

Or the other case where edges need to be swapped adjacently:

R’ U’ R U’ R U R U’ R’ U R U R2 U’ R’ U2

And this is it. We’re done!


Follow

Get every new post delivered to your Inbox.

Join 72 other followers