Rock..Paper...Ugly If-Else Statements!
Today I paired with Daniela, who I think I met up with the most times before the program started (we share a fondness for beer) and who is, in my opinion, one of the brightest members of our cohort. My code and my learning benefitted in all kinds of ways from working together with her today, but there was one instance in particular that really struck me.
Learning to code well is about way more than just learning the "correct" syntax to express a problem. There are too many different problems and too many different ways of solving each of those problems to come up with a comprehensive reference of code solutions. Creating elegant code is a matter of learning to think in code as a language, a concept I touched on in a prior post, and a skill that I'm still in the earliest stage of refining.
Daniela, on the other hand, is a bit further along in that capacity (I credit her former life as a middle school teacher). For one of our challenges today, we had to assign our partner a problem to work on as practice writing 'pseudocode' a language-agnostic set of instructions for building a program. I assigned Daniela a two-player story creator game, and she assigned me rock, paper, scissors.
Rock, paper, scissors pseudocode:
https://gist.github.com/3838300
After an hour or so of working on our solutions, I was feeling pretty good. Building on Shereef's advice yesterday, I tried to pay really close attention to keeping all of my methods light- 3 lines of code or less- and creating many of them and linking them together. I ended up with this:
https://gist.github.com/3838308
Now, the astute among you, and probably even the non-techies, will notice that the outcome method, the heart of the logic of determining whether the player or the computer wins, is a bit longer than three lines. About seven times longer, to be exact. I couldn't conceptualize a way to simplify this logic, which first has to identify the player's choice and then identify the relationship between the player's choice and the computer's choice, into anything simpler.
I showed my code to Daniela, and she came up with a fantastic solution. I'll show it to you before I explain it so you can try and make sense of it yourself:
https://gist.github.com/3838304
Got it? Yes? No? I'm going to explain it regardless just so I can hammer the concept into my own head one more time. Here's how it works: combination_hash represents the series of winning combinations. Scissors is paired with paper, paper with rock, and rock with scissors. So how does this work?
We access the combination hash using the player's decision as the key, which means that the value returned by the hash is the losing pair to the player's decision. Then the ternary operator (if/else statement) checks to see if that value is equivalent to the computer's decision. For example: if the player picks scissors, the combination hash will return paper. If paper == the computer's decision (if the computer chose paper), the ternary operator returns "win".
Now what happens if you don't win? We have to determine whether you drew or you lost. To do that, we nested a second ternary statement in the first's "else" branch. This time, we access the hash using the computer's decision as the key (again, returning the losing pair to the inputted choice) and see if the returned value is equivalent to the player's decision. If so, the computer wins, if not it's a draw!
This refactoring decreased the length of that method from 23 lines down to 5, but it's about more than just the physical size of the program. The refactored version is simply more elegant than a bunch of nested if/else statements, and I think learning to conceptualize problems under these terms is a major part of becoming a better coder.
On another note, Steve Huffman, the co-founder of Reddit and Hipmunk, came and talked to us for our first Thursday night speaker series. He talked a lot about what coding as a craft means for him in terms of the kind of attitude, practices, and knowledge he expects from job applicants. Although it can sometimes be overwhelming, I really appreciate that our environment forces us to maintain a dual consciousness focused on both the micro and macro steps toward becoming programmers. On the one hand we're faced with micro-level Ruby challenges- figuring out methods to make pig latin or return prime numbers, and getting a basic understanding of all the different methods. On the other hand (Steve's talk was skewed toward this end), there are macro-level concepts like how the computer actually performs all of these methods, how a server works, or even how the internet works!
There's so much to learn, and on that note, I'm going to bed. I felt my brain shutting off after wrapping up the pig latin problem and decided to leave "early" at 9pm. Time to enjoy a few extra hours of sleep.


















