Lecture 1: Introduction to CS and Programming Using Python

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[SQUEAKING] [RUSTLING] [CLICKING] ANA BELL: All right, so welcome to the first lecture of 6.100L. That's our new number. My name is Ana Bell. That's two separate names, first name Ana, last name Bell-- super confusing. But I've been a lecturer here in the EECS Department for probably almost 10 years now. And I've been doing the intro course for a while. I'm really happy to be teaching this full semester version of 6.100A. So today what we're going to do is go over a little bit of course administrative information, and then we'll dive right into some thoughts about computers, high level how they work. And then we'll start going into some Python basics. So we're going to get coding right away. So I highly encourage you, since you're in this class, to download the lecture slides beforehand, to take notes, and run code when I do. Some of the lectures are interactive. And we'll have breaks, so there'll be a place where you can take a break to actually do some coding. And that's important-- I call them "you try it" breaks. That's important to make sure that you're actually practicing what we are learning right at this time. The main idea for lectures is, yes, I will do some teaching, but there will also be opportunities for questions and for you guys to try some programming right on the spot. Even if you don't finish writing a program that we start talking about, I will finish it, and we can all talk about it together. And I'll show you some pitfalls and things like that. There will be lots of opportunities to practice in this class at various degrees of granularity. And then there's also lots of opportunities that I have in the handouts to do extra practice at home and through a bunch of different resources as well. The reason why I stress participation and practice is because part of the reason you're here is you want to learn how to program. You don't know how to program yet. And programming is actually a skill. it's like math or reading. It's something that you have to practice. You can't just watch me type in a bunch of lines of code And then when it comes time to do the quiz, you automatically know how to do it. You need to do it often, more and more so that it becomes sort of second nature. So the three big things you'll get out of this class are knowledge of concepts, obviously-- we're going to learn some computer science ideas-- programming skill, and problem solving-- problem solving skills. Lectures and exams basically help you with your knowledge of-- test your knowledge of concepts and help you get knowledge of concepts. Finger exercises give you the programming skills. And the problem sets help you with problem solving. Basically, if you're given an English version of-- a problem in English, how do you go from that to thinking about what computer science concepts can I apply? And then after that, how do I take those computer science concepts and actually do the programming? So what are some topics we'll be covering? We will be, at the core of it, learning computational thinking. So in the future, when you encounter a problem, your first thought shouldn't be, How do I mathematically solve this? or, How do I brute force or manually solve this problem? How can I apply computation to help me solve this problem? And throughout these lectures, you're going to see some examples of us applying computation to a problem you might have already seen and maybe solved mathematically, which is pretty cool. Obviously, to get that, we're going to learn the Python programming language. Once we get the basics, we're going to see how we can start to structure our code to look a little bit better so we don't just have a bunch of code dumped in a file. We're going to start to organize our code and see how we can make it neat, readable, and modular. And then towards the-- not in this lecture but in a couple of lectures and as a theme throughout this class, we're going to look at some algorithms. They're not super complicated, but they're kind of the base algorithms for a bunch of algorithms you might see in the future if you decide to take more CS classes. Lastly, towards the end of the class, we're going to see algorithmic complexity, which basically means we're going to start asking or trying to answer the question, how do we know the programs we write are efficient? We can write programs, but how do we know that they're fast, and how do we know that they don't take up all the memory in the computer? So things like that, comparing different algorithms that do the same thing against each other. So if there's no questions-- again, as I said, a bunch of this information is already in the handout plus more-- we can begin. OK, so let's start by talking about knowledge. Declarative knowledge is a statement of fact, and a lot of us probably in math and in the past have worked with declarative knowledge. But this is not how computer science, this is not how this class works. In computer science what we do is we work with imperative knowledge, which is basically a recipe, how to do something. And when we're programming, all we're doing is writing a recipe for the computer to do something. That's it. So here's a numerical example. The first statement is a declarative statement. The square root of a number x is y such that y times y is equal to x. There are many possible values for x and y that this statement can be true, right? But if we gave that statement to a computer, it wouldn't know what to do with it. What we need to do is tell the computer how to find the square root of a number and then tell us what the square root of that number is. And so the computer then needs a recipe. So the recipe, a really simple one for finding the square root of a number, is steps one, two, three. So what we do is-- let's say we want to find the square root of 16. We obviously know it's four, but the computer doesn't. And so we give it an initial guess. Let's say the guess is three. How do we go from there? So the steps we follow-- step one, if 3 times 3, 9, is close enough to 16, we can stop. It's not really close enough for me. So let's keep going. Step two-- otherwise, we're going to make a new guess by averaging g, which is our original guess, 3, and x over g, which is 16 over 3. 16 was the square root we wanted to find. So our next guess is 4.17. OK, using the new guess, repeat the process until we are close enough. So we go back to step one. That's the first part of the process. We find guess squared. 4.17 squared is 17.36. So now we say, is that close enough? Not really. It's not. It's 17. It's not really even close to 16. So let's do it again. We make a new guess by averaging 4.17 and 16 divided by 4.17. That gives us our new guess, 4.0035. OK, next step, using the new guess, we repeat the process. So 4.0035 squared is 16.277-- .0277. Is that close enough to x? Yeah, I could be happy with this. I could stop there because we're within sort of plus/minus 1. So I'm OK with that. But if we want it to be within plus or minus 1 times 10 to the negative 6 or 7 or something like that, then we would continue the process. So really what we had there is an algorithm. It's a sequence of steps-- step one, step two, step three. There's some sort of flow of control. We had a place where we said if the guess is close enough, then we can stop. Otherwise, we do something else. We had another flow of control where we said repeat this thing. So we're kind of not going linearly, but we're changing the flow. And then lastly is a way to stop. We don't want the algorithm to go on forever. We would like to stop at some point. And this stopping point, I was kind of vague about it. But it could be when we were within plus or minus 1 of the actual answer. And so recipes are basically algorithms, right? My grandmother was basically teaching algorithms when she would teach me to bake a cake. She didn't call it that, but she was really. And so even recipes have that same structure. There's a sequence of steps. There's a flow of control. Like, if you don't have egg, use egg substitute. Or repeat sticking a toothpick to see if it comes out clean every minute or something like that. And then there's a way to stop. When the toothpick comes out clean, you take it out of the oven, and you eat it. And so computers are machines that execute these algorithms. They're actually dumb. Computers are not very smart. They don't make decisions on their own. They just follow these sequences of steps that we told them to do. Computers are good at storing lots and lots of data. We can't really do that, but computers can store gigabytes of storage, terabytes even. And computers can do operations really, really quickly, which is something we can't do. They're good at those two things, but they're not very smart. They can't make decisions unless they're told to make the decisions. So really, the computer only does what you tell it to do. And that's one of the big ideas that I want you to come away from this lecture with. Computer only does what you tell it to do. The sequences of steps that you tell it to do, that's the only thing it follows. So a little brief history just to make you appreciate programming, Python programming language before we actually get started with it is-- so before the 1940s, we had these things called fixed program computers. A pocket calculator as an example of that. Every button was an operation. In the little screen, you could use parentheses to put a bunch of different operations together, but there was no way to store all these operations together to later put in different inputs for that same sequence of operations. You had to input it every single-- input those sequences of operations every single time. After the 1940s, stored programs computers came into play. And they were able to store instructions to do things as data. And there was a special program called an interpreter that executed these instructions. It knew how to follow simple sequences of steps. When the program told it to go to a different location, it did. So it was basically executing these instructions. And the instructions that it did were arithmetic and logical, so addition, subtraction, things like that; simple tests like checking for equality between two values; and moving data, so taking this value and putting it at a different memory location. So I just wanted to give you a really brief overview, and this is not super accurate, but it gives you a sense of how exactly things happen low level in the computer. So the computer basically has memory, where things are stored. It has an arithmetic logic unit that does operations. It knows how to add things, subtract things, multiply things, compare things. And then it has the control unit, where this program counter is set. And this is where you put a program in. So let's see if this works. This is a program. And up here is our memory. So we have a bunch of memory locations, 3456, 3457. And at each of these memory locations, we have some values stored, prefilled. So when we first run this program, what ends up happening is that the interpreter sees the first instruction, Add, the values at 3456 and 3457 together. So it goes to these memory locations here, grabs the 3 and the 4, and sends them to the Arithmetic Logic Unit. The ALU knows how to do the addition. So it adds 3 plus 4, 7, and sends the result back here. Now, we never told it to store that result anywhere. But the next instruction says Store the value you just got back from the ALU at this memory location, 3458. So the next step basically takes that 7 and stores it at memory location 3458. Super tedious-- all we did was add 3 plus 4. We do that again. We add the values at 7889 and 7890. So it goes in the memory. It grabs the 5 and the 2, sends it to the ALU. The ALU calculates it as 7, brings it back, and then we store that in location 7891. And then after that, all we've done is two additions. And then the next instruction says Compare the values at memory locations 3458 and 7891. So we're going to compare the 7 with the 7. The ALU again does this comparison and says, all right, well, 7 and 7 are equivalent. So this is true or whatever it wants to give back to the interpreter. And then the last instruction here we have is Print the result of that comparison. So we print True because they were equal. Again, super high level, but it kind of gives you an appreciation for programming languages these days. This is very tedious to write if we had to write programs in this manner. Alan Turing a long time ago showed that you can compute anything with actually an even more basic set of primitives, not addition, subtraction. But instead, with a tape, you would actually have six primitives-- move the tape left, move the tape right, read the value at the tape, put a value on the tape, erase the value from the tape, and no operation. And so since he showed this what the result of it actually was is down here. Anything computable in one language is computable in any other programming language. So if we had some program written in Java, that basically boils down to something super long but something that is made up of these six primitives. That means that if we boil down this program to these six primitives, we can build back up the same program in a completely different language. And that's really powerful. That's a really cool statement. Now, we're not going to be working with those primitives. We're going to be using the Python primitives, which are more convenient, and they allow us to do a lot more things in much less time. I'm going to do a little comparison as we talk about the primitives of Python with English. So in English, some of the primitives might be words or even we can do letters or characters. But we can say it's words. With characters, we can build up words. With words, we can build up sentences. With sentences, we can build up stories. With stories, we can build up books and things like that. In programming languages, the primitives are numbers, sequences of characters, operators like addition, multiplication, division, checking for equality, checking that something is greater than, things like that. So once we have these primitives in a language, we can start to build up the syntax of the language. So in English, having something like noun and noun and noun doesn't make any sense. Cat dog boy doesn't make much sense. It's not syntactically valid. But noun verb noun is syntactically valid. Similarly, in programming languages, we can have two objects kind of side by side. So here, this is a sequence of characters h and i. And this is the number 5 right beside that sequence of characters. But that doesn't make any sense, right? What does it mean to have this sequence of characters and that number right beside it? It has no meaning in Python. Instead, what we have to do is we have to add an operator in between these two objects. So here we add a little star operator in between the sequence of characters "hi" and the number 5. And in Python, the meaning to this is I want to repeat the sequence of characters "hi," h-i, five times. So this would basically give me hi, hi, hi, hi, hi. So once we have sentences in English and expressions that are syntactically valid, we can now talk about the static semantics of the language. So in English, saying something like "I are hungry" is syntactically correct, but it's not static-- it's not-- sorry, it doesn't have good static semantics. There's no meaning-- there is no meaning to that because the "are" is for you or plural. Similarly, in programming languages, and this will differ depending on what programming language you use-- here, in the previous slide, we saw that you can use the star operator between the sequence of characters and the number. And that meant repeat that sequence many times. But if we use a plus operator in between the sequence of characters and a number, that doesn't have any meaning in Python. So it has a static semantic error, even though it's syntactically valid, right? We have operator-- sorry, object operator object. So, so far, we've been able to find really nice parallels with English, the English language and the programming languages. But this is kind of where things break down, when we talk about the semantics of a language. So in English, you can have many different meanings. The chicken is ready to eat means let's eat this chicken. Or the chicken is ready to eat means the chicken wants to eat something. Programming languages, there is no multiple meanings to a program that you write. Because the computer, the machine, the language follows the set of instructions to a T, there is no ambiguity about what it needs to do. It just follows the instructions and does what it needs to do to the end, till it reaches the-- it terminates the program. And so programs only have one meaning, but the problem is it might not be the meaning that you intended it to have. And that's when things start to go wrong. We can have syntactic errors in our program, spelling errors and indentation errors, things like that. And those are easy to catch. Static semantic errors are 90% probably easy to catch. But the problem comes in with the semantics. The meaning that you intended this program to have might not be what it's actually doing. And that's where most of my errors happen. And that's where I get super frustrated when I program. And that's probably where you guys will get super frustrated too because you write a program that you think is doing one thing, but instead, either it crashes right away, or it runs forever and doesn't really stop, or it terminates, but it gives you an incorrect answer. It's not what you were expecting. And we'll talk about this in a few lectures. So when we write programs, we're basically writing sequences of definitions and commands. And we're going to write these either in a file editor or in a shell. The first, today at least, we're writing in the shell directly. And half of tomorrow, we'll write in the shell because we're not really writing any-- we're not really writing many lines of code. We're just going to be-- I'm just going to be showing you some really quick things that we can do with the Python programming language. So hopefully you all have installed the programming environment. This is the Code Editor. So tomorrow, we'll start working in here. But for today, we're really just going to work in the shell. And even in the future, you can still type commands in the shell. I find the shell very useful if there's just something really quick that I want to check, that I don't want to write a program for and then run. It's just like a simple command that I want to check to make sure it's doing what I think it's doing before I insert it in my code editor. So here we have this. So mine is-- I guess I'm using the white theme just because I find it easier for you guys to see. This is the file editor. And this is just a bunch of expressions or-- yeah, a bunch of code that we're going to type in today. And we're going to type it in the shell today, so the thing on the right-hand side. OK, so what exactly do we do when we write a program? At the base of it, we are going to create objects inside our programs, and we're going to manipulate them. That's it. That's what programming is mostly about at its core. Now, when we create objects, it's important-- this is kind of something we're going to come back to again and again in a more high-level setting. But right now what I want you to understand is that when we create an object, an object has a type. And the type that an object has tells Python the things you're allowed to do with that object. So here are two examples. The number 30, it's a number. The type we'll talk about it in a bit. The type is an integer. It's a whole number. But basically, what are the things we can do with this integer, with this number? We can add it to another number. We can subtract it to another number. We can take it to another power. We can take some other number to this power of 30. A bunch of mathematical operations, as you would expect. So that's pretty straightforward. What about this one here, this quotation capital A, lowercase a-- lowercase n, lowercase a quotation? So this is something we'll talk about next lecture. It's called a string. And it's a sequence of characters. The quotations tell Python it's a sequence of characters. And the characters part of it are capital A, lowercase n, and lowercase a. The kinds of things I can do with this string are not the same kinds of things I'm allowed to do with the number, right? If I tried to take Ana and divide it by the sequence of characters Bob, Python would complain very much because you can't divide a string by another string, a sequence of characters. It doesn't make sense to divide it by another sequence of characters. Similarly, I can't take Ana to some power. I can't multiply-- I can't multiply by itself, things like that. But the kinds of things that I am allowed to do on a sequence of characters is different than the kinds of things I'm allowed to do on a number. So the things I can do with a sequence of characters is I can say, well, what's the character at the first position? What's the middle character? How long is the sequence of characters? How many characters do I have? And so now you can see that the type of the object is actually really important. Python uses it to know the kinds of operations you're allowed to do with it. And so there's actually scalar objects, and these are Python's primitives, numbers and truth values. And there are nonscalar objects. We're not talking about these yet. We'll talk about these in a few lectures. But these have some sort of structure. So for example, a list of numbers has a structure because there's a number at the beginning of the list, there's a number at the end of the list, things like that. But a number itself doesn't have a structure. It's just the number. So what are the types of the scalar objects? What are the types of the primitives in Python? Integers, so number 5, 0, negative 100, 1 million. Float is another type. It represents all the real numbers, so 3.27. 2.0 is a float because it has a decimal number even though to us that just means 2. But to Python, if you put in 2.0, it says that's a type float. Negative 3.14159, things like that. Bool is a Boolean. It represents truth values. And there's only two possible values that a Boolean type has, True and False. And it has to be capital T True and capital F False. And the last one is this NoneType type. It's literally called NoneType. And it has only one special value, None. We're not going to talk about it for a bit, but we will sometime in the future. So to figure out the type of an object when you create that object, you use the type command. So we can say something like type parentheses. And this is a command. And inside the parentheses, you say, what do you want to find the type of? So if we do type of 7, it tells me it's an int. And if you want to do the same command again, I hit the up arrow, and it automatically puts in what I wrote previously. And then if I want to do type of 0.0, it's a float because there's a decimal point. So this is basically what I said. So we type this in the shell. And the shell tells us what the output is. So just to reiterate, int, float, bool, and NoneType are types of objects. And there can be many different objects you can create of that type. So if you think about it, ints and floats, we basically have an infinite number of objects we can create of those types because we can have 0, 1, 2, 3, 100, 200, 300, 1 million, and all the negatives. There's almost an infinite number of values or objects that we can create of type int and float. But bool, there's only two, the truth values True or False. And the NoneType, there's only one, this None. So that's the type, and these are the possible values, possible objects we can create. You try it. So you can just yell out the answers. There's nothing to type unless you want to check yourself so what is the type of 1234? AUDIENCE: Int. ANA BELL: Int. Type of 8.99? Float. Type of 9.0? Float. Type of True? Bool. And type of False? Bool. Perfect. If you ever wonder what the type of something is, you type it in here. You guys are doing well. Type is bool. Type of lowercase t true is an error, just wanted to point that out just to reiterate the fact that capitalization matters in Python. This is our first error, by the way, guys. Very exciting. The error is a NameError, and this is the message associated with it. You also know that it's something special in Python when you have color-coded stuff. So you see capital T True, capital F False are this dark blue here, whereas anything that's not special in Python is just black. So type is a special command. This is a float, so you see they're color coded. OK. So once we create objects, one thing we can do with these objects is to cast them to a different type. Now, this is a little bit maybe confusing because we're not actually changing the object once we've created it. So once we create the integer 3, it's there in memory. If we cast that integer to a float version of it, we're creating a new object in memory. We're not changing the 3. The 3 already exists. We're just getting the float version of it and storing it as a new object in memory. So when we do float 3, this is a command that gets for me the float version of the integer 3. So that will give me 3.0. So for example, this is what I had, float 3. The output is 3.0. If I do int of 5.2, it truncates it, and it gives me the integer portion of this float. If I do int of 5.9, it still truncates it and gives me the integer version of this float. It doesn't round. I'm just asking for the integer version of this float. Some operations like round is an operation we can do has an implicit cast in it. So if I round 5.9, it's actually going to round it to 6.0 and then cast it to an integer. So notice it doesn't give me as an output 6.0. It then rounds it to just six. So that's basically what I said in the example. So let's have you try this. What are the types of the following? I don't need the values but the types. So if I get type of float of 123, what is the type of that? Float, yeah, exactly. Yep. What if I round 7.9? What's the type of the result? Int, yep. What if I create a float of the round of 7.2? AUDIENCE: Float. ANA BELL: Yes, good. Float would be 7.0. And the int of 7.2? AUDIENCE: 7. Int. ANA BELL: Int, yes, exactly. I want the type not the value. And the int of 7.9 is an int, exactly. Awesome, good. OK, so we've created a bunch of objects. We know that we can create a bunch of objects in our programs. What do we do with them? Well, we can combine them into expressions. So let's say we have 3 plus 2. I've got object, operator, object. Cool, syntactically valid in Python and has no static semantic error. So if I do that in Python, it's going to be OK. 3 plus 2, 5. And the type of 3 plus 2 is an integer. So basically what I've done here, I've put an expression within this type command. And that's OK. That's, in fact, encouraged in Python. You don't just want to calculate and then stick in. That would be very, very tedious. So you can insert expressions in many, many different places. So here we have 3 plus 2, 5 divided by 3. Again, we've got 5 divided by 3 has this decimal value. And the result has a float-- is of type float. So the important thing to remember when we're doing expressions is Python reads the expression, but it does not store the expression in memory. What it does is it reads the expression, evaluates it to one single value, and then it stores the result value in memory. So it never stores the expression. It evaluates the expression and then stores the value. And so this is the syntax for an expression-- object, operator, object, as we just saw. And that's really-- and the idea I said before, where Python stores values of expressions, not the expressions themselves, is really, really important. So this is my first big idea slide. I decided to insert these because I think they stress the importance of several concepts. So I hope this is one. So we're taking expressions. They can be as complex as you'd like. We can use parentheses, a bunch of-- it doesn't just have to be object, operator, object. It can be more complex than that. But basically, however complex that expression is, we evaluate it, and we replace it with one value. And the expression can be something like this. It doesn't just have to be something that's mathematical. This was a mathematical expression, but this is also an expression. And it evaluates. So this entire thing evaluates to this word, this word which represents the type integer. So here are some more examples. 3 plus 2, again. We've got these examples with the parentheses, 4 plus 2 times 6 minus 1 obviously gives us the number, 35. And then we can insert expressions wherever we'd like. So here I'm inserting that specific expression in the type command. And this is also an expression, like I just said. And its result is int. And similarly, we can also insert that expression here. And then we can wrap that around cast. And it gives us a float. Yes? AUDIENCE: So when you're inserting expressions [INAUDIBLE] include the operators-- [INAUDIBLE] operators in? ANA BELL: When you're inserting-- sorry, when you're inserting what? AUDIENCE: Well, since you said they're expressions, and you said that you need like object, operator, object, expression, type. What would be the operators in this case? ANA BELL: Oh, I see. AUDIENCE: How are they defined? ANA BELL: Yeah, that's a good-- that's a good question. So in this particular case, the type and the float are not-- there is no operator I guess in this particular case. It's more like a command that gives us an output. But there is still some-- there is still an output that it gives us. So we can then take the result of this and save it somewhere else. Sorry, yeah, I guess the example I gave on the previous slide was just an example of an expression where we could do object, operator, object. Yeah. Yeah, so when we have these-- I guess it works for mathematical expressions. Mathematical expressions work left to right, just like in math. Parentheses can override certain precedents. If we have commands that have computations, then we have this command with the parentheses. And we evaluate what's inside the parentheses first. So we work our way in to out in that particular case. So here are some examples. Let's have you try these. So we can type these in our console. What are the values of the following expressions? So 13 minus 4 divided by 12 times 12. So we can try that. I don't know off the top of my head, so we'll have to type it in. 0.0625, OK. So the value of that expression is a float, right? 0.0625. What's the value of the expression type 4 times 3? AUDIENCE: Int. ANA BELL: Int, yeah. What about the type of the expression 4.0 times 3? AUDIENCE: Float. ANA BELL: Yes, exactly. That's very good. So type of 4 times 3 is int. But 4.0 times 3 is a float. Good. And then what about int of a half or of 1 over 2? AUDIENCE: So it's 0. ANA BELL: Yeah, exactly, it's 0. Yep, because it's 0.5, and we truncate to 0. The reason I had this here is because it leads nicely into this slide. You don't have to memorize these rules. You can always check it out in the console. But there are some rules for the resulting types when we do operations. So when we do operations with numbers, addition, subtraction, and multiplication always yield an integer if both of the operators are integers. If one is a float or both are floats, then it gives me a float. Division is different. No matter what types you divide, you will always get a float. Now what about this // and this percent? These are actually useful operations. They kind of go hand in hand with division. So when I do 5 divided by 3, it's this 1.667. // is basically a floor or getting the integer portion of the division. So 5//3 gives me one. It truncates the fraction. The percent gives me the remainder. So 5%3 gives me the remainder when I divide 5 by 3. So it's going to give me-- give it to me in a whole number. So that's going to be 2 because there's 2 left over when I divide 5 by 3. So these are pretty useful operations, the // and the percent, when we do mathematical programs. The last thing is the ** is how we denote power, exponentiation, kind of different than you might be used to in math. So 2 to the power of 3, 8. 2 to the power of 3.0, 8.0. And the rules for integer division, percent, and exponentiation are just like addition, subtraction, multiplication. If one is a float, then the result will be a float as well. Yeah. OK, and we talked about the type of output. So I think I briefly mentioned this. The operator precedence is exponentiation and then multiplication, division, percent or remainder at the next level, and then addition, subtraction at the bottom. But you can always override these using parentheses. OK, questions so far before we move on? Yes. AUDIENCE: So why does division-- why does it always result in float if you have 9 by 3 and that's [INAUDIBLE] why does it [INAUDIBLE]?? ANA BELL: Yeah, so the question is, why does it always result in a float? If it didn't, I think it would the operation itself would have to do extra work to figure out whether it's a whole number or not. So I think it's just easier that it gives us always a float, I guess. Previous versions of Python, the / was actually, I think, integer division, which is super counterintuitive because you would use that in your program. And then you would basically integer divide, and things would go wrong. But again, just a design choice on behalf of the programmers. Other questions so far? OK, so we have a lot of objects. Objects have different types, again, floats, integers, Booleans. What can we do with them? So far, they're kind of just sitting in there, and we can get properties about them. But what we'd like to do is write programs, basically trying to automate some things about these objects, manipulate them to help us achieve a more complicated and interesting program. So what we can do to get to that end is to start assigning names to some of these objects. If I create an object for pi in my program to 20 decimal places somehow, and I have that number in my program, that float in my program-- if I want to use that number in many different places in my program, I'd have to copy and paste it a whole bunch of times so far, which is very tedious, lots of errors will happen. I don't want to do that. So instead what I can do is I can give a name to this ridiculously long value of pi called pi. And then I can just use this name anywhere I want to grab that ridiculously long value for pi in my program. It's a lot easier to read. It's a lot easier for me to write this program. And it leads to a really nice and neat program. So what we can do is we can start saying that the float 0.001 will be referenced by the name "small" or the 100.4 will be referenced by the name "temp." So what we want to do is create these things called variables. And a variable is different in computer science from a mathematical variable or variables that you've known so far in math. So math variables come back to the idea of declarative knowledge, a declarative statement. You can have something like a plus b is equal to b minus 1 in math, or x is equal to-- or x times x is equal to y, and that's perfectly OK. In math, we basically say that variable x represents all the square roots of y. That's not going to fly in computer science. In computer science, we don't have-- we don't do declarative knowledge. We do imperative knowledge. And so what we're working with in computer science is a bunch of assignment statements. So what we can do in computer science is we're going to basically bind a value to a variable. So we're going to say this variable name is bound to this value. Every time I want to grab this value, I'm going to invoke this variable name. So here are some examples. I've got a is equal to b plus 1. The thing on the right-hand side will evaluate to some value as long as I have something that b has a value for. I've got here m is equal to 10. So m is a variable. Its value is 10. I've got F is equal to m times 9.98. So again, I have an expression on the right-hand side, and that's OK. I'm going to use the value of 10, so F's value will be 99.8. Yeah. AUDIENCE: Can you put it so that for F-- is it like this one value of m? Or can you have it so it's going to be whatever m assigned recently? ANA BELL: Yeah. The question is, can you have m whatever it recently is? So in this particular case, I just have these two lines. And m will be whatever 10 is. But we'll see in a couple lectures that we can write a loop where you change m. And then every time you change m, you immediately calculate F. And then it'll calculate F based on the new value of m. But if we just have these two lines, that's all there is. It just uses 10. Was there another question? So in computer science, you have only one variable to the left of this equal sign, called the assignment operator. And you have a value to the right-hand side of the equal sign, the assignment operator. So one variable basically maps to or binds to one value. So the equal sign is an assignment statement. It's not equality. It's not a solve for x type of situation. It's just an assignment. It binds this name to this value. So the way that we figure out the name with the value is, well, if we have this assignment statement here, we first look at the right-hand side. So we always start with the right-hand side. And we evaluate it. Remember, we have an expression on the right. We have to evaluate it to one value. So this will be 3.14, whatever it is, 1.159. And then we take that value and bind it to the name pi. So anytime I type in p-i, "pi," in my program from now on, Python will automatically grab 3.14159 from memory. So it's bound to that value now. OK, there are some rules. Did I have them on the previous one? Yes, there are some rules to variable names, but we'll talk about that in a bit. For now, I want you to tell me if any of the following are allowed. If I do x is equal to 6, is that allowed in Python? AUDIENCE: Yes. ANA BELL: Yes, it is. Good. Because I have one variable name bound to one value, 6. What about 6 equals x? It's just backward. AUDIENCE: No. ANA BELL: OK, good. 6 equals x is bad, syntax error. How about x times y equals 3 plus 4? AUDIENCE: No. ANA BELL: No, exactly, because the thing on the left has an operator in it. And operators are special. So it can't have-- you can't have a variable with that * as a name. How about xy equals 3 plus 4? AUDIENCE: Yes. ANA BELL: Allowed, yes, exactly. I was hoping to get you guys with that, but I didn't. Xy equals 3 plus 4 is OK. There was no error. And then I can invoke the name of the variable I just created simply by typing it in. So if I type in xy, it gives me 7. And then I can do operations with it, xy plus 1 is 8. Yeah. AUDIENCE: Before you were putting the strings with apostrophes. So wouldn't you need that? ANA BELL: So those are strings, right, sequences of characters. Here, these are variables. So these are names that I am giving as a variable. Yeah, that's a great question. So this is going to be a string. And you notice it changed color. It has some meaning in Python. But xy is a variable that I create. OK, so why do we want to give names to variables? Because as I showed you with the pi example, it's a lot easier to write readable code if you have variable names within your programs. So when you grab-- when you write programs, it's important to choose variable names wisely. You don't want to use just single letters. You don't want to name it something that doesn't have something to do with the program you're writing, because you're going to want to reread these programs sometime in the future. Or others might want to read your programs sometime in the future. So here's an example of a nice program. It's just basically four assignment statements that do some calculations. The first line of the program is not really a line. It's called a comment. You can have as many of these as you like. They start with a hash. It's a line that starts with a hash. And it's basically a text that you write that helps you or others figure out what the code is supposed to do. And usually we comment large chunks of code at a time, not line by line. Then we have these four assignment statements. So here I'm defining variable named pi bound to the value here, so not the division but 3.14159. Variable named radius bound to this float 2.2. And then I have a variable named area which is bound to the result of this expression. So when Python sees my pi and my radius, it grabs them from memory, replaces them with the values, evaluates the expression, grabs that one value that we evaluated to 15-point-something, whatever this is, and binds the 15-point-something to the name area. Same with circumference. Code style is something that we're actually going to look at in your problem sets. So I just wanted to quickly talk about that. Here is a program that has really bad style. Actually, that shouldn't be meh. It should be terrible or something like that. But in case you haven't noticed, it's the same program as on the previous slide. But if I gave you this program straight off the bat, you probably wouldn't know what it's doing. It's reusing 355 over 113 twice here. It's using just a and c as variable names. Its description is "do calculations." So pretty bad. This is a little bit better. I've recognized that 355 over 113 is being used twice. So I'm saving it as a variable. But my variables are still single characters. And my comments are pretty bad. I'm basically saying what the code is doing. Please don't do that. We can see that a equals p times r times r. I see that I'm multiplying p with r squared. I don't need to read that in English. What I would like to see is a comment like this. Here I'm commenting a chunk of code. And someone who doesn't want to read this chunk of code just reads the comment, and I already know that I'm calculating the area and circumference using an approximation for pi. That's a pretty nice comment there and good descriptive names and all that. So we can actually-- once we create an object, a variable-- sorry, once we create an object and bind it to a variable, we can change the bindings. So we can take that variable name and bind it to a completely different value. This might not be useful right now, but it will be useful when we introduce control flow in our programs. So to rebind a variable what that means is we're going to take the name, we're going to lose the binding to the previous value, and we're going to rebind it to a new value. So I'm going to show you how this looks like in memory. I'm going to use this sort of cloud picture to represent what happens behind the scenes whenever we write programs. And it's like a little animation to help you understand line by line what's going on. So here we have pi equals 3.14. So the green 3.14 is my value in memory. Cloud is memory. That's my value in memory. And it's bound to this name pi. So this is my variable name. The next line, radius equals 2.2, same thing. I've got 2.2 as my value in memory, my object. And radius is the name for that object. Area equals pi times radius squared. So what happens behind the scenes is it calculates this value. It doesn't store the expression. It stores the value resulting from the calculation, and then it saves it-- or binds it to the name area. OK, everything OK so far? We've seen this code before. Cool. So now what happens when we do this, radius equals radius plus 1? In math, that would say 0 equals 1. But we're not in math here. We're in computer science, and this is perfectly valid. We're following the rule when we have an assignment that says look at the right-hand side first and evaluate it and then bind it to the left-hand side. So if we look at the right-hand side first, we see radius. Well, what's the value? 2.2. We see add 1 to it, 3.2. Save that in memory. And then we see the assignment. Now save it with the name radius. OK, so we can only have one variable assigned to one value at a time. This is not math. This is computer science. So you can only have radius point to one thing at a time. With this line of code, radius equals radius plus 1. We've lost the binding to 2.2, this object in memory, and we've rebound it to the value 3.2. And that's perfectly fine. 2.2 is now just sitting in memory. We can't get back to it unless we say maybe radius equals 2.2. It just sits in memory and then might be collected later on by-- or reclaimed by garbage collection or something like that. But for now, we can't get back to it. Now, what's the value for area at the end of these lines? Well, according to this, it's 15.1976. So it's using the old 2.2 value for radius. And that's OK because the program never told-- never had a line that said recalculate area after we changed the radius. It's just following, dumb, line by line. It doesn't know that, hey, if I change the radius, the user might want the area changed. It doesn't make those connections. It's just following instructions. And that's OK. If we want it to change the area, we would have to copy this line and paste it after we've changed the radius. And then the area would change as well. Does that make sense? That's kind of an important part of this lecture. OK, cool. So big idea here is our lines are evaluated one after the other. We're not skipping. We're not repeating things. That's something we're going to learn about later. But for now, line by line. So here's a little you try it. These three lines are executed in order. What are the values for meters and feet variables at each line? So how about at the first line, what's the value for meters after we execute the first line? 100. What about feet? So at the end of the first line, there is no value for feet yet. How about after the second line? 328.08. Right? How about the value for meters? AUDIENCE: 100. ANA BELL: 100 still. And what about after the third line? I'm changing meters to 200. Exactly, yeah. Meters is 200, but feet is still 328.08. And this is something I want to show you guys today. And we're going to use this Python Tutor a lot more in the future. Python Tutor is a nice website that allows you to step in your code-- step through your code step by step. So at each line that you execute, you get to see the values of all the variables in the code. It's a very useful debugging tool. I hope you'll try it out today and on Monday, maybe, for the finger exercises if you're having trouble. And you can use it for quizzes to help you debug. But I can just show you. It's pretty simple here because it's just a step by step. So we step through. So the red says the line I'm going to execute. Green is the line I just executed. So I just executed meters 100. So here I have my meters variable with the value 100. Step through next. So I just executed feet equals this. So I now have a variable named feet with a value 328.08. Meters still 100. And then meters 200, feet remained 328.08. So obviously, this is a pretty simple program to run the Python Tutor on, but you can imagine using it in more complex settings. How about one more? And this is my last example. I want you to try to write a program that swaps the values of x and y. So originally-- and I'll draw this, the memory diagram real quick. So we have-- this is our memory. We have x is bound to 1. Y is bound to 2. And what I want to do without saying x equals 2, y equals 1, what I want to do is swap the values. I want x to be associated with 2 and y to be associated with 1 but only using commands like this. And so the code here is buggy. That means it's wrong. It has an error in it. Well, let's step through-- let's step through a little bit at a time. Y equals x. What do I do when y equals x here? Yeah, exactly, y is going to move from 2 to 1. Now, what happens when I do x equals y? Yes, x stays the same. My first line, y equals x, lost the binding to 2. And now it's all messed up because I can't get it back. So instead-- so if you didn't understand this, you can click Python Tutor and just step through step by step on your own. But how can we fix this? AUDIENCE: Create a third variable. ANA BELL: Create a third variable? Yeah, that's a great idea. Yeah, we can create a third variable. So x is 1, y is 1-- y is 2. So we can create a third variable. What do you want to make the variable equal to? X or y? Yeah, either one. I made it y, so let's do y. So here I've got a temporary variable called "temp," and I made it equal to 2. And now what can I do? Which one can I reassign now? X equals y, or y equals x? Exactly, y equals-- if I do x equals y, I lose my binding to 1, and it messed up again. So y equals x is OK to do. So I'm going to lose the binding from y from 2 and bind it up to 1. And now what do I do? Yeah, now I can safely reassign x to temp. So I can say x is equal to temp because temp points to 2. And I want to make x point to 2 as well. So in terms of code, that's sort of the diagram. But we can write the code. So you don't-- let's see. We don't write it in here, but on your own, you can write it in here if you'd like. Or we can do it together. So x is equal-- oops. X equals 1, y equals 2. And then we had temp. We wanted to assign it to whatever y was. So we say temp is equal to y. And if you want to check the values of the variables, you can just invoke the names. So x is 1, y is 2, and temp should be whatever y is, 2. OK, good so far. So now I'm at the step here, I think, right? I've just created this. And then the last thing I need to do is lose the binding from x to whatever temp is. So I want to do this operation here, which means I want to assign x to be equal to temp. So now x is 2, y is 1. What did I do? Yeah, so this happens sometimes. We can just start all over. So y equals temp. Sorry. Temp equals y. Y equals x. Y is one. X is 1. And then x equals temp. Y is one, x is 2. So it's OK if things go wrong. They will go wrong. We can just start all over in this particular case by redefining our variables and just trying it out all over again. So that's kind of what the shell is for. That's what I use it for. That's what we're going to use it for in the future, just to do quick things like this and also things like checking the types and other commands we've done earlier. OK, so any questions before we do the summary? Was this all right pace or was it too fast? Or it was OK? OK, good. Thumbs up is good. So let's do a quick summary. We saw that we can create programs by manipulating objects. We created objects in Python. And we saw that objects have a particular type. The type that the object has tells Python the things that you can do with that object. We can combine objects in expressions. And these expressions evaluate or boil down to one particular value. Objects or values can be stored in variables. And these variables allow us to access these values with nicer names later on in our program. And then we're able to write neater, more legible programs as well. So the equal sign-- I showed you a couple of differences between math and computer science. The equal sign was one notable difference. The equal sign in math is declarative, and the equal sign in computer science is an assignment. You're basically saying this is associated with this. And we're not doing any sort of equality in computer science. And yes, computers do what you tell them to do. That's kind of the big thing here. Line by line, it executes starting from the top, goes line by line. So far, we haven't seen any places where the computer makes a decision. But next lecture, we will see how we can insert decision points in our programs for the computer to either execute one set of code or another set of code. All right, so that's the end of today's lecture. Thank you all for joining. I will see you on Monday.
Info
Channel: MIT OpenCourseWare
Views: 520,336
Rating: undefined out of 5
Keywords: computational thinking, computer science, introductory programming, python, python variables
Id: xAcTmDO6NTI
Channel Id: undefined
Length: 63min 30sec (3810 seconds)
Published: Thu Apr 11 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.