Lecture 8, April 14, 2010
- Several people have asked me about getting tab complete to work in Python. It turns out this is fairly straightforward: I've posted instructions on the webpage.
print and string formatting
So we've been using the print statement for a while, but we've skirted around the issue of exactly what goes into the formatting of its output. In particular, there's this business with the % operator that we haven't talked much about. Here's an example of how this works:
>>> print "%s is thicker than %s"%('blood', 'water') blood is thicker than water >>> print "man, i shoulda had a V%s!"%8 man, i shoulda had a V8!
In fact, it turns out that this is something completely independent of the print command:
>>> s = "%s is odd" >>> s '%s is odd' >>> s%3 '3 is odd' >>> print s%3 3 is odd >>> s = "%s is odd, and %s is even" >>> s%3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: not enough arguments for format string
So now we can see more of what's happening: whenever we have a string that has a %s in it, calling the % operator will some arguments will replace each %s with one of the arguments, and Python gets unhappy if we have a mismatch between the number of %s strings and the number of arguments. In fact, it turns out you can do a bit more with this: for instance, you can format for width, or round, or do a bunch of other interesting things:
>>> print "<--%5s-->"%3 <-- 3--> >>> print "<--%5s-->"%333 <-- 333--> >>> print "<--%*s-->"%(10, 'hihi') <-- hihi--> >>> print "<--%-*s-->"%(10, 'hihi') <--hihi --> >>> print "Value in dollars: $%.2f"%(43.2398749) Value in dollars: $43.24
So you can do all kinds of things: round, control the width of the area you print to, left justify ... if you're interested, you can read more of the details.
Now, there's one more thing we need to know about printing: can we control how often Python puts in newlines? Of course, the answer's going to be "yes":
>>> print 3 3 >>> print 3, 5 3 5 >>> for x in range(10): ... print x, ... 0 1 2 3 4 5 6 7 8 9 >>>
For the record: there's no way to get rid of the spaces between items just using the print statement: you have to instead put everything into a string by hand, and print the string:
>>> s = "" >>> for x in range(10): ... s += str(x) ... >>> print s 0123456789 >>>
Now, in that last case, Python was more than willing to turn an integer (like 3) into a string for us (like '3'). In general, Python is more than happy to try converting between common types for you -- all you have to do is ask:
>>> int('3') 3 >>> str(3.14) '3.14' >>> int(str(3)) 3 >>> str('my house') 'my house'
In general, this is referred to as coercion -- we'll hear about this again when we talk about Sage.
Other string methods
There are a ton of interesting methods available on strings in Python:
>>> s = "abcdefg" >>> for method in [ x for x in dir(s) if not x.startswith('_') ]: ... print method ... capitalize center count decode encode endswith expandtabs find format index isalnum isalpha isdigit islower isspace istitle isupper join ljust lower lstrip partition replace rfind rindex rjust rpartition rsplit rstrip split splitlines startswith strip swapcase title translate upper zfill >>>
You should spend some time reading through what these do. For our purposes, let's mention a few interesting ones:
>>> s = " this is a STRING\t abc\t " >>> s ' this is a STRING\t abc\t ' >>> print s this is a STRING abc >>> s.strip() 'this is a STRING\t abc' >>> print s.strip() this is a STRING abc >>> s.lstrip() 'this is a STRING\t abc\t ' >>> s.expandtabs() ' this is a STRING abc ' >>> s.find('STRING') 13 >>> s[s.find('STRING')] 'S' >>> s[s.find('STRING'):][:6] 'STRING' >>> t = "string\nwith\nnewlines" >>> print t string with newlines >>> print t.replace('\n', ' ') string with newlines
Python has excellent support for manipulating files -- there's a lot you can do, but we'll just talk about the basics. You can open files with the open command, which takes an extra argument that tells it whether you want to read or write, and the format you want to read or write in (text or binary):
>>> f = open("test.txt") >>> f.readlines() ['theutaheuththhibyelaterhi\n', 'bye\n', 'later\n', 'asnotehusanotheusnth\n', '3\n'] >>> f.readlines() 
Notice that the file object "remembers" where it is. That's why the second attempt to read the lines out of the file didn't do anything -- we'd already read them all. One can reset the position, or just close and reopen:
>>> f.seek(0) >>> f.readlines() ['theutaheuththhibyelaterhi\n', 'bye\n', 'later\n', 'asnotehusanotheusnth\n', '3\n'] >>> f = open("test.txt") >>> f.readlines() ['theutaheuththhibyelaterhi\n', 'bye\n', 'later\n', 'asnotehusanotheusnth\n', '3\n'] >>> f.seek(10) >>> f.readlines() ['hthhibyelaterhi\n', 'bye\n', 'later\n', 'asnotehusanotheusnth\n', '3\n']
Now, writing is just as straightforward: there's a write method on file objects, or you can use the "print chevron":
>>> f = open("myfile.html", "w") >>> print >>f, "<html>" >>> f.write("<body>this is a short webpage</body>\n") >>> f.write("</html>\n") >>> f.close() >>> open("myfile.html").readlines() ['<html>\n', '<body>this is a short webpage</body>\n', '</html>\n']
Note that when you use the write method, you need to specify newlines yourself -- Python won't automatically add them for you. Similarly, if you use print and end the statement with a comma, you won't get a newline added.
There's one basic thing to remember about files: if you're writing to a file, it's possible that the file on disk and the file object in memory are out of sync: Python buffers output. So if you write something, then look at the file, you may notice it's not yet available -- in that case, use the flush method:
>>> f = open("buffering", "w") >>> f.write('hihihi\n') >>> open("buffering").readlines()  >>> f.flush() >>> open("buffering").readlines() ['hihihi\n']
Pieces from the standard library
There's an amazing amount of useful stuff in the Python standard library -- in fact, the comprehensiveness of the standard library is one of the things that draws people to Python. You could even take some time to look through documentation on all the modules. There are a handful we'll use in this class, especially those in os, os.path, and shutil.