In our final functions lecture, we'll revisit a problem we solved in our iteration work, that will improve our solution using functions. Specifically, the problem that we're going to solve is we need to print out a box composed of asterisks, using a width and height that the user specifies. Our constraints on this problem are that the width needs to be between three and 20, the height needs to be between three and 20, and a new constraint, now that we know about functions, is that we need to use functions as much as possible in our solution. Let's go get to work. For our starting code, I've added the function prototype in the actual function implementation for our get valid integer function, but I haven't started using it in our code yet. The main function is the solution we came up with way back when we were learning about for loops and nested for loops, and we're going to convert this code to be much more compact using functions. The first thing we can do is, we can take advantage of that get valid integer function by setting width equal to the results of calling that function. We know we need to pass in four arguments, we need to pass in the prompt, we need to pass in the error message, which is down here, though I am going to get rid of that newline character in there in the lower bound and the upper bound, and when we do that, we can get rid of all of this code. Let's run it to make sure that that works properly. You can see I get the error checking and properly, I'll just enter five and then three for the height, and we have a five by three box. Now that I've seen that that I can do this for width, I can obviously do this for height as well. Change my comment when I change my code to behave differently. Of course, I went to change the prompt in the error message, and I'll get rid of all of the stuff as well. We'll check again. The width we already know works, the height, we'll try to make sure the error-checking is working properly, and then we'll enter a valid input, and we have that five by three box again. So just using the function that we wrote a couple of lectures ago, we've made our code much more compact here in our main function. Next, I want to write a new function that will print a character, but it will be a little more complicated than that. The function return type is void, and I'll say print character. But really, I want to pass in two pieces of information. I want to pass in the character that I want to print, and I also want to pass in how many times the character will get printed. So this won't just print a character once, it will print it numTimes times. Let's write a comment that says that, prints the given character numTimes times, and we certainly know how to do this. We'll just use a for loop, and we know how to print out a character, we just print f formatting as a character, the character that we have as a parameter. Now we can scroll up and change this to printCharacter, and we need to provide two arguments, we provide the character we want to print, and we provide numTimes, which is just the width. Now when we run it, we can see that the top of the box is printed properly. Now that we know how to print the top of the box, we also know how to print the bottom of the box. So we'll do that and we'll run it again, and you'll notice that I keep running to test the code after every small change we make, that's a really good way to do it, because if we mess something up, then we know it's probably in the small chunk of code we just wrote. So making small changes and then testing them and just doing that repeatedly is a really good process to have. I'm going to change these printfs to also just use the print character. The number of times I'm printing this character is once. We'll run it again. By now, you should know what's coming, I have this that prints a character a number of times, and I want to call the printCharacter function for this as well, printCharacter. In this time we're printing a space, in this time where printing it with minus two times, and everything is still working. We could actually leave it just like this if we wanted to, but I want us to have a little more practice writing functions, and once we've written this last function, we'll take a look at what our main function looks like then. So let's write one more function. We're going to write a function called printBoxInterior, and we know from the code that prints the interior of the box that we're going to need to know the height of the box and we're going to need to know the width of the box. So we will provide it two perimeters, width and height, I'll grab this function prototype, prints the interior of the box. Then I'll just grab this code that prints the interior of the box, put it down here instead, and because I called it the parameters height and width just like I had here, we're ready to go. Let's say you were all excited about this and you said, "Okay, let's run it. You say five by three and all we get is the top and the bottom, because remember writing a function isn't enough, we actually have to call the function as well. So we'll call the function here passing in a width and height, and when we test one more time, everything is still working. Now, you could certainly say, "Well, printBoxInterior is only used once, so that's not really a reusable chunks of code," but you can certainly imagine that we could have a while loop here in the main function that lets the user print as many boxes as they want, until they get tired of printing boxes and then we let them quit somehow. So in that case, we'd be reusing this function as well. One of the reasons I wanted us to write it even in this context is because if you look at our main method now, our main method really looks like a complicated problem that solves by solving a number of subtasks. We get a valid integer then we get another valid integer, then we have this print character subtask, then we have this printBoxInterior subtask, and so on, and it makes the main function look like a high level view of how the program works. If we need to know the details about some of those subtasks, we can just dig into those functions to see those details. So the code we generated in this lecture really shows that whole idea of problem decomposition by solving a bunch of smaller subtasks. To recap, in this lecture we saw how we can greatly improve our solution to the asterisk box problem by using functions. We also saw that as we get used to using lots of functions, our main function starts to look more like a high-level plan for how we're solving the problem, and each of the functions solves one of those subtasks needed to solve the problem, and as you'll recall, that's really problem decomposition.