Here is my work for Exercise 48.
My code: on github.
I duplicated the project skeleton directory made in Exercise 46. Then, I changed all instances of NAME to ex48. I created a lexicon.rb file in my ex48 directory. In the test_ex48.rb file, I added a require ‘./lexicon.rb’ on the very first line. (Note the ./ is needed because we are in the tests directory and need to go one level up first.) I ran rake test, to make sure the require line was working.
In tests_ex48.rb, I created a test_directions function that takes no parameters. I typed line 6 of the code, assert_equal(Lexicon.scan(“north”), [[‘direction’, ‘north’]]) and then went to my lexicon file. From this assertion line, I knew that the class Lexicon needs a scan class. I added a class Lexicon with an empty scan method in the lexicon file. *Note* if you simply write def scan() end, this creates an instance method. We want to use scan as a class method (Lexicon.scan), so we must put def self.scan() end! Then I ran rake test, the assertion failed. Good.
The failed assertion will tell you the expected result versus the actual result. Knowing what’s expected, I then wrote the code for the scan method so it would return the actual result. It is important to start with a failed assertion, so that you don’t get false-positives. (Make sure it fails, then when it passes, you know it didn’t just pass to begin with.)
I added one assertion, ran the test and saw it fail. Then added code to make it pass. Then I added another assertion, ran the test and saw it fail. And repeated… until all the assertions in the example returned true and the tests all passed.
- Improve the unit test to make sure you test more of the lexicon.
I added a test_combination method to test strings containing all the types of elements. I also added west to the test_direction function.
- Add to the lexicon and then update the unit test.
I added more verbs, nouns, and stop words to the lexicon. I added these scenarios to the test cases in the unit test. I also wanted to play around with names, so I added name as a category to the lexicon. Then, I added a test_names function that would check to see if the names were categorized correctly.
- Make sure your scanner handles user input in any capitalization and case. Update the test to make sure this actually works.
When I check to see if an array of words contains a word element, I use .include?(text_element.downcase), my lexicon’s word list only has lower case words so this will compare the elements and find matches regardless of the input’s capitalization. I do not use downcase! because I still want to return the word element categorized in its original capitalization.
- Find another way to convert the number.
Another way to convert the number is to first strip any leading zeros with .sub!(/^0+/, “”). Then you take the string and convert it to an integer with .to_i, then back to a string with .to_s, and check if it’s the same as the original string(with the leading 0s already removed).
- My solution was 37 lines long. Is yours longer? Shorter?
Longer… 55 lines. 😛
In this exercise, I used test-driven development for the very first time. TDD is useful for when you know what you want to do with the code but you’re not sure how to implement it. In this exercise, we knew the output that we wanted, but we didn’t know how to go about it. So, first we write a unit test that fails, then we write pseudo code with what needs to happen, and then we write the code. After writing the code, we run the test and make sure it passes.
It is important to start with a failed test, so that you do not get false positives. A false positive would be when you think your code passes the test, but the test already passed to begin with!