This is a long handout -- so I'm planning to use it for two classes (the second class and the third class). I'll also ask people to try only the homework problems involving things we get to during the second class. [Postscript: I think it will actually be three classes, the second, third, and fourth.] [Post-postscript: There is also an appendix to this handout based on things which we actually discussed in the second class -- related to the print statement.] Data types ---------- Information processed by a computer is usually called "data". (See etymology/culture note.) Data is (or are) organized inside a computer in various ways. "At bottom", all the information processed by a computer is represented in terms of numbers. I don't personally like to say "in binary", because it can lead to some misconceptions. It's true that the particular implementation of modern computer hardware uses binary (and that this affects some programmers and engineers). But the really fundamental conceptual point is that the information in the computer is represented as a bunch of numbers. The operations of the computer are implemented in terms of operations performed on numbers. You can certainly store numeric data (like your checkbook or budget or bank account) in a computer. But the numbers in a computer can also represent or "code for" other kinds of information -- like text, or pictures, or audio or video data. (See etymology/culture note on "digital".) The fact that the information inside a computer is physically represented in binary is significant sometimes, for certain applications. It's certainly relevant to understanding things like why there are 8 bits in a byte, why there are 256 different ASCII characters, why lowercase and uppercase "A" are exactly 64 positions apart on the ASCII chart, why a kilobyte is 1024 bytes and a megabyte 1048576 bytes instead of 1000 and 1000000, why your computer monitor might be able to display 65536 different colors at once (perhaps from a palette of 16777216 possibilities?), why your computer has 16 or 32 or 64 or 128 megabytes of RAM... On the other hand, for most purposes, including most programming purposes, it's usually sufficient to know that the information inside a computer is numbers, without worrying about the physical representation on the numbers (any more than it matters whether you do arithmetic in pen or pencil, or whether you are right-handed or left-handed). In a high-level language like Python, you can do lots of things without worrying about the computer's internal representation of the data. (For example, you can display a picture from a graphics file without knowing anything about how the graphics file works internally! To use a simpler example, you can print out a text string without knowing anything about how the content of that string is stored inside the computer's memory.) In a low-level language, like an assembly language, you might well need to worry routinely about _exactly_ how the computer "codes for" particular sorts of data. One of the features of the abstraction provided by a high-level language is that you can write programs which act directly on higher-level objects. So, for example, in Python we can talk directly about the length of a string, or about combining strings, or even potentially about objects like a network connection, a sound file, or a window in a graphical interface. In lower-level languages, we would have to spend more time paying attention to the implementation details, like the arraangement of bytes in memory. In Python, each kind of data has a "type", which affects how it is interpreted or processed, and what kinds of things you can do to it. (I think it makes sense that you can't do the same things to different kinds of data. After all, you can imagine asking whether letters are upper case or lower case, but what about numbers? And you can imagine asking whether numbers are odd or even, but what about letters? You can multiply numbers, but you can't multiply colors, or add three to a color. So I think the principle that "certain operations work only on certain types of data" makes good intuitive sense.) Integers or whole numbers are one type -- like 5, or -29. Floating point (decimal) numbers are another -- like 3.141592 or 9.87654321. Complex numbers (mentioned last week) are another. There are also "long integers" or "big integers", about which more later. All of these are considered "numeric types", and in Python, unlike some languages, you can combine any numeric type with any other numeric type in doing arithmetic. For example, you can do 5 + 8.7 even though 5 and 8.7 are actually considered different types. They're both numeric, so Python lets you use both together in arithmetic. (Why do we make the distinction between these types, then, if they can be used together? Well, it matters in certain special cases. For example, division of integers is treated differently from division of floating point numbers. How does Python's value for 1/2 differ from its value for 1.0/2.0? How would you explain the difference? How does Python seem to deal with division when both of the numbers involved are whole numbers?) We've also encountered the string type, which holds a text string: "hello there" "This is the forest primeval" "Congress shall make no law respecting an establishment of religion, or forbidding the free exercise thereof, or abridging the freedom of speech, or of the press, or the right of the people peaceably to assemble, and to petition the government for a redress of grievances." "You see here a lantern and a sword." "Q" "" (this is called the "empty string" because it doesn't contain any characters) ":-)" A string could potentially be very long. I wrote a one-line program which constructed a string of hundreds of thousands of characters, and Python handled this with no problem. Some programming languages have separate "character" and "string" types (so that a single letter or other character is one type, and a string, or sequence of characters, is considered another type). There are good implementation reasons for this and perhaps good programming reasons, but Python (like BASIC and like many high-level languages) _does not distinguish between a "character type" and a "string type"_. (Unless you were wondering about this or you're used to programming in another language, you probably don't need to worry about it much. However, this lack of distinction is unusual from the point of view of lower-level languages. In general, when programming in lower-level languages, there are more distinctions you have to remember, which sometimes translates into "more possible errors you can make".) Lists ----- Most languages have numeric types and string types, and some languages have other types as well. Python has several more, only some of which we'll discuss right now. One is the list type, which is represented by enclosing a bunch of items in brackets, with the items separated by commas: ["first amendment", "chocolate cookies", "Boston", "Python"] ["Jack Valenti", "Hillary Rosen", "Patricia Schroeder"] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ["this", "is", "a", "list", "of", "strings"] ["CIPA", "COPA", "COPPA", "CPPA"] [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] When we have combined a bunch of things into a list, we will be able to treat them as a unit (for example, storing or retrieving the list _as a whole_), and also to do other things to them. Notice that Python can print a list using the print statement. But there's a big difference between [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] and "[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]" What's the difference? The data items inside a list can, in Python, be of any type. One implication of this is that lists can be nested -- you can have lists inside of lists. [["EFF", "ACLU", "EPIC"], ["MPAA", "RIAA", "AAP", "WIPO", "FRC"], ["legislative", "executive", "judicial"], ["http://slashdot.org/", "http://www.eff.org/"," "http://cryptome.org/", "http://www.aclu.org/", "http://www.loyalty.org/~schoen/"], [2, 4, 6, 8, 10, 12, 14, 16, 18]] This "outermost" or "top-level" or "encompassing" list contains five elements (_not_ twenty-five). Each of its elements is itself a (separate) list: one list of organizations, another list of organizations, another list of branches of the U.S. government, another list of URLs, and finally a list of some even numbers. Most lists used in Python programs are not nested inside other lists, but it's worth keeping in mind that this is possible; types which can contain other data objects are prevalent in Python and very potentially useful. We'll see some examples in the future. And advanced programmers often find multiply-nested data structures convenient because obtaining a particular fact from them can be very concise (often a single line of code). In LISP, where the list data type is a basis for most other complex data types, nested lists are absolutely routine; it would be unusual to see a LISP program which did not involve nested lists in some way! This approach is useful for many reasons, but Python has a greater diversity of data types and lists aren't of such paramount importance for us. Quick quoting questions ----------------------- What do these mean? What are the single and double quotes for (in general)? print "I'm nobody, who are you?" print "Are you nobody too?" print "Then there's a pair of us -- don't tell." print 'It is an ancient mariner,' print 'and he stoppest one of three.' print '"By thy long grey beard and glittering eye,' print 'now wherefore stopp\'st thou me?"' print '|\\-/|\\-/|\\-' print '"' print "'" print '\'' print "\'" print "\\" print '\\' print "\Hello" What is the backslash for, and how does it work? Python's string quoting features, like the corresponding features in some other languages, can be very complicated. On the other hand, most people can get by with a basic understanding, because it's not likely that they'd have an application for the full power of Python quoting. Many languages have their own rules for quoting or "escaping" (causing some symbol to be interpreted "literally", which is to say "as letters" or "letter by letter", which is what "literal" means in Latin, rather than according to the symbol's meaning _to the programming language_). Some languages double quotes in order to escape them, like Pascal, where you can write things like writeln('Imagine there''s no countries, it isn''t hard to do.'); (That isn''t the way Python does it!) If you were making up your own programming language, how would you deal with quotes? What problems do you think you might run into? Variables --------- In Python, unlike some languages, any variable can hold any type of data. So a given variable could be used to store a string at one time and a list at another time (if you had some reason to do that). A variable is a name for a value, and you can assign a value to any variable (subject to some rules about what is a legal variable name -- for example, a variable name must start with a letter, and not contain certain punctuation characters). To store a value in a variable, you use what's called an assignment statement. In Python, this looks like this: variable = value For example, pi_approximation = 3.14159265358979323846264338327950288 or opening = "May it please the court." After the assignment statement has been processed by the interpreter, we say that the variable has the value, or the value has been stored in the variable. This means that the variable's name can now be used anywhere the value could have been used. print 5 + 4 works the same as xyzzy = 4 print 5 + xyzzy Getting used to storing things in variables and retrieving and using their values is an important part of Python programming. What does s = "hello" l = len(s) mean? What does i = i + 1 mean? (This sort of statement shows up in almost _every_ programming language.) For the benefit of people who are not accustomed to programming, there are various metaphors for variables ("a variable is like a box!" "a variable is like a drawer in a filing cabinet!" "a variable is like a name tag!"). Some people find these helpful and some people find them distracting; I don't intend to use these metaphors, and will simply say "the variable x has the value y" or "the value of x is y" or "y was stored in x" or "y was assigned to x" to refer to what's happened after the interpreter encountered the statement "x=y". If you do find variables confusing, please don't hesitate to ask questions about their use. Variables are an essential part of programming, and a source of much of its power. They're the principal way that programming languages let you store something in a computer's memory and refer to it later on; this, in turn, allows you to teach a computer to make and act on decisions about things it's been told before. (People who lack reliable short-term memory, often because of tragic diseases, have a difficult time doing complex reasoning or complex tasks. This is also the case for computers -- to do sophisticated things, they need the ability to remember facts, or "data", as well as where they are in a process, which is often called "state information" or "state".) Lists and slices ---------------- One data type we've just mentioned, built in to Python (there is also a way to define your own, which we'll get to eventually), is called a list. The list type is an example of a "sequence type". A sequence type is a data type made up of some number of elements, which are in a fixed order. The list is the most obvious example. In Python, a list can be made up of elements of _any_ type. (Some languages which have lists require that everything in the list be the same kind of object -- for example, a list of numbers, or a list of strings, or a list of open file objects, but not a list which combines several of these. In Python, however, the list's elements can be _anything_ and don't necessarily have to have any similarity to each other.) There are other sequence types in Python aside from the list; we'll talk about some of them later on. One of the nice things about the idea of a sequence type is the ability to do iteration over the sequence -- that is, you can describe a certain action and then say that the same action should be applied _for each element in the sequence_ in order. This is an extremely common task in programming, and all programming languages have some concept of iteration over a sequence (sometimes also called "iteration _through_ a sequence"), although the way you do it in a given language may vary widely. We'll talk about iteration next class. Another thing about Python sequence types is that you can access particular _parts_ of them in a convenient way. For example, you can ask Python for the first element in a sequence, or the last element, or the 13th element, or the 5th, or the 7th from the end. Or you can ask for a "subsequence", which just means a new sequence made up of particular elements. For example, we could ask Python to give us the 9th through 18th elements of some list; that would give us a new list containing just those elements (in their original order). You can store a list in a variable. Here's an example: directions = ["north", "south", "east", "west"] print directions[0] print directions[1] print directions[2] print directions[3] print directions[4] You might notice that Python starts counting the elements with 0. (An element's "element number" is also called its "index", or, more rarely, its position.) So somewhat confusingly, the first element, in the sense of "the element at the very beginning", has index 0, not 1. The second element, the one after that, has index 1, not 2. And of four elements, the last one ends up with index 3, not 4. (If you tried typing the example into Python, you'll see that it's designed to elicit an error at this point, because there _is no element with index 4 of the list stored in the variable "directions"_.) Why do computers often start counting with 0 instead of 1? It's a long story, which I'd like to tell. But it's important to keep in mind when you're dealing with Python sequences -- the indexes start with 0! The indexes start with 0! If you had 100 numbers in a list, the first number would have index 0, and the last number ("the 100th number", in the usual way of talking in English) would have index 99. Forgetting about this and messing up is one example of what's called a "fencepost error", a very common mistake in programming. The name of that mistake comes from the fact that fences, like picket fences, have a difference number of fence posts (pickets) and fence segments: |--|--|--|--| four segments (beams), five pickets |--|--|--|--|--| five segments, six pickets |--| one segment, two pickets So in programming, you sometimes count fenceposts (items) and sometimes beams (transitions or "steps" in going from one item to a new item). The number of each is always off by one relative to the number of the other, which is why a fencepost error is often called an "off-by-one error". As a programmer, you will probably commit many fencepost errors in your life. I made this mistake not one but several times while writing the linguistic diversity hand-out for the first class -- in several different programming languages! Anyway, to get accustomed to how Python assigns indexes to the elements of a list, try it out: currency = ["penny", "nickel", "dime", "quarter", "half-dollar", "dollar"] print currency[1] ----> "nickel" print currency[3] ----> "quarter" print currency[6] ----> error print currency[0] ----> "penny" I call this the specific-element notation, because it lets you access one specific element in the list, based on its location. Which element index would you ask for to get Python to print "dime"? How about "half-dollar"? How many elements are in this list? What's the highest index, and the lowest? Python has a function called range which gives you a list whose elements' values are equal to their indexes. (Does that make sense to you?) For example, >>> print range(5) [0, 1, 2, 3, 4] You get a list with five elements; the element at index 0 is 0, at index 1 is 1, at index 2 is 2... range(n) always gives you a list with n elements, which are numbered 0 through n-1, just like their indexes! There is also a way to start at the _end_ of the list, using negative numbers: print currency[-1] ----> "dollar" (-1 is the last element) print currency[-2] ----> "half-dollar" (-2 is the one before that) In general, somelist[-n] gives the nth element from the end, counting toward the beginning. So somelist[-1] is always the last element, however many elements there are; it's exactly the same as somelist[len(somelist)-1], which is exactly how Python interprets it. (You can think about it that way if you want -- or any other way which makes sense to you.) So the specific-element notation lets you look up any particular element in any list, by position (from either the beginning or end of the list). There is also a "slice" notation which lets you take a slice out of a list, to extract part of that list. The slice notation is extremely useful, but sometimes difficult for new Python programmers to remember. It looks like somelist[start:stop] and the important rule is that the start is inclusive (that element will be included as part of the slice) and the stop is exclusive (that element will not be included as part of the slice). If this description confuses you, try it out. (Some parts of programming may be best learned through formal definitions, and others through experiment. I can describe how slices work now, but I only learned to use them by trying some examples and then writing useful programs which used slices.) For example, q = ["using", "Python", "slices", "is", "fun", "for", "everyone"] print q[1] ---> "Python" print q[2] ---> "slices" print q[3] ---> "is" print q[1:3] ---> ["Python", "slices"] Note that the slice taken out of the list is a new list, and it includes the elements starting with the element with index 1 ("Python"), and going up to, but not including, the element with index 3. print q[1:5] ---> ["Python", "slices", "is", "fun"] Now the slice goes up to, but does not include, the element with index 5, which is "for". How about q[1:2]? How about q[4:7]? How about q[1:1]? Do these make sense to you? What is ["this", "thing", "called", "love"][3:4]? Here's another interesting example which builds a list using a variable -- which contains a value provided by the user. print "Who are you?" you = raw_input() friends = ["Plato", "Jonas Salk", "Richard Stallman", "Trey Hyde", you] print "My friends are" print friends print "How many friends do I have? I have" print len(friends) Do you see that we could make this code shorter by writing it print "Who are you?" friends = ["Plato", "Jonas Salk", "Richard Stallman", "Trey Hyde", raw_input()] print "My friends are" print friends print "How many friends do I have? I have" print len(friends) and it would still work the same way? Here's a further thing you might want to learn about sequence types, since I've only given you one sequence type example so far (lists): Strings are sequence types too (!) ---------------------------------- Everything you learned about slices (and everything you will learn about iteration) applies to strings as well as to lists (and also to any other sequence types you may encounter). What are the "elements" in a string when you consider the string as a sequence? They are the individual characters. The string "Hello" is made up of five characters, in a certain order. The "H" is the first character, the "e" is next, and so on out. Since Python considers strings to be built out of sequences of characters in this way, you can use the specific-element notation to ask for a particular character. Or you can get a particular range of characters out of the middle of a string (or from its beginning or end) using the slice notation. So for example 0123456789 n = "sethschoen" print n[1] ---> e print n[0]+n[6]+n[7]+n[8]+n[4]+n[2]+n[1]+n[9]+n[5]+n[3] print n[6:9] print n[0]+n[6:9]+n[4]+n[2]+n[1]+n[9]+n[5]+n[3] This anagram of my name is due to Bennett Haselton of Peacefire. You might want to add a +" "+ between n[8] and n[4]. Can you write a program which asks the user for her first name and then prints the third letter of it? Comp: What is your name? User: Seth Comp: What is your quest? User: I seek the Holy Grail! Sorry, wrong program. Let's try again. Comp: What is your name? User: Seth Comp: Seth, the third letter of your name is 't'. How would you write a program like that? What will happen if Jo Hastings (of HavenCo) tries to use your program? Concatenation ------------- Two items of the same sequence type (so, for example, two strings, or two lists) can be concatenated. (See ety-cultural on "concatenate".) 2 + 2 ------> 4 "foo" + "bar" ------> "foobar" (one big sequence) ["good", "morning"] + ["to", "all"] -----> ["good", "morning", "to", "all"] (one big sequence again) ["weird"] + [5,6,7] + ["hi"] ----> ["weird", 5, 6, 7, "hi"] "string" + ["a", "list"] -----> error (unlike types can't be concatenated) "string" + 7 ----> error (ditto, and even more, 7 isn't a sequence type, but rather a number) which is why we couldn't do things like print "I am " + age + " years old" even though it would be convenient. [There is a way to convert a number into a string whose text is the usual representation of that number -- it's called the str function, and I mentioned it last time. It's one of several functions which can convert from one type to another, in this case from a number to a string. So you could say "I am " + str(age) + " years old" to get the behavior that you probably want; the use of the str function causes the number to get converted into a string.] [To convert a string into a number, you have to choose what kind of number type you want -- use the int function for a whole number, and the float function for a floating point number. This is very handy when you want to read in a number from the user, at least if you expect to be able to do any arithmetic with the number you read in!] There is a cute convention in Python that _multiplying_ a sequence type by a whole number is defined to mean the same thing as concatenating it with itself that many times. ["I", "like", "EFF"] * 3 ----> ["I", "like", "EFF", "I", "like", "EFF", "I", "like", "EFF"] "Ba" + ("na" * 8) -----> "Banananananananana" (really!) You don't have to remember that, but if it's convenient, you might enjoy using it. There is another way to do the same thing with iteration, which we haven't studied yet. This is an example of the fact that Guido van Rossum can just _decide_ what something will mean, because he was creating the language from scratch. Multiplying a list by a number doesn't have any particular inherent meaning (and probably was originally just an error, because it was "meaningless"). At some point, someone decided that it would be handy to give it this particular meaning, and so that's what it means. You may see other "cute" shortcuts like this; in a sense, they are not necessary, because you can write exactly the same program without this sort of shortcut. But they might help make your programs more concise. In the Perl world, there's a proverb that "There's More Than One Way To Do It" (TMTOWTDI). Perl has a large number of shortcuts and abbreviations, which can make programs very succint, but sometimes difficult to read or modify. In general, Python is relatively straightforward and does _not_ provide many different ways of accomplishing the same task; it's relatively free of shortcuts and abbreviations. This can make Python code much easier to read than many other languages. It also means that two programmers attacking the same problem with the same general technique are likely to produce code which looks similar, more or less. That's definitely not the case in all languages. A quick cheer for Python's abstraction: there are many things you can do to _any_ sequence type. Here are some examples of things you can do to sequence types. * access elements by number using sequence[n] * take slices using sequence[start:stop] * use the len function to find out how many elements are in the sequence, by asking for len(sequence) len("frontier") ----> 8 (the elements of a string are characters) len(["non", "fui", "non", "sum", "non", "curo"]) ----> 6 (the elements of a list are individual elements) * concatenate two sequences of the same type with + "EFF" + " " + "rules" ----> "EFF rules" * repeat a sequence with * "E" + ("F" * 2) ----> "EFF" * call sequence methods (more on these later; we can ask sequences to "do things to themselves") you can store elements into a sequence using the specific-element notation or the slice notation. example: organizations = ["EFF", "CDT", "ACLU", "EPIC"] print organizations[1] ----> "CDT" organizations[1] = "VTW" print organizations[1] ----> "VTW" (the element has been replaced) print organizations ---> ["EFF", "VTW", "ACLU", "EPIC"] * iterate over a sequence (more about this next class) * apply a particular action to each element of a sequence (in several different ways, none of which we've discussed) For next time ------------- Squares ------- Write a program which reads a number from the user and prints out the square of that number (the result of multiplying the number by itself). Computer: What's your number? User: 54 Computer: 54 squared is 2916. Temperature scale conversions ----------------------------- There are various ways to measure temperature, much to the irritation of people who travel between the U.S. and the rest of the world (or scientists who work with chemistry, physics, astronomy, and so on). The world's most popular temperature scale is called the Celsius or Centigrade scale ("C"). This scale is based on the freezing and boiling points of water -- originally defined as 0 and 100 degrees C. A Celsius degree is 1% of the difference between the freezing and boiling points. The second most popular scale is called Fahrenheit ("F"). This scale is based on the freezing point of salt water (around 0 F) and human body temperature (originally defined as 100 F, now measured at about 98.6 F with more accurate thermometers). (Salt water freezes at a lower temperature than regular water -- which freezes at 32 F on the Fahrenheit scale -- which means that adding salt to water is likely to make it more resistant to freezing, which is why salt is spread on frozen roads and walkways. Water boils at 212 F on this scale.) This tells us about correspondences between different points on these scales: 212 F = 100 C, 32 F = 0 C. If you plot this on a graph, you will see that -40 C = -40 F (the only point at which the scales come together, which you can also see on certain thermometers). You can also use algebra to find a formula to convert between the two scales. (You need to use formulas like this to solve this problem -- if you don't remember enough algebra to figure out the formulas for yourself, drop me an e-mail and I'll supply them to you.) The third most popular scale is the Kelvin scale ("K"), named for Baron William Thompson, Lord Kelvin, who was the first to calculate the temperature called "absolute zero" (at which all of the heat energy of an object has been removed) based on measurements of the behaviors of different kinds of gas at different temperatures. The Kelvin scale uses the same "degree" as the Celsius scale, but it starts at absolute zero instead of at the freezing point of water. Absolute zero is -273.15 C, so -273.15 C = 0 K, or 273.15 K = 0 C (so water freezes at 273.15 K). The remaining scale is the most obscure; it's called the Rankine scale ("R"), and used to be used by some scientists in English-speaking countries. It's been almost entirely displaced by the Kelvin scale. The Rankine scale uses the Fahrenheit degree, but, like the Kelvin scale, it starts at absolute zero. Absolute zero is -459.67 F, or 0 R; 0 F is 459.67 R. Write a program which reads a temperature in Fahrenheit and tells the equivalent in Celsius, Kelvin, and Rankine. Now write a program which reads a temperature in Celsius and tells the equivalent in Fahrenheit, Kelvin, and Rankine. If you use the first program to convert 70 Fahrenheit to Celsius, and the second program to convert that result back to Fahrenheit, what do you get? Horses ------ Write a program which asks which horse came first (win), second (place), and third (show) in a race. Store the names of the horses in a list, and then print out the list. [Now suppose there was a mistake and the middle horse may have been typed incorrectly -- make your program allow the user another chance to enter that horse's name, and store the corrected name in the original list.] Horses again ------------ Write a program like the previous program, but which then allows the user to enter a place number (1, 2, or 3) and tells the user which of the horses came in that place. e.g. Comp: Which horse came first? User: First Amendment Comp: Which horse came second? User: Sybil Liberty Comp: Which horse came third? User: Spirit of Freedom Comp: What position are you interested in? User: 2 Comp: The horse in position 2 was Sybil Liberty [Note: Sybil Liberty is a cartoon character devised by the ACLU for their pamphlets about students' rights.] Menu ---- Write a program which will display a menu of court decisions, each with a corresponding number, and then ask the user to choose one. (The particular list of court decisions can be built into your program so that it never changes; eventually we will think about how it could be entered by the user or read from a file on disk.) The program should then display a one-line summary of the decision the user chose. It is OK to make up the names and descriptions of the court cases. If you prefer, use food items or restaurants or anything else instead of court cases. e.g. Comp: 1. U.S. v. Pacifica Comp: 2. Schenck v. U.S. Comp: 3. Universal v. Sony Comp: 4. Katz v. U.S. Comp: 5. New York Times v. Sullivan Comp: Please choose a court case. User: 1 Comp: In the U.S. v. Pacifica case, the FCC got the power to censor radio. or Comp: 1. Fat Slice Comp: 2. Scenic India Comp: 3. Jamo Thai Kitchen Comp: 4. Whiz Burger Comp: 5. Napoleon Pizza Comp: 6. Ganesh Comp: Please choose a restaurant. User: 2 Comp: Scenic India is an Indian restaurant on Valencia. Can you modify the program to use slices somehow? (Mmmmm, pizza!) Question -------- What does range(10)[5:6][0] do? How about ["foo"][0]? ["foo"][1]? What's the difference between ["foo"][0] and ["foo"][0:1]? If you set hi = ["Hello", "there"] then what is hi[0][0]? hi[1][0]? hi[0][1:4]? hi[1][-1]? hi[-1][-1]? hi[0:2][1]? hi[0:1][0][0:4][-1]? How come? (Can you figure these out without typing them into Python?) I know these examples aren't very exciting, but being familiar with sequences and slices can help you a lot later on. Nested lists ------------ (I mentioned this in the handout above, after originally planning not to. You could still try to answer this.) Can you have a list inside a list (i.e., a list in which some or all of the elements are themselves lists)? How deeply could you nest lists? Can you give an example of nested lists which shows how to access information stored within them? Why would you want to nest lists inside of other lists? Obscure question ---------------- What do you think "X"[0][0][0][0][0][0][0][0][0][0][0][0][0] is? Does that make sense to you? Emptiness --------- What is []? What is ""? What is len([])? What is len("")? What is [][0]? How about ""[0]? Can you put something into an empty list by doing foo = [] foo[0] = "bar" print foo Can you write, in Python, a list of all the senators who voted against the DMCA in 1998?