###################################################### # CptS 111, Fall 2012 # Lecture 09 # 2/8/2012 # John B. Schneider # Diary of in-class presentation. ###################################################### Python 3.2.2 (v3.2.2:137e45f15c0b, Sep 3 2011, 17:28:59) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> ################################################### ... # We have seen simultaneous assignment. ... # In simultaneous assignment we have comma-separated expressions ... # to the right side of an equal sign (assign operator) and an ... # equal number of "lvalues" to the left side of the equal sign. ... >>> x, y = 10, 20 # What we have seen before. >>> 10, 20 # This is what is to the right of equal sign. (10, 20) >>> x, y # This shows assignment worked. (10, 20) >>> x, y = y, x # Here is how we can swap the values. >>> print(x, y) 20 10 >>> z = 30 # Can have any number of values... >>> x, y, z = z, x, y >>> print(x, y, z) 30 20 10 >>> >>> # When we have a comma-separated collection of expressions, ... # if they are not enclosed in anything or if they are enclosed ... # in parentheses, they form a tuple. ... # ... # A tuple is like a list. It is a collection of ordered data. ... >>> [10, 20] # This is a list. [10, 20] >>> 10, 20 # This is a tuple. (10, 20) >>> (10, 20) # This is also a tuple -- same as previous statement. (10, 20) >>> # We have been doing simultaneous assignment with tuples. Let's ... # add parentheses to the right side to indicate this more ... # explicitly. ... >>> x, y = (10, 20) >>> x, y (10, 20) >>> >>> # The difference between tuples and lists is: ... # ... # * lists are mutable -> elements can be changed. ... # * tuples are immutable -> elements cannot be changed. ... # ... # So far we have used lists to collect data, but we haven't used ... # one important feature of lists: we can modify the individual ... # elements. Let's see how this works. ... # ... # First, let's demonstrate that a tuple behaves like a list in ... # many ways. ... >>> xt = (10, 20) # Create a tuple. >>> xt (10, 20) >>> xt[0] # Can index elements just like a list: first element. 10 >>> xt[1] # Second element. 20 >>> for item in xt: # Can use a tuple as the iterable in a for-loop. ... print(item) ... 10 20 >>> xl = [10, 20] # Now create a list. >>> print(xl) [10, 20] >>> xl[0] # First element of list. 10 >>> xl[0] = 40 # Assign new value to first element of list. >>> xl # See that list changed. [40, 20] >>> xt # Now back to tuple. (10, 20) >>> xt[0] = 40 # Try to assign new value to first element. Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment >>> >>> # Now, let's return to simultaneous assignment. We know it works ... # with tuples, but it works with lists too! ... >>> x, y = xl >>> x, y (40, 20) >>> a, b, c = ["hi", "greetings", "salutations"] >>> print(a, b, c) hi greetings salutations >>> >>> # Question: Is the left side of "a, b, c = [...]" in the previous ... # statement a tuple? ... # Answer: No, it is a collection of lvalues and that does not form ... # a tuple. A tuple is a comma-separated collection of ... # *expressions*. The left side does not contain expressions. ... # ... ################################################### ... # We've now seen why we say "lvalue" instead of "variable" when it ... # comes to describing what can appear on the left side of the ... # assignment operator. When we assign a value to an element of a ... # list, we are not assigning it to a variable -- we're assigning ... # it to an element of the list. The lvalue consists of the ... # variable name and the index of the element. ... >>> xl # A list with variable name xl. [40, 20] >>> # The following assigns 111 to the lvalue xl[1] which is the ... # second element of the xl list. ... >>> xl[1] = 111 >>> xl [40, 111] >>> # If we assign something to a variable, then whatever the ... # variable used to point to is lost. (If the variable didn't ... # previously exist, it is created.) ... >>> xl = 122 # xl is now the integer 122. Previous list is lost. >>> xl 122 >>> >>> # Let's create another tuple and again demonstrate that an element ... # of a tuple cannot be used as an lvalue. ... >>> xt = (10, 20, 30, 40) >>> type(xt) >>> xt (10, 20, 30, 40) >>> xt[1] = 40 Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment >>> ################################################### ... # Accumulators: ... # - initialize a variable ... # - modify the variable in a loop based on its previous value. ... # ... # The sum in summer() from the previous lab was an accumulator. ... # ... # Consider an example: We want to calculate the values: ... # ... # x**2, x**4, x**8, x**16, ... ... # ... # But, we want to do this using an accumulator and not with the ... # built-in exponentiation that Python provides. Let's do this ... # with successive squaring of the previous value. ... # ... # Define a function to square its argument. ... >>> def square(x): ... return x * x ... >>> # Now, let's square successive values, but do it "by hand" instead ... # of with a loop. ... >>> x = 2 # Initial value. >>> square(x) # Square it. 4 >>> x = 4 # Reset x and square again. Give fourth power of original. >>> square(x) 16 >>> x = 16 # Reset x and square again. Give eighth power of original. >>> square(x) 256 >>> x = 256 # Reset x and square again. Give 16th power of original. >>> square(x) 65536 >>> x = 65536 # Reset x and square again. Give 32nd power of original. >>> square(x) 4294967296 >>> >>> # Now, instead of doing things by hand, let's perform this ... # calculation with a loop, but go a little further. (This is very ... # similar to what you have to do for the next homework ... # assignment!) ... >>> x = 2 >>> for i in range(6): ... x = square(x) ... print(x) ... 4 16 256 65536 4294967296 18446744073709551616 >>> >>> # To be goofy, let's go a little further... ... >>> x = 2 >>> for i in range(11): ... x = square(x) ... print(x) ... 4 16 256 65536 4294967296 18446744073709551616 340282366920938463463374607431768211456 115792089237316195423570985008687907853269984665640564039457584007913129639936 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216 32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638215525166389437335543602135433229604645318478604952148193555853611059596230656 >>> >>> # For the next homework you have a function that generates values ... # that vary between 0 and 1. For parameters in a particular ... # range, the values are chaotic, meaning there is no way to ... # predict in advance what the next value will be. You simply have ... # to calculate it in see. These kinds of functions are quite ... # important! We will hopefully revisit the use of this function ... # in a future assignment dealing with cryptography. ... >>> >>> ################################################### >>> # return vs. print() ... # ... # Recall: return doesn't print anything; and print doesn't return ... # anything. ... # ... # We considered various versions of a file in IDLE that helped ... # illustrated this. ... >>> s = """ ... Version 1: ... ================================================================== ... def square(x): ... return x * x ... ================================================================== ... If we store and run this, the function is defined but no output is ... generated. We need to explicitly call square() to test it. ... ... Version 2: ... ================================================================== ... def square(x): ... return x * x ... ... square(10) ... ================================================================== ... When we store and run this version, the function is defined *and* ... called, but no output is generated. square(10) will return 100, ... but we haven't told Python to do anything with that return value. ... So, it is simply discarded. ... ... To further illustrate this, consider this file/program where there ... is a statement that calculates 1 + 1, but we don't tell Python to ... do anything with whatever that evaluates to. ... ... Version 3: ... ================================================================== ... def square(x): ... return x * x ... ... 1 + 1 ... square(10) ... ================================================================== ... Again, when this is run, no output is produced, but the square() ... function is defined and available for us to use. ... ... Finally, in the next version, we see output since we use print() ... function to display results. ... Version 3: ... ================================================================== ... def square(x): ... return x * x ... ... print(1 + 1) ... print(square(10)) ... ================================================================== ... """ >>> # To further emphasize the difference between print() and return, ... # let's define a function that prints the square of its argument. ... >>> def squarep(x): ... print(x * x) ... >>> squarep(10) # 100 on following line is from print() in squarep(). 100 >>> square(10) # 100 on following line is return value of square(). 100 >>> 5 + square(10) # Can use return value in an expression. 105 >>> # squarep() doesn't return anything so it cannot be used in an ... # expression. ... >>> 5 + squarep(10) 100 Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'int' and 'NoneType' >>> >>> ################################################### ... # Test #1: ... # ... # * Practice tests have been posted. ... # There are some slight differences this semester from ... # previous semesters in terms of what has been covered. ... # For example: ... # o Didn't have append() and list construction in previous years. ... # o Didn't have divmod() in previous years. ... # So, don't count on your exam looking just like those of ... # previous years! ... # ... # * Closed computer. ... # ... # * Will provide summary sheet(s). ... # ... # * Can bring one sheet of your own notes. ... # ... # * Will post sheets by the weekend. ... # ... # * 50 minutes! Work on exam the entire time. ...