|| The Python
(second edition) by Alex
Anna Ravenscroft and David
Ascher, 2005, ISBN 0596007973, O'Reilly.
This is a collected set of recipes for doing all sorts of common (and
so common) tasks in Python. The recipes are grouped into task-specific
chapters, so you can often just glance down the list of chapters and
then skim the contents of one or two chapters to find what you are
looking for. The recipes are usually less than a page long, often short
enough to just type into the Python interpreter shell directly to play
with, and come with a write up that will cover what the recipe does and
go into details about any additional background material you might need
If you are a lone programmer who's looking to get productive in Python fast, this is a good book to get. Its the sort of thing where you could find a solution in this book in 5 minutes that will save you a few hours of web searching and experimentation. If you've got a few people at work who use Python, then at least get one copy for the office, it'll pay for itself in one use.
|| Python Programming on
Win32, by Mark
Hammond and Andy
Robinson, 2000, ISBN 1565926218, O'Reilly.
If you are working with Python in a Windows environment and you want to talk to other applications (say by using COM or DCOM) or control or modify the operating system from Python (perhaps using Python as your operating system scripting language), you simply must get a copy of this book. Like the Python Cookbook, each time you use this book it'll save you hours of "interesting" times. I highly recommend this book.
It's also the sort of book where a programming team needs at least one copy. The sample code and errata page is here.
An introductory presentation by Mark Hammond and Greg Stein on COM given at a conference. In Feb'06 an announcement of a website dedicated to this was made: win32com.goermezer.de.
in Action, 2006, by Noel Rappin and Robin Dunn, published by
Manning Publications. ISBN: 1932394621.
Here's an artical
interviewing Robin Dunn. Reviewed
on voidspace. Reviewed
on Slashdot by Ron Stephens.
This is a very good introduction to using wxPython to create GUI applications in Python. Currently I've read about 70% of the book and found it quite easy to follow, the examples are quite concise, but still illustrate some powerful concepts (especially the grid table in Chapter 5 and the simple drawing application in chapter 6). Source code to the examples is available from the publisher's web site, but sometimes one learns more from actually typing in some of these that just downloading and running them. That's one of the beauties of Python, you can actually type in some stuff in the Python shell window and interactively experiment with things.
Incorporating HTML into wxPython. Using PIL (Python Imaging Library) within a wxPython application.
This sort of calculation also means that if a device like a compact flash drive is used in a computer as a system disk (so it's getting log files updated and the swap partition is on the drive) then so long as the device is large enough and the average write rate is acceptable then it will have a long life - and the easiest way to assure this is to just oversize the drive a bit. So instead of using a 512MB drive for your disk-less server, installing a 2GB unit will make it last 4 times as long. 
Getting out of a sub dialog, by hitting the tab can be done by trapping the tab key and putting in some code to manually move the focus out of the dialog to another window. If you really want this behavior the best thing to do would be to override CDialog::PreTranslateMsg() to handle the tab key and then use that version of CDialog as your base class for dialogs.
Using the Spy++ tool can help understand the window tabbing order because the tabbing order is the order that windows appear in its view (i.e. the order they are constructed and chained together).
The win32 function ::GetWindow(HWND, UINT) can be used to find the first child window of a given window when UINT == GW_CHILD. It can also be used to find the first (among several) sibling windows when UINT == GW_HWNDFIRST. There is a CWnd::GetWindow() equivalent function. 
VBoxManage setextradata VMNAME "VBoxInternal/Devices/piix3ide/0/Config/IRQDelay" 1I shut down VirtualBox, opened a DOS window, changed directory to "C:\Program Files\Sun\xVM VirtualBox" and then issued the command replacing "VMNAME" with the name of my virtual machine. Then I restarted VirtualBox and continued the installation. This time the install completed properly. 
I encountered the "busy drive" bug while checking to see if any of my Seagate drives might be affected. Quite ironic, you shutdown the system to check the serial numbers and drive labels; and then, when you power up the system again one of the drives is no longer responding to the BIOS. Seagate now has a few online tools that you can use to find out if you need new firmware - the best is to get the drive's serial number and enter it. If your drive is one that is known to be at risk they will send you to a page from which you can download a small ISO image that you can burn to CD and then boot from to flash the drive.
Seagate's firmware upgrade procedure is described here, if you have an X86 PC which can boot from CD then it is pretty simple to flash the drives (just detach all your other drives first to be on the safe side).
I was able to unbrick my drive that had entered the busy state by following this procedure. If you just unscrew the screw near the drive power connector a few turns, then you can slide some insulating material (say the corner of a business card) between the connector and the controller board quite easily. I used one of these RS-232 to TTL level shifters (here from www.robotcraft.ca) and used a pair of AA batteries to power it at 3 volts. For the connector to the RX/TX pins I used a piece of cable from an old computer case, one of the two pin headers that is used to connect the front panel (lights or switches) to the motherboard. This had the correct pin spacing but was slightly too thick to insert into the drive's socket, so I used sand paper to thin it down a bit. Once I had found a serial cable (which I have not used for many years) I was able to connect the drive to the computer and verify that it did have the "busy error" symptoms (the drive will keep sending, about once a minute, a string like "LED:000000CC FAddr:0025BF67" to the terminal). At this point things worked up to issuing the "Z" command to spin down the drive. For me as soon as I issued that command the drive would enter the busy error state. The command sequence looked like:
F3 T>/2 F3 2>Z LED:000000CC FAddr:0025BF67 LED:000000CC FAddr:0025BF67In the end I reviewed the various drive commands (a list is listed here) and noted that the "Z" command was also available at other "levels", so I gave level 8 a try and this worked. The output from my command session looked like:
F3 T>/8 F3 8>Z Spin Down Complete Elapsed Time 0.161 msecs F3 8> F3 8>U Spin Up Complete Elapsed Time 9.250 secs F3 8>/1 F3 1>N1 F3 1>/T F3 T> F3 T>i4,1,22 F3 T>m0,2,2,,,,,22 Max Wr Retries = 00, Max Rd Retries = 00, Max ECC T-Level = 14, Max Certify Rewr ite Retries = 00C8 User Partition Format 5% complete, Zone 00, Pass 00, LBA 00004339, ErrCode 000 User Partition Format 5% complete, Zone 00, Pass 00, LBA 00008DED, ErrCode 000 00080, Elapsed Time 0 mins 10 secs User Partition Format Successful - Elapsed Time 0 mins 10 secs F3 T>After I had done this I was able to remove the drive, test it and confirm that it was working fine. I then did a firmware update which took it from SD15 to SD1A.
And one more thing, my drives were "made in China" so this problem was not just with the drives from Thailand. 
import win32api s = win32api.GetLogicalDriveStrings().split("\x00")[:-1]The [:-1] is to drop the last element from the list which will be an empty string. This will give you a list of drive root directories like:
['C:\\', 'D:\\', 'G:\\', 'I:\\', 'S:\\', 'Y:\\', 'Z:\\']If you need to get the volume label, or some other information about each of these drives you can use the GetVolumeInformation function, like:
t = win32api.GetVolumeInformation("C:\\")This returns a tupple like:
('MDATA', -590490522, 255, 6, 'FAT32')where the first element is the label of the drive (which can be handy if you have a few USB drives that Windows insists of giving different drive letters to depending on the order you insert them or power them up and you need to be able to find a particular drive to do some processing on).