Monday, September 2, 2013

My best computer science students do these things

Recently, I went through a list of every single student I have had over the last 10+ years of teaching computer science to undergraduate students. It brought back a lot of memories (and made me feel very old). I decided to make a list of the things that I have noticed that my best students do.

1. They are hard workers
Ok, this is a really obvious one, lazy people don't accomplish much. In this case, however, I mean that computer science students have to be willing to 'try, then fail, then fix' in order to learn. There are some disciplines like mathematics, philosophy, and economics that a really bright student can learn a great deal by listening to lectures, reading textbooks, attending class, and thinking. They learn by applying their impressive brainpower to a complex topic and somehow all the abstract pieces mysteriously fit together. I am jealous of these people.

Computer programming, on the other hand, is a topic that one can only learn by building. No one has ever learned to be a great programmer by simply listening to great lectures, reading amazing books, or watching Linus or Zuck program. Similarly, no one has ever become a great artist simply by observing Picasso paint or become a great writer simply by reading and rereading Mark Twain (observing skilled craftsmen can certainly help, but it can't be the only learning technique in one's toolbox). Art and writing are also skills that one learns by building. When the students are the ones building all the pieces (code) they never just magically fit together.

Occasionally, I will get an incredibly bright student who has never had to learn by building. A humble student will recognize that there are some topics in which their passive approach will not be sufficient and they will adapt. Others don't adapt and they tend to switch majors. One has to be willing to get their hands dirty and spend six hours looking for an elusive bug or be willing to throw out three weeks of work and start over to make a program better.

2. They are creative
I am truly impressed by some of the creative approaches my students take when solving problems. Even though I have been programming longer than some of my students have been alive I don't intrinsically know the best solution to every problem. Often I will be talking with a student about a problem and I will give them some advice- I will tell them how I'd solve the problem. If there is something they don't like about the suggestion (usually when it sounds like a lot of work) it tends to create a spark in them. This spark might lead to another way of accomplishing the same end result. Their creativity is inspiring to me.

So what do you do if you are not a creative person? What if you were never good at art or don't have great personal style? It turns out that those are not the only ways express your creativity. A creative problem solver uses all of their past experiences and intuition to propose radically different solutions to problems. Often they will 'see' the problem in a different way that allows them to propose a more elegant, simple, and efficient solution. If you don't feel like you are a creative problem solver perhaps it is because you aren't listening to other people's ideas and engaging them with yours. Talking to other developers is often the best way to improve your creativity skills and become a better programmer. 

3. They are curious
My best students are very curious about how and why things work. If I tell a student that one algorithm is better than another without explaining why, the good ones will demand that I tell them why. Sometimes I am unable to convince them and they seek proof. I have had many students write programs to try to prove or disprove something that I have claimed. This is very satisfying for me as a teacher because I know that I can trust this person to always seek the truth.

My best students are also the best debuggers of code. When some of their code doesn't work they need to know why. I will see students debug their programs, sometimes for hours, trying different inputs and going down different paths of the call stack until the find out the 'why'. They then reflect on what they have discovered and burn the reason into their brains so that the next time they won't make the same mistake again.

4. They believe in magic
Ok, its probably not a good idea to believe in magic, but it is good to believe that you are a wizard. From my earliest days programming, whenever I write and then run a program it has felt like magic. Even after I learned that there is no magic happening inside the computer, I still feel like I can conjure up miracles with the spells I write in my editor.

There is something so unnatural about telling a machine to do billions upon billions of operations and have it do them so quickly and without complaint. If this feeling ever goes away I will probably stop being a programmer. I especially like to watch my students make the realization that they too can conjure up miracles. One of the benefits of being a teacher is that students (at least partially) attribute this power to me- that's awesome!

5. They are patient with themselves 
It's hard not to feel like an idiot after spending several hours debugging code only to realize the problem was a simple, easily fixable error. It's hard for some, but not for my best students. For them, finding and fixing any bug is an exciting activity. Not only do they learn something new (or what not to do in the future) but the process of moving through their living code is enlightening. Moving through code validates that everything is working as it should and provides confidence in the program they are building.

Writing complex programs is a difficult task. One should expect to encounter trouble along the way. The best programmers come to expect difficulty and do not get down when it happens over and over again.

6. They are patient with others
I always try to convince my best students to become tutors in the department. Being a tutor means learning how other people perceive programming problems, suggesting ways of looking at the problems, suggesting possible solutions, listening to the feedback about those suggestions, and guiding students towards a critical realization that they can, in fact, solve the problem that was so elusive before. In other words, being a tutor is a lot like being a professor.

I was a tutor in college and I found it fascinating. Without that experience I definitely would not have ended up being a professor. In fact, being a tutor has shaped my teaching style. I have often felt that what I do best as a teacher is talk to students about the problems and make them realize that they can solve them. I try and provide confidence.


Here are some things that unsuccessful computer science students do:
- underestimate how much time is required to 'learn by building' and don't put in the time
- don't talk to other people about what they are doing
- are afraid to ask questions
- insist on figuring things out by themselves
- are unfriendly to their peers
- they don't feel like they need to know why something works or does not work
- don't compile and run their code often enough, they don't get the feedback necessary to eliminate problems as soon as possible and they don't get to feel like a wizard
- get frustrated at themselves for making simple mistakes- it's ok, we all do it!