 You'll learn how to become a competent Python programmer by learning the fundamentals of the language in detail. You'll learn how to navigate complex data structures and accumulate results from them. And you'll learn how to convert data into a format that can be used by other programs. At the end of the specialization, you'll be able to write Python programs of a few hundred lines. You'll be able to use and integrate Python modules into your code. You'll be able to use external tools like APIs by reading their documentation as well. We start from the beginning and we don't assume any prior knowledge, but we do go deep into the fundamentals of Python to be sure that you understand every aspect of code. So, you want to say something about what's our runestone interactive environment? Yeah, so the runestone interactive textbook allows you to interleave learning materials with active code assessments that will allow you to actually write code. And we find that writing code is really important because even though you can learn how a concept works in theory, so you might know how some particular feature of Python works, it's really important to actually write code to gain more of a working understanding and to know how to actually apply those concepts in practice. So, there's also the way of the programmer segments. So, most of the course is about how to use Python and learning about Python features. The way of the programmer segment is more about how programmers can and should work. Programming is a little bit more of an art than a science. There's lots of correct ways to do things, but there are best practices. So, there are things like how to write programs incrementally. In the way of the programmer segments, you'll also learn about how to write good automated test cases. So, that's going to come in course four. Until then, we're going to write those test cases for you. Lauren has created a whole lot of assessments where not only can you run the code in the browser, but it'll tell you whether you got it right or not. And you get that immediate feedback and you can try it as many times as you want. In fact, we've set up the assessments so that you have to get everything right, 100% in order to pass the assessment. And the reason for that is we really want you to build mastery so that you don't go on to the later stuff until you've got the early material really solid. You'll also notice that in all of the projects that you do, you'll find ways of translating the concepts that you learn in the courses and throughout the specialization into your real life. For example, different ways of building programs that might be fun in your job, or your school, or your work, or whatever it is that you do. So, one of the things that I really like as I've watched you all put this together is in Python for Everybody, and you kind of already said this, in Python for Everybody, I really focus on the program. If you get the program, it's like you win, you know, you get the gold star. And we didn't have the time or the luxury to really understand what was going on inside the program. We're just like, we got the program done and we got to move on to the next thing. But with some of the stuff that you have in Runestone, you get to say, what's really going on inside of the program and how does this really work? And that's part of the mastery is so that if you can't, as a programmer, kind of put yourself inside the program and understand how the program is actually functioning, it is difficult to write more sophisticated programs. And so, that's where, even though this technically is a beginning course, I think it's really important for people to take more than one beginning course because you have to go over the same material over and over with, in a sense, deeper understanding each time you go through it. Yeah, we have this great code lens tool that I think you're referring to that lets you visualize what's happening in the execution of the program one line at a time and you can go forwards and back and see what actually was the value of that variable and when did my list change what its contents were? And so, it gives you a way of thinking about it. It's really great for debugging so that you don't have to just do trial and error. Let me change something in the code. You can really think through what is a program. So, another thing that the students always ask me is what next? And I think that it's kind of cool that you've built into this specialization kind of a step into what they're going to do after this, Chris. Yeah, so one of the things that we've added to this course at the very end is a project course and that's really to focus people on how to take other APIs that might be out there or packages and use them and do something novel with them outside of just learning. And it gets to this repeated practice comment that you made. And for that, we're actually doing it within the Jupyter environment. So, just like you need repeated practice with APIs and with Python fundamentals, there's so many different places that you can write Python code and Runestones one of them and the tools you use in Python for everyone are one of those. Jupyter is one that's quite common and we teach that in the data science specialization that students can follow this with. And there's other environments too and so we're trying to really showcase a diversity of learning environments and production environments for Python. Programming is not one environment, right? It's not like you have this one thing and you type this stuff in and that's all the programming. When you're out in the real world, each job often has different kinds of environments. Yeah, and practice is so important in the context of programming. I think Lauren has written some great examples of practice problems for you to work on in the course as well. And we have this great practice tool that you'll get to see where it represents to you for review some questions that you've already seen in the past. And it keeps presenting them to you more frequently if you're having trouble, less frequently if you're showing mastery of them and it's a way to really reinforce what you've got. So, look for that practice tool. It also has these fun fireworks that don't have your practice problems for the day. So, as you can tell, we're all really excited to share this material with you and we hope you have a lot of fun and wish you a lot of luck. Here at the University of Michigan our school colors are maize and blue. You might think of them as yellow and blue, but we call it maize and blue. And if I travel anywhere and I have a Michigan logo thing on, someone will come up to me in the airport and say, go blue. So, on three, two, three, go blue. Hi everyone. I'm excited to show you some useful features of the free interactive textbook that will be available to you as part of this specialization. Content in the first four courses all track pretty closely to the textbook content. So, whichever course you're starting with, you'll want to go through this video to see the important interactive features. You can skip it if you've already seen it in a previous course. The runestone interactive textbook environment by my friend Brad Miller. I've made a few contributions to both the software environment and especially the textbook over the past four years, but Brad deserves almost all the credit. Let's take a look. The first thing you'll need to do before accessing any of the textbook pages is to log in from Coursera. So I just click on this open tool and I'm automatically logged in. You've already logged into Coursera and Coursera is passing the credentials to Runestone, so you'll be automatically logged in here. Once you're logged in, all of your work will be saved and we've deliberately disabled any other ways to log in except by doing it through Coursera. So when you first log in following that link, you'll be taken to this practice page in the textbook. It's our way of encouraging you to use the practice feature every day, but we'll come back to that later. Once you're logged in, you'll be able to click on any of the links for the readings and you'll be taken directly to the pages in the textbook for those readings. So here's a link to the Runestone page for variables and I'll click on it and now I'm on a textbook page. In the textbook you'll find text and images, diagrams but you'll also find some interactive elements. For example, here's what we call an active code window. It's got some code in it and I can click save and run. It'll run and print something out over here in an output window. I can change that code and I can run it and all of your code versions when you save and run them will be saved. I have this little scrubber here and I can move it and see all of my old versions and they're not just saved while this page is open they're saved permanently. For example, let's reload this page. When the page loads we're back to the original window contents but I can click load history and then I get the scrubber and it shows me my last code run. Now if I rerun a previous version it won't it won't show in the scrubber but it will show in the latest version. But if I change it instead of 17 I do 18 now it becomes the latest version in the history. Show in code lens is a really useful feature of active code windows. This is an amazing tool developed by Philip Guo, a professor at UC San Diego. It lets you step through the execution of a program one line at a time. I can click forward and show me what happens after one line is executed in the next can print out just the first message and so on. That's not such a big deal now but it will be really useful for you when you start to do more complicated programs with conditional execution and iteration and defining your own functions. Part of our educational philosophy in this specialization is to reveal all the magic. We want to give you a way to reason about how your programs are executing because that's the foundation for being able to debug your code through understanding rather than through trial and error. Code lens really helps with that. Now sometimes these code lens examples are built right into the textbook but you can always get to code lens by hitting the show code lens or hide code lens for any active code. Here are some that are built in on the textbook page. There are also other interactive features. Here's a multiple choice question. You can answer those and get immediate feedback by clicking on check me. I've actually already answered this one but suppose I said Thursday as the thing that would print out here because day is set to Thursday. I click check me and it gives me some feedback. That's true. Thursday is the value of day but it gets overwritten later so the correct answer is 19. Now when you get to the bottom of the page I suggest that you click on mark as completed. If you haven't clicked on it, this is what it will look like initially. If you click on mark as completed a couple good things will happen. One is you get the satisfaction of it says yay completed well done but you get a couple other things too. First some of the multiple choice questions or other activities on the page get added to the practice tool which I'm going to show you in a minute. That practice tool will help you review things so that you don't forget them. Sort of like vocabulary flash cards when you're learning a foreign language. Second the pages that you've marked as completed will be marked in the table of contents. So you can keep track of the textbook of what you've read and what you haven't. Here's the table of contents and you can see these orange dots indicate things that I've completed and I've marked as complete and the check boxes the check marks indicate things that I've opened but I haven't marked as complete. So this completed button at the bottom of the page is separate from marking a reading as complete in Coursera. You may want to do both of those things. In Coursera we'll generally provide you with links to particular pages and so you can just read that one page but if you want to you can navigate through the textbook once you're on the Runestone site. We have these forward and back buttons. This goes to the next page in the book. Back to the previous page. If you click on the textbook title as I showed you a second ago you'll get to a table of contents that's very detailed with every single page and sometimes subsections within the pages. If you want a more overview look at it. You can click on this chapters and it'll show you the different chapters and you can just see the detail for one chapter at a time. Now notice that the orange dots aren't shown on this detailed view of just a single chapter. That's a little unfortunate and now that I've noticed it I'll try to add that feature at some point. Finally, there's a search option so I can search for variable and it'll tell me lots of pages in the textbook where the word variable shows up. There's also an index I want to look for various things and I can click on them and it'll take me to where they are in the textbook. Normally if you log in from Coursera you'll be taken directly to the practice feature but you can also get there from within the book working on practice. What this practice feature does is it represents to you questions on topics that you've marked as already completed. That thing at the bottom of the page where you mark the pages completed. When you're here in the practice feature you get to answer it again and if you get it right you'll remember that and it won't ask you that same topic again for a long time if you get it wrong I might ask you again tomorrow. So this practice tool is the brain child of my doctoral student, Iman Yakisare. He just implemented it last year and in the first semester where we made it available to students in our on-campus classes those students who used it in the first semester where we made it available to students in our on-campus classes those students who used it more did a lot better on the course exams than those who didn't. This is a striking result for me because I'd been monitoring for several years to see whether just spending more time in the textbook had a similar effect on student performance and it didn't. In my on-campus classes use of this practice tool is now required and earns a few points towards the final grade. For the Coursera courses it's not required but based on the results I've seen with our on-campus students I strongly encourage you our on-campus students love the fireworks that they get so here I'm going to answer a couple of questions I have only two left to practice for today and I'm going to say done ask me another question and it gives me one more it says hang in there last question for today and what's going to print out oh this is a review the one we just looked at I say check me and then I done and I get these fireworks which are a little little fun when you finish all the questions for the day. For those of you who are taking this course for a certificate you'll also see links to graded assignments usually at the end of each lesson or set of lessons. In the first four courses the assessments and projects are in the runestone textbook and they're all auto graded there. You'll only be able to see these in Coursera if you're paying to take the course for a certificate. If you're not paying you can find similar questions in the end of chapter assessment pages in the runestone textbook. So let's follow the link for this first assessment and this assessment just has two questions I've actually already answered one of them correctly before that was a multiple choice question and they want me to write some code the answer to this one is I'll save and run it and I get some immediate feedback an automatic test in here and it's telling me that I got the right output. If I said hello word instead I would get feedback saying that I had failed. I would actually when I tell it to grade me it'll use the best answer I've ever given so if I ever manage to pass the test I will pass this. We've set up the assessments so that you have to get usually that you have to get 100% in order to pass the assessment but you can keep trying and keep getting feedback until you get that 100%. We've done that because we think it's really important to master the early material because things keep building on each other. So I click grade me and it comes back you can see now that it's updated the score to 1 instead of 0. I've gotten a total of 2 out of 2 for this assessment and if I go back on Coursera and I refresh it it'll tell me instead of trying again it's going to tell me that I've passed. Passed with 100%. That's the runestone environment. It's been a labor of love for all of us who've worked on it as an open source project over the last few years especially Brad Miller who started the project. I hope you'll find it really helpful to you as you master the fundamentals of Python. I usually end my on-camera segments with a little joke so here's a bit of humorous advice. Procrastinate today always today. Don't put it off until tomorrow. Okay then. Don't listen to my advice. Don't procrastinate today. Go get started with the first lesson in this course. I'll see you next time. In this course you're going to learn to write computer programs in the Python programming language. But before we get into that we need to know exactly what programming is. Fundamentally programming is giving a list of instructions for a computer to follow. In the context of programming these instructions are sometimes called algorithms. Now computers are really good at following these instructions very reliably and very quickly but not very creatively. And we can't just give computer's instructions in English or any other natural language that we normally speak because natural language has ambiguity. Words or sentences can have multiple meanings which computers can't figure out. Instead we need to give computers instructions in a programming language which is a kind of language that computers can understand because they have a formal syntax or a set of rules. There are many programming languages that exist including JavaScript, C++, Java, Haskell and many many more. But in this course we're going to learn to use the Python programming language. The process of learning programming is more than just learning the rules of the Python programming language it's also about how to break down and solve problems regardless of the programming language. And I like to think of programming as a translation process where the programmer translates their goals from natural language into a programming language. For example, if I want to write my own version of the game Wheel of Fortune then I need to translate the rules of the game into an unambiguous set of instructions written in the Python programming language that tell the computer how to run the game. And as you become a programmer you'll learn how to come up with strategies or algorithms for solving problems and how to translate these strategies into Python code that a computer can execute. Now all that said the best way to learn programming is through practice so let's get started. In this course you'll be able to write Python codes right in your browser. You'll see what are called active code windows that look like this in your textbook. Now most programming courses start off with what's called a Hello World program or a program that prints out Hello World on the screen when you run it. In Python a program to print Hello World looks like this. In order to actually run this code we need to click the Save and Run button. When we do that we'll see an output window show up to the right here. Now to break down what all of this shows we have our Python source code on the left and we have our output on the right. Now when we click Save and Run what happens is that there's a hidden Python interpreter and it looks at what's in our source code and prints out whatever any relevant output is. And remember that this source code is a set of instructions. In this case the source code is an instruction to print out whatever is in quotation marks here in this case Hello World. If we wanted to change the set of instructions so for example I want to change it to print out Hello Michigan then I need to put it through the interpreter by clicking Save and Run again. And now when I do that you'll see that my output changed from Hello World to Hello Michigan. If I want to change it back then I need to click Save and Run. Now the Python interpreter typically tries to run all of the source code that we put in this window but it can sometimes be helpful to leave natural language notes or explanations for ourselves or for other programmers who are looking at the source code. Now the Python interpreter typically tries to run all of the source code that we put into our source code window but sometimes it can be helpful to leave natural language notes or explanation for ourselves or for other programmers looking at the source code. In order to do that we have what are called Python Interpreters. In Python we write a comment by using the pound symbol and writing what we want after it. When we write a comment then Python ignores everything that comes after the pound symbol meaning that we can write whatever we want here. And on the next line Python will start running the code again so if we wanted to write a comment we would need to add a pound symbol. And what comments do are they tell the Python interpreter to ignore these portions of the source code and only to run what's not commented. In our case the only code that actually runs here is print hello world. Another thing that's worth noting is that the Python interpreter is not very forgiving so recall that when you write source code you're giving the computer a set of instructions and these instructions need to be unambiguous to follow the rules of the Python programming language. One of the rules of Python is that when we have an open parentheses then we are going to need to have a close parentheses. So let's suppose that I forget that rule and I delete this close parentheses and I try to run my program. What happens is that I get what's called a syntax error. A syntax error is Python saying that it doesn't understand the rules of what you wrote so it doesn't try to actually execute what's in the source code window. In other words a syntactic error or a syntax error is when you're not following the rules of the Python programming language. In this case we're not following the rule that this open parentheses has to be followed by a close parentheses. Throughout this course we're going to run into syntax errors and other kinds of errors including runtime errors and semantic errors. So when we get a syntax error as we will many times throughout this course we can fix it by editing the source code to obey the syntactic rules of the Python programming language. In this case I'm going to add a close parentheses to match the opening parentheses that starts out here. Now when I click save and run again then you'll see that the syntax error disappears and my program runs again. With that you're already on your way to becoming a programmer. With more practice we'll better understand how the Python interpreter works and we'll be able to write larger and more complex programs. See you next time. In this lesson we're going to go over some of the basics of writing Python programs. Part of the reason that I really like Python as a first language is that it doesn't take much to actually write a simple Python program. So when we write a Python program we are going to write our Python code in this window and the code that we write is going to go into a Python interpreter which is a program that's running behind the scenes but it takes what we write in our code window and interprets it and then depending on what we write it might send something to the output. So again this is the source code this is the output and the Python interpreter looks at our source code. We've already seen a Hello World Python program but I'm going to write a program that's even simpler. This is a valid Python program so if I click save and run then you aren't going to actually see anything in the output program but Python did actually interpret and run this program correctly. So remember that there's this hidden Python interpreter and when we actually ran this code the Python interpreter looked at our source code ran it and saw that there was no output for it. So when we write code we're actually writing what are called expressions. Learning the program is in part learning the right expression to write for what we actually want to compute. So 100 is an expression and when we write expressions what the Python interpreter does is it computes the value of those expressions. So we have expressions, every expression has a value. So in the case of the expression 100 the value of the expression 100 is just 100 and then every value also has what's called a type. A type is like a category of data so the type of 100 is an integer an integer is just a round number so I'm going to add on to this program by writing another expression. So here's another expression 3.14 Again when I run my program nothing shows up but what's happening is that behind the scenes the Python interpreter is looking at my code and deciding what to output. So here we have two expressions the first expression is 100 the second expression is 3.14 and these expressions have a value so the value of 100 is 100 the value of 3.14 is 3.14 and both of those values have types. So the type of 100 is an integer the type of 3.14 because it has a decimal place is something called a float short for floating point number. So we want to compute all of the values that we want and Python will do these computations behind the scenes again with this Python interpreter but typically we want our programs to actually give us some feedback we want it to do something and then give us back some value in the output window in other words we don't just want our source code to go to the Python interpreter and get no output we usually actually want some output or some feedback from our programs and in order to do that what we need to do is we need to use what are called print statements so a print statement is a special kind of expression that tells something to show up in our output window so I'm going to modify my source code to say rather than just computing the value to also print out the value that I do that is I say print open parentheses and then the value of whatever expression I want to print out and then close parentheses so if I only say print 100 and I run my program then I'll see that in my output window I get 100 because I specified that I want to print out the value of this expression so notice here that print 100 prints out 100 but when I say just the expression 3.14 then this doesn't lead to any output in order to actually print out the value of this expression I also would need to add a print statement here and now when I run my code then you'll see that the value of both of these expressions is printed so so far we've seen two kinds of types we've seen integers which are round numbers like 100 and floats numbers like 3.14 another type that we've actually seen in an earlier lecture was a string so when we said print hello world then this expression hello world is a string a string is a sequence of characters and if I run this program then you'll see that hello world is what actually gets printed out when I run line 2 so so far we've seen the types integers like 100 strings like hello world and floats short for floating point number like 3.14 and in all of these cases these 100 the string hello world or 3.14 are all expressions now expressions are like the building blocks of programming we can combine and reuse expressions to get more and more complicated programs so the expressions that we've written so far are what are called literal expressions where the value is the same as the expression itself so the value of the expression 100 is 100 the value of the expression 3.14 is 3.14 let's move on to operators to see how we can combine expressions to get more complicated expressions so far we've seen simple expressions like 100 hello world or 3.14 and these are all literal expressions where the value is the same as the expression itself but expressions are like building blocks that can be combined to form larger and more complicated expressions operators are one way to combine expressions the first operator that we'll learn is the addition operator in order to use it we write something like print out 100 plus 200 when I run this code note that I get the value 300 so when we execute a print statement then rather than printing out the expression itself the expression here being 100 plus 200 then we print out the value of that expression so this expression has a value of 300 now this expression uses the addition operator the addition operator which is done using the plus sign expects one expression to the left and one expression to the right and what it does is it computes the value of the expression to the left and the value of the expression to the right it adds up these two values and then the value of this overall expression is the value of this expression plus the value of this expression so in the case of 100 plus 200 we add the value 100 plus the value 200 and the value of this overall expression ends up being 300 and remember that whenever we call print we print out the value not the expression itself and so 300 gets printed in our output beyond the addition operator python includes many other kinds of operators so there's subtraction so when I print out the value of 5 minus 2 then we get 3 if we reset our code here there's also a multiplication multiplication is done using the star symbol so when we print out the value of the expression 2 times 4 then we get 8 there's also division so when I print out 10 divided by 3 so division is done using the slash symbol and when I print out the value of this expression then it's 10 divided by 3 which is 3.3 repeating and in addition to addition multiplication division and subtraction there's also some other kinds of operators so you'll notice here that when we take 10 divided by 3 we had 2 integers 10 and 3 and we got a float as a result sometimes we don't actually want that remainder so python also includes truncated division which leaves out the remainder so that we get 3 back and it also includes the modulo operator so if I say 10 and then percent sign 3 this is the modulo operator so it gives me the remainder of 10 divided by 3 which is 1 python also includes exponentiation so if I print 4 star star 2 then this expression is like saying 4 to the power of 2 or 4 squared and so the value of this expression is 4 squared which is 16 when executing code python follows the normal order of operations that you might be used to in math so at highest precedence is whatever is in parentheses and then below that is exponentiation so that would be something like 4 to the power of 2 below that there's multiplication and division so that would be something like 2 times 4 and then below that there's addition and subtraction so what this means is that suppose that we wanted to compute the average of 2 numbers 10 and 20 so if we wanted to compute the average of these 2 which should be 15 then we might intuitively write something like 10 plus 20 divided by 2 so if I run this code you'll note that I get 20.0 rather than 15 which is the actual average and the reason is that python because division is higher in precedence than addition when computing the value of this expression then python first computes the value of 20 divided by 2 and gets 10.0 and then it adds 10.0 and gets the value 20.0 if instead we wanted to first add 10 and 20 and then divide by 2 then we could add parentheses around 10 and 20 so I would say print out 10 plus 20 in parentheses divided by 2 and now what python is going to do is it's first going to add 10 plus 20 to get 30 and divide by 2 and get 10.0 and you can see that now we're correctly getting the average of 10 and 20 see you next time welcome back one type of expression that you might write in python is what's called a function call expression so you can think of functions as boxes that contain some machinery inside of them so I'm going to visually represent them here just using this gray box and you can think of a function as some inputs so here the inputs feed into the top here and then these inputs go inside of this machinery this machinery does something with the inputs and then after it done its work with the inputs it spits out an output so visually again you can think of it as working something like this so here we have a function it takes in 3 inputs or arguments and then it does some work and then it spits out an output or a return value so let's watch that again so again we have the function and it takes in 3 inputs here or arguments then it does some work and then it spits out an output or a return value now let's translate this visual metaphor into actual working python code here's an example of how we would actually write a function call expression in python suppose that we have a function named square and our square function takes in one argument which is going to be a number and then it returns or outputs whatever that argument is squared so for example if we say square and then open parenthesis and we put our argument in between the parenthesis here so this is called calling the square function with 4 as an argument so this is how we actually write that in python again we say square or whatever the name of the function is then inside of parenthesis immediately after the name of the function we pass in our arguments so the arguments go here and then the value of this overall expression so whatever the value of this expression is is going to be the return value and so in the case of square if square squares whatever input or arguments you give it the return value is going to be 16 and this is what it looks like when we translate this python code into that visual representation that I just mentioned so we have the square function again represented as a box and the square function in this case we suppose that it takes in one input or argument and if we pass in 4 it does some work and it spits out an output or return value of 16 to watch that again we pass in the square function does some work and it computes an output or return value in this case of 16 and again this is how we write that in python code we say the name of the function, square then open parenthesis to say that we want to call that function and then in between parenthesis then we pass in whatever arguments we want our functions to take now python functions can take one, two or any number of arguments but there's always exactly one output so for example here this function takes in three inputs or arguments but it spits out one return value so again functions always take any number of arguments but there's always one value of that function call so let's look at a little bit more python code and calling functions so here on the first line we're actually calling two functions technically because here print is a function that we're calling and we're passing in as an argument to print an expression which just so happens to be another function call and this function call uses the square function that I just described so again the square function that I'm describing this isn't a built in with python this is something that we define for the purpose of explaining function calls but we defined it in a way that it takes in one argument in this case square three and then it spits out that number squared so if we say print out the value of square three then this is going to print out the integer nine so let's see that in action so I'm going to comment out the rest of these lines and run my code and I can see that the value of this expression square of three is nine if we call a function but we don't have a print statement so let's suppose that I say square five the value of this expression is going to be ten but you'll notice when I save and run my code it's not going to actually affect the output and that's because we never actually printed the value of square five we just computed the value of square five excuse me it's not ten it's twenty five of course so here the value of this is twenty five but we never print out its value now let's suppose that we have another function called sub so sub takes in two arguments so I can represent that visually like this so it takes in one and two arguments and just like every other function it's going to spit out one return value now let's suppose that sub subtracts the second argument from the first argument so in other words suppose if I passed in six if I passed in six and four then my sub function is going to spit out two because six minus four is two so we would call the sub function by saying print out and then sub and then here you'll notice that we have two arguments and we separate those arguments by a comma so we print out the value of sub six and four and we see that the value of this expression sub six and four is two if we call that again so if we call sub with arguments five and nine then this is going to give us negative four because five minus nine is negative four we can also combine function calls with other operators including function calls so here if we print out the value of square three plus two then python is going to first compute the value of this overall expression by evaluating the value of square of three and then it's going to add the result of that to two so python is going to compute the value of square of three and it's going to get nine and then it's going to compute the value of this expression which has the value two because it's a literal expression and then it's going to add these numbers together to give us 11. Now, this expression on line two is much more complicated. So here we can see that we're calling the sub function. We are calling it with two arguments. So the first argument is square of three. So this is arg one. The second argument is square of one plus one. So this is arg two. Now whenever Python calls a function call expression, it needs to figure out what the values of the arguments are. So Python kind of computes the values of a function call expression from the inside out. So it's going to go from the value of one plus one to the value of square one plus one, and then the value of square three. And then after it has the values for square three and square one plus one, it's going to subtract those two values by calling the sub function. So again, we're kind of going from the inside out to the next layer, and then out to the next layer beyond that. So when Python computes this, it's going to first compute the value of square one plus one, or two. So it's going to compute the value of square two, and that's going to give us four. It's going to compute the value of square three, and that's going to give us nine. And then it's going to compute the value of sub when called on nine and four, and that's going to give us five. So if I run my code, you'll see that we get 11 from line one and five from line two. Just to run through the exact steps that Python takes when computing the code online to Python first computes what's the value of square three, it gets nine. Then it computes what's one plus one, it gets two. Then it computes what's square of two, and it gets four. Then it subtracts nine and four, and gets five. And that's what it ultimately prints out. Now one thing to note is that functions are objects in Python. So if I print out what's the value of square, then Python is going to tell me that square is a function. So if I run my code, you can see that line one prints out function square. In order to actually call the function or run that machinery, we need to have the name of the function, and then open parentheses and pass in our arguments inside of those parentheses. So in other words, we need to have open parentheses right after the name of the function in order to say that we want to call the function. We don't want to just reference the function object itself. Let's offer now until next time. If you're not sure what type a given value has, then Python has a nice function called type. And what type does is it tells us what the type of a given value is. So for example, if we print out the value of type when called with the string hello world as an argument, then Python is going to tell us that this is a string. It'll tell us that this is an int. And then here, if we don't call the type function, we get the value itself. But if we type print out the type of 3.2, then we get that this is a float. So let's run our code. And what you'll see is that when we print out the type of hello world, then Python has a way of telling us that this is a string, print out the type of 17. Python's telling us this is an integer. This is just us printing out the string hello world itself. But if we print out the type of 3.2, then Python tells us that this is a float. And this can be especially helpful in situations where you're not necessarily sure what type something has. So for example, here we have a value 17. And even though this is a number, because it's in quotation marks, the value of this expression is going to be a string. And so the type of this expression is going to print out class str. Same thing with this. So even though 3.2 is a float, because these are in quotation marks, this overall expression is a string. So if I run my code, then I'll see that both of these are strings. Now there are a few other things to note when working with Python expressions. First, when creating a string, as we mentioned, there are multiple ways of creating a string literal. One is using a single quotes mark. Another is using double quotation marks. Another is using three double quotation marks or three single quotation marks. Now the important thing to note is that even though all of these expressions create a string in a different way, if we ask what's the type of each of these, then Python is going to tell us that these are all strings. So even though we create strings in four different ways here, all of these boil down to the same type in Python, which is a string. So another thing to note when creating strings is that sometimes you want to include single or double quotation marks inside of a string. So for example, I might want to print out the string Bruce's beard. Now here you'll note that I have an apostrophe in Bruce's and when I try to run my code, then Python gives me a syntax error and that's because to Python it thinks that this is the string because it thinks that this quotation mark starts the string and that the apostrophe is supposed to end it. One way to get around this is by using double quotation marks if we know that we're going to have an apostrophe inside of our string. So here this works. Conversely, if we had a string that we knew would contain double quotation marks, again, if I run this code, then I get a syntax error because Python thinks the string starts here and ends here. But one way around it is by using single quotation marks to create the string. If I have a string that might contain single and double quotation marks, then one way around that is by using triple quotation marks. So I might say something like, oh no, she's claimed Ben's bike is broken. So now I can use both double and single quotation marks inside of the string. And again, triple quotation marks allow us to create strings that span several lines. Another thing to note when creating an integer is that in the US, we often use commas every third digit in larger numbers. So for example, we might indicate 42,500 using a comma like this. But here if Python sees a comma inside of the integer, it thinks that these are two separate values. So it thinks that we're printing out 42 and then 500 as separate values. So when we're creating large numbers in Python, we shouldn't ever use commas to separate out every three digits. We need to write the integer like this. And now we have the number 42,500 in one value. And one more thing to note along those lines is that we can call print with any number of arguments. And when we do print decides to take every argument and print out its value separated by spaces instead of commas. So here we're printing out all of these values on one line, and then all of these values on the next line. So let's do a few multiple choice. How can you determine the type of a variable? Well, one way to determine the type of the variable is by using the type function. Next question is what is the data type of this is what kind of data. So in other words, if we called type on this expression, then what would then what would we get? Well, Python would tell us that this is a string because it starts and ends with a single quotation bar. That's all for now. Until next time. Welcome back. Sometimes it's necessary or convenient to be able to convert values from one type into another in Python. And for that, Python has type conversion functions. So the type conversion functions that we'll learn right now will be int to convert to an integer float to convert to a floating point number and string str to convert to a string. And each of these type conversion functions expects an argument. And usually we want to pass in arguments. That's another type. So for example, if we're calling in to convert to an integer, then we'll usually pass in an argument. That's something else either a float or a string. So let's look at that in code. So here we print out the value 3.14. And then we print out the value of in when called with 3.14 as an input. And the value of this overall expression is going to be 3.14 a float cast or converted into an integer. So the value of that expression is going to be three. Now when Python converts a float to a string, it always just does that by discarding or kind of cutting off the decimal point and everything after it. So 3.14 becomes three. What that also means is that 3.99999 also becomes three. So that's how Python chooses to cast a float to an integer. So this will make sense sometimes if we do 3.0. But other times it might end up being a little bit strange. So casting negative 3.99999 from a float to an integer ends up being negative three. So in addition to converting floats to integers, we can also convert strings to integers, which actually comes in handy fairly often. So here we have a string 2345. And let's say that we wanted to convert that string into the integer 2345. We do that by calling the int function and using the string 2345 as input. Another note, if we take in something that's already an integer and call the int function on it, then we're going to get that same value back. So if we call int 17, then we just get the integer 17 back. Now we can call int on any string. So for example, if we call int on this string, but Python isn't necessarily going to be able to convert every string into an integer. So for example, here this string starts out with 23, but it also contains bottles. So when Python sees that we're trying to convert this string, which isn't quite an integer into an integer, then Python gives us an error. So here we're told that on line eight, there's an invalid literal for it. So it's telling us that this string can't be converted into an integer. Now the float function works just like the int function, except rather than converting to an integer, it converts it to a float. So if I call float on the string 123 period 45, then that converts it into a float 123.45. And if we print out the type of this expression float 12345, then we're going to get that its type float. So you can see that the value of this expression was the float 123.45. And the value of this expression, which computed the type of this expression is a float. Now in addition to in float, we can also convert into a string. So for example, we might print out what's the value of the string 17 of string 123.45. And then if we print out what's the type of this expression, then we're going to get that this is a string. So let's run our code to be sure that this is the case. So we can see that when we print out string 17, it prints out the string 17. It just so happens that the output actually matches up with if we print it out the integer, but this is a string. This is also a string because we converted it again using the str method. And then the type of this expression is a string. So that's telling us that when we call str on this number, then we get a string back. So one reason that we might want to use casting is when we want to concatenate or combine values. So let's suppose that we have an integer val, which is set to 55, and we want to print out the value is val. We get an error saying type error, val must be a string not an integer. So we have to add a conversion to convert val from an integer to a string by calling the str function. So we print out the value is, and then if this is an integer, we need to add the str to convert it to a string. What value is printed when the following statement executes? So again, when we call the int function to convert or cast this float into an integer, Python does that by just cutting off everything that comes after the decimal place. And so even though this number rounds up to 54, we're going to instead get 53 as our answer. So the answer here is b. That's all for now until next time. Welcome back. If you write an expression to compute a value, then you probably want to store that value somewhere. Variables are useful because one, they allow us to store the values of expressions to be used later on in our programs. And two, because they allow us to give us human readable names for values that we can then reuse later on. So for example, in math class, if you ever have done geometry, then you might be familiar with pi. And when you use pi, you usually don't write out 3.14159, etc. Instead, you just use the symbol pi. So pi is almost like a variable. It has a name and a value. And Python has an equivalent to variables in its programming language. So every variable has a name and a value. So in this program, we create three variables. The first variable is called message, and it's created on line one. So message has the value WhatsApp doc, which is a string. And then we create a second variable whose name is n and whose value is 17. And then we create a third variable whose name is pi and whose value is 3.14159. Now the first three lines are setting variables. And then we reference or use those variables in the last three lines. So if I run my code, then you'll see that I get three things printed out from lines 5, 6, and 7. So when we print out message, then we print out WhatsApp doc. When we print out n, then we print out 17. When we print out pi, then we print out the value 3.14159. Now it's useful to be able to kind of simulate the execution of programs like this in your head. And in order to do that, we have what's called a variables values diagram or a reference diagram. Now to draw a reference diagram, what we do is we go line by line from top to bottom. So we start at the top, line 1, and then go down. And for every line, we're going to say what variable is set to what value. A reference diagram has two columns. It has variables and values. So what we do is we go line by line from the top of the program to the bottom. And we're going to say what variable is set to what value. So in this program, on line 1, then we set the variable message to the value, the string WhatsApp doc. So in our variables values diagram, we say the variable message is set to the value WhatsApp doc. On line 2, we set the variable n to the value 17. On line 3, we set the variable pi to the value 3.14159. And now by the time we get to line 5, when we say print out message, then this expression is an expression whose value evaluates to whatever message is pointing to. So when Python says print message, it looks at this and it says this is an expression, specifically it's an expression that references the variable message. And so the Python interpreter looks in this variables values diagram and it asks what's the value of message. We see a message here and we see that messages value is WhatsApp doc. And so what that means is that when we print out message, then we print out WhatsApp doc. And same thing for when we actually look up the value of n. So when we say print out the value of n, then Python is going to first look in this variables values diagram, and it sees that the value of n is 17. So what that means is that when we print out the value of n, we print out 17. And same thing for when we print out the value of pi. So Python looks in this reference diagram sees that pi is 3.14159. And when we print out pi, then we print out 3.14159. Make this green just to be slightly clear. Okay, so you might ask what happens if we actually overwrite the value of a variable? So what happens if we actually have a variable that I'll just call x and reset it to 5 and then I'll say print x and then I'm going to later on reset x to be 10 and I'll say print x again. So in order to determine what's going to happen here, then I'm going to write out my variables values diagram. So line one sets the value of the variable x to the value 5 and then on line two, when we print out the value of x, then we're going to print out 5. On line four, we set the value of x to 10. And so what that does is it says x no longer points to 5, so I'm going to erase this line and I'm going to cross out 5. x now instead points to 10. So x now points to 10. And here when we print out x, then we actually are going to print out 10 rather than 5. And you can see this if we run our program. So again here the first line, or the first print statement prints out 5, the second print statement prints out 10. So every variable has a name and a value. Even though the value of a variable can be anything, the name has some restrictions. So every variable name has to start out with a letter and variable names can only contain letters and numbers. So for example, x is a valid variable name because it starts out with the letter and only contains letters and numbers. Same thing with my variable. I can also have capital letters. So I can say x, y, z, capital X, y, z equals 100. And these are all valid variable names. So if I print out the value of x, y, z, then it prints out 100. One thing to note is that Python is what's called case-sensitive. And what that means is that the variable name x, y, z in all capitals is different from the variable name x, y, z in lower case. So if I print out x, y, z in all capitals, I get 100. If I print out lower case x, y, z, then I get this other variable value. If I print out x, capital Y, z, then there's no variable that's called x, capital Y, z, and so I get an error saying that this variable is not defined. So variable names have to follow these two rules. Start with a letter and it can only contain letters and numbers. And what that means is that a variable name that starts out with a number, so if I say 2x equals 50, this is not a valid variable name because it starts with a number rather than starting with a letter. And if I try to save and run my program, then I'm going to get a syntax error because I have a bad variable name here. I can have a variable called x2 because that starts with a letter, but I can't have a variable name 2x. One thing to note here is that Python also treats underscores like characters. So what that means is that I can have a variable my variable and I can set it to 5.5. And if I print out the value of my variable, then I'll get 5.5. So because Python treats this underscore character as a letter, people often use underscores as a substitute for spaces in their variable names. So variables are a useful tool that we'll use to, one, remember an expression's value to use later on, and two, to give a nice name to the value of an expression so that it's more human readable. Until next time. Welcome back. So far we've talked a little bit about expressions, which are the building blocks of programs, values, which are what Python evaluates an expression to, and then types, and in Python every value has a type. So there's one more concept which is called a statement. A statement is a complete instruction that the Python program executes. So the only statement that we've seen so far has been the assignment statement, where you say something like x equals 1 plus 2 plus 3. So here, this is a complete statement. And in this case, it's an assignment statement. But this part is an expression. And so when Python is computing the value of this expression, it breaks it down into smaller parts. So it first adds 1 plus 2, takes the result, and then adds 3 to that, and then it gets 6 as the value of this expression. And then the statement says, assign the value 6 into the value for the variable x. Now let's look at just a few other examples of expressions. So here, the expression 500 is what's called a literal expression, because the value 500 is going to be the same as the expression itself. And this has type integer. Another literal expression with a float might be 3.14, which has value 3.14, and has type float. And again, we can have slightly more complex expressions as well. So we might have an expression that adds two numbers. So 200 plus 300 is an expression. When Python sees this expression, it computes its value, which is 500, and an integer. And we can have expressions, of course, with floats as well. So we can have 10.0 plus 5.0, an expression that has the value 15.0, which is a float. Now whenever we call a function, including the print function, Python first evaluates the value of the expression that we're actually printing. So here, on line 1, we're calling the print function, and Python sees that the argument to the print function is this expression. And so what Python does is it doesn't print out the expression itself. It instead first computes the value of this expression, and it computes the value of this expression by breaking it down into smaller sub-expressions. So here, Python is going to compute 1 plus 1 and get 2. And then it's going to compute the value of this sub-expression, 2 times 3, and it gets 6. And then we add 2 plus 6 to get 8. And 8 is the final value that we actually print out. Here, when we print out the value of this expression, then Python first figures out what's the value of this expression. Here it's a literal expression. So Python figures out it's a string that has H-E-L-L-O as its characters. And then when we call the lend function on that string, then we see that there are 1, 2, 3, 4, 5 characters. So the value of this overall expression is going to be 5, and that's what gets printed out. So again, Python does the work of computing the value of the expression that we're printing out, and it prints out the value of the expression and not the expression itself. So you'll see when we run our code that the first line prints out 8 because that's the value of this expression, the second line prints out 5 because that's the value of this expression. And the same thing goes when we're actually assigning variable values. So if we say y equals 3.14, then that assigns the variable y to the value the float 3.14. But when we say x equals the lend of hello, then as Python is evaluating line 2, it crosses this out and computes the value of the actual expression. So the value of that expression is 5. And so that value of 5 gets assigned to x. So in our variables values diagram, x points to 5. Now when we print out x, we're going to print out 5. When we print out y, we're going to print out 3.14. Now we can combine different kinds of expressions into larger expressions as well. So here, this print statement prints out the value of one large expression. This expression combines literal expressions with function call expressions and also arithmetic operators. Now when Python is computing the value of this more complicated expression, then again, it kind of breaks down every expression. So here, Python goes from kind of the inside out and it says, okay, what's the lend of hello? And it crosses this out and replaces it with 5. What's the lend of goodbye? We get 1, 2, 3, 4, 5, 6, 7. So it crosses this out and it gets 7. And then it knows we're printing out the value of 2 times 5 plus 7. So 2 times 5 plus 7. Then Python computes the value of this sub expression, 2 times 5, and it gets 10. And it adds 7 to that. And then it gets 17 as the value of the overall expression. So if I run this code, it's just going to print out 17. So in this code, we first assign x to be 2. So in our variables, values table, we say that x points to 2. Then we assign y to be 1. So we assign y to be 1. Now again, when Python sees a complex expression like square when called with y plus 3, it evaluates kind of from the inside out. So it first figures out what's the value of y and then it sees that y is 1. And then we add 1 plus 3 and that gives us 4. And so that means that we're taking the square of 4 and that gives us 16. And that means that the value of this overall expression is going to be 16. Here on line 4, we're printing out square of y plus square of x. So Python, again, you can think of it as competing from the inside out. So Python is going to replace x with 2. So that means that square of 2, the value of this expression is going to be 4. When we add y whose value is 1 to 4, then we get 5. So that's, you're taking the square of 1 plus 4 or the square of 5. And then when we take the square of 5, then the value of this overall expression is going to be 25. In this third example, we're taking a sub of square of y and square of x. So Python first asks, what's the value of y? For y, it gets 1. And then square of 1 is going to be 1. That's what's the value of x. That's 2. It takes square of 2 to get 4. And then so we're calling sub with 1 as the first argument and 4 as the second argument. And that's going to give us 1 minus 4 or negative 3. So you'll see that's what gets printed out for this line. And 25 gets printed out here. And 16 gets printed out for line 3. That's all for now. Until next time. Welcome back. Now for this video, I want to be a little bit more precise about how Python evaluates expressions in the order that Python evaluates different expression parts in. Now when we're doing a function call, the first thing that Python does is it evaluates the function that we're calling itself. So it evaluates the function itself. So in other words, let's suppose that we're calling this add function. The first thing that Python is going to do is it's going to look up what is the value of this expression. And it's going to hopefully see that add as a function. Now the function call expression might be something more complicated than just a variable name as long as it evaluates to a function. Then the next thing that Python is going to do is it's going to evaluate each one of the arguments in order. So it evaluates the arguments from left to right. And so in this example, the first argument is square. So Python is going to compute the value of this expression. And then it's going to compute the value of this expression. And then finally, after Python knows what function it's calling and what the value of every argument is, then Python is going to finally call the function. And then the value that that function calls returns is going to be the value of this overall expression. So let's see that in action. So here we assign x to 5 and y to 7. And the first thing that Python does is it evaluates this add function. So it sees that add as a function. And so the next thing that it does is it evaluates each one of its arguments. So first it evaluates this sub expression and it sees that square itself is a function. And so it's going to repeat that process and it looks up square and finds that it's a function. Then it repeats that process, looks up y, finds that its value is 7. And then it's going to call square on 7 and get 49. Then it's going to look up the value of this square function and it's going to see that it's a function. It's going to compute the value of each one of its arguments. So it's going to see that x is 5. And then it's going to call square on 5 to get 25. So, so far what Python did was it found what's the value of add and then it computed the value of its two arguments. And then it ended up getting 49 as the first argument and 25 as the second argument. And so now that we have the function itself and all of the arguments, then we can finally call the function add on 49 and 25. And as a result, we're going to get 74 as the value of this overall expression. Now suppose that we have this complex expression, square of x plus sub of square of y and two times x. And we're asked to figure out what order is Python actually going to evaluate these arguments in. Now, bear with me for a bit as I drag each one of these blocks in the correct order. Okay, so the first thing that Python is going to do is it's going to try to look up the square function. And so if we see, yeah, look up the variable square to get the function object. And then it needs to compute the value of each one of its arguments. So here there's only one argument. And so the first thing that Python is going to do when figuring out what's the value of x plus sub of, you know, this function, is it's first going to look up the value of x because that's leftmost. So it's going to be look up the value of variable x. So I'm going to get look up the value of variable x to get two. And then before we can add x plus this expression, then we need to compute the value of this expression. So when computing the value of this expression, then we need to in turn look up the value of the sub of the sub function. So we need to look up the variable sub to get that function object. And then we're computing of the value of its arguments. So the first argument is square of y. So in order to do this, we need to look up what's the square function. So we look up the variable square again to get the function object. And then we need to compute the value of its argument. So we need to look up the value of y. So we look up the value of y to get three. And then we back up and we need to compute the value of the second argument to sub. And in order to do that, we need to look up x again to get two. And we need to multiply two by two to get four. So now we have the value of both of these expressions. Oh, excuse me, there is one more thing here. So after we look up the value of variable y to get three, we actually call the square function. So here after we look up y to get three, we have to run the square function. Okay, so now we have the value of this sub expression or this argument and this argument. And so now we can finally call this sub function. So we run the sub function on inputs four and nine, giving us the value five. And so then we get x plus five. So that's going to give us two plus five. And we get seven. And that means that we're calling square with seven as an argument. And so we run the square function again on the input seven, giving us the final value of 49. That's all for now until next time. Welcome back. So we've seen how to assign variables to different values. For example, on line one here, we have code that assigns the variable x to the value six. And what that does is you can imagine a variables values table that says x now points to six. And so what that means is that after we've assigned x to six on line one, if we print out the value of x on line two, then this should print out six. Because Python asks, what's the value of x? It looks in this variables values table. It sees that x points at six and it gets six. Now, what happens if we say something like on line three, x equals x plus one. Now, on first blush, this might look almost like a contradiction. But the way that Python evaluates this expression is it first computes the value of this expression. And then it takes the value of this expression and assigns it to the new value for x. So in other words, what Python is first going to do is it's going to ask, what's the value of x and Python is going to get six. And then it takes that and adds one to it. So the value of this expression x plus one is going to be seven. And so all Python does is it computes a value of x plus one to which we get seven. And then it puts that as the new value for x. So x is no longer six, x is now seven. So now when we print x on line four, then this prints out seven. So if we run our code, you'll see that when we print out the value of x on line two, we get six. But then after reassigning x to be x plus one on line three, then when we print out x on line four, then we print out seven. Now this kind of operation where we say x equals x plus one, or whatever x is, or whatever x's previous value was, we want to add one to it and reassign that to x. That's actually really common. And for that reason, Python includes a shortcut for incrementing and decrementing like that. So let's run through this code. So on line one, we assign x to have the value six. And then we print out the value of x, which is going to print out six. On line three, we have this special syntax where we say x plus equals three. x plus equals three is a shortcut for saying x equals x plus three. Now it allows us to just say the name of the variable x only once here. So it's a little bit shorter and less verbose, especially if we have much longer variable names. So again, this increments x by three and reassigns it. So if we have our variables values table here, on line one, we've assigned x to be six, then we print out that. On line three, we say x equals x plus three by saying x plus equals three. So x is no longer six, x instead becomes nine. Then when we print out x, this prints out nine. And then we can do the same thing with subtraction. So we can say x minus equals one as a shortcut for saying x equals x minus one. And so that's going to take x from nine and it's going to reassign it to the value eight. And now when we print out the value of x, then we're going to print out eight. So you can see x goes from six to nine to eight. So we can do reassignment as many times as we want. So we can say s equals one and then we can add two to it. Then we can add three to that and four to that, et cetera. If I run this code, you'll see the different values of s. So s starts out as one. When we add two to that, it becomes three. When we add three to that, it becomes six. When we add four to that, it becomes 10 and so on. Later on in this course, you'll find an even a much shorter way to actually do something like this. Now let's run through some multiple choice questions. What gets printed out when the following statements execute? So here we assign x to be 12. So x has the value 12. And then we say x equals x minus one. So the value of this expression, we replace x with 12 and we subtract one from 12 to get 11. And we take 11 and that's x is new value. So x is no longer 12, x is now 11. So when we print out x, we're going to print out 11 or c. Next question, what gets printed when the following statements execute? So here we first assign x to be 12. Then we say x equals its previous value minus three since x goes from 12 to nine. Then we say its previous value plus five. So x goes from nine to 14. So then we say x equals x plus one. So it goes from 14 to 15. And so x ends up with the value 15 or c. Next question, construct code that will result in the value 134 being printed. So the first thing that we want to do is we want to assign an initial value for bank balance. If I try to put this first, then Python when trying to evaluate the value of this expression we say that it didn't find a variable named myBankBalance. So I know that this line can't come first. Here I can do the assignment first so I can assign myBankBalance to 100 and then I can reassign it like I do here. So this looks valid and by the end of running these two lines then myBankBalance is going to have the value 134. And then if we print out the value of myBankBalance on line three then we're going to print out 134. Next question, which of the following statements are equivalent? So I see this statement reassigns x to its previous value plus y. This statement assigns y instead of x. So I know that this can't be equivalent to statement a. x plus equals x plus y looks like it's similar to statement a but what that's really saying because we have plus equals here is x equals x plus x plus y. So here we have that extra x plus so that's not equivalent to statement a but statement d is and then statement e just wouldn't work. So statements a and d are equivalent. That's all for now until next time. The last thing I want to talk about in this lesson is hard coding and before I get to that I'm just going to tell a kind of motivating story from my childhood. So I have three older siblings and when they were doing algebra then if you remember algebra then you often get problems of the type solve for x solve for y solve for z. And one day I overheard my sister talking on the phone with a friend about a math problem that they had and they were trying to solve for the value of x and I overheard my sister saying the value of x is three and when I heard that I thought that I had found out some hidden secret about algebra x is three. I could take every single problem that involved x and just substitute three in I had cracked the code and I didn't have to learn algebra anymore. I could just skip that grade. Of course if you have actually taken algebra then you know that x isn't three. You know that you have to solve for the value of x every single time. So what I was thinking of doing there was a form of hard coding or thinking that x is three for every single problem. So in the context of solving Python programs what hard coding is is it's writing down the answer without actually going through the work of competing the answer. So let's suppose that I want to write a program to print out the value of x and y averaged. So if I have x equal to 10 and y equal to 20 then I could hard code my answer by saying average equals 15.0 and I let's say print out that average and so yes in this case I happen to get the right answer that the average of x and y is 15 but my answer is hard coded because I said that the average was 15 and what that means is that if I change the value of x here to be 30 the average should be 25.0 but instead I still get 15 because my answer was hard coded. So what I'll do is instead of writing out average equals 15 I want to actually write out the expression that's going to reference x and y to compute the average. So I'll say average equals x plus y divided by 2 and so even though I still get the same answer of 15 then because this answer is no longer hard coded if I change the value of x to 30 then my answer is still going to be correct. Same thing if I change the value of my answer y to 40. So in your assignments we'll often say don't hard code your answer and what that means is that you have to write expressions that actually reference the variables and rather than just jumping straight to the answer you actually have to write expressions and statements that will actually compute the answer in your code. Until next time. Welcome back. So Python gets a lot more interesting once we learn how to write code that doesn't actually execute or output the same thing every single time that we run it. Now the first way that we'll learn how to add some variability into what our code executes is by getting input from the user. So we'll be able to have different outputs from our code even with the same program by asking the user for some input and then doing something with that input. And the way that we'll do that is with the naturally named input function. So input asks the user to enter something. So for example in this code on line one we ask the user to input their name by calling the input function and the input function accepts a prompt as its argument and so here we prompt the user please enter your name. Now the value of this expression of input is going to be whatever the user entered. So if the user enters Steve then the value of this expression is going to be the string Steve. The value of input is always going to be a string no matter what the user enters. So if the user for whatever reason enters 500 then the value of this expression would be the string 500. And now n gets assigned either Steve, 500, or whatever string the user entered. And so when we print out hello n then we print out hello and whatever the user entered. So let's run this code into what we get. So when I hit save and run you'll see that I have this prompt here and it says please enter your name and that's the exact prompt that we passed into input. So if I type in Steve as my name then you'll see that my code then prints out hello Steve. If I save and run my code and I enter something different so let's say that I enter Paul then my code is going to output hello Paul. I can enter absolutely anything that I wanted here so I can enter 9999 and my code is going to print out hello 9999. So again input always gives back a string but let's suppose that we wanted a number instead of a string. Well the way that we would do that is by casting or calling one of the functions to convert strings to a number. So for example let's suppose that we wanted to write some code that was going to convert a number of seconds into a number of hours and a number of minutes and we want to also compute the remainder when we actually divide together the number of hours and minutes. So here we prompt the user please enter the number of seconds that you want to convert and then we put that into this variable str seconds. The next thing that we do is we cast that variable str seconds because again input always gives us back a string we cast that to be an integer and we assign that to be total seconds. We then compute the number of hours by taking total seconds and then doing division without remainder by 3600 to convert seconds into hours and then we find out how many seconds are still remaining by taking the remainder of total seconds when it's divided by 3600. Then we take those seconds that didn't divide evenly into the number of hours and convert them into minutes by again taking the remainder I'm sorry by again dividing without remainder by 60 and then we figure out how many seconds are still remaining at the end of this by taking the remainder when we divide seconds still remaining by 60 and then the end we get the number of hours, minutes and seconds for whatever number of seconds the user input. So if I save and run my code and then let's suppose that I just want to convert 60 seconds then I'll see that this is zero hours, one minute and zero seconds if I convert 6000 seconds then I'll see that this is one hour and 40 minutes if I convert 999 seconds then I'll see that 16 minutes and 39 seconds, etc. So again the point of this is we can use whatever the user entered as an integer by converting it to an integer by calling the int function or if we wanted to make it a floating point we might call the floating point function. Now you might ask what if the user enters something other than an integer so if we're asked to enter the number of seconds that I want to convert and I type in let's say a name and I run then you'll see that Python wasn't able to convert Steve into an integer and so we get a runtime error. Now let's look at a multiple choice question. So this asks what gets printed when the following statements execute. So let's suppose that we ask the user please enter your age and then the user enters 18. So here n gets assigned to the string 18 because remember input always gives us back a string. It doesn't matter what the user actually entered even if they enter 18 then n gets assigned to the string 18 and when we print out the type of n then we're going to get that n is a string. That's all for now until next time. There's lots of minutia to master when you just get started programming and it can be kind of tedious and not so rewarding. In today's lesson we're going to give you a chance to be creative do something a little fun. You're going to write programs that will instruct an on-screen turtle to draw a picture. Now I have with me some bobblehead turtles handcrafted in Mexico to give us a little inspiration. In our live classes sometimes I use them as prizes for especially good pictures. So you can be writing programs that will instruct your on-screen turtle to draw a picture but there's also a hidden agenda in today's lesson which is to introduce some Python capabilities particular object notation, methods that act on objects and how to repeat a set of commands many times. At the end of this lesson you should be able to write a multi-line program or program with many lines of code. You should be able to distinguish between instances, attributes and methods. You should be able to invoke methods and set attributes using the dot notation and you should be able to use a loop, a for loop to execute commands repeatedly. And stick around at the end for a turtle joke. See at the end. Let's learn how to draw some pictures. Our metaphor here is that there's a virtual turtle. It starts out in the middle of the screen. In the turtle's tail there's a pen. So when the turtle moves around it leaves a drawing on the screen. In this code we've created a turtle named Alex and we're telling it to move forward and turn left and go forward again. Let's see what its picture looks like. So in this case our virtual turtle is really represented by just an arrow. It doesn't even look like a turtle. But he started over here, moved forward by 150 pixels. That's what happened on this line of code. Told him to start here and go forward by 150 pixels. He then sort of turned left by 90 degrees. That's what the line 5 told him to do. And then he moved forward by 75. Let's go through in a little more detail what each of these lines of code does. The first line just says to make our turtle commands be available. The second line says make a screen. So that's what line 2 does. And then any turtle things that we have in the rest of the program will happen on that screen. Line 3 makes a turtle. That's what creates our little turtle guy. And it assigns that turtle object to the variable called Alex. On line 4 we are invoking a method, the forward method. So this is our hidden agenda. And this lesson is to teach you about objects in this dot notation. So Alex is the name of the turtle. If you have an object and then a dot, it will look up attributes or methods of that object. So Alex dot forward says find the forward method, which is just like the functions that you've seen before. It takes an action. In this case it says take the forward action on Alex. And we pass in the value 150. That says how much Alex should move forward. So we have object dot method. And in parentheses we pass a value. So on line 5 we're telling Alex to turn left by 90 degrees. Line 6 says move forward by 75 degrees. And because Alex has a pen in his tail, we get to see the lines that show where he went. So a little vocabulary we've gotten here. We've gotten the idea of an instance. Alex is an instance of the turtle class. WN is an instance of the screen class. So turtle is a class. Alex is an instance of that class. Screen is a class. WN is an instance of that class. And we've gotten the idea of a method like forward or left. Now in addition to these things, we can also set and read attributes. In this turtle drawing we don't really need to do it. But I want to show you how setting attributes works for object instances. So Alex is an instance. And if I want to set any attribute, let's say Alex is salary, because he should really be paid a lot for doing all of this drawing work for us. And we'll set his salary, let's say, to $50,000. If I do that, Alex will store in its salary attribute the value $50,000. And I can then refer to it just like we would other variables. So Alex refers to the instance and we can print out his salary. As before, when we print things, they're going to show up in our output window. So this is going to redraw that whole thing. And at the end of it, it's going to print out the $50,000. That's because we printed it here. So we're not going to do much with these attributes of instances for a while, until much later in this course sequence. But we wanted to give you a hint of it before we went too far with Python. I want to make a little more interesting picture. Let's see if we can finish making a rectangle here. So instead of doing this stuff with Alex's salary, let me get rid of that. And let me have Alex do a little bit more. I'm going to have him turn to the left by 90 degrees again. And what that should do is turn him that way so that when he goes forward, he'll be going in that direction. Now, how far should I make him go if I want it to be the same distance as this one was? Well, that one came from here. So I have to have him go forward by 150. Let's see what happens when we run that. It's always a good idea to run things when you write some code. Great, that seems to have worked. Let's have him turn and finish the rectangle. This time I have to go just 75 the shorter length. Sure enough, we've got a rectangle there. Welcome back. We can have more than one instance of a class. And each one will have its own attributes, its own internal state. In this code, we'll create two turtles, Alex and Tess. Tess is going to draw a triangle with a thick black pen. Alex will draw a square with a pink pen. So let's go through the code. First we'll run it. That's test drawing there. And now Alex is drawing. So let's go through the code. As before, we need to import the turtle module and create the screen. That creates the place for us to do the drawings. In this case, we get that instance down to the variable WN. And we're calling the BGColor method on it to make it be light green, as you're seeing here. We create a turtle Tess and we set its pen size to be five. That's what makes Tess have this wider pen instead of just the narrow pen that's the default. We create a second turtle called Alex and we set Alex's color to be hot pink. After that, we have a whole segment where we have the movement commands for Tess. That's where she does her drawing. And then below that, we have some movement commands for Alex. And finally, there's this little WN.exit on click. That just says that when somebody clicks on the window, it disappears. Let me make a couple comments about the coding style here. One thing to notice is that we've chunked the code using some white space. And that just makes it easier to read. That segment that I just marked, lines 12 to 17, is what causes Tess to make her triangle. And then there's a break with a blank line on line 18 and then lines 19 and 20 have her make her extra line that goes off to the left at the end of the drawing. And there's another blank space and we get from lines 22 to 29 Alex's movements. We don't have to do this chunking in order to make the picture come out right. We do this chunking because it makes it easier for people to read the programs. You can sort of look at it and say, oh, there's a chunk of code from 22 to 29 and that's drawing a square. There's a chunk of code from 12 to 17 and that's drawing a triangle. One final thing to notice and I'm going to rerun this so that you'll get to see it again. You might notice that on line 17 Tess turns to the left by 120 degrees then on 19 she turns to the right by 180 degrees. We're following a little convention that lines 12 to 17 are drawing a triangle and putting Tess back into the same orientation that she started in. It just makes it easier for a programmer to think about it if the net impact of all of the movements is to leave Tess back in her original position in the same orientation. Similarly on line 29 you'll see that after we've completed the square we make Alex turn to the left for 90 degrees even though we're not going to make him move again. That's again just trying to get him back into the same orientation he was in before. This would be especially useful if we were going to take the whole block of code and reuse it and that's something that we'll see later in the course where we define functions. We could make a function to draw a square and wherever he starts the turtle would create that square and leave the turtle in the same spot that he was in before. So let's go on and do one of the Parsons problems. At the bottom of this page you'll find more than one Parsons problem. I'm just going to go through one of them. Here we're going to create a program that has one turtle Jamal draw that capital L in blue and then Tina is going to draw that orange line. So this is a mixed up code problem. We have all of the code that we need to have Jamal draw his blue L and Tina draw her orange but your job is to drag the parts over and drop them off in the right order. The first thing to remember about this is that the very first thing in any turtle program is you have to import the turtle module so that we can have all of those turtle commands available and you have to create an instance of the screen so that there's a place for the turtles to draw. In the instructions it said that all the stuff with Jamal should happen first so those things are going to come before the Tina stuff. But we do have a little decision to make. Should we make the left and the forward commands first or should we have this larger block first? And the clue here is that you can't have Jamal turn left before you create Jamal. So we need to have this block first because it has the line of code Jamal equals turtle dot turtle that creates the instance Jamal. Tina stuff happens after Jamal. Oops, got to get that a little lower. And finally, we have our exit on click so that when the user clicks on the drawing it disappears. Let's check it and make sure I got it right. Perfect. All right, see you next time. Suppose we have a line of code or a bunch of lines of code that we'd like to make run more than once. You could just write those lines of code and copy and paste them so that you add them again but that would start to give you long programs that were hard to understand. So Python gives us a special command that says do some lines of code multiple times. It's called a for loop or iteration. We begin with a special word for then we have some variable name or in this case since we're not really using it we just have underscore and we have a special word in and in this case we say do it three times. And then we have a colon all of the lines of code that are indented farther in this case by a few spaces. All of those lines of code are a block and that block of code will be executed three times in this case. It's always a good idea to work on your understanding of code before you run it to try to predict what it'll do. In this case you might imagine that it's going to print in our output window this will execute first and then it'll say this will execute three times this line will execute three times this line will execute three times and then this line will also execute three times this line will also execute three times. But in fact it doesn't do that it doesn't print this line three times and then this one three times. What it does is it executes line four and then line five and then four and then five and then four and then five. So the whole block is executed and then the whole block is executed again and the whole block is executed a third time. Let's see how that works. So you can see in our output window the whole block executes once and the whole block executes a second time and the whole block executes a third time. Let's go look at the next example. In this next example we're going to be able to draw a more interesting turtle program by having a set of commands get executed a bunch of times. In this case we're creating a turtle named Elon and we're going to make Elon do some commands 10 times for I underscore in range of 10 do this block from lines 8 through 10 do that 10 times. So Elon's going to go forward by 50 and then turn right 90 remember from the previous chapter what distance equals distance plus 10 does we had the variable distance and it was initially bound to the value 50. We look up 50 plus 10 that equals 60 and we replace the 50 with 60. The next time that we execute line 10 we're going to replace it with 70. And you can see that that distance variable is used here to determine how far Elon will move. So each time Elon moves forward he's going to go forward a little bit farther 50 pixels the first time then 60 then 70. So before I run this you might want to pause the recording and see if you can envision in your mind what is this going to look like when I run it. Here we go let's see. So it's getting a little bit longer each time and that means instead of just making a square it ends up making a spiral. So how many times does it do this block? It does it 10 times because it says range of 10 there. Now what if I made the angle increase every time too? Suppose instead of turning right by 90 degrees I turned right by whatever the current value of the angle was and it started at 90. If I do this I get just exactly the same picture that I have right now but suppose that I change the angle every time. Maybe I'll make it a little bit smaller. So again you might want to pause the video and see if you can predict what this is going to look like. Here we go the angle is getting a little smaller each time and so we end up with this even more interesting spiral. Now if I wanted the spiral to go even farther I could increase this range. This means it's going to go forward and turn more times. Means a little off the screen there and now he's back maybe he's gone forever now. So that's making the turtle do a set of commands a bunch of times so that we can have a relatively short program but have it do a lot of drawing on the screen. Let's see a few more interesting things we can do with turtles. We've got another little spiral in this case we're not seeing the whole line. Tess is moving around and only leaving her imprint occasionally. So how did that happen? First as before we've seen things where Tess is getting a color in this case blue. We also changed her shape so instead of being that little abstract triangle representing a turtle now Tess really looks like a turtle. On line 9 we introduced a new method called up. What that does is lift the pen up off the paper so that when Tess moves she doesn't leave a line behind her. As before we have a for loop. So 30 times we're going to execute that whole block of code. On line 11 we have a new method called stamp which basically stamps Tess's shape at the current location where Tess is. The rest of the things are things that you've seen before. He's moving forward, the distance is increasing a little bit. Each time that's what makes it a spiral. In this page in the textbook there are some more mixed up code problems, Parsons problems, and I really encourage you to take a look at those because they will help you reinforce what order these things have to happen in and the fact that you have to indent the block of code under the line that says for. See you next time. Welcome back. In all our turtle examples I kind of glossed over the import statement. In this specialization we're trying to minimize the amount of magic. We want you to be able to read code and reason about it. So this video provides some details about that import statement. There are lots of functions and methods available to you in Python that other people have already written. And we can just invoke them, we don't have to write them ourselves. Some of those functions are built into the core of Python, like the LEN function. You can just invoke it and it's always there. Lots of other functions are not built into the core of Python but are readily available. They're part of a standard library of modules. A module is a code file that defines some functions that can be used by other programs. Before you can invoke a function that's from a standard library module, you need to tell the Python interpreter to make it available. And that's what the import statement does. Turtle is one of those standard library modules. But we'll come back to that in a minute. Let's look at a simpler module first. There's a module called random and you just have to import it in order to make all of its functions available. One of its functions is called randrange. You can see this on line 6. We've imported the random module and then on line 6 we ask for randrange which says give me an integer between 1 up to but not including 7. So 1, 2, 3, 4, 5, or 6. There's another function called random. I'll talk in a minute about this weird thing of random.random. We have this random function that returns a floating point number between 0 and 1. In this case we got 0.72 and then we get a die roll of 1, 2, 3, 4, 5, or 6 from the randrange function. If I do it again, I may get different values. I get 0.039 and 3. Run it a third time I'll get yet again different values. There are two possible syntaxes for importing and referring to stuff from modules. The first makes the stuff available but doesn't give it any special alias. That's what this version that I'm showing in the current code does. On line 1 we make everything from the random module available but every time we want to refer to it we have to say random.random. It doesn't give us any alias. So I say random. And then the name of the function that's defined within the random module like randrange or random. Notice that this is another use of the dot notation. Before we've seen something like test.forward where test was a turtle object and dot forward and we would say how many pixels to go forward. Forward is a method that can be applied to test the turtle object. Here we're saying random.randrange. It's a little bit analogous. We're getting something from the random module and that something is the randrange function but it's not exactly the same. Random is a module, not the kind of python object we've been seeing so far. The way to tell the difference between these two different uses of the dot notation is just by the context. If we said import random as we did on line 1 then random.something will find the something object inside that module. Anyway, that explains the funny random.random on line 3. Random is the name of the module. That gets us the first random. And inside that module there's a definition of a function also called random. And that gives us the second random. Similarly, random.randrange. Random is the name of the module. randrange is a function inside that module. One thing we can't say is randrange.random. That is going to fail. Don't do that. The second approach to importing stuff from other modules puts the functions directly into our local namespace so we don't have to keep referring to the module they came from. Let me show you how that works. Instead of saying import random we're going to say from random import randrange. And we can also import the random function while we're at it. Now when we refer to them we no longer have to say what module they came from. Those names become available in our local namespace. And this will work just like the other one did. We got a new value there when we ran it again. Either of these two different ways works. Either the commented out version that I have on line 1, import random or the other version on line 2 from random import randrange and random. But you have to refer to the things a little differently depending on which one you did. So if we say from random import randrange then we'll just refer to random. If we did the other one we'll have to say random dot random on line 4. With that understanding of module importing let's take a look back at how we imported the turtle module. Let's look at lines 1 through 3 here. On line 1 we say import turtle make everything from the turtle module available to us. And then on lines 2 and 3 we're doing that turtle dot thing. On line 2 we do turtle dot screen. Now we haven't explicitly talked about classes yet and you won't talk about that until much later in the specialization. But this is creating a new instance of a class. The class capital screen is defined in the turtle module. Similarly the class turtle is defined. It's like we're invoking a function but it's a function that creates a new turtle object. On line 2 it's creating a new screen object. So this is just an example of the same syntax we were seeing with import random previously. We're importing the turtle module and then we're referring to something screen that is defined inside of the turtle module. By the way, we only have a few of the standard library modules that would normally be available in Python. Only a few of those are available in this runestone textbook environment. We have the random module, the turtle module, and the math module. But there are a lot more that are part of the standard distribution if you just install Python on your own machine. They can do lots of stuff for you so you don't have to write very much code yourself. You just have to find the right module. And then even beyond the standard library there's lots of other modules that you can install if you've installed Python on your local machine. By the way, if you haven't seen XKCD before there's lots of great geeky humor there and I highly recommend it. Here's one of my favorites. A friend is talking to his other friend who's up in the sky. He says, you're flying, how? His friend says Python, which I hope you're also experiencing. You're using Python and you're flying high. He says, I learned it last night. Everything is so simple. Hello World is just print Hello World. Of course, in the newer version of Python we have these days we would have to have parentheses. But it's still very simple. And his friend says, I don't know about Python. I've heard it's got these weird things like dynamic typing and white space matters. And his friend who's up in the sky says, come join us. Programming is fun again. It's a whole new world up here. But how are you flying? Well, I just typed import anti-gravity. That's it. Well, I also sampled everything in the medicine cabinet for comparison. But I'm pretty sure it's the Python. So Python has lots of great modules. Just import them. I don't know about the anti-gravity module though. We'll see you next time. As a reward for sticking around this far, here's a little joke. A snail was out on the beach taking a walk and he looked back. There were turtles behind him wearing leather jackets. Made him a little worried. So he picked up his pace. And he's inching along. About four hours later, he turns around again. And sure enough, they're still following him and they're getting closer. He's getting very worried. He moves forward, keeps going. Two hours later, he sneaks another look back. They're still following him and they're really close. So he starts sprinting as fast as he can. But an hour later, the turtles caught him. They mugged him. Took his money, his car keys. Took him all the way till the next morning before he managed to get to the parking lot to a pay phone. He calls the police. He says, I got mugged by three turtles wearing leather jackets. Can you get down here as fast as you can because they're going to get away? The officer asks, sir, can you describe the turtles in a little more detail? No, I can't. It all happened too fast. Happy drawing. I'll see you for the next lesson. Most weeks, our last lesson is going to be titled The Way of the Programmer. These segments are not about how Python works but about how you should work. Style tips for your codes, strategies for solving programming problems, habits, mindsets that will make it so that you can have fun even though it's hard work and sometimes frustrating. This week, we'll focus on debugging. Your programs are not going to always work the first time. In fact, they rarely will. You have to debug them. And debugging your code is a little bit like being a detective in a crime movie where you are also the criminal because you wrote the code. So our learning objectives for this lesson, the end of it, you should be able to distinguish between three types of errors, syntax errors, runtime errors, and semantic errors. You should develop a habit that when you get an error, you'll look at the error messages and you should start to build a skill of interpreting those error messages. You will internalize a mantra of get something working and keep it working. Don't write big swaths of code before you test it. And you'll be able to recognize some common errors and how to fix them. The first kind of error is called a syntax error. Just like in English where we have syntax is an important part of grammar. A syntax error in Python means that the statements just aren't well formed. The interpreter can't parse it. In this case, we have the word print. We have the open parentheses and then something to print. But we're missing the closing parentheses. And the Python interpreter tries to keep looking farther on. Well, there's no closed parentheses here, but maybe it'll be here or down here. And it keeps going to look for it. It can't find it. And it just says, this is an error. I don't know what the programmer had in mind here. It doesn't try to guess. It says this is a syntax error. Let's see what that looks like. We actually get an error message and it tells us syntax error. And then it tells us something about what's going on. It says EOF. That's an acronym. EOF end of file. Of course, we don't really have a file. We just have a little window, but it thinks of the contents of that window as being a file that has commands in it. It got to the end of that file. It was in the middle of a multi-line statement. The statement started on line one and it was waiting for that statement to end with that closed parentheses and it never got to the end. It got to line three, the end of the file without ever seeing a closed parenthesis. Now, in the textbook, when you're executing Python, we've actually tried to translate some of the error messages that you would get in a normal Python interpreter and make them easier to understand for someone who's just getting started programming. So believe it or not, this is actually already a little bit more human-friendly than you might get normally. And we've tried to give you a little description and some suggestions of what you should do to fix it. The other things that are suggesting aren't quite what we need. What we really needed was a closed parenthesis. The other thing to notice here is that it's telling us line three. There isn't even a line three, but certainly the place where we ought to add the parenthesis is on line one, not on line three, is just that the problem started on line one and the interpreter wasn't really sure it was a problem until it got to the end of the file, without getting the closed parenthesis. So if I put this here, now it'll run just fine. An alternative, I could have put it here, and that also would be fine. Normally, there would be no reason to do that. It would be much easier to read if you put it there. Now here I'm going to get another error. It says a bad input on line three because I have this extra closed parenthesis. These are all syntax errors that make it impossible for the interpreter to figure out what the program was supposed to do. The second type of error are runtime errors. These occur when the interpreter is able to parse the program, but during the running of the program, some illegal operation happens. For example, let me do one of those. Suppose I print three divided by zero. What is three divided by zero? Infinity may be. It's just not a legal operation. Doesn't make sense to divide by zero, and if I try to do that, I get this zero division error where it says the integer division or modulo by zero on line one. So that's an example of a runtime error. It can figure out what you're trying to do, but it's not a legal operation. The third type of error is called a semantic error. That's when the Python interpreter is able to parse the code. It's actually able to run it, but it doesn't produce the thing that the programmer intended. So, for example, suppose I try to print something that explains a conversion of a fraction to a percentage, but I do it a little bit wrong. So I say one-half as a percentage is, and then I say one over two. I'd like it to say 50%, but it's really going to say 0.5. What I should have done here is multiplied by 100 to turn it into a percentage. So one-half as a percentage is 50%. I apologize for the line break there, but you can figure out what it means, 50%. So when I left off the 100, and I just said one over two, that was a semantic error. It was a programmer's error that produced the wrong thing, but the program was able to run all the way to completion. It just didn't do what I wanted it to do. Those are our three types of errors, syntax, runtime, and semantic. In this multiple-choice question, you'll get a version of on each of the pages for the three different error types. We've got one example of each. So attempting to divide by zero, that is a runtime error. Forgetting a semicolon at the end of a statement where one is required, that would make it impossible to parse what you've written, and that would be a syntax error. If you forget to divide by 100 or multiply by 100 when you're printing a percentage amount, that would be a semantic error. It's really valuable when you get an error to look at the error message. It can tell you a lot. The first thing you notice is that there's that pink box and you got an error. You may be tempted to just go look at your code and try to figure out what's wrong, but it's really worth investing the time to look at the error message. It'll tell you a line number, which will be a good clue, to learn to decode the specific messages. They will also be really helpful. So let's go through an example here. Here's a program that's going to ask for a couple of inputs. It's going to ask what time we want to start, how long we want to wait, and at the end it's supposed to print. So if I enter three o'clock, or three is our start time, then I want to wait four hours. It should tell us that that's seven o'clock. Let's see what actually happens. What's the current time in hours? Let's say three. How many hours do you want to wait? Four. And it should print out seven, but instead we get that pink error box. Let's go see what it's telling us. It says, first of all, that line five is a good place to look. It says the type of problem that we have is a name error, and in particular, wait time int is not defined. So let's go look at line five. This means that it actually executed one through four. Everything was going fine until it got to line five. Whenever you see an assignment statement like we have on line five, what happens is we first evaluate the right hand side, the stuff after the equal sign, and then we'll assign it to the variable wait time int. So it's going to get a value, but it only gets that value after we manage to evaluate the right side. So the right side says to look up the current value of wait time int, but it is not defined. So by the time we get to line five, wait time int has not previously been set. So when you try to look it up on line five, we get this error. So that should give us a clue. Now we have to go back to what we were trying to do and figure out what's going on and say, oh, wait a minute. We were trying to take this input that we got that was going to be a string that was maybe four hours, but this isn't the name of the variable. Wait time str is the variable. So if I do that, I have a better chance of it working. Let's see if that does. I start at three. I say that I want to wait four hours, and now I get the seven that I was expecting to get. See you next time. You can reduce your headaches as a programmer. By writing your programs incrementally, get something working and keep it working. That's going to be our mantra. Or start small and keep it working. Here's a program where we're trying to draw a house, a rectangle with a triangle on the top. And we've done the first part for you. Get something working. But I'm now going to try to add to it in a way that says draw more and more of the house and when we make mistakes to catch them before there's too much code. So we've started with something that's working. Bob is going down and turning left. Let's complete that square. That should be pretty easy to do. Just make him turn left again and go forward. You might be tempted to do more lines of code than that, but I really recommend testing after you write every little bit of code. Let's turn him again and we'll test that. Then we're going to get to the slightly harder part. Now I want to make him turn this way so that he can finish the house like that. Let me do that. Instead of turning left, I'm going to want to have him turn to the right. Instead of 90 degrees, let's just try going 45 degrees. We'll go halfway and then we'll have him go forward by our 50 again. Oops! This is why it's a good idea to do things a little bit at a time because I'm going to get to realize already that I am going the wrong direction. I wanted him to turn to here so that he would go that way, but he didn't go far enough. He turned 45 degrees, but I really needed him to go all the way around to there, so another 90. So I need him to go 135 degrees. That looks a lot better. Now I'll just have him turn 90 degrees, go forward, and we will have our house. Let's see. Oh, we don't get a house that way. So it turns out that we need to make him not go quite as far. So instead of going 50, he's got to go a little bit less. Maybe he should go 40 each time. Almost, but not quite. You can try just doing trial and error until you get something that's pretty close, or sometimes it really helps to step back and do a calculation. In this case, the Pythagorean theorem, remember that, can really help us. We want to make something that is 50 here and is going to be a right triangle there. If we have some length a, we need a squared plus a squared to equal 50 squared. So you could do this in a calculator, or you could have the Python interpreter work it out for you. There is a square root function. It's a little tricky. You have to import the math module, and then we're going to say distance is the square root of 50 times 50 divided by 2. And then we will have Bob go forward by that distance each time. Let's try it and see if we get a nice roof on the house this time. Yay. So the main point that I wanted you to take away from this was that you're unlikely to get it all right the first time if you just write a really long program. It's much better to start with something that's working, add a line or two, test it, and make sure that you continue to have a program that is working. So build up and always keep your program working. Let's go through some common errors. These are typical mistakes that programmers make. So it would be helpful just to have seen some of the error messages and how to recognize the problems and how to fix them. So one that we've already seen is forgetting a parenthesis. Here it tells us there's a syntax error. It doesn't really know exactly what's wrong. It tells us there's a syntax error on line 6. Whenever you see a syntax error, you should always look on the line number that it says if everything looks right there, you should really look on the lines above it. In this case, we forgot to close the parenthesis on line 5. Even though it says line 6, it's line 6 where the Python interpreter realized there was a problem, but it's on line 5 where you really have the problem and where you should correct it. We should add that parenthesis and now it works. Our next set of errors involve variable names. The first thing to realize is that capitalization really matters. In this case, we got to line 3. And on line 3, it tries to do capital turtle dot small turtle. First thing to know is that capital turtle and small turtle are two completely different variable names. And small turtle is the name of this module. In that module, you can find the turtle class. So we really needed to have small turtle dot capital turtle. So another example of a variable naming problem occurs here. And sometimes you got to watch out when we have a big window to draw in that there may be an error message down below. In this case, the name right is not defined on line 6. You might look at this and say, this is all just fine. We're telling June to go right by 90 degrees. That's not the correct way to say it. We first have to mention the object and then the dot and then the method. So June should go right by 90, not right dot June. So let's fix that. And now we get it without the error message. Here's another variable naming problem. We create a turtle named June and then we tell June to move right by 90. Again, the error message is down off the screen that it's saying June is not defined on line 6. So we're telling June to go right. There's no binding for the variable June. There is a binding for the variable small j June. This is a situation where small j June, capital j June, not the same variable. And so we got that error. Fix that. No more error there. Another common type of error is when we invoke a function but don't pass in the right values, the right arguments that it's expecting. So here we've got a program where June is supposed to move forward and turn right and do that repeatedly. But we didn't tell it how many times to do it. So we invoke the range function but we didn't pass in an argument saying how many times to do it. We get an error and it tells us that on line 5 we tried to invoke the range function. It wanted to have at least one argument but we didn't give it any. There are no values in the parentheses and it wants at least one. So we should have said something like do this three times. Let's give it an argument of three and now it works just fine. So those are some kinds of common errors that you're likely to see as you start writing your own programs. We'll see you next time. Congratulations. You've picked up some valuable debugging skills. Remember your programs aren't going to work the first time and you shouldn't expect it but with the debugging skills you've started to pick up that won't be a problem for you. At this point you should be able to distinguish between syntax, runtime, and semantic errors. You should be well on your way to developing a habit of looking at the error messages and developing a skill of interpreting them. Learn to love your error messages. You should be internalizing a mantra. Get something working and keep it working. Celebrate the small wins and in order to celebrate the small wins you first have to have those small wins. And finally you should now be recognizing some common errors and how to fix them. So today's joke. A manager, a mechanical engineer, and a programmer they're driving back from a convention going over some mountain roads and suddenly the brakes fail. They fly, they're careening down the mountain. They're scraping against the guard rails and fortunately they finally stop in a ditch to their great relief. All three of them they get out and they start to assess the damage. The manager says let's collaborate, let's share our ideas, work together on this and we can solve this issue. The mechanical engineer says well let's disassemble the whole car and we'll analyze each part for failure and figure out what went wrong. The programmer says hey why don't we just push the car back up the hill and go back down and see if it does it again. Now don't be that kind of programmer. Be more like the mechanical engineer. Read the error messages. Figure out what's wrong. Your life as a programmer will be a lot more pleasant. We'll see you next time. Welcome back. Sometimes you'll want to change an object after you've created it. You create a list. You want to keep adding items on to the end of the list. Create a turtle. Change its pen color. There are two ways to change the value of an object after you've created it. One, you can make a modified copy of the object and the other is to modify the original. We'll call that mutation and it's useful but sometimes confusing. So today's lesson, how a mutation of existing objects works, recognizing the potential confusion that that can cause. At the end of today's lesson you should be able to identify whether an object is mutable or immutable. You should be able to identify whether a method mutates an object or creates a modified copy of it. And you should be able to recognize when two different variables are aliases for the same object and predict whether an operation on one of those variables is going to cause an impact on the contents of the other one. Welcome back. Recall that types are like categories of data and that different types are good for storing different kinds of things. So for example, we've seen integers which are good for storing round numbers and we've seen floats which are good for storing floating points or decimals. In this lesson we're going to learn three new kinds of types, strings, lists, and tuples. All three of these types are sequences. A sequence is an ordered collection meaning that it's a collection of items and it has an order meaning that it has a first item, a second item, a third item, and so on. And it also has a length. So let's start by talking about strings. The simplest way to create a string is with a string literal expression. So for example here, we're creating a string and storing its value in the variable s. I create a string by starting with either double quotes or as I'll talk about in a little bit, single quotes and then inside of those quotation marks then I put the content of the string. The content of the string is a sequence of characters or letters. So in the case of this string, the first character is capital H, the second character is lowercase e, and so on. And in this string, we have exactly 1, 2, 3, 4, 5, 6. Yes, the space counts. 7, 8, 9, 10, 11 characters. So I would say that the string s is 11 characters long. We can also create strings using single quotes. So if I replace these double quotes with single quotes, then s is still a valid string. If we wanted to create a multi-line string, we can use triple quotes. So now if I print out the value of s and I get hello world, if I print out the value of m, then I get this multi-line string. For multi-line string, we can make these triple quotes either double quotes or single quotes. Either is valid. So we can use either double quotes or single quotes as long as we're consistent about which kind of quotation we're using. So for example, I can't start out this string s with double quotes and end it with a single quote. If I try to do that, then I get a syntax error on line one. Instead, I need to either use double quotes for both the start and end, so I could do this. Or I need to use single quotes for both the start and end. And the same is true for multi-line strings. We can either use three double quotes or three single quotes. So I'm going to modify this string s a little bit. So first, here's another valid string, s equals capital M. And so if I print it out, then I get m. So what this is doing is it's creating a string that's one character long and that first character is capital M. Here's another slightly more confusing string. So here, s is a string that has zero characters in it. So s has a length of zero. And that's not to be confused with a string that has one character, but that character is a space. Here, the length of s is one. Whereas here, if I delete this space, the length of s is zero. One more note for strings. I can have a string that looks a lot like an integer. So for example, I can say s equals five, and when I print out the value of s, then I get five. To Python, this is entirely different than saying something like i equals the integer i. So even though when I print these two things out, they look almost exactly the same in their representation, there are things that I can do with s or things that I can do with i that I can't do with the other because s is a string and i is an integer. Just to show that these are different types, I'm going to print out the type of s and I'm going to print out the type of i. So when I run this code, I see that i and s have different types, but this actually has consequences for what I can do with i and s. So for example, let's suppose that I wanted to print out what ten plus i was. I can say print out i plus ten. And now when I print out s, then I get five, and when I print out i plus ten, then I get fifteen. What if I tried to add ten to s, so I printed out s plus ten? Well, if I try to do this, then Python is actually going to give me a runtime error, and it's going to say that it can't concatenate string and integer objects on line four. Just to break that down, what it's saying is that s is a string and I can't add an integer to a string because even though s is a string whose first character happens to be five, to Python, that's still a string, but even though to us s looks like a number, to Python, s is just a sequence of characters, and so we can't add a number to a sequence of characters. To Python, that doesn't make any sense to do, and so we get a runtime error. If we did want to add five to something like s, then we would need to cast it first. So I could say print int s, and this call to the function int is going to cast the string s to be an integer, so the value of this overall expression is the integer five, and so now when I run my code, then I can see that I can add ten to the integer value of s. Alternatively, I could cast it to be a floating point number, so I could say float s plus ten, and then I would get 15.0 because the value of this expression is the string s or five casted to a float, and so the value of this overall expression is 5.0, and when we add 5.0 plus ten, then the value of this overall expression is 15.0. So one thing to note when we cast strings like s into numbers by calling something like float s is that when we call float or int to cast the string, then the string needs to be a valid number. What that means is that if I have something other than numbers in the string, so for instance let's suppose that I say 500, when I try to cast s into a float, then I get a runtime error, and what this is saying is that the string 500 is not a number. In other words, Python doesn't know how to convert this string into a float, and the same goes for integers. Welcome back. So where strings like s are sequences of characters, lists are a new kind of Python type, which are sequences of any type of value, which can include other strings or lists. So lists are created by using square brackets. So I start creating a list by using a left square bracket, and then I put my content separated by commas. So here I'll make the first item actually be a string. I'll make the second item be an integer, and I'll make the third item be another string. So when I print out my list, then I get back the items that I actually put into the list. Now, just like strings, lists have an order and a length. So in the case of this list, my list, then I actually have three items. The first item is the string 1, and then separating out every item is a comma. The second item is the integer 2, separated by a comma again, and the third item is the string 3. So I would say that this list has length 3, the first item being 1, the second item being the integer 2, the third item being the string 3. So here are a few other examples of lists. So just like I can have an empty string, I can also have an empty list. So this is a list with length 0. I can also have a list with one item. So here, my list is a list with one item, and that one item is the integer 100. Now, just like strings, my list equals the list 100 is very different from creating an integer i equal to 100. So even though these look similar to us, to Python, these are entirely different. And further, if I make s the string 100, then all three of these are entirely different things, because s is a string, my list is a list, and i is an integer. So if I tried to do something like, say, my list plus 5, then I would get a runtime error saying that we can only concatenate lists with other lists. Because my list is a list, the only other thing that we can add to it is a list, as we'll talk about in a later lesson. Until next time. Now, we said that we were going to cover three kinds of sequences. So we've already done strings and lists, but the third kind of sequence that I'm going to cover rather quickly are tuples. The reason that I'm going to cover tuples relatively quickly are that tuples are just like lists, except the difference between a tuple and a list is that tuples are what are called immutable, meaning that after a tuple is created, it can't be changed. We're going to talk more about mutability later on, but for now I'm just going to cover how to create a tuple. So here I create a list with three items, and to create a three-item tuple, I would do something very similar. So I would say my tuple equals, and basically I would take almost the same syntax, except I would replace the square brackets with parentheses. So the first item is the string 1, the second item is the integer 2, the third item is the string 3, and I have to close parentheses to say that this is the end of the tuple. Now, if I print out the type of my tuple and run it, then I'll see that my list is a list and my tuple is a tuple. So for the most part, when creating tuples, then you can just use the same syntax that you use for lists, except replace these square brackets with parentheses. There are just a few exceptions where creating tuples is slightly different from creating lists. So let's suppose that I have a list with 100 as its only item, and I want to create a tuple with one item as well, so I want that item to be 100. When Python sees this expression, it actually thinks that this is an integer. So when I run my code, I can see that my tuple, or this expression, actually created an integer whose value is 100. And that's because Python was a little bit confused here because it thought that I was putting 100 in parentheses to do something like change the order of operations. So it thought that I meant to create an integer. In order to specify that I want to create the tuple 100, I just have to add an extra comma. And with that extra comma, if I rerun my code, then I'll see that my tuple is a tuple again. If I want to create a tuple with zero items, just like I can create a list with zero items, then I can just say open and close parentheses with nothing in it, and you'll see that my tuple is still a tuple. Until next time, welcome back. Now remember that sequences like strings, lists, or tuples are ordered collections, meaning that they have a first item, a second item, a third item, and so on. Now, often it can be useful to actually ask what is that first item or second item. Indexing allows us to access a specific element of a sequence. So let's suppose that I have the sequence s, which is a string, again, a sequence of characters. Now, when I print out s, then I get Python. Suppose that rather than getting the whole string, I only cared about the first character. In order to do that, then I would index on s. In order to index, then I would say s, and then I would say in square brackets, the actual index that I want. So if I wanted the first character of s, I would actually say index zero, because Python's what's called zero indexed. And what that means is that if I have a string like s, which is p, y, t, h, o, n, then Python, because this is a sequence, every character is almost in a little bin. And the first character has index zero. The second character has index one. The third character has index two, three, four, and so on. So you might be wondering why almost every programming language, including Python, is zero indexed, where this first index is zero. So the creator of Python explained this. He said to anyone who prefers one based indexing, you're the same people who screwed up the calendar starting at year one and calling the 1900s the 20th century and arguing that the year 2001 ought to be the start of the next millennium. Haven't you done enough damage? So he said this in jest, but there is a reason that most programming languages are zero indexed. It can actually be somewhat convenient once you get used to it. So indexing works on strings, lists, and tuples. So let's suppose that I have a list, my list, and I set my list to be a list with three items. One, two, three. So again, if I print out my list as a whole, then I get the complete list. If I only cared about the second item in my list, then I would say my list and then open square brackets and close square brackets. In between the square brackets, I would say the index that I want. So if I cared about the second item, then I would say index one because in zero indexed languages, that's the second item. So when I print out my list sub one, then that gives me two. If I print out my list sub two, then that gives me three. If I print out my list sub zero, then that gives me one. So another useful thing to do on sequences is to be able to ask what's the length of the sequence? In other words, how many characters are in this string? How many items are in this list? And in order to do that, we have a function called len. Len takes in a sequence like s or my list, and the value of this overall expression, this called len, is going to be how many characters or items are in that sequence. So for example, if I print out the length of s, by saying print len of s, then I get the number of characters in s, which is going to give me six because I have six characters in the string s. If I print out the length of my list, then I get three because I have three items in my list. One thing to note here is that even though the first and third item happen to be strings, then my list itself only has three items, the first item being a string, the second item being an integer, and the third item being a string. So its length is three. So sometimes it can also be useful to be able to get the last item of a sequence as opposed to the first item. So again, if we wanted to print the first item, I would say s sub zero. If I want to get the last item, I would say print s sub, and then I can write the length of s, but then I actually have to subtract one from that because s is zero index. So if I run this, then I see that printing out s sub zero gives me the first character of s, which is a capital P, and printing out s sub length of s minus one gives me the last character of s, which is an n. So again, just to illustrate why that is, then I'm going to write out the indices of s. So the first character is item zero, second character is item one, third character is item two, three, four, and five. And so what that means is that there's a total of one, two, three, four, five, six items, and so the length of s, this part of the expression, has value six. But if I actually asked for s sub six, then it would be looking for a character that s doesn't have. Again, because s is zero indexed, I need to subtract one from six to get five. Now, it is really common to ask for the last item or the second to last item. So Python also includes, in addition to these positive indices, one, two, three, four, five, and zero of course, it also includes negative indices that count backwards from the end of the sequence. So I can ask for s sub negative one, or negative two, negative three, negative four, negative five, or negative six. So if I replace this call to print out the last character of s by printing out s sub length of s minus one, just to say print out s sub negative one, then I get the exact same result. If I print out s sub negative three, then that's going to be the third to last character, in this case h, which I can see when I run my code, if I print out s sub negative two, then I get o and so on. And of course this negative indexing also works for lists just as well as it works for strings. So if I print out my list sub negative one, then I'm going to get the string three, because that's the last item of this list, my list. Until next time. So let's go over some of the things that we've learned so far. So remember that slicing and indexing works with tuples, just like it works with strings, lists, or other kinds of sequences. So here we have a tuple, Julia, with a few items, two strings, some integers. And on line two, we print out Julia sub two. If we want to determine what that prints out, we first need to determine what kind of operation this is. So we see that we're saying Julia sub, and so that should tell us that we're either indexing or slicing. I don't see a colon here, so that should tell me that this is indexing. And so when I print out Julia sub two, that's going to print out the third item. Again, the third item because we're zero indexed. So the third item is zero, this is one, this is two. And so this should be 1967. Then we print out Julia sub two through six. And so in order to determine what that prints out, I'm going to write the indices on the edges of the items. Six. And so two through six is going to be two through six. And so that should be everything from 1967 through actress. And that's what this line should print out. When we print out the length of Julia, then that's going to ask how many items are there. So I see there's zero, one, two, three, four, five, six. Don't get fooled by the comma here. It's actually part of the string, not part of the tuple definition. And so that's going to say that there are one, two, three, four, five, six, seven items. If the last index is six, then because there's a zero here, then that means that the length is seven. And then here we have a complicated concatenation operation. So first we take Julia sub from the beginning through item three. And so that's going to be Julia Roberts 1967. So let me write that out. Julia Roberts 1967. And then we concatenate to that the string eat, pray, love in 2010. So eat, pray, love and 2010. And then we add Julia from index five on. So that's going to be everything from actress on. So that's actress and Atlanta, Georgia. I just add commas between these. And this gives us a tupleback. So this is what I expect to print when we run this code. Let's test our hypotheses. Okay, so I see that line two does indeed print out 1967. Line three does in fact print out everything from 1967 through actress. Line five does in fact print out seven. And line eight does in fact print out this list that we specified. So let's go over some questions related to slicing and indexing. So first, if we ask what's printed out by the following statement. So the string S is Python rocks. And we print out S from index three to eight. And so in order to determine what actually gets printed out, then I'm going to first find out where index three is. So this is zero, one, two, three. And so what that means is that because we include index three, I'm going to draw a line right here. And then we print out that through eight, four, five, six, seven, eight. But we don't include index eight because we move kind of all of these dots to the left. And so what that means is that we're going to get everything from here to here. So we should get H O N space R or item C. Okay, next question. So here we have a list that has a mix of some integers, some strings, and some actual other lists as items. And so what we're asking is what's printed by the following statement. So we create this list and we print out a list sub four colon. So in order to figure that out, I'm going to first find index four. So we have zero, one, two, three, four. So index four contains this empty list. And because we don't have anything after the colon, then we're saying we want everything from index four on. And so we can draw kind of a line here. And we know that it's going to contain everything from this empty list to 3.14 to false. And so I expect the answer to be a. And so we can see that answer a here was the correct answer. Okay, so now we have a question asking us to create a new list using the ninth through 12 items. So four items and all of new list and assign it to the variable sub list. So the first thing I'm going to do in order to answer this question is I'm going to say sub list equals. And then I know I'm going to be slicing on new list. So I'm going to say sub list equals new list sub. So if we want the ninth item, then we actually have to use index eight. So I'm going to say index eight and because I want to subset then I want to slice. So I use the colon and I went through the 12th item. So if we include index eight, nine, 10, 11, then that's going to give us four items. So what I want to say is I went through but not including index 12 because that's actually the 13th item because again, Python is zero index. So if I say sub list equals new list from indices eight through 12 and run it, then I get the correct answer. That's all for now until next time. So far we've created sequences like lists, strings and tuples just by declaring literals just like on line one, how we declare this list fruit. Another way to create them is through concatenation and repetition. Concatenate takes two sequences and adds them together to form one long sequence. So here on line three, we say print out the value of this sequence with two items, one and two, concatenated with this other sequence with two other items, three and four. Now the result of this overall expression is going to be a new list that has all of those items kind of squished together. So it's going to be a new list with items one, two, three, four. So let's run and we can see that our new list just has items one, two, three and four. So that's concatenation. We can also take an existing list like fruit and concatenate it with a list that we create on the fly, like right here. So here we have a list of strings in fruit. So we have apple, orange, banana and cherry. And here we take that list and concatenate it with another list with numbers six, seven, eight and nine. And when we do that, then we're going to get apple, orange, banana, cherry, six, seven, eight and nine. Let's run to be sure. And you can see that these two lists were concatenated. In addition to concatenation, we can also do repetition or repeating a list any number of times. And whereas concatenation uses the addition or plus operator, repetition uses the star or multiplication operator. So if we have this list that has one item, that item being the integer zero, and we say repeat this item four times by saying the list and then multiply it by four, then we get a new list that repeats the contents of this list four times. So we should get a list that has zero four times. And you see that's exactly what we get. If this list had more than one item in it, so let's suppose this list had zero and one as items, then both of those items get repeated four times as well. So you can see our new list has zero one, zero one, zero one. And just like before, we can actually mix up different types. So we can say something like print out fruit plus the list one and multiply that four times. And so that's going to take apple, orange, banana, cherry and then add one to that list. So apple, orange, banana, cherry one. And it's going to repeat that four times. So you see apple, orange, banana, cherry one, apple, orange, banana, cherry one, and so on. So one thing to note about concatenation and repetition is that they follow the exact same order of operations as addition, multiplication, and subtraction. And so here we put parentheses to say that we want to do the concatenation before we do the repetition. If we had actually left out the parentheses, then we would get the list fruit plus the list one repeated four times, so we would get an entirely different result. So let's go through this in code lens. So suppose that we create that same list that we created last time. So we have fruit as a list, apple, orange, banana, cherry. If I step forward and you'll see that fruit here gets assigned to a list with item zero, item one, two, three. And then if I create a new list of numbers, so those numbers being six and seven, then we create a new list in the global frame. So we say num list is assigned to a list with six and seven in it. Now if I create another new list, and this time I'll just call it new list, and say that it's the concatenation of fruit and num list, what you'll see is that we create a third list and that third list contains some elements from fruit and some elements from num list. So we're not affecting either fruit or num list in any way. We're just creating a new list that actually has both of their elements concatenated together. If I create a fourth list of zeros to say zero repeated four times, then you can see that that's a fourth item in our global frame. So let's answer some questions about concatenation and repetition. So this question asks, what's printed by the following statements? So we create a list, a list, with three items, one, three, and five, and b list with another three items, two, four, and six. And we print out the value of a list plus b list. What do we get? So it can be tempting to say one, two, three, four, five, six, because that's what's natural to us. But because a list is one, two, three, all of those items come before the items of b list, which are two, four, and six. So the result that we get from a list plus b list is one, three, five, and then two, four, six. So the order is the elements of a list in order and then the elements of b list in order. And so that means that the answer is going to be c. Let's do another one. So in this question, we create a list, a list, and set it to a list with three items, one, three, and five, and then we print out the value of that repeated three times. And so what we should get is this repeated three times, so one, three, five, one, three, five, a list that has nine items, and that's going to be answer c. That's all for concatenation and repetition. See you next time. Most sequences have a few useful methods that you can do on any sequence. The way to call that method is to say the sequence name and then the method name. So I'm going to go over two methods on sequences. Count in index. So suppose that we have a string and we want to find out how many times a given character or a given sequence of characters appears in the string a. The way that we would do that is using the count method and the way to call count is we say the name of the sequence, whether it is a string, integer, or tuple, that we want to count on. So here we want to do a count on a. So I say a and then the dot or period and then the method name that we want to call dot count open parentheses and in the case of count, we pass in a string which is the sequence of characters that we actually want to count. So on line two, we're counting the number of characters e in a and then we close parentheses in order to finish that method call. One thing to note here is that count is case sensitive, meaning that we don't count capital E's if there were any capital E's in a. We would only count lower case ease. So here when we say print out a dot count e, then we look for the number of E's that are in the string a. So in this case, we should get one, two, three, four, five. In addition to counting individual characters, we can also count substrings. So here we're counting the number of times the substring HA appears. So we should get one, two. So let's run our code just to double check. So we can see that we get five E's and two times that HA appears in this string a. Just like strings, count also works on lists. So here we have a list z that has one, two, three, four, five, six, seven, eight, nine, ten items. So on line two, if I comment out the rest of these lines, on line two, we're finding out how many times does the string four appear as an item in z. One thing to note here is that the string four is an entirely different thing than the integer four, which we have here, here, and here. And so when we say print out z.count the string four, then we're going to actually get zero because no item in z is the string four. If we instead counted for the integer four, then we would get what we might expect. So we would get one, two, three, because there are three integers four in our list z. So if I hit save and run again, then I'll see that I get three when I print out z.count the integer four. Here's something that's a bit trickier. So let's suppose that I say z.count the string a. Now we can see that in our list z, the letter a appears a few times. So in the first item of z, a appears in atoms, and then it also appears in atoms in the last item. So we might almost expect the result to be two. But if we actually run our code, then we'll see the result is zero. Now, why is that? Well, when we call z.count the character a, what we're looking for are items in z where the item itself is the string a. So the fact that a just happens to be a character in this larger string doesn't matter to Python. What Python would care about is, is the value actually the string a? So if I had one item here that was the string a, then I would get count one. But because this instead is the string atoms, then I get zero when I look for the number of a's. On line five, we do z.count electron. And when I look, I see that there is one, two electrons in z. And so I should expect line five to print out two. Now let's go on to another useful method named index. Index finds where an item is. In the case of index, it searches for the first time that a given string or item appears. So let's suppose that on line one, we're creating this string, pull out your music and dancing can begin. And on line two, we create this list that has one, two, three, four, five, six, seven, eight, nine, ten items. Now, when we print out the value of music.index of m, then we're printing out the first or leftmost index where lowercase m appears. So if I comment out the rest of these lines and only print out the value of music.index of m, then we should get the index of the first m. And just to find out where that is, we should get it at zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen. So this m, which is the first term leftmost m that appears, is at index fourteen. And what that means is that the value of this overall expression, music.index of m, is going to be fourteen. Let's run our code and make sure that that's the case. So we see that we get fourteen. On line five, we print out the value of music.index of your. And so what this is going to do is it's going to search for the first time that this substring your appears. And it's going to print out the index where it starts. So we should expect that to be zero, one, two, three, four, five, six, seven, eight, nine. So when we run this, then we get nine as the result because your starts at index nine. Now index works with lists as well as it does with strings. So if we print out bio.index of metatarsal, then we get the first index where metatarsal appears. So here on bio, that should be index zero. Even though this appears multiple times at index zero and one, index always gives us the first or leftmost index where it appears. So line seven should print out zero. On line eight, we print out bio.index of an empty list. This is going to search for the first empty list in this list bio. So the index should be zero, one, two, and we find it at three. So when we run this, we should expect three. Then finally on line nine, we print out bio.index of 43. So that's going to be zero, one, two, three, four, five, six. Now one thing to note for index is that if something's actually not in the sequence, then we get a runtime error. So if we create this list seasons and set its values to be winter, spring, summer, and fall, and then we search for autumn, note that autumn is not in here because we instead wrote fall. So if we print out seasons.index of autumn, then we're going to get a runtime error. And that runtime error is going to point out that the item that we searched for in this case autumn was not in our list seasons. Okay, so let's answer some questions about count in index. So this question asks what will be stored in the variable ty below. So we say ty is qu, which is the string that index of we. So this is searching for the first time that we find the string we. So that's going to give us zero, one, two, three, four, five. Again, when we search for a substring, we search for where it starts. And so that's going to give us five. Next, what will be stored in the variable ty now? So we say ty is the string qu that count of we. So here we're searching for how many times does this substring we appear in this string qu. And so we see we right here at the start of welcome here at the start of week. And we might think that we actually see it here. But if you look closely, this is actually capital W and not a lowercase w. Now remember that Python is case sensitive. So capital W is a completely different thing than a lowercase w. And so Python isn't actually going to count this. And so Python isn't actually going to count this we because it contains a capital W. And so the end result here is that we get two. So here we're asked what we stored in the variable ht below. So we have room set to a list with one, two, three, four, five, six items. And we ask for rooms dot index of garden. So we're going to search for is garden in this list rooms. And so we see it's not here nor here nor here nor here nor here nor here. And garden isn't anywhere in this list. And remember that when we try to do index on something that's actually not in the list, then we get an error. So the answer here should be an error. That's all for now until next time. Split and join our two other useful methods on strings and lists. So split takes a string and turns it into a list of substrings of that string. So let's suppose that we have a string leaders and best. So here we have a string literal. And let's suppose that we call dot split on that string. What that split does, if we call it with nothing as an argument, it first looks for all the spaces in the string. So here it finds a space and here it finds a space. And it kind of cuts the string along those spaces. So what it does is it turns this what was one string into three different strings and it divides them along the spaces. So the end result of this expression is going to be a list where the first item is leaders, the second item is and, and the third item is best. One thing to note here is that split actually does get rid of the spaces in between all of these. So this is leaders with no space afterwards and no space before or after and, or before and after best. So split essentially takes a string and splits it up into different words if it's called with no arguments. So let's try this out in code. So suppose that we have this string song equals the rain in Spain and we say words equals song dot split. Then when we call song dot split, the value of this expression is going to split song along every space. And so we're going to get a new list that has four items, the, and then rain in Spain dot dot dot. So when we print out words, then we should get a four item list. Now we can also call that split with an argument to specify what we want to split along. So let's suppose that we actually called dot split with the argument e. Whatever argument we pass in here, in this case e, specifies what we actually want to split along. So here if we say we want to split along every e, if we split the string leaders and best, then that's like crossing through every e that's in the string. And then the result is that we get a list where the first item is L. The second item is ad. The third item is RS and so on. So let's try that out in code. So here we have the same song, so the rain in Spain. And let's suppose that we say song dot split AI. So when we do that, then we're going to search for every AI. So we find this AI and then this AI. And what we should get back is the list with three items. The space R and space I N space and so on. And you see that that's exactly what we get. Now the opposite of split, which kind of splits a string along lines is join. Join takes a list of strings and joins it into one long string. So split is like chopping with a knife and join is like joining it back together with glue. So if we say I want to use this as the glue to join the items in this list, what we get as the value of this overall expression is every item in this list, leaders and best kind of glued back together with this string. So we get leaders slash and slash best. So let's try that out in code. So here we have a list of words, red, blue and green, and we specify a variable glue. And this variable glue is what's going to come in between these items when we call dot join. So if we say glue dot join words and assign that to S, then when we print out S, then we should expect to see red, semi colon, blue, semi colon, green. So let's test that out. I'm just going to comment out the rest of this code. So you can see that what we got was the semi colon gluing back together the items in words. But one thing to note is that calling dot join doesn't affect the value of the list itself. So if we print out words after having called glue dot join words, then we still get out a list that has three items, red, blue and green. Of course, we can also use a multi character string to actually join the words together. So if I use three stars to join words, then I get red, star, star, star, blue, star, star, star, green. And I can even use an empty string to glue back the words together. So if I use an empty string dot join words, then I get red, blue, green, all concatenated together. So let's go through some problems. So this question asks us to create a variable output that's assigned to a list whose elements are the words in string one. So in other words, we want to split up string one into individual words. So I want to assign output equal to str1 dot split. And if I call that split with no arguments, then it splits it along the spaces. This question asks us to create a variable called words and assign it to a list whose elements are the words in the string sent. And it tells us not to worry about punctuation. And so I'm going to do something very similar here. I'm going to say words equals sent dot split. Again, no arguments in dot split because we want to split it along the spaces. And now words is set to a list of words in sentence. So split and join our functions that will keep coming back to throughout this course and they'll end up being enormously useful. That's all for now. Until next time, welcome back. So we've already covered sequences. And in this lesson, we're going to cover iteration. Iteration runs a piece of code for every item in a sequence, be it a string, list, or tuple. In order to do iteration, we're going to use a for loop, which is the first of many control structures that we're going to see in this course. So let's look at a for loop in action. In order to create a for loop that's going to iterate over a sequence, we start out by saying the keyword for, which specifies that we want to create a for loop. After the four, then we create something called a loop variable. We could call our loop variable any valid variable name. But in the case of this for loop, we're calling our loop variable name. After we declare our loop variable, then we say in. And after that, we specify what sequence we're actually iterating over. So in this case, we're iterating over this list, which has one, two, three, four, five, six, seven items. And what this for loop is going to do is it's first going to assign name to be the first item in the sequence. So Joe, then it's going to assign name to be the second item. And then it's going to assign it to be the third item and so on. And after it assigns it to be any particular item in this sequence, then we're going to run whatever is inside of the for loop. In this case, the only code that we have inside of this for loop is this print statement, which prints out high and then whatever name our loop variables value is. Please come to my party on Saturday. So when we run this code, what we get is high Joe, please come to my party on Saturday and then hi, Amy, please come to my party on Saturday. Hi, Brad, please come to my party on Saturday and so on. So in general, what's happening here is that Python is running this code, this print statement for every single item in this sequence. And for every single item in the sequence, it's a first assigning name to be that item. And then we're printing out high and then whatever that name is, please come to my party on Saturday. So for all seven items in this list, then we get seven print statements. So let's look at the same code inside of code lens. So again, we're iterating over this list of names and our loop variable is called name. So the first time that we run this code, you'll see that name gets assigned to the first item in our list. In this case, name gets assigned to Joe. And now when we run this print statement to print out high name, please come to my party on Saturday. Then we print out high Joe, please come to my party on Saturday. And then next name gets reassigned to the second item in our list. So in our case, it gets assigned to Amy. And now when we print out high name, please come to my party on Saturday, we get high Amy, please come to my party on Saturday. Then name gets reassigned to the third item or Brad. So now when we print out high name, please come to my party on Saturday, we get high Brad, please come to my party on Saturday. And this pattern repeats for every single item in the sequence that we're iterating over until we're done iterating over all of the items in which case our program is terminated. So when we create a for loop, let's say abstractly it looks like something on the left hand side here. So we have some code that might come before we have some code that might come after and then we have our actual for loop. We declare our for loop again by saying for and then our loop variable. And then we say in and then we say whatever sequence we're iterating over. And then inside of the for loop, we have what's called a code block. So here the code block is represented in green. The way that we say that this loop code block is inside of the for loop as opposed to outside of the for loop is through either tabs or spaces. So we have to indent the loop code block to indicate that this code belongs to this loop. So when we declare a for loop like this, then this is equivalent to first assigning the loop variable in our case X to the first item in the sequence and then running the loop code block and then assigning our loop variable X to the second item in our sequence and then running the loop code block and so on and so forth. So assigning X to the third item, the fourth item and so on until we finally assign our loop variable X to the last item and running the loop code block. So one thing to note here is that the loop code block may or may not reference our loop variable but if it does reference our loop variable, then that reference is going to change every single time. For example, in our previous code, we referenced our loop variable name inside of the code block in our loop. So that means that name is going to change for every single item in our list. So in addition to iterating over lists, for loops allow you to iterate over any kind of sequence including strings, lists and tuples. So let's go over an example of iterating over a string. So here we're iterating over the string go, spot, go and we're calling our loop variable HR. So what that means is that the first time this loop body runs, then HR is going to be assigned to the character capital G. The second time that it runs, it's going to be assigned to the character lowercase o. The third time that it runs, it's going to be assigned to a space character and then capital S and so on. And so what that means is that when we run our code then when we're first going to print capital G and then lowercase o and space and so on for every character in this string and because print prints out characters on a separate line then we get go, spot, go kind of printed out vertically. So let's go over a multiple choice question. First we assign the string S to be Python rocks and then we say for every character in S so again here our loop variable is CH and the thing that we're iterating over is S and our loop body consists of one print statement that prints out the string hello. And the question asks how many times is the word hello printed by the following statements? So one thing that we know is that CH is going to be assigned to the first character in S then the second character then the third character and so on and what that means is that this loop body is going to run once for every character in the string S. So in other words this loop body is going to run however many times S is long. So if S were one character then it would run one time. If S were two characters it would run two times. So in order to find out how many times the word hello is printed out in this code I'm going to find out what's the length of S and I find out that it's 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 characters long which means that I should expect this code to run 12 times. So next we're asked how many times is the word hello printed out by the following statement? So here we're assigning S to the same value and we have the same loop variable CH. Now rather than iterating over the entirety of S we're iterating over a slice of S specifically we're iterating over S from indices 3 to 8. So what that means is that we're iterating over S from 0, 1, 2, 3 from here to 4, 5, 6, 7, 8 to here. And so we should expect this to run 1, 2, 3, 4, 5 times. So we can see that because a 5 character sequence is returned by the slice then we run our 4 loop 5 times. So in this code example we create a list that has 4 items and we have a loop variable named a fruit and we iterate over our 4 item list. Now when we print out the value of our loop variable a fruit then we should expect to get every item of our list printed out on a separate line. 4 loops also work even if we don't care about the sequence that we're iterating over. So here we have an example that uses turtle and let's suppose that we want to draw a square with our turtle. One way to draw a square is by going forward and then left 4 different times. So we first set up our turtle and we call our turtle Alex and then we create a 4 loop and we have our loop variable I and we have the sequence that we're iterating over which is a 4 items list. But here inside of our 4 loop we're not referencing our loop variable at all. Instead we're taking advantage of the fact that we're repeating this code 4 times in order to form a square by going left and forward 4 times in a row. It doesn't matter what we're actually repeating over if we're not referencing the loop variable. So for example here we're looping over a list of strings that represent different colors but we're still not referencing our loop variable a color in any of the code inside of our 4 loop. So when we run our code then we still get the same result which is a square with 4 sides and every side is still black. If we did want to reference our loop variable then we might want to say something like this. So here we're referencing our loop variable a color by assigning that color to our turtle Alex. So first a color is assigned to yellow then red then purple then blue. And so the result here is that every side of our square ends up being a different color because we first go with yellow then red then purple then blue. So let's answer just a few more questions on 4 loops. So here we have a list that has 1, 2, 3, 4, 5, 6, 7, 8, 9 items and we're asked how many times will the 4 loop iterate through the following statements. So because CH gets assigned to all 9 items once then we should expect this to execute 9 times. So this question asks how does Python know what statements are contained in a loop body? So Python always checks the indentation of statements to check to see if it's in the loop body. So we can have more than one line in the loop body even though many of the examples that we went over only had one line and the way that Python knows if something is in the loop body is if it's indented the same after we declare the 4 loop. That's all for now until next time. Welcome back. The accumulator pattern is a common programming pattern where you iterate through the contents of a list and you accumulate a single value such as the sum of all of the items in that list. It always involves an accumulator variable which you'll have to initialize. Usually you'll set it to be 0 or some initial value that you're going to start with and then you'll iterate. You'll have an iterator variable that iterates through some sequence and each time on each iteration you'll update the accumulator variable. When you've made it through the whole list, updating the accumulator for each item in that list at the end, you're going to look at the accumulator variable and it's going to have your total value. So the code on lines 1 through 5 is doing that. We have a sequence on line 1. AcuM is the name I've given to my accumulator variable, naturally enough. And now I'm iterating through the sequence nums. W is going to be my iterator variable. AcuM was the name of my accumulator variable. And then on line 5 I'm going to update the accumulator. For each item I'm going to add that value to whatever is in the accumulator so far. At the end I print it out and I should have the sum of all the values in the list. So let's just run that and we'll demonstrate that it really does produce the sum of the numbers 1 through 10. But now let me show it to you in code lens. So in code lens we can see what's happening at each step. I have a sequence. I set my accumulator variable to have an initial value of 0. Then I start iterating through the sequence. W is bound to 1, the first element of the list. And now I do an update. AcuM equals AcuM plus W. So it used to have the value 0. And now it's going to have 0 plus 1. And we're on to the next item in the list. Now W is going to be 2. And the accumulator is going to get updated this time to be 1 plus 2. So it's sort of keeping a running sum for us. Now it's 3. This time we'll add in 3. So it'll get to be 6. We'll add in 4. And so it'll get to be 10. And we keep going and going and going. So we get through all the items in the list. Eventually the accumulator has the running sum of all of the items in the list. And we can print it out. So I'm going to hide code lens now. And give you a little challenge to predict what would we get if instead of having on line 5 the print where it is, what if I indented it so that it's part of the for loop? So before I run this, why don't you try and make a prediction of what you think it'll do? Here we go. So the difference is that now the print is happening inside the for loop. That means on each iteration we're going to print the value of the accumulator, the running sum. So after the first iteration it had the value 1. Just 0 plus 1. Then we added in 2. And we had 3. And we added in 3 and we got 6 and so on. So that's the basics of the accumulator pattern. You'll be seeing that a lot in this course. You start with an accumulator value that gets initialized to some value like 0. You iterate through a sequence. And your iterator variable is used on each iteration to update the accumulator. You update the accumulator each time and at the end, after you've gone through all of the items in the sequence, the accumulator value, after you've gone through all the items in the sequence, the accumulator variable will have the accumulated value from the whole list. In this case, the sum of all of the items in the list. We'll see you next time. Welcome back. I previously showed you the accumulator pattern iterating over a sequence like the numbers from 1 to 10. Python actually provides a function for us called the range function. It takes as an input a number. And what it produces as an output, range of 5 will produce a sequence. 0, 1, 2, 3, 4. So the sequence it produces has the same number of items as the value that we passed in. The first element will be 0 and then we'll get all the numbers up to but not including 5. If I say range of 10, I'll get the integers from 0 up to 9. Now there's one subtlety to this. The range function in a real Python implementation doesn't actually produce a list. It produces what's called an iterable, something that will generate the numbers 0 through 4 when we iterate through them in a for loop. So if I say for I in range of 5, it will print out the numbers 0, 1, 2, 3, and 4. If I actually want a real list, I would have to cast it. I would take range of 5 and pass it to the list function, which would turn it into a real list. Now in our runestone environment, we cheat a little bit and we actually have range of 5 producing a list object. So in the runestone environment, you don't strictly speaking have to do this casting of the output to make it a list. But it's a good idea to get into the habit of doing things like lines 12 and 13 because in a full Python environment, if you really wanted to have a list, you would have to take the output of range of 5 and pass it to the list to cast it into being a real list. One other thing I want to show you here and then we'll see the output to check everything we've done. Range takes an optional second argument. So it actually takes several additional arguments and we'll have a chance to see what impact this extra argument has. So let's run it and just to match things up here, we're just printing that it's range of 5 and then lines 4 and 5 are producing these numbers 0 to 4. That's the same as saying range starting at 0 and going up to 5. But if I said range of 1, 5, I would get something a little different. Now I would get starting from 1 up to but not including 5. And there's actually an optional third argument that can say, you know, you want it to increment by a certain amount but we won't go into that detail. Now as I was mentioning, in the Runestone environment, range of 5 comes out as an actual list. In a full Python interpreter, it wouldn't be an actual list object unless you first passed it into the list function to cast it. And the advantage of having the range function is that we don't have to write code like on line 1 to ask for all the numbers between 1 and 10. In fact, I'm going to take you back to our code for the accumulator pattern and show you how it could have been a little simpler. So instead of saying nums equals that list, I could have said nums equals range of 1 comma 11. And I would have gotten the same result of 55. The range function will show up as a handy little utility for us throughout the rest of the specialization and throughout the rest of your time as a Python programmer. Now keep in mind, the range function can just take one argument and then it would give you all the numbers from 0 up to but not including 11. Or it can take two arguments where you specify the first item and the last. So 3 to 11 is going to give us less than 55 because we're not including the one and the two. So we get 52 instead. The range function takes a number and it gives you back a sequence like this list of numbers from 1 to 10. We'll see you next time. Welcome back for a little way of the programmer advice on naming the variables in your for loops. So suppose that x was a variable who's bound to a list somewhere. You might be tempted to write for y and x print y. The problem is if you haven't looked at this code in a while and x was defined somewhere above this code like what is x? You haven't given it a name that gives any suggestion that it's even a list much less what it's a list of. And I have for y and x also I'm not with my code here I'm not giving any hint as to what kinds of items are supposed to be in x. So this is a very simple for loop you might be able to get away with this and still be able to understand what's going on. But it's really going to be helpful if you give more meaningful names. And one bit of advice I have is to whenever you're having a variable name that's going to refer to a list give it a plural noun as its name. And whenever you're going to have an iterator variable give it a singular noun. So here's an example in my next code window. I have a variable called genres because it has a plural name with an s on the end I kind of expect it to be probably a sequence. Then I took my iterator variable and I chose to make it be a singular noun. And moreover it is a singular noun that sort of goes with the plural noun. So each item in a list called genres is going to be one genre. And so then in my code inside the for loop I'm going to refer to this singular variable genre and it's going to remind me that it's one item from the genres list. This is a lot better than doing things like and I sometimes do see students confuse themselves. They'll say for apples in fruit and fruit actually you look at their code and it's a list of the names of fruits and apples is the first string that's in that list and so somehow they decided that they would name the variable name apples but this will be very confusing to read because you get four lines into the code and you see apples somewhere and you think oh, apples must be a list of different kinds of apples or something like that. So don't do this for fruit in fruits that's fine. So for your sequence do a plural noun. For your iterator variable do a singular noun. Follow that little convention and you'll save yourself a lot of confusions as you're coding. See you next time. Welcome back. I'm here with some way of the program or tips on how to make it so that you can understand what's going on in your programs. Here I've got some code for doing an accumulator pattern to add up all the numbers from one to ten but suppose you didn't recognize it as that. You could use CodeLens if you have a small enough program like this one but it's good to start learning how to add some print statements that will print out intermediate results. So suppose I run this and I'm surprised that I got 45 rather than 55. What should I do? And the answer is I should start adding some print statements. So here I've added inside the for loop something that prints the number the current value of the iterator variable. So what's the value of num on this iteration? So now I find out that it's zero, then one, then two, then three, then four. If I was thinking that range of ten was going to give me the numbers from one to ten adding this print statement on line five will give me a clue that actually it's giving me the numbers from zero to nine. Now suppose I'm still a little puzzled maybe I don't really understand what line six is doing with this tote plus equals num. Here I've added an extra print statement on line eight to print tote the value of the accumulator variable at the end of each iteration. So now we find that we get zero and zero. So this is num is zero and tote is zero and num and tote are both one. Then num is two and tote is three because we've added the previous total one plus the new number two and we get three and so on. So now I can start to understand that line seven is taking the old value of total adding in the current value of num and writing that back into tote. So we get the old value of total was one the new value of num is two and we write it back into tote so that it's three and on the next iteration we'll have three in tote. Now I had to do a lot of writing stuff here to remind us of which variables were getting printed out so when you're printing intermediate results sometimes it's helpful to print out you know a little text saying what it is that you're printing and that's what I've done in the next window. So I've got a print statement on line four saying hey we're before the for loop then on line six we say we're doing a new iteration and the value of num is something you can see that with all of this diagnostics it's much easier to read the output. So instead of me having to write in num and tote we've got it all getting printed out already the value of num was zero and the value of tote was zero then they were both one then num was two and tote was three because we added the two and the one we have a value of tote is three and the value of num is three so we add those two together to get six six and four makes ten and so on. So it's helpful to add print statements if you just add one you don't need to have all this diagnostic stuff like saying what it is you're printing out but once you start to have several print statements it's helpful if you include things like value of num is this so that when you go to look at it over here you know what you're seeing in the printout. So that's the little tip on printing intermediate results. I'll see you next time. Welcome back for another way of the programmer segment. Students sometimes get confused with iteration about what's the iterator variable and what's the iterable. So I want to just go through and give you a little practice. So I have a series of questions that ask what's the type of your iterable or what's the type of your iterator. Here I have a variable n and I am iterating through it. The iterable is the thing that we are going to iterate through. It goes after the word in and in this case it is a list. Ray we got that one right. Some of them may get a little trickier. Here what's the type of our iterable? Well again the iterable is after the word in it's the variable t and I have deliberately for these exercises given you variable names that don't give things away. This is not good coding styles, better to have meaningful names this is forcing you to reason about it. t is going to be a string. Now what will the type of my iterable be here? Again it's the thing after the in. It's the variable y whose value is 18. You might be tempted to say that it's an integer but of course an integer is not a sequence at all. You can't iterate through it. So this one's going to be an error that we can't iterate over the object. What's the type of my iterable here? Well the open parentheses rather than the brackets are an indicator that this is a tuple rather than a list. I'm going to go on to some that ask us about what the iterator variable is. So now what is the type of your iterator variable? Here it's not asking about the iterable not the sequence but the iterator variable. So z, what kind of thing will z be bound to when we get down to print z on the third line? Well z will be bound to one of the things that is in the iterable. One of the things that's in t. So in this case z will be a string. What will be the type of my iterator variable on the first iteration? So z will be bound to 9 on the first iteration so z will be an integer. So I think you get the idea here. I'm really just trying to reinforce the vocabulary. The iterable is the sequence. It's the thing that you iterate through. It's the thing that goes after the word in. The iterator variable is the variable name between the word for and the word in and it will be bound each time to one item from the iterable, one item from the sequence. So don't get confused. The iterable is the thing that you iterate through. It goes after the in. The iterator variable is the thing that's bound to each item in the sequence. We'll see you next time. Welcome back. It's time for us to learn about a new Python type. So far we've seen integers which are good for storing round numbers, floats which are good for storing decimal numbers, strings which are good for storing sequences of characters like words, and lists and tuples which are good for storing sequences of other items. In this lesson, we're going to learn about a new Python type called Booleans. Booleans are good for storing truth values and that is whether something is true or false. In fact, there are only two possible values for Booleans, true and false, and this is in contrast with pretty much every other type. So an integer might be negative 10, 5, or one of any infinite number of values, but Booleans are always either true or false. As a result, we almost never write a Boolean literal. Instead, we typically write expressions that compute values of Booleans. So again, Booleans can only have one of two values, true or false. We can write a Boolean literal by saying capital F false for false or capital T true for true. So if I print out the value of false, and you can see that I get false, if I print out the value capital T true, then I get true. Now, just to be sure that these are Booleans and not strings or any other type, then I can say print out the type of the expression true, and then print out the type of the expression false. So I should expect both of these to print out something like Boolean. So when I run my code, and I can see that type of true this is short for Boolean, and type of false is also bool short for Boolean. One thing to note about Boolean literals is that they're entirely different from strings. So if I print out the type of this expression, capital T true, and then I print out the type of this expression, capital T true but in quotation marks, then I should see that this is a Boolean and this is a string. It's a string whose contents just so happen to be a Boolean expression true, but to Python, this is just a sequence of characters starting with capital T and then RUE. So when I run my code, I can see that the type of this expression is a Boolean, and the type of this expression is a string. So again, we almost never actually write Boolean literal expressions like capital T true or capital F false. Instead, we write expressions whose values evaluate to be a Boolean. So we're going to start with one kind of Boolean expression called a comparison operator. A comparison operator compares one thing on the left and then one thing on the right. So for example, the first comparison operator that we'll learn is the is equal to operator. So the value of this overall expression is going to be true if the thing on the left is equal to the thing on the right, but it's going to be false otherwise. So let's see this in action. So on line one, I print out is the value of 5 equal to the value of 5. So the thing on the left is 5, the thing on the right is 5, and so I should expect the value of this overall expression to be true because 5 is equal to 5. Here on line 2, I print out is the value of 5 equal to the value of 6. So I should expect the value of this overall expression to be false. And let's see if that's the case. There are other comparison operators that we can use. So in addition to equals equals, there's the opposite, which is not equal. With an exclamation point equals. So that's true if L is not equal to. So if the value of L is not equal to the value of R, then the value of this expression is going to be true. So if I write is 5 not equal to 6, then I should expect this to be true. And I can see when I run my code that it is. In addition to equals equals and not equal to, there's less than, less than or equal to, greater than and greater than or equal to. And all of these expressions expect one thing on the left and one thing on the right. So let's write out a few more Boolean expressions. So I can say print out is the value of the expression 3 less than the value of 4. I should expect that to be true. I can print out is the value of 4 less than or equal to the value of 4. I expect this to be true because 4 is equal to 4. I can print out is the value of 5 greater than the value of 6. I should expect this to be false. If I print out is the value of 7 greater than or equal to the value of 8, I should expect this to be false as well. So you can see that these are the most common types of comparison operators that we have. Equal to, not equal to, less than, less than or equal to, greater than, greater than or equal to. And they compare the thing on the left with the thing on the right and the value of the overall expression is going to be a Boolean, again, either true or false. So let's answer a multiple choice question. Which of the following is a Boolean expression? Select all that apply. So the value of this expression, true, is a Boolean literal expression. So I should say this is a Boolean. The value of this expression 3 equals equals 4 is true if 3 is equal to 4, but because those 2 aren't equal it's going to be false. But this is still a Boolean expression. So I'm going to say yes, this is a Boolean expression. This addition between 3 and 4 has the value 7. That's not a Boolean, that's an integer. So this is not a Boolean expression. The value of this expression 3 plus 4 equals equals 7 is a Boolean expression. And the value of this expression is the string false. And so this is not a Boolean expression. So I'm going to say a, b, and d are all Boolean expressions. One thing that I want to note really quickly with this equals equals Boolean expression is that this is entirely different than saying something like x equals 3. So if I say x equals 3, this is an assignment that assigns x to 3. If I say x equals equals 3 then this is a comparison and the value of this overall expression is going to be a Boolean. And if x is equal to 3, its value is going to be true. If x is not equal to 3, then it's going to be false. But again, the way that we distinguish between assignment and comparison is assignment uses 1 equals, comparison uses 2 equals. That's all for now until next time. So, so far we've seen two ways of creating Booleans. We've seen literal expressions. That's either true or false. We've seen comparison operators that compare two values. So there's equal to, not equal to, less than, less than or equal to, greater than, greater than or equal to. And all of these compare one thing on the left with one thing on the right. And the value of the overall expression is going to be true or false. Again, a Boolean. Now, there's another way to create Booleans, which are logical operators. So, like comparison operators, logical operators expect one thing on the left and one thing on the right. So, the logical operators that we'll cover are and, or, and not. So, and and or, just like comparison operators, expect one thing on the left and one thing on the right. Not only expects one thing that I'll call B short for Boolean. Unlike comparison operators where the thing on the left and the thing on the right can be an integer or a string or pretty much any type, logical operators expect the thing on the left and the thing on the right to be Boolean expressions. So, the value of L and R is going to be true if both L and R are true. The value of L or R is going to be true if either L is true or R is true or both are true and the value of not B is going to be true only if B is false. In order to make it clear how these logical operators work, I'm going to draw what's called a truth table. So, I'll start by drawing the truth table for and. So, remember that L and R are both Booleans and so L is either going to be true or false. So, I'm going to represent whether L is true or false in columns. So, here the first column is going to represent L being true and the second column is going to represent L being false. I'm going to represent the value of R in rows. So, R being true is the first row and R being false is the second row. So, every cell represents the combination between L and R values represented by that row and column. So, here this cell represents L is true and R is true. This represents L is true and R is false. This represents L is false and R is true and this represents L is false and R is false. I'm going to write the value of L and R in each cell. So, here if L is true and R is true then L and R is true. If R is false but L is still true then the value of L and R is going to be false and if the reverse were true so if L were false but R was true then the value of L and R is going to be false and if both are false the value of L and R is going to be false. So, you can see that L and R is true only if L is true and if R is true. Let's write out the truth table for OR. So, just like AND we have L and R so we have L true L false and we have R true R false. So, if the value of both of these is true then the value of L or R is going to be true. If L is true and R is false then L or R is true. Same thing with if R is true but L is false the only way that L or R is going to be false is if L is false and R is false. So, you can see L or R is going to be true if either L is true or R is true and then the table for NOT is a little simpler so, if B is true then the value of NOT B is going to be false if B is false the value of NOT B is going to be true. So, you can see that NOT B is only true if B is false. So, when we write out logical operators you don't need to write out these truth tables entirely but I use these truth tables as a way to understand systematically how AND OR and NOT work. So, let's look at some code. In this code we assign the variable X to have the value 5 and we print out X greater than 0 and X less than 10. So, here on the left we have one Boolean expression and we have another Boolean expression here on the right. What that means is that the value of this overall Boolean expression is going to be true only if this expression is true and this expression is true. So, we can check is X greater than 0 well X is equal to 5 and so yes 5 is greater than 0 so this is true is X less than 10? Well I see that X is 5 and yes 5 is less than 10 so this is true and what that means is that if this is true and this is true then we're here on the truth table meaning that the value of this overall expression is true. On line 4 we assign a variable N to have the value 25 and we print N modulo 2 equals 0 now remember that modulo means remainder so what this is saying is what's the remainder of when we divide N by 2 so when we take modulo 2 we're either going to get 0 if it's an odd number because even numbers will divide by 2 and have no remainder odd numbers will divide by 2 and have a remainder of 1 here we see that N is 25 which is an odd number so N modulo 2 is going to be 1 if we take N modulo 3 that's asking is there a remainder when we divide by 3 and we should actually have a remainder of 1 when we divide by 3 and so what that means is that this expression N modulo 3 equals equals 0 the value of this expression is going to be false because it's comparing 1 with 0 and checking if they're equal and N modulo 3 equals equals 0 the value of this overall expression is also going to be false because 1 is not equal to 0 and so when we ask false or false when we fall here in the truth table and false or false is going to be false so I'm printing out true and then I'm printing out false let's check our work so you can see we get true and then false so if you recall from a previous lecture python has a notion of operator precedence so at the highest precedence is when we have parentheses and then just below that exponentiation that's when we say something like x star star 2 which stands for x squared below that we have multiplication and division so that's x times 5 or x divided by 5 then we have addition in subtraction x plus 2 and so our comparison logical operators do fall in this order of precedence in fact comparison operators fall just under addition and subtraction so here we have comparison like equals equals and then below that we have the not operator like not x and then below that we have and and or so that's like x and y what that means is that if we have an expression like x greater than 5 and y less than 2 then python is first going to evaluate this expression because this comparison between x and 5 has a higher precedence than the and and then it's going to evaluate this overall expression that's all for now until next time so there are two more useful operators for producing boolean values first we're going to go over in and then we're going to go over it's opposite not in so in checks to see if the thing on the left is a member of the thing on the right so for example here suppose that we have a string apple and we want to check if some substring is contained in that string so the value of this expression is going to be true because the character p is an apple the value of this expression is going to be false because the character i is not an apple the value of this expression is going to be true because the substring ap is an apple in the value of this expression is going to be false because p a is not an apple so I should get true false true false So if I print out, is a in the string a, then I should get true because yes, even though these two things are the same, technically this is inside of this. Same thing with if I spell out apple. So the value of both of these expressions will be true. Somewhat weirdly, if I check to see if an empty string is contained in any other string, then I'm going to get true. So is this empty string inside of the string a? It's kind of debatable what the answer should be, but the way that Python evaluates this expression, I get true. So if I check to see if this empty string is in the string apple, I'm going to get true for this as well. Now the opposite of in is not in. So if I check to see if something is not in another string, then I'm going to get true if it's not in that string. So x is not in the apple. And so the value of this overall expression is going to be true because the string apple doesn't contain the character x. So somewhat confusingly, this not has the same spelling as something like not Boolean expression, but these are entirely different things. They kind of have the same function which is reversing the value of a Boolean expression. So I'm saying not be is going to be true if be is false and not in is going to be true if this is not in it. But to Python, there are different kinds of expressions. So I just want to also illustrate that in also works with lists. So here, if I check to see if this item is in this list, I'm going to get the value false because it's checking to see, is there an item in this list whose value is just the string a, even though I have some strings that happen to contain a's, there's no item whose value is equal to a. So I get false for this expression. That's all for now until next time. In this question, we ask, which of the following properly expresses the precedence of operators using parentheses of the following expression? And here we have this expression. So I know that and is going to be the lowest precedence operator. So this thing on the left is going to be evaluated and then this thing on the right is going to be evaluated. So now the question is within these expressions, what gets evaluated first? So multiplication has a higher precedence than comparison. So this is going to be evaluated first. So I should know that there are parentheses around five times three. And then we compare that to 10. Five times three is greater than 10. And I can add parentheses around this whole thing. Now on the left hand side, addition has a higher precedence than this comparison. So I should say four plus six is in parentheses. And then we compare that with 11. And this overall expression is in parentheses. And so our result should look like this. And we can see that that's in A. So let's see this example step by step, the way that Python would evaluate it. So here we have the exact same expression. Five times three greater than 10 and four plus six equals 11. So Python sees this overall expression and the first thing that it evaluates is five times three and it gets 15. And then it's going to check is 15 greater than 10 that gets true. And then it's going to check the value of four plus six so it gets 10. And then it's going to ask is 10 equal to 11 and that's going to be false. And then it's going to take the value of true and false and get false. So that's how Python evaluates and breaks down this complex expression. Welcome back. So we've already covered Booleans which allow us to write expressions that evaluate to either true or false. But knowing if something's true or false isn't typically that useful on its own. Most of the time when we use Booleans we use them in combination with conditional execution. Conditional execution allows us to say run this piece of code if something is true run this piece of code if something else is true or run this piece of code if something's false. So let's jump right into conditional execution. So we do conditional execution with if in else statements. So in this code we declare a variable x and set it here to the value 15. And then we say if x modulo two equals equals zero as a quick reminder modulo is the remainder operator. So for example, if we take 15 modulo two then because 15 divided by two is seven with a remainder of one modulo gives us only or the remainder. So 15 modulo two is one. If we did 14 modulo two then because 14 divides evenly into two with seven then we get a remainder zero. If we do 13 modulo two then we get a remainder of one and so on. So in other words, if we take x modulo two then it's going to be zero if x is even and it can be divided by two with no remainder and it's one if x is odd. So in this code we say if x modulo two is zero which to us this is a Boolean expression that's going to evaluate to true if x is even and it's going to evaluate to false if x is odd. So we say if it's even then print out x is even then we say else. So you can think of else as being like otherwise. So else is saying otherwise if this condition is false then do something else. So we say if x is even print out x is even otherwise if x is not even print out x is odd. So when I run this code while x is 15 then we should expect this else condition to print out x is odd. So let's run our code. Okay, so we printed out 15 is odd and that indicates that we ran what's in this else class. Let's modify our code slightly to set x instead to an even number like 14 and run it again. Now we instead get 14 is even. So one thing to note is that we specify what's inside of this if through indentation. So just the same way that we specify what's inside of a for loop versus outside of a for loop. Just like for loops we can have any number of lines here. So I can say print it is even in all capital letters and this is inside of this if. I can put here print it is odd. So now when I run my code I get 14 is even it is even and this else clause is ignored. So let's answer some questions around conditional execution. So this question asks how many lines of code can appear in the indented code block below the if and else lines in a conditional. So in other words what this is asking is after we have an if then we have some Boolean expression. How many lines can we have inside of here? Well really we can have pretty much any number of lines. So I'm going to put one or more because we have to have at least one thing inside of this block but we can have more. We can have any number of things inside of our if block and same thing with our else block. So this question asks what does the following code print? Choose from ABC or nothing. So here we say if and then we have a Boolean expression four plus five equals equals 10. So when Python evaluates this Boolean expression it's first going to evaluate four plus five because that's higher precedence than the equals equals. And so four plus five evaluates to nine and then it says is nine equal to 10 and when it evaluates this expression then we get false. And so what that means is if we say if and then this expression evaluates to false then we do not run what's inside of this if clause. Instead we run what's inside of the else clause. Inside of the else clause we have print false and so that's what I expect to be printed in this code. So I'm going to answer B. Okay. Here's a slightly trickier question. We have the same conditional that we had in the previous question. So from that I'm just going to note that this is false. So this if does not run but what's inside of this else runs. Now if we look after this else then you should see this print true is not indented. So in other words this print true is outside of this if else clause. So what's inside of this else clause is just print false and what that means is that this print true is run regardless of what happens in this if else clause. So from the previous question we know that the else clause is run here because nine is not equal to 10. So we know that this print false is what runs first but then this print true gets executed regardless of what happened in this if else clause. So I expect false to be printed then true to be printed. So in other words answer C. So now I'm just going to go through one of these questions. The rest are fairly similar to this. So you should try them on your own. Here we're asked to write code that assigns the string you can apply to SI to output if the string SI 106 is in the list courses. So I'm going to start by writing the Boolean expression to evaluate whether this is true or false. So is the string SI 106 inside of the list courses? So you might remember that the way that we do that is we can say SI 106 in courses. This is a Boolean expression that evaluates to true if SI 106 is in courses and false if SI 106 is not in courses. Now if I want to do something if this Boolean is true then I can write if and then add a colon after this. And now what do I want to do if SI 106 is in courses? Well it says write code to assign the string you can apply to SI to the variable output in that case. So inside of this if I'm going to write output equals the string you can apply to SI exclamation point. And now it says something to do if SI 106 is not in courses. So if it's not in courses assign the value take SI 106 to the variable output. So I'm going to say else. So in other words if SI 106 is not in courses output equals take SI 106 exclamation point. Okay so even though my code doesn't actually print anything here you can see from the tests passing that we correctly assigned the variable output. So sometimes we can actually omit the else clause if we don't need it. We can just have an if with no accompanying else. So in this code we first assign the variable x to 10 and then we say if x is less than zero so in other words if x is negative then we print this out. Note here we don't have an else after this if instead we just have a print statement that as the contents imply always gets printed. So when we run this code because x is 10 we should expect the expression x less than zero to be false and so we should expect only this is always printed to print out. If we run our code that's the case. Now what if we changed x to be negative 10? Rather than running this code I'm just going to go to this multiple choice question which has that exact code. So we first have x equals negative 10. Then we say if x is less than zero then print out the negative number x is not valid here. Then we print out this is always printed. So we should expect that because negative 10 is less than zero that this if clause is going to execute. So it should print out the negative number negative 10 is not valid here. And then this is always printed because it's outside of the if should be printed as well. So our answer should be B. In this question we have similar code. So we say x is negative 10 if x is less than zero then print out the negative number x is not valid here. But then we add in else saying otherwise print x is a positive number but then we have another else that prints out this is always printed. And the question is will the following code cause an error? And the answer is going to be yes. The reason is that every else has to have an accompanying if right. So you never would start off a conversation or a sentence by starting with otherwise. If you do that then it's like, well, otherwise what? You have to have a thing that you're saying otherwise in response to. So every else always has to have an accompanying if. So this else corresponds with this if. This else has no if that it corresponds with. And so Python says I don't understand what we're actually writing here. And so it's going to give us a syntax error. So yes, this code causes an error. One thing to note with conditionals is that inside of an if block or an else block we can also have another set of conditionals. So remember that whatever goes inside of a block. So for example, inside of this else block is all indented and only runs if what's inside of this if is false. But we can have other if and else statements inside of either of these blocks. So for example, here inside of this else block we have another if statement saying if x is greater than y, then do something. Otherwise, and this else corresponds with this if. So otherwise print x and y must be equal. So these are what are called nested conditionals. And you can have any level of nesting. So for example, this if block could have another if l statement which could have another if l statement as many times as we want it to. So when we look at this code, we first assign x and y to 10 on lines one and two. Then we say if x is less than y, so 10 is not less than 10. So this statement is false. And what will happen is we'll jump to the else. And then we say if x is greater than y, but 10 is not greater than 10. So this is also false. So we then jump to this else. And what gets printed out is x and y must be equal. So let's run our code just to verify that this is the case. So we get x and y must be equal. Let's change our values for x and y a little bit. So let's start by changing x to instead b5. So when we change x to five, then this if x is less than y, so five is less than 10, that's true. And so we print out x is less than y and we skip this entire else block. So the only thing that gets printed out is x is less than y. Okay, so now let's change our numbers slightly again. So I'm going to say x is 10 again and I'm going to change y to be three. So now 10 less than three, this is false. So we skip to the else and then we say if x is greater than y, 10 greater than three is true. So we run what's inside of this nested if and we print out x is greater than y. So we're going to come back to this code and learn one new construct of if and else statements called an LF, but before then, let's answer some questions. So in this code, we have another nested conditional because this else has an if else inside of it. And the question we're asking is, will this code cause an error? Well, I don't see anything invalid in this code because this else is allowed to have this if else in it. And so I'm going to say, no, this code is not going to cause an error. So let's actually figure out what this code is going to output. So we assign x to be negative 10 first and then we say if x is less than zero, print out the negative number, negative 10 is not valid here. And because this if ran, then we entirely skip this else. So the only thing that would get printed is the negative number, negative 10 is not valid here. Now recall this code from the nested conditionals discussion. So here we assign two variables, x and y to be numbers. And if x is less than y, we want to print out x is less than y. If x is greater than y, we want to print out x is greater than y. And if they're equal, we want to print out x and y must be equal. So far, we've needed to do this through nested conditionals. So in other words, this else statement had to contain another if statement and else statement. So in other words, if x is less than y, we print out x is less than y. If x is not less than y, but it is instead greater than y, then we print out x is greater than y. If x is not less than y and x is not greater than y, then we print out that they must be equal. But Python offers a cleaner way to express conditionals like this. So in this case, rather than having an if and else contained within this else, we can write something called an LF. So an LF is short for else if. So LF looks exactly like this. So now we have the exact same logic that we had before, but it's a little flatter and doesn't require nesting. So we say if x is less than y, then print out x is less than y just like before. But then after that, we write LF, which again is short for else if. So in other words, if x is not less than y, but x is greater than y, then we print this out. And now this else is saying if none of the conditions in this LF or this if were true, then run what's in here. So when I run this code, when x and y are 10, then I'm going to print out x and y must be equal. So just like else, every LF has to have an accompanying if. So this LF corresponds to this if and this else corresponds to this if as well. Remember, you don't start off a sentence or a conversation by saying otherwise. Likewise, you aren't going to start off an if conditional by saying LF. You always have to start with an if. So here's a diagram that explains where you use if, LF and else. So every conditional group always starts out with exactly one if. So we have if and then some Boolean expression and then some code to run if that Boolean expression is true. Then we can have any number of LFs. In other words, we can have zero or more LFs that come right after that if. So if we say LF condition two, then this block runs if condition two is true and nothing earlier in this if group ran. So in other words, condition one was not true. This LF condition three runs if condition three is true and condition one in condition two were not true and so on. So at condition X, then this runs if condition X is true and none of these other ifs or LFs were true. So then after the if in any number of LFs, we can have either zero or one else statements. In other words, we can omit this else statement or we can have one of them. And this else statement is going to run only if none of these conditions inside of this if block were true. So in other words, this is saying if something's true, otherwise if that thing was false and this thing is true, otherwise if everything else so far was false and this is true. And then the else is saying otherwise if everything so far was false, then run this. So for example, here are some valid if LF else orders. So we can have an if with nothing else. We can have an if with one else statement. We can have an if that has one LF and an else. And we can have an if with two or any number of LFs with no else. So let's answer some questions about if LF and else. So here we have some code and the question asks which one of one, two, or three gives the same result as the following nested if. So in other words, what we're doing is we're trying to replicate this code with an LF. So what I would do is I would say, okay, if we join this if in else into an LF, so I would say if X is less than zero, LF X greater than zero and then else. So this code is not valid because we have else and then a conditional, but whenever we write else, we can't have a conditional. So we know that the answer isn't one and in fact one would cause a syntax error. For answer two, we have pretty much exactly what we wrote here. So we joined this else and if and made this else a clause on this if. And so I'm going to say that the answer is answer two, but let's look at answer three just in case. So we have an if X is less than zero then print out the negative number X is not valid here. And then we have another if. So in other words, we have one if clause that goes from here to here and another if group that goes from here to here that includes an else. Now this code looks like it's going to be exactly the same, but it's actually a little bit different. So I'm going to answer number two is the answer here. And we can tell that that's the right answer. So this question asks, what will the following code print if X is equal to three, Y is equal to five and Z is equal to two? So here we have a slightly more complex Boolean expression to say if X is less than Y and X is less than Z. So first is three less than five? Yes, that's true. And then we ask is three less than two? That's false. And so true and false is false. So this if does not execute. If Y is less than X, so five is not less than three. So we know that this is going to be false. And we don't even need to know whether this is true or false because we know that false and any other value is going to be false. And so what that means is that we run what's inside of the else clause. So we print out C. In this question, we're asked to write code using one conditional to find whether the string false is in the string str1, which is specified here. So I'm going to first write out the Boolean expression to express that. So that's the string false in str1. And the question we say, if that's true, then assign the variable output to this string. So I'm going to say, if this is true, then output equals the string false, you aren't you, question mark. And then it asks, check to see if the string true is in str1, and if that is, then assign true URU to the variable output. So I'm going to put that in an LF. So LF true is in str1, output equals true URU. If neither are in str1, then assign this string to the variable output. And so we're going to express that within else. Else, remember, else doesn't take a condition because its condition is implicitly that neither of these conditions were true. So we say else output equals neither true nor false. I'll leave it up to you to complete the remaining exercises. So previously we've discussed the accumulator pattern, but the accumulator pattern becomes even more powerful when we combine it with conditionals. So recall that the accumulator pattern involves three broad steps. So first we initialize an accumulator variable and then we iterate through the relevant sequence. And then as we iterate through that sequence, we update our accumulator variable. And then in the end, the accumulator variable, if we did these steps right, has the answer that we want. Okay, so let's apply this template and use it in combination with conditionals. So suppose that we have a phrase here and we want to count the number of characters that are not spaces. So in other words, we want to count one, two, three, four, we want to skip the space, five, skip the space, six, seven, and so on. Then we can use the accumulator pattern with conditionals. The way that we can do that is here we initialize our accumulator variable total to be zero. In other words, the number of non-space characters that we've seen so far. Then we iterate through our sequence. In this case, it's phrase. And then we update our accumulator variable appropriately. So in this case, we want to say we've seen one more non-character space if the character in our phrase is not a space. So we write if character and then exclamation point equals, that's to say not equal to. So if character is not a space, then we say total equals total plus one. So when we run our code, it's going to count the number of non-space characters. In this case, it's 26. If we had only spaces here, then we would get zero. If we had three non-space characters, then we would get three and so on. If we wanted to solve a slightly different problem, so let's suppose that we want to count the number of vowels inside of this string S, then we take the same broad steps. So we initialize our accumulator variable X to be zero, then we loop through our sequence, and then we say if this character I, so I is the individual character, so if it's in this list, A, E, I, O, U. So in other words, this is saying if I is a vowel, it's one of A, E, I, O, or U. If it's a vowel, then we update our accumulator variable X to add one onto it. And so the result is that we're going to count the number of vowels. So when we run our code, we can see that there are eight vowels in this string S. So we can visualize this with an example. So here we want to count the number of O's and non-monopoeia. And in our code, we loop through every character, and we say if the character C is the character O, then add one to O count. And the result is that we're going to loop through every character in our word and print out the number of O's in our word. So when we see the first O, we add one onto it. When we see the second O, we add another onto it. And then we keep looping through. Every time we see an O, we increment O count by one. And when our code is done running, then O count would be four, and we print out there are four O's and non-monopoeia. Another common pattern that mixes conditionals in the accumulator pattern is what's called max value accumulation. So in max value accumulation, we're trying to find the largest thing in a list of things. So in this example, suppose that we want to find the largest number in this list of numbers. So nums is just a random list of numbers. And what we're going to do is we're going to use the accumulator pattern to keep track of the best or highest number that we've seen so far. So in other words, we assign best underscore num. So at first we just assign it to be the first number that we see. So we assign best num to be nine. And then what we're going to do is we're going to loop through all of the numbers in nums and say if we find a higher number than our best number so far, then we're going to update best num to be that number. So we say for every number N, if N is greater than the best number that we've seen so far, then reassign best num to be N. So I'm going to simulate execution on this code before actually running it. Okay. So first we assign best num to be the first number. Then we loop through every number. So after we assign best num to be the first number, then we loop through every number. So first N is going to be nine. And we say is nine greater than best num, which is nine. It's not. So we then loop through to the next number. Three is three greater than nine. It's not. So we loop through to the next number. Eight is eight greater than nine. It's not. So we loop through to the next number. 11. And then now when N is 11, we say is 11 greater than nine? It is. So we reassign best num from nine to instead be 11. And then we loop through to the next number, five. And rather than comparing it to nine, because best num is now 11, we compare is five greater than 11? It is not. So we loop through to the next number, 29. And we ask is 29 greater than 11? It is. So we reassign best num to be 29. And then after we've done that N is now two. And we ask is two greater than 29? It's not. And so at that point, because we've gone through all the numbers in our sequence, then we're done with this for loop. And when we're done with this for loop, best num has been assigned to 29. And so we print out 29. So in other words, our strategy for max value accumulation is to keep track of the highest value that we've seen so far and then to loop through every item in the sequence. And if we see a number higher than the highest one that we've seen so far, then reassign our highest that we've seen so far to that higher number. And we know that by the time this for loop is done running, then best num it's going to be the largest number that's in our sequence. So when we run this code, we should expect 29 to print out and we see that it does. If I change this sequence to instead half 50 instead of five, then we should now expect 50 to print out and so on. If I changed this to be 200, 200 would print out. So it always prints out the largest number in this sequence. So in this question, we're asked what is printed by the following statements. So we assign S to the string we are learning. Then we assign X to be zero. So X here is our accumulator variable. S is the sequence that we're iterating over. And we say, if I is an A, B, C, D, E. So in other words, if it's one of these characters, then we assign X to be X plus one. Then at the end, we print out what's the value of X. So this is the accumulation pattern and we're accumulating the number of characters that are A, B, C, D, and E. So in order to answer this question, we have to count the number of A, B, C, Ds and E's in the string S. So I see one, two, three, four, five. And so I expect the answer to be five. So this question asks, what's printed by the following statements? So we have a variable called minValue that gets assigned to zero and we have a list that we're iterating over in this for loop. And we say, if an item in this list is less than minValue then minValue equals item. So here we assign minValue to zero and one thing I notice right away is that no item in this list is actually less than zero. And so what that means is that this boolean expression is never going to be true because we don't have an item that's less than zero. And so I expect this to never run and by the end of our loop, minValue is going to be zero. So if we actually wanted to collect the minimum value in this list, rather than assigning minValue to be zero, we should assign minValue equals the first item in the list. So in other words, list sub zero. And then minValue would start out as five and we would do a form of maxValue accumulation. So as we've seen, the accumulator pattern becomes even more powerful when we combine it with conditionals. That's all for now until next time. Welcome back. Sometimes you'll want to change an object after you've created it. You create a list, you want to keep adding items on to the end of the list. Create a turtle, change its pen color. There are two ways to change the value of an object after you've created it. One, you can make a modified copy of the object and the other is to modify the original. We'll call that mutation. And it's useful but sometimes confusing. So today's lesson, how a mutation of existing objects works, recognizing the potential confusion that that can cause. At the end of today's lesson, you should be able to identify whether an object is mutable or immutable. You should be able to identify whether a method mutates an object or creates a modified copy of it. And you should be able to recognize when two different variables or aliases for the same object and predict whether an operation on one of those variables is going to cause an impact on the contents of the other one. Lists are mutable. You can change them. You can reassign the contents at any position to be a different value. So in this example, we're setting fruit as a variable to have the value banana apple cherry. And then we're going to change it so that the first item isn't banana, it's pear instead. Let's go through this a line at a time and draw out the reference diagram. On line one, we create a variable fruit and assign it to a list with three items. We have banana, we have apple, and we get cherry. If we print it out, we'll get banana, apple and cherry. Then we'll get to line four, where we're going to change the value in one of these positions. Now you've previously seen indexing into lists. Lists have positions like zero, one and two. And so fruit square bracket zero is referring to this position that currently has banana. On line four, we're not just referring to fruit square bracket zero. We are changing the value of fruit square bracket zero. We're making fruit square bracket zero equal to a new value. So that has the effect of replacing the old value with a new one. We cross out banana and we add a new value pear. Then we get to line five, where we're going to make another replacement. In this case, we're replacing at position minus one. And just as we did for looking up values in a list by position zero, one, two, or from the end, position minus one, position minus two, position minus three, we can assign to those positions. So fruit square bracket minus one equals something that's going to cause us to cross out, replace the current value that's there with a new value. In this case, orange. So let's try running this the first time something is printed, we have the original values of banana, apple, and cherry. Then we made our two substitutions and then we printed something else. We printed the new value of fruit, which had pear, apple, and orange. Instead of just replacing a single item, we can replace the items at a particular slice using the same slice notation used for looking up items. We can use that to find a place where we want to do a replacement. So let's look at this one in code lens. The first line when we execute it creates a variable called a list. A list has as its value, this list of five or six items, a, b, c, d, e, and f. And line two is going to mutate to destructively modify this list. Now remember that when we use the slice notation, we're referring to a subsequence of the list. And we begin at position one and we go up to but not including position three. So this is a slice that's two items long and we're gonna replace those. We get rid of that whole slice. And we're gonna add in two new items there, x and y. So now when we print it out, let's just see the net effect of that. Here are our notations. We've now replaced the items at position one and two with x and y. And if I print it, I now get a, x, y, d, e, f instead of a, b, c, d, e, f. Now we're not required to have the things that we add in be of the same length as the things that are being replaced. Here's an example showing how we can actually use this reassignment to delete items. So in this case, we first assign a list to have the values a, b, c, d, e and f. We're going to start at position one, go up to position three, but not including position three, and we're gonna delete those items and replace them with the empty list. So we're gonna replace them with all of the items that are in this empty list, which is nothing. So we're really gonna just get a, d, e and f. Sure enough, when I go forward, I get a, d, e and f. Lists are mutable, strings aren't. We could reassign to position zero in a list. We cannot reassign to position zero in a string. So for example, if I run this code, I set the variable greeting to be a string, and then I try to change the thing at position zero, just analogous to what we were doing before, we had reading bound to this string. So we have greeting bound to that string. In position zero, we've got that h, and you might think that we could just replace the h with a j, but we can't do that. That is not permitted, and we get this error message. We get a message saying type string does not support item assignment. We can't reassign a value within a string. Now, suppose we really did want to take our hello world string and turn it into jello world. How could we do that? We can't reassign at position zero. That's what we found out just a moment ago. So how do we do it? Well, we can take the string hello world and we can make a new string that has some of hello world, but a little bit different. In particular, we're going to take that hello world and we're going to start at position, so this is position zero, position one, two, three, and so on. We're going to start at one and go all the way to the end. That's what it tells us when we say greeting square bracket one colon. Greeting is the name of our variable and we're going to start at position one, that's with the letter E, and go all the way to the end because we don't have anything after the colon that means keep going all the way to the end of the sequence. So that gives us hello world and if we take hello world, concatenate that onto j, we get jello world. And there we have jello world. Now notice on line four, it says print greeting. Greeting is still hello world. So that's why we get this as our second line. New greeting was bound to our new string jello world and that's why we get this printed out. So you can't change the original string hello world, but you can make a new string using a lot of the letters from hello world and just concatenating them onto a new first letter. Here's an example of concatenating together a bigger string from parts. Let's show this one in code lens. We first start with a small phrase, many moons. We want to expand that. So we define a new string that has many moons plus some more letters. So we still have the old variable phrase, but we have an additional variable now called phrase expanded. And we can keep doing that. We can make it even longer. That's what's going to happen in step three. So phrase larger is yet a longer string. Notice that the previous variables are still bound to their original values. And then finally, we're going to replace that small m with a capital M. So you'll be assembling longer strings from shorter strings in this way and it'll let you put variables in in the middle of your strings to generate slightly different strings each time. It's awkward and error prone to use slicing to delete things out of a list. So Python gives us a special operator to do that. It's called the delete operator DEL. In this case, in this code, we're creating a list called A with three items in it, one, two and three. And then we're calling the DEL operator to remove item one. Let's see this in code lens. We first create the list and then A square bracket one refers to this position. And when we delete it, the value three is now going to move up into position one and we'll end up with just one and three in our list. Now we've just got one and three. And we can not just delete a single item, we can delete a whole sequence of items. Here we have a list, A, B, C, D, E and F. We're going to start at position one. Go all the way up to but not including position five. That's A list, square bracket one, colon five. And that's all going to be deleted. So we do that and we're left with just A and F. When we have two variable names that point to the same value, things can start to get confusing. It's actually not too bad when we point to immutable objects. So for example, we have the variable A pointing to banana and we've got B also pointing to banana. Now it turns out that with strings, the Python interpreter figures out that it's the same string banana and it makes A and B both point to it. And so we have this operator is, which checks and tells us whether A and B are pointing to the same object. Are they aliases for the same object? And here it says true. A and B are pointing to the same object. It's going to get a little more complicated for us when we start dealing with lists and other mutable objects. Here we've got variables A and B both pointing to lists that have equivalent values. But it turns out they aren't actually aliases for each other. Let's see this in code lens. So the variable A is bound to a list of three items, 81, 82, and 83. Then we're going to assign B to a list that's really equivalent, but it isn't the same list. So we end up with two lists that each have the values 81, 82, and 83. And then A is not an alias for B. So when we print A as B, it tells us false. However, if we ask does A equal equal B as we do on line six, it'll tell us true. So equal equal is an operator that checks whether two variables are bound to objects that are equivalent to each other. A is B, checks whether A and B are aliases for exactly the same object. If we print the IDs of these two, we'll see that they are not the same. So those are very long IDs. I just want to point out one other thing, which is that if we run this not in code lens, but in the active code window, we get the same answers false and true for whether A is B and whether A equal equals B, but the ID numbers are a little different. In code lens, the interpreter is running off on some remote computer and it's got a real Python interpreter where the ID numbers are really big. When we run it in code lens, it's doing something right in the browser. It's the only thing running and so it ends up with these small ID numbers. But the important thing to notice whether you run it in the active code window or whether you run it in code lens is that the two ID numbers are not the same. Three and four are different or these two ID numbers are different. So you might wonder why are we making such a big deal out of whether A and B point to the same object or two objects that are equivalent. The answer is that when they are aliases for each other, when they point to the same object, things can get pretty confusing because when you change one of the objects, you've changed the other one too. So let's just see how that works out. On line one, so the variable A is bound to the list 81, 82, 83 and B is bound to an equivalent list, but not the same one. So when we get to line three and it says print A is B, the answer is false. Now on line five, we're gonna make B and A be aliases for each other. They weren't before, but now they are. So B is no longer gonna be bound to that one. It's gonna be bound to the thing that A is bound to. Now A is equivalent to B, but we also have that A and B are bound to the very same object. If we then set B square bracket zero to equal five, well, this is position zero, position one, position two. If we set B square bracket zero to now have the value five, and then we go to print A, we're gonna get five, 82, 83. The reason I say this is confusing is if you look at this code from the top to the bottom, we set A to be 81, 82, and 83. We never change A again. There's no assignment statement to A anywhere in here. And then we go print it, and it's different. Now in this code, A and B, they're all pretty close to each other. We can figure out what's going on, but you can imagine a much bigger program where you have a variable and somewhere else in the code, some other alias for that variable causes the item to be mutated to change and you have no idea why it's happening. So that's why I say aliasing and mutable objects can create some confusions. Be on the lookout for that. See you next time. Let's suppose you wanna make a clone of a list, not an alias for it. You want another variable that will have an equivalent list, a copy of the original list or a clone of the original list, but you want the two lists to be independent. So we start, let's say we start with a list A that has the elements 81, 82, and 83. We want to make a new variable B that has a clone or a copy of it. We can do that using the slice operator. The slice operator always grabs some part of a list and makes a new list using those items that have been grabbed using the slice. So if we execute this in code lens, we can see what happens. So we created a list A, we make a slice. In this case, our slice begins at the beginning of the list and goes all the way to the end of the list. So we get all three items, zero, one, and two, and they are copied into a new list. And so we get a new list. So B is now not an alias for A. B is referring to a list with equivalent contents, the same contents. So if we print A equals equals B, they are equivalent, so that's true, but A is not B, they're pointing to different lists. Now, if I change B sub zero to B five, unlike our previous example, where B was an alias for A, when B sub zero is set to five, only B is going to be affected. So we see that it has a new value five, but the 81 is still there for A zero. So when I print A, I'll get the original list. B was originally an equivalent list with the same contents, a clone of A, they've become independent, and B gets mutated without having any effect on A. There you have it, clone a list by using the slice operator. If you don't say either a beginning or an ending index, you get the whole list and you get a clone or a copy of the list. That's the basics of object mutability. You should now be able to identify whether an object is mutable or not. Lists are mutable, doubles and strings not. You should be able to recognize when two variables are aliases for the same object and realize that if you make a change to the object that one variable refers to, you'll be changing the contents of the other variable at the same time. We sometimes refer to mutation operations as destructive. They change the object and then any aliases for that object also see the effects of that destruction. Speaking of destructive operations, did you hear about the guy who worked at the calendar factory? He got fired because he took a couple days off. And another bonus joke, what's an undercover tarantulas alias? A spider. Keep laughing, keep coding, see you next time. Welcome back. This lesson, you'll learn a bunch of useful methods on lists and strings. At the end, you'll be able to read and write code using the following methods. For lists, append, insert, reverse, sort, remove, pop, and some non-destructive methods, index and count. For strings, you'll learn upper, lower, count, index, strip and replace. The end of this lesson, you'll be able to extend a list using either append or concatenate. And very importantly, you'll be able to identify whether a method mutates an object or creates a modified copy of it. Methods on tuples and strings can never mutate them, only make modified copies. Some operations on lists mutate them. Assignment and deletion you saw previously and new methods that we'll talk about it. In this lesson, append, insert, reverse, sort, remove, and pop, they all mutate lists. Good luck, see you after the screencasts. Let's see some useful methods that operate on lists. Some of these methods will mutate the list, some of them will just return a value. So we've got a lot of things in this code. Let's run it using code lens so that we can step through it one step at a time. Our first command just creates an empty list. The next thing calls the append method on it. That's line two. So just as with alex.forward, we have mylist.append. That means run the append method on mylist, which says add a new item to the end. In this case, the item will be whatever we've passed in as an argument, it's going to be the value five. So we start with an empty list. After we run this, we'll have a list containing one element, the value five. If I do it again on line three, now the value 27 is going to be appended to the end of the list. So we'll have five and 27. I can do it a third time. This time three will be appended to the end of the list. It's helpful to notice here that the variable mylist is always bound to that list object. So we have the arrow pointing to it. That never changes throughout all of this. What changes is the list itself. It's getting additional elements added to it. So we get a fourth element there. If I now print it out, it'll show up in the output window. A second useful method is insert. Append always sticks an item at the end. Insert inserts the item wherever you tell it to. In this case, we're going to tell it to insert at position number one. So it's going to go to position number one and it's going to insert it. It will not erase the current contents at position number one. That's what we had with assignment. Recall we could do something like my list square bracket one equals a new value. That would replace the 27 with 12. But that's not what happens with our insert command. Our insert command splices our new value in right before position one. We'll go forward and sure enough, the 12 has been inserted there between the five and the 27. You can print that out and now the list has five items in it. Line 10 introduces a new method called count. The argument that you passed to count, in this case 12, is not a position in the list. It's a value. The count operation is going to go through all of the values in the list and count how many of them are equal to 12. So in this case, the count will be two. That's something you did with an accumulation pattern in a previous lesson. But the count method just does it for you. Counts how many times 12 appears in my list. Index is a method where we will pass in a value and it will tell us the position where that value can be found. So we'll pass in value three and it'll tell us the index, the position where that three can be found. Perhaps somewhat confusingly, it's also three here. So we're gonna get back the value three. Print my list dot count of five is gonna look through and find all the places where five appears. There's only one of them. So we'll get a count of one. My list dot reverse takes the order of the items in the list and changes them. So the last becomes first. And then we get the three, the 27, the 12 and the five. But these values are actually gonna go back into the original positions. So the list itself is being changed. We're not making a new copy of the list. So when I run that, it actually reverses the items. I print it, they come out in the opposite order that they were in before. Sort is another method. It's gonna take the items in the list and just reorder them from smallest to biggest. So we'll get three, then five, and 12, and another 12 and 27. So sort and reverse, keep all of the same items, but they rearrange them into a different order. Our next method we see on line 21 is dot remove. You've seen previously a deletion operation, DEL, which takes a position. And whatever item is at position one would get deleted if I write DEL of my list square bracket one. Dot remove doesn't specify a position, it specifies a value. So it's going to remove the five wherever it is. And then now the five is gone. There's one more operation for removing items, pop. It removes the last item from the list. So in this case, when we pop my list, we'll get 27. And it actually returns that value. So the list will be changed and we'll get the value 27 back. In this case, we've chosen to assign the results of the pop operation to a new variable called last item. And sure enough, last item now has the value 27. So to summarize, you've learned here how to use several mutating operations, mutating methods on list, append, index, reverse, sort, remove, and pop. We've also seen a couple of non-mutating methods, index and count that return values and pop that was a mutating method that changed the list and also returned a value. Of all of these, I would say append is the method that's the most important. You'll be using append all of the time. See you next time. Welcome back. There are two ways to add stuff to the end of a list. One we've seen already and illustrated here. Is to append. So orange list on line one gets assigned to a list of three things and then on line three, that list gets an additional item at the end. It gets cat added to the end. The second way is using concatenation, the plus operator. So on line one, we create the same list, but on line three, we're now going to use concatenation and then reassignment. So we concatenate the original list with a new list and the new list has only one item in it. And then we reassign that back to the same variable. So orange list is gonna end up being bound to a new list that has four items, 45, 32, 88 and the word cat. Now in CodeLens, it's not actually gonna show us that we have a new list here because there's nothing pointing anymore to the old list and so it doesn't bother to show it to us anymore. So it'll look like we've just replaced the old list, but it's actually a new list with four items. So sure enough, that's what we get. Now let's look at a little more complicated one. Here, on line one, again, we're creating orange list with the three values in it and then we're just printing out some things to remind us of what those are, but then on line four, we're doing something different. Instead of reassigning the concatenated list of orange list plus cat back to orange list, we're reassigning it to a different variable called new list. Let's see how this is gonna play out in CodeLens. On line one, we assigned the list to orange list and we're just printing out some stuff. Line four, we're making a new variable and it's pointing to the new list. So remember before it didn't show us that the old list was still unchanged. Here, we're seeing that the old list with just three items in it is still bound to the variable orange list. Even though we did a concatenation operator, that did not change the contents of the actual list. It made a new list and then we bound that to a new variable. So then we print some stuff out and now we actually are using an append operation. That's gonna stick a new value, an additional value on to orange list and so we're going to get something added on here to orange list. We're gonna get cat here as well. That's what we'll get. Let's run it and see. Sure enough, cat is added onto that original list as well and then we print some more things. Now we've printed out the identifiers like these long numbers just so you can see that orange list is pointing to one object with one identifier and new list is pointing to a different object with a different identifier. There's one more tricky thing to know about a pendant concatenate and that is that this plus equal sign that we've seen previously, we've seen it as we had things like x plus equals one and we describe that as being a synonym just another way of saying x equals x plus one. In the world of mutable lists, that's not quite true anymore. They're not quite the same. Now what's gonna happen with the plus equal sign when we do it with a list is that it actually is gonna mutate the list. It doesn't make a new list and concatenate to that. The only time that's gonna matter is if we have some other alias for the same list. So in this code, let's run it. The first line of code just assigns a list of three items to orange list. The second line of code makes a new variable that points to that same object. So alias list is an alias for orange list. And now we're onto line three. On line three, we have this orange list plus equals cat and we're gonna see that that's a slightly different thing than saying orange list equals orange list plus the new thing. The difference is that we're actually going to extend the original object. And because we extend the original object rather than making a copy and a new one, we will also affect any aliases for it. So when we run this, we will find that not only does orange list now have cat as its last item, but so does alias list. So this is a different outcome than we would have gotten had we run this line of code instead of line three. My suggestion is with lists, don't use the plus equal operator. It's just too confusing. Sick with what we have on line four where we say orange list equals orange list plus another list. Don't use the plus equal operator with lists. On the textbook page about append versus concatenate as with many of the other pages, there are lots of useful exercises and I encourage you to try those out. We'll see you next time. Welcome back. Let's see some useful methods on strings. Remember that none of these methods can ever change or mutate the original string. They can only produce a new one based on the old one. First, let's learn about the upper and lower methods. I'll show this in code lens. We create a string SS that is bound to hello comma world. If I call the upper method on it, all of the letters become capital letters. So we get hello world and capitals in the output, but notice that SS hasn't changed. It still has the small letters. I can also call the lower method which will make the capital H and the capital W be small letters. In this case, I'm assigning it to a new variable called TT. That's what the TT equals a line four does. I can print that out. And again, SS has not changed. It still has its original value. Next, I'll show you count, strip and replace. In this example, hello world has a bunch of spaces at the beginning and some more at the end. The count method works similarly to the way count works on lists. You specify as an argument what value to look for. In this case, a letter, and we're gonna look for L. It appears three times. So the count method returns the value three and we're assigning it on line three to the variable ELS. So now ELS has the value three, out. Line six is a little bit more complicated. Here we've got something that's gonna get printed out. Nothing's gonna change with our variables, but the thing that's getting printed out requires a little sleuthing to understand. We've got the plus operator twice and so we're gonna have three different strings one, two, and a third here and we're gonna put them all together. So we're gonna get star, star, star and we're gonna have star, star, star at the end. What we get in the middle is whatever is returned by calling the strip method on SS. What the strip method does is it looks at a string and it looks for any white space at the beginning and white space at the end and it gets rid of it, leaving only the characters that are in the middle. White space in the middle, that's okay, that does not get removed. So we get hello. So that's our new string and we're not assigning it to any variable but we're just asking for it to be put into the output window. So we get hello world with the stars instead of the spaces in our output window. On line eight, we are calling the replace method. So that's gonna look for any place where the letter O appears and it's gonna put in star, star, star instead. Now, strings can never be mutated. So what's gonna happen is we're gonna get a new string that has those replacements in it and that's going to be bound to our variable news. So here, we can see that the O is replaced by three stars. This O is also replaced by three stars but still this string that SS was bound to, it is unchanged. We can print that out. News has these white space at the beginning so that shows up in the output window. As with other pages in this text, there are more useful exercises. I'm not gonna go through them all but I do wanna do one here that I think is particularly illuminating. So here, S is bound to a string Python rocks and we're gonna print out this complicated expression. So you have to get used to kind of breaking these big expressions into parts. And the star operator, if I said, quote, X times four, that would give me a string X, X, X, X. So it just repeats the string however many times you say when you're multiplying. So we really need to have the thing to the left of the star resolve to some character string and the thing to the right of the star to resolve to a number. And that's what they're gonna do. S square bracket one, well, we have position zero, position one, so S square bracket one is Y and S dot index of N, that says what position can you find the letter N in the string S? Well, zero, one, two, three, four, five. So it's the letter Y times five. And when we print it out, we get it without the quotes around it. So sure enough, it's the letter A. There it answer A, which is Y, Y, Y, Y. So to summarize what we've learned in this segment, all methods on strings are non-mutating. They leave the original string alone. They generate new strings. So if you want to keep changing a string that's bound to a variable, you'll have to make a new version of the string and reassign it to that same variable name. So the methods you've seen here are dot upper and dot lower to make the string all uppercase or all lowercase letters, dot count to find how many occurrences of some substring occur in the larger string, dot index to find the first position in the string where the substring can be found. That strip gets rid of all the white space at the beginning and the end of the string and that replaces all occurrences of some substring with a different substring. We'll see you next time. Welcome back. There's one more method for strings that's a little more complicated and important enough to warrant its own video segment. We can concatenate a string together, including some hard-coded parts and some variable parts like this one. We've got a hard-coded part, hello, period, your score is. Then we've got some variable parts like the name and the score. If I run it, we concatenate, we get hello, we get Rodney Dangerfield, that's coming from name, your score is minus one that's coming from there. So one thing to notice about this is it's just sort of a little hard to read. It's a little hard to read this and figure out exactly what it's gonna look like over here. And you gotta be careful about things like getting the period, which really belongs with the end of the name, but you gotta stick it on there, you gotta remember to put spaces there. You have to remember that score is a number, so we gotta pass it through the str function in order to turn it into a string. A lot of stuff that's not so convenient here and not so readable. So we're gonna have a new command, the .format method, that's gonna make this a little cleaner. Before we get to that, though, let's just do a slightly more complicated version of this where instead of saying just Rodney Dangerfield score, that we're gonna get a whole list of tuples. So we've got Rodney Dangerfield with a score of minus one, Marlon Brando getting one, and of course, you would get 100. And we're gonna loop through all these people. For each of them, we're gonna print out something like that, like what we did for Rodney Dangerfield. So hello, Rodney Dangerfield, hello, Marlon Brando, and hello, you. What I'm gonna do next is show you something that's gonna replace that concatenation with something that's a little cleaner. So I've just replaced line five with something that is little cleaner. We have a first part of it, which is called the format string, and it's got some things in it which replaces where we're gonna do substitutions. So we have a complete format string and you can kinda look at that and get a sense of what the shape is of the thing that's gonna come out at the end, but we're gonna have some substitutions. And this first set of curly braces says do a substitution here, and we have positional replacement. So the first value is gonna get stuck in there and the second value is gonna get stuck in here. So looking at this, we have a format string and then we are calling a method on it, the dot format method. So it's a method on that string and we're passing in a couple of parameter values. The first parameter value is gonna get substituted in for the first curly braces, the second parameter value for the second curly braces. So when I run this, the first time we get to line five, name will be Rodney Dangerfield and score will be minus one. That's what's gonna get substituted into the hello string and the next time it'll be Marlon Brando and so on. So we get the same result as before, but our code is a little more readable. We'll be doing this more and more as the specialization goes on using these format strings rather than concatenating together strings out of individual parts. So a little vocabulary that we have here, we have the format string, we have parameters and these are the parameter values that are getting passed in and then we have references close to substitute in those parameters. Here's another example that's a little more complicated where we can give some hints to the format method telling it how many decimal places to use for numbers. In this program, we're first asking the user to type in an original price for an item and then a percentage that it's going to be discounted. We compute a new price from the original price and the discount and then we're gonna just create a string and finally print it out. The string that we're gonna create is we're gonna have a whole sentence that includes some information about the original price, how much the discount was and what the new price is and those things are gonna get substituted in. The original price will go here, the discount will go here and the new price will go here. The new thing that we're seeing here is this colon 0.2f and what that says is the thing that's gonna get substituted in here is a floating point number. That's what the f is saying and the period two is saying after the decimal point have two more digits. If I run this, let's see what it looks like. I'm gonna have an original price of $89.99. We're gonna get a 20% discount and that comes out saying that $89.99 discounted by 20% is $71.99. Now it isn't the case that 20% off of $89.99 is exactly $71.99. It's actually a tiny bit less than that but the closest number that's in dollars and cents is $71.99. If I told the Python interpreter that I wanted four decimal points instead of two, then I would print it out with more precision. Let's take our $89.99 item, get a 20% discount and now it turns out it's $71.99.20. So we can control how many numbers we get after the decimal place by specifying it in that inside the curly braces. If we remove the hint entirely about how many decimal places to use, then it just goes and uses its default. In this case, it's giving us three decimal places. If we had some different value, it might choose to give us more decimal places or less because we weren't giving it any instructions on how many to do. It was using its built-in algorithm to decide it. If we want to control exactly how it comes out, that's when we use this little hint. And for dollars and cents, it really makes sense to have two decimal places because that's the precision for dollars and cents. All right, so that's the format statement. Just a reminder, a format statement begins with a format string and then we call the .format method on it and we pass in any values that are supposed to get substituted. The substitutions happen where the curly braces are. We'll see you next time. You've now seen the most important methods that you'll be using on lists and strings and a few more obscure ones that you'll only rarely use. You should now be able to read and write code using those methods. You should be able to extend a list using either a pen or concatenate to add more items onto the end of it. And you should be able to identify whether a method mutates an object or creates a modified copy of it. Methods on tuples and strings, stream reminder, they can never mutate them. They can only make modified copies because tuples and strings are immutable. Some operations on lists mutate them. Assignment, deletion, append, insert, reverse, sort, remove and pop, those all mutate lists, index and count, leave them alone and just tell you some property of those lists. So today's joke. How can you get two cats in the same room? You concatenate them. See you on the flip side. Hi, welcome back. We're going to use the accumulator pattern a lot in this course. Previously, you've seen how to accumulate a number, a count or a sum. In this lesson, you're going to accumulate lists and strings. With lists, you'll start with an empty list and then you'll mutate it repeatedly by appending another item each time. With strings similarly, you'll start with an empty string and extend it repeatedly with concatenation and reassignment so that you get a longer and longer string accumulated. At the end of this lesson, you should be able to read and write code that accumulates lists and strings. See you later. Welcome back. You've seen the accumulator pattern before. Now we're going to accumulate a list instead of a number. So in this code example, as with all accumulator patterns, we have to have some sequence that we're going to iterate over. In this case, we have a variable nums and we are binding to a list containing three, five and eight. And we're now going to accumulate a list. We'd like that list to contain the squares of all the numbers from the original list. So nine, 25 and 64. As with all accumulator patterns, you have some accumulator variable. I'm going to call it a CUME. We could call it something else, maybe squares would probably be a reasonable choice. And anyway, it's called the CUME here. And we initialize it to be just an empty list. And this is typical when we're accumulating a list. We start with an empty list and we're going to keep appending to it. This is the analog of starting with zero when you're going to take an accumulation that gives you a sum. We start with the empty list and then on line three, we start our iteration. So we're going to iterate each time W is going to be bound to one of the items from nums. In the first iteration, W will be bound to three. We'll set X to be the square of three or nine. And then we're going to append the current value of X, nine, into the accumulator. On the second iteration, W gets bound to the second value, five. And so X gets bound to 25 and we append 25. The third time, W is eight, X is 64 and 64 gets appended to the list. So this is following the same logic of your accumulator pattern before. Each time through this iteration, an additional item is going to be appended into a cube and so really a cube is the squares so far that we've managed to accumulate. When we're done with this iteration, we finished with all three of these. We can print out a cube and the cube will have all of the squares. So let's run it. Sure enough, we get nine, 25 and 64 at the end. So it's a little check on your understanding. Let me try changing one thing in this. Suppose that I indent that print. Can you predict what the output will be? It's a good chance to pause and see if you can predict it. At each stage, we're now going to not just change the contents of the accumulator but we're going to print what we've accumulated so far. So we're now going to have three lines of output. First just the list nine and then the list with nine and 25 and then the list with nine, 25 and 64. So as before, this is a useful debugging strategy with the accumulator pattern is to print out what you've accumulated so far and see how it grows over time. So in summary, to accumulate a list, you will initialize the accumulator to be an empty list. You'll iterate and at each iteration, you'll append a new item. At the end, voila, you've accumulated a new list. Catch you later. Welcome back. We can also use the accumulator pattern to accumulate strings. In this case, you'll start with an empty string and keep appending to it. But when you append, you'll have to reassign to the accumulator variable because you can't actually change the original string. So here's an example, sort of a Michigan example, Michigan winter example where we've got someone who's got chattery teeth because it's so cold outside, all of their letters are coming out double. So they're going to say a word like hello and because their teeth are chattering, it comes out as hello. So here's how we do that. We're going to start by asking the user to type in a value. That's on line one. They enter some text. And that gets assigned to the variable s. Let's suppose that, well, let's make it easier for us. They say cat. The accumulator variable is going to have our result so far, our teeth chattering version of that string that we've accumulated so far. Initially, there's nothing, but it's going to accumulate things. And then we start iterating one letter at a time. The variable c is going to be bound to the letter c. And then we are ready to execute the accumulation part, line four, for the first time. So it's going to take our current value of ac, which is an empty string. It's going to add the current value of c, which is the letter c. And then it's going to give us a dash and the letter c again and another dash, which yields a string c dash c dash. And that becomes the new value for ac. The old string is still there, but we don't worry about it anymore because ac has been reassigned to this new string c. We're now ready to go on to the second iteration. When we get to line four for the second time, c is now bound to the letter variable c. C for character is now bound to the letter a, the second letter in our string. And we're now going to make a, let me write it over here, we're going to make a string that has the old value of ac. And then we append the letter a and a dash and a again and another dash. And that becomes our new value, caca. And similarly for t, we're going to extend this each time that we do all this concatenation, we have to reassign to a. Because we're not actually changing the old, we have to reassign to the variable ac, I should have said. And we have to do that because ac has not been changed. So we've made a new string and we reassigned it to ac. So in summary, to accumulate a string, you start with an empty string. On each iteration, you reassign the accumulator variable with a concatenation of its old value and some new stuff. At the end, you've accumulated something like cc a, a, t, t. So let's run it, I enter cat, I get caca at. Michigan frozen winter, speaking cat, or if I run it and ask for a dog, I'll get dd o, o, g, g. See you next time. Congratulations, you've now learned how to accumulate lists and strings in addition to numbers. For a number, you usually initialize the accumulator to 0. For a list, you initialize it to an empty list. For a string, you initialize the accumulator to an empty string. You can accumulate all kinds of things now. I hope you're accumulating friends and not enemies. So instead of an accumulation joke today, let me close with a little information about Ann Arbor, Michigan, for our learners who are joining us from around the world. Michigan is in the northern part of the United States in the Great Lakes region. In the winter, it gets very cold here. And in the western part of the state, they get lots of snow, the lake effect. You might say it accumulates there. See where I'm going with that. In Ann Arbor, however, we don't get so much accumulation. We don't get much snow here, just the cold. And that's snow joke. See you next time. Welcome back. In this week's Way of the Programmer lesson, we'll be encouraging a habit of drawing reference diagrams and offer some tips on how to recognize when to use the accumulation pattern and how to do it well. The learning objectives, at the end of this lesson, you should have developed the habit of drawing a reference diagram to resolve any potential confusions. And you should be able to recognize when you should use the accumulation pattern based on the words that are in the problem statement. See you at the end. When in doubt, make a reference diagram. Even if you only might be in doubt, make a reference diagram. It's gonna seem slow, painful, even to watch me do it. When you're doing it for the first few times, it's gonna be even slower and more painful, but it's worth it because it gives you a way of understanding things that can be pretty confusing otherwise. So here's a little code example, four lines, and then we're printing out what's the result, but it's not so easy to figure out exactly what's gonna print out. And so let's make a diagram to follow it. So we're gonna basically simulate like what code lens would do, but we're gonna do it ourselves. So X on line one gets bound to a list of three items. One, two, three. On line two, Y becomes an alias for X. On line three, we have this X plus equals. Now I gave you the suggestion that when you're dealing with lists, just don't use plus equals, but sometimes you have to read other people's code and they don't follow that good advice. So suppose you had this, X plus equals, that's the version where we're gonna take the new list four and five and append them on to the old list so that we now have a list of five items and line three changes the object that X is pointing to. Since Y is pointing to that same object, Y now has five items as well. Next, on line four, we're gonna use the better version that is a little easier to understand where we do the normal thing of figuring out the right-hand side which takes the list one, two, three, four, five and appends another list to it making a new list. So then we have one, two, three, four, five. That's a list. We concatenate on this other list which contains six and then we reassign it. That's what this equal is doing so that Y no longer points to what it used to point to, it now points to this new value. X, however, still points to the old value. So when we print out X on line five, we're gonna get five items. When we print out Y on line six, we're gonna get all six items. Let's check and see if that analysis is correct. Sure enough, line five prints out five items, line six prints out all six. Trying to do this in your head, especially if you ever end up with more than four lines of code that are doing things like this, very difficult to do. So remember, if there's anything even remotely confusing, make a reference diagram. Practice now, even when it might not be so confusing, you'll thank me later. Onto the next, we're back with a little more way of the programmer advice. You've seen the accumulator pattern in various guises now. And this is some advice on how you can know when to use it and some little tricks for getting it right. You may remember back in elementary school, maybe you have kids like I do who've been in elementary school recently and they start dealing with word problems and you look at the problems and you say, wow, you're just gonna, that's three plus five. But somehow converting that word problem into three plus five is challenging. So they learn little tricks, like when it says how many do they have altogether, they should know that it's an addition problem or how many are left is gonna be a subtraction problem. So here's something a little similar for how to recognize when you're gonna be dealing with one of our accumulation patterns. We've got these phrases on the left in this table and we've got which accumulation pattern that might suggest to you that you're gonna use. So if the problem says how many things are in a list or how frequently does something happen, that's gonna be account accumulation. If the problem asks for the sum or the total, that's gonna be a sum accumulation. If the problem asks to generate a list of things, that's gonna be a list accumulation. And if it says to concatenate or join things together, that's probably gonna be a string accumulation. Next on this page, we've got a little bit of advice of how to think about what you're gonna do before you write any code. And one thing to ask is, which sequence are you gonna iterate through? And the second question is, what kind of value are you going to accumulate? Are you going to accumulate a number, a list or a string? And then our third set of advice is about choosing good names for your accumulator variable and your iterator variable. Names that'll help you keep track of things. As we've said for any iteration, it's a good idea to use a singular noun for the iterator variable name. And if you are iterating through a list of words, then it might be a good idea to use an iterator variable name like W-R-D to just remind you that each time, on each iteration, W-R-D, your iterator variable is going to be bound to a word. For the accumulator variable, I sometimes just use a generic accum, but it also can be helpful to sort of remind yourself of what you're accumulating. So, got suggestions for names like countsofar or totalsofar or cubessofar? Could be good names for your accumulator variable. Having that appendix sofar sort of reminds you that on each iteration, the accumulator is getting more stuff. And so what you have at a certain point in the execution of the program is the totalsofar, not the grand total. But after you've finished all of the iterations, you're going to have the grand total. There's a bunch of questions to help you check your understanding on this, but I'm just going to go through a few of them with you. So, and we've got several of these in the book. I'll just go through a couple, and you're supposed to sort of pick out what, if anything, in this problem should make you think that you're going to do an accumulation. And I'll tell you now that some of them, there is something, and for some of them, it actually isn't an accumulator pattern at all. So let's start with this one for each string in words, add ed to the end of the word in order to make the word be in the past tense, and save those past tense words to a list called past words. Does this suggest to you an accumulation pattern? And if so, why? We've got two possibilities for why here, either because it says save some things to a list, or because it says add ed to the end of the word. The correct answer is saving a bunch of things to a list should suggest to you accumulating a list. What goes into each item, that's not what suggests that we need an accumulation pattern. Let's try the next one. Write code to sum up all the numbers in the list seat counts, store that number in the variable total seat counts, and here our correct answer is to sum up, because to sum up suggests that we got a bunch of things and we want to get the grand total, so that is going to be a sum accumulation. So there's some more, and I encourage you to try those. Here's a couple questions about what type of object you should expect to have stored in your accumulator variable. So the question here is, write code that will count the number of vowels in the sentence S and assign the result to the variable num vowels. Now we haven't quite got all the mechanisms in Python to be able to count only the vowels and to leave out the consonants. You're going to get that pretty soon in this course. But even so, the structure of this is enough that you know it's going to be an accumulation pattern, and you're going to count the number of vowels. A count is a number. So our correct answer here is that it is an integer because we want to keep track of a number. So different question about that same problem. What sequence will you iterate through as you accumulate a result? And we have two possibilities here because we have a sentence S and we have variable num vowels. Which of those are you going to iterate through? And the answer is you're going to iterate through S. You're going to accumulate your results in num vowels, but the sequence that you're going to iterate through is the characters in the sentence S. So there's a couple more of that flavor. And then we've got some questions about what should you name your accumulator variable and what should you name your iterator variable? So let's try this one. For each string in words, add ED to the end of the word to make the word past tense. Save these past tense words to a list called past words. So a couple possibilities here. We're either going to name our accumulator variable word so far or we're going to name it changed words. And our iterator variable name can either be W-R-D, short for word, or X, or it could be ED. And my suggestion is this is just a matter of style, but these style things help you to avoid confusion and can help readers of your programs also not get confused. Is that words so far is kind of an ideal name for your accumulator variable. It tells you so far says it's an accumulator and word says what kind of thing you're accumulating there. And for your iterator variable, you're going to be iterating through this string W-R-D-S. Plural, that's a list of strings. Each of those strings is one word. So having an iterator variable of W-R-D seems like a really good choice to me. There are a few more questions like this and I encourage you to go through all of them just to reinforce the way of the programmer around recognizing when you need to use an accumulator pattern on choosing the right variable names and on recognizing what kind of thing you're gonna accumulate a string or a count or a number and what sequence you're going to iterate through. So go through those and you will become an expert on the accumulator pattern. See you next time. Welcome back. I hope that you are traveling the way of the programmer, making a habit of writing reference diagrams, choosing good variable names and training yourself to recognize the telltale markings of an accumulation problem. Above all, practice programming. To borrow and horribly mangle a quote from Mahatma Gandhi, there is no way to programming. Programming is the way. I didn't find a great joke for you, so I'm gonna give you just a random pun verse that I've always enjoyed. One, one was one race horse. Two, two was one, two. One, one, one race. Two, two, one, one, two. I'm here to tell you about your end of course project. So this course project that you're about to do will cover a lot of the concepts that you've already covered in the course. You'll have to do a series of problems that are of varying types and covering varying concepts. But all of these problems that you'll be doing are the kind of programs that lots of people use in their real lives. Accumulation, gathering data together, changing what it looks like in this little program. So these kinds of programs that you're about to write in your project are possibly very applicable to your everyday life in school or work or whatever really. I wanna remind you of some tips that may be useful as you start to work on this project. So first of all, as you know, you should always change one thing in a program. Predict what will happen when you eventually run that program after changing this and then try it. That way, if you've only changed one thing, made a prediction and then tried it, you will know whether or not that worked or whether or not your prediction was right. And so you'll know if you have a good understanding of what you're working on in that moment. If you do a bunch of different things and then try it, you might have to dig through all those different things to figure out what was good and what was not good and what you need to do to finish that program and get it to happen the way you want. So always change one thing, predict and then try it. I also wanna remind you to use variable names that are clear to you. For instance, if you're using an accumulator pattern or any for loop, you never want the iterator variable to be plural because it's always gonna be bound to one singular thing. And you wouldn't wanna plural variable name for a singular thing because that can be really confusing when you talk and think about your code. Similarly, I would advise you not, for example, to use the word L-I-S-T inside a variable name that couldn't be a list because that's gonna get confusing too when you read your code later and you'll think, oh, it's a list and then it will not be a list. All of these problems that you're about to do in this end of course project are different but they're all similar patterns to problems that you've seen or done before. And as you work on them, I'd advise you to think about those and think about how they're similar to other stuff you've done and that will make it easier to progress on these. For each one, you should go through, make a step-by-step plan in words, no code at all for how you're gonna solve the problem and then make sure that you can translate each of those pieces into code. For example, in an accumulation problem, you should talk through step-by-step as if you're talking to a robot or write down what each of those steps are that needs to happen in that program, that little task. And then you can think step-by-step about how to translate each of those things into code, how can you translate your words into a program that will run and continue with changing one thing and then trying it to make sure that the code runs. Finally, if you see a problem, for example, maybe the last problem in this end of course project where there's a complex task to do for each one of a set of things, do something with each string, for example. You should think about your plan for each individual task, say for doing that complex task for one string and make sure that that works, that everything is fine for just one string. If your code for doing the task one time with one string is successful, then you can move to building all of your code and putting it into a for loop and implementing the full solution so that all of your code is successful for that program. All of these problems are really useful for applications in almost everybody's everyday life in one way or another. I think they're fun. I hope you will enjoy yourself and I wish you good luck.