 All right. Welcome back to Computer Science E1. Tonight is our lecture on programming. Next week, same time, same place, we'll be exam two. We will have, led by Alex, our teaching fellow, a review session after tonight in lieu of the regularly scheduled section. That will be filmed, though, for those who can't stick around or who are tuning in on this video. This coming Wednesday, we will post the upcoming assignment and also some specifications for the final project, which is due several weeks hence, but will culminate the course with a little bit of website design. So today's all about program. What does it mean? Softball question to program, even if you've never done it before. Give me something. Writing code. OK, so now we have a cyclical question. What does it mean to write code? No looking down at your papers as an alternative. What's that? Good. So giving instructions to the computer to tell it to do something. So you can kind of infer this answer from weeks ago when we talked about software and what a program is, something you might double click on a computer to actually run some program. Well, to program as a verb means to write those kinds of things, to write some set of instructions, somehow transform them into zeros and ones so that when executed, so to speak, they tell a computer to do something. So programs can do all sorts of things. You can use them for email, for web browsing, for writing documents, really anything you've ever seen a computer do is the result of one or more persons having written some program, aka software, to tell or inform the computer how to do that. But more generally, writing programs is about thinking logically and thinking methodically. And unfortunately, as sophisticated as you might think the computers on your desk at home or at work are, they're actually pretty dumb devices because they can only do what you tell them to do. And if you are not ever so clear and ever so precise, what tends to happen in programs from what we've discussed? They crash. You get some kind of bug, some kind of unforeseen behavior. Infinite loops or spinning beach balls or just things grinding to a halt. Unexpected behavior tends to ensue if you haven't quite thought through all of the possible consequences. So you may have heard now of languages. Computer programs can be written in all sorts of languages. What languages might you be familiar with, even if you've never seen them yourself? OK, so Java is a popular one. C is another one. C++ is another. Came after C. C-sharp is another one. From Microsoft, others? So HTML is a language, but recall from last week, it's not a programming language, but a markup language. It's a way you can tell a browser how to display something, but you can't necessarily tell the computer how to save files or open windows with HTML alone. It's really about marking up data. So we'll leave that off this list for today. Other programming languages, though? OK, basic from yesteryear, one of the earlier languages that some of you may have grown up on, myself included. OK, so CSS, sorry, I have to strike this one down, too. CSS is another one in the genre of last week that's used really for aesthetics, for rendering data, but not instructing a computer what to do, but rather how to do something aesthetically. So let me leave that one off the list. But you get three tries every lecture. Yeah? What's that? Ah, OK, so we're really going backwards in time. What else? OK, Python is an increasingly trendy one. Just round out the list with one or two more, if you've heard of any. Perl is another popular one. A lot of websites these days that are dynamic, that take input and produce output, are implemented in a language called PHP. So XML, I'm going to have to put that in the last week bucket. It can be used for different things, but at the end of the day, it stands for extensible markup language. So that too wouldn't belong in the programming bucket. R? OK, R. Good, some of the more R, K, and ones, but that's OK. Yeah? OK, so also going a little back in time, there's another one where everyone was freaking out over the lack of people who knew this language around Y2K. So Fortran was another one that a lot of folks here might have grown up with, but that has fallen into largely disuse simply as the result of more modern incarnation. So suffice it to say, much as there's a ridiculous number of spoken and written languages in the human world, there are all sorts of programming languages in the computer world that humans have invented. None of these just have existed from the beginning of time. Humans have implemented or designed all of these languages from scratch with which to communicate their instructions precisely to a computer. So what all of these do, you can basically just understand these as languages, just like you would understand different languages to communicate with other people. In other words, this is just a way of communicating to a computer. And so in order for a computer to understand one of these languages, it has to be able to understand it in order to do something with it. But specifically, for most of these or many of these, what actually happens on sort of a higher level is this task or this activity that's performed on this source code. So you write a program in one of these languages, and then you use something called a compiler. And then a compiler will take all of this source code and convert it. All of these little things that you've written, all of these statements, all of these commands that you've written in one of these languages, and it will convert it to binary ones and zeros in a fashion that a computer will actually be able to understand. So the end result should be some sort of an executable file that has a pattern, a specific pattern of ones and zeros that it will be able to understand. And so if you recall from some of our initial lectures, way back, say to lecture one, for example, the CPU, the central processing unit inside of a computer, understands a fixed set of instructions. So maybe a certain sequence of ones and zeros will tell the CPU that what you want to be able to do is actually add two numbers. So then it will be able to understand that, OK, with this sequence of ones and zeros, add two numbers. And so the job of a compiler then is to convert, basically, or to compile all of this code that you've written in one of these languages from this higher level language that you've written into this sequence of ones and zeros that the computer will then be able to understand. And so when you're writing one of these programs, it's usually referred to as a couple of things. And one of them is, or it is called generally like source code. So if you were writing code, what you were writing is a file that, in general, is known as source code. Then you typically use a compiler and it's just converted to these ones and zeros that the computer will then be able to understand. And so recall that the computer, and specifically the CPU, has a fixed set of instructions. So for example, you can tell a computer to add two numbers together with a certain sequence of ones and zeros. And that you might imagine that that means that there's between different CPUs, for example, between Intel processors and IBM processors, or AMD processors, or even different versions of processors, the instructions might be a little bit different. Or the actual binary that's used to perform something is a little bit different. And so that's why there's so many different compilers that can exist for pretty much all of these languages. They have to be targeted specifically not only to one of the languages, but also to what's called the architecture, or just the computer as a whole and the instructions that that computer is able to understand. So even though people like us certainly couldn't teach you a new spoken language, like Spanish, in just one night, similarly tonight, can we not teach you the entirety of any one of these languages? But what we will use is a graphical language that was developed just a few years ago from some folks down the street at MIT's Media Lab. This environment, or this graphical language, is called Scratch. And as you will see in just a little bit, it allows you to program quite literally by dragging and dropping puzzle pieces, each of which happens to represent some of the low level building blocks that Dan alluded to, like addition and subtraction. But the nice thing about it being very graphical and visual is that you can actually see pictorially how certain instructions fit together logically and how various programmatic constructs, as we'll call them, to use some lofty jargon here, fits together and allows you to go from nothing to a program that actually does something. But just so that you can see this in the context of a real, so to speak, programming language, or something that a person might use really to solve an arbitrary problem with the computer, I'm just going to go ahead and load a program here on my Mac. This is a program called Terminal. Anyone who has a Mac has this program. But what's neat about Macs, among other things, is that you can actually use what's called a command line. It's a somewhat arcane interface where you interact with the computer by typing commands instead of by pointing, clicking. But because what I want to use here is a language called C initially, it allows me to interact with the system as folks originally did when this language came out. So if I wanted to write a simple, simple, simple program whose sole purpose in life is to say, hello, when you run it on the screen, I can go about it in this way. And this is intentionally introduced here to look a little cryptic. I first have to say a little something like this. This is a sequence of character. Whoops, let me increase my font size. So this is a sequence of characters that simply tells this program to go include some source code that someone else years ago wrote. And standard io.h is simply a file, text file, that contains that code that someone else wrote. And it has some built-in functions, as we'll call them, some built-in functionality that I can leverage as a programmer years hence to have the computer do some very basic things. For instance, I have no idea, off the top of my head, how I can make a computer spit a certain ASCII character out on the screen at a given location. But thankfully, because others have paved the path before me and written what are generally called libraries, I can use programs that other people wrote inside of my own programs in order to get started and not have to worry about writing myself zeros and ones that people years ago had to do. So that's the first line of code. I then have to do something like this. This is main, the main part of my program. And then I have to do some crazy stuff with some curly braces here. You might not often use them on your own keyboard, but they're very common in programming. And then it turns out that there is a program, or really function, that someone years ago else wrote whose sole purpose in life is to, take a guess, print something to the screen. Now as for that F, it means print a formatted string, which means you can actually format it in certain ways. But this function, as it's called, takes what's generally called an argument. And that argument is simply what it is you want the computer to print in this case. So I'm going to go ahead and say print quote unquote hello. Now the syntax I have to use is another parenthesis and a semicolon. And these are the kinds of stupidities, frankly, that plague a lot of programming languages, certainly for new programmers. Because you just have to start to memorize or remember that you need parentheses here, quotes here, semicolons here. And this is why you'll see in a moment that we intentionally choose a language like scratch, because it allows us to do very similar things and make much more interesting programs in the first day without the silliness of this syntax. So now I'm going to go ahead and, as Dan said, I'm going to save this source code. So now we're here. So the next step in creating a program is to run this source code through what? A compiler. Now there's many different compilers in the world. A lot of them are free. Some of them are commercial, Microsoft, if you've ever heard of a project called Visual C or Visual Studio, Visual C++. A lot of people, programmers at work, you might know, have mentioned this at some point. That's just a really big program suite among whose tools is a compiler. The one I'm going to use on this Mac, which is common also on Unix and Linux systems, is called GCC. And I'm going to run GCC on this file called hello.c. That was the name I gave this text file. I'm going to hit Enter. Nothing seems to have happened, but it turns out. And this, again, is a stupid arcane convention. The default file name that this compiler spits out is a file called a.out. A, because probably it's the first letter in the alphabet. It's the first program I made, and .out because it's been outputted. And I go ahead and hit Enter. Voila. I have now written a computer program. So all this time, if you've ever wondered how programs are actually written, well, there's many more steps after this to actually write a word processor and a spell checker and the like. But that is what a typical programming language actually looks like. So what exactly is that? Can be more precise. What do you mean consist of? Oh, sorry? What does this tell the p? Oh, OK. So what exactly is the programming language? Oh, OK. So that's my fault for not being precise. So when I originally opened this blank file and started typing commands like this, think of a reasonable analogy as being, suppose my computer only speaks and understands Spanish. And I want to tell this computer to say something in response to me. I would have to type out, like, por favor, dime algo. Like, say something to me in Spanish and then hit Enter. And then that computer would presumably respond because the computer, too, understands that particular language. Well, this computer does not understand Spanish. It understands zeros and ones. Now, I, the human, don't speak zeros and ones. But thankfully, there's this middleman that exists, a program itself that other really smart people wrote long ago that takes source code that looks like this, which is just an arbitrary set of rules that some humans decided. If you want to write a program, the first thing you do is say int. The second thing you do is say main. The third thing you do is open parent, close parenthesis. The next thing you do, dot, dot, dot. So this is an example of a program written in a language called C, much like if you looked at a printed essay, that an essay would be an example of an essay written in English. So when I actually run that source code, that program through the compiler, what I get out, stored in a separate file altogether, is one that I can then conceptually double click or run by typing its name at the command line. And that will instruct the computer to do something in a language it understands, even if I don't understand all of it myself. Exactly. Each language, so source code is more generic. Each language has its own compiler. But that's a bit of a white lie, because there's different types of languages out there. Some of them are, in fact, compiled in this way into zeros and ones. But some of the languages on this board are what are called interpreted languages, whereby the computer does not convert them in advance to zeros and ones. But rather, similar to a browser in HTML, it reads your program top to bottom, left to right, and essentially converts it line by line to the actual program. And let me reveal one more detail just to make clear that this is one example of a language. Let's do really fast another one by doing hello.java. So now I happen to speak multiple spoken languages. I also happen to speak multiple computer languages. So here, I'm going to do something like this, class hello. And again, these are fairly arbitrary human conventions. And now I'm going to say public, static, void, main, string, args. And then let me go ahead and indent this. The indentation is just a human convention as well. And then I'm going to say system.out.print line hello. And actually, I'll call it printf2. So notice it looks different. There's definitely some similarities. There's that keyword main. There's that keyword printf. But it definitely looks different from the previous version. There's some different syntax. And in fact, the procedure via which I run this program is slightly different. Instead of using GCC, I need to use a compiler designed for Java. So I use a program called Java C. Hit Enter. Again, nothing seems to happen. But now I can run another command called Java itself. No C, no Java C for compiler. Just Java. And then the name of the class I just defined and hit Enter. And voila, now I have a program written in two languages. So to summarize, we have hello.c, which is this program here. And then we have hello.java, which is this program there. They achieve the same result, but in a different way. Much like in reality, could you say hello to someone in different spoken languages? And this is actually a very useful thing. So it sounds very arbitrary just to write a program to say hello. But this is the sort of introductory program that is very, very popular. And in fact, it's generally called a hello world program, where usually what people are shown the very first time they're introduced to a new language is how to do this exact thing. What series of characters they're actually supposed to type in order to print out, to have the computer print out, hello world. And in fact, let's see, switch me over to number one. There's something like 200 plus different types of programming languages. If not more. And it's very difficult for people to know all of them, obviously. But usually, once you understand some of the main concepts of programming, it's pretty easy to pick up some other programming language, just because then you can figure out what the other syntax is or what the actual words are that represent something in a different language. And so you might then be able to relatively easily pick up something else. So for example, what we saw before was a C program to print out hello. But what if we wanted to look at, say, C plus plus? Well, it would look slightly different. But you can see there are some similarities in order to accomplish this same goal. And so there's C plus plus. Let's see, we had a C sharp down here. And usually, this sort of thing becomes actually kind of a game to a lot of programmers where they actually try to figure out what the shortest program is to make a hello world, to actually make it print out hello world. And it's always some big thing whenever they can figure out how to print out hello world in the fewest number of characters possible. But that's sort of tangential to this. And there is other programming languages. So what David mentioned before and what the examples that he provided for both C and Java are examples of these compiled languages. And Java is sort of shaky. It's really difficult to say that it follows this exact same model, but you can essentially think of both as being compiled. However, he also mentioned that there were these other class of languages as well that are interpreted. And in other words, you can think of this as being, whereas the compiler, as soon as you write some source code, you have to compile it first and then the resulting file you can run. It's an actual application that you can run. An interpreter is different. It's sort of like what it sounds. It takes a file in whatever source code and whatever language you've written and it interprets it in that directly from that source code and it interprets it into the zeros and ones directly so that you usually have to have another program, an interpreter program or just some sort of a helper program to help you accomplish the same thing. So to just pluck off another one, another one of these languages, PHP, for example. This is an example of an interpreted language. So if we wanted to write just a very simple Hello World PHP program, we can just create a new file and make it bigger and then we would just do something like this. I guess we'll do printf just to make it look similar. All right, so now that's pretty much it. Now I've written this program in PHP and I will be able to run it if I can find an interpreter and in fact, PHP does have its own interpreter and we can run it very simply by running a program called PHP. So there's a program somewhere on my computer that's called PHP by running it and telling it that I want to run, hello.php, it will run. It will first interpret and then it will run the code that exists within this source code. So it's important to note that there's a difference here between compiled languages and interpreted. So compiled again, you just, you write some source code and then every time you want to run, or not every time, but when you want to run the program, you must compile that source code into ones and zeros and then you can run that compiled file any number of times that you want. It's just an executable file that you can double click or that you can run from the command line and it will run. Whereas interpreted languages, when you write the application or when you write the source code, you have to run it through an interpreter in order for it to actually perform its task. Yes? For the compiled language, once you've assembled it into binary, can you actually edit that binary file? Open it up? In theory you could, yes, if you know what you were doing and when we discussed a couple weeks ago in our security lectures, the idea of cracking software and bad guys figuring out how they can circumvent prompts for instance for serial numbers or the like, what sometimes they do is exactly that. They take the binary because they don't have physically the source code and try to figure out where the low level zeros and ones are that represent ask for serial number. Right, and along those same lines, it's obviously now a lot easier to modify an interpreted file or to when rather it is a lot easier to make a change and then run it immediately because you don't actually have to compile your source code when it's an interpreted language. You can just make it whatever change. So if we want to actually change, for example, what this says, we can just change from hello to hello world, run it again via PHP and now it says a new text. Whereas using a compiled language, we would actually have to, as soon as we save the source code, we'd have to recompile it. We'd have to recreate this binary code so that now when the computer runs that program, it sees that change. It has that change within that executable file and it will then show you whatever changes have been made. And that might seem irrelevant for such simple programs as the ones we just wrote that say hello because if you recall running GCC, running Java C took what half a second maybe, but consider that we've just written programs that are two lines long, five lines long, whereas real software, something like Microsoft Word these days or Windows, is literally millions of lines long and dozens, hundreds of people will have written those lines of code. So compilation, the act of compiling a program can take seconds or minutes for much larger programs. Yes. So the time that you want to run that program, you have to run PHP, no PHP, you have to run PHP. Yes, for an interpreted language, every time you have to, the computer won't understand this hello world. So just to do, just to mirror what David did before, if I try to run hello world, it doesn't understand. It just gives me a bunch of errors. It doesn't understand what this random gibberish is. It's not in binary language. So if I wanted to run it, I have to run this source code through an interpreter. And so then, yes, then for a PHP file, I do have to run PHP every time I want to do it. Now there's, it's possible to tell the very top of a line in the specific case of PHP, just so that I mentioned all of the details here. It is possible to put at the very beginning of this PHP source code what interpreter it should use and then you don't have to type in PHP hello dot PHP, but it's still the same thing. It's still using an interpreter to understand the source code, interpret it into binary and then actually run the code as it is shown. So what I thought I'd do just to tease you now with what you can start to do with programming languages is right now we've written programs using only what's called generally a statement. A statement is like a single instruction that tells the computer to do something, in this case, print something to the screen. Well, what if we wanted to print something multiple times? Well, if I go back to my original example, arbitrarily the one that was written in C, well, if I wanted this thing to print the screen multiple times, you know what I could do? Just copy paste. And this will now print hello 10 or so times. Let me go ahead and rerun a dot out. And oh, wait, oops, a dot out. And why did it only say hello once? Right. So C is a compiled language, so we have to recompile it. We're missing this step. So OK, GCC hello dot C. Now I run this program called a dot out. And there's hello 10 or so times. Now, this should already strike you as a little inefficient. If you have a lot of smart people in the world that are supposed to be writing programs that allow you, the human, to do things multiple times, spell check your document again and again, you'd hope that someone just hasn't written code that generally looks like this inside the file. You'd like to think that there are other constructs or other fundamental types of code you can write with which you can instruct the computer to do things optionally or multiple times cyclically. And in fact, you can. It differs based on the language. And we'll see in a moment how to do it in the graphical language called scratch. But I might do something stupid, let's say like this. Do the following while 2 is less than 3. Now, this is a completely inane program, but it hints at the fact that you can, in fact, perform logic. You can compare one number against another, one sentence against another, one word against another. So very arbitrary example, but one that's important, because it is always true or always false, this statement. It's always true. 2 is always less than 3. I'm not changing the numbers 2 or 3. So anything inside of these so-called curly braces, you might imagine conceptually, is going to happen again and again and again because it's going to do the following while 2 is less than 3. And that's unchanging. So now, let's put that comment in the middle, printf. Hello. Same syntax, but now it's inside what we're going to call a loop. This keyword, while, demarks the start of what programmers call a loop, does something multiple times. Unfortunately, this is an example of an infinite loop, which you might not necessarily have seen the source code for, but you've probably experienced. On macOS, if you get the spinning beach ball, or in Windows, if you similarly get that annoying icon that's just kind of whirling around and nothing's ever happening, or your machine's just grinding to a halt, and yet it seems to be doing something, it's just your hands are off. You don't know what it's doing. It might just be because someone hopefully didn't do something as inane as this, really a stupid mistake here. But there are ways to create the same effect by not anticipating maybe what the values are going to be that you might be comparing in your code. Because as we'll see in a moment, you don't have to hard code numbers like 2 and 3 into programs. You can use things called variables, like in algebra, x and y and z, that might actually have changing values. For instance, if you're implementing a game, and it's a little shooting game or whatnot, you might have a score. That would be an example of a variable that's going to increase and increase and increase over time. So certainly, can you imagine numbers changing inside of a program as that program runs? But let's see what happens here. Let's recompile hello.c. And now let's rerun a.out. And unfortunately, this program will never, ever, ever stop. Unless the power goes out, I pull the plug or reboot forcibly this computer. Now this is kind of silly here. But suppose I wanted to actually do some arithmetic. We'll see this in Scratch in a moment, too. I'm going to declare, and this syntax is a little weird in C, I want an integer, just a number. I'm going to call that integer x, like I learned in algebra class. Although I can use any word I want. And I'm going to initialize it, set it to the default value of 0. And then you know what I'm going to do? I'm going to do this silly thing here while let's do while x is greater than, well, actually, let's do this. Let's set it equal to 1. While x is greater than 0, go ahead and do the following. Print something. But then you know what? After you print something, increment the value of x. x gets x plus 1. So if you think through this logically, odds are you've never programmed in C. But even with these basic building blocks, you can imagine we've declared what's called the variable, set it to 1. I'm then saying while x is greater than 0, do the following. What should I do? Print to low, then increment 1, increment x by 1, and then do what? What's that? You want to go back around? Well, careful now. Now x is equal to 2, because x equals x plus 1. So x equals 1 plus 1. So that's 2. So 2 is still greater than 0. So I print to low again. Then what do I do to x? Add 1. So now x is 3 greater than 0. Of course, now we do it again and again and again. So now, and actually, let's not print out x. Let's actually, and this syntax is just a little weird, let's print out. No, let's not print hello. Let's print the value of x. And I'm going to wave my hand at how I'm doing this. But percent d means put a digit here. Put a number here, a decimal number. So now I'm going to go ahead and rerun gcc. And I'm going to, oh boy, here we go. That's how fast this particular computer can count. So the difference between 2 and 3 is always better. Whatever the 2 is always less than 3. Correct. So then you were doing that, that's why I'm going to give 1 over and over. Exactly. And now in this case, I changed that. I ripped out the stupidity of 2 less than 3, because that's obviously always the case. And this time I put a variable, while x is greater than 1. But the problem is, because I just keep adding to x and I never subtract from it, well surely x is going to be equal than 0. And so we're again going to keep looping ad nauseam here as the computer counts up and up and up and up and up until maybe something bad will happen. Now this is an intentionally erroneous example. This is showing you what can happen if somebody types in something that's bad or types in something that's wrong. And this is, again, a very simple idea. It's a very simple error that David intentionally put into this source code. But you can get an idea that, OK, well, if we have a million lines of code, it might be relatively easy to have one mistake like this that can cause some sort of a crash that can cause its own sort of infinite loop that would cause all of these sorts of problems that you might associate with your particular computer. But it refers to, and at least it alludes to a concept that's a bit more abstract that's really important to be able to understand when we're talking about programming. And that is this idea of algorithms. And an algorithm is basically just a sequence of steps. It's just a set, fixed number of steps that can accomplish some task. So let's say I am a dumb computer and I am given a phone book. And what I need to do is find a person's name within this phone book. What is an algorithm? And just plain English. You don't have to tell me in source code or anything like that. And just plain English. What's an algorithm that I can use to guarantee that I will find a name or that name within that phone book? Yeah. Right, very good. So open the book to the very first page. Start looking at each name and go from the very first name, AA, to the very last name, until we find the name that we want. And that is an example of an algorithm. But it's important to note that you can usually skin cap many different ways. There's usually more than one algorithm that will accomplish the same goal. And sometimes different algorithms might be more efficient than others. Some algorithms might be more error prone than others. And this is really where the programming aspect becomes very, very interesting. It's trying to figure out, trying to come up with an algorithm that you can express in a programming language that can accomplish some task and doing it the most efficient way possible and the least error prone way possible. So that way you will have fast code, fast efficient code that will run, that will accomplish the task that you want without crashing or without any sort of problems. And so if we wanted, say, a faster version of the same algorithm, of the same task, is there something that we can do that will make this a lot faster? Yeah. Right, very good. So now instead of just going through every name individually one at a time, which is a very valid way to do it, but if we have a billion names in this very large phone book, and it takes us one second to look at a name, compared to the name that we're trying to find, you can imagine now it can take up to a billion seconds to find the name if it's like the very last one. So what we could do instead is try to have the number of names that we actually have to find. So instead of starting at the very first page of the phone book, for example, let's say we open it just in the middle. And then we compare. We look, and we're probably somewhere in the m's or the n's. And we say, OK, the name that we're looking for starts with a b. Is a b less than an m, or is it more than? And if it's less than, then we can just throw away the complete latter half of that phone book. We don't need to look at that, because we know, because it's in order, that b, the name that starts with a b, is not going to be in that latter half. And so then we now have a set of names or this phone book that's now half as large. It's now 500 million names instead of a billion names. And we can do the same thing. We can, again, open it in half at the very, very middle and say, OK, well, where are we going to be now? Like f or something like that. OK, is b less than f, or is b greater than f? And then we can then, again, throw away half the phone book. And so doing it this way, this is actually much more efficient. We can actually perform this same task in probably only about 20 steps for any name in the phone book out of a possible billion names. So this is much, much faster. And it's not error-prone still. And so it's just a much more efficient way. It's just a much more efficient algorithm to be able to accomplish this same task. So let's try to use not so much technical jargon, but just useful jargon with which we can talk about programs now in any language. And we've already tossed out a couple of keywords, loops, and variables. Let's see if we can't now use this framework, this example, a silly example from what you might have done this morning, to tease some of these concepts apart. So here's an algorithm. Again, an algorithm is a procedure. It's a set of instructions that somehow tells a computer, or maybe a robot, or maybe sort of a slow-witted human what to do. You have to be terribly clear and terribly precise with them. Now, we've chosen this program specifically so that you can see an example, but in English, or in an English-like syntax, some of these important ideas without the silly distractions of the semicolons and all that other syntax. So here's an algorithm procedure for putting on your socks in the morning. And we've numbered each of the steps, and we put forward for consideration that this algorithm takes maybe a 17 steps. This is not a perfect algorithm, and that's also intentional. But let's see if we can't tease apart how this thing would run. So in step one, even though it's now in kind of this broken English-like syntax, what is step one an example of using tonight's jargon thus far? What would you describe the thing going on in step one as? Yeah? Yeah, so setting a variable. Now, I didn't use x and y and z, which we were taught to use in algebra, but rather I used an actual word or word with some underscores just because in programming, especially if you start writing hundreds of lines of code, thousands, millions of lines of code, if your programs are filled with x's and y's and z's, honestly, what the heck do they mean in various different contexts? So the nice thing about real programming languages and things like Scratch is that you can actually give words or short phrases to your variables to just help you, the human, or other humans who might inherit your program and have to maintain it in the future keywords that describe those variables. So in step one, we're defining some variable called socks on feet and initializing it to the number zero. And this should make sense unless you sleep in your socks that when you wake up in the morning, you have zero socks on your feet, and so thus begins our program. Now, step two, by contrast, is an example of what other construct we talked about thus far. This is a loop. So it's a cycle, something that might induce the same behavior again and again. And rather than use the silliness of curly braces, which a lot of languages use, we instead took the approach that actually Python, another language uses, of just indentation. Because it's kind of clear to the reader that everything below step two seems to somehow be related to step two, because it's all indented underneath it. It's just some kind of hierarchy. And we've seen this in what other language? HTML, right? It wasn't required in HTML. It was just us being anal last week. But we did argue that humans can read it better if you nicely indent everything so that there's this nest thing. Same deal here. So step three, open sock drawer. That's a statement. It's instruction. Now, it's a real world instruction, but it's analogous to things like print that we've looked at thus far. Step four is another statement. Look for sock, whatever that means. And here's where you can start to push back on us. Frankly, what does it mean to look for a sock? If we were really being precise here, we would have to tell the computer, or imagine the robot, exactly how to find a sock. But we skip that. We're waving our hands because we don't want a 1,000 line program just to discuss some simple ideas. So step five is an example of what? Haven't used this term just yet. Yeah? So it's an if statement, or a condition, or a branch, or in the real world, if you prefer, a fork in the road. You check whether or not something is true or false. Just like before with loops, check if something is less than or greater than something else. But it's a decision point. And you either go this way conceptually, or you maybe go this way. Or in some cases, you could go in any number of directions. Totally depends on the program. But in this case, the computer is asking itself, or in this case, we're asking the human, if you find a sock, then do what? It looks like what we should do is everything from line six through line 15, because notice that's how the indentation lines up. So if you just look straight down, everything below step five is indented from line six to line 15. So just to make sure you're following along. So what do we do if we find a sock? We put it on. Then we increment our variable. Plus plus is shorthand notation for increment this by one. Add one to it. So now zero becomes one. Then look for other matching sock. Then, oh, an interesting construct. Another if, another decision point that's inside of another. Totally legit. It's because we're doing two things conditionally now. If I find a matching sock, then what do I do? Put it on. Then? OK, careful. Increment socks on feet by one. And then finally, close the drawer. Do I do step 13, 14, or 15? So no. Because again, per this concept of a fork in the road, either if something's true, do this. Else, do that. So I should not do those additional steps. And keep that in mind, because we'll see a very similar construct in scratch in a moment. And how about line 16 and 17? Do I do those now? So no, those were part of the first fork in the road. So those are also inapplicable. Now, per the indentation, what line should I be going back to next to check? Two. Two, right? Because that's how I got in here. We started with step two. And I said, while socks on feet. Oh, and I should have pointed that out this out before. Because there's no not equal sign on a typical keyboard, there is an exclamation point as one character on the keyboard. And there is an equal sign. So the human convention to say not equal tends to be exclamation point, which just means do the opposite of the following character, equals as the second character. So that meant not equals. So now I've gone through this loop once. How many socks do I have on my feet? At this point in our particular story? Two. So I ask myself the question again, while socks on feet is not equal to two, is socks on feet equal to two? It is. So where do I go in my program? That's kind of it. I seem to be done. Put another way, is socks on feet not equal to two at this point in the story? Actually, I don't like phrasing it like that. Confuses me. We have two socks on our feet at this point in the story. So when asked, while socks on feet not equal to two do the following, well, clearly that doesn't apply. Because socks on feet does, in fact, equal two. And so implicitly, and this is where we just waved our hands because it's going to get boring quickly, you're done with the program because there is no step 18. But this program is imperfect. Where can it go wrong? Are there any errors in this particular algorithm? Yes. OK, that's a good point. So if you do laundry, let's say you own zero socks and you look in the sock drawer, you don't find any socks or something like that. And you just try to do laundry, but you don't have any socks in your laundry bin. And so you wash your clothes and you don't actually replenish your sock drawer. Then, yes, you could get a problem with that. You could get an infinite loop because then, in this particular case, well, this is not being replenished. However, we do explicitly state that we are replenishing the sock drawer. So let's just assume for a moment that that is actually going to happen successfully. Are there other problems that could cause some sort of failure in this algorithm? Any ideas? Yes. What if socks are already paired? What if socks are already paired? What do you mean? Mine are paired. So I'm never looking for one sock as I'm always putting a pair in. Well, this doesn't handle the case of pairs, I would say. But we can give you a different algorithm after you or someone else has done your laundry. How do they get magically into these pairs? So we can push back on that. At some point, the matching had to happen. But fair. There's some real world issues here. I mean, still, it still might sort of work because you can find a pair and you would be able to find one sock within that pair. You could take that one sock out and then the rest of the algorithm would still apply. So still, it's possible that, depending on the interpretation of some of the English statements in this case, that we could still make it work in that particular case. But that is an interesting and good point. But is there anything else? Yes. That's an interesting point. Yes. So it's right. So let's see. If you find a matching sock, then so let's see. OK. So no. So what this is saying, this is actually saying that. So what you want to do is you want to actually remove the first sock. Because then what you will do is you will take off. So you put on one sock, then you look for a matching sock for that. You just pick up a sock. If that matching sock, let's see, doesn't exist, then you remove the first sock, and then you put on another one. Yeah? So put it on after you draw. Yes. No, these are all very good points. And what you're doing is you're thinking very critically about these statements. You're trying to remove the ambiguity of these statements. And so that is a very good point. That's the one. So if you have a horrible accident, and suddenly your sock drawer or your stock reserve, your stock pile, so to speak, only have one sock within it, then you will have a problem in this particular case. Because, yes, only if you put the sock back. Well, no, I mean, even if you don't, even if you just set it aside, then you still have the same sort of problem. Because, right, but then you don't have any socks, and so it just goes back. Yes. But this is actually the failure. So if you interpret it and say that, OK, when you remove the first sock from the foot, you're actually putting it back, then yes, you will get this infinite loop problem that we're talking about. This is why I handed this part of the class off to you. Usually, you're lucky that we didn't actually ask one of you to come up here and demonstrate this algorithm for us. Is there a question? Yes, so this statement 17 says to do laundry and replenish sock drawer. So this algorithm waits until this statement is complete. So if it takes you an hour or two hours to do your laundry and then to replenish your sock drawer, as soon as that is done, then it goes up to the very top. This while socks on foot, socks on feet does not equal two. Right, so as long as it equals zero, or as long as it equals one, even, it will keep trying. Or if, for some reason, you have three feet, now then the same thing will happen. Yes, so this algorithm assumes that you have two feet. Exactly two feet. Yes, that is another failure in this algorithm. You're not explicitly stating which. You really should have prepared better. You should have written a better algorithm. I did write this slide. Yes, so we don't explicitly state which foot to put the matching sock on. So it's possible that you could have both socks on one foot and zero socks on the other foot. OK, enough about socks, I think. So we need someone to come up here and play a little game for just a moment. You have to be comfortable on camera, need to listen to say. But is there anyone who would like to come up here and play a game for about 30 seconds? Come on down, all right. So what I'm going to do is, oh, and this program's still running. We'll come back to that later. So we are about to introduce a program called Scratch. If you go in the future to scratch.mit.edu, as you'll likely do for an upcoming assignment, and give me just one second, you'll see a website like this. Scratch, long story short, is a graphical programming language. Again, it was implemented down the road by MIT's Media Lab. And it's actually targeted at grade school or middle school children to use in after school community centers and to actually engage them in something intellectually interesting and fun on computers. But we've actually been using it for some time at Harvard College and in the Extension School. And other universities have started to do this as well. As a language with which to introduce programming. So what you will do over the next week or two is go to scratch.mit.edu. And we'll put all the instructions in an email for you on the wiki as well. You'll download the software. And that will allow you on your Mac or your PC to have this program called Scratch installed. Completely free. And once you download it, you will have an icon on your desktop or similar for this program called Scratch. And when you open it up, and this is what we'll have you play with in just a moment, is a screen like, oh, there it is, already running. You'll see this interface here. And the nice thing about Scratch is that it actually doesn't take all that long to explain it, because frankly, it's targeted at young children. So you really can't expect the learning to be very high, which is nice. Because we ourselves can dive in and start doing really interesting, really fun things quickly. So a few definitions of what you're seeing here. So that guy up there at top right is Scratch. He's a cat, but you can make him look like anything you want. And he's what is called a sprite or a computer character. And you can have multiple sprites. And these are characters in whatever it is we're about to make. We might make a game. We might make something artistic. We might make some kind of animation. But anything you want moving around on the screen or doing something interesting is called a sprite. And the default one you get for free out of the box happens to look like a cat. Now the thing that the Scratch sprite is on top of, the big white square, is what's called the stage. So that is his little world. Up, down, left, right diagonally. That is the stage on which the sprite can move. On the bottom right, we'll see all of the sprites we've created. At this moment, we just have one such sprite. That's why we have this guy here. In the left-hand side, though, is where things start to get interesting. These are the puzzle pieces we alluded to earlier, or the building blocks, literally, of a particular computer program. And what you'll do in just a moment, or what we'll do as a class in a moment, is start dragging and dropping those puzzle pieces much like a moment ago. If I was typing stupid things like PRINTF for printf, we're simply going to drag and drop the equivalents here. When I typed W-H-I-L-E for a while, I'm just going to drag the puzzle piece that happens to represent the loop in just a moment. And in the middle is where I'm going to actually drag all of those puzzle pieces to, and where I'm going to write my scripts, a.k.a. programs. Now to wet your appetite, what I thought we would do, though, is open up this particular one, which was actually made by a former student. And let me go ahead and double-click the wrong icon. Do you want to come on down for your game-playing exercise? Just to give you a sense that, though this might actually be targeted at young demographic, you can actually do really neat fun things with it. Oh, come on. So I'm going to make this full screen by clicking the appropriate icon. And the instructions here are right here on the screen for you. In a moment, I'm going to go ahead and click the green flag. Notice at the top right, there's two signals. Green flag means go. Red button means stop. So I'm going to click go. And then you're going to play with the equivalent of DDR, for those familiar, the game where you move your feet quickly and have to interact. You're going to use the arrow keys instead. So there are your definitions. I'm going to click the green flag. And as soon as you're ready, can you crank up the volume? Go ahead and hit the space bar when you're ready. I'm probably going to switch the audio over to yours. I did. It'll start in a second. Left. Left. And now as he hits the arrow key in lock step with the animation, notice that the numbers at the top, the so-called variables, are actually being incremented. And now think for yourself. Even though we've just begun talking about programming, how would you implement some of these ideas? Clearly things are happening again and again and again. If you're watching closely, they're happening faster and faster. So somewhere there's a variable that's actually controlling the speed of all of this. So we have loops somewhere. We have multiple sprites, multiple programs. That's just hard. Multiple variables. I'll give you a few more seconds at it. Come up on the chorus one more time. But you've all probably seen at least various arcade games that it might be as relatively simple as this. The basic building blocks that we've already covered tonight are really what compose those programs. Yeah, it's out of control now. All right, a big round of applause. So before I hand scratch off to Dan, let's now not start with maybe one of the more impressive things you can do. Let's take a step back. Just how do you do something like hello and how do we begin manipulating this interface? Well, I'm going to go ahead and just create a new file for myself, which will close off this particular scratch project or program as it's called. And now I just want to have the cat say hello, just like I did more esoterically by typing commands before. So notice at the top left here, above all of the available puzzle pieces or blocks, there are different categories of blocks. And nicely enough, they're all color coded. That's consistent with their type of logic. Loops are all one color. Statements are all another color. Variables are a third color. So notice this guy is pretty much the equivalent of that keyword we used before called main, which was the main part of my program. This is kind of the same thing as main because it's saying literally when the green flag is clicked, dot, dot, dot, do something. Just like the main keyword did before. Well, what do I want to do? Well, it turns out under the looks category. And the first time I use this, I don't know where the heck it was. I just poked around, clicking around the categories. And oh, there it is. Say hello for two seconds. So I'm going to drag this. And now notice as it gets close to the existing puzzle piece, notice the line appears. That means, hey, this will snap into place here if I let go. So here I go, letting go. And it snaps together, fitting together, much like a puzzle piece. So what's nice now is done. No semicolons, no indentation, no stupidity, honestly, just the idea that I'm trying to communicate to the interface. And so if I now go over here and click the green flag, and I'm not going to bother filling the screen this time because it's not interesting enough, here we go, green flag click. There it is. Sorry, my max a little slow. There it is. So let's do it again to prove that it did actually work. I think, frankly, the reason it's being slow is because I'm doing this in the background. So let's just minimize that. But I want to see how high we can get. So green flag, there we go. Hello. All right, let's take a five minute break. When we come back, we will make our own DDR, or with the building blocks, at least. All right, as Dan would say, hello, everybody. Welcome back. That's right. So I smelled something burning during break. And I got a little suspicious after scratch being slow. So I pulled up that thing called Activity Monitor. And what strikes you about the top of this list? Yeah, so that infinite loop is not such a good thing. And so literally, this machine, this mag, is getting hot to the touch because it is so operating at full duty cycle, really churning away, consuming the entirety of my CPU, of course, to the detriment of scratch. So I'm going to fix this while Dan drives us with his own version of scratch on his machine. All right, so switch me over. All right, here we go. So scratch has a lot of these same components, or these same building blocks that we saw in the first hour. So these statements, for example, these statements are a way that we can actually do something. So what we saw before was a statement that said hello. And that was the point of the statement. There's a variety of statements that are available to us. So we can actually do something like we can print out some text using this say statement. We might be able to wait a certain number of seconds. So we can actually pause the operation of this program for a certain number of seconds with a separate statement. Or we can even do some really fancy stuff like playing sounds, for example. We could import some sound files into scratch and be able to play them whenever we want. Doing it at a specific time requires a little bit more complexity, but you can imagine that if we just have some of these statements, we would then be able to do something with them. So how can we actually implement some of these? Well, we have this just very basic program, recall. We have the very beginning block that says, when flag is clicked, we say oh-hi world. And then when we hit run, it will actually say oh-hi world. Now what we might want to do is actually combine a number of statements together so that we have not just a very, very simple program, but that we can accomplish something that's a bit more interesting. So maybe not quite yet to that complexity of the DDR-like game that we saw just a minute ago, but maybe we want to do something a little bit more interesting, like we want to wait a certain amount of time. Let's see. Where is wait in here? There it is. We want to wait a second. Then we are going to say something else. And then maybe we will wait another second. And then maybe we will say one more thing. And I will just change the text so that we can see how this actually changes. All right, so now we have this program. And so what's important to realize about Scratch is that you're building these statements, one on top of the other. And just like with a program that you write in a programming language, the computer interprets it. Starting from the top, it just goes one at a time. It starts from the top and just goes from top down. So it doesn't necessarily or never, unless you tell it to, goes out of order. So it's not going to skip from the beginning to the middle for any reason whatsoever. With this program, it's going to go, it's going to, when we click the green flag, it's going to say, oh, hi world. It's going to wait a second. Then it's going to say hello. Then it's going to wait another second. And then it's going to say hello again. And so just to prove that this can happen, we will run it. OK, so it says, oh, hi world for one second. Then it, all right, did it faster than I can say it? But you saw what happened. It said exactly what I said it would do. OK, now it's important to realize also that all of these statements and, well, the say statement is relatively easy to replicate in all of these other programming languages. So you saw, for example, the C example, the Java example, the PHP example. And frankly, even though it was a little bit cryptic, it's not all that difficult to get it to say or to get it to print out something. So if you just copy and pasted the source code that we showed you, you would then be able to relatively easily get it to print out additional things just by copying and pasting that one line of code that said hello, altering the text as you wanted or doing what have you, whatever you want with that particular text. But other things that we can do in Scratch are just a lot more difficult to do. So this is sort of where Scratch really shows its power. So a lot of this animation, showing graphics, playing sounds, playing different things, it's very easy to do in Scratch. But you might get a little bit disillusioned. If you're playing with Scratch, you do this really amazing, really awesome program. And you try to do the same thing in one of these other programming languages. You'll find that it becomes much more difficult in order to play a sound and see, for example, it's just going to be a lot more complicated than it will in Scratch. And so it's just important to realize that with Scratch, you can do a lot of these things very, very easily. You can create these statements, or you have all of these statements available to you that do these really nice, really fancy things like movement, animation, sounds, et cetera. And it's just complicated to do most of these things, except for these very basic building blocks, these programming, like building blocks that we've been showing you, if statements, loops, et cetera. It's difficult to replicate that in a separate programming language altogether. All right, so my CPU is back down to like 0%, so I can be useful again. Let me grab my own point in the PDF here, and let's add some ZAs now to this. So we only did the equivalent of print thus far, but it turns out, as we saw with the example Ian played a moment ago, that you can have sounds too. So let's see if we can't really leverage the idea or exploit the idea that this thing is a cat here. So on the left-hand side, we have a recreation pictorially of what Dan just did. And on the right-hand side, just in English words, what's this thing gonna do if I run the program on the right-hand side now? All right, so it's gonna play sounds. It's gonna do the same kind of thing, but this time audibly. So let me go ahead and load up a new project. I'm just gonna reload Scratch, and I'm getting a little more comfortable with it, so I'm just gonna start from Scratch, no pun intended, and go when green flag clicked, and then I'm gonna go, let's see, sound, all right? So there's a lot going on here, but I'm just gonna go with the first thing I see. Top left, it says play sound, meow. And so notice here too, Dan typed in words like hello and hello again, those were what we called arguments or parameters when I was typing at the keyboard before for printf. Remember, printf takes something in quotes in between the parentheses, that was an argument? Same deal here. Sometimes Scratch presents you with arguments with drop-downs instead of with text, but this is because I could really get crazy here and record my own sounds. So you can actually start to have fun with this. So I'm gonna go ahead and just say one sound once first. So let's see if my speaker's up loud enough, we'll hear it. All right, so we're on our way. Now that's just one meow. Let's see if I can't now augment it like Dan did, with let's wait for two seconds, and now let's go back to sound, and let me go ahead and play the same meow again, and then let me do two more seconds of waiting, and then one last time, well, I actually meow. All right, so now let me go ahead and hit play. All right, so it's kind of cute, but you can immediately see this is a bad road to start going down if I wanted to meow again and again. I'm already kind of starting to do the equivalent of what? A copy paste, right, which I did at the keyboard before. This could very easily degrade into a stupid looking program where I just copy and paste ad nauseam, and then that's aesthetically ugly, but what else is bad about this approach that I might take on first instinct of just copying and pasting previous blocks again and again and again? Why could that be a bad thing in the long run? Yeah, yeah, exactly. If I wanna change the sound, maybe change it from a meow to like a woof woof or something I record with my own voice, I have to then change every darn block, and if nothing else, that's tedious for the human, and programming is not actually supposed to be tedious. It should actually be fun and interesting, and so having things easily updated is a very compelling reason to do things in a more intelligent way. So you know what? I'm gonna actually go back to the control constructs here, scroll down, and you know what? Let me just click and drag so you can break these puzzle pieces apart, even after you've been working on them. Notice this, scratch doesn't quite call it the same thing as some of these more modern or more traditional languages. So scratch is a real programming language, but it definitely does something differently vis-a-vis these, but there is a forever block. Now, you might think on first glance, wow, I can barely fit one meow inside of that block, but what's nice about scratch is that these puzzle pieces will remain the same shapes overall, but they'll expand to fill as many pieces as you wanna cram inside of the loop, and here too is a nice detail. The forever block is intentionally kind of horseshoe shaped, much like the idea we've been trying to convey with parentheses or curly braces that open and close or just the indentation we used with our socks example. So I'm gonna go ahead and rip this apart and I'm just gonna grab a play sound meow right in there. And you know what, wait, I seem to have consumed the space, but if I drag now my weight block, I gotta move them farther away so they actually unstick, notice that if I cover close enough, it'll start to wanna go in there and if I let go, sure enough, it will expand to fit the puzzle piece. So now let me zoom out and hit play now and let's see what happens. Your turn. Okay, now I have two seconds to be able to talk to you about the next thing that I actually want to say, and that is, oh my gosh, this is, okay. So if I actually want to be able to do something a little bit more interesting, so maybe I want to actually have this fork in the road, for example. So yes, we can loop these things forever and ever and ever and ever, but that's going to get annoying and repetitive very, very quickly. There might actually be cases where this is actually very useful, very interesting for our program, but playing a meow sound over and over and over is not probably the best use of doing this. So maybe what we want to do is have some sort of control flow or having a way of altering the direction of a particular program. And so we saw how we could do this with the algorithm, the SOX algorithm before, using those if statements. So if something is true, then we'll accomplish some task or we'll accomplish some statements. Else, if it's not true, then we'll do something else. And so this exact conditional statement, this exact construct, is available to us in scratch. So just to show you an overview, just of what we are about to do, take a look at this program. What does it say? Just read it out loud, what does it say? So when flag is clicked, if one is less than two, then play sound meow. That's exactly, so will this be an infinite loop? That's right, why not? Right, so it is not an infinite loop because there is no loop in this case. So it is just a conditional statement. So if one is less than two, it will play the sound meow and then that's it. There's no subsequent step and it's because there's no loop, it doesn't go back up to the beginning to apply this same logic, to apply the same Boolean logic as it's called. It doesn't perform that test again, it just ends. If one is less than two, it plays the sound meow and then that's it. So let's just show that this works. Okay, well it was now much quieter. So one is less than two, so in this case it plays it and then it stops, it's done. But how are we able to accomplish this? So realize that if we have, or if we are adding a so-called conditional statement and realize that all of these statements are available to us under the control section within scratch, if we want to accomplish one of these we can just drag the if block to the appropriate place where we want it and notice that there's nothing in it yet. So there's still this empty area right within the block where we can fit statements and in this case, in this example we had the play sound meow statement but there's another empty block as well. This little trapezoidal something diamond shaped, I don't know, geometry was so long ago. This little shape that allows us to put in Boolean statements that we can combine in multiple ways to be able to perform this relatively trivial question that the computer will be able to answer for us. So in this case, notice this third block from the top is that green less than and the shape of this block implies that it can fit within that same shape in this if statement and so we can then just find this particular block, drag it into the if statement and then apply whatever values we want within it. So in this case, you notice that again it's color coded so we can go to operators and we have a variety of operators available to us. So it starts out with some pretty basic operators plus minus times divide but those aren't the right shape and it doesn't make a lot of sense logically either to be able to fit one of those if two plus two what does that even mean? That doesn't make any sense but we could do something with that but just not right now. What we need to fit inside of this if block is a so-called Boolean statement. It is a statement that actually performs a Boolean comparison to the end result of which should either be true or false. If it's equal to anything else, it doesn't make sense, right? If something is true, then you do something otherwise something else. There's no sort of ambiguity allowed in this case. So we have to look at the statements that will answer that specific question. Is something less than something else? That is an example of this Boolean statement. Is something equal to something else? Is something greater than something else? All of these are Boolean statements that we can use within this if block. So I can just drag it in here and then I can literally type in some values inside of this Boolean statement. If one is less than two, then I would be able to put in some statements whatever statements I wanted to be able if this statement was true then it would run those particular statements for us. But here too, we have a contrived example. What if we actually want some dynamism? Well, if you don't mind my steering here for a second, Dan pointed out that not all of these green blocks are the same shape. In fact, there's this guy here. It turns out that even though computers only do what you tell them to do, they can kind of do things a little randomly. Now they're actually using some fairly fancy mathematics to create the illusion of randomness because at the end of the day, a computer can only do things you tell it to do and it can't do vague things like, give me a number off the top of your head. Like, what does that even mean? But the world has figured out ways mathematically to approximate that and even Scratch has as well. So if instead of putting in the number one and two arbitrarily, let me go ahead and instead clear these back to blank, drag this guy here. And so now notice that the condition says if pick a number from one to 10 is less than something. Well, let me be a little clever here and I'm going to actually pick the value, let's say, six. Because what percent of the time will the number of the computer pick, assuming it's actually choosing random numbers, be less than six? Yeah, so half of the time. So this is a way of expressing half of the time do the following or put more casually, flip a coin. And if it comes up heads or it comes up tails, do the following. Well, what do we want it to do? Well, maybe we want it to play a sound like before. So let me go ahead and choose play sound meow. Although you know what, let's actually introduce one other feature. This is more of a fun feature than an intellectually interesting one, but it's how you can really start to dive in and get carried away. Instead of doing meow here, what I'm going to do is not record because I really don't want to embarrass myself, but click on sounds. So notice we have scripts by default, costumes, which is what the sprites look like, and then sounds. And notice I can click import or record if you have a mic, but import. And then what's nice about Scratch, when you download and install it from MIT's website, comes with a lot of example. Projects, a lot of example sounds, a lot of example costumes. And you can really get carried away. If I go here into the, let's say, animal folder, there's a cat. If I go down the list, can you raise your volume? Some crickets? Oh, that got the most immediate laugh. So let's go with the duck sound. Now notice I have two sounds in my little palette here. So if I go back to scripts now and play not sound meow, but duck, we're going to have a pretty weird-looking sounding cat. But I'm going to hit the green flag now. Wait a minute, nothing happened. Why? It must have been 6 or 7 or 8 or 9 or 10 and not 1 to 5. Let's try again then. Uh-oh, coin came up heads again. Ah, there we go. Let's do it again. Oh, that's pretty good randomness, 50-50 so far. No? No? OK, so feels like it's a coin toss. And in fact, it is. And so randomness is actually a big part of computer programs, even if you think of the simplest games. Games would be pretty darn boring if every time things happen in precisely the same way, that was actually the way things were years ago. And even now, if you play Super Mario Brothers from the original Nintendo, the reason people can win it incredibly fast is because everything is predictable. There wasn't really all that much randomness, certainly not when you first start the game. But here is the basic building block. Just doing something simple, like simulating a coin toss, can you actually have your programs behave in interesting ways? Good question. So Scratch does not have the greater than or equal to block. They just decided, eh, just add one number to the other side and you can approximate that. But you do have that typically in more traditional languages. Good observation. There's no less than or equals to sign or the opposite. Other questions? For that reason, it hopefully should be apparent why this works at 50-50 probability rather than, say, 60-40. The reason is that it literally means less than 6. And that includes the numbers 1, 2, 3, 4, and 5, which is half of this random block of 1 to 10. And so if it was less than or equal to 6, then, yes, it would be 60% probability that we would play this duck sound. But because we don't have that particular capability, we have to use this less than sign and is therefore 50%. So now recall from our SOX example that we were able to have an if condition, a branch, and then inside of that, so to speak, was another branch. If we actually found the SOC, then also do this thing. Well, we can actually achieve a similar result using most any of these languages, including Scratch. So just like in our English-like syntax and incidentally, the SOX example, if you hear this term again, was called pseudocode. It's kind of code, but it's not really. It's mostly English. It's just our fake David and Dan language that we use. It's called pseudocode. You can still do the same kinds of things in Scratch. So if you wanted to have a fork in the road that either goes this way or that way, you don't just use the if condition, which pretty much says either go this way or go nowhere, like Dan just did with his example. Or you can have this other two-pronged fork. If something do this, else do that. Now, if you want to have three directions, well, it'll eventually get to be a little weird looking. But you can certainly nest these structures. And conceptually, it becomes if, else, if, else. And that, in fact, would be a three-way decision point and mutually exclusive. If you think through the logic of an expression like this, if, else, if, else, that means you're only going to go in one of those directions, not two or three optionally. It's only going to be one of them. So we can actually take advantage of other features of Scratch now. Rather than only interact with, like, mathematics, like random number generators, we can interact with the user as well. So I'm going to go into a folder of examples here. This is version six of our high example. And incidentally, if we've not said it before, this way of spelling high, H-I-A-I, is just a stupid internet ism that is maybe falling out of disuse. We should probably get rid of this next year. Let's see if we can't now make use of some of these additional features of Scratch. So right now, just to be clear, we have an example like that before. It's just this meowing ad nauseum. It's an infinite loop, but it's intentional. You can imagine programs having intentional loops intentionally. Infinite loops intentionally, if you actually want something to go on forever, but this just quickly gets annoying. But let's see if we can't have the cat meow only under certain circumstances now. So let me open up this next variant. And for time's sake, we came with some of these examples prefab, so we don't have to manually do each and every one of them. Take a look at this guy. In English, what does this do? Just define this program in a sentence. Perfect. So when you put the mouse pointer on the cat, or put more specifically, if the sprite is touching the mouse pointer, what do you do? Play it the sound. Wait two seconds. Well, let's see what happens. I'm going to go ahead and hit the green flag. Nothing's happening, though, why? OK, right. Obviously, I'm not touching the cat. So if I move my mouse now, oh, and move away, nothing. So this is sort of our petting the cat example. But now it's beginning to get a little more of an incarnation of a real world problem. How would you simulate petting a cat? Well, you might do that. Well, if we take things up a notch and use that nested construct, here's another variant of this. What's going to happen with this version of the cat petting? Good. So this is the don't pet the cat example put another way. So let me go ahead and play this. And it'll make sense that definition in a moment. Cat's meowing away. He's perfectly happy. But then I move my cursor over to touch him. And OK, so not such a good idea. All right, so there we have two decision points, two forks in the road. And just so you've seen it, if you actually don't want your cat to look like that, I'm going to very quickly go back to the costumes tab in the middle. I'm going to click Import. And here's two, where you can waste way too many minutes in the middle of the night picking some other appearance for your sprite. For instance, we could make it look like a shark, but still meowing like a cat. So you can start to do interesting things. And these, again, are the basic building blocks that our own students used to implement that DDR game. She instead chose the sprite to look not like a shark, not like a cat, but rather like an arrow pointing in one direction. And she used a loop that said Move up and down. So in fact, we should probably do one example where at least the cat is moving. OK. Is that the beauty of your charge? Well, I was going to go in a separate direction. You did that real quick. All right. Oops. OK. All right. So let's actually make the shark, let's say Move. So I'm going to go ahead and just get rid of this. If you want to get rid of your scripts, you can just drag it to the left let go and it disappears. So now let's just make the shark Move, because surely we saw from the DDR example, you can have Movement. So when the green flag is clicked, what do I want to do? Well, there's a Motion tab. We've not yet clicked. But here, too, is where this is intentional. We're not going to walk you through every one of the blocks and scratch, because it's very uninteresting. But it's notice the richness of what's there. You can start playing around. And if you can imagine a game or your animation doing something, the challenge, the puzzle, so to speak, is really in figuring out how to wire these things together. And that really is what programming is all about, whether with puzzle pieces or with syntax like that before. So let me go ahead and move 10 steps and run this program now. OK. Not very interesting. But if I run this program again and again, all right, I seem to have the illusion of animation. How do we fix this? How do we make the thing glide across the screen? Yeah, so do that forever, right? Maybe he'll hit the wall at some point. But let's see, as a first version of this, forever do the following. Move 10 steps. Go ahead and click the green flag. There he goes. Now he's gone. Now wait, I can pull him back. There he goes again. And he's going pretty fast. Let me slow this down. Have him move one step at a time, one step on each iteration, thereby slowing the effect of this loop. And let me hit Stop. Let me drag him manually over here. Whoops. There we go. And now click Play. So it's kind of a boring game. But it occurs to me there are actually some other sensor blocks. You can actually have multiple sprites interacting with each other. Now I could do this manually. If I play around, you'll notice that if I click this link here, this icon here rather, I will get a sort of MacPaint style thing where I can draw a new sprite. Or I'm not very good at drawing, certainly. You can click this to choose a new sprite from a file that would give you an existing character, much more effective. But I'm going to skip those steps entirely and just go to something that I made in advance. Let me quit this and open up Move 2.sb. sb is the file extension for Scratch. And now I'm going to hit Play. You can actually have the sprites interact with each other. It seems that one sprite, in this case the cat, is pointing perpetually toward the bird, the game being cat and mouse. OK, so that was a little inappropriate perhaps. But you can see now that you can start taking one sprite, figure out how do I get him to move around kind of randomly. And once you have one sprite, you can add another sprite and say, all right, how can I make this sprite interact with the other? And so a key takeaway when you tackle a Scratch program for yourself for an upcoming homework assignment is you're not going to want to sit down and decide, I am going to make DDR, just like that other student, where to begin? You need to think about, just in very real world terms, what are the basic components of that program? You don't have to know a priori how to implement DDR, that game we played earlier with Ian. But think about it, all right, I need an arrow to appear at the top left. And you figure out how do I make a sprite look like an arrow? How do I position it at the top left? There is a puzzle piece that says set x, y, x being horizontal, y being vertical, set it to a specific coordinate. If you think of the stage as a grid of pixels, all right, so that puts an arrow in one place. Now how do I make it move? Well, we've seen there's a move block. We've seen there's a forever block. Surely I could figure out a way using these basic ideas of just making that arrow move down or move up, depending on my goal. In other words, our student did not sit down and write DDR over the course of an hour just from start to finish. She literally implemented little building blocks or literally took baby steps toward the final picture. And so that's important because it's very easy to get overwhelmed if you have a vision and have no idea where to start. We'll just pluck off the easiest aspect of it to actually begin. So in this case here, notice that this is actually more sophisticated than most of the programs we've seen before. But notice right now I have the cat highlighted. The cat's scripts are not all that long. There's maybe 12 puzzle pieces there, 12 lines of code, if you will. And if I click on the bird, I'll see his scripts. Also it's pretty short. So let's see. It feels like it's the bird who's in control at first. He's the one running around dictating the cat's direction. So let's zoom in on the bird. How is he doing that? So when the green flag is clicked, there's a puzzle piece called go to. And you specify x and y. And this was just trial and error. If you didn't notice already when you move sprites around by clicking and dragging them, notice that in the bottom right hand corner you see the x, y coordinates. There it goes again. So I just trial and error to figure out where I wanted the guy to start. And now if I look back at the bird, let's zoom in. All right, point in a direction. Well, if you recall the definition of a circle, you have 0 degrees all the way around to 360 degrees. So just trial and error. I decided I like the angle 45 degrees. That's how I want him to begin into this program. But again, completely arbitrary. And now here's another type of loop that Scratch supports. But you can infer just from the English letters on it what it's doing forever if. So this is kind of a special construct. It's like a loop and a what combined. It's a loop and a if, a condition, a branch, a fork in the road kind of merged into one. And that's OK. Because if you just understand the concept on the blocks, it kind of tells you what it is. So do the following forever if you're not touching the cat. Now the point here was just to avoid a stupid mistake I might make if I have the cat in the mouse touching initially. I don't want it to start moving. I want it to just stay where it is. Why? Just because. That's what I wanted it to do. So this is the other lesson to take away ultimately from this assignment. If you want to accomplish some goal with the program, there is probably an infinite number of ways you can do it. Now the downside is there's probably an infinite number of stupid ways to do it, among them copy, paste, ad nauseum. But there's more than one smart way, certainly, to do these things. So take comfort in that many different ways to do it intelligently. What does the bird do? Well, just forever he moves three steps. That kind of speaks to his speed. Then if he's on the edge of the screen, he bounces. And this is a special scratch block, so I don't have to figure out the angles or the mathematics. Just bounce off the edge. And that's it. That drives the entire bird's behavior. And now if I click on the cat, let's see how I got to the point of this chase game. Well, when the green flag is clicked, the cat starts at that location, trial and error. I just arbitrarily decided where I like the cat to start. Point in what direction? Well, I did want this game to be a little different each time. I didn't want it to be completely boring for the audience. So I said, at least start the cat pointing in some semi-random direction, and then do the following forever. If you're touching the bird, we'll play that lion sound, and then stop. Stop script. Else, and now notice this is kind of an implicit else. And here, too, is an example of doing things in different ways. I could do an if else, or I can just do an if, and then put the else part after it. Because logically, it's just going to flow from top to bottom. Else, point toward the bird, and that is a special scratch block. Point towards the bird, move one step. So notice the cat is moving faster or slower. So a little slower, but the idea is that even though the bird's moving three paces, the cat's moving one, eventually the cat will catch up, because the bird again is just bouncing on the edge stupidly, randomly, whereas the cat is actually targeting his prey again and again. And so the end result is this animation that's a little different each time, but the end result eventually is that the cat will catch the bird. All right, so all of these scripts so far have been relatively basic in terms of all of the information that we've been using has been hard-coded. So every time that we did an if statement, or every time that we did this forever if statement, we actually typed in these values, except for this random example. But still, we explicitly told the program what values to use. So you might imagine that we want to add some additional complexity. Maybe we want to be able to have a counter of some kind. So if we have a game, maybe we might, for example, in this particular program, maybe we might want to be able to record. Rather than just stopping the script, we want to be able to record how many times the cat actually caught the bird and just allow it to keep going. Or maybe we are just accomplishing some goal in that a person has to be able to reach a certain number of, I don't know, whatever it is in your game. So like this DDR example, this DDR example, where it actually counted how many of each arrow key was hit correctly. So we would then need to use something that allows us to capture and retain this information, be able to change it appropriately, and scratch. Just like in these other programming languages, and we just saw an example of it in that pseudo code, in that example algorithm involving the socks, scratch supports variables. And a variable is just the named location. It's just a place in memory that has a name that holds a certain value. So we can find out what that value is just by referencing that particular name. And so in this case, we have created a variable called counter. And at the very beginning, what is that first line of code called? So not the one that says when fly click, but the one after that. What is that? We called it something earlier in the algorithm. What is that called? We're doing something. Yeah, so we're initializing or we're setting the variable to some value. We're just giving it an initial value. Otherwise, if we don't do that, we have no idea what counter would be equal to when we first start running this program. So we have to give it some initial value, some known value, so that we are sure that we give it just something that we are aware of, just so that there's no sort of ambiguity in this particular case. So there's this variable that's called counter. We're setting it equal to 0, and then we have a loop. And now what we're going to do is instead of just saying a word or a phrase, we're going to use this counter to show us what this counter is now equal to. And so we wait a second, and then we do something. We change that counter by 1. So we increment. It's like that socks on feet plus plus line, for example. All it does is it just takes the value, adds 1 to it, and then now counter is equal to that value that's been incremented by 1. So if we hit play, we should then see what exactly happens. So it starts at 0, and then every second, it increases by 1. So there is a counter. There's a number somewhere in memory that's just increasing by 1 every second, and then we are printing out this data. And so while you may not want to do this, unless you are unable to sleep and need to count sheep, what you can do is use this variable to just track some numerical piece of information that will be very, very useful. And how do you do this? Well, there's a special section within Scratch called Variables. When you select that section, you'll notice that we have not only a few statements that are available to us to allow us to modify or retrieve some of the information from this variable, but we can also do some things like create a variable. So you might imagine that there might be cases where we would want more than one variable. So maybe there's two states that you need to be able to maintain. Maybe you want more than one counter. Maybe you want to be able to keep track, let's say you're making a soccer game, for example. And you want to be able to keep track of how many goals each team is making. You don't want to have the same variable for both. That's just stupid. Nobody's going to lose or nobody's going to win, depending on how you look at it. So you need to have one variable for each team to be able to determine who will be the winner of that particular match. So to create a variable, there's a little button here that says Make a Variable. And it brings up a new window. And this window, you can give a variable a name. Now, conceptually, you might be able to figure out why you would not want to have two variables have the same name. It's just not going to work. The computer's not going to be able to distinguish between the two. And most likely, and hopefully scratch, will not allow us to actually create two variables that have the same name. But what you might want to do is have two separate variables that are unique in some ways. So maybe you want to be able to count the team one score, and you want to be able to count team two score. Well, you could just create a new name or a new variable for that other one. So in this case, just counter two. So the second counter in this particular case. And your variable names should probably be a bit more descriptive. But again, this is just as an example of how you can actually create a variable. Now, we could hit OK. But there's one more option that we're given here as well. There is an option that says for all sprites or for this sprite only. And so this brings up this idea of globalization or localization, rather, where this variable actually exists. So for all sprites means that this variable will behave pretty much like you expect. All of the script. So as in this example that David showed before, we had two sprites, there was a bird and there was a cat. And you could make it so that each sprite had their own variables. But that may or may not be appropriate for whatever it is that you are trying to accomplish. Instead, what you might want to do is have what's called a global variable. So a variable that's accessible by all of the scripts. And in other words, that means that if we have a counter two and we have multiple sprites, then all of those sprites, all of the scripts within those sprites, would be able to access this counter two. And so this is the default for a good reason. Because this will behave like you would expect. If you have multiple sprites and you need to access that counter, then you will make sure that this selection, this for all sprites, where this global variable is then created. So I'll just accept the default for now and hit OK. And then you'll notice that I have a list of variables directly underneath these buttons. Counter and counter two. And what I can do is then just modify this set counter to whatever, to whichever variable it is that I want to actually modify. If I want to set both equal to zero, then I would need to add an additional puzzle piece. Let's see, move the forever block, set counter two to zero. And now I've initialized both of these variables to be equal to zero. So no, so in this case, all we've done is we've just created a new variable. Because we haven't actually told the computer to create a second sprite, there is no other sprite. It's not actually going to say counter two. It's not going to say both counter and counter two. This should behave the same way that we saw before. It's the sheep, and it just says counter. The reason for this is that we don't do anything with counter two currently. We could add another sprite, and then we could also have another loop for that sprite that increments this counter by one. And then, or maybe it starts a different number and increments it by one, or decrements it by one. It's just some other value other than this. But until we actually do something with that other variable, then nothing happens. Now you'll notice that if you check these two boxes over here, underneath the make variable, delete variable, this lists the variables that you have. And if you check them, what Scratch will do in this stage is actually show you the value of those two automatically. And so we can get a better idea of what's happening if we just take a look at the value of counter two and counter. We see that counter is incrementing. Your sheep example is very effective. What? Explain later. OK. So we have counter and counter two. Oh. All right. That's not very nice for you to point out on camera. So we have, now it's funny for everyone. Anyway, so we have counter and counter two. And we can see that counter two is actually not incrementing. And the reason for this is that we're actually not changing it in this loop. We're not doing anything with counter two. So it's not going to be modified. Because we haven't explicitly told the computer to do something with it. We've just set counter two equal to zero. It's not actually going to modify that or display it. We could change everything to counter two. And then we would see sort of the opposite effect. We would see counter two increment. We would see counter two be printed out. But then we would not see counter one change in any way. So it turns out there's another type of variable that we saw toward the bottom of that set of blocks. And it's called a list in Scratch. But in most programming languages, it's called an array or a vector or a linked list. Comes in different forms, all of which have slight differences. But here's one example where you might not want an individual variable, but a growing list of variables. Because that's the downside with a variable like x or y or z or counter. It can only thus far store one piece of data, like a number. But what if you want to have a role playing game, an RPG, like this thing, where this little blue guy starts walking around the screens. And his purpose in life, according to the instructions for this game, is to pick up the pieces of fruit. Notice at the top left, the way the student implemented this game is they drag the variable that was of type list, aka array. So what you're seeing in top left is just what Dan did with the counter. But this time, it's a growing sized variable, if you will. And this is useful so that it can collect all of these different things. Now, how in the world does this work? Well, I'm hitting the arrow keys up, down, left, right. And it turns out one of the puzzle pieces under the sensing category is when such and such a key is pressed. So you can actually listen for specific keys so that you can have the Jungian input for this game as well as for the Dance Dance Revolution game that Ian played before. Here, too, what does it mean to actually add something to your inventory? Well, I'm the little blue guy. When I get close enough to be touching the other sprite, the pineapple sprite, there must be a condition somewhere. If touching pineapple, do what? Add pineapple to your inventory. So again, the very basic building blocks. And so realize, too, even though we're spending a good amount of time today talking about scratch and talking about this feature and that, the end of the day, it's all of those same fundamentals of loops and conditions and variables and statements and Boolean expressions, which are omnipresent in most all languages out there. So do realize that these skills, these concepts, are absolutely transferable. There's a few other topics that are worth keeping in mind, especially as you ultimately play yourself with scratch for an upcoming assignment. One is just the idea of threads. So we've talked about this in our hardware lecture. When you have CPUs, multiple CPUs or multiple cores inside of CPUs, recall that a computer can actually do two things at once, because they are, if programs are quote, unquote, multi-threaded. A multi-threaded program is just something that can do multiple things at once. So Microsoft Word can do this. If you've ever wondered how it's able to do the red underline when you have typos or the green underlines when you have grammatical errors, that's because it can do at least three things at once. It can listen for your keyboard commands. So it actually puts words in your essay. It can simultaneously be checking all of your words grammatically. And it can simultaneously be checking all of your spelling while you type. So in that sense is Microsoft Word an example of a multi-threaded program. Well, Scratch 2 is multi-threaded. You can do multiple things at once. Case in point, our little bird and cat game. That program had two sprites, a.k.a. two threads, each of which was acting simultaneously or in parallel to use a technical buzzword. And so this is useful because you can actually have really interesting things going on on the screen simultaneously. Another example is this one. So this is something actually stole from a teaching assistant of mine years ago at MIT. I replaced his face with mine just because I figured it would be more interesting. And if I actually pick this one out, you'll see that here, too, can you have multiple sprites, in this case three, right glove, left glove, and then opponent, or my face there. If I actually blow this up and hit play, what you'll notice is that if I move the up arrow, I'll start getting punched. If I hit another key on the keyboard, this guy goes. And now notice what's happening to my face. Turns out there's a Scratch puzzle piece that lets you control the color of a sprite dynamically. These are not different pictures. This is just a little color wheel, like Dan showed in Photoshop last week. And if I keep it, there we go. So eventually, you actually go down. But again, the interesting question here is not, oh my god, how do I implement that whole thing at once? Rather, how can I break it down into component pieces? Well, there's a left glove and a right glove that apparently need to be able to respond to keyboard commands. How do you do that? Well, we've shown a few examples tonight, not all of the source code. But the neat thing about Scratch, coming with so many prefabbed examples, is you can look at them. One of them is of a fish tank. Well, how in the world did this kid make the fish tank? Well, what you do is you open the project, look at the sprites, and read through the logic, the code, the scripts, if you will. And you can infer. And you can learn. You can bootstrap yourself just like we preached last week with HTML. So incredibly boring to review all the possible HTML commands. But the reality is, once you've seen it elsewhere in an example, you can now apply it yourself here. Well, what are some of the other designs? Another key feature that you might want to tuck away in the back of your mind is something like this. You can actually have two sprites interact with each other, not just by sensing, by touching, but also by talking behind the scenes to each other by sending what are called events from one sprite to another. So you can have one sprite sort of whisper something to another sprite and have the other sprite listening for that whispered command so that one sprite can influence the behavior of another. And when I say whisper, I don't mean show the word on the screen for the human. I mean, this is more of a back end underneath the hood kind of thing so that two sprites can interact. So here's an example involving a game you might have played in the swimming pool, Marco Polo, where someone says, Marco, and then the kid who's got his eyes closed says, Marco, then everyone else has to respond Polo. And so that is one sprite, one human interacting with all these other humans by sending an event, the event, Marco, and they're supposed to respond with Polo. So here's an example of two sprites, boy and girl. The boy's purpose in life is to do this. When the green flag is clicked, forever do the following. If spacebar pressed, do what? Say Marco for two seconds and then do this other block, broadcast quote unquote event. And I define the word event just to be consistent with the jargon I wanted to use tonight. You can broadcast anything. This does not mean show it in a cartoon bubble. This means send a computer command to all other sprites, any one of which or more of which might be listening for it. So on the flip side, if we look at the girl sprite now, she does not have one green flag clicked. It turns out under the control category, there's other ways in which you can induce sprites to start doing something. One of them is when I receive dot, dot, dot. Well, when I receive that event, that back end underneath the hood command, what does the girl do? Polo for two seconds. So here we seem to have two threads, two sprites, each of which is operating simultaneously but waiting for one human input and the other for a message, a broadcasted event as it's called from the other sprite. So the net effect is this. If I zoom in on the screen, hit the green flag. Nothing happens yet. But if I hit exactly the space bar, he says Marco behind the scenes, she knows to say Polo. If I hit the space bar again, he says Marco, she knows to say Polo two seconds later. And so we do in fact have these two threads interacting. And so if we put all of these building blocks together, you can actually make a pretty neat program. Just like what David did when he had way, way too much free time, he made this program that actually is timed to music. And using all of these things that we've actually seen, did you switch my sound over? Yeah, I did. You can actually time these things so we can drop pieces of trash into Oscar's trash can and we have a counter that detects how many pieces of trash we've actually collected and completely useless, but really, really neat, really fun and a great way of showing you how you can waste a lot of time with scratch, developing something that is actually really, really neat and a lot of fun. So go home tonight, try it out, it's a lot of fun and we will see you next week at the exam.