Exercise Monday

Goal: Focus on understanding the BDD process - how to break down a problem into smaller, more manageable chunks.

Warm Up


  • What process should we follow when designing our specs?
  • Why should we use plain-English specs when we begin our specs?
  • Explain the process of turning a spec into a test.

Code


Each spec that you write should be describing input and output without any concern for how to do it. Remember to think of the interface before the implementation.

And then, once the problem is solved according to the requirements of your specs, it should be smoother when you actually build the interface in Silex.

Title Case

Follow along with your weekend homework to create a Silex website which changes a sentence from the user into title case.

  • As always, start by creating a new Git repository. Remember to make plenty of commits as you work.
  • Start with the PHPUnit lesson. Create the folder structure, including src, web, and tests. Then create your TitleCaseGenerator.php class declaration file inside of src and your test file TitleCaseGeneratorTest.php inside of tests.
  • Create your composer.json file in the top level of your project folder as usual. You can start by just including PHPUnit for now. Run composer install. Then while you're in the Terminal start your server in your web folder - now you've got that out of the way.
  • Then focus on writing your specs before writing any code. Write plain English versions of your specs first, in the order you'd implement them. Include the chosen input and desired output for each spec. Get a teacher's approval before you start writing code.
  • Now translate each plain english spec into a test method, and make it pass by filling in your makeTitleCase method. Only work on one spec at a time.
  • It's a good idea to take turns writing and implementing your specs with your pair. If you wrote the first spec, your pair starts out writing the code to make it pass. If your partner wrote the spec, then you drive for a bit and try to write the code to make it pass. You'll often have to work together on actually writing the code to implement a spec, but you can take turns making the initial stab at it.
  • When you are finished, all of your tests should pass and your method should take any string as input and return a modified version of it in title case. Google the specific rules of title case if you want clarification.
  • Now follow along with the lesson on using PHPUnit with Silex to use your TitleCaseGenerator class with its new method in a website. When you are finished, have a teacher look at your code before you continue to the next problem.

Ping-Pong with BDD

Let's do the Ping-Pong problem from your Epicodus applications again, but this time we will work through it using BDD. Then your goal is to use Silex and Twig to create a website where the user enters a number into a form on the first page. When they submit the form, they should be taken to a second page printing out all the numbers from 1 to the number they entered. Except: numbers divisible by 3 should be replaced by "ping", numbers divisible by 5 should be replaced by "pong" and numbers divisible by both should be replaced by "ping-pong".

  • We will start by thinking about what classes and methods we will need to create for this website. We will just make one class called PingPongGenerator and it will only need one method called generatePingPongArray.
  • The method should take one input argument - the number to count up to.
  • It should return a numerically indexed array holding all the numbers and words to print out in order.
  • Just as before, write your plain english spec descriptions first, in the order you would implement them, including your chosen input and desired output for each one. Then get a teacher to check them before you start coding.
  • Then write each test and make it pass.
  • After your class and its method is done, add Silex and Twig to turn it into a website. When you want to display the answer to the problem, pass the array returned from your generatePingPongArray method into a Twig template and then use a foreach loop to display it as an unordered list.
  • When you are finished, have a teacher look at your code before you continue to the next problem.

Leetspeak

Leetspeak uses an alternative alphabet of numbers and symbols to replace various letters in words.

Write a LeetspeakTranslator class with a method called translate which converts a string into a simple version of Leetspeak using the following rules:

  • The letter "e" should be replaced with "3".
  • The letter "o" should be replaced with "0".
  • The capital letter (not the lower case), "I", should be replaced with "1".
  • All instances of "s" should be replaced with "z" UNLESS it is the first letter of the word.

Here is a final sample input and output: In: "Don't you love these 'String' exercises? I do!"
Out: "D0n't y0u l0ve th3z3 'String' 3x3rciz3z? 1 d0!"

Code tips:

There will be 2 arrays - an array of the letters from the original string and an array of letters after they have been checked and modified where appropriate.

Each letter in the input array of letters will need to be evaluated and then pushed to the output letter array.

Finally, the letters after being checked will need to be returned from the method as a joined string.

Here are your steps for this, and the following two problems:

  • Write plain english specs of each behavior in the order of simplest to hardest. Get them checked before moving on.
  • Create your class declaration file and your test file. One by one, write each of your test methods and make them pass by writing the code for your translate method.
  • Create a Silex app using Twig templates to allow a user to enter a string to run through your LeetspeakTranslator's translate method.

Queen attack

In chess, a queen can move horizontally, vertically, and diagonally, making it the most powerful piece on the board. If another piece is within its line of sight along these three lines, then the queen can attack it.

Here is the end goal: We're going to make a website in Silex where the user can enter an X and a Y coordinate for the queen, and an X and a Y coordinate for another chess piece which the queen is attacking.

When the user submits the form, you should create an instance of a Queen class, with properties for its current X and Y coordinates. This Queen class should have a method called canAttack, which takes an X and a Y coordinate as arguments.

The method should return true if the queen can attack the given space and false if it can't. A message should be displayed to show the result after the form for filling out the coordinates is submitted.

Remember to write your tests in plain english and get them checked first. Don't be tempted to write a single test for the true case (e.g., it 'is true if it can attack horizontally or vertically or diagonally') - there are three separate behaviors here for horizontal, vertical, and diagonal. Also remember to try to refactor or simplify your code as soon as you get something working.

Clock angle

Time for something a little more complicated. Let's write a Silex site that tells us, given a certain time, the distance in degrees between the minute and hour hands on an analog clock. It should use a Clock class with a method to take a time of day as input, and return the number of degrees for output. For example, 12 o'clock would return 0º and 6 o'clock would return 180º. Always return the smaller distance and be as precise as possible. As with the previous exercises, start with your tests and your class, then when you're sure your method works, build the rest of the website around it.

Peer Code Review


  • Are there plain-English specs written for each user case?
  • Does each test accurately reflect the plain-English spec?
  • Look for tests that build on each other incrementally. Does each test look for new behavior?