Now we have a bit of an understanding of the main pieces of a computer based on the von Neumann Architecture and how it can store and use data. But data has just one piece of the puzzle here. We also need to think about how the computer executes instructions and how a program can tell it what to do. Earlier in this part of the course, we saw that one of the pieces of the von Neumann Architecture is the CPU, which contains the control unit. The control unit's job is to do these four things: fetch, decode, execute, update, and repeat. In the simplest case, the control unit executes one instruction, then moves on to the next one in the program which directly follows it in memory. For instance, if we were going to add two numbers and store the result in memory, we would first get the first number, get the second number, send them to the ALU for it to calculate the sum, and then write that sum to memory. Then it would update the address of the next instruction to be the one that happened to follow the one we just executed and so on. But what if after performing some operation, we want to execute one instruction under some circumstance and a different instruction under a different circumstance? As an example, here's the flowchart for linear search that we saw in the last part of the course. There are a few places where we have a decision to make and based on that decision, we'll do either one instruction or a different one. For instance, here, we compare the target to an item in the collection. This would be one instruction. If that instruction determines that they are equal, that means we've found the target. So, we would do this instruction over here to output true. On the other hand, if that instruction to compare those numbers determines that they're not equal, we would do a different instruction, which is to continue looking at the items in the collection. So, this means that the CPU needs a way of executing one instruction in some case, but a different instruction in a different case. Fortunately, the control unit can do that here in step four, when it updates the address of the next instruction to execute. In step three, you can execute an instruction that uses the result of a previous instruction to decide what the next instruction should be, and update that address in step four. So, when we go back to step one, we may execute one instruction in some case and a different instruction in another depending on that previous result. Let's use a flowchart to get a visual representation of this idea. For instance, in that previous example, we would execute an instruction to compare the two numbers and store that result somewhere, which we'll say is either true or false. Then we'd execute an instruction which looks at that result and decides what to do next. If the result is not true and the numbers were not equal, we'll just do the next instruction. But if the result is true because the two numbers we compared were equal, we'll set the address to that of a different instruction. As we'll see in the next part of the course, in programming languages, this is known as an if-then-else construct. If the result is true, then we'll do one thing. Otherwise or else, we'll do something else. We can combine if-then-else constructs in our programs in more complex ways to consider different conditions. Here we see that the first instruction generates what we'll call result number one. If it's true, then we'll go down here to this next instruction. But if result one is not true, then we'll go over here to this instruction. This instruction also generates a value which we'll call result number two. We'll see if it's true and if so, we'll go down here to this different instruction, and if it's false, we'll go over here to this other instruction. This is known as an if-then-elseif construct. If result number one is true, then we'll do one thing. Otherwise or else, we'll do another if which is based on result number two. If that's true, we'll do something, and if it's false, we'll do something else. Keep in mind that after we branch, the program keeps executing instructions in sequential order one after the other, as I'm showing down here with these ellipses. But in the last part of the course, we saw that many of the algorithms use iteration, where we repeat some steps some number of times or until some condition is met. Here's the flow chart showing the use of a loop. This is similar to the previous flowchart and that we make a decision based on the results of a previous operation. Here we execute some code if we're still iterating and execute different code if we're done. The difference is that the end of the code inside the loop, we always go back to the instruction that generated the result, that we use to determine whether or not to keep iterating. If it evaluates to false, meaning don't keep iterating or stop iterating, then we exit the loop and keep going with the rest of the program. So, now we've finished our overview of the von Neumann Architecture by looking a bit more at how the control unit works. Its job is to execute instructions and then figure out which instruction to execute next. Usually, it just executes instructions one after the other as they're stored in memory. But it can use conditional execution to decide which instruction to execute based on a prior operation, and it can repeatedly run some instructions and then jump back to where it was, which is called a loop. Now that we have an understanding of what the computer is capable of doing, we're ready to start thinking about algorithms in these terms. In the next lesson, Sue will tell you about a structured way of expressing an algorithm, and then I'll come back and revisit our two case studies.