 When you have a long complex line of code, especially say when you have a function call with many arguments or say a list literal or dictionary literal with many items, it's often desirable in such cases to take that one big line and spread it onto multiple successive lines to make it more presentable. While Python syntax is not freeform, it does have a special rule to allow for this, and that is the rule of open delimiters. If in your line of Python code you leave a delimiter open, whether an open parenthesis or an open curly brace or an open square bracket, then until the matching closing delimiter is encountered, Python's usual rules about indentation and one statement per line, those are temporarily deferred. So here, for example, if we have this line x equals and then this long complicated call to foo with many arguments, well, we can take whatever in the parenthesis there and spread it onto the succeeding lines however we wish. Only when Python encounters the matching closing delimiter, the end parenthesis here, do the normal indentation rules resume. So here after the end parenthesis, we can finish off the line with asterisk 98, but on the next line, the usual rules resume. So the call to bar has to be aligned, how you see it here has to be aligned with the statement which precedes it, which starts with x equals. Now when I have a function called with many arguments or a list literal with many items or a dictionary with many items, I like to format it like so, where all the successive lines are indented one level underneath of the line where it starts. And then I place the closing delimiter level with the start of the original line. And I do it this way because it mirrors how I format my curly braces in curly brace languages like JavaScript. Of course, you don't have to imitate this precisely, but I do strongly recommend that you settle upon some formatting style and stick with it. Again, be clear that this special rule applies not just to parenthesis, but to all delimiters. So here for example is a square brace being left open. And then that logical line doesn't end until you encounter the line with the matching closing square bracket. As another stylistic affordance to get around the usual rules of indentation, Python also lets you use a backslash at the end of the line to indicate that that line actually continues on to the next line. So think of it simply as a marker that says this line is not over yet, it actually continues on to the next line. So here for example we have one logical line but it's actually been written across three separate lines and it reads just simply x equals foo plus bar times 3 times 98. Now there is one important gotcha and that's if a line ends with a backslash. That line cannot also have a comment. If you put a comment on the same line, that's a syntax error. In my opinion you should really never use the backslash, it's just more trouble than it's worth. The open delimiter rule should really serve all of your needs. For yet another stylistic allowance, if you have a code block consisting of just one statement, you can write that statement on the same line as the block header. So here for example you see an if and a function definition both of which have just one statement in their bodies so they're just all written on one line. It's also allowed using semicolons to write multiple statements on one line. The only limitation that these statements must be just either expression statements or assignment statements, they can't be statements like an if statement or function definition statement. So here we have on one line three statements, x equals 7, an invocation of foo and then an invocation of bar. And those of course are executed left to right. So it's really just the same as writing them on three successive lines. It's just a stylistic choice here to put them on one line. And in fact you could use a semicolon to put multiple statements in a one line block. So here this if block has two statements, first a call to foo and then a call to bar. Like the backslash for line continuation, I never use multi statement lines or one line blocks. I think they're just bad style. Yeah, they do let you write your code a bit more compactly, but it's really not worth it. You're just making your code harder to read at a glance. A pass statement is a statement consisting of just the reserved word pass. And as the name implies, the pass statement does nothing. It passes over execution. So it's just a placeholder statement effectively. And the pass statement exists mainly because when you're writing out your code, you're writing your functions in your classes, when you just start out typically you leave just a stub of a function or a stub of a class. You know, you write class and then the name of the class colon and then you don't actually put a body there because you haven't written it yet. And yet you want your code to actually still compile because you have other stuff you want to test or whatever. So you can't leave that body, that class header, without anything there because that would be a syntax error. So when stubbing out our functions in classes, we just write them with pass statements and then we can run that Python module without getting a syntax error even if the code is incomplete. Many of Python's operators, including the basic arithmetic operators, come in a compound assignment form. Basically, it's the combination of the operator with an assignment. So if you see x plus equals y, that means add x and y together and then store the result of that addition in x. The purpose of this is simply that that's something we want to do commonly enough. It's nice to have a more compact syntax. In fact, this is the preferred syntax in Python for incrementing or decrementing a variable. So if you have a variable x and you want increment it, you write x plus equals 1. And if you want to decrement it, you write x minus equals 1. And Guido considered this sufficiently convenient that he decided Python doesn't need an increment or decrement operator like you have in JavaScript and C and all those languages. So there's no minus, minus operator or plus, plus operator. The basic operator methods all have a corresponding reflected operator methods which all have the same name except there's r in front. So say the add method has a corresponding reflected add method which is called radd. Python invokes these reflected operator methods in a scenario where first the two operands are of different types and if the regular method, the non-reflected method is first invoked and then raises the not implemented exception. So here for example, if we have the code 3 plus w, assuming w is the instance of some class we've defined, well first Python will invoke the add method of the int object and w will get passed as the argument. But the add method in this case will raise the not implemented exception because the standard int method isn't defined to add together a standard int object, the number 3 here, with some instance of a class you've defined. So it will raise the not implemented exception and that triggers Python to then invoke the radd method, the reflected add method of the w object with 3 passed as argument. So assuming in this class you have defined an radd method you can then have a defined behavior for what happens when the plus operator is used with instances of this class as the right operand. Now assuming you want there to be a defined behavior with the plus operator and instances of this type then you would give that type both an add method and an radd method, and generally in most cases you will want them to basically do exactly the same thing, the only difference is that the radd method is invoked when the instance of the class is only the right operand. Normally we assume that a plus operation is commutative, that's how addition is defined right, it doesn't matter if you write a plus b or b plus a. However with some types you might define you might decide that you want there to be some non commutative behavior so you might want 3 plus w to do something different than w plus 3. So that's why we have this reflected add method because sometimes you want there to be different behavior. If instead Python just assumed these operations should always be commutative then we wouldn't have the reflected operator methods, Python would just after not implemented is raised, it would just invoke the regular add method of the right operand. But Python decided otherwise, it decided that sometimes we'll want to have non commutative operations so that's why it has reflected operator methods. Recall that in JavaScript we can define a function by writing not just a function statement but also by writing a function expression. And we can actually do the same in Python is just that whereas we define functions as a statement with the def statement for a function as an expression we use a different reserved word lambda. Why lambda? Well, lambda is a symbol used in lambda calculus that denotes a function. So that's the thinking behind the name. The unfortunate thing about Python's lambda is that it's much more restricted than a full on def statement. When you write a lambda function the body of the function can only consist of a single expression statement. You can't have any other kind of statement and it can only be one. The real reason for the syntax is that if you want to include multiple statements or to have other kinds of statements like ifs and so forth in the body of the lambda function that would require using indentation to denote them and that just doesn't make any sense in the context of an expression. So if there's one real downside to Python's indentation-sensitive syntax I would say this is it. This is the one thing I miss when I program in Python rather than JavaScript. The ability to write any function as an expression. Of course, the work around of this is simple. Any time you want to have a function that needs more than just a single expression statement in the body you just write that as a regular function definition and then pass it by name where you need it. But what I think is surprisingly bothersome about having to do that is it means you have to give the function a name. You don't have to be a believer in wherever you can. Get away without having to give things names because the more names you have in your code the more likely you're going to give them bad names that aren't very meaningful and that actually make the code harder to read and harder to understand. In any case, looking at this example here first we have a regular function definition that's defining a function foo with the parameters x and y and it just adds those two parameters together and returns that result and then you have the same thing with the function object returned by the lambda expression here is really exactly the same as the function object that gets assigned in the def statement to the variable foo. Notice that the parameters in lambda are listed before the colon and they're not included in parentheses. To define a function with no parameters with lambda you just put the colon immediately after the reserved word lambda. So here again same idea we're defining a function with the def statement that takes no parameters and just prints high and then we're expressing precisely the same thing just expressed using lambda.