 This is the second video about refactoring. Here we're going to focus more on functions. As we saw in the previous video, refactoring is all about removing duplicate or similar code to make the program easier to understand and to improve code maintenance. Let's look at an example here. We've got two chunks of code somewhere in the program and we can see that they're quite similar but they just differ in a couple of things. So we can just produce a function. We can see that the intention is to draw a red ellipse. You can see by the fill. But all that varies is the x, y coordinates. So that's captured in this function here. It's got the stroke and the fill. You can see the parameters that are important here are the x and the y. They're the things that change. And so we can replace the original two bits of code with two calls to the function. The only thing we need to supply are the things that change the x and y coordinates. Here's another example. So here we see it's like the previous one but we've got an extra thing here. In one place we've got an ellipse and the other we've got a rect. We can still capture this. It's a little bit more complicated. But what we can do is we can do something that represents whether we have an ellipse or a rect. So we've got these two constants up the top here. An ellipse having the value one, a rect having the value two. It is totally arbitrary values that we're using. And now it's like our previous drawer red ellipse function. But now we're saying drawer red shape and we have a third parameter int shape. And shape is going to have the value of either one or two to tell us whether we're meant to be drawing an ellipse or a rect. And you can see how that works in the function there. We've got if shape is an ellipse then draw ellipse else draw rect. But otherwise everything else is the same. So we've still got the same stroke and fill. We're still using the x y coordinates for drawing the shape. And we can see then the code up the top there, the two chunks of code in the top left of the slide can now be replaced by these two function calls here. It's like the previous example except we need to pass in as a third parameter, the shape. Sometimes we have functions that do very similar things with a little bit different here. We'll get the average of two numbers we'll get the average of three numbers. So how can we generalize this? Well this just screams out for an array. And now we can say ok well we can work out the average of all the numbers in the array. This means that the original two functions need to be slightly different in that we have to create arrays for those two values or the three values. But this new average function would probably find why to use. Here's a bigger function here. And really what we're trying to do with a function always is get it to do a single thing. And if we look closely at this this is actually doing two things. We split the function with an empty line in the middle there. We can see that the first part is working out the average of an array. And the second part maybe not all that obvious but it's trying to find the element in the array as closest to that average. So what we can do is basically split this into two functions to capture those two different things that it's doing. So the first part we can create a function that calculates an average. And the second part we can say let's find in an array the first element that's closest to a particular value. Previously we were looking for closest to the average but let's just generalize it slightly and say closest to a particular value. And now we can just reduce that down to two functions and we can go back and change where that's getting used. What I want to talk about here is just a brief case study in how refactoring can happen out in the real world. Back in the 1990s when GST was introduced in Australia programs had to be changed excuse me programs had to be changed to incorporate GST and so everywhere where you had a price you wanted to know what the GST was then you needed to work out 10% of that. So you divide the price by 10. Here we're assuming price is kept in sense. So it seems like you could just go around everywhere in the code and just write whatever you want to know what the GST is. You just divide the price by 10. But what we really wanted to do is centralize how GST is calculated. There's always a chance that GST might go up or somehow the way that GST is calculated changes. So now we've got a function, you pass in a price and it returns the GST. And so you need to go through everywhere in your program. You want to know GST. You don't just divide by 10 you call this function. Then things can change. Turns out that some users of this, this is on a web service here. Some users of this were actually exempt from GST. So we needed to be able to look at the user's user ID, look them up and see if they're exempt. And if they're exempt then GST is just going to get returned to zero. And if the user is not exempt then it's just calculated in the normal way. And then it can get more complicated. It depends on the particular product. Some products you don't calculate the GST on the whole price of the product. You only charge it on the margin over the cost. So again you need to have the product available to be able to do this. So suddenly a simple little GST calculation function which took price, now it's four parameters instead of one. But what happens with all this is we've centralized always what has to be done. So the moral of the story is if you think change is likely in the future then you should always centralize that code in a function and then use that function everywhere and maintenance will be a lot easier.