 All right. Hey, welcome everyone to our course summary of Sailor Academy CS 105 Introduction to Python. If you haven't been following this series so far, feel free to go down in the description below. We'll have a link to all the previous videos we've done where we've done a recap for every unit of the course. Of course, if you haven't done the course, you should go over to sailor.org. Check out the course in full. You can come back, leave comments, you know, get to what we can. I'll make sure to put links to the course, links to our discourse, and links to Replet, which is the course, which is the program that the course has been using this whole time. And that Dr. Sack will be using probably in this video to help describe some stuff. But without further ado, Dr. Sack wanted to take it away. Again, I'll make sure everything's in the chat and everything's in the description if you need any links. Dr. Sack, how's it going? Oh, great. Thanks so much. Appreciate that. I'm going to try and get into Replet right now. So this is interesting. Would you like me to put a link in the chat? Yeah. Well, no, you know, I had something like set up. I just want to make sure, oh, here we go. Okay, it's a little laggy for somebody. Sometimes, you know, Replet lags. But anyway, I think while this is trying to find itself, I'll come over to the webpage just to let you know where I'm going with this whole thing today is there are 10 units to the course. The first unit just has to do with introduction. And I made the decision to go with the web-based IDE. But there are other ones out there that you should probably look into installing because a lot of people try and communicate via notebooks and so forth. And there's just so many resources out there for Python. It's really a very popular language. And so once that's all set up and get through the basics, then talked about different kinds of operators from arithmetic, relational and logical. Then unit three was just talking about flow control and loops and so forth, basic built-in data structures. And then at that point, it became sensible, I think, to at that point become sensible to really talk about functions without lists and strings and so forth. You can show little examples and so forth. But I think once you start to introduce lists and strings in the context of flow control, then it's sensible, more sensible to talk about interesting kinds of functions. Then a little bit more into Python built-in data structures. Talked about handling files, doing string searches using regular expressions, a very important topic, exception handling, if you want to go out and do this for a living. And then ultimately getting into just some introductory, very introductory, very rudimentary, very scratch-the-surface concepts in object-oriented programming. And so trying to get the higher view of things, I think the most important aspect of unit one really was just understanding really simple stuff like what a print statement is, how to identify the variable type. My experience has been when students get into like a unit one situation, there are two important concepts, I think. One is just the notion of an assignment operator, the fact that if for certain data types, if I go ahead and say A is equal to 7, and then I rewrite A as being, let me just make sure I'm sharing this, and then I rewrite A or recompute A as being able to A plus 4, and then say print A. A can only hold one thing. And because of that, the assignment operator is destructive and intentionally destructive, so that when you're done, you don't see the 7 anymore, you see whatever the old value of A was, which was 7, you add 4 to it, and you get A back out again. So I think at the introductory level, some students oftentimes get confused about what the assignment operator does, because your brain doesn't work that way. If you had to, you'd be able to memorize the number 7 and 11 very easily. In fact, I was just out of 7 and 11, I got a cup of coffee this morning, but anyway, I don't know why, maybe that's why subconsciously I picked those numbers. But the point is that you can remember the 7 and the 11, but for one variable, in this context, you've got one number inside of that variable. Now if we get to this, there'll be more, but I'm just saying that this notion of overriding, this notion of having an old value and overriding it to get a new value, now like I said at the introductory level, that takes a few iterations for students to kind of hook into. But once you're beyond that, I think the other part of it is when it comes to floating point notation, again, everybody has different math backgrounds, and so there's some students who may not be a thousand percent comfortable with certain floating point representations. And so in this sense, you might be comfortable with C is equal to 0.001, clearly that's a float number. And so that's fine. But I would say that to really grasp or key into, because in the course, I actually created information that was designed to have you actually review scientific notation. To really understand floating point numbers, you've got to understand scientific notation. And so don't run away from that, I guess is what I'm saying. For Unit 1, when the scientific notation portion is brought up, I want you to feel comfortable with that. Programmers have to feel comfortable with numbers with whatever context things are put in. And then finally, just again, whatever your preference is for string representation, some people like double quotes, I like single quotes. But that's your preference. It's just various basic kinds of data types so you can get up and running. Then once you're comfortable with floats and ins and bool for logical, actually I don't introduce bool until we get to relational operators because that's where they make the most sense. That's really all there is to Unit 1. I didn't mean for it to be overly complicated. I wanted to be a nice stick your toe in the water, very easy examples where you start to get comfortable with numbers, comfortable with representations, comfortable with the fact that for the computer's sake, not for your sake, you don't make a distinction between an int and a float and a string. Your brain just processes that data. But just because of the way data gets represented on computers, we have to make the distinction between those data types. And that's what's most important is that you have to understand the type of data that you're dealing with because they mean different things. If I say in this instruction print a plus 5 and over here I say print d plus 7 if I do it like a string, they're going to mean different things. In this case a plus 5 is going to be 11 plus 5 and that's going to give you a 16. But over here if I say d plus 7 in the context of strings, this is an overloaded operator. It's an operator that can be used in many different contexts so that if I wanted to concatenate or append a character to a string, you can see that the 7 gets appended to the string value. So again there's the basics of just learning data types and then there's the gymnastics of learning different operators and then learning how to navigate through different methods that might be associated with a given data type. So that's what I think Unit 1 was about. Unit 2 with regard to operators and arithmetic operators and relational operators, even into the course, if we just pop into the operator section, the ability to construct arithmetic expressions really, really depends on you understanding these most basic operations plus minus, multiply and divide fairly straightforward, exponentiation, a number of ways to do this in Python. In the math library, in the math module, there's a POW function that will take, and that's typical of most languages. Many languages have a power function and some languages will give you like a carrot to x-bench. So you have to be careful with this one with regard to what language you're using. In Python, my recollection, again I'll have to double check this but we're going back, but I think the power function in math just basically uses the double star that's for free as part of the syntax. So I don't think there's anything deeper, but I'll have to go back and double check. Anyway, it's your preference. If you come from another language where you're used to using the power method, then by all means, if you're just starting out and you'd like to have a simple operator where you could raise things to a power, then this is the way you would do it. And then the other integer operators. One is integer division. This was introduced in Python 3 because I think a lot of people, such as myself, were just getting a little bit miffed at how the division operation was working in Python 2. So there are differences between Python 2 and Python 3. That's why this is a course in Python 3. And so there's a specific operator for integer division, which basically says, do the division and take the integer part, whereas this is integer division. Tell me what the remainder is, modulo, whatever divisor you're using. And there's a lot of fun ways to use this operator. Maybe I'll bring this up in a second just to remind you. But if you take something modulo 2, you can use that to decide whether or not you have an even or an odd number, for instance. There are lots of applications for arithmetic operators. Your job for this course is to make sure that you are clear as to what the order of operations is typical of what you might have learned in an algebra course, because you have to, and I've seen this happen when students start programming, they get very careful. They get very careful about their programming. So they start adding parentheses everywhere. And it just looks chunky to have a simple expression that needs like nine sets of parentheses, because they want to be sure that the operation that they're computing within the parentheses comes first. But if you really start to get comfortable with the order of operations, then there's no need to use 10 pairs of parentheses in your expression. So that's the PEMDs. That's the parentheses before exponentiation and then exponentiation between multiplication and division, and then multiplication and divisions occur before additions and subtractions. The only reason I learned PEMDs was from my daughter. I don't know how I knew this. I think once you start to do, all I know is that when I started to do algebra, it was just natural for that to happen that way. But some people need acronyms to remember stuff, and that's totally fine. So maybe in your math background, somebody taught you the acronym PEMDs. And that's why I threw it into the course, because I was just trying to relate it to something may have seen before. Once you get beyond arithmetic operators, then you're going to get to relational and logical operators. And when you start playing around with these and you start mixing together expressions, just to give you some idea to do something like this, again, the reason I put these parentheses in here is simply just to, for your eye, for the reader to understand this is true. But the question is, do we really need this? Do you need something like this? And the answer is not, because if you go ahead and look at the order of operations, that the, what doesn't like about that, everything should be fine. Oh, I got to find A and B. Yeah, sure. Good. Yeah. That's why I'm teaching the course. That's why I'm the teacher. You know, something like that. NSC also, so it doesn't like that. So choose C for C4, right? So then, so this would be false. And so the question is, do we need these? And the answer is no, once you start to get comfortable, you just go for readability. And your eyes start to scan across things like this, that you'll recognize that, excuse me, that the relational operators are taking place before the logical operators. Why is that? I'll get to that in a second. So sometimes you're putting parentheses in for readability. Sometimes you're trying to help the person that's reading your code, you know, see structures that are less obvious, you know, in terms of in terms of reading complicated expressions. So that's really one reason for using parentheses beyond the order of operations. And so sometimes I'll put parentheses in for readability, for instance. And that's important. When you do this stuff professionally, you want people to be able to read your code. So often, unfortunately, when people start writing programs that can have thousands and thousands of lines of code, the notion of readability somehow goes up the window. But you don't want to lose that. You're always trying to communicate what you're doing to a reader to make them as easily understand your code as possible. That's a good rule of thumb. But anyway, but the parentheses can be taken away. So I have a different point to make now. The parentheses can be taken away. Because if we come over to the order of operations from lowest to highest, we'll see that parentheses, you know, are always going to come first. And then you go through exponentiation and arithmetic negation or logical negation. Then you get into, you know, the PEM, this type of thing, multiplication, division, so on and so forth, in addition and subtraction. And you go up the scale to the less, to the lower precedence operations. Well, you go from the relational operators, and then next, finally, at the lowest end of the scale, you know, are the logical operators. So this basically says going from highest to lowest, from the bottom up in this diagram, some people make their tables from highest to lowest. This group decided to do it from lowest to highest. Just be careful when you're reading about stuff like this. You just want to make sure you know what the order of the precedence is. But this is relational and these are logical. So when you come back over and you look at an expression like this, you can see that the relationals are going to be resolved first. And then the AND, which is a logical operator, will be resolved second. So it's not, you're not saying A less than, you know, because you could, in principle, you could interpret it as something like this if you were reading from left to right. And you could say, well, B and A will be evaluated first. And then somehow A less than this expression, less than that, you could read it that way. I don't want to confuse people by drawing into something your brain wouldn't have done in the first place. But you don't know. Coming in blind to a course, if you've never done this before, you wouldn't necessarily know whether you're reading from left to right or if you're evaluating one expression over another. But even if you go ahead and write it like this, it's still going to come out false because the A less than B and the B less than C are going to be evaluated. Now, when it comes to the logical operations, remember, you've got to remember how the logical operations work. The OR only is zero if both operands are false. Okay, the OR is an operation between two operands, and it can only be false if both operands are false. Otherwise, you have to get it true. The AND is kind of a little bit different. The AND can only be true if both operands are true. So in order for this AND to evaluate to a true, just as a review, the A less than C has to be true. And then the A less than B has to be equal to true. Let me shrink this a little bit just to put this back and make it look normal again. So just as a review, the A less than B will evaluate to either true or false. Is A less than B? The answer is false. Now, and A is A less than C. The answer is false also. But what if I made C a 16? Okay, just to remember, 416. That A is actually less than C, but it's not less than B. So what should this? You should be able to predict what an expression like this, by the end of the unit, you should be able to predict what this is going to evaluate to. It's going to evaluate to a false. Why? Because in order for an AND to give you a true result, both A less than C has to be true and A less than B has to be true. They're being evaluated first because of the order of operations. The relationals are going to get evaluated before the logical. That's what the table says. And then you ask, well, is A less than B? 8 is 8, B is 5. So that's false. A is less than C. Yeah, 8 is less than 416. But if this is false, false and anything is false. Why? Because the only way an AND could be true is if both of those results are true. So A is less than B. So that's not true anymore. If I made A a 1, okay, 1 is less than 5. 1 is less than 416. So then in those cases, I would get true. So one of the things you want to leave the unit with on logical operators is to have those Boolean functions burned into your neurons. You need to know them upside backwards and forward. So you need to know that the OR can only be false if both operands are false. So maybe if I made A equal to 1,000 just as a review and to call this an OR, okay, then now A is not less than B. And A is not less than C. So now I can get a false answer. Okay. But if I made A equal to, so clearly A is less than, but if I made A equal to a 6, then in this case, I'm going to get it to be true. Why? Because A is not less than B. So this is where I get A is not, but it is less than C. So I get a true over here. So even though this is false, false or with a true is going to give me a true. So it's very, very important that you have a quick way of evaluating expressions. And so you can use the tables in those units as a crutch, or you should immediately learn that OR can only be false if both sides of the OR are false. And AND can only be true if both sides of the AND are both simultaneously true. And that's kind of how I would say the two overarching important concepts from leaving the arithmetic, logical, and relational operators are the order of operations, the order precedence, very, very important. And then in addition to the order precedence, just understanding how those logical Boolean operations, computer scientists, programmers know those tables, and they know how those operations work. So you need to know that. You need to have, you need to understand that. Because why is this being done? Well, the next unit goes into conditional operators. And to understand conditional operators, you have to be able to write down conditions that are going to evaluate to logical truths or falses. So when you construct your conditional operations, then the logic behind it works itself out because you understand the expression that you're constructing. So that's why the relational operators are introduced. Just to give you the 30,000 foot view, it wouldn't be sensible to talk about unit three. It wouldn't be sensible to introduce conditional operators, I'm sorry, conditional expressions, if, else, LFs, without understanding relational and logical operators. Because 99% of the time when you're writing if statements, you're invoking some type of a logical condition. And if you have that logical condition, you've got to be very adept at formulating what that logical condition is, which will necessarily involve complex combinations of relational and logical operators, and potentially arithmetic operators as well. So that's important to know. So then going into the if LFs, then in your, in the text, if I have it over here, in the course, you see pictures of these kinds of flowcharts. So flowcharting is something that's very important for you to be able to do on the back of an envelope. Again, as I said before, I always tell my students, you don't have to become a flowchart artist. You don't have to become a flowchartist to be able to write flowcharts. But you need to be able to have a way of writing down the logical flow of your program so that it makes sense for you to actually write the program. Sometimes you'll have to, again, if you do this for a living, you're going to have to work out different logical conditions. And you may have to draw yourself diagrams to make sure that you have the logic straight. So for an if statement, the key thing I think for students to get once again is that if you have an if conditional expression based upon some logical condition, and then you have some code that's indented, that's inside that logical condition, if the conditional expression evaluates to a true, if A is greater than B, if A is less than B, or D is less than C, and this or that, I mean, this could get quite involved, that the if statement, if it is true, that group of instructions will execute. And if it is false, if this works out to be a Boolean false, then it will not execute. And once again, this is a concept that I think students sometimes have a little bit it's weird, right? It's like you've got code in your program. And up until this unit, everything that you've taught is sequential. I've got instructions A, B, and C, and instruction A executes, and then instruction B executes in C and D in all perfect sequential order. Now you encounter this kind of different situation where you can have sequential code, but it may not that block of code may not execute because the if condition worked out to be false. And basically the program control jumps over that, if you will, it branches over that, and it never gets executed. And so, so emotionally, you know, students have to kind of begin to deal with the fact that they've got code in their program that may never execute, you know, but you have it there just in case the condition is true. So that's different. You know, this is where this, in my opinion, this is probably one of the most important units, units three and four, because the because you've got to learn how to handle logical conditions. And in addition, we'll get to loops in a moment as well. Very important. But so, but, but this is a good picture to keep in mind. The next picture is the if L if case, I'm sorry, the if else case, where, where are you? Because there's no extra if you're the if you're going, if the if statement is true, you're going to execute one set of commands. And if the statement is not true is false, then you're going to execute another set of commands. So, so this is an important picture to show you that if one condition is true, you're going to do this. The other condition is if this condition is not true, basically, then it will do that. Okay. So, so else is like everything else that wasn't part of the if the conditional statement were a less than b, then, then the else would necessarily mean that a has to be greater than or equal to b. Okay. So, so it's kind of like the logical, the else is like the logical complement of the rest of the universe of logical possibilities outside of what you specified in the condition of expression. And then finally, you can go on forever with this, what you need to be able to do is that is that if the if statement is true, there might be something some other condition that you're working for. Once again, it's important to understand that once you execute one of your L ifs, you're done, you don't consider anything else in the L if list, you can have 25 L ifs, right, you can have so many different other conditions. But once you find the L if that is first encountered in the program, okay, you find a condition. Then, then beyond that, once that once that group of commands is executed, you're done, you leave that whole if clause, and then you go on to the rest of the Python program. So very, very important when you can when you construct these structures, because, you know, oftentimes, again, I see students at the beginner level, when you have a series of five, six, seven conditions, and there may be some potentially because because somebody's just starting out, there could be a logical overlap between condition three and condition five, because of the fact that the L if checked condition three first, and ran the block of code with respect to that L if you don't get to go back and execute the other L if block you're done at that point. So that's important to understand that there are blocks of code that absolutely will not execute, you know, they will not execute because those logical conditions either weren't satisfied, or even if they were, there was a prior logical condition that was encountered first, and then that group, what that group of commands was executed. So just very important to understand the architecture behind if L if and L statements, because again, they can get they can get really involved, you know, and they can have they can involve a lot of logical statements. Another thing that isn't was important were loops. Okay, so for loops, as I said before, here's what I think I just want to give you a 30,000 foot view and maybe I'll just do a quick example. Let me show you. So so in unit three is the most important universe I feel in the course, if you're just if you've never programmed before. And the reason I say this is because of the fact that up until unit three, you know, you're just learning about expressions, you're writing singular sets of, you know, sequential commands, and there's no harm, no foul when you go from one command to the next, just like this, this is this is a simple unit one, unit two type of a program, you know, or script that you would write here are some assignment statements here are some operators print out what the result is. You really only start to begin programming when you get to unit three, because unit three has the most important components of a component of a true computing language, and that is you've got you've got the if conditionals, and which is an application of the relational operators and logical operas, and then you've got loops that are going to be doing operations over and over and over again, and those are really the fundamental components of programs. I don't care if your programming methodology is procedural, object oriented, when you're trying to get a computer to do something, your program consists of a lot of loops, and it consists of a lot of if, else types of statements. And so it's imperative that you not leave unit three without really embracing without really embracing, you know, what that what that means. So, so, so for fun, you just as a quick example, you know, with like a, and it let's do like a for loop and say for for i in range, for i in range, you know, five or something like that, just just just a quick review, you just want to show you this, and then maybe we'll do is we'll just print i again, not a very interesting, and sometimes what I ask students to do in fact I'm probably going to ask this on an exam question tomorrow is what all what I ask them to do is could say convert if you understand for loops and while loops convert, convert the while loop into into, I'm sorry, maybe convert the for loop into a while loop, and you can always convert a for loop into a while loop, you may not be able to compute a while loop back into a for loop if there's not if counting isn't even some form of counting isn't involved. But I could say something like, you know, while I is less than, and if any of you know any of my students in the course I'm teaching it's a different language, but don't tell me I'm asking this question tomorrow unless they're watching this video right now. So I'm just kidding. Anyway, I don't care, you know, I mean, it's just an exam. So, so the the notion of a for loop, right, the main thing about it is that is that for the for loop, you have to say where to start counting, you have to say where to to stop counting, and then you have to say, you know, what the increment is. Okay, so up here when you say I is in range five, range five is counting from zero to four and steps of one. And so, and it's going to go from zero to four. So the condition here is that we're going to keep on incrementing this index up until we're looping until I is incremented from zero to four. Once we increment to five, this condition is no longer true because I has to be less than five to stay in loop. So the way a while loop works just as a review is that you only stay in the loop while the condition, the logical condition is true. In this case, we're asking the question is I less than five, it's less than five stay in the loop, if not, you know, go home and get on to the next thing. So, so I'll just say maybe print, you know, done here just to, you know, just to indicate that this is finished. And if we run something like this, something you're in this junk here, if you run something like this, and just to separate this out, you know, like this, just so you can see it in all its glory, is that both of these loops are going to print out the digits from zero to four. So, so the point is, is that if you're counting, you should be able to go back and forth between a while loop and a four loop. That don't really indicate if you understand how the loop works. You can't necessarily always go from a while loop to a for loop, because as I said, the logical condition and the stuff inside the loop doesn't involve a counting index of some kind. Yeah, you can kind of rest a little bit sometimes, but who wants to, you know, use the while loop, that's what I'm saying. But I think all I'm trying to say here is that, is that in order to really understand what the for loop and the while loops are doing, you should be able to jump seamlessly back and forth between these two chunks of code and understand exactly what they do. So that's that's the most I want to say about unit three. And I'm probably harping on this, probably for the for a good bulk of the time in this summary and review, because my position is that you really, really honestly have to understand these structures to become a program. There's just there's just no way. There's no way, you know, sometimes students, I feel miss the connection between just learning syntax and learning how to program. The key to starting a language to understand, I don't care what line, I don't care if it's English, or you know, some, you have to learn the syntax, and you have to learn the grammar. But once you understand that it's meaningless, unless you start putting the words together to accomplish some task of some kind, all then only then can you call yourself a programmer, because now you're taking those structures, and you're putting them together to do something interesting. That's what that's what programming is. So there's learning the language. And then there's actually learning how to program. And I believe personally that that unit three is the most regardless of the language, any language that you ever learn, you've got to learn how to put those structures together in ways that are efficient and sensible and so forth. Okay, and then after so that's enough about unit three, I've talked about, you know, that's my diatribe for the day. And you'll just have to look at that. Okay, um, then when we get to now when we get to unit four, which is on lists and loops, this is really, really, really where we can be applying the concepts of lists to loops and so forth. And what I tell students at the introductory level is that is that you should always, if you leave a course, you should always know how to perform a running sum. So so I hop on that a little bit, you should know how to compute the minimum or the maximum of a list of values, you should know how to how to find a value on a list by what's called a sequential search, they're more, they're more, they're a very efficient search algorithms out there. And this is this isn't the place to discuss that. But minimally, you know, you should know how to to perform a running sum, you should know how to find a min or max, and you should know how to find stuff on on lists of stuff. And if you can, because computers are really good with this, if you can perform some type of a sorting algorithm, depending on what your appetite is for nested loops, you know, this is another good one also. So in any introductory course, I never ever ever allow students to leave the introductory course without knowing how to do it, at least three, if not all four of these, because this is this is, you know, a 105 introductory programming course. And what you got to recognize is that computers are really good at certain things. They're really good at sorting stuff, they're really good at searching for stuff. You know, if I give you a small list of five numbers, you could probably find a number on that list, you know, better than a computer could because your brain is a parallel processor. But what if I give you a billion items, you know, if I give you a billion items, then you want to write a loop to find something. So a lot of what you see me doing in the in unit four just has to do with constructing lists, and then integrating them with with loops, you know, to compute stuff. And and that's sensible. That's a sensible thing to do. Because you want to exercise your ability in your capacity to to write loops. So at some point, I'm sure, you know, I don't know exactly what the example was, you know, I tried to maybe show examples like this in the course, I'm sure, where where you see applications of loops. So maybe I create some list of numbers in this case. And with lists, again, you've got the left bracket, the right bracket, we talked about building lists, we talked about constructing lists, adding elements to lists, using the dot append method. But once we go ahead and build the list and do all that stuff, then the application, you know, might be to to write loops that that sum the values on the list. Again, there's a sum function to do this. But as we said, if you start mixing these these the summing instructions with if statements and relational operators, that sum function goes out the window, it can't do everything that that, you know, you would want a sum function to do, you've got to, you might want to extract out only the values that might be greater than zero out of the list. And in order to do that, then you'd have to be able to edit edit code that looks like this, but but minimally fundamentally, you know, to sum a value sequentially is that you have to start off with an initial sum equal to zero, and then you successively add all the new values to the old values and then you update. And then you can do this implicitly, or you can do it explicitly dependent upon whether or not you have a use for the index. So in this case, you've got a for loop that's cycling through all the values iterating through all the values and be it's creating a range variable that where I is going to iterate through all those values from zero to the length of B minus one. And then remember, lists are ordered containers. So the way that since they're ordered, that means you can use an index to access those values, the zeroth element, the first element, the second element. But if you have no use for the index, then then you can sort of implied implicitly cycle through all the values just by writing code like this. So so which formulation of a loop that you would use to access values within a loop depends upon depends upon what the application is. If you have no use for the index, then you probably don't need to write code like this. You could write code like that. And that would be fine. Both of these, both of these, both of these chunks of code accomplish the same thing. And of course, like I said, the sum function is there, because this is exactly what the sum function does. But again, if you only wanted to, if you only wanted to filter out the values that were greater than zero on the list, for instance, then you'd have to integrate if statements into these sections in order to say if the value is greater than zero, then contribute to the sum. And the sum function doesn't do that. It doesn't do that for you. So this is why it's so important to understand how the code works. This is what makes you a programmer. Not this makes you a programmer as well. It's like, oh, I just used some, you know, obviously you'd use in the right context. But understanding basic algorithms like summing minimum maximum finding stuff, which are all in the course, by the way, that's what's going to make you a real programmer. Okay. And so, so like I said, to see lots of exercises, you know, that ask questions along these lines, because, because this is what I believe a 105 student is capable of learning. And then once you learn these, then you can go on to more interesting, more interesting algorithms and structures, you know, through which you, you know, you can use. All right. Then unit five goes into functions. So now in unit five, you know, we went and elevated, well, a few things really, we went and elevated all the goal of the goal of unit five is to elevate everything that we did in the previous units, so that you integrate them into functions. So with something like this, if I if down in Maine now, I say, maybe, well, I understand. Okay. Let's do it like this. I'm just going to really cut to the chase because the whole you what you should be able to do, let me put it this way, what you should be able to do at the end of unit five is you should be able to I'm just trying to save myself some typing time that I'll, I'll just type it up over here. Okay, so and just back to this, I've got other examples that I apparently come back over. I'm getting myself lost. All right, here we go. And what I'll do is I'll just quickly integrate this into a function. So everything that you do in in you in the previous units now by the time you get to unit five, you're able to take this code and you're able to integrate it within a function, let's say. So definition, and I'll call it f example, for example, it'll have some input be just to save myself some time be as local now. So it's a local variable. And then what I'll do is, is return this so that so what I'm doing very quickly here, you yourselves should be able to do at the end of unit five, which is basically to take to take any, any script that you've written to compute something, and then put it in the context of a function. So if I do something like this and say, well, this function is going to do what? Well, it's going to sum the values on the list. That's, that's the 30,000 foot view of what you want to get out of module five out of unit five, is that you want to be able to take any code, any chunk of code that you've written that accomplishes something or compute something and put it in the syntax of a function. So now you're all experts at the running sum, you should be able to take that code and chop it and drop it into a function. What's a function? Well, it's going to get, you're going to have the death line, the definition line for DEF define it. Here's the name of the function. Here are the inputs. In this case, there's only one input. The syntax for the function is left parentheses, right parentheses for all the inputs, the colon operator afterwards. And then finally, just as it was for ifs, while loops and for loops, the, there's, the indentation tells you, you know, what, what is being accomplished within the function, basically. And then we're returning s, that's going to be the sum. So if we go ahead and run this, now we compute the sum via a single function. Why? Well, because, because in a real program, you might have need for this code to reuse it over and over and over and over again. Why take this code and reproduce it, you know, 25, you know, this just, you know, why do this when, whenever you need the function, you can just call it with a, with a one liner. And that's what I really, so this is, this is your introduction to procedural programming is that you're writing a procedure, you know, or a function to accomplish some computation. Okay. And that's, that's what you want to leave with a 30,000 foot view. By the time you get to unified, you're able to take all the applications and, and convert them to, you know, to function, basically, anything that you've written previously. And what else? It's 1013. I'll say two more things, because I, I, you know, I've raised it, I don't know what the, it's, it's funny, you know, because I, I remember I was short of time in the unit on lists. I want to, I want to bring out the fact that, that you can use notation just very, very quickly. I want to say about slicing, because I had to race through this also, I remember having to race through this. But, but slicing is using this colon operator, basically, to index several values on a list at a time. So in this case, what I'm saying is, is that A is being constructed, maybe I'll go from, from list value two to five. So when you're slicing, just like for the range function, you'll have an initial index, a final index, a final index, and then you say what the step is. So maybe I'll go from, from starting at, at index zero to maybe element five, and I'm going to go in steps of two. And you'll see here that what happens is that this is element zero, that's element one, that's element two, I'm sorry, zero, one, two, three, four, and five, right? So this is saying go from, from element zero to element five, element, element five is eight, but if I add two, I'm going to go too far. So I'm only going to process elements three, five, and seven, because that's what this is telling me to do. So the slicing notation basically is used to grab multiple elements from a list or tuple or what have you. And, and the syntax usually is start, what the stop is, and then what the, what the index is. Here it says go from element zero, I apologize, to element four, because the maximum, it's the maximum, as Python always is, because you start counting at zero, it's the maximum element minus one. So this is element zero, one, two, three, and four. Okay. And so that's what gets printed out. And there's other tricks that you'll learn within the course. You can have negative indices, you're allowed to use a negative index to indicate the end of a list. So that's, that's nice to know as well. Because this way this, this absolves you of, of the responsibility of determining how long the list is, if your list has, you know, 10 billion elements or one billion elements, if you want the last element, you can use negative indices. So there's a good connection between slices between slicing and negative indices. And again, that's an important part of lists as well. All right, let's go on to to dictionaries now very quickly. So dictionaries were just more of the same at this point when you're constructing dictionaries at this point, when you construct constructing sets when you're constructing. So the tuple was the generalization of or change in the list. The tuple is like a list, except it's a constant, it's still an ordered container. Okay, it's still an ordered container. So you can still use indices. What you can't do is that they're not mutable, you can't change tuples. So tuples and lists have their place. If you understand lists, you naturally understand tuples, the only thing that you can do with tuples that you can do with lists is change the values. Then moving on to the concept of unordered containers, sets and dictionaries are unordered containers, they don't have an order into them, meaning that if you fill them up with data, you can't predict sort of how Python is choosing to store them because there's no order. So sets are performing or for performing set operations. And when you're performing set operations, it means that you understand set operations. So, you know, whether you do or you don't, it's kind of irrelevant. But one of the things that you should be able to relate back to is stuff that you may have done in introductory math courses where you learned about unions, where you learned about intersections, where you learned about possibly set differences, but definitely unions and intersections. When you take the union of two sets, it means you're taking everything in set A, everything in set B, mixing them together. And then Python doesn't have duplications. So, you would remove duplications. And to intersect, basically, you're asking the values that are commendable to A and B. And if you're subtracting one set from another set, then you're removing a set from another set. So, that's kind of like, you know, in some sense, it's like, well, I'll leave it alone. And so these operations, I think, are very important because they'll relate operations that you're interested in. If you have a set of things, and you wanted to know whether or not there was an element in that set, it's very easy to use like an in keyword to ask the question, is E in the set? You know, and like I said, unions and intersections are very common within like database operations. They're sort of the basics behind a lot of what one might do with regard to databases. So, it's good to know set operations. And that's why they're in the course. The next thing was to go ahead and move one level up. The problem with sets, well, they're not really a problem. It depends on the application, is that you can't index them. And the way that you can index sets and tuples, I'm sorry, lists and tuples, because they're not ordered. And but dictionaries are kind of the answer to what if I wanted to index a set, basically, I guess that's probably the best way that I could put it. And if you want to, if you wanted to index the set, you know, then maybe with something like this, just to show you how to initialize. So the dict keyword will be one way of initializing a dictionary. Or you can just do it by hand and do it this way as well. It's up to you, depending on what the application is. But in this case, you'll notice what I'm doing here with a dictionary is that you've got keys, and then you have values, you have key value pairs, the syntax is using the colon. For every value, there's going to be a key. So the dictionary uses the left squirrely bracket, right squirrely bracket notation, just like you would for sets. But it answers the question, well, what if I wanted to have an index for a set? How would I do that? Is that possible? And the answer is yes, it is. It is because what I can do is use the left bracket, right square bracket notation to say here, I'm interested in the second element. Well, the second element would like for a list would be an index, but you can't have an index for an unordered container, but you can if you have keys. So this notation with the left square bracket, right square bracket is not an index, but it's just asking you what the key is. You choose the key. The key can be anything. It can be a number, it can be an integer, it can be a string, it can be a character. And once you have that key, if you wanted to use it like an index, in this case, it almost looks like this is an index, but it is and it isn't. But it answers the question, if you had a set and I wanted to index it, how would I do that? So that's a nice way to use dictionaries. And then there's a whole host of examples in the course for writing structures and loops for cycling through and iterating through dictionaries based upon either the keys or the values, because a lot of times what you're doing with dictionaries is you're searching, that's why you have the dictionary because you set up the keys so you can find stuff. That's exactly why you're doing it. So there's tons of examples for using the keys to find values or to compare dictionary keys to see whether or not there's any overlap or uniqueness and all these types of things. So the dictionary kind of gives you in some sense the best of both worlds. It gives you an ability to index into an unordered set via the key and then it also gives you the ability to have set like operations. And that's why they're kind of in the same unit together. And I want you to see the bigger picture for those examples. And then Unit 7 is about file handling. So just a quick review of file handling because sometimes you might not just have data that's constructed within a program. So you want at least an introduction to understanding how file handling works. And basically what that means, so you'll see examples like this kicked around in the course that we said, well, for file handling, you've got to always got to remember an operating system has to do three things. It's got to be able to open and then it has to, you might either read or write to it, you're trying to edit, and then finally you have to close it. You have to close it. And those are the three operations, open and then whatever operation you want to perform and then you close it. And so you can see here, there's an open command. In this case, I'm planning on writing to a file. In this case, I'm planning on, and then I can actually close it and then open it again for a read and I can read it and do something like this. Assuming that replete doesn't see our AP out. Oh, there it goes. Okay. And so this means that I've created this file, remember there was the file window over to the left where the file gets created for you. And you can save that, you can download it. But this is kind of like your local disk drive, I guess, is the files, when did you can think about it like that? And so this set of instructions has written to a file, saved it, closed it, and then reopened it so that you can read it again. So a lot of the unit is just the gymnastics of learning how to create files, how to write data to those files, text data for starters, and then read that data or append files, and just kind of have that gymnastics of going back and forth. And all the methods that will be associated with reading and writing to files. And again, it's part of your arsenal of programming because you can't always assume that your data is going to be contained within your program. And it's not going to be. In fact, it'd be very common for you to have files sitting out on disk and you have to read them or write your data so that you remember them. So that's an important part of the course. Then moving on to other really, really kind of important topics. If you want to, if you really want to explore your ability and you really are interested in computer science per se, there's a beauty to computer science about algorithms for searching for strings and so forth. Let me come back over here. Every once in a while, you get a refresh replete. So I'll come back to that. So what I did was I tried to emphasize the, you know, in terms of writing code for regular expressions within the course within the regular expressions unit, it's good to become familiar with these special characters. And, you know, just tons of examples that we have for using these, because this is the meat. This is the, this is your vocabulary for writing regular expressions to do, to perform string searches. And, you know, once you have these down and you understand these, then you'll be able to, you know, search through. I think there's an example, if I remember correctly, the way that I set it up was actually the text for Moby Dick, which is just, you know, a novel and attempting to sort of go through there and perform string searches within that novel. Because that's usually, this is why you're doing, you know, these examples in the unit are onesy twosies, but really the way that you use these is that, you know, you're interested in going into a database to find somebody with an address or the right phone number or, you know, what have you, some characteristic within an enormous database that you don't have the time, you know, you would never want to do something like this by hand. So, so, so if you go down that application, if you ever happen to leave this course and get into the application, you know, you'll have this arsenal at your fingertips for performing, for performing string searches. And then the next part of the course again gets more practical. You know, this would be good for like interview type of stuff where you, you know, if you're really interested in getting like an introductory programming level position or something like that, you know, probably one of the things that I think a lot of people miss, you know, in academic circles oftentimes too often is that, you know, you're right code, but then you never have to test it. You never have to be sure if it works or not. And the whole point of the, and I'll come back to this with a final example, because I'll link this up to object oriented programming, but your code has to be bullet proof. It has to be able to work when you're not, when you don't know what the user is going to do. So your job really, if you're going to be a pro at this, in addition to creating test cases and obeying certain basic software engineering design principles, is that, is that you're going to have to have a way of trying to anticipate the types of errors that occur. And like if I were interviewing somebody for a program position, I would be interested in their understanding of algorithms and code and what their experience is. But, but I would really, really be interested in, in if they, if they understand how to make code that when other people use it, it's not going to blow up and explode. Because you don't want that to happen. I mean, again, there's just so many examples of companies that, you know, you get what I'm saying. And then, and then finally, and that's enough about that. Oh boy, I could spend another, couldn't I, but I'm not going to because, all right, anyway. And then, you know, lastly was the, you know, was the set of object oriented, oriented programming examples. And what I tried to do was to bring out to kind of mix together things, because I think this is, this is the major deal is, oops, I'll get my indentations right here. That's thanks. And they're still in lip. So here's an example, I feel, okay, I feel is the, is the real step in for, for recognizing the power of, you know, of an object oriented program. And the, the idea is, is, is the reason that I have a question like this, and I forget exactly where it is, but I know what I was, I'll let you know what I was thinking was that the real art to constructing exception handlers is, oops, I got my notation. The art to constructing exception handlers, okay, is, I'll try to accept that, I apologize. The art to constructing exception handlers is, if I can get my co construction back here, I got to do this in like two seconds, I just really want to fit this in. Let me come up here, it's going to take a couple of seconds. I don't, I don't, I'll leave it, I want to run this, I'll see if I have time to do it. But I want to make, let me make my point, is that, is that when you constructed exception handlers, that, I keep on messing up my indentation here, sorry, is that, is, is, is, it is an object, exception handlers are inherently object oriented, where you get to create your own exception handlers. Okay, and what that means is that, thank you, is that you as part of your object oriented construction, can construct handlers using object oriented techniques, and that's not really a point for this type of a course, it's introductory. But I tried to give an example question of, of, you know, how you might begin to approach a problem like that. And in this case, what I'm, what I'm trying to exercise, or at least try and show you, is that within these definitions, you can, you can invoke your own exception handlers, okay, you can actually invoke your own exception handlers. So in this case, what I've done is I've taken the init, if you remember, the init is a magic method that's going to automatically run to, to construct this rectangle class, let's say. And, and then what happens is that when you get your values of X and Y, that the try is going to try and set up values. But if you have negative values, they'll be initialized to these, to this set. And then you can have like an else, which says, well, if there is no error, then go ahead and do this. And then finally, you know, if there is an exception, then go ahead and run it like so. So what was I trying to do and show in this example, is that is, and I'm trying to figure out where the issue is here. I got some type of indentation thing going on here. Is that, is that I'm trying to show you that you can integrate, for instance, a try else and accept it within an object, within a class definition, so that if you attempted to run this, that that it would ideally catch the errors. And so, so it's 1030. And, you know, like I'm just kind of wrestling with, with the time now. But, but my point is this is that I don't want you to see Unit 9 as being separate from Unit 10, that really the next step beyond that is to sort of be able to integrate those two together, so that you're creating classes that actually can, can handle errors as well. So with, with regard to object-oriented programming, the key, the key ideas were that you want to know how to define methods, you understand attributes, you understand inheritance, there's a little bit about inheritance and how to have parent classes and child classes. And then like I said, with one final example, I think this may have been on one of the quizzes, is that I try and get you to sort of match together, you know, what you did in Unit 9 with what you're doing in Unit 10. So it's like 1032 right now. I don't know if anybody has any overarching questions, but I just want you to be able to see the bigger picture so that, so that you can, you know, walk away from the course, being able to, you know, understand a little bit more about programming than just, excuse me, and then just syntax. So are there any questions or is there anything, because I'm in sort of, this is like a fire hose, so yeah. No, I think it was good. I haven't seen any questions in the chat. I know it's a little past time, but if you have any, anything you need to go out, I have a meeting at 5.30, I got to get to. So if you have any last points you want to make, feel free. Yeah, not necessarily. Like I said, I just, I wanted students to be able to see the bigger picture, which is, you know, I think, as I said before, Unit 3 is very important for programming. And then as you begin to build upon that, it seems like there are these pieces that, well, how would I integrate file handling or how do I integrate regular expressions? Where do I, you know, and it seems like there are just these, you know, these kind of offshoots. But I would say that, you know, by the time you get to the object-oriented portion of the course, you're kind of seeing how to write methods. You're seeing how to write functions. You're seeing how to mix together different structures so that this is what I wanted to do. And that, and that, I'm trying to talk and do the program at the same time. And then finally, by the time you get to the object-oriented portion of the course, that you're able to look back and see the bigger picture, you're able to integrate everything that you've learned so that if you yourself wanted to create a class, you know, that would be, you know, for regular expressions or a class for file handling or, you know, a class to perform operations and then be able to handle exceptions, you really have that at your fingertips. There's a lot of power in these units that we just don't get a chance to exercise because they would be subject matters for a more advanced course, but you have an immense amount of material to work from. And I don't want you to kind of lose the bigger picture of what it takes to sort of become a programmer. There's a mixture of understanding a little bit of math, you know, you need to know some math, you need to know about numbers, you need to know about data processing, you need to know how to handle files, you need to, and when you mix all these things together at the end of the day, it means that you really have learned how to program. So I hope that that's really the transformation that I hope that takes place at the end of the units. And it doesn't take that long to make it happen, honestly. A course like this, you could easily finish, you know, within a month, two months at the outset, if you really committed yourself. And even less time, if you were very committed, you could do it within a couple of weeks. And then you'd be able to answer very, very basic questions, like even interview questions, you know, that somebody might ask an introductory level programmer. Again, you wouldn't have all the data structures and the algorithms and stuff. But just if you're saying, you know, I'd like to try my hand at doing some basic programming, that you have enough to actually do that, believe it or not, when you leave the course. So that's all I hope everybody enjoys it. I hope that you learn a lot. And that's kind of, you know, that's it. That's all I have to say. All right. Well, thank you very much, Dr. Sack. I think that was great. I hope everyone got a lot out of these. I know I know more now than I did before. So I feel I'm sure people who are smarter than me and working harder than me or I've learned a lot from this. So again, everyone, thank you for joining us. Dr. Sack, thank you again. Of course, everyone, make sure you check out the course at sailor.org. Again, links in the description below. And thanks for joining us. And if you're taking the course, good luck on the final exam. Yeah. And just, and you know, I want to thank Mike so much. I mean, you've been fantastic, so helpful. You've been the best second set of eyes. And I just, I can't thank you enough. You're great, really. All this technical stuff happened because of you. So none of it was me. Well, now I'm all embarrassed. But thank you very much. And again, good luck, everyone. Again, thank you again, Dr. Sack. And we'll see you.