FizzBuzz Rules Overview 0:00Now that you've made your way through a bunch of katas in this series, hopefully you're beginning to see that it's not as difficult as you thought. For example, one of the first katas that many people do, that we didn't, but many people do the fizzbuzz kata. It's not too challenging, but it does a great job of getting you into the mindset. So now, to see just how much you've learned, let's work through this fizzbuzz exercise, and you'll see how incredibly easy it really is. Okay, to make sure that we're all on the same page, here's your quick review. Don't worry, it's very easy. It's an old children's game to help you learn about division. So they sit in a circle, and one by one, they count up. 1, 2, 3, 4, 5, etc. But now, if the number that you speak is divisible by 3, like 3, 6, 9, 12, etc.,So they sit in a circle, and one by one, they count up. 1, 2, 3, 4, 5, etc. But now, if the number that you speak is divisible by 3, like 3, 6, 9, 12, etc., then you say fizz instead of the number. Next, if the number is divisible by 5, then you say buzz instead of the number. So in this case, we have 1, 2, fizz, 4, buzz. 6 is divisible by 3, so we replace that. Then we have 7, 8, fizz. And then 10 is divisible by 5, so you say buzz. 11, fizz, 13, 14. And now 15 is divisible by 3, and it's also divisible by 5, so we would say fizzbuzz there. And that's it. There's nothing more to this game than the rules I just showed you. Okay, so now, our job is to reproduce this using test-driven development and phpspec. Let's get into it. phpspec.describe. Within our Acme namespace, we call it fizzbuzz. Okay, let's run our tests. It will offer to create the production class, and if we run it again, First TDD Spec Setup 1:42and phpspec. Let's get into it. phpspec.describe. Within our Acme namespace, we call it fizzbuzz. Okay, let's run our tests. It will offer to create the production class, and if we run it again, we're at green, so I'm going to boot up Gulp here. Let's open this up, fizzbuzz, and let's get started. What is the simplest thing that we can check for? Well, what about when we feed it 1? What should that return? Well, 1 is not divisible by 3 or 5, so we just return the number. Okay, it translates 1 for fizzbuzz. So if we say this, and why don't we call the method execute, and I pass it 1, well, I expect that to return 1. That's the easiest possible test we can write. And of course, it fails. So if we take a look, there's no execute method. That's our next step. Switch over. Add our execute method. Save it. It still fails. So now, we expected an integer, but we got null, so we just slime it. Return 1, and we're back at green. Awesome. Let's do anotherSwitch over. Add our execute method. Save it. It still fails. So now, we expected an integer, but we got null, so we just slime it. Return 1, and we're back at green. Awesome. Let's do another one. What if we give it 2? Well, that should return 2 as well, right? Let's run it. It fails, so we make it pass. If this will accept the number, number equals 2, then we're going to return 2, and green. Now, let's do another one here. If we translate 3, well now, that is divisible by 3, so we should return fizz, and let's make a pass. Maybe we'll do one more round of this. If the number is 3, then return fizz. Save it, and there we go. But maybe now, we can do a quick bit of refactoring, because as we've learned, if the number is divisible by 3, return fizz. If it's divisible by 5, return buzz. Otherwise, just return the number, which means I should be able to do this, return number, and we should still get green. Awesome. Well, next, we know Add Buzz and Modulo 3:44If it's divisible by 5, return buzz. Otherwise, just return the number, which means I should be able to do this, return number, and we should still get green. Awesome. Well, next, we know that 4 is fine, so why don't we switch over to 5? If we translate 5, that's divisible by 5, so we should return buzz. Okay. Duplicate this. If the number is divisible by 5, we return buzz, and we get green. Okay, what about 6? We know that one is divisible by 3, so that means it should return fizz, and it fails. So again, what is the easiest thing we can do? Well, if number is 3, or number is 6, then return fizz. So now, you get the basic idea. Let's do a second layer of refactoring. If the rule is, if the number is divisible by 3, then return fizz, then we have a mathematical way to represent that. If number modulus 3 equals 0, and if you're not familiar with this, think of that as the remainder. If the number we feed it is 9,then we have a mathematical way to represent that. If number modulus 3 equals 0, and if you're not familiar with this, think of that as the remainder. If the number we feed it is 9, then 9 divided by 3 is 3, with nothing left over, 0. But if it's 10, 10 divided by 3 is 3, with 1 left over. So, when you see the percentage sign there, just think of it as, what is left over? If nothing is left over when you divide by 3, then the number is divisible by 3. Return fizz. And we can do the exact same thing for 5. Like so. Let's run it, and we're back to green. Excellent. So that means we don't even have to check for things like 10. Let's run it. 10, and that should return buzz. That's already being handled at this point. But now, what about something like 15? Okay. Well, remember, 15 is divisible by 3 and 5, so that should return fizz buzz. But it fails. So, how do we fix this? And this is where a lot Handle FizzBuzz Case 5:47what about something like 15? Okay. Well, remember, 15 is divisible by 3 and 5, so that should return fizz buzz. But it fails. So, how do we fix this? And this is where a lot of beginners kind of get messed up. They end up trying to use some kind of concatenation. For example, output is a string, and then they would say output concatenate, and then do the same thing here. And then finally, if they have output, then return that. Otherwise, return the number. A lot of people end up with something like this. But you don't need to do this at all. We can bring it back exactly how we had it before, and just add one final check. If the number is divisible by 15, 3 and 5, well, then you return fizz buzz. And we still get green, but this is a lot cleaner. And believe it or not, that's it. We've solved this challenge. So, if you want to do something random just to see if it works, what about 123? We know that's Generate Sequence Up To 6:42but this is a lot cleaner. And believe it or not, that's it. We've solved this challenge. So, if you want to do something random just to see if it works, what about 123? We know that's divisible by 3. So, that means it should return fizz, and of course it does. Excellent. So, maybe we just want to do one more thing. We want to add an additional method so that we can calculate all of the fizz buzz sequence up to a given number. Let's make that work. So, what does it do? It translates a sequence of numbers for fizz buzz. All right. So, now we're going to say execute up to, and let's say we give it 5. Well, that should return to me either a comma-separated list, or how about it returns to us an array. 1, 2, fizz, 4, buzz. That's what we expect. Of course, it fails, so we're going to make it work. Method, execute, up to, and then the number. And now, how do we want to do this? Well, we basically want to say if the number iswe expect. Of course, it fails, so we're going to make it work. Method, execute, up to, and then the number. And now, how do we want to do this? Well, we basically want to say if the number is 10, then 10 times, we want to trigger that execute method and then save the result in an array. Okay, easy. In PHP, we use the range function to build an array out of an integer. So, why don't we tackle this the no-brainer route, and then we'll refactor it a little bit once you get it. So, how about for each range 1 to number as i, then we'll have some kind of output array like this, and we will append to it. This, execute, and then pass in i. Finally, we will return the output. And I think that should do it. Yeah, and it works. Not too hard at all. So, if you just want to verify this, why don't we say up to 10, and that would be fizz, 7, 8, fizz, buzz. Run it again, and we still get green. Okay, can we refactor this? Only if you want to. Really, this is Refactor and Testing Benefits 8:40verify this, why don't we say up to 10, and that would be fizz, 7, 8, fizz, buzz. Run it again, and we still get green. Okay, can we refactor this? Only if you want to. Really, this is perfectly fine. Very readable. No issues there. But maybe if you want to use some of PHP's dedicated array functions, then sure, you could use ArrayMap in this case. Return ArrayMap, and we're going to feed it range 1 to number, and that will return this, execute, i, and get rid of all of this, and we should still get green, and we do. So, it was a successful refactor. So, like I've been drilling in through this whole series, I want you to pay attention to the fact that because we had this set of tests backing us up at all times, we have this ability to refactor with abandon, so to speak. We can feel free to rearrange as much as we want, because we have that understanding that if we break anything, well, the test will return red.with abandon, so to speak. We can feel free to rearrange as much as we want, because we have that understanding that if we break anything, well, the test will return red. In worst case scenario, we can just backtrack a few clicks and try again.