Exercise Wednesday

Goal: Continue practicing foundational PHP concepts as you integrate testing and Behavior-Driven Development into your applications.

Warm Up


  • How do views with html.twig extensions differ from those with a simple .html extension? Which should we use? Why?
  • What's the difference between var_dump() and echo? When would you use one over the other? How can either/both assist in debugging?

Code


Anagram

An anagram is a word that you can rearrange the letters and it becomes a new word. For example, "bread" is an anagram of "beard". Create a web page, with Silex, where a user can input a single word, and a list of other words that may be anagrams. After submitting the form, the user should be told which of the list of words were anagrams. Start by writing the specs and method first, before you begin creating a Silex webpage.

The array sort method may come in handy, so try it out in the PHP shell to see exactly what it does.

If you finish this, modify your function to handle partial matches - in other words, 'hat' should match 'path'.

Coin Combinations

Have you noticed those coin slides used by modern cash registers that automatically give the correct amount of change? Build a Silex app that lets users enter an amount of cents and shows the smallest number of quarters, dimes, nickels, and pennies needed to make that change. Again, make sure you build the method with good, clear specs first and then create a webpage with Silex.

For bonus points, show more than one coin combination. Start with tests for small combinations and work up from there.

Rock, Paper, Scissors

Recreate the game Rock, Paper, Scissors. For anyone who has never played it, here are the rules:

  • It is played by 2 people. Each person chooses "Rock", "Paper", or "Scissors" by forming a shape with their hand.
  • They choose at the same time, so that each person doesn't know what the other person has picked.
  • If one person chooses "Rock" and the other person picks "Scissors" then "Rock" wins. It's a game of combinations:
Rock v. Scissors = Rock wins
Rock v. Paper = Paper wins
Paper v. Scissors = Scissors wins 
  • If both people choose the same thing, then it is a draw and nobody wins.

Write a method that can handle the different combinations of plays and make sure to write specs for all possible combination of plays. Your method should take 2 inputs - one for each player's choice. It should return "Player 1" if the first input wins, "Player 2" if the second input wins, and "Draw" if nobody wins.

Start by considering all possible inputs and outputs. Then choose the simplest input/output values and use them to write your first spec. Write all specs in english first, and then translate them into test methods and make them pass, one by one. Don't start coding until you've written your english specs, and don't start building the Silex website until all your specs are passing and your method is done.

Then, build a website, styled with CSS, where someone can go to play your game. Make sure you include a README for this project and create a Git repository for it.

Here is a first spec to get you started:

<?php

    require_once "src/RockPaperScissors.php";

    class RockPaperScissorsTest extends PHPUnit_Framework_TestCase
    {

        function testRockScissors()
        {
            //Arrange
            $test_rock_paper_scissors = new RockPaperScissors;
            $first_input = "rock";
            $second_input = "scissors";

            //Act
            $result = $test_rock_paper_scissors->playGame($first_input, $second_input);

            //Assert
            $this->assertEquals("Player 1", $result);
        }
    }

?>

If you get this far, you've done great! Don't worry about getting to the rest of the projects by the end of the day.

Bonus points: Find a way to get the computer to randomly select a 'play' and make your website into a one player game. We don't yet know how to test something that's random, so it's okay to skip writing a spec for that part. Or, you could expand the rules of your game to include 3 players. Make sure to write specs for that before coding. You must understand your goal clearly before you can figure out how to get there.

Find and Replace

Create a website, with CSS, where a user enters a string, chooses a word in that string and provides a replacement for that word. Your method in action could look something like find_and_replace("Hello world", "world", "universe"). The result of which would be "Hello universe".

Do first: Write the method so that it replaces whole words only, as in the "hello world" example above. First, write your specs in english with an input/output example for each one. Then, one by one, create test methods for your english specs and make them pass.

Do second: Add to your method, so that your method takes into account partial matches. For example find_and_replace("I am walking my cat to the cathedral", "cat", "dog") would return the silly phrase "I am walking my dog to the doghedral."

Make sure to account for odd user inputs like all capitalization, partial capitalization, etc. Make sure you include a README for this project and create a Git repository for it.

Palindromes

This one is tricky and will require you to think back to all the methods we introduced to you so far.

A palindrome is any word, phrase, number, or other sequence of characters which reads the same backward or forward. Create a method to identify if a word is a palindrome. It should return true if the input word is a palindrome and false if it is not.

The easy way: There is a method strrev. Check it out in your PHP shell to see what it does. The hard way: Create the method without using the strrev method.

When you are done writing your method and making it pass, build a website, with CSS, where someone can go to check if their word is a palindrome. Make sure you include a README for this project and create a Git repository for it.

Bonus points: Make your method check a string of words and also an integer. For example: "Hello olleH" is a palindrome by our definition. An integer palindrome would be: 101.

Peer Code Review


  • Did you regularly make commits with clear messages that finish the phrase "This commit will…"? You should be committing before and after each spec and after each major code change. Projects that do not document your workflow in this way will need to be redone completely from scratch.
  • Were English specs committed in a text file before any code?
  • Were passing, correctly-formatted tests in place for all behaviors before integrating Silex?
  • Do specs begin with the simplest case and progress in complexity? Do they cover enough different input values?
  • Does the application work as expected?