This weekend I will walk across the stage to receive my diploma for completion
of my Bachelor’s degree in Computer Science from Carnegie Mellon University.
In light of this, I thought I’d take some time to share my experiences, to give a taste of what
the past three years of my life have looked like,
for anyone who may be interested.
General Comments
It’s hard to compare CMU to other universities, mainly because I haven’t attended
any other universities. Instead, I’ll avoid comparisons and just list some
observations:
The campus is great. This was actually a major factor in my college decision
making process. The campus is small, self contained, super well maintained,
and beautiful. Of course, I benefitted from the fact that the CS buildings are
some of the nicest on campus, but it really does apply to the campus as a whole.
I loved the fact that I could just about walk between any two of my classes without
having to be outside for more than 30 seconds, max. This was especially useful during
Pittsburgh winters.
There is a culture of interdisciplinarity (I may have made that word up).
I think just about everyone I’ve met is deeply interested in some subject in addition to
the one they’re majoring in. The founder of Mellonheads, the club for just
about anyone interested in hackathons, is a cognitive psychology major. There’s
a whole degree program for a combination of arts and technology. I think this
is one of the things that makes CMU so interesting
It is stressful. These past three years have, by far, been the most stressful
years of my life, though I haven’t lived many years. Many people will say that
CMU has a “stress culture.” I don’t know if I agree with that; maybe it was true
once, but in my experience, I’ve never met anyone who encouraged others to be
stressed out. It’s not an accomplishment to pull an all-nighter, even though
they definitely happen. Instead, what I will say is CMU teaches you how to deal
with the stress. Or at least, it taught me. Though I’m proud to say that I
made it without ever pulling an all-nighter (for school work), and fairly consistently getting
7+ hours of sleep per night. That said, I didn’t have much of a life outside
school.
Coursework
I’ve taken so many interesting classes at CMU. I’ve invented a languge, I’ve
written an operating system from scratch, and I’ve built super cool robots. To
avoid going on for too long, I’ve chosen a few particularly interesting/difficult
courses that I feel are representative of the coursework here at CMU.
Principles of Imperative Computation (Freshman Fall)
This was my very first CS class at
CMU. I took it with Tom Cortina, who is an absolutely wonderful professor and
human in general. This class is basically an intro to “C” (In quotes because most
of the class is taught with a safer derivative of C called C0) with the very Carnegie
Mellon-twist of focusing on proving correctness of programs. The class introduces
the concepts of preconditions, postconditions, loop invariants, and basic
data structures like stacks and queues. It’s probably equivalent to most colleges’
intro CS courses, but with a greater focus on correctness and proofs. I ended
up TAing this course for a year which was a lot of fun.
Great Theoretical Ideas in Computer Science (Freshman Spring)
HERE WE GO. This is that course. The hard course. The one where exam averages
are in the 50s and no one except that one kid that sits in the front actually
knows what the hell is going on. I took this class with Ada and O’Donnell (also
really great professors). The bulk of this course is CS theory: Turing machines,
finite automata, graph theory, etc. It doesn’t go too deep into any one topic,
but given that most of the people in the class have no experience with any of
it it feels like being thrown into the deep end. The problem sets consistently
took 12+ hours a week. It sucked. Coincidentally, this class is also how I met
the person who would become my roommate for the next 2 years. The shared misery
brought us closer together.
Operating System Design and Implementation (Junior Fall)
This is widely touted as one of the most difficult CS courses at CMU. It is one
of several that fulfills the Systems Elective requirement of the curriculum, so
many people don’t take it. I couldn’t resist, however, and I regret nothing. The
semester I took it, the course was taught by Dave Eckhardt and Dave O’Halleron.
This course is composed of roughly 4 major projects, the largest of which being
the design and development of a multi-threaded Unix-like operating system from
scratch. I think I learned more in thise course than I did in any other CS course
at CMU. The biggest takeaway for me was that nothing is magic under the hood
of operating systems. I won’t claim to know how everything works, but I have
a much better understanding of how it could work, because I did it. Another
great benefit of taking this course is that my debugging skills are easily 10x
better than they would have been without it. For anyone at CMU reading this
and trying to decide if they should take this course, you should. It will
make you a better programmer.
Introduction to Robotics (Junior Spring)
This is one of the required courses to graduate with a minor or additional
major in robotics (I did the minor). It is taught by Howie Choset. I have
many negative things to say about this class. For one, I think it tries to
do too much and therefore accomplishes very little. The scope of the class
is broad: path planning, computer vision, localization, mechanical design,
kinematics, and more are all covered in the semester. As a result, you only
get a very high level overview of any particular topic, and don’t really
learn as much as I’d like. In addition to the theory portion of the course,
there are weekly labs that involve building robots to accomplish various tasks
using the Lego NXT kits. Some of my group’s robots are shown below:
Most of the difficulty of this class comes from the short deadlines caused
by the extreme breadth of the course. It is a time consuming and very frustrating
class but not a particularly intellectually stimulating one. That said, the
TAs do an excellent job at making the course a little bit less miserable and
are perhaps the course’s single redeeming quality. Playing with Lego is also
fun, but not for 15 hours a week.
Extracurriculars
Planetary Robotics Lab
One of my main reasons for attending CMU in the first place was because it
boasted a high number of undergraduates involved in cutting edge research, and
I wanted to be a part of that. Just a couple of weeks into my freshman year,
I started reaching out to professors about potentially working in their labs.
I was lucky enough to get a response from Red Whittaker who is famous for many
things, such as leading the CMU team to victory in the DARPA Urban Challenge.
When I met Red, he invited me to participate in the Planetary Robotics Lab,
which was working on an extremely small lunar rover in pursuit of the Google
Lunar XPrize. During my three years working with Red, I went from a novice
just trying to wrap my head around all the work being done to leading the
Avionics/Software team on three iterations of the rover. This was perhaps
my most rewarding experience at CMU. I learned so much, and now, when some
iteration of the rover lands on the moon in a few years time, I can say that
I was a part of it, which I think is pretty cool. Below is a video showcasing
Tetramorph, the first rover I worked on. It’s not shown in the video, but it
can actually fold up and fit inside a 30cm cube and then deploy itself to
the form shown in the video.
TAing
Something else that is unique at CMU (at least based on what I’ve heard about other
universities) is that
students make up the majority of the course staff for core courses. I was a
Teaching Assistant for Principles of Imperative Computation for two semesters,
along with about 15 of my peers. As a TA, I held regular office hours and
lead recitations along with hands-on labs. This was super rewarding for a
multitude of reasons.
I had the opportunity to make a serious impact on others’ experience at CMU.
I would often have students come in to office hours frustrated by a bug they’ve
been working on for hours or not quite grasping a lecture concept, and I got
to help them work through it until it clicked. That alone is an awesome feeling.
I was able to encourage them and help them deal with the stress, and I’d like to
think that I was able to significantly improve at least once person’s experience
in the course.
I got an inside look into how a typical course is run, and what the hiccups
or difficulties are. This made me appreciate all the courses and teachers I’ve had
in my life because now I know that grading, and teaching in general, isn’t as
easy as I thought.
You don’t really understand something until you have to teach it. When I took
the class, I passed with an A, but I learned so much more from teaching than I
did from taking the course. Being the first class on data sturctures and algorithms,
increasing my mastery of those topics will definitely help me in the long run.
FOCUS
FOCUS is the Fellowship of Catholic University Students. I’ve been Catholic my
whole life and immediately sought other like-minded students on campus. What I
found were 4 dedicated missionaries who invited me to join bible studies, participate in discipleship,
and just hang out with other Catholic students at Carnegie Mellon. I think without
this connection, I could have had a rough time not just in my faith life, but
in my every day life. The Catholic community at CMU provided a solid group of
friends and a sense of community that I don’t think I would have had otherwise.
Recruiting and Internships
One thing I didn’t really expect going into CMU was the extent to which major
companies recruit on campus. The moment that sticks out the most to me was during
finals week my freshman fall when Microsoft hired professional masseuses to
give free massages to CS students. This is an extreme example, but almost every
other week there is some company set up in the CS building offering T-shirts or
cookies or coffee, or other random swag in exchange for resumes or conversation
with a recruiter. After my freshman year, I applied to several companies including
some bigger ones (Google, Microsoft) and some smaller random startups, but didn’t
get any offers (I got interviews for about half). After my sophomore year,
I applied to fewer companies, but got an offer from every
company that gave me an interview: Google, JPL, and Narrative Science. I
ended up accepting JPLs offer and spent the summer working on path planning
algorithms for the Mars 2020 mission.
Regrets
Some things I planned on doing as an incoming freshman never panned out. This
is a list of some of those things:
I never attended PennApps. Hackathon culture at CMU is huge, and I was really involved
for a year or so, serving on the board of Mellonheads, the primary club for all
things hackathon. Despite this, I never made it to PennApps, the world’s largest
collegiate hackathon. The reason for this is mainly that I could never convince
myself I had the time to go. My weekends were precious for getting work done,
and it was hard to give them up. I did make it to a hackathon hosted by CMU on
campus, which I’ve written about,
but I never made it to “the big leagues”
I never painted The Fence. The Fence is a tradition at Carnegie Mellon. In the heart
of campus, The Fence has been painted hundreds of times by the students. On campus
organizations “take the fence” to promote upcoming events or just for fun, completely
covering the structure in a layer of paint between the hours of midnight and 6am.
Unfortunately, this was a tradition that I never got to be a part of.
I never participated in Buggy/Booth. Carnival is pretty much the only “party weekend”
for CMU. THe weekend is filled with fun including Buggy, in which teams
race their aerodynamic vehicles at high speeds around campus, and Booth, in which
campus orgnanizations build large, often multistory structures for viewers to
walk through and admire. It’s a fun weekend, but participating in either event
is a huge time commitemnt and my time was precious.
All in all, most of these come down to me not wanting to give up my time. I’d
urge those who come after me to be less of a Scrooge and have a little fun. You’ll
regret it if you don’t.
Life After College
I graduated from CMU in 3 years and acquired about $90,000 in student loan
debt. I accepted a job at ASV Global where I’ll
be working as a software developer for their autonomous boats. I
ended up with ASV for a variety of reasons, not least of which being that
they have an office back in my home town of Lafayette, Louisiana. I’ve been
wanting to go home for a while now to be around family, and the cost of living
is also much, much lower compared to Silicon Valley. The downside is, of course,
my salary is lower compared to what I’d be getting in Silicon Valley,
but that’s a small price to pay for the comfort of being at home.
All in all, I’ve enjoyed my time at Carnegie Mellon. I hope this has given
some insight into what life is like there for prospective students or others.
With this chapter of my life closed out, I look forward to the many adventures
that lie ahead, knowing that Carnegie Mellon has prepared me well.
As hinted in my last post I’ve recently
started work on a game. I intend to make this the first of a series of devblogs
chronicling my work on it. Today, I’m going to give a brief rundown of what the
game is (or how I imagine it) and the current state of the prototype I’ve been
building.
Fleet
The working title for the game is Fleet; it’s a bit of a mixture between chess
and Hearthstone with spaceships and RPG elements. Here’s how it works:
Before a match/out-of-game each player maintains his/her “fleet” which is a
collection of ships. Each ship has a pilot and some items. Pilots have some
stats, right now Precision, Accuracy, and Evasion, which control Crit Chance,
Hit Chance, and Dodge Chance, respectively. A ship’s items are things like
weapons or shields or even signal jammers that can be used in game. Pilots’ stats
or weapons can be upgraded out of game with some sort of currency that’s earned
by winning/participating in games.
Each ship additionally has a class which determines things like how many
items it can have, how much health it has, etc. For example, “Jumper” class
vessels can move around really quickly, but have low health and only one item
slot.
In game, every action (moving, using an item) consumes a portion of the ship’s
energy. A fixed amount of energy regenerates at the end of each turn.
Once in-game, the object of the game is to destroy the opponent’s mothership
before they destroy yours. The mothership will be at a fixed location opposite
your own mothership and can be damaged with weapons like any other ship.
Overall, I want the game to be simple-enough for anyone to jump in after a tutorial
and I also want it to be very open to casual play. However, I also think the
strategic elements make it a prime candidate for serious/competitive play.
I always planned on launching for desktop first, but had hoped I’d be able to
open it up to mobile as well (I’ll be developing in Javascript so that’s particularly
easy) but I’m starting to think that the amount of information necessary to
play will be hard to fit on a mobile screen. That’s a ways off though.
Prototyping
So here’s the problem: I am terrible at prototyping. I’m the type of person that
enjoys the design and architecture part of software development probably more than
the actual implementation. I’d rather spend 10 days designing the perfect API rather
than designing 10 iterations every day. This is almost always a bad thing; iteration
is crucial. One article that I found particularly interesting against the idea
of premature-abstraction was
Casey Muratori’s post on “Compression Oriented Programming.
The idea of not abstracting until you need an abstraction, rather than abstracting
in anticipation of needing it, makes a lot of sense to me, even if it isn’t
exactly what I’ve been taught.
So here’s my progression from being very bad at prototyping to being slightly
less bad at prototyping. When I started working on
this game, the first thing I started working on was the server
networking architecture. And I spent at least an hour just designing it. This
was terribly unproductive for a few reasons:
Networking is genuinely very hard to get right
Networking is not as fun as the actual game
Networking won’t tell me whether or not the game is fun
I can’t get easily get feedback on the networking without also having developed
the game
A lot of these realizations came after having watched
Extra Credit’s excellent video on “MVP”
I ended up scrapping a lot of what I had done and
started working on a purely client-side implementation. The games would be between
a human and an AI player so I wouldn’t have to worry about anything server-side.
The next hiccup I encountered was the UI. The nature of the game pretty much
requires a fairly hefty UI to represent all the information you need and allow
you to take action appropriately. I originally had started out trying to do it all
on the canvas, trying to roll my own basic layout library before I caught myself
and searched for a better solution. I was working with web-tech anyway, so why
not just use HTML for the UI for now? Within about 20 minutes I had a fully
functional UI thanks to my existing HTML+CSS experience. That allowed me to
finally get to work on the important stuff: gameplay.
Current Status
The gameplay is going well, and I have a few ideas for posts in the next couple
of weeks about interesting things I’ve done so far. Currently, the game supports
the following:
2 unique weapons
Deploying vehicles from the hanger
Moving vehicles on the board
Using items
Fully functional UI to do all of the above
Turn-taking
An example of current gameplay is shown in the GIF below. The blue hexagons are
ally ships, and the red is an enemy ship. The green bars on the left side of hexes
represent health and the yellow represent energy.
Against my best wishes because the codebase is a mess, I’ve forced myself to
put all the code on GitHub in its current state.
Try not to look at the client code because it’s a mess. The game folder is a bit
better and more interesting.
Issues & Next Steps
I have these ordered based on how important I think they are, so if you think
I’m wrong please let me know!
Very basic AI; just enough to test more interactions
Add “win” conditions so you can play a game to the end
Allow users to customize their fleet (this actually might not be necessary in the prototype)
Add support for status effects/items other than just weapons
Improve AI to make it somewhat formidable
At this point, I’d say it would qualify as a “game”. From there, I’d need to
add art, begin adding multiplayer, add much more content & items, etc. One step
at a time.
I hope you enjoyed my first devblog; hopefully there will be many more to come.
Until then, let me know what you thought on
Twitter (@ganashaw).See you next time!
I’ve never really been one for New Year’s resolutions. Part of it is probably
that I’ve always been fairly comfortable and complacent with my life that
making any drastic changes has seemed entirely too inconvenient. As you’ve
probably surmised from the title, I’ve had a change of heart. My hope is that
by writing them down, even if no one else reads them, I might feel a tiny bit
more obligated to stick to them. Hopefully, in 365 days I’ll have a new post
to say that I actually completed them all.
1. Write More
I’ve had this blog for quite a while now (3+ years) and I have 6 posts, including
this one. That’s pretty pathetic. I think writing or at least keeping some sort
or journal is a fairly productive thing to do. Especially with respect to
technical aspects, I think writing about projects helps to review your work and
think about ways you could have done things better or differently. Assuming
someone reads what you write, it also provides a means of receiving feedback
which is invaluable. I think the most important consequence of writing about
projects is that it forces you to justify your decisions. The more detail you include, the
more you have to rationalize each decision you made. I hypothesize that this
will make me a more deliberate, careful developer since if I make bad decisions
I’ll then have to tell the entire internet about how I made terrible design choices.
2. Develop and Launch a Game
Every two months or so for the past several years, I get an overwhelming desire
to develop a video game. This typically results in me coming up with a
half-baked idea, spending an inordinate amount of time to come up with a
clever name, spend about a week tops coding up a prototype without finishing and
then abandoning the project altogether. My goal for 2017 is that I actually
follow through on one of these projects and “finish” it. Besides just developing
a game, I want to maintain a devblog, promote the game on social media, and do
all the things a typical indie developer would do. I don’t plan to go into gamedev
full-time any time soon, but I think there are a lot of skills that I can learn from
hobby gamedev that will help me in other aspects of my career. The gamedev bug
has bitten me again so I’ve currently got something in the works; with any luck,
the first entry of my devblog for that project will be out this week.
3. Read More
I’ve always vehemently abhorred reading. I don’t know why. I found it tedious and
boring. I still do, but now I recognize that it’s actually kind of a good thing
to do. Especially in the software development field, there is a ton of literature
written about how to become better at the craft. I’d like to read a few of these
books. At the top of my list are:
I’d also love any fiction suggestions to throw into the mix. I’ve read and loved
the entire “Hitchhiker’s Guide” series by Douglas Adams.
4. Increase My Faith
2017 will be the first year in which I’m not a student, seeing as I’m graduating
in May (woohoo!). A consequence of this is that I’ll no longer be held accountable
by others (e.g. religious educators, FOCUS missionaries) with respect to my faith.
It will be completely up to me to nurture and increase it. My goal for 2017 is to
accomplish this. The exact method isn’t clear, but I know I want to grow
closer to Christ and He wants to grow closer to me.
So that’s it. My four resolutions for 2017. Feel free to hold me accountable on
Twitter (@ganashaw). Hopefully, I’ll be back in
a couple days with a devblog for my latest project.
I’m definitely an idea guy. I have ideas all the time. I think that most of them
suck, but the thing with ideas is that there’s no way to know if they suck unless
you execute them. Generally, when you have an idea you want to make a prototype
as quickly as possible so you can decide where your idea falls on the scale of
suckiness (or greatness, if you’re lucky). But like I said, I’m an idea guy, not
an execution guy. Executing is hard. Whenever I sat down to try to prototype an
idea one of the major roadblocks for me were graphics. It seemed like any low
level (aka powerful) language required lots of external libraries and gross stuff.
It was a pain, for me and probably for many others. So ugly is my attempt
at fixing that. I dreamed up ugly as a universal graphics library, a graphics
library that could be used on any machine, with any language, really quickly.
And I think I succeeded.
Goals
Starting out, I had a few goals in mind when making ugly:
Good revision history
I wanted to force myself to make small, frequent commits. This has a two-part
purpose. One, by keeping the commits small, it’s easier for me to make progress
because it takes less time to make that little change here or add some safety
checks there. Secondly, it makes it easier to track down bugs. If I don’t
notice a bug right away, it’s easier to go back in the history to find out where
the bug first occured, and since the commits are small, it’s usually very obvious
what change introduced the bug.
(There’s also a third advantage: it makes writing project-recaps like this much
easier)
Finish it
I had a really bad habit of not finishing projects. I wanted to finish ugly.
And I did. And I’m proud of myself for it. (Ironically, this blog post took
me several months to finish…)
Planning
So I wanted to make ugly language and platform agnostic. That means it had
to be written in a language that everyone had. And what does every computer have?
A web browser. So I decided to make ugly with Javascript, doing all the
rendering in the browser. Unfortunately, there’s really no good way to get data
from a user’s machine to a Javascript front-end without introducing a server,
so I built a server implementation in node.js to forward data from the client
to the viewer. The interface was fairly simple: The client program or whatever
needed to be rendered writes data to the node.js server via stdin. The server
would validate incoming commands and then forward them to the browser-based
renderer using websockets.
At this point, there were a few things I wasn’t certain of. I was mainly worried
about the latency that would be introduced by introducing the node.js
middle-man. It was important that the rendering happen as close to realtime
as possible. However, as I couldn’t think of a better way to achieve what I
wanted, I decide to go ahead and try it out.
Execution
Note: This is pretty much me narrating my commit history. Yay version control!
Making connections
I started out just having the node.js server read lines from stdin. I then
introduced a basic logging module to handle logging to a file and/or stdout
and stderr. Next I cooked up the code for serving the rendering-client where
the actual drawing would happen and forwarded the lines read from stdin to the
client via websockets. At this point, all the connections were made and I just
had to add the logic.
Protocol
The next thing I had to do was define the format in which ugly would expect
incoming commands to be. I decided on a fairly minimal syntax:
command_name arg1 arg2 arg3 ...
I also introduced the concept of ‘chunks’ which grouped related commands:
There would be two types of chunks: CONFIG chunks which would define settings
to be used throughout the render and FRAME chunks which would define the
drawing commands to be used for a single frame.
Validation
I decided that the server would be responsible for validating the commands so
that the client could assume it only received valid commands. The less
non-drawing work the client would have to do, the better. As I started writing
validation code for the commands, I realized that this was going to get real
gross real fast. I essentially had a block of code that looked like
And I planned to have well over 30 commands. I decided to split out the commands
into their own module. Each command be an object with a validate function.
This way the server, could simply query the command module, get the command,
and call its validate function:
For one, this made it a tad bit easier to add commands (I didn’t have to add an
extra “if” branch for each command), but it also turned out to make executing
the command easier on the client-side.
(Note: in the end, instead of having
a validate function for the whole command, I had a validate function for each
argument, but this is a minor implementation detail; the gist remains the same)
Rendering
Once the command was validated server-side, I sent the full plaintext string to
the client via websocket. Here, I once again leveraged my command module. In
Javascript, suppose you write a function like so:
Conveniently, you can also access and execute this function like
The key here being that the function is identified by a string. That meant
in my command module, I just needed to save the string representation associated
with each frame command. Additionally, I needed to get the arguments. This was
again easy because the arguments my plaintext command took were exactly the same
taken by the Javascript function. So I could apply all of my frame commands
in exactly the same way; all that changed was the data.
Putting It All Together
To give you a better idea of how the commands are actually processed, I’ll trace
the execution of one all the way through. Here’s an example of how the
clearRect command is represented in the command module:
And here’s how that command would be provided:
$FRAME
...
clear_rect 0 0 100 250
$END_FRAME
The server would first read in the full string (line 3 in the code block above).
It would then take the first “word” ('clear_rect') and search for it in my
commands module (which would return the objct in the firstcode block above). From
here, the arguments of the plain text command would be validated. To do that, it
first sends all four parameters (0, 0, 100, 250) to the FLOATparamType,
since it is the paramType of the first parameter in the parameter list. That parameter object
would validate it and return whichever arguments it didn’t use. In this case,
the float parameter uses only the first parameter so it leaves 0, 100, and
250 (parameter types don’t always consume just one argument; a color param-type
for example consumes four: r, g, b, a). The remaining parameters then passed to the
next parameter objects until they are all validated. If no errors are encountered,
that command is sent to the client.
When the client receives the command, it again looks up the clear_rect object.
It then asks each of the command object for the Javascript value type.
For example, for a paramTypes.FLOAT, passing the string '3' would return
the value 3. This argument list is then used to call the function:
And we’re done! Feel free to read through the code to see it in action.
Final Thoughts
So that was the basic design and structure of ugly. I’m very pleased with the way I
was able to cleanly separate the data (the commands and their arguments) from the
execution. The amount of code reuse in this project is really quite impressive
in my opinion.
I think the most exciting thing about ugly was when I got the first (and as
of yet only) pull request. Just a few hours after posting the project
on Reddit and HackerNews, someone submitted an example that used ugly to
visualize Conway’s Game of Life. It was super neat to see someone using code that
I wrote. That alone made the whole project worth it.
If ugly is something that sounds useful to you, go check it out on
GitHub. As always, pull requests are welcome!
Last year while I was looking at perspective colleges, and even once I had decided
on CMU, I was very interested in the student perspective; what it’s like to actually
be a student at Carnegie Mellon. Surprisingly, there was very little available
aside from the standard student life page on each university’s website. Seeing
as I’ve completed roughly a semester and a half now, I thought I’d go ahead
and contribute for anyone who might be interested in that sort of thing.
About Me
Since a significant portion of the post will be subjective, my background is probably
relevant as it definitely shapes my expectations and opinions of things. First
things first, I’m a freshman studying computer science. Before college, I spent
three years at The Louisiana School for Math, Science, and the Arts
a public school for high-achieving highschoolers in Louisiana. LSMSA is actually
situated on a college campus, and most of the classes are taught by college
professors at a college level; about 90% of my teachers had a terminal degree
in their field of study. As a result, I had already experienced a lot of what
is often lumped into the “college experience.” Namely, I had spent three years
living relatively independently in a dorm, I was being taught at a college level, and I was
being exposed to a truly diverse group of people; much more than an average
highschool. I point this out mainly because these are all aspects which may
have a significant impact on one’s college epxerience, but they weren’t for me,
so I probably won’t talk about them as much. Additionally, I’m one of the most
introverted people you’ll ever meet (if you ever meet me..) so I can’t comment
much on the social scene at CMU either.
First Impressions
As a freshman, your first real look at CMU will be during orientation week.
I mean sure, those summer tours are great, but they don’t really give you a feel
for the campus and student body. Before anything else, you have to move in. I must
say, the orientation staff make this absolutely painless. I got out of my car,
they told me to go do some logistical things like get my ID and some CMU swag,
and by the time I got back my stuff was already at the door of my room…on the
third floor. Already, I’m digging this place. The week continued pretty much
as expected, awkward ice breakers, cool performances and shows, crowded meals,
and lots of walking. As an introvert, a lot of the week was uncomfortable for me;
I suspect that that’s the case for a lot of CMU students, especially computer science
majors. I didn’t really end up with a close-knit group of friends like many people
seemed to; however, that’s not for lack of opportunities, and probably more
for lack of me trying/knowing how.
After orientation, I got my first experience of real college life. A few classes,
surprisingly not terrible food, and a pretty substantial amount of homework.
My first class was Matter and Interactions I, which is described as the “Honors Physics”
course at CMU. I felt compelled to take this course for a variety of reasons.
First of all, without it I would have been carrying “only” 40 units of classes.
(For a freshman, the maximum is 55 and the minimum is like 35, I think) Despite
having been accepted into one of the most prestigious schools in the world, while
I was scheduling my classes I for some reason still felt the need to “prove” myself.
To justify my presence. I thought that the best way to do this was to take
as many hard classes as I possibly could. As if somehow I was being a slacker
if I wasn’t taking the maximum number of units every semester. Within about two weeks, I gravely
regretted my decision. One of the most dangerous traps that I fell into during
that first semester (and still do to this day) is making the assumption that
because my computer science classes are super hard (and they are), all of my
other classes are super easy. (and they aren’t) Matter and Interactions kicked
my ass and the ass of just about everyone else in that class. It was hard, and
it took up a lot of my time. And the worst part? I don’t think it really even matters.
I mean, I’m not a physics major, I have no intention of getting a degree in physics.
I could have taken the intro physics class and my graduation requirement would
have been just as fulfilled, recruiters probably wouldn’t have known the difference,
and I would have had more time to spend doing things
that did matter, like my CS classes, side projects, and research. More on that later…
The Grind
Eventually, I got into the groove of things and developed a pretty routine schedule.
I had class every day til about mid-afternoon, went to Gates and watched Netflix until
5, grabbed dinner, worked on any homework due the next day, played video games,
and went to sleep. On the weekends, I spent my Saturday afternoons playing video games
or working on side projects and my Saturday nights (about 8pm-1am) working on problem sets because I honestly
didn’t have anything better to do. Typically I could finish about half of my week’s
work on Saturday nights. On Sundays I went to my research meeting and worked on that
for a few hours, then worked on homework until a meeting for the FSAE team at 6:30,
before having dinner, going to mass, and going to bed. This was how just about every
week played out. Honestly, it wasn’t that bad, aside from the inevitable frustration
over my math assignment, I was pretty satisfied. Still, it seems as though this
pattern of routineness is inevitable; or at least I haven’t found a solution.
This semester is pretty much the same except I have a lot more work. Great
Theoretical Ideas for Computer Scientists (15-251) is, according to many, one of the most
challenging CS courses students are required to take at Carnegie Mellon; I easily
dedicate 6-10 hours per week just working on the homework not to mention attending
lectures and “homework writing sessions.” (don’t ask…)
Now, don’t get me wrong, I’m not complaining. When I decided to come to CMU, I
expected to be pushed harder than I’ve ever been pushed before, and to get my
ego taken down a few pegs. Both of those events occurred within about a week.
The grind isn’t bad…in many ways it prepares you for the real world, for a job,
but it is a grind nonetheless and it can wear you down. On the brightside, to counteract
the grind, CMU students, especially CS students, are presented with loads of perks
that make the grind worth it.
The Perks
Carnegie Mellon University has one of the top computer science programs in the
country. Naturally, there are benefits. The first that I noticed was just how
eager companies and recruiters are to talk to you. I remember sitting in Gates
(the computer science building) one afternoon and a company’s recruiter came around
the study area handing out cookies and flyers for a tech talk that
evening. Maybe it’s just me, but that blew my mind. Companies really really
want to hire you. Even as a freshman, it’s pretty normal for students to get
summer internships at Google, Amazon, Microsoft, etc. as well as smaller startups
working on really cool things.
Another huge perk is the caliber of the faculty working here. World famous professors
in any field are normal, professors working on things that could truly change the
world. And the best part? They’ll let you work with them. I knew coming into
Carnegie Mellon that I wanted to get a taste for doing research, so I started
looking at professors doing cool things. I eventually found Dr. Red Whittaker.
He’s done some pretty freaking cool things like
building an award winning autonomous vehicle,
and leading the pack for the Google Lunar XPrize.
I walked into his office one day and asked him if there would be room for me to
work in his lab and within a month (he’s a busy guy) I was writing software
for a 30cm x 30cm x 30cm experimental lunar rover. Opportunities and perks abound
at CMU, and I’ve done my best to take advantage of them as much as possible.
The Journey Continues
I’ve only been here for about 6 months now, so I’m still figuring stuff out, but
I’ve definitely learned a lot already. I’ve learned that I don’t need to be the best
at everything. I don’t even need to be the best at anything. In fact, there’s
probably many people better at me in just about everything. The best I can do
is my best, so that’s what I’m going for. One step at a time, the journey continues,
and so far it’s been totally worth it.
It seems to be more and more common for students to brag (or complain, regret)
about how little sleep they got the previous night. It definitely happened at
my highschool and it’s even more prevalent here at CMU. Fortunately, I had been
lucky enough to never have to pull an all-nighter…until last weekend when
I participated in my first ever hackathon here at CMU. TartanHacks 2015 was a
blast and probably one of the most enjoyable all-nighters I’ll ever experience.
Pre-Hack
It started like any other Friday: classes until 2:20, research meeting at 2:30,
bible study at 4:00, dinner at 5:00. Then things got exciting. I waited in line
for about 5 minutes, obtained a wristband, and proceeded into the auditorium.
I met up with my group and we listened to the sponsors brag about their sweet
prizes (read: badass drones, cash money) and convince us that we should use their
APIs. Then, we rushed to get dinner (after securing our hack spot of course).
The wait for dinner was absurdly long and unfortunately we lost about an hour of
valuable hack time, but in the end it turned out not to matter.
Commence H4cking
Our idea was pretty simple: craigslist, but for rentals. A platform that would
allow students to rent out their un(der)used items to fellow students. As simple
as it was, it still turned out to be a lot of work. One thing our group struggled
with was the division of labor. All the inner workings seemed pretty connected
that it didn’t really seem possible to work in parallel. As a result, most of the
coding ended up on me while my peers helped me scope out potential APIs and other
logistics. I didn’t mind, but I felt kind of bad that I got to have all the fun.
This is definitely something I’d like to improve upon in the future.
I think I wrote the first line of code at around 8:30pm Friday night and I had
finished a somewhat working application around 9:30am Saturday morning. Luckily
I didn’t run into any significant technical challenges throughout the night; I
really had a ton of fun. Something about bringing a project from nothing to..
something in such a short period of time was really rewarding. It really affirmed
my education/career/life path. Programming is truly something I love.
The Expo
After hacking had officially ended on Saturday night, there was an expo for everyone
to show off the things that they made. To say I was blown away would be an
understatement. There were devices made of card board to help the visually impaired
see in 3D. There was an augmented-reality version of Asteroids. There were so
many things I never would have thought of and yet I wasn’t surprised at all.
Hackathons seem to really bring out the most intelligent, creative, awesome people.
The kind of people that you just know will be successful.
My team’s app, shown above, didn’t win, but I wasn’t really disappointed. We got
some awesome feedback and I had a ton of fun. I was absolutely exhausted and I
think I slept for about 14 hours the next day, but it was so worth it. It is
definitely an all-nighter I’ll never forget.
Almost all programmers that I’ve talked to are huge proponents of open source
software. Recruiters avidly encourage job applicants to contribute to open source
software because they love to see it on resumes. Until a few days ago, I had never
contributed to any open source project other than my own. Finding myself terribly
bored one weekend, I decided to change that. So this is a brief summary of my first
contribution to open source software.
Step 1: Find a Project
This has almost always been the hardest part for me. Ideally, you want a project
that doesn’t have a huge codebase already. Less code makes it easier for you to
contribute right away. However, you also want your contribution to matter. The
incentive to contribute to an obscure command line utility that only works on
Ubuntu 10.02 is minimal at best. I used Github to explore interesting projects.
There are also websites that pick out Github repos with the most “issues” but
the problem with that is that most of these projects have literally 1000s of issues.
That can be pretty intimidating for a newcomer. Luckily, I stumbled upon a neat
little Javascript library called TheaterJS.
The appeal of this project was three-fold:
It was written in Javascript, a language I’m fairly familiar with
It’s codebase was small and condensed. Everything was in a single file of about
400 lines
The owner had included an explicit TODO list at the bottom of features he’d like
to add but hadn’t gotten two yet. A perfect place for a rookie like me!
Step 2: Write Some Code
After I had found this project and settled on how I would contribute, I forked
the repo and got to work on my solution. This should be the fun part, and it was.
I did my best to maintain the same style as all the other code that had been
written, even if I didn’t agree with it (spaces are inferior to tabs, people).
Aside from style issues, I made sure to avoid making any unnecessary globals
to avoid polluting existing code. Overall, I made sure I wrote quality code,
just like I would if I were working on my own project.
Step 2a: Test Your Code
I can’t think of anything more embarrassing than submitting a broken pull request,
so I made sure to thoroughly test my code after it had been fully integrated.
I found a few bugs, fixed them, tested some more, washed, rinsed, and repeat until
I was confident I had flawlessly implemented the feature.
Step 3: Submit a Pull Request
Finally, I submitted my pull request and waited for the owner’s response. At first,
he briefly looked at my code, said it looked good and that he was testing it locally.
Score! A few hours later he came back and told me he was experiencing a bug with
part of my implementation. Much to my dismay, there was indeed a bug in my code.
Luckily, I was able to fix it in a matter of seconds. I committed, pushed, and
waited for his response. After that, the owner and I had a brief discussion about
what different parts of my code did, and then he merged it with the existing repo!
Now, anyone who uses his library will be using some code that I wrote, and I
think that’s pretty cool.
Hopefully, this is the first of many contributions to open source software. It’s
definitely a satisfying experience that I would recommend to any programmer.
I just recently finished developing an adaptation of the classic “Lights Out”
game. For those of you who aren’t familiar, the object of the game is to turn
on all the lights on the grid. Whenever you toggle a light, all 4 adjacent lights
would also be toggled. In my version of the game, Lights, the same rules and
objective apply. However, some lights are “directed” meaning when you toggle them,
only the adjacent light(s) in certain direction(s) are toggled, which increases
the difficulty of the game. The game itself has some fairly interesting nuances
to it. Firstly, the order in which you toggle lights doesn’t matter. Assuming
you start with a board configuration A, if you toggle light 1 and then light 2, this
is equivalent to toggling light 2 and then light 1. Also, somewhat obviously,
tapping on the same light twice (or any even number of times) is the same as not
tapping it at all. Likewise, tapping a light an odd number of times is the same
as tapping it only once. What this mean is every solvable board can be solved by
tapping a subset of lights only once. Pretty nifty.
Design and Structure
I have a really bad habit of over-engineering my code. I actually started this
project last May, but I didn’t get very far. I started looking at the code again
about a week ago and was pretty overwhelmed. It consisted of about five
different classes that did somewhat obscure things in very obscure ways. I started
by pruning away almost all of the existing code, and began working in a single file.
Surprisingly, this made my code more readable than when it was split up between
classes. It was easy to follow the code which greatly aided debugging. I think that
having everything in one place will also make it easier to maintain (to a point).
I’ve always had a thing about making my code “look good” and to me, long files always
failed to achieve this. However, I’m starting to see the beauty of consolidating code
and replacing lots of little classes with lots of little functions.
As far as the design of the game, I’m actually pretty happy with it. One
aspect that I didn’t like was the fact that I couldn’t find a way to add multi-directional
arrows without cluttering the design. If you play it, you’ll notice that arrows
are always either up/down or left/right. Never both. There’s nothing difficult about
this from a programming standpoint, but I absolutely could not find a way to
elegantly add it to the design. I’m not too upset about this, but I never really
like when form gets in the way of function. Perhaps a better designer than I could
come up with a solution.
Development
The development process went fairly quickly, which is a first. I did get to play
with a few things that I hadn’t before, though. For example, this was the first
time I had ever used CSS3 transitions, and boy are they cool! It made the Javascript
so much simpler to have all of the animations handled by CSS. I know I’m barely
scratching the surface but I can see now why people have been so excited about
them.
I also got to work with cookies to keep track of users’ best scores. The way Javascript
handles cookies is very interesting for me. Cookies are stored in document.cookie
as a “string.” I put string in quotes because there’s some sort of voodoo going
on behind the scenes. Namely, when you define a cookie, it’s generally of the form
name=value; expires <UTC DATE>. You then assign this value to document.cookie.
But what if you want multiple cookies? Well, you do the same thing. But you only
specify one at a time. So, as an example, the following snippet would store three cookies:
What gets to me is that it looks like we’re assigning to document.cookie each time, but it never
gets overwritten. Furthermore, if we were to then read document.cookie, we would see
What happened to the expiration dates?! Your guess is as good as mine. What made
cookies really annoying is that there doesn’t appear to be a way to test cookies
using the file:/// protocol, which makes local development very difficult. (As
an aside, Google Chrome supposedly has a flag to enable file cookies, but I couldn’t
get it to work).
Takeaways
I think the biggest thing I gained from Lights was finally finishing a project
and releasing it to the public. I don’t think I’ve ever done it before and it’s
a really good feeling to finish something and be satisfied with it. I would deeply
appreciate any feedback you may have, you can contact me on Github or via email.
At the moment, my best score is 31. Can you beat me?