Anyway, my friend introduced me to exercism.io, a tool that helps you improve your skills through “crowd-sourced mentorship”, created by Katrina Owen. (Actually, I’m not entirely sure what it is, because their website doesn’t explain it that well. Hopefully it will make sense once I start using it.)
##Setting up Exercism.io on Windows
I logged in using my GitHub account. Easy enough. The welcome page explains how it works:
- “Fetch the current exercises using the command-line client.”
- “Write code using your usual tools. Make the tests pass.”
- “Submit the code to the website. Other people who have completed the same assignment provide a code review, ask questions, and discuss trade-offs with you.”
Sounds good to me! And their list of GitHub issues indicates a pretty active community.
So I need to install the command line interface (CLI), which I heard can be trickier on Windows, so I’m feeling a little bit nervous right now. Luckily, they have detailed instructions for Windows. So, first I need to check if I’m on a 32-bit or a 64-bit version of Windows. (I don’t even know exactly what the difference is, to be honest!) But it looks like I’m on 64-bit Windows.
Downloading the latest release for 64-bit Windows…
Copying the executable file from the zip file into a new folder…
Now, what’s all this stuff about adding it to my
PATH? Like I’ve mentioned before, I’m still very new to using the command line, so I thought I should read up on this a bit first.
“PATH is an environment variable on Unix-like operating systems, DOS, OS/2, and Microsoft Windows, specifying a set of directories where executable programs are located.”
That helps a little, but I sense a very deep rabbit hole here… I don’t want to dive into learning all about the guts of operating systems just yet. Well, I do want to, but I need to stay focused on the basics first!
Following their instructions, I’m backing up my
PATH variable by typing this into the command prompt:
Oh wait, I’m stupid! I don’t type the first part, haha. Oops. And I obviously need to replace the date with the actual date, so I type this:
Seems to have worked; I have a new text file in my users folder. I opened it up, and it seems to contain a list of program locations, including where I installed Python and Ruby a while back. Cool!
The instructions warn me that if I skip a step, I could break my computer or something. Better be careful! Oh, actually, this is super simple, basically just a copy-paste into a Systems window. Done!
Now, let’s see if it worked…
Success! And I didn’t even break anything! OK, that was actually very easy. Hearing from multiple people that installing stuff like this on Windows is “a nightmare” just made me really nervous about it. I probably wouldn’t have written about the process in detail if I knew it would be this straightforward.
Next, I configure exercism using my API key from their website:
(I did learn a while back that you’re not supposed to type the
$, only the other stuff. lolz.)
Yay, I think it worked! So I guess this means that I should be able to run test files using that Jasmine framework now. But first, I need to actually download the files for exercism’s practice problems. It looks like all I have to do is this:
Cool! It created a new folder for me. I’ll use the
cd command (which stands for “change directory”) to move into
bob_test.spec.js, which I assume is the file for the test framework.
Hmm, it looks like it’s broken…. Oh right, but that’s the whole point! I’m supposed to write some code in order to pass the tests. So of course it says the test failed:
OK, so I need to make the tests pass. How do I do that? What are the tests? Why is it set up this way? And who in the world is Bob?!
##Test-Driven Development (TDD)
Whenever you don’t know what something is, go to Wikipedia!
“Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: first the developer writes an (initially failing) automated test case that defines a desired improvement or new function, then produces the minimum amount of code to pass that test, and finally refactors the new code to acceptable standards.”
I also like this description from An Introduction to Test Driven Development:
“Not only does this process prove that the emerging code correctly satisfies tests (essentially that the code is fit for purpose) but it aids developers in thinking about the design of the code they write.”
“In addition, tests by their very nature, provide valuable documentation. The tests grow to form a catalogue of how the software should behave…”
In fact, he describes TDD as a way to fight “entropy” in code – the way little inconsistencies and moments of laziness add up over time to create “spaghetti code”. (I didn’t know was a real term! That just tickles me, haha.)
Anyway, I just spent some time searching the interwebz for a mroe detailed and beginner-friendly guide to test-driven development, but so far I haven’t found anything really good. (If you know of any, let me know!)
But I did find some other resources that look useful but seem too complicated for me right now, so I’ll dump them here and come back to them later:
- The Failures of “Intro to TDD”
- Is TDD Dead?
- A free O’Reilly book: Test-Driven Development with Python
- Behavior Driven Development (BDD), a synthesis of TDD and ATDD, which is short for Acceptance Test Driven Development (whatever that is!)
I guess I’ll just dive right into the first practice problem from exercism.io and learn about this whole TDD philosophy as I go along.
##First Attempt at Making a Test Pass
The following notes won’t make any sense unless you’re following along with the exercise files! You can see the files on their website here:
OK, here we go! So I don’t know why this works, but I can infer from the code that
bob_test.spec.js is testing the function
bob.hey() and expecting the result to be
'Whatever.' when given the input
And then in
bob.js, I’m supposed to define the
bob.hey() function so that it returns the expected result when given that input:
This is the laziest (and most efficient) way to pass the first test, because it gives the expected result of
'Whatever.' regardless of what the input is. It will probably fail the other 16 tests, but let’s see if it worked for the first test. I’ll run the test again:
Now, following the instructions to submit an exercise, I’ll type this:
Cool, it says my submission can be viewed online here! I added a comment explaining that my solution is the simplest, most efficient way to pass the first test.
##Onto the next test!
I realized I didn’t know how to move onto the next test, so I did a little digging. This page gave me a clue (though I wish they made it more obvious!):
“Some of the languages use skipped or pending tests in order to simulate the Test-Driven Development (TDD) process.”
“In these languages, only the first test will be active. Once you write enough code to get that test passing, you’ll need to open up the test suite and edit it to remove the skip to activate the next test.”
And how do I “remove the skip to activate the next test”, I wonder? A little Googling took me to Jasmine’s introduction page, which revealed that the
it() function I saw in
bob_test.spec.js is used for active tests, and the
xit() function is used for pending or inactive tests. That’s the key I was looking for! I took a look in
bob_test.spec.js again and sure enough, the other 16 tests all use
xit(). So all I have to do is remove the
x and I should be able to run the other tests one at a time or all at once.
Cool, now I’m onto the second test. But this could take forever if I try to make the code pass one test at a time! Looking ahead at the other tests and the README file, the pattern seems to be something like this:
- Shouting: If the input is in all-caps, the result should be ‘Whoa, chill out!’
- Questions: If the input ends in a question mark and it doesn’t meet the criteria for “shouting” listed above, the result should be ‘Sure.’
- Silence: If the input is empty or contains nothing but spaces, the result should be ‘Fine. Be that way!’
- Whatevs: For everything else, the result should be ‘Whatever.’
I’m going to let my ideas percolate while I walk to tonight’s meetup group, and then I hope to work on the problem with a buddy or two while I’m there. I should be able to solve this before bedtime, I think!
Useful stuff I’ve found so far:
- String object reference page
- chartAt() method - returns a single character at the specified point in a string
- substring() method - returns a subset of a string between one index and another
- trim() method - removes whitespace from a string
- toUpperCase() method - returns a given string converted to uppercase
Luckily for me,
toUpperCase() also works on special characters that represent letters with accent marks! So this should work for all 17 tests in this exercise, some of which contain letters with umlauts.
So I think it should look something like this:
Now, for identifying questions, I just need to check if the last character in the string is a question mark. For that, I could use the
charAt() method or
substring() method. I’m not sure if it matters which I use, but it seems like
charAt() is simpler, so I’ll go with that:
And now fo identifying silence, I think that
trim() method will do the trick! Something like this:
Now I’ll throw it all together and see if it passes all the tests! Here’s my code:
// silence: if input is empty or contains nothing but empty characters
And here’s the result:
Oh right, numbers! There are two tests for inputs with no letters:
'1, 2, 3' which should have the result
'4?', which should have the result
'Sure.' I guess I need to check if the string contains letters, because these special cases need to be handled by different rules.
Let’s see if that worked…
BOOYEAH! I win! Haha, OK, it’s almost my bedtime so I’m going to submit my solution and see if I get any feedback on it here. Goodnight!