http://www.tiddlywiki.com/
<<list all>>
<<list missing>>
<<allTags>>
<<list orphans>>
<<timeline>>
<<search>><<closeAll>><<permaview>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel options "Change TiddlyWiki advanced options">>
//This rearranges the sidebars\nvar contentWrapper = document.getElementById('contentWrapper');\nvar sidebar = document.getElementById('sidebar');\nsidebar.insertBefore(document.getElementById('mainMenu'),document.getElementById('sidebarOptions'))\n
[[Python]] [[Grimoire|Introduction]]
You wish to convert a number to the corresponding string representation. For example, you want to convert a number like 144 to the string {{{'144'}}}. \n \nThe simplest way is to use the built-in function {{{str()}}}, or the backquote notation {{{`144`}}}. Both solutions will convert the number to a string in the most straightforward way. \n \n{{{\nV = 187.5\nS = str(V) # Produces '187.5'\n}}}\n \nIf {{{V}}} contains an integer or long integer, and you want to convert the number to hexadecimal or octal representation, use the built-in functions {{{hex()}}} or {{{oct()}}}. \n \n{{{\n>>> hex(187)\n'0xbb'\n>>> oct(187)\n'0273'\n}}}\n \nIf fancier formatting is required, such as rounding a floating-point number to a given number of decimal places, or padding a number with zeros, use the % operator on strings, which allows more precise control of the output. \n \n{{{\n>>> "%04d" % (87,)\n'0087'\n>>> "%.2f" % (187.375,)\n'187.38'\n}}}\n \n(See the Library Reference manual for the complete details of the available format characters.) \n \nThere's no library function to convert a number to its base-2 representation, so here's a function to do the job. \n \n{{{\ndef atob(number):\n """Returns a string containing the binary representation of a number"""\n if number < 0:\n prefix = "-" ; number = -number\n elif number == 0: return "0"\n else:\n prefix = ""\n\n # Loop, looking at the lowest bit of the number an\n s = ""\n while number > 0:\n s = chr( 48+ (number 1) ) + s\n number = number >> 1\n return prefix + s\n}}}\n
You have a tuple, and want to turn it into a list. Or, the opposite problem: a list that you want to turn into a tuple. \n \nThe built-in functions {{{tuple()}}} and {{{list()}}} convert any sequence type into a tuple or list containing the same items in the same order. \n \n{{{\n>>> tuple( [1,2,3] )\n(1, 2, 3)\n>>> list ( ('monty', "python's", "fliegende", "circus") )\n['monty', "python's", 'fliegende', 'circus']\n>>> tuple('Dr Gumby!')\n('D', 'r', ' ', 'G', 'u', 'm', 'b', 'y', '!')\n}}}\n \n''Discussion:'' \n \n{{{list()}}} was introduced in Python 1.5; in previous versions, the following idiom was used to convert things to lists: \n \n{{{\nlist = map(None, (1,2,3,4) )\n}}}\n \nHere's how the above line of code works: the {{{map()}}} built-in function is used to evaluate a function for every value in a sequence type like a tuple, and returns a list containing the function's output for each value in the input sequence. Put another way, {{{map(F, seq)}}} returns a new list containing {{{[F( seq[0] ), F( seq[1] ), ... ]}}}. If {{{None}}} is passed as the function {{{F}}}, then {{{map()}}} simply returns the elements of the sequence {{{[seq[0], seq[1], ...]}}}. \n \nYou may still see the above use of {{{map()}}} in programs that attempt to be compatible with older versions of Python; if you don't care about backward compatibility, simply use {{{list()}}} which is clearer. \n
After creating a dictionary, you want to loop over the dictionary's contents and do something for each entry, such as printing them. \n \nThe {{{keys()}}} method of dictionaries returns a list of the dictionary's keys, arranged in essentially random order: \n \n{{{\n>>> for colr in fr_colours.keys(): print colr\n...\nyellow\nred\nblack\nwhite\nblue\n}}}\n \nIf you want to loop over the contents in some sorted order, you'll have to retrieve the list of keys and sort it before looping through it. \n \n{{{\n>>> keylist = fr_colours.keys() ; keylist.sort()\n>>> for colr in keylist: print colr\n...\nblack\nblue\nred\nwhite\nyellow\n}}}\n \nRemember that the {{{sort()}}} list method sorts a list in-place and returns {{{None}}}. {{{for colr in fr_colours.keys().sort()}}}will not work, because the value of {{{fr_colours.keys().sort()}}} is {{{None}}}. \n \n''Discussion:'' \n \nThe list returned by {{{keys()}}} is arranged randomly, because the key/value pairs are scattered across random bins in a hash table. Dictionaries therefore don't impose any ordering on their contents. For example, if you assemble a dictionary element-by-element, and print the dictionary after each new key/value pair is added, there's no order to how the contents are displayed. \n \n{{{\n>>> d = {} ; d['red'] = 'rouge' ; print d\n{'red': 'rouge'}\n>>> d['blue'] = 'bleu' ; print d\n{'red': 'rouge', 'blue': 'bleu'}\n>>> d['yellow'] = 'jaune' ; print d\n{'yellow': 'jaune', 'red': 'rouge', 'blue': 'bleu'}\n>>> d['green'] = 'vert' ; print d\n{'yellow': 'jaune', 'red': 'rouge', 'green': 'vert', 'blue': 'bleu'}\n}}}\n \nThere are two other methods available for retrieving the contents of a dictionary. If your loop will require each key and its corresponding value, you can use the {{{items()}}} method, which returns a list of {{{(key, value)}}} 2-tuples. Again, the list contents are arranged in a random order. \n \n{{{\n>>> for english, french in fr_colours.items():\n... print english, '\st', french\n...\nyellow jaune\nred rouge\nblack noir\nwhite blanc\nblue bleu\n}}}\n \nLeast commonly used of all, the {{{values()}}} method returns a list containing only the values from a dictionary. \n \n{{{\n>>> for colr in fr_colours.values(): print colr\n...\njaune\nrouge\nnoir\nblanc\nbleu\n}}}\n \nThe way to keep these method names straight is to remember that dictionaries map from keys to values; the {{{keys()}}} and {{{values()}}} methods return a list of the corresponding elements of the dictionary. That leaves {{{items()}}} to return a list of 2-tuples. \n
If a default value is some expression, that expression is evaluated at the time the {{{def}}} statement is executed, not when the function is called. Consider the following example: \n \n{{{\ndefault_level = 9\ndef new_compressor(compresslevel = default_level):\n print 'Compression level:', compresslevel\n\nnew_compressor() # Prints the default value\ndefault_level = 2 # Will this change the default value?\nnew_compressor()\n}}}\n \nWhen this code is run, it will print: \n \n{{{\nCompression level: 9\nCompression level: 9\n}}}\n \nRemember, {{{def}}} is an executable statement, binding the function's name "{{{new_compressor}}}" to a function object. At that time, {{{default_level}}} has a value of 9, so that's used as the default value of compresslevel. Subsequently changing the value of {{{default_level}}} has no effect on the default value of the function. It's not possible to change the object that's been defined as the default value. However, if an object is mutable and can be modified in place, as a list or dictionary can be, then any modification made to that object will change the default. Another example will make this clearer, I hope: \n \n{{{\ndef modify_list(List = []):\n print 'Before:', id(List), List\n List.append( 1 )\n print 'After: ', id(List), List\n}}}\n \nCalling this function with {{{modify_list()}}} will output: \n \n{{{\nBefore: 135048144 []\nAfter: 135048144 [1]\n}}}\n \nThe first number, the value of {{{id(List)}}}, is an integer guaranteed to be unique for this object while the object exists, and is usually derived from the machine address at which the object resides. The value printed here will vary from run to run of the Python interpreter, but will remain the same in each execution. On the first call of {{{modify_list()}}}, the list object assigned as the default value is changed. A second, identical call will produce: \n \n{{{\nBefore: 135048144 [1]\nAfter: 135048144 [1, 1]\n}}}\n \n{{{id(List)}}} is the same on both function calls, so the same list object is assigned as the default value, but the contents of that object have been changed, which doesn't affect the value returned by {{{id(List)}}}. New users are often surprised by this behaviour, and wonder if it's a bug in Python; it's not, and follows consistently from Python treating everything as a reference. \n
Some programming languages, such as the scripting language in MATLAB, allow calling a function and ignoring some of its return values. You need to do this in Python, ignoring some value returned from a function. \n \nIf the function returns a tuple, as done by most functions that return multiple results, treat the return value as a tuple and slice it to obtain the results that you need. \n \n{{{\ndef get_rgb_colour(colour_name):\n # ... set R, G, B, to the values\n return R, G, B\n\n# Get just the red component of a colour\ntup = get_rgb_colour('teal')\nR = tup[0]\n}}}\n \nThis can be expressed more compactly, though less clearly, without a tuple variable as: \n \n{{{\nR = get_rgb_colour('teal')[0]\n}}}\n \nYet another solution is to use a dummy variable name for the variables that aren't of interest. {{{_}}} is suggested as a short and rarely used name for this purpose. \n \n{{{\nR, _, _ = get_rgb_colour('methyl yellow')\n}}}\n \nFor the sake of completeness, it should be mentioned that Perl supports an idiom for ignoring return values by assigning them to {{{undef}}}, the Perl counterpart of Python's {{{None}}}. (This idiom is rarely actually used in Perl programs.) Don't try the same thing in Python, which would be: \n \n{{{\n None, None, B = get_rgb_colour('da Vinci green')\n}}}\n \nThis will run without errors, and {{{B}}} will get the expected value, but it also adds a new name to the local scope: {{{None}}} is now bound to some value. (Maybe that last sentence should end with a '!') Later uses of {{{None}}} in the same code will retrieve the assigned value, not the Python {{{None}}} object. In short, if you use the above idiom in Perl, don't attempt to use it in Python. \n
Remember that Python is extremely dynamic and that you can use this dynamism to configure a program at run-time to use available functionality on different platforms. For example you can test the sys.platform and import different modules based on its value. \n \n{{{\nimport sys\nif sys.platform == "win32":\n import win32pipe\n popen = win32pipe.popen\nelse:\n import os\n popen = os.popen\n}}}\n \nAlso, you can try to import a module and use a fallback if the import fails: \n \n{{{\ntry:\n import really_fast_implementation\n choice = really_fast_implementation\nexcept ImportError:\n import slower_implementation\n choice = slower_implementation\n}}}\n \nThis is commonly used to write code which will use a faster C extension module if it's installed, but will still work without the extension. \n
Use the struct module. It allows you to take a string read from a file containing binary data (usually numbers) and convert it to Python objects; and vice versa. \n \nFor example, the following code reads two 4-byte integers in big-endian format from a file: \n \n{{{\n import struct\n f = open(filename, "rb") # Open in binary mode for portability\n s = f.read(8)\n x, y = struct.unpack(">ll", s)\n}}}\n \nThe '>' in the format string forces big-endian data; each letter 'l' reads one "long integer" (4 bytes) from the string. \n \nYou can refer to the Library Reference for more details about the struct module. \n
The terminal has to be put into cbreak mode, in order to be able to read single characters from the terminal. \n \n{{{\nimport sys\ndef getch():\n import os, tty\n fd = sys.stdin.fileno()\n tty_mode = tty.tcgetattr(fd)\n tty.setcbreak(fd)\n try:\n ch = os.read(fd, 1)\n finally:\n tty.tcsetattr(fd, tty.TCSAFLUSH, tty_mode)\n return ch\n}}}
To delete (remove, unlink) a file, use {{{os.remove(filename)}}} or {{{os.unlink(filename)}}} \n \nFor documentation, see the posix section of the library manual. They are the same: {{{unlink()}}} is simply the Unix name for this function. \n \nTo remove a directory {{{os.rmdir()}}}\n \nTo create a directory {{{os.mkdir()}}}\n \nTo rename a file {{{os.rename()}}}\n \nTo truncate a file, open it using{{{ f = open(filename, "r+")}}}, and use {{{f.truncate(offset)}}}\n \n(The offset defaults to the current seek position. The {{{ "r+"}}} mode opens the file for reading and writing.) \n \nThere's also {{{os.ftruncate(fd, offset)}}} for files opened with {{{os.open()}}} for advanced Unix hacks only. \n
If you need to automatically save and restore objects and other data structures to files, the {{{pickle}}} library module solves this in a very general way (though you still can't store things like open files, sockets or windows), and the library module {{{shelve}}} uses {{{pickle}}} and {{{(g)dbm}}} to create persistent mappings containing arbitrary Python objects. For possibly better performance, use the {{{cPickle}}} module. \n \nA more awkward way of doing things is to use {{{pickle}}}'s little sister, {{{marshal}}}. The {{{marshal}}} module provides very fast ways to store noncircular basic Python types to files and strings, and back again. Although {{{marshal}}} does not do fancy things like store instances or handle shared references properly, it does run extremely fast. For example loading a half megabyte of data may take less than a third of a second (on some machines). This often beats doing something more complex and general such as using {{{gdbm}}} with {{{pickle}}}/{{{shelve}}}. \n
You can use the {{{sizehint}}} parameter to {{{readlines()}}} to get some of the efficiency of {{{readlines()}}} without reading in the whole file. The following code isn't optimized, but it shows the idea: \n \n{{{\nclass BufferedFileReader:\n def __init__ (self, file):\n self.file = file\n self.lines = []\n self.numlines = 0\n self.index = 0\n\ndef readline (self):\n if (self.index >= self.numlines):\n self.lines = self.file.readlines(65536)\n self.numlines = len(self.lines)\n self.index = 0\n\n if (self.numlines == 0):\n return ""\n\n str = self.lines[self.index]\n self.index = self.index + 1\n return str\n}}}\n
You want to retrieve a file from an FTP site by using a Python program. \n \nUse the {{{ftplib}}} module. \n \n{{{\nimport ftplib\n\n# Open the connection\nftp = ftplib.FTP("ftp.fbi.example.gov")\nftp.login("mulder", "trustno1")\n\n# Change directory\nftp.cwd('pub/x-files')\n\n# Write the output to a local file.\n# It's a binary file, so be sure to open the file in\n# binary mode.\nf = open("trixie.jpg", "wb")\nftp.retrbinary("RETR trixie.jpg", f.write)\nf.close()\n\n# Close connection\nftp.quit()\n}}}\n \nThe {{{ftplib}}} module provides an {{{FTP}}} class that represents a connection to an FTP server. To open the connection, you must provide a username and password. \n \nRetrieving the file isn't completely straightforward, because the {{{FTP}}} class provides a highly flexible interface. There's no method which will retrieve a file named "{{{X}}}" and write it to a local file named "{{{X}}}"; instead, you have to handle such details yourself. When a file is retrieved via FTP using the {{{retr}}} and {{{retrbinary}}} methods, you have to provide two pieces of information: the filename, and a Python function. The Python function will be called for each chunk of the file's contents, receiving a a string containing the data; the function then has the job of writing the data to a file. Luckily, you can often find a built-in function or method that does what you need, as in the example: \n \n{{{\nfile = open("trixie.jpg", "wb")\nftp.retrbinary("RETR trixie.jpg", file.write)\nfile.close()\n}}}\n \n{{{file}}} is a file object, whose {{{write(S)}}} method writes the string S to the file. In Python, you can use bound methods as callbacks; a bound method remembers the object that it belonged to. {{{file.write}}} is a bound method in this example. You can provide a custom function that does additional work beyond just writing out the data. \n \nWhen retrieving a file in text mode, each line is returned without any trailing newline characters, so you can add the required line endings for your platform when writing each line out to a file. \n \n{{{\nf = open("sightings.txt", "w")\nftp.retrlines("RETR sightings.txt",\n lambda s, w = f.write: w(s+"\sn") )\nf.close()\n}}}\n \nThe following function prints a progress counter as the file is retrieved, by maintaining a count of the bytes read so far. On every call, the current byte count is padded out to 9 characters, printed, and followed by 9 backspace characters. \n \n{{{\nimport sys\n\nbyte_count = 0\noutput_file = open('...', 'w')\n\ndef write_block(data):\n global byte_count\n byte_count = byte_count + len(data)\n\n output_file.write( data )\n\n # Output the current byte count and backspaces\n sys.stdout.write('%9i%s' % (byte_count, 9*'\s010') )\nsys.stdout.flush()\n}}}\n \n{{{sys.stdout}}} has to be flushed after each {{{write()}}} call, in order to ensure that the output is actually sent to the screen as it's generated. \n \nSee also the section on "Passing Functions as Parameters". It discusses how to pass a function as a parameter to another function, and will help you to understand callbacks. \n
This is the opposite of the previous problem. You now want to upload a file to an FTP server. \n \nThe {{{ftplib}}} module comes to the rescue, again. \n \n{{{\nimport ftplib\n\n# Open the connection\nftp = ftplib.FTP("ftp.fbi.example.gov")\nftp.login("mulder", "trustno1")\n\n# Change directory\nftp.cwd('pub/x-files/bigfoot')\n\n# Read from a local text file, and send it to the FTP server\n# The local filename is 'sightings', but it'll be stored on the remote FTP\n# server under the name 'sightings-1999-01'.\nf = open("sightings", "r")\nftp.storlines("STOR sightings-1999-01", f)\nf.close()\n\n# Upload a binary file.\n# Local filename: 'footprint.jpg', remote filename: 'footprint-1.jpg'\nf = open("footprint.jpg", "rb")\nftp.storbinary("STOR footprint-1.jpg", f, 1024)\nf.close()\n\n# Close connection\nftp.quit()\n}}}\n \nWhen uploading a binary file, as opposed to a text file, a third numeric argument has to be provided to the {{{storbinary()}}} method. \n \n{{{\nftp.storbinary("STOR footprint-1.jpg", f, 1024)\n}}}\n \nThe file will be read and sent over the network in chunks of the specified block size, so it shouldn't be set to a very small value like 1; this would result in too much overhead. It would be possible to spend a good deal of effort trying different values of the block size and measure the performance in order to figure out the optimal block size, but it's not that critical a parameter. 1024 is a reasonable number, so you can simply set the value and forget about it. \n
You want to retrieve a file through HTTP. The data returned might be the HTML text of a Web page, an image such as a GIF or JPEG, or a binary file such as a JAR or TGZ file. \n \nThe easiest course is to use the {{{urllib}}} module, which will try to open an arbitrary URL and return a file object which can be read from to retrieve the data. \n \n{{{\nimport urllib\n\n# Open the URL\ninput = urllib.urlopen('http://www.example.com/info/index.html')\n\n# Read all the data from the file as a single string\ndata = input.read()\ninput.close()\n}}}\n \nAn alternative solution that operates at a lower level is to use the {{{httplib}}} module to perform the HTTP transaction yourself. \n \n{{{\nimport httplib\nh = httplib.HTTP('www.example.com')\nh.putrequest('GET', '/info/index.html')\nh.putheader('Accept', 'text/html')\nh.endheaders()\nerrcode, errmsg, headers = h.getreply()\nif errcode == 200:\n f = h.getfile()\n data = f.read() # Print the raw HTML\n}}}\n \nSome pages require a user name and password; Web browsers will prompt you for them when required. The {{{urlopen()}}} function will prompt the user and request the user name and password on standard input. Such user intervention is unsuitable for fully automatic Web page retrievals, so you should specify the user name and password when retrieving such a password-protected page automatically. The user name and password can be specified in the URL, when it's written in the form {{{http://user:password@host/...}}}. \n \nFredrik Lundh suggests an alternative approach that's more flexible, but is also more complicated. The {{{urllib}}} module contains several classes for opening URLs using different protocols, one such class being {{{FancyURLopener}}}. The {{{urlopen()}}} function simply creates an instance of {{{FancyURLopener}}} and uses it to access URLs. When input from the user is required, the {{{prompt_user_passwd()}}} method is called. Fredrik suggests the following approach: subclass {{{FancyURLopener}}} and add attributes to hold the username and password. {{{prompt_user_passwd()}}} is then overridden to simply return the user name and password without user intervention. \n \n{{{\nimport urllib\n\nclass myURLOpener(urllib.FancyURLopener):\n def setpasswd(self, user, passwd):\n self.__user = user\n self.__passwd = passwd\n\n def prompt_user_passwd(self, host, realm):\n return self.__user, self.__passwd\n\nurlopener = myURLOpener()\nurlopener.setpasswd("mulder", "trustno1")\n\nfp = urlopener.open("http://www.secretlabs.com")\nprint fp.read()\n}}}\n
a hypertext tome pertaining to that most elegant of languages
The creator of TiddlyWiki, without whom the Grimoire would probably have stayed in static HTML format.
Email address: rui -dot- carmo [at] gmail -dot- com\n\nCurrent steward of the [[Grimoire]] and responsible for managing its TiddlyWiki incarnation, plus adding random bits and pieces. Can also be [[contacted|http://the.taoofmac.com/space/RuiCarmo]] through [[his site|http://the.taoofmac.com]].
Introduction\n[[Table Of Contents]]\nCredits
This document is based on version <<version>> of TiddlyWiki, an experimental MicroContent WikiWikiWeb built by [[Jeremy Ruston]]. It's written in HTML, CSS and JavaScript to run on any modern browser without needing any server-side logic, and you can find out more about it at [[its homepage|http://www.tiddlywiki.com]].
The [[Conversion Script]] that [[I|Rui Carmo]] used to convert the original HTML version into TiddlyWiki format shows a possible way to emulate {{{switch}}} statements in Python using exceptions:\n\n{{{\n...\n try:\n raise intern(str(tag))\n except ('tr', 'thead'):\n self.buffer += '\sn'\n except ('th'):\n self.buffer += '|!'\n except ('blockquote'):\n self.buffer += '\sn<<<\sn'\n except:\n pass\n}}}\n\nThis is actually not a very good example, since the use of {{{intern}}} is likely to be deprecated soon. Nevertheless, right now it ensures that {{{except}}} will deal with the results of string conversion properly.
[[Introduction]] [[Table Of Contents]] [[Credits]]\n<<newTiddler>><<newJournal "DD MMM YYYY">>
You want to read through a file line by line. This is the most common way of processing text files. For example, if you're writing a Python program that searches for text in a file, you'll have to loop through the file contents on a line by line basis.\n \nYou can code the loop explicitly, like this: \n \n{{{\nfile = open('/tmp/filename', 'r')\nwhile True:\n line = file.readline()\n if line == "": break # Check for end-of-file\n do_something(line)\nfile.close()\n}}}\n \nOr like this, which reads all of the lines of the file into a list: \n \n{{{\nfile = open('/tmp/filename', 'r')\nlines = file.readlines()\nfile.close()\nfor line in lines:\n do_something(line)\n}}}\n \nThe {{{fileinput}}} module makes this even simpler by handling the loop for you: \n \n{{{\nimport fileinput\nfor line in fileinput.input("/tmp/filename"):\n do_something(line)\n}}}\n \nFor sheer simplicity, it's hard to top reading all the lines from the file into a list, like this: \n \n{{{\nfile = open('/tmp/filename', 'r')\nlines = file.readlines()\nfile.close()\nfor line in lines:\n do_something(line)\n}}}\n \nOr like this: \n \n{{{\nfile = open('/tmp/filename', 'r')\nfor line in file.readlines()\n do_something(line)\n}}}\n \nThis is easy to code, but it does require reading the entire file into memory. These days, most systems will have enough memory to effortlessly handle files a few hundreds of kilobytes long. A 10 megabyte file will cause problems - swapping to disk, if not an actual crash - for many systems. Use your common sense; if you're pretty sure you won't need to handle large files, use {{{file.readlines()}}}; otherwise, use either of the two suggested solutions. \n \nTo loop over multiple files using fileinput, use a sequence of filenames (a list, tuple, etc) instead of just a single file.\n \n{{{\nfor filename in ("file1", "file2", "file3"):\n\n file = open(filename, 'r')\n lines = file.readlines()\n file.close()\n\n for line in lines:\n do_something(line)\n}}}\n \n If you omit the names, they default to {{{sys.argv[1:]}}}, or to standard input if no arguments were given. \n
A useful trick you can pull off with Python is to set up a small web server at a moment's notice (mostly as a one-off file share for those occasions when you simply can't get files across any other way).\n\nTo do that, create a short shell script containing:\n\n{{{\n#!/bin/sh\npython -c '__import__("SimpleHTTPServer").test()'\n}}}\n\n(or just alias the {{{python}}} invocation in your shell)\n\n{{{SimpleHTTPServer}}} defaults to port 8000 and serving files from wherever you invoke it. It is not spectacularly smart, but should to a good enough job of serving simple demos and the odd file.\n\nBe sure to use "Save Link As..." when downloading Office files from it, since it does not have all the [[MIME]] types defined.
* First public release in TiddlyWiki format, using [[Clint Checketts]]' adaptation of the GTDTiddlyWiki theme and version 1.2.31 of TiddlyWiki.\n* Minimal content fixes (mostly re-phrased some headers and fixed whatever the [[Conversion Script]] didn't get right the first time).\n* Did a second update fixing minor typos that persisted from the original HTML, adding a couple of extra notes and pointing out that the file URL will change soon.
<<tabs txtMoreTab\nMissing "Missing tiddlers" TabMoreMissing\nOrphans "Orphaned tiddlers" TabMoreOrphans\nUntagged "Untagged tiddlers" TabMoreUntagged\n>>
<<tabs txtMainTab\nTimeline Timeline TabTimeline\nAll "All tiddlers" TabMoreAll\nTags "All tags" TabTags\nMore "More lists" TabMore\n>>
<<list untagged>>
This is the simple conversion script that [[I|Rui Carmo]] used to batch-convert the original [[Grimoire]] HTML into TiddlyWiki markup.\n\nThe result is another HTML file with TiddlyWiki markup inside {{{textarea}}} tags, which were then individually cut and pasted into TiddlyWiki for minor tweaks (mostly spacing, tables and bulleted lists, which [[I|Rui Carmo]] forgot to process.\n\n{{{\nimport sys\nimport re\nfrom HTMLParser import HTMLParser\n\nclass IndexParser(HTMLParser):\n def __init__(self):\n HTMLParser.__init__(self)\n self.buffer = ""\n self.fixed = self.table = False\n\n def handle_starttag(self, tag, attrs):\n try:\n raise intern(str(tag))\n except ('table'):\n self.table = True\n except ('tr', 'thead'):\n self.buffer += '\sn'\n except ('td'):\n self.table = False\n self.buffer += '|'\n except ('th'):\n self.buffer += '|!'\n except ('blockquote'):\n self.buffer += '\sn<<<\sn'\n except ('pre'):\n self.buffer += '\sn{{{\sn'\n self.fixed = True\n except ('tt', 'code'):\n self.buffer += '{{{'\n except ('i','em'):\n self.buffer += '//'\n except ('b'):\n self.buffer += "''"\n except ('u'):\n self.buffer += "__"\n except ('p'):\n self.buffer += '\sn'\n except ('h1'):\n self.buffer += '</textarea><textarea>!'\n except ('h2'):\n self.buffer += '</textarea><textarea>!!'\n except ('h3'):\n self.buffer += '</textarea><textarea>!!!'\n except:\n pass\n\n def handle_entityref(self, name):\n try:\n raise intern(str(name))\n except('lt'):\n self.buffer += '<'\n except('gt'):\n self.buffer += '>'\n except:\n pass\n\n def handle_data(self, text):\n if(self.table):\n text = text.strip()\n if(self.fixed):\n text = re.sub('\st+', ' ', text)\n text = re.sub('\sn\ss', '\sn', text)\n else:\n text = re.sub('\ss+',' ', text)\n self.buffer += text\n\n def handle_endtag(self, tag):\n try:\n raise intern(str(tag))\n except ('body'):\n self.buffer += '</textarea>'\n except ('table'):\n self.table = False\n except ('td'):\n self.table = True\n except ('tr','thead'):\n self.buffer += '|'\n except ('blockquote'):\n self.buffer += '\sn<<<\sn'\n except ('pre'):\n self.buffer += '}}}\sn'\n self.fixed = False\n except ('tt', 'code'):\n self.buffer += '}}}'\n except ('p'):\n self.buffer += '\sn'\n except ('b'):\n self.buffer += "''"\n except ('u'):\n self.buffer += "__"\n except ('i','em'):\n self.buffer += '//'\n except:\n pass\n\nparser = IndexParser()\nparser.feed(sys.stdin.read())\nprint parser.buffer\n}}}
The rise of the Internet has greatly eased the life of network programmers, by reducing the importance of proprietary standards and replacing them with open protocols whose specifications are readily available. Various standard Internet protocols, such as the Simple Mail Transport Protocol ([[SMTP]]) for electronic mail, or the Web's HyperText Transfer Protocol ([[HTTP]]), now dominate their respective niches. \n\nPython's standard library includes many modules that implement different Internet protocols, and some frameworks (like [[Twisted]]) take those implementations beyond the basics, allowing you to code just about any sort of client (or server) imaginable.\n\nThe basics, however, are well represented in the standard library, mostly in the form of classes like <<PythonModule SocketServer>> and <<PythonModule SimpleHTTPServer>>.
''Problem:''\n\nYou need to convert an integer value {{{V}}} to a 2-byte or 4-byte string representation. For example, the number 1 would be the bytes 0,1; 1956 would be 164, 7 because 1956 = 7 * 256 + 164. This is often needed when reading or writing binary data files, or implementing network protocols. \n \n''Solution:'' \n \nYou can write code to perform the conversion by taking the low byte of {{{V}}}, shifting {{{V}}} down 8 bits and taking the low byte of the result, and so forth. However, the code is long and relatively slow: \n \n{{{\ns = ( chr( (V) 255 ) +\n chr( (V >> 8) 255 ) +\n chr( (V >> 16) 255 ) +\n chr( (V >> 24) 255 ) )\n}}}\n \nA faster and simpler solution uses the <<PythonModule struct>> module, which is intended for such conversions: \n \n{{{\nimport struct\ns = struct.pack('i', V )\n}}}\n \nTo reverse the conversion, and go from a binary string to a tuple of integers, use {{{struct.unpack()}}}:\n \n{{{\nbyte, short = struct.unpack('BH', '\s377\s000\s377\s377')\n}}}\n \n''Discussion:'' \n \nYou're not limited to only packing a single value at time. Instead, the {{{pack()}}} function in the <<PythonModule struct>> module takes a format string containing several characters, along with the values to be packed: \n \n{{{\n>>> struct.pack('iii', 127, 1972, 1234567890)\n'\s177\s000\s000\s000\s264\s007\s000\s000\s322\s002\s226I'\n}}}\n \nRepeated format characters can be written as a single character preceded by an integer repeat count; the previous example could have been written as {{{struct.pack('3i', ...)}}}, and would produce identical results. \n \nDifferent-sized values can be packed using several different format characters, whose output will vary in size. For example, the "{{{b}}}" (byte) character will produce a single byte of output, and therefore is limited to values between -128 and 127. "{{{h}}}" (short) produces 2 bytes, "{{{i}}}" (int) produces 4 bytes, and "{{{l}}}" (long) will be 4 bytes on 32-bit machines, and 8 bytes on most 64-bit machines. \n \nHere's a table of some of the more commonly used format characters supported by {{{pack()}}} and {{{unpack()}}}. Consult the Library Reference's section on the <<PythonModule struct>> module for a complete list:\n\n|!''Format''|!''C Type''|!''Python''|\n|b|{{{signed char}}}|integer|\n|B|{{{unsigned char}}}|integer|\n|h|{{{short}}}|integer|\n|i|{{{int}}}|integer|\n|l|{{{long}}}|integer|\n|f|{{{float}}}|float| \n\nBecause the <<PythonModule struct>> module is often used for packing and unpacking C structs, it obeys the compiler's alignment rules. This means that padding bytes may be inserted between format characters of different types. For example, the zero byte in the following example is padding: \n \n{{{\n>>> struct.pack('BH', 255, 65535)\n'\s377\s000\s377\s377'\n}}}\n
<<<\ngrimoire /grim''waar''/ (noun) ::= a book of magic spells and invocations. Origin: French, alteration of grammaire 'grammar'. A grammar is a description of a set of symbols and how to combine them to create well-formed sentences. A grimoire is a description of a set of magical symbols and how to combine them properly. It is sort of a recipe-book for magic spells.\n\nSee also the <<Wikipedia 'Wikipedia entry' 'Grimoire'>>.\n<<<\n\nThe //Python Grimoire// explains how to perform common programming tasks in Python. It is a good place to go after you've read the Python Tutorial and have a reasonable grasp of the basics of the language. In essence, the //Grimoire// is a collection of small recipes for very basic tasks. Its purpose is similar to that of the [[Python Cookbook|http://aspn.activestate.com/ASPN/Python/Cookbook/]], but the //Grimoire//'s recipes are much simpler and more basic than those in the Cookbook. It does not cover advanced and/or specialized topics such as [[GUI toolkits]] and [[Jython]].\n\nThe //Grimoire//, then, is an unpolished document. It may still contain occasional typos, formatting bloopers, code errors, and out-of-date material.\n\n<<<\nPlease keep in mind that //the Grimoire's file location will change soon//, so please don't link to it directly - link to [[this page|http://the.taoofmac.com/space/Python/Grimoire]] instead, which also holds links to the old version in plain HTML and PDF formats.\n<<<
A related problem to [[generating random numbers|Generating Random Numbers]] is generating a random permutation of numbers between 1 and N, with no repeats. For example, you might want to rearrange a list into a random order. \n \nThe solution is to generate a list containing the numbers from 1 to N, and use the {{{random.choice()}}} function to pick a random element. Remove the chosen element, and then repeat until the list is empty. \n \n{{{\nnumbers = range(1, N+1)\nwhile numbers:\n j = random.choice(numbers)\n numbers.remove(j)\n print j\n}}}
''Problem:'' \n \nGiven a string, you wish to replace all the occurrences of one substring with different text. For example, you wish to replace all occurrences of the string {{{'USER-NAME'}}} with the string {{{'Joseph Addison'}}} in the string contained in the variable {{{data}}}. \n \n''Solution:'' \n \nFor simple string substitutions, the {{{string.replace}}} function will be the simplest and fastest solution. \n \n{{{\nimport string\nnewdata = string.replace(data, 'USER-NAME', 'Joseph Addison')\n}}}\n \nIf {{{data}}} contains {{{"USER-NAME has been added to the list."}}}, then after the above line is executed, {{{newdata}}} will contain {{{'Joseph Addison has been added to the list.'}}}. \n \n''Discussion:'' \n\n<<<\n''Note:'' the following has not yet been revised to account for [[Unicode]]/[[UTF-8]] details, and so should be taken with a grain of salt in modern Python - but the principles are sound.\n<<<\n\nString replacement is a common operation, and there are several ways to do it. The fastest and simplest way is the {{{string.replace()}}} function, which can only replace a fixed string with another fixed string. For example, the following line replaces the Latin-1 character 219, a capital U with a circumflex accent (^), with the HTML entity {{{Û}}}. \n \n{{{\nnewdata = string.replace(data, chr(219), 'Û')\n}}}\n \nThe {{{chr()}}} built-in function takes an integer between 0 and 255, and returns a string of length 1 that contains the character with that byte value. \n \nMultiple replacements will require multiple calls to {{{string.replace()}}}: \n \n{{{\nnewdata = string.replace(data, chr(219), 'Û')\nnewdata = string.replace(data, chr(233), 'é')\n}}}\n \nThe replacement string is fixed, so it can't be varied depending on the string that was matched. For cases that require matching variable strings, such as "match anything between square brackets", or that require varying the replacement string, you'll have to use regular expression matching, available through the built-in <<PythonModule re>> module. \n \nThe following example uses regular expressions to replace URLs in a string with the [[HTML]] for a link to that URL, with the URL as the link text. \n \n{{{\nimport re\n\ndata = """http://www.freshmeat.net\n ftp://ftp.python.org/pub/python/src/\n"""\n\nnewdata = re.sub(r"""(?x)\n( # Start of group 1\n (http|ftp|mailto) # URL scheme\n : # Separating colon\n \sS+ # Everything up to the next whitespace character\n) # End of group 1\n""", r'<a href="\sg<1>">\sg<1></a>', data)\n}}}\n \nNotice that the order of the arguments to {{{re.sub}}} is different from the arguments for {{{string.replace()}}}. {{{string.replace()}}} takes the arguments (string, substring, replacement), while {{{re.sub()}}} takes the arguments (pattern, replacement, string). {{{re.sub()}}} has a different ordering of its arguments for consistency with the other functions in the {{{re}}} module; the regular expression pattern is viewed as the most important argument, so it's always passed as the first argument. \n \nRegular expression patterns have a complicated syntax. Let's dissect the above pattern into its components. \n\n* {{{(?x)}}} Specifies that this pattern is expressed in verbose mode. Most whitespace will be ignored, so you can format the pattern neatly, and comments can be embedded in the pattern by preceding them with a "{{{#}}}". \n* {{{(http|ftp|mailto)}}} The parenthesized group lists several alternative strings, separated by "{{{|}}}" characters. Any one of these strings can produce a successful match for this component of the pattern. \n* {{{\sS+}}} The {{{\sS}}} special sequence matches any character that isn't a whitespace character. Whitespace characters are space "{{{ }}}", tab "{{{\st}}}",newline "{{{\sn}}}", carriage return "{{{\sr}}}", form feed "{{{\sf}}}", and vertical tab "{{{\sv}}}". The "{{{+}}}" character is a qualifier that specifies how many times the previous component should be repeated; "{{{+}}}" indicates that the {{{\sS}}} should be repeated one or more times. \n\nThe replacement string can contain sequences which will contain pieces of the matching string. For example, {{{\sg<1>}}} will be replaced by the contents of the first group, which in this case will contain the whole URL that matches the regular expression. The replacement string is therefore {{{'<a href="\sg<1>">\sg<1></a>'}}}, which will contain the text of the URL at two different places, along with the required HTML. \n \nThe <<PythonModule re>> module can perform simple substitutions that are equally possible with {{{string.replace()}}}. This is simply a matter of writing a pattern that doesn't use any of the regular expression syntax: \n \n{{{\ndata = re.sub('USER-NAME', 'Joseph Addison', data)\n}}}\n \nTry not to use regular expressions when a simpler fixed-string replacement can do the job, because you're paying a speed penalty for the extra generality of regular expressions. \n\nFor much more information on regular expressions in Python, consult the [[Regular Expression HOWTO|http://www.python.org/doc/howto/regex/]].
! Problem:\n\nYou have a string such as {{{'533'}}} and wish to convert it to the number 533. \n\n! Solution:\n\nThe built-in functions {{{int()}}}, {{{long()}}}, and {{{float()}}} can perform this conversion from string to a numeric type: \n \n{{{\n>>> int( '533' )\n533\n>>> long( '37778931862957161709568' )\n37778931862957161709568L\n>>> float( '45e-3'), float('12.75')\n(0.045, 12.75)\n}}}\n \nNote that these functions are restricted to decimal interpretation, so that {{{int('0144')}}} will return a result of 144, and {{{int('0x144')}}} will raise a {{{ValueError}}} exception. \n \nTo support different bases, or for use with versions of Python earlier than 1.5, the <<PythonModule string>> module contains the functions {{{atoi()}}}, {{{atol()}}}, and {{{atof()}}}, which convert from ASCII to integer, long integer, or floating point, respectively. \n \n{{{\n>>> import string\n>>> string.atoi('45')\n>>> string.atol( '37778931862957161709568' )\n37778931862957161709568L\n>>> string.atof('187.54')\n187.54\n}}}\n \n{{{atoi()}}} and {{{atol()}}} have an optional second argument which can be used to specify the base for the conversion. If the specified base is 0, the functions will follow Python's rules for integer constants: a leading "{{{0}}}" will cause the string to be interpreted as an octal number, and a leading "{{{0x}}}" will cause base-16 to be used. \n \n{{{\n>>> string.atoi('255')\n255\n>>> string.atoi('255', 16) # 255 hex = 597 decimal\n597\n>>> string.atoi('0255', 0) # Assumed to be octal\n173\n>>> string.atol('0x40000000000000000000', 0)\n302231454903657293676544L\n}}}\n \nWhile you could use the built-in function {{{eval()}}} instead of the above functions, this is not recommended, because someone could pass you a Python expression that might have unwanted side effects. \n\nFor example, a caller might pass a string containing a call to {{{os.system()}}} to execute an arbitrary command; this is a serious danger for applications such as CGI scripts that need to handle data from an unknown source. {{{eval()}}} will also be slower than a more specialized conversion operation. \n
! Problem:\n \nYou wish to split a string into N equally-sized parts. The last part might be smaller than the previous ones when the length of the string isn't an exact multiple of N. For example, dividing the 9-character string {{{'Woodhenge'}}} into 2 parts would result in the list {{{['Woodh', 'enge']}}}, containing a 5-character and a 4-character string. \n \n! Solution:\n \nThe following function takes a string {{{S}}} and a number {{{N}}}, and returns an {{{N}}}-element list containing the different sections of the string. The function works by taking the length of the string and computing how long the sections must be. The list is then constructed by looping over the string and extracting each section by slicing the string. \n \n{{{\ndef equal_split(S, N):\n """Split up the string S into N parts, returning a list containing\n the parts. The last part may be smaller than the others."""\n part = (len(S) + N - 1) /N\n L = []\n for i in range(0, N):\n L.append( S[part*i : part*i+part] )\n return L\n}}}\n \n{{{equal_split('this is a test', 3)}}} will return {{{['this ', 'is a ', 'test']}}}.\n\nMore general slicing and indexing of strings works in the same way as other [[sequence types|http://www.python.org/doc/2.4.1/lib/typesseq.html]].
! Problem:\n\nYou want to perform a calculation that requires operations beyond the basic ones of addition, subtraction, multiplication, division, and exponentiation. For example, you need to evaluate a sine or cosine. \n\n! Solution:\n \nImport the <<PythonModule math>> module, and use the functions that it provides. \n \n{{{\nimport math\n\nangle = math.pi / 6\nx = math.cos( angle )\ny = math.sin( angle )\n}}}\n \nIf you want to get results that are complex numbers, use the <<PythonModule cmath>> module. \n \n{{{\nimport cmath\nresult = cmath.sin( 1+3j )\n}}}\n \n''Discussion:'' \n \nMathematical functions such as sine and cosine are contained in the <<PythonModule math>> module. The functions are identical to those defined by the C standard, since they're simply Python wrappers on top of those functions. The <<PythonModule math>> module also defines two constants: {{{pi}}}and {{{e}}}. \n \nThe functions in <<PythonModule math>> always return floating point numbers, whether the input was an integer or a float. If a result would be a complex number ({{{math.sqrt(-1)}}}, the square root of -1, is the common example), this is considered an error and triggers an exception. To get complex numbers as answers, you need to use the <<PythonModule cmath>> module, which is similar (though not identical) to the <<PythonModule math>> module, and can handle complex parameters and results: \n \n{{{\n>>> math.sqrt(-1)\nTraceback (innermost last):\n File "<stdin>", line 1, in ?\nOverflowError: math range error\n>>> cmath.sqrt(-1)\n1j\n}}}\n \nHere's a list of the functions contained in the <<PythonModule math>> module. The <<PythonModule cmath>> module defines analogous functions that operate on complex numbers. \n \n\n|!''Name''|!''Purpose''|\n|{{{acos(x)}}}|Arc cosine of x|\n|{{{asin(x)}}}|Arc sine of x|\n|{{{atan(x)}}}|Arc tangent of x|\n|{{{atan2(x,y)}}}|Arc tangent of {{{x/y}}}|\n|{{{ceil(x)}}}|Ceiling of x; the largest integer equal to or greater than x|\n|{{{cos(x)}}}|Cosine of x|\n|{{{cosh(x)}}}|Hyperbolic cosine of x|\n|{{{exp(x)}}}|e raised to the power of x|\n|{{{fabs(x)}}}|Absolute value of x|\n|{{{floor(x)}}}|Floor of x; the largest integer equal to or less than x|\n|{{{fmod(x)}}}|x modulo y|\n|{{{frexp(x)}}}|The matissa and exponent for x.|\n|{{{hypot(x, y)}}}|Euclidean distance, {{{sqrt(x*x + y*y)}}}|\n|{{{ldexp(x, i)}}}|{{{x * (2**i)}}}|\n|{{{log(x)}}}|Natural logarithm of x|\n|{{{log10(x)}}}|Base 10 logarithm of x|\n|{{{modf(x)}}}|Return the fractional and integer parts of x|\n|{{{pow(x, y)}}}|x raised to the power of y|\n|{{{sin(x)}}}|Sine of x|\n|{{{sinh(x)}}}|Hyperbolic sine of x|\n|{{{sqrt(x)}}}|Square root of x|\n|{{{tan(x)}}}|Tangent of x|\n|{{{tanh(x)}}}|Hyperbolic tangent of x|
! Problem:\n \nPython's strings are immutable, so you can't change a single character of the string without constructing a new string. Sometimes this is a problem, particularly when dealing with very large strings; constructing a new string will require copying most of the original string, and can be slow. \n \n! Solution:\n \nUse the <<PythonModule array>> module, which provides a mutable array data type that can only hold values of a single type. If used to hold only characters, an array behaves similarly to a mutable string. \n \n{{{\nimport array\n\nA = array.array('c')\nA.fromstring('hello there!')\nprint A\n}}}\n \nThis prints: \n \n{{{\narray('c', 'hello there!')\n}}}\n \nThe array object {{{A}}} is mutable, so you can modify an element in place: \n \n{{{\nA[0] = 'j'\nprint A\n}}}\n \nThis will print: \n \n{{{\narray('c', 'jello there!')\n}}}\n \nMost functions that require strings, such as {{{string.split()}}}, won't accept array objects, so you'll have to convert the array to a string in order to pass the data to certain functions: \n \n{{{\nprint string.split( A.tostring() )\n}}}\n\nBut since both strings and arrays are [[sequence types|http://www.python.org/doc/2.4.1/lib/typesseq.html]], several forms of indexing and slicing can be performed on either.
Most of the time this will do: \n \n{{{\ninfile = open("file.in", "rb")\noutfile = open("file.out", "wb")\noutfile.write(infile.read())\n}}}\n \nHowever for huge files you may want to do the reads/writes in pieces (or you may have to), and if you dig deeper you may find other technical problems. \n \nUnfortunately, there's no totally platform independent answer. On Unix, you can use {{{os.system()}}} to invoke the "cp" command (see your Unix manual for how it's invoked). On DOS or Windows, use {{{os.system()}}} to invoke the "COPY" command. On the Mac, use {{{macostools.copy(srcpath, dstpath)}}}. It will also copy the resource fork and Finder info. \n \nThere's also the shutil module which contains a {{{copyfile()}}} function that implements the copy loop; but in Python 1.4 and earlier it opens files in text mode, and even in Python 1.5 it still isn't good enough for the Macintosh: it doesn't copy the resource fork and Finder info.\n\n<<<\n''Note:'' This should be fixed for modern Python on [[Mac OS X]], but needs to be confirmed (especially due to the way the OS now stores metadata).\n<<<
! Problem:\n\nYou want to convert a tuple in a string into the corresponding tuple object; such a {{{str2tuple()}}} function would be used like this: \n \n{{{\n>>> myString = "(12, ' abc ' , ' b, c', 'd\s\s'e')"\n>>> print str2tuple(myString)\n(12, 1.0, "'XX'", ' abc ', ' b, c', "d'e", "'f")\n}}}\n\n! Solution:\n \nThe following {{{str2tuple()}}} function will do the job. \n \n{{{\ndef str2tuple(s):\n return eval(s, {'__builtins__': {}})\n}}}\n \n! Discussion:\n \nThe above function uses the {{{eval()}}} built-in function, along with a special trick. {{{eval()}}} takes a string and evaluates the contents as a Python expression, returning the value of the expression. One or two additional parameters can be supplied that must be dictionaries that will be used as the table of global and local variables, respectively. \n \nThe {{{str2tuple()}}} function uses {{{eval()}}} and provides a dictionary containing a single key-value pair, mapping the key "{{{____builtins____}}}" to an empty dictionary. "{{{____builtins____}}}" is a special name internal to Python.\n \nThe net effect of this is to evaluate the string in a highly restricted environment. This denies access to Python's standard built-in functions such as {{{open()}}}, and thus cannot access anything that isn't hardcoded in the language. For example: \n \n{{{\n>>> str2value(' (1,"test",10.2)')\n(1, 'test', 10.2)\n>>> str2value('11+13')\n24\n>>> str2value('open("/etc/passwd")')\nTraceback (innermost last):\n File "<stdin>", line 1, in ?\n File "<stdin>", line 2, in str2value\n File "<string>", line 0, in ?\nNameError: open\n>>>\n}}}\n \nNotice that {{{str2value()}}} can accept expressions such as "{{{11+13}}}" thanks to its use of {{{eval()}}}, returning an integer value. If you really want to make sure that the result is a tuple, you must use the {{{type()}}} built-in function to determine the type of the result and compare it with the type object for tuples. \n \n{{{\nv = str2value( text )\nif type(v) is not type( () ):\n raise ValueError, "Text %s does not contain a tuple" % (text,)\n}}}\n \nA clearer way to do this is to import the <<PythonModule types>> module, which contains predefined variables for the most common Python types, and compare the type of the result to {{{types.TupleType}}}.\n\n{{{\nif type(v) is types.TupleType:\n raise ValueError, "Text %s does not contain a tuple" % (text,)\n}}}
! Problem:\n\nYou wish to check whether a given key is stored in a dictionary. For example, you wish to know if the key {{{'green'}}} is in the {{{fr_colours}}} dictionary.\n\n! Solution:\n\nThere are two ways of doing this. The {{{has_key()}}} dictionary method returns true or false depending on whether the key is in the dictionary or not. \n \n{{{\n>>> fr_colours.has_key('blue')\n1\n>>> fr_colours.has_key('purple')\n0\n}}}\n \nIf a dictionary retrieval fails, Python raises a {{{KeyError}}} exception. You can catch this exception and do something appropriate in the exception handler.\n \n{{{\ntry:\n fcolr = fr_colours[ ecolr ]\nexcept KeyError:\n fcolr = "<Untranslated colour %s>" % (ecolr,)\n}}}\n \n! Discussion:\n \nDeciding whether to use {{{has_key()}}} or catch the exception is a question of both style and speed. Either way is fine from a stylistic point of view, though you may have a preference for one or the other, depending on what your programming background is. For example, one of the authors rarely catched the {{{KeyError}}} exception, preferring to write {{{if dict.has_key(key): ...}}} before a block of code which can then assume that key is present. You can do whatever you like.\n\nThe comparative speed of the two solutions depends on how often you expect the key to be present. Raising an exception and then catching it is slower than a call to the {{{has_key()}}} method. Consider a program where you're looping over 100,000 keys, and doing something different depending on whether the key is present or not. If you expect only a few keys to be missing, the exception will almost never be raised, while calling the {{{has_key()}}} method would cost a little bit of time on every pass through the loop. In this case, catching the infrequent exceptions will be faster.\n\nOn the other hand, if 50,000 or 90,000 of the keys won't be present, the overhead of raising exceptions and catching them will be larger because an exception will have to be raised more often, so checking the result of {{{has_key()}}} is probably a better idea. The exact crossover point will vary a bit; in [[a presentation|http://barry.warsaw.us/papers/ecshort.pdf]] ([[PDF]]) at the sixth Python conference, Barry Warsaw found it to be around 5 or 10 percent.
* Fixed some of the formatting in the [[Generating Random Numbers]] tiddler, moved portions of the text around.\n* Re-tagged some tiddlers, added [[Clint Checketts]]' Untagged tab to the sidebar.\n* Created some [[Grimoire Macros]] to help with formatting links to Python online references, tweaked some tiddlers to see if it works properly, revised a whole bunch of them.\n* Spent some time tracking down a few corrections reported by e-mail (from the plain [[HTML]] days)\n* Confirmed downloads so far: 1718
! Problem:\n\nYou have a function in a variable {{{F}}}, and a tuple {{{T}}} containing its arguments. You wish to call {{{F}}} with the arguments {{{T}}}.\n\n! Solution:\n \nUse the built-in function {{{apply()}}}: \n \n{{{\nresult = apply(F, T)\n}}}\n \nFunctions that don't require any arguments can be called using an empty tuple. For example, {{{time.time()}}} doesn't take any arguments, so it can be called like this: \n \n{{{\ncurtime = apply( time.time, () )\n}}}\n \nIf the function takes keyword arguments, you can also pass in a dictionary whose keys and values are the keyword arguments and their values. \n \n{{{\n# Equivalent to\n# menu.add_command(label = 'Open Help', command = window.show_help)\nkw = {'label': 'Open Help',\n 'command': window.show_help }\n\napply(menu.add_command, (), kw)\n}}}\n \n''Discussion:'' \n \nOne subtle point is that {{{apply(F, T)}}} is not the same as {{{F(T)}}}. {{{F(T)}}} calls {{{F}}} with exactly one argument, the tuple {{{T}}}, while {{{apply(F, T)}}} calls {{{F}}} with {{{T[0]}}} as the first argument, {{{T[1]}}} as the second, and so forth. An empty tuple corresponds to calling the function with no arguments. \n
! Problem:\n\nYou have a list, and wish to ensure that each item in the list is unique, only occurring once. For example, if your list is {{{[1,4,5,2,4]}}}, you would want to remove one of the 4's. \n\n! Solution:\n \nIf you can reorder the list, sort it to put duplicate values next to each other. If the list is sorted, then removing duplicates requires just a single loop. Note that the opening test for the length of the list is required - without it, if the list is empty, this code will raise an exception.\n \n{{{\nif len(List) > 1:\n List.sort() # Sort the list\n\n # Walk from the end of the list to the beginning;\n # if two elements are identical, delete one of them.\n last = List[-1] # Start with the last element\n\n for i in range(len(List)-2, -1, -1):\n if last==List[i]:\n del List[i]\n else:\n last=List[i]\n}}}\n \nIf all the elements of the list can be used as dictionary keys, you can create a dictionary with the list elements as keys, and take the result of the dictionary's {{{keys()}}} method as the new list. \n \n{{{\nd = {}\nfor x in List: d[x] = x\nList = d.keys()\n}}}\n
! Problem:\n\nYou wish to parse some sort of structured input, such as a configuration file or some data file. \n\n! Solution:\n \nThere are many possible ways to go about this. \n \nFor simple input parsing, the easiest approach is usually to split the line into whitespace-delimited words using {{{string.split()}}}, and to subsequently convert decimal strings to numeric values using {{{string.atoi()}}}, {{{string.atol()}}} or {{{string.atof()}}} If you want to use a delimiter other than whitespace, {{{string.split()}}} can handle that, and can be combined with {{{string.strip()}}} which removes surrounding whitespace from a string. \n \nFor more complicated input parsing, the <<PythonModule re>> module's regular expressions are better suited for the task, and are more powerful than C's {{{sscanf()}}}. \n \n! Discussion:\n \nA parser for configuration files is included as the <<PythonModule ConfigParser>> module in the standard library; you should take a look at it and see if it meets your needs. \n \nPython programmers often choose to decree that software configuration files should written in <<RFC 822>> format, specifying names and their corresponding values; this allows using the parser in the <<PythonModule rfc822>> module to read the files. A sample configuration file might then look like this: \n \n{{{\nTitle: Index to Python Information\nDescription: Python code, information, and documentation.\nKeywords: Python, Python articles, Python documentation\nPalette: gold\nSidebar: none\n}}}\n \nThere's a contributed module that emulates {{{sscanf()}}}, written by Steve Clift and availabe from the Contributed Software section on [[here|http://www.python.org/ftp/python/contrib-09-Dec-1999/Misc/sscanfmodule.c.Z]].\n \nIf you're trying to parse some sort of well-known file format, it's possible that a Python module has already been written to deal with it. Some common cases are: \n* [[The Python Imaging Library|http://www.pythonware.com/]] can read many different graphics formats, ranging from well-known ones such as [[GIF]] and [[JPEG]], to more specialized formats such as [[DCX]] and [[TIFF]]. \n* Support for many scientific file formats has been implemented for use with Numeric Python; consult the [[Scientific Computing|http://www.python.org/topics/scicomp/]] topic guide for more information. \n* The [[XML]] [[topic guide|http://www.python.org/topics/xml/]] tracks the available software for processing [[XML]] with Python.\n\nBefore spending a lot of effort implementing a module for a new file format, do some research first and see if someone has already done it; you might save yourself a lot of work.
! Problem:\n\nYou want to send an e-mail message that has been generated by Python code. Many applications require sending e-mail automatically. Most Web sites have a feedback form where submissions will be sent to maintenance staff. Python programs that are executed automatically may send their output to the person responsible for them, or may send an e-mail if the program can't run successfully because of an error condition, such as a full disk partition. \n \n! Solution:\n\nThe way to do it is to use the <<PythonModule smtplib>> module: \n \n{{{\nimport smtplib\n\nmessage = """From: sender@example.com\nSubject: Sample E-mail\n\nHi!\nThis message is just to say hello, and has been automatically generated.\n"""\n\nS = smtplib.SMTP('mail.example.com')\nerrdict = S.sendmail( from_addr = 'sender@example.com',\n to_addrs = ['receiver@example.com'],\n msg = message)\nif len(errdict) != 0:\n print 'Not all addresses accepted'\n print 'Failed addresses:', errdict.keys()\n}}}\n \nThe Simple Mail Transfer Protocol ([[SMTP]]) is the most common protocol used for sending mail. On Unix systems, [[SMTP]] mail is most commonly handled by the {{{sendmail}}} daemon, though there are several alternative mail transport agents, such as {{{exim}}} and {{{qmail}}}, that also implement [[SMTP]]. \n \nThe format of [[SMTP]] e-mail messages is defined in <<RFC 822>>. A message consists of a header followed by the actual content of the message. The end of the header is indicated by a blank line. A sample <<RFC 822>> message looks like this: \n \n{{{\nReturn-Path: <amk>\nReceived: (from amk@localhost)\n by 207-172-99-98.s98.tnt13.ann.erols.com (8.8.7/8.8.7) id QAA00866\n for amk; Sun, 14 Feb 1999 16:55:57 -0500\nDate: Sun, 14 Feb 1999 16:55:57 -0500\nFrom: "A.M. Kuchling" <amk@mira.example.com>\nCC: other-person@example.com\nMessage-Id: <199902142155.QAA00866@mira.example.com>\nTo: amk@mira.example.com\nSubject: Hi!\n\nHello! Long time no hear...\n}}}\n \nEach header line contains a header name, such as "{{{From}}}" or "{{{CC}}}". Header names are case-insensitive, so it doesn't matter whether the name is "{{{FROM}}}" or "{{{From}}}". A colon separates the header name from the header's contents. <<RFC 822>> defines various standard header names for specifying the recipient's address, the sender's name, addresses to which carbon copies should be sent, etc. \n\nYou can add your own headers by following a naming convention; header names beginning with "{{{X-}}}" are considered extensions, and won't be mangled or dropped by the programs transporting the mail. For example,if you're writing a set of scripts which will send an e-mail on completion, you might want to add a header giving the name of the script sending the mail. This header could be called "{{{X-Script-Name}}}". Don't invent headers whose names don't begin with "{{{X-}}}", because a mail transport agent might drop them along the path from the sender to the recipient. To create headers, simply add them to the header of your message: \n \n{{{\nmessage = """From: sender@example.com\nCc: testing@example.com\nX-Script-Name: mailnotify.py\nSubject: Sample E-mail\n\nHi! ... """\n}}}\n \nProprietary mail systems, such as cc:Mail from Lotus, or platform-specific interfaces such as Microsoft's MAPI, don't use [[SMTP]], so the <<PythonModule smtplib>> module won't help you use such systems. If you're trying to use such a system, you'll have to either access them through some platform-specific mechanism such as Microsoft's COM, or write a [[C]] extension module specifically for the mail interface. \n\nOn Unix-like systems, it's also possible to send mail by running a mail program (such as {{{/usr/lib/sendmail}}}) in a subprocess and sending it the message over a pipe; this can be done by the {{{os.popen()}}} function. Using a mail program has some drawbacks; it assumes that mail service is correctly configured on the machine, and the location of the sendmail program may vary between systems; {{{/usr/lib/sendmail}}} is most common, but alternative locations such as {{{/usr/sbin/sendmail}}} have been seen. (Refer to the manual page for {{{sendmail}}}.) Worst of all, if an error occurs, the subprocess may just print an error message which will then be ignored by your program. Using <<PythonModule smtplib>> is often the better course. \n \nHere's an example, in case you still need to send mail this way: \n \n{{{\nSENDMAIL = "/usr/sbin/sendmail" # sendmail location\nimport os\np = os.popen("%s -t" % SENDMAIL, "w")\np.write("To: recipient@example.com\sn")\np.write("Subject: test\sn")\np.write("\sn") # blank line separating headers from body\np.write("Some text\sn")\np.write("some more text\sn")\nsts = p.close()\nif sts != 0:\n print "Sendmail exit status", sts\n}}}\n
/* Style created by Nathan Bowers http://shared.snapgrid.com/gtd_tiddlywiki.html\n Imported and improved upon by Clint Checketts\nchecketts [at] gmail -dot- com */\n\n\n\n*{\n margin: 0;\n padding: 0;\n}\nbody {\n background-color: #262626;\n color: #000;\n font: 13px/125% "Lucida Grande", "Trebuchet MS", "Bitstream Vera Sans", Verdana, Helvetica, sans-serif;\n _text-align: center;\n}\n#contentWrapper {\n position: relative;\n margin: 0 auto;\n padding: 0;\n border: 1px black;\n width: 775px;\n _width: 770px; /* CSS UNDERSCORE HACK FOR PROPER WIN/IE DISPLAY */\n _text-align: left; /* CSS UNDERSCORE HACK FOR PROPER WIN/IE DISPLAY */ \n}\n#header{\n color: #fff;\n padding: 20px 20px 10px 0;\n}\n#mainMenu {\n position: static;\n line-height: 166%;\n background: #600;\n border-right: 3px solid #500;\n margin: 1em 0 0 0;\n width: 215px;\n padding: 0;\n text-align: left;\n}\n#sidebar {\n position: static;\n margin: 2em 0 0 0;\n float: left;\n clear: left;\n color: #000000;\n width: 218px;\n}\n#displayArea {\n float: right;\n margin: 0 2em 0 0;\n _margin: 0;\n width: 520px;\n _width: 545px; /* CSS UNDERSCORE HACK FOR PROPER WIN/IE DISPLAY */\n}\n#messageArea\n{\n font-size: 13px;\n font-weight: bold;\n padding: 5px;\n width: 41em;\n margin: 5px 0px;\n background: #ffe72f;\n border-right: 3px solid #da1;\n border-bottom: 3px solid #a80;\n text-align: center;\n display: none;\n}\na:link, a:visited, a:hover, a:active {\n text-decoration: none;\n}\n\n/* HEADER ========================================================== */\n#titleLine{\n background: transparent;\n margin: 0;\n padding: 0;\n}\n#siteTitle {\n font-size: 30px;\n}\n#siteSubtitle {\n font-size: 13px;\n padding-left: 10px;\n}\n#titleLine a {\n color: #cf6;\n}\n/* SIDEBARS ========================================================== */\n#mainMenu a {\n color: #fff !important;\n background: #700;\n display: block;\n padding: 0 5px 0 10px;\n height: 22px;\n line-height: 22px;\n border-bottom: 1px solid #500;\n border-top: 1px solid #900;\n text-transform: capitalize;\n}\n#mainMenu a.tiddlyLink:hover, #mainMenu a.button:hover{\n background: #b00 !important;\n}\n#sidebarTabs {\n background: transparent;\n padding: 8px 0 0 10px;\n}\n#sidebarTabs a {\n color: #fff;\n padding: 2px 8px 1px 8px;\n height: 22px;\n}\n#sidebarTabs a:hover {\n background: #000;\n color: #fff;\n}\n#sidebarTabs a:active {\n color: #000000;\n}\n#sidebarContent{\n padding: 0 10px 10px 10px;\n font-size: 11px;\n clear: both;\n}\n#sidebarContent br{\n display: none;\n}\n.sidebarSubHeading {\n padding: 8px 0 0 0;\n display: block;\n width: 100%;\n color: #000;\n}\n#sidebarContent a {\n color: #fff;\n display: block;\n margin: 1px 0 1px 5px;\n padding: 0;\n width: 100%;\n}\n#sidebarContent a:hover {\n color: #fff;\n background: #000;\n}\n#licensePanel {\n padding: 0px 10px;\n font-size: 11px;\n}\n#licensePanel a {\n color: #960;\n display: block;\n margin-top: 10px;\n}\n#licensePanel a:hover {\n color: #fff;\n}\n#licensePanel a:active {\n color: #fff;\n}\n#sidebarOptions {\n background: #eeb !important;\n border-right: 3px solid #bb8;\n color: #b4c675 !important;\n padding: 5px 0;\n}\n#sidebarOptions a {\n color: #700 !important;\n display: block;\n padding: 0 !important;\n margin: 3px 10px;\n}\n#sidebarOptions a:hover, #sidebarOptions a:active {\n color: #fff !important;\n background: #700 !important;\n}\n#sidebarOptions input {\n margin: 2px 10px;\n border: 1px inset #333;\n}\n#sidebarOptions .sliderPanel {\n display: none;\n background: #fff;\n color: #000;\n padding: 5px 10px;\n font-size: 11px;\n}\n.sliderPanel div{\n margin: 5px 0;\n}\n#sidebarOptions .sliderPanel a:link, #sidebarOptions .sliderPanel a:visited {\n color: #17b !important;\n font-weight: normal;\n margin: 0;\n display: inline;\n}\n#sidebarOptions .sliderPanel a:hover, #sidebarOptions .sliderPanel a:active {\n color: #fff !important;\n background: #000;\n}\n.optionsText {\n margin: 2px 0;\n}\n#tabTimeline {\n font-weight: bold;\n display: inline;\n background: #960;\n border-right: 1px solid #740;\n}\n#popup{\n background-color: #cf6;\n color: #000;\n}\n\n.tabset{\n border-right: 3px solid #bb8;\n background-color: #eeb;\n}\n#contentWrapper a.tab {\n font-weight: bold;\n display: inline;\n margin: 0px 2px; \n border-right:1px solid #aaa;\n font-size: 12px;\n color: #fff !important;\n text-decoration: none;\n}\n#contentWrapper a.tab:hover {\n background: #000 !important;\n}\n#contentWrapper a.tabSelected {\n background-color: #960 !important;\n border-right: 1px solid #740;\n padding: 4px 4px 2px 4px;\n}\n#contentWrapper a.tabUnselected {\n background-color: #660 !important;\n border-right: 1px solid #440;\n padding: 4px 4px 0px 4px;\n color: #fff !important;\n}\n/*===================================================================*/\n/*=====================================================================*/\n#sidebarTabs{\n margin: 0;\n padding: 0;\n}\n#contentWrapper .tabContents {\n background-color: #960;\n border-bottom: solid #520 2px;\n border-right: 3px #740 solid;\n}\n#contentWrapper .tabContents a.tiddlyLink, #contentWrapper .tabContents a.button{\n height: auto;\n margin: 0 0 0 1em !important;\n padding: 0 !important; \n background-color: transparent;\n color: #fff !important;\n font-weight: normal;\n text-decoration: none;\n}\n#contentWrapper .tabContents a.tiddlyLink:hover,#contentWrapper .tabContents a.button:hover{\n background-color: #000;\n}\n#contentWrapper .txtMoreTab .tabset{\n border: 0;\n background-color: transparent;\n}\n#contentWrapper .txtMoreTab a.tabUnselected {\n background-color: #b00 !important;\n padding: 2px 4px 0px 4px;\n color: #fff !important;\n border-right: 1px solid #900;\n}\n#contentWrapper .txtMoreTab a.tabSelected {\n background-color: #700 !important;\n padding: 2px 4px 2px 4px;\n color: #fff !important;\n border-right: 1px solid #500;\n}\n#contentWrapper .txtMoreTab a.tab:hover {\n background-color: #000 !important;\n border-right: 1px solid #500;\n}\n.txtMoreTab .tabContents {\n background-color: #700 !important;\n border-right: 3px solid #500 !important;\n border-bottom: 3px solid #500 !important;\n color: #fff;\n font-weight: bold;\n}\n.txtMoreTab .tabContents a{\n font-weight: normal;\n background-color: transparent !important;\n}\n.txtMoreTab .tabContents a:hover{\n background-color: #000 !important;\n}\n#sidebar popup{\n padding: 0;\n}\n\n#contentWrapper .viewer #popup *{\n color: #000 !important;\n}\n#contentWrapper #popup a{\n color: #000 !important;\n margin: 0 !important;\n padding: 0;\n}\n#contentWrapper #popup hr{\n border-top: solid 1px #000;\n border-left: 0;\n border-right: 0;\n border-bottom: none;\n height: 1px;\n color: #000;\n margin: 5px 0 !important;\n}\n#contentWrapper #popup a:hover{\n background-color: #ef9 !important;\n}\n\n\n\n\n\n\n\n\n/* TIDDLER DISPLAY/EDIT SPACE ============================================= */\n.tiddler {\n margin: 0 0 10px 0;\n padding: 0 15px;\n width: 99%;\n border-right: 3px solid #aaa;\n border-bottom: 3px solid #555;\n background: #fff;\n}\n#displayArea .tiddlyLinkExisting {\n font-weight: bold;\n text-decoration: none;\n}\n#displayArea .tiddlyLinkNonExisting {\n font-style: italic;\n text-decoration: none;\n}\n#displayArea .externalLink {\n text-decoration: underline;\n}\n.title {\n font-size: 1.5em;\n padding: 0 0 0 0;\n font-weight: bold;\n display: block;\n color: #900;\n}\n.toolbar {\n font-weight: normal;\n font-size: 11px;\n visibility: hidden;\n text-align: right;\n padding: 5px 0;\n}\n.toolbar a {\n padding: 1px 5px;\n color: #000 !important;\n text-decoration: none;\n border: 1px outset #cf6;\n background: #cf6;\n}\n.toolbar a:hover {\n background: #ef9 !important;\n}\n.toolbar a:active {\n background: #ff0 !important;\n}\n.viewer .tabset{\n background: transparent;\n border: 0;\n}\n\n\n\n\n\n\n\n\n\n\n\n\n.viewer a.button{\n background-color: transparent !important;\n color: #700 !important;\n}\n\n.viewer {\n line-height: 140%;\n}\n.viewer a:link, .body a:visited {\n color: #15b;\n text-decoration: underline;\n}\n.viewer a:hover {\n color: #fff;\n background: #000;\n}\n.viewer blockquote {\n border-left: 3px solid #777;\n margin: 5px;\n padding: 5px;\n}\n.viewer ul {\n padding-left: 30px;\n}\n.viewer ol {\n padding-left: 30px;\n}\nol\n{ \n list-style-type: decimal;\n}\nol ol\n{ \n list-style-type: lower-alpha;\n}\nol ol ol\n{ \n list-style-type: lower-roman;\n}\n.viewer ul, .viewer ol, .viewer p {\n margin: 5px 0 12px 0;\n}\n.viewer li {\n margin: 3px 0;\n}\n.viewer h2,h3,h4,h5,h6 {\n font-weight: bold;\n background: #eee;\n padding: 2px 10px;\n margin: 5px 0;\n}\n.viewer h2 {\n font-size: 1.3em;\n}\n.viewer h3 {\n font-size: 1.2em;\n}\n.viewer h4 {\n font-size: 1.1em;\n}\n.viewer h5 {\n font-size: 1em;\n}\n.viewer h6 {\n font-size: .9em;\n}\n.viewer table {\n border-collapse: collapse;\n border: 2px solid #303030;\n font-size: 11px;\n margin: 10px 0;\n}\n.viewer th {\n background: #eee;\n border: 1px solid #aaa;\n padding: 3px;\n}\n.viewer td {\n border: 1px solid #aaa;\n padding: 3px;\n}\n.viewer caption {\n padding: 3px;\n}\n.viewer hr {\n border: none;\n border-top: dotted 1px #777;\n height: 1px;\n color: #777;\nmargin: 7px 0;\n}\n.body\n{\n margin: 5px 0 15px 0;\n padding: 5px 0;\n border-top: 1px solid #ccc;\n}\n.highlight {\n color: #000;\n background: #ffe72f;\n}\n.editor {\n font-size: 8pt;\n color: #402C74;\n font-weight: normal;\n padding: 10px 0;\n}\n.editor input, .editor textarea {\n display: block;\n font: 10px/130% "Andale Mono", "Monaco", "Lucida Console", "Courier New", monospace;\n margin: 0 0 10px 0;\n border: 1px inset #333;\n padding: 2px 0;\n}\n.editor textarea {\n height: 500px;\n}\ninput:focus, textarea:focus\n{\n background: #ffe;\n border: 1px solid #000 !important;\n}\n.editorFooter, .footer{\n font-size: 10px;\n}\n.editorFooter a.button:hover, .footer a.button:hover{\n color: #fff;\n}\n#storeArea, #copyright, .site_description {\n display: none;\n}\n#floater {\n background: #df9;\n border: 3px solid #999;\n color: #df9;\n position: absolute;\n left: -99999999px;\n top: -99999999px;\n width: 1px;\n display: none;\n}\n\n@media print{\n*\n{\n margin: 0;\n padding: 0;\n}\nbody {\n background: #fff;\n color: #000;\n width: 2.5in;\n height: 4.7in;\n font-size: 6.2pt;\n font-family: "Lucida Grande", "Bitstream Vera Sans", Helvetica, Verdana, Arial, sans-serif;\n}\nimg {\n max-width: 2.2in;\n max-height: 4.3in;\n}\n#header, #side_container, #storeArea, #copyright, .toolbar, #floater, #messageArea, .save_accesskey, .site_description\n{\n display: none;\n}\n#tiddlerDisplay, #displayArea\n{\n display: inline;\n}\n.tiddler {\n margin: 0 0 2em 0;\n border-top: 1px solid #000;\n page-break-before: always;\n}\n.tiddler:first-child {\n page-break-before: avoid;\n}\n.title {\n font-size: 1.6em;\n font-weight: bold;\n margin-bottom: .3em;\n padding: .2em 0;\n border-bottom: 1px dotted #000;\n}\np, blockquote, ul, li, ol, dt, dd, dl, table\n{\n margin: 0 0 .3em 0;\n}\nh1, h2, h3, h4, h5, h6\n{\n margin: .2em 0;\n} \nh1\n{\n font-size: 1.5em;\n}\nh2\n{\n font-size: 1.3em;\n}\nh3\n{\n font-size: 1.25em;\n}\nh4\n{\n font-size: 1.15em;\n}\nh5\n{\n font-size: 1.1em;\n}\nblockquote\n{\n margin: .6em;\n padding-left: .6em;\n border-left: 1px solid #ccc;\n}\nul\n{\n list-style-type: circle;\n}\nli\n{\n margin: .1em 0 .1em 2em;\n line-height: 1.4em; \n}\ntable\n{\n border-collapse: collapse;\n font-size: 1em;\n}\ntd, th\n{\n border: 1px solid #999;\n padding: .2em;\n}\nhr {\n border: none;\n border-top: dotted 1px #777;\n height: 1px;\n color: #777;\n margin: .6em 0;\n}}
The [[Conversion Script]] is a very simple demo of how to parse clean, structured [[HTML]] using the standard <<PythonModule HTMLParser>> object. The <<PythonModule HTMLParser>> is actually a lot more flexible than it seems, and can be used for simple [[XML]] parsing as well.\n\nHowever, if you have to deal with mis-formatted [[HTML]] or don't want to get into the complexity of Python [[XML]] bindings, a nice alternative might be [[BeautifulSoup|http://www.crummy.com/software/BeautifulSoup/]], which despite requiring some tinkering with (and probably more documentation and samples), can handle pretty much anything on the Web.\n\nBut any mention of [[XML]] parsing wouldn't be complete without mentioning [[RSS]] or [[Atom]] feeds, which are best handled with [[Mark Pilgrim]]'s [[Universal Feed Parser|http://feedparser.org/]]. currently the basis for many Python-based news aggregators.
! Problem:\n\nYou have two dictionaries {{{d1}}} and {{{d2}}}. You wish to add the key/value pairs from {{{d2}}} to {{{d1}}}. \n\n! Solution:\n \nThe {{{update}}} method of a dictionary adds the contents of another dictionary. To solve this problem, you can simply do: {{{d1.update(d2)}}}. \n \n{{{d1.update(d2)}}} is equivalent to the following code: \n \n{{{\nfor key, value in d2.items():\n d1[ key ] = value\n}}}\n \nIf the same key is associated with a value in both {{{d1}}} and {{{d2}}}, {{{update()}}} will replace the value in {{{d1}}} with the value from {{{d2}}}. {{{d2}}} is never modified by this method.\n
! Problem:\n\nYou want to have a function that returns more than one value as its result. For example, you may have a function that takes a colour name, and returns three numbers, the red, green, and blue values for that colour. \n\n! Solution:\n\nThe simplest and most common solution is to return a tuple containing the different values: \n \n{{{\ndef get_rgb_colour(colour_name):\n # ... set R, G, B, to the values\n return R, G, B\n}}}\n\n! Discussion:\n\nAn alternative solution, using a class instance to hold return values, is useful if you want to return very many values, or differing numbers of values in different cases. You would set instance values of the class instance, and then return the instance to the caller. \n\n{{{\nclass RGBSetting: pass\n\ndef get_rgb_colour(colour_name):\n retval = RGBSetting()\n # ... set retval.R, retval.G, retval.B, to the values\n return retval\n}}}\n
There is a problem that routinely bedevils new Python users who come from a Windows or DOS background. The problem is that on Windows, a backslash is a separator in filenames, whereas on Unix (where Python originated) the backslash has an entirely different function (as an escape character) and the //forward// slash is the filename separator character.\n \nWhen a person from a Windows background starts having problems with filenames, and goes looking for a solution, the first thing that he (or she) usually finds is Python's "raw" strings. However, from the perspective of a Windows user, raw strings aren't truly raw they are only semi-raw, as you will rudely discover the first time that you use a raw string to specify a filename (or filename part) that ends with a single backslash.\n \nA better strategy is to routinely code your filenames using forward slashes, and then use a Python function such as {{{os.path.normcase}}} to change the separator to whatever is appropriate to the local operating system. A nice bonus of ths strategy is that it is platform independent\n \n{{{\nimport os.path\nmyFilename = "c:/mydir/myfile.txt"\nmyFilename = os.path.normcase(myFilename)\n}}}\n
* Added an RFC macro to ease referencing IETF material.\n* Many more tiddlers reformatted.\n* Replaced the gradient image from the StyleSheet with a flat gunmetal grey (it was generating unnecessary network traffic).\n* Confirmed downloads so far: 2271
In a radical departure from the HTML version, the TOC is generated dynamically from the TiddlyWiki tags:\n\n* <<tag Numbers>>\n* <<tag Strings>>\n* <<tag Tuples>>\n* <<tag Lists>>\n* <<tag Dictionaries>>\n* <<tag Objects>>\n* <<tag Functions>>\n* <<tag Files>>\n* <<tag Directories>>\n* <<tag Parsing>>\n* <<tag Network>>\n* <<tag Portability>>\n* <<tag Exceptions>>
Email address: checketts [at] gmail -dot- com\n\nClint is a student at BYU-Idaho studying Information Systems, and has published a number of extra TiddlyWiki [[styles|http://15black.bluedepot.com]], as well as several standalone tweaks that were incorporated into this file.
These InterfaceOptions for customising TiddlyWiki are saved in your browser.\n\nYour username for signing your edits. Write it as a WikiWord (eg JoeBloggs)\n\n<<option txtUserName>>\n\n<<option chkSaveBackups>> SaveBackups\n<<option chkAutoSave>> AutoSave\n<<option chkAnimate>> EnableAnimations\n<<option chkSinglePageMode>> SinglePageMode\n\nSee AdvancedOptions for more
! Problem:\n\nWhen a file will be accessed and modified by several programs at the same time, you need to ensure that the programs can't make conflicting changes at the same time, which can result in the file being corrupted. \n\n! Solution:\n\nThis is accomplished by locking the file. \n \nThe <<PythonModule posixfile>> module provides an object that acts like Python's standard file objects, but adds some extra methods. One of the extra methods is {{{lock(mode, len, start, whence)}}}. mode is a string specifying whether you want a read or write lock, or to give up an already-acquired lock. \n \nFor example, to gain a write lock for the entire file: \n \n{{{\nfile.lock('w')\n}}}\n\n! Discussion:\n\nLocks can be for reading or writing. Multiple read locks can be held by different processes, because several processes can read the same data at the same time without harm. Only a single write lock can be held at a given time, and read locks won't be granted while a write lock is being held. \n \nWhen requesting a lock, the default is to lock the entire file. It's also possible to lock a part of the file, by specifying the start and length of a region in the file. This allows multiple processes to modify different parts of a file at the same time. Consult <<PythonModule posixfile>> for more information. \n
! Problem:\n\nYou want to process a file, but starting with the last lines first.\n\n! Partial Solution:\n\nIf you can read the entire file into memory, you can simply read all the data into a list and then reverse the list:\n \n{{{\nL = open('myFile').readlines()\nL.reverse()\n}}}\n \nOn a character-by-character basis, a similarly memory-bound solution is: \n \n{{{\nimport string\nL = string.split(open('thefile', 'r').read(), '')\nL.reverse()\n}}}
! Problem:\n\nYou wish to create a list of lists.\n\n! Solution:\n \nThis obvious solution for creating a list of {{{N}}} lists is wrong; see the Discussion for an explanation. \n \n{{{\nLL = [ [] ] * N\n}}}\n \nInstead, build an {{{N}}}-element list first, and then replace each element with a list. \n \n{{{\nLL = [None] * N\nfor i in range(N): LL[i] = []\n}}}\n\nIf you want to fill out the contained lists with default values, simply replace {{{[]}}} with an expression like {{{N*[0]}}}. Elements could then be retrieved by accessing {{{LL[i][j]}}}. \n\n! Discussion:\n \nWhy doesn't {{{[ [] ] * N}}} work as expected? When multiplying a list, Python copies the contents of the list //by reference//.\n\nThis means that you'll wind up with a list containing {{{N}}} references to the same objects, which is fine for immutable objects such as floating point numbers or tuples, but can be confusing with mutable objects such as lists. To make this clearer, consider the list constructed for {{{N=5}}}. \n\nWhat happens when you append an element to the first list? \n \n{{{\n>>> LL = [ [] ] * N\n>>> print LL\n[[], [], [], [], []]\n>>> LL[0].append(1)\n>>> LL\n[[1], [1], [1], [1], [1]]\n}}}\n \nAll of the lists are modified, not just the first one! The {{{is}}} operator will tell you that all the elements of {{{LL}}} are actually the same list; a true value is returned by {{{LL[0] is LL[1]}}}. \n \nA common use of multi-dimensional lists is to store matrices. Before reinventing the wheel and writing yet another matrix type, take a careful look at [[Numeric Python|http://www.python.org/topics/scicomp]], which includes a matrix type, interfaces to libraries of functions such as LINPACK, and lots of other modules useful for numeric work.
! Problem:\n\nYou want to rename a file on the filesystem, and have already figured out how to deal with your operating system's naming conventions inside Python.\n\n! Solution:\n\nSimple: use {{{os.rename}}}:\n\n{{{\n#Rename file with filename f1 to filename f2\nos.rename(f1,f2)\n}}}
! Problem:\n\nYou want to make a list of the files in a directory, in order to do something for every file. \n\n! Solution\n\nThe {{{os.listdir(path)}}} function returns a list of strings containing all the contents of the directory specified by {{{path}}}, in no particular order. Note that the list will also include directory names in the resulting list. \n\n{{{\n>>> os.listdir('/usr')\n['X11R6', 'bin', 'dict', 'doc', 'etc', 'games', ... ]\n}}}\n \nIf you want to list all the files matching a wildcard specification such as {{{*.py}}}, you can implement it by checking each filename in the list returned by {{{os.listdir()}}}. The {{{glob()}}} function in the <<PythonModule glob>> module can do this for you: \n \n{{{\n>>> import glob\n>>> glob.glob('/usr/lib/python1.5/B*.py')\n['/usr/lib/python1.5/BaseHTTPServer.py', '/usr/lib/python1.5/Bastion.py']\n}}}\n \n{{{glob.glob()}}} will also list directories that match the wildcard specification. \n \nOnce you've gotten a list of filenames, you'll often want to limit it to those names that correspond to files and not directories. The {{{os.path}}} module contains functions called {{{isfile(path)}}}, {{{isdir(path)}}}, and {{{islink(path)}}} which return true if the path corresponds to a file, directory, or symbolic link. \n \nThese functions can be combined with the built-in {{{filter()}}} to easily select those paths that are actually files: \n \n{{{\nfilelist = os.listdir('.')\nfilelist = filter(os.path.isfile, filelist)\n}}}
The Wichmann-Hill random number generator is described in: "An efficient and portable pseudo-random number generator (Algorithm AS 183)", Wichmann, B. A. Hill, I. D., //Applied Statistics// 31 (1982) 188-190.
Eric wrote a [[SinglePageModePlugin|http://www.elsdesign.com/tiddlywiki/#SinglePageModePlugin]] for TiddlyWiki, which has been incorporated into the SiteMacros to make the Grimoire easier to read for people who prefer a "single item" view.
! Problem:\n\nYou wish to pass a function as an argument to another function. \n\n! Solution:\n \nPython is flexible enough to treat functions and methods in the same way as ordinary variables. \n \n{{{\nF = f.write\nF(s)\n}}}\n \nis the same thing as: \n \n{{{\nf.write(s)\n}}}\n \nAs a computer scientist would describe it, functions are first-class objects in Python. So, you can simply pass a function as one of the arguments: \n \n{{{\ndef repeat_func(func, N, data):\n "Repeat a function N times"\n for i in range(N):\n data = func(data)\n return data\n\nrepeat_func(differentiate, 3, data)\n}}}\n \nIt's also possible to store functions in Python data structures, such as variables, lists, tuples, and class instances. For example, the following function takes a list of functions, and calls them all, from left to right. \n \n{{{\ndef compose(func_list, data):\n for F in func_list:\n data = F(data)\n return data\n}}}\n\n! Discussion:\n\nA common application of this is to keep a dictionary of handler functions, retrieving the function to call. The following toy example has a dictionary mapping command names to the functions that should be called: \n \n{{{\ndef output_status():\n ...\n\ndef set_bf_mode():\n ...\n\n... other function definitions ...\n\ncmd_dict = {'status': output_status, 'brightfield', set_bf_mode,\n 'darkfield': set_df_mode, 'icr': set_icr_mode}\n\ndef call_command(cmd_name):\n function = cmd_dict[cmd_name]\n function()\n}}}\n \nIt's not necessary to actually have a {{{def}}} statement in order to create a function. The {{{lambda}}} keyword is used to create small unnamed functions. The function is limited to a single expression, but that's enough to be useful in many cases. A common use for {{{lambda}}} is in concert with built-in functions like {{{map()}}}, which loops over the elements of a list, performs a function on each list element, and returns a list containing the results. \n \n{{{\n>>> map(string.upper,\n... ["Here's", "a", "list", "of", "words"] )\n["HERE'S", 'A', 'LIST', 'OF', 'WORDS']\n}}}\n \n{{{lambda}}} would be used if there's no built-in function corresponding to what you need. For example, the following code would take the first character of every word in the list: \n \n{{{\n>>> map(lambda word: word[0],\n... ["Here's", "a", "list", "of", "words"] )\n['H', 'a', 'l', 'o', 'w']\n}}}\n\nHere's another example. In this case, a default argument is used to bind the {{{f.write()}}} method to the local variable {{{wr}}}, and added a newline before calling the write method. \n\n{{{\nftp.retrlines("RETR sightings.txt",\n lambda s, wr = f.write: wr( s+"\sn" ) )\n}}}
! Problem:\n\nYou need a dictionary that can store the key and more than one value. For example, after {{{d[key] = value1}}} and {{{d[key] = value2}}}, you want {{{d[key]}}} to return a list containing {{{[value1, value2]}}}. This differs from an ordinary dictionary, where assigning to the same key twice causes the first value to be deleted and replaced by the second.\n\n! Solution:\n \nThe following class stores lists of values; setting a new value causes it to be appended to the list. \n \n{{{\nimport UserDict\nclass MultipleDict(UserDict.UserDict):\n def __setitem__(self, key, item):\nif self.data.has_key( key ):\n self.data[key].append( item )\nelse:\n self.data[key] = [item]\n}}}\n \nUsing the class is simple: \n \n{{{\nd = MultipleDict()\nd[1] = 'a'\nd[1] = 'b'\nd[1] = 'c'\n}}}\n \n{{{d[1]}}} will return {{{['a', 'b', 'c']}}}. To remove the key, you'll have to delete the entire list of values with {{{del d[1]}}}. \n \nThis class subclasses the {{{UserDict}}} class from the <<PythonModule UserDict>> module, which implements all the methods of dictionaries in a Python class, and stores its contents in the {{{data}}} attribute, which is a real dictionary. \n\nTo implement the desired change in behaviour, we only have to override the {{{____setitem____}}} method, and store the right result in {{{self.data}}}. \n\n<<<\n''Note:'' Since Python 2.2, you can derive from the built-in types ("new style classes"), and {{{MultipleDict}}} would be best implemented as inheriting from {{{dict}}}.\n<<<
! Problem:\n\nYou have a sequence, and you wish to loop over its contents. \n\n! Solution:\n \nThis is the purpose of the {{{for}}} statement: \n \n{{{\nfor item in [1,2,3,4,5]:\n print item\n}}}\n \nThis will work for tuples and strings, too. \n \n! Discussion:\n \nTo iterate over a list in reverse order, the traditional solution before Python 2.4 was to simply reverse the list:\n \n{{{\nList.reverse()\nfor item in list:\n # ... do something with item ...\n}}}\n\nHowever, this modifies the list itself, so as of Python 2.4, a built-in {{{reverse}}} iterator is also available:\n\n{{{\nfor item in reverse(List):\n # do something with your item\n}}}\n\nThis allows reverse iteration over any sequence without modifying the underlying sequence, and therefore allows easy iteration over immutable sequences such as strings or tuples:\n\n{{{\ns = "abcd"\ns.reverse()\nTraceback (most recent call last):\n File "<stdin>", line 1, in ?\nAttributeError: 'str' object has no attribute 'reverse'\n>>> for i in reversed(s):\n... print i\n...\nd\nc\nb\na\n}}}\n\nAn equivalent function, {{{sorted}}}, exists for sorting sequences.\n\n<<<\n''Note:'' This will probably require a modern Python example of its own.\n<<<\n\nHere's another way to iterate backwards when you have some other sequence type like a tuple or a string, or if reversing the list is unacceptable to you. You'll have to loop over the indices, from the length of the sequence minus one, down to zero. \n \n{{{\nfor i in range(len(seq)-1, -1, -1):\n item = seq[i]\n # ... do something with item ...\n}}}
Xavier supplied the {{{reverse}}} examples for [[Iterating Over a List]] and a set of notes for [[Multiple-Valued Dictionaries]].
! Problem:\n\nYou want to process not merely a single directory, but an entire hierarchy of files and folders, and perhaps find a specific set of files.\n\n! Solution:\n\nImport the <<PythonModule os>> module, and use {{{os.path.walk(path, function, arg)}}}. That recursively walks through the tree rooted at {{{path}}}, and calls {{{function()}}} in each directory that's visited.\n\n{{{function()}}} must accept 3 arguments: ({{{arg}}}, {{{dirname}}}, {{{name_list}}}). {{{arg}}} is the same as the value passed to {{{os.path.walk}}}; {{{dirname}}} is the current directory name; {{{name_list}}} is a list of the names of the directories and filenames in the directory. You can modify {{{name_list}}} in place to avoid traversing certain subdirectories. \n\nHere's a simple program to find files: \n\n{{{\nimport os, sys\n\ndef find(arg, dirname, names):\n if arg in names:\n print os.path.join(dirname, arg)\n\nos.path.walk(sys.argv[1], find, sys.argv[2])\n}}}\n\nSample usage: \n \n{{{\n$ python ~/t.py /tmp/ README\n/tmp/xml-0.4/README\n/tmp/xml-0.4/demo/README\n/tmp/xml-0.4/dom/README\n}}}\n
The core of the //Grimoire// was originally developed and released by [[Andrew M. Kuchling]] in May, 1999. However, it never reached a stage where Andrew felt that it was ready for publication, and eventually he withdrew it. [[Steve Ferg]], however, had found the Grimoire very helpful as he was learning Python, and he persuaded Andrew to allow him to take over maintenance of the document in August, 2002.\n\nIn December 2004, Andrew and Steve released the Grimoire under the [[Creative Commons Attribution-NonCommercial-ShareAlike License 2.0|http://creativecommons.org/licenses/by-nc-sa/2.0/]] and [[Rui Carmo]] began hosting it at [[The Tao of Mac|http://the.taoofmac.com/space/Python/Grimoire]], where it lingered until [[Rui|Rui Carmo]] decided to re-cast it in [[TiddlyWiki]] format for ease of use.\n\n[[TiddlyWiki]] is the work of [[Jeremy Ruston]], and the current look and feel is based on enhancements by [[Clint Checketts]]. There are more contributors and sources of inspiration, all tagged as<<tag Credits>>
! Problem:\n\nYou want to read a file that's been compressed with the GNU {{{gzip}}} program, or want to write a compressed file that {{{gzip}}} can read.\n\n! Solution:\n \nThe <<PythonModule gzip>> module provides a {{{GzipFile}}} class for reading and writing {{{gzip}}}'ped files. {{{GzipFile}}} instances imitate the methods of Python's standard file objects. To read a file: \n \n{{{\nimport gzip\n\n# Open the file in 'r' mode for reading\nfile = GzipFile('data.gz', 'r')\nline = file.readline() # Read a single line\ndata = file.read(1024) # Read 1K of data\nfile.close()\n}}}\n \nWriting compressed data is much the same: \n \n{{{\nimport gzip\n\n# Open the file in 'w' mode for writing\nfile = GzipFile('output.gz', 'w')\nfile.write( 'First line of output\sn')\nfile.close()\n}}}\n\n! Discussion:\n\nIt's legal to use the {{{'a'}}} mode to append data to a compressed file; the {{{gzip}}} file format can handle a file with several chunks of compressed data. When reading such a file with {{{GzipFile}}}, you won't be able to tell where one chunk leaves off and the next begins because {{{GzipFile}}} seamlessly handles the transition between them. \n \nThe <<PythonModule gzip>> module is built on top of the <<PythonModule zlib>> module, which compresses strings of data. The <<PythonModule zlib>> module can be useful on its own to save disk space or network bandwidth. \n\nFor example, you can compress data before sending it over a TCP/IP socket or storing it in a DBM file. Here's a short example:\n \n{{{\n>>> import zlib\n>>> s = "This is a test of the emergency broadcast chicken."\n>>> comp = zlib.compress(s)\n>>> comp\n'x\s234\s013\s311\s310,V\s000...'\n>>> print zlib.decompress( comp )\nThis is a test of the emergency broadcast chicken.\n}}}\n \nThe <<PythonModule zlib>> module also provides compressor and decompressor objects that can be used to compress large amounts of data without having to squeeze all of it into memory.\n
[[Stephen Ferg|http://www.ferg.org/]] was the second maintainer of the Grimoire, and has some interesting [[Papers and Projects|http://www.ferg.org/projects/index.html]] online that may be useful to Python newbies - most notably [[a list of Python Gotchas|http://www.ferg.org/projects/python_gotchas.html]].
Python offers a variety of different numeric types: integers, which are fast but limited in size; long integers, which are slower but can be of arbitrary size; floating-point numbers; and complex numbers. \n \nThe simplest and most basic type are integers, which are represented as a C {{{long}}}. Their size is therefore dependent on the platform you're using; on a 32-bit machine, they can range from -2147483647 to 2147483647. Python programs can determine the highest possible value for an integer by looking at {{{sys.maxint}}}; the lowest possible value will usually be {{{-sys.maxint - 1}}}. \n \nLong integers are an arbitrary-precision integer type. They're slower than regular integers, but don't have the size limitations. Long integer literals have the letter "{{{L}}}" as a suffix; a lowercase "{{{l}}}" is also legal, but should be avoided because it's often difficult to distinguish a lowercase letter "{{{l}}}" from the numeral "{{{1}}}". If integers and long integers are combined in an expression, the regular integer is converted to a long integer automatically: \n \n{{{\n 2L + 3 5L 5L ** 100 7888609052210118054117285652827862296732064351090230047702789306640625L \n}}}\n \nPython's floating point numbers are represented as C's {{{double}}} type, and behave pretty much as you'd expect: \n \n{{{\n 5.4 / 2.3 2.34782608696 6.4 * 2 12.8 7.5 % 5 2.5 \n}}}\n \nIn operations that mix floating-point numbers and integers, the integers will be converted to floating-point before computing the result, which will be left as a float. \n \nPython also supports a complex number type. (It's possible to compile the Python interpreter without complex numbers, but few people bother to do so; saving 20K of code isn't that important.) Complex numbers are represented by a floating point constant with a suffix of "{{{j}}}"or "{{{J}}}" suffix, "{{{j}}}" being used to represent the square root of -1 in many engineering contexts. \n \n{{{\n 1j * 1J (-1+0j) (3 - 7j) + (2 + 1j) (5-6j) (1 + 3j) / (2 - 4j) (-0.5+0.5j) \n}}}\n \nNote that an expression like {{{1 + 3j}}} isn't a constant, but an expression that adds two constants: {{{1}}} and {{{3j}}}. This is a minor semantic quibble, whose major significance is that you should make liberal use of parentheses in complex expressions. {{{1+3j / 2-4j}}} is not the same as {{{(1+3j) / (2-4j)}}}, because the first expression will evaluate {{{3j/2}}} first. \n
In Python, functions are defined using the {{{def}}} statement. The following example defines a function called {{{get_word()}}}. {{{get_word()}}} will take two parameters: a string sentence and a number N, and returns the N'th word of sentence. \n \n{{{\nimport string\n\ndef get_word(sentence, N):\n words = string.split(sentence)\n return words[N]\n}}}\n \nThe {{{return}}} statement, when followed by an expression, causes the value of the expression to be returned as the result of the function. In the above example, {{{words[N]}}} is returned as the result. \n \nPython functions always produce a result, whether the code contains a {{{return}}} statement or not. If the path of execution falls off the end of the function, {{{None}}} is returned. A lone {{{return}}} statement, not followed by an expression, also returns None. \n \nDefault values for parameters can be specified by placing a "{{{=}}}" and an expression or a literal value after the parameter name. (For a discussion of using expressions to specify a default value, see the next section.) \n \nIn the following example, the function's filename parameter has no default value, the compresslevel argument has a default value of 9, and the fileobj parameter has a default value of {{{None}}}. \n \n{{{\ndef open_file(filename,\n compresslevel = 9,\n fileobj = None):\n if fileobj is None:\n fileobj = open(filename, 'w')\n compressor = zlib.compressobj( compresslevel )\n}}}\n \nTo call a function with keyword arguments that can be specified in any order, no special function definition is needed, though default arguments are often used in concert with keywords. The function call can simply give the names of function parameters, followed by an "{{{=}}}" and the desired value for the parameter. Given a function definition like {{{f(a, b = 'empty', c=3.5)}}}, the following function calls are all legal: \n \n{{{\nf(1, 'new', 7.2)\nf(1, c=7.2) # Equivalent to f(1, 'empty', 7.2)\nf(c=1, a=4, b='new') # Equivalent to f(4, 'new', 1)\n}}}\n \nThe following calls are all illegal: \n \n{{{\nf(b = 'new') # No value provided for a\nf(a = 4, 4) # Non-keyword argument after keyword argument\nf(4, b=1, c=3, b=1) # duplicate keyword argument b\n}}}\n
Dictionaries are associative data structures, storing key/value pairs. Given a key, the corresponding value can be retrieved. For example, the following dictionary maps English colour names to French ones. \n \n{{{\nfr_colours = { 'red': 'rouge', 'blue': 'bleu',\n 'black': 'noir', 'white': 'blanc',\n 'yellow': 'jaune'}\n}}}\n \nTo retrieve the value corresponding to a given key, the notation is the same as when retrieving an element from a list or tuple. When indexing an array, you can only For example, to get the French word for 'white', you would write {{{fr_colours['white']}}} in Python code. \n \nA dictionary can use any immutable Python value as the key, and there are no restrictions on what you can store as values. That means that keys can be integers, floating point numbers, strings, or tuples; lists are the most important type that //can't// be used as keys. \n \nDictionaries are implemented as resizable hash tables. Hash tables are data structures optimized for quick retrieval; the result of a semi-random hash function is computed for each key, and the value is stored in a bin given by the hash function's result. Retrieving a key is then a matter of calculating the hash function and looking in the corresponding bin, so retrieval always takes the same amount of time no matter how large the dictionary is. (At least, this is true unless you have a pathological set of keys that all hash to the same value, or to a very small set of values. This is highly unlikely, unless you deliberately engineer your keys to beat the hash function.) \n \nThe hash table implementation of dictionaries explains the reason for the restriction to immutable keys. If the key were mutable like a list, it could be changed in-place which would also modify the hash value. The value would then no longer be stored in the right bin, and lookups would incorrectly fail. \n
Python's lists and tuples are the simplest compound data types. They can contain any number of other Python objects, no matter what the type of the subobjects. One tuple or list can contain numbers, strings, other tuples and lists, class instances, or any other data type that Python can handle. \n \nTuple constants are written as a sequence of values separated by commas; optionally they can be surrounded by parentheses. A zero-length tuple is written as an empty pair of parentheses {{{()}}}, and a tuple of length 1 is indicicated by a trailing comma, to distinguish a one-element tuple from an expression.. \n \n{{{\n1,2,3\n('subject', 'from', 'date', 'to')\n() # Empty tuple\n(1,) # Single-element tuple\n2, # Another single-element tuple\n2 # The number 2 (no trailing ',')\n}}}\n \nLists are always surrounded by square brackets: \n \n{{{\n[] # Empty list\n[1] # List of length 1\n[1,2,3] # List of length 3\n["this", 1, "is", "a", "list"]\n}}}\n \nYou can retrieve the ith element in a list or tuple by indexing it: {{{a[i]}}}. Retrieving a single element is a fast operation, and is indepent of the size of the list/tuple or the value of i. A smaller list or tuple can be retrieved by slicing: {{{a[i:j]}}} returns a sublist or subtuple containing elements i up to j-1. \n \n{{{\n>>> L = [0,1,2,3,4,5,6]\n>>> L[0:2], L[3:5], L[0:-1]\n([0, 1], [3, 4], [0, 1, 2, 3, 4, 5])\n}}}\n \nIf an index is a negative number, then the length of the sequence is added to it. This means that {{{L[-1]}}} is the last element of the sequence {{{L}}}, L[-2] is the next-to-last element, and so forth. You can mix positive and negative indexes as you like. Omitting i, the starting index of a slice, will default to 0, and omitting the ending index j defaults to the length of the sequence. \n \n{{{\n>>> L[:2], L[-2:], L[:-1]\n([0, 1], [5, 6], [0, 1, 2, 3, 4, 5])\n}}}\n \nTuples and lists are similar in many ways. The most important difference between them is that lists are mutable, or changeable objects; it's possible to replace any given list element, or to change the list's length. By way of contrast, once a tuple has been created it's not possible to change it in any way. \n \nTo modify a list, you can simply assign to an element or a slice, or use the {{{del}}} statement. \n \n{{{\n>>> L=[1,2,3]\n>>> L[ -1 ] = 7 ; print L\n[1, 2, 7]\n>>> L[0:2] = ['a', 'b', 'c'] ; print L\n['a', 'b', 'c', 7]\n>>> del L[1] ; print L\n['a', 'c', 7]\n}}}\n \nBecause tuples and lists are so similar, you might wonder why Python supports them both. Why not only have lists, since they're more flexible than tuples? \n \nImmutable tuples are useful in situations where you need to pass a few items to a function and don't want the function to modify the tuple; for example, \n \n{{{\npoint1 = (120, 140)\npoint2 = (200, 300)\nrecord(point1, point2)\n}}}\n \nYou don't want to have to think about what would happen if the {{{record()}}} function changed the coordinates -- it can't, because tuples are immutable. In the section on dictionaries, you'll learn that tuples can be used as dictionary keys, while lists can't. \n \nOn the other hand, the mutability of lists makes it easier to change them, so they're useful when you're constructing a collection of objects over time, or when objects need to be freely removed and added. For example, if you're iterating through the lines of text in a file and saving lines that match a certain criterion such as a regular expression, a list is the natural data type for storing the matching lines. Adding a new line is fast -- just call the list's {{{append()}}} method -- while building a new tuple by concatentation ({{{tuple1 + (line,)}}}) would be slow since it copies the entire tuple every time. \n \nWhen to use a list or a tuple is ultimately a stylistic question, and you'll arrive at your own opinions about it. Personally, I generally use tuples to hold a collection of dissimilar data; for example, a function might return a numeric error code and a string describing an error as a tuple {{{(code, errmsg)}}}. In this style, tuples wind up being used like Cs structures or Pascal's records. A function that returned a number of similiar objects, such as lines from a text file, would return a list. In other words, while lists can contain data of different types, I tend to only use them to contain similar objects: all strings, all numbers, all instances of the same class, or whatever. (On the other hand, I don't follow this rigidly; if I had some different data types collected together and sometimes needed to change only one of them, I'd probably use a list instead of a tuple, even though the data in that list wouldn't be homogeneous.) \n
Relatively few tasks can be performed by only dealing with numbers; programs will usually print out reports, modify the contents of text files, parse [[HTML]] and [[XML]] documents, and perform other operations on strings of characters. Strings are therefore an important data type in modern programming languages, and Python is no exception. \n \nIn the source code for a Python program, strings can be written in several ways. They can be surrounded by either single or double quotes: \n \n{{{\nif version[:5] != 'HTTP/':\n send_error(400, "Bad request version(%s)" % `version`)\n}}}\n \nStrings are one of Python's sequence types. This means that strings can be sliced, and the {{{for}}} statement can be used to iterate over the individual characters in a string: \n \n{{{\n>>> s = "Hello, world"\n>>> s[0:5]\n'Hello'\n>>> s[-5:]\n'world'\n>>> for char in s:\n... print char,\n...\nH e l l o , w o r l d\n}}}\n \nStrings are immutable; once a string has been created, whether as a literal in a program's source code or in the course of a program's operation, you can't modify the string in-place. Trying to change the first character of a string by slicing, as in the code {{{s[0] = 'Y'}}}, fails; to create a modified version of the string, you have to assemble a whole new string with code like {{{s = 'Y' + s[1:]}}}. \n\nThis means that Python has to make temporary copies of the string, which will be slow and memory-consuming if you're modifying very large strings. \n\nSee the [[Mutable Strings]] section for a way around this by using the <<PythonModule array>> module, and the <<PythonModule UserString>> module for a {{{MutableString}}} type which may be useful if you absolutely must modify strings in-place and still use some of the more common <<PythonModule string>> methods.
* Added [[Eric Shulman]]'s "single page mode plugin" to display one tiddler at a time, making it an OptionsPanel fixture and moving less relevant options to AdvancedOptions.\n* Added [[Xavier Morel]]'s feedback.\n* Fixed a lot of formatting snafus and added the relevant external links.\n* Merged more redundant articles, fixed some samples.\n* Renamed "Introduction" articles to have an "@" at the beginning, so that they are displayed first in the [[TOC|Table Of Contents]] and other lists - they are the ones likely to be most useful to first-time readers.\n* Upgraded (painlessly) to TiddlyWiki 1.2.32
<<option chkOpenInNewWindow>> OpenLinksInNewWindow\n<<option chkSaveEmptyTemplate>> SaveEmptyTemplate\n<<option chkGenerateAnRssFeed>> GenerateAnRssFeed\n<<option chkRegExpSearch>> RegExpSearch\n<<option chkCaseSensitiveSearch>> CaseSensitiveSearch\n<<option chkToggleLinks>> ToggleClosed ^^(override with Control or other modifier key)^^\n<<option chkHttpReadOnly>> HideEditingFeatures when viewed over HTTP
// HTTP read-only options\nconfig.options.chkHttpReadOnly = true;\n\n// Macros used internally to format links to external sites and documentation\n\n// Links to Python library module documentation\nversion.extensions.PythonModule = {major: 0, minor: 1, revision: 0};\nconfig.macros.PythonModule = {url: "http://www.python.org/doc/2.4.1/lib/module-"};\nconfig.macros.PythonModule.handler = function(place,macroName,params) {\nwikify('{{{[[' + params[0] + '|'+ this.url + params[0] + '.html]]}}}',place);\n}\n\n// Wikipedia links\nversion.extensions.Wikipedia = {major: 0, minor: 1, revision: 0};\nconfig.macros.Wikipedia = {url: "http://en.wikipedia.org/wiki/"};\nconfig.macros.Wikipedia.handler = function(place,macroName,params) {\nwikify('[[' + params[0] + '|'+ this.url + params[1] + ']]',place);\n}\n\n\n// RFCs\nversion.extensions.RFC = {major: 0, minor: 1, revision: 0};\nconfig.macros.RFC = {url: "http://www.faqs.org/rfcs/rfc"};\nconfig.macros.RFC.handler = function(place,macroName,params) {\nwikify('{{{[[RFC ' + params[0] + '|'+ this.url + params[0] + '.html]]}}}',place);\n}\n\n// Untagged List Handler\nconfig.macros.list["untagged"] = {prompt: "Tiddlers that are not tagged"};\nconfig.macros.list.untagged.handler = function(params)\n{\n//displayMessage("Building list of untagged tiddlers");\n var results = [];\n for(var t in store.tiddlers) {\n var tiddler = store.tiddlers[t];\n if(tiddler.getTags() == "")\n results.push(t);\n }\n results.sort();\n return results;\n}\n\n\n// Eric Shulman - ELS Design Studios\n// "SinglePageMode" Plug-in for TiddlyWiki version 1.2.31 or above\n\nversion.extensions.SinglePageMode= {major: 1, minor: 0, revision: 0, date: new Date(2005,8,13)};\n\nif (config.options.chkSinglePageMode==undefined) config.options.chkSinglePageMode=false;\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSinglePageMode>> Display one tiddler at a time";\n\nwindow.coreDisplayTiddler=window.displayTiddler;\nwindow.displayTiddler = function(src,title,state,highlightText,highlightCaseSensitive,animate,slowly)\n{\n if (config.options.chkSinglePageMode) closeAllTiddlers();\n coreDisplayTiddler(src,title,state,highlightText,highlightCaseSensitive,animate,slowly);\n}\n
! Problem:\n\nYou wish to display a random line from a file.\n\n! Solution:\n\nIf you are dealing with a short file, you can produce a list containing all the lines, and then choose items at random:\n \n{{{\nlines = sys.stdin.readlines()\n# or file.readlines(), where file is a file object\nwhile lines:\n line = random.choice(lines)\n lines.remove(line)\n print line,\n}}}
! Problem:\n\nYou need to generate random numbers for an application, such as generating test data or selecting an item from a list. \n\n! Solution:\n \nThe standard library module <<PythonModule random>> implements a random number generator. Using it is simple: \n \n{{{\nimport random\n\n# Generate a random number between 0 and 1\nrandval = random.random()\n\n# Generate a random integer between 45 and 55\nrandval = random.randint(45, 55)\n\n# Choose a random value from a list\nrandname = random.choice( ["Glenna", "Jody", "Natalie"] )\n}}}\n \n! Discussion:\n \n{{{random.random()}}} returns a random floating point number in the range [0, 1), generated using a Wichmann-Hill <<Wikipedia 'random number' Random_number>> generator. There are also other specialized generators in this module, built on top of the {{{random()}}} function:\n\n* {{{randint(a, b)}}} chooses an integer in the range [a, b]\n* {{{choice(S)}}} chooses a random item from the given sequence S\n* {{{uniform(a, b)}}} chooses a floating point number in the range [a, b]\n\nTo specify the random number generator's initial setting, use {{{random.seed(x, y, z)}}}, which sets the seed from three integers in the range [1, 256]. There's also a {{{random}}} class, which you can instantiate to create independent multiple random number generators. \n \nThe <<PythonModule random>> module contains functions that approximate various standard distributions, such as a normal or Gaussian distribution, lognormal, gamma and beta distributions, and a few others. These functions are specialized enough to make me refer you to the Python Library Reference for the details. \n \nNote that the {{{rand}}} module, which is occasionally used in some examples and demo programs, is now considered obsolete. Use <<PythonModule random>> instead.
* Disabled editing when viewing the Grimoire over an [[HTTP]] connection (therefore enforcing the "save to edit" rule).\n* Very minor updates (lost an interim version of the file)\n