There is no p10c.sql A brief review of tuples and lists: Lists: Lists are used in the way that most programming languages would use Arrays. You "declare" a List by assigning it some list data. That can even be the empty list: li1 = [] li2 = [1, 2, 3, 4, 5, 6] Lists are indexed starting with 0. You can access lists like you normally access an array: li2[0] --> Returns 1. li2[5] --> Returns 6. The length of a list is found with the function len() len(list2) --> 6 As opposed to arrays, Lists can contain different data types: li3 = [4, 'ab', 5] Lists can even contain sublists: li3 = [4, 'abc', 5, [9, 10, 11]] The most interesting list operation is called "slice." While there is an explicit call to slice(), most of the time you do slicing by putting appropriate expression between [ and ]. For example: li3[0:3] -> [4, 'abc', 5] The first number - the 0 - is the starting index. The second number - the 3 - is the ending index. Important: The first number - the 0 - is inclusive. The second number - the 3 - is exclusive. Always. So li3[0,3] returns the list consisting of li3[0], li3[1], li3[2] A slice of one element is different from the element. li3[0:1] ---> [4] Note that this is DIFFERENT from li3[0] ---> 4 In the first case, a list is returned. In the second case, an element is returned. Now there are shortened versions of slicing. li4 --> ['a', 'b', 'c', 'd', 'e', 'f'] li4[:2] --> ['a', 'b'] In other words, li4[:2] means li4[0:2] !!!!!!!!!! Now to the explicit slicing operation slice(). li4 --> ['a', 'b', 'c', 'd', 'e', 'f'] sliceobject1 = slice(1,3) Note that there was a COMMA above, not a COLON. It's a function call. li4[sliceobject1] --> ['b', 'c'] A negative start number in a slice will return the last element: >>> li4 ['a', 'b', 'c', 'd', 'e', 'f'] li4[-1] --> 'f' Now it gets more complicated. li4[-3:-1] --> ['d', 'e'] li4[-1:-3] --> [] li4[3:1] ---> [] This gives you the whole List: Always. li4[0:len(li4)]) Slicing allows a third parameter. li4[0:6:2] --> ['a', 'c', 'e'] So the third parameter - the 2 - means show every second element. It starts with the 0th element, followed by the 2nd element followed by the 4th element, etc. We are now returning to li2. li2 --> [1, 2, 3, 4, 5, 6] li2b = li2 li2b ---> [1, 2, 3, 4, 5, 6] List variables are POINTERS. This is important!!! Look: We are changing li2: li2[3] = 'x' li2 --> [1, 2, 3, 'x', 5, 6] Now look at li2b li2b --> [1, 2, 3, 'x', 5, 6] It was ALSO CHANGED. When a list is passed as parameter to a function and then changed in the function, this changes the list in the main program!! def testalist (li): li[4] = 'Z' testalist(li2) li2 --> [1, 2, 3, 'x', 'Z', 6] Again, this is not obvious. What if you want to define a large empty array? That's actually not obvious either. The most basic way to do it is like this: li5 = [] for i in range(10): li5.append(i) li5 --> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] But there are many syntactic variations, some of them quite unusual. For example: li6 = [0] *10 li6 --> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] Stackoverflow has a whole article about this: https://stackoverflow.com/questions/10712002/create-an-empty-list-in-python-with-certain-size Why is it called a List not an Array? Maybe because many of the standard list operations are allowed for these lists. Now we are treating them like objects. Examples: li2.append(99999) li2 ---> [1, 2, 3, 'x', 'Z', 6, 99999] li2.reverse() li2 --> [99999, 6, 'Z', 'x', 3, 2, 1] IMPORTANT: This is a destructive change. You have changed li2 itself. Not a copy of it. (In other programming languages this is different.) That's enough about Lists. Now about Tuples. Tuples: Tuples are in many respects like lists. The three important points about tuples are: 1) Python uses Tuples internally for several purposes. So you will encounter them. 2) Tuples are initialized with round parentheses. But other than that, confusingly, for element access and slicing you still use [ ]. See example: tup1 = ('z', 'y', 'x', 'w') tup1 -> ('z', 'y', 'x', 'w') tup1[0] -> 'z' tup1(0) -> ERRRRROR Why is this so? Because a name followed by () is considered a function call. You CAN define a FUNCTION tup1 and this will work. def tup1 (x): return x tup1(9999) --> 9999 So elements in the tuple data structure tup1 cannot be accessed with (). But you CANNOT have a tuple variable and a function with the same name tup1. So above definition of the function tup1 wipes out the Tuple tup1. So I have to recreate the tuple tup1. Tuples can be sliced just like lists: tup1 = ('z', 'y', 'x', 'w') There is no error message that you are losing the the function tup1!!! tup1[0:4:2] --> ('z', 'x') 3) Tuples cannot be changed. See example: tup1[3] = 4 --> ERRRROR The technical term that you will hear a lot is Tuples are IMMUTABLE. ------------------------- While we have managed to implement everything from PL/SQL, except for integer out parameters, in Python there are may powerful data structures besides Lists and Tuples and functions processing those data structures that we did not cover and cannot cover. See http://docs.python.org/3/library/stdtypes.html There are complex numbers iterator range (we saw a little of that) str (we saw a little of that) bytes dict (dictionaries, sort of like hashes in Java) Furthermore, Modules, Classes, Functions, Methods, Code Objects, Type Objects, etc. are also considered data types. We cannot cover any of this.