Prime factor algorithm2:55
move to the next level and we repeat. However, there's one tweak here. What about this step? Is 25 divisible by 2? No. So what do we do? In that case, we move up to the next candidate. Is 25 divisible by 3? No. Then you move up. So we could say, if false, increase the candidate and try again. Okay, so in this case, 25 is not divisible by 2 or 3, but it is by 5. So then you divide. And then finally, repeat. Okay, so that's sort of like our formula here. Okay, I think we're ready to go. I'm going to go ahead and create a phpunit test. We will be testing a class we haven't yet created called PrimeFactors, and the test name will be PrimeFactorsTest. Okay, let's begin with an example. It generates PrimeFactors4, and let's start at the beginning, 1. So what are the prime factors for 1? Well, 1 is a unique number. It's not a prime number, so it has no prime factors. It doesn't qualify for a
First TDD test setup3:50
let's start at the beginning, 1. So what are the prime factors for 1? Well, 1 is a unique number. It's not a prime number, so it has no prime factors. It doesn't qualify for a prime number, so it has no prime factors. So in this case, let's create a new instance of a PrimeFactors class. And if I were to say, factors generate for 1, I'm going to expect that to return an empty array. There are no prime factors. So that will be our first test. Okay, let's give this a shot. We run it, and if we scroll down, PrimeFactors does not exist. Of course not. I'll add a new class here called PrimeFactors. It's within the app namespace, so let's switch back and make sure we import that. And then finally, we'll clean up the code here. Okay, let's run it again, and if we scroll down, there is no method called generate. All right, there's our next step. We accept a number, and if
we'll clean up the code here. Okay, let's run it again, and if we scroll down, there is no method called generate. All right, there's our next step. We accept a number, and if I run it again, let's see. Now the method is returning null, but of course we expected an empty array. All right, so when following TDD, a basic rule of thumb is to write as little code as possible to bring the test to green. So in our case, if it expects an array, then let's return an array. Even if it sounds silly, it does bring us to green. So now, we're going to write another test until it forces us to make the code a little more dynamic. So let's do another one here. It generates the PrimeFactors for 2. In that case, we know 2 is a prime number, so it should return an array with 2. All right, we run that. Of course it fails. We switch back, and again, we want to keep it simple.
Implement modulus division6:16
see what we can do here. If I switch back, hmm, if the number is greater than 1, rather than hardcoding it in an array, let's do this. We know we ultimately need to generate an array of PrimeFactors, and that is what we will return. Okay, so with that in mind, why don't we say, well, if the number is greater than 1, we could reproduce it like so, but this still isn't quite right, because imagine that you have the number 4. Is 4 greater than 1? Yes, so we push to the factors array 4. But that's not quite what we want, right? That isn't following our scratch example from earlier. Let me paste that in. Here it is again. For any given number, we check if it is divisible by 2. So how could we programmatically do that? Well, like this. We could say, if the number mod, we're going to use the modulus operator, mod 2 equals 0. So what this means is you take a number, you divide it by 2,
do that? Well, like this. We could say, if the number mod, we're going to use the modulus operator, mod 2 equals 0. So what this means is you take a number, you divide it by 2, and you check the remainder. And if that remainder is 0, that means it's perfectly divisible by 2. So let's try this. Is the number divisible by 2? If true, then record the PrimeFactor. So factors push 2, and then divide by 2. Okay, so divide the number by 2, and then repeat. So when I see repeat, I'm thinking, hmm, we need a while statement here, don't we? while number mod 2 equals 0. Then push to the factors, then divide, and then repeat. So if we have that number 4 again, let's do it together. 4 mod 2 equals 0? Yes. So now factors is this. Next, we update the number 4. 4 equals 4 divided by 2, or 2. Alright, let's do it again. Is 2 mod 2 0? Yes, it is. So push 2. And that is what we want. Finally,
Add divisor iteration loops8:59
because we missed this section right here. If false, increase the candidate. And what is the candidate? Well, it's 2. It's whatever term you want to refer to it. I'll use divisor. So we start at 2. While the number mod the divisor equals 1, then push that as one of our prime factors. Finally, divide by it. Okay, now here's the kicker though. If false, then we break out of the while loop, and we need to increase the candidate. So now divisor should become 3. So here's what I'm thinking. We need to wrap this in a second while loop like this. Let's bring it up, and ultimately, divisor will have to increase. So now what's our check up here? Well, while the number is greater than 1, that's the only time we want to perform these checks, while the number is greater than 1, then try to break it down to its prime factors. And when it no longer breaks down, increase the divisor, and then
Refactor tests with data providers10:40
divided by 3 is 1, and at that point, this check no longer returns true. So we break out of it, and we return the factors. So this is ultimately what we end up with. Let's run the code, and all four tests are passing. Okay, very cool. So let's now switch back to our tests. You'll notice they look very, very similar. So in situations like this where you're basically substituting data and then performing the exact same check, you can instead use PHPUnit data providers. So for example, we could say checks or factors, whatever you want. And now I'm going to return an array of arrays. So for example, if I had foo and bar here, well, here's how that'll work. If I scroll up to one of our tests, what we could do is declare a data provider, and we need the name of the test. I'm sorry, the name of the method, which is factors. Okay, so now this test is going to be triggered for
do is declare a data provider, and we need the name of the test. I'm sorry, the name of the method, which is factors. Okay, so now this test is going to be triggered for however many items in this array you define here. And each of these values will be passed to the method like this, foo and bar. So if I were to var_dump foo like this, and we run the test, there it is, we grab the value. Okay, so this ends up being pretty useful. Let's think about it. This, if we update this, if we pass it one, we expect that to return an empty array, right? There are no prime factors for one. So we scroll up, we're going to accept the number and the expected result. And then all we have to do is substitute number and the expected result. So if we give that a run, of course it passes. Okay, so now I can get rid of all this junk. I don't have to repeat myself anymore. Whenever I have a new check,
