I l@ve RuBoard

### 2.12 Exercises

This session asks you to get your feet wet with built-in object fundamentals. As before, a few new ideas may pop up along the way, so be sure to flip to Appendix C when you're done (and even when you're not).

1. The basics. Experiment interactively with the common type operations found in this chapter's tables. To get you started, bring up the Python interactive interpreter, type the expressions below, and try to explain what's happening in each case:

```2 ** 16
2 / 5, 2 / 5.0

"spam" + "eggs"
S = "ham"
"eggs " + S
S * 5
S[:0]
"green %s and %s" % ("eggs", S)

('x',)[0]
('x', 'y')[1]

L = [1,2,3] + [4,5,6]
L, L[:], L[:0], L[-2], L[-2:]
([1,2,3] + [4,5,6])[2:4]
[L[2], L[3]]
L.reverse(); L
L.sort(); L
L.index(4)

{'a':1, 'b':2}['b']
D = {'x':1, 'y':2, 'z':3}
D['w'] = 0
D['x'] + D['w']
D[(1,2,3)] = 4
D.keys(), D.values(), D.has_key((1,2,3))

[[]], ["",[],(),{},None]```
2. Indexing and slicing. At the interactive prompt, define a list named L that contains four strings or numbers (e.g., L=[0,1,2,3]). Now, let's experiment with some boundary cases.

1. What happens when you try to index out of bounds (e.g., L[4])?

2. What about slicing out of bounds (e.g., L[-1000:100])?

3. Finally, how does Python handle it if you try to extract a sequence in reverse梬ith the lower bound greater than the higher bound (e.g., L[3:1])? Hint: try assigning to this slice (L[3:1] = ['?']) and see where the value is put. Do you think this may be the same phenomenon you saw when slicing out of bounds?

3. Indexing, slicing, and del. Define another list L with four items again, and assign an empty list to one of its offsets (e.g., L[2] = []): what happens? Then try assigning an empty list to a slice (L[2:3] = []): what happens now? Recall that slice assignment deletes the slice and inserts the new value where it used to be. The del statement deletes offsets, keys, attributes, and names: try using it on your list to delete an item (e.g., del L[0]). What happens if you del an entire slice (del L[1:])? What happens when you assign a nonsequence to a slice (L[1:2] = 1)?

4. Tuple assignment. What do you think is happening to X and Y when you type this sequence? We'll return to this construct in Chapter 3, but it has something to do with the tuples we've seen here.

```>>> X = 'spam'
>>> Y = 'eggs'
>>> X, Y = Y, X```
5. Dictionary keys. Consider the following code fragments:

```>>> D = {}
>>> D[1] = 'a'
>>> D[2] = 'b'```

We learned that dictionaries aren't accessed by offsets; what's going on here? Does the following shed any light on the subject? (Hint: strings, integers, and tuples share which type category?)

```>>> D[(1, 2, 3)] = 'c'
>>> D
{1: 'a', 2: 'b', (1, 2, 3): 'c'}```
6. Dictionary indexing. Create a dictionary named D with three entries, for keys a, b, and c. What happens if you try to index a nonexistent key d (D['d'])? What does Python do if you try to assign to a nonexistent key d (e.g., D['d'] = 'spam')? How does this compare to out-of-bounds assignments and references for lists? Does this sound like the rule for variable names?

7. Generic operations. Run interactive tests to answer the following questions.

1. What happens when you try to use the + operator on different/mixed types (e.g., string + list, list + tuple)?

2. Does + work when one of the operands is a dictionary?

3. Does the append method work for both lists and strings? How about the using the keys method on lists? (Hint: What does append assume about its subject object?)

4. Finally, what type of object do you get back when you slice or concatenate two lists or two strings?

8. String indexing. Define a string S of four characters: S = "spam". Then type the following expression: S[0][0][0][0][0]. Any clues as to what's happening this time? (Hint: recall that a string is a collection of characters, but Python characters are one-character strings.) Does this indexing expression still work if you apply it to a list such as: ['s', 'p', 'a', 'm']? Why?

9. Immutable types. Define a string S of 4 characters again: S = "spam". Write an assignment that changes the string to "slam", using only slicing and concatenation. Could you perform the same operation using just indexing and concatenation? How about index assignment?

10. Nesting. Write a data-structure that represents your personal information: name (first, middle, last), age, job, address, email ID, and phone number. You may build the data structure with any combination of built-in object types you like: lists, tuples, dictionaries, strings, numbers. Then access the individual components of your data structures by indexing. Do some structures make more sense than others for this object?

11. Files. Write a script that creates a new output file called myfile.txt and writes the string "Hello file world!" in it. Then write another script that opens myfile.txt, and reads and prints its contents. Run your two scripts from the system command line. Does the new file show up in the directory where you ran your scripts? What if you add a different directory path to the filename passed to open?

12. The dir function revisited. Try typing the following expressions at the interactive prompt. Starting with Version 1.5, the dir function we met in Chapter 1 has been generalized to list all attributes of any Python object you're likely to be interested in. If you're using an earlier version than 1.5, the __methods__ scheme has the same effect.

```[].__methods__      # 1.4 or 1.5
dir([])             # 1.5 and later
dir({})```
 I l@ve RuBoard