[FAQTS] Python Knowledge Base Update -- May 14th, 2000

Fiona Czuczman fiona at sitegnome.com
Sun May 14 09:17:43 EDT 2000


Hi,

Below are the entries I've entered into http://python.faqts.com over the 
last two days.  Sorry for the double spacing problem from the previous 
mails.

Happy Mother's Day to all the mums reading this newsgroup :-)

regards, Fiona Czuczman


## New Entries #################################################


-------------------------------------------------------------
Is there is a function in Python for converting Latin-1 to UTF-8?
http://www.faqts.com/knowledge-base/view.phtml/aid/2781
-------------------------------------------------------------
Fiona Czuczman
Fredrik Lundh

Here's one way to do it (well, two ways, actually):

import string, sys

if sys.version[:3] >= "1.6":
    def utf8(str):
        return unicode(str, "iso-8859-1").encode("utf-8")
else:
    # brute force translation from latin 1 to utf 8
    def utf8(str):
        out = []
        append = out.append
        for ch in str:
            if ch < "\200":
                append(ch)
            else:
                ch = ord(ch)
                append(chr(0xc0 | (ch >> 6)))
                append(chr(0x80 | (ch & 0x3f)))
        return string.join(out, "")


-------------------------------------------------------------
How do I check to see if a file exists?
http://www.faqts.com/knowledge-base/view.phtml/aid/2782
-------------------------------------------------------------
Fiona Czuczman
Fredrik Lundh

To check if a file exists use:

os.path.exists(filename)


-------------------------------------------------------------
Is there a pre-written script that will provide either a tar+gz or PkZip like functionality on top of ZLIB?
http://www.faqts.com/knowledge-base/view.phtml/aid/2794
-------------------------------------------------------------
Fiona Czuczman
Oleg Broytmann, Mike Steed

There should be modules for both formats. Search through Deja.com.

AND

If you can build zlib into the application, can you not also hack in
info-zip as well?  Python it ain't, but it should do what you want.

http://www.info-zip.org/pub/infozip/


-------------------------------------------------------------
I'm new to Pyhton and would appreciate advice on what book(s) I should be looking at?
http://www.faqts.com/knowledge-base/view.phtml/aid/2795
-------------------------------------------------------------
Fiona Czuczman
Chris Lada, Snoopy :-)), Paul Winkler, Dana Booth, Frank V. Castellucci

A range of books that should be useful when starting out with Python:

- "Quick Python" by Harms, and McDonald.

- If you already program, David Beasly's "Python Essential Reference" is 
very good. Another plus is that the book is high quality. It covers 
1.5.2, is tight fast text with no little fluffy animal or snakes 
writhing through the text, just down to the bone reading.

Snoopy :-)) wrote:

If you are New to Programming, then In addition to the Tutorials found 
on Python's Home Page, you should get as the 1st. choice "Teach Yourself 
Python in 24hrs".

BTY: "Learning Python" is also a very good book, but as a Newbie I found 
it quite overwhelming, to the point that I almost stopped learning 
Python. On the other hand I am very happy that I bought the "Teach 
Yourself Python in 24hrs". I find it considerable easier to comprehend 
the concepts, etc.

You can read the book online at the following:
                        http://www.pauahtun.org/TYPython/

Paul Winkler wrote:

OTOH, I got "Learning Python" and I've found that after reading just
the first half of the book and doing maybe 1/4 of the exercises, I
had a very good grasp of the language, including classes and
exceptions (both new ideas to me). From there the next step is to
skim the second half looking for useful bits, or poke around in the
library reference manual.

But then, it did take more than 24 hours. :)


-------------------------------------------------------------
How can I get one thread (messenger) to send a message to another thread (waiter) as a responce to some action?
http://www.faqts.com/knowledge-base/view.phtml/aid/2796
-------------------------------------------------------------
Fiona Czuczman
Fredrik Lundh, Glyph Lefkowitz

Solution 1:

The trick is to use a thread-safe queue to pass information from
the messenger to the worker thread.  Here's an example, adapted
from a queue example in the eff-bot guide:

# adapted from queue-example-1.py

import threading
import Queue
import time, random

class Worker(threading.Thread):

    def __init__(self, queue=None):
        if queue is None:
            queue = Queue.Queue(0) # no limit
        self.__queue = queue
        threading.Thread.__init__(self)

    def add(self, item):
        self.__queue.put(item)

    def shutdown(self):
        self.__queue.put(None)

    def run(self):
        while 1:
            item = self.__queue.get()
            if item is None:
                break # reached end of queue

            # pretend we're doing something that takes 10-100 ms
            time.sleep(random.randint(10, 100) / 1000.0)

            print "task", item, "finished"

>>> worker = Worker()
>>> worker.start()
>>> worker.add(1)
>>> task 1 finished

worker.add(2); worker.add(3)
>>> task 2 finished
task 3 finished

>>> worker.shutdown()

</F>

<!-- (the eff-bot guide to) the standard python library:
http://www.pythonware.com/people/fredrik/librarybook.htm
-->

Solution 2:

###
Python 1.5.2 (#0, Apr  3 2000, 14:46:48)  [GCC 2.95.2 20000313 (Debian 
GNU/Linux)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> from threading import *
>>> from Queue import *
>>> q=Queue(100)
>>> def Waiter():
...     while 1:
...             x=q.get()
...             print 'Waiter got a message ->',x 
... 
>>> def Messenger():
...     while 1:
...             x=raw_input("Messenger: ")
...             q.put(x)
... 
>>> w=Thread(target=Waiter)
>>> w.start()
>>> Messenger()
Messenger: hi de ho
Messenger: Waiter got a message -> hi de ho
###

The way that second line of output appears is a bit of foreshadowing
of the nasty tricky things that await you down the path of
multi-threading.


-------------------------------------------------------------
Is there an easy way of accessing the registry from within Python?
http://www.faqts.com/knowledge-base/view.phtml/aid/2810
-------------------------------------------------------------
Fiona Czuczman
Tom Vrankar

Below is a script written to queue Palm OS database files for 
installation at the next HotSync. It makes several references to the 
win32 extensions you can download from www.python.org. Look for 
win32all: there's not much documentation, but this example _plus_ the 
help files may be get you where you need to go.

#!/usr/local/bin/python
#@(#)heuristic to prepare files for installation at the next HotSync 
20000507

import sys, os, string, re
import time, shutil, struct
import win32api, win32con

class PalmInstall:
  # this always runs quietly, even if it can't figure everything out
  def __init__ (self, user =None):
    self.initialized =0
    self.palmroot =win32con.HKEY_USERS
    flag =0
    # try to anticipate company name change in registry
    for i in ["U.S. Robotics", "Palm Computing", "Palm", "Palm Inc."]:
      # obtain the path to the Palm desktop installation
      try:
        self.palmcomm =".DEFAULT\\Software\\%s\\Pilot Desktop\\" %i
        self.palmcore =self.palmcomm +"Core"            # Path
        key =win32api.RegOpenKeyEx (self.palmroot, self.palmcore,
                                    0, win32con.KEY_READ)
        self.path =win32api.RegQueryValueEx (key, "Path")[0]
        win32api.RegCloseKey (key)
        flag =1
        break
      except:
        pass
    if not flag: return
    # prepare a key paths for processing below
    self.palmpref =self.palmcomm +"Preferences"         # LastUserName
    self.palmsync =self.palmcomm +"HotSync Manager"     # Install[0-9]+
    # find Palm username of the last desktop user; this becomes the 
default
    if user:
      self.user =user
    else:
      key =win32api.RegOpenKeyEx (self.palmroot, self.palmpref,
                                  0, win32con.KEY_READ)
      self.user =win32api.RegQueryValueEx (key, "LastUserName")[0]
      win32api.RegCloseKey (key)
    # really extract the secret install code from users.dat
    # and set the user's install directory path
    try:
      self.setuser (self.user)
    except:
      return
    # mark this instance initialized, and therefore useable
    self.initialized =1

  def setuser (self, user):
    # extract secret install code from name of permanent key in standard 
apps
    # old way that was barely okay
    # flag =0
    # for kp in [self.palmmemo, self.palmaddr, self.palmdate, 
self.palmtodo]:
    #   key =win32api.RegOpenKeyEx (self.palmroot, kp, 0, 
win32con.KEY_READ)
    #   for i in range (64):
    #     try:
    #       name =win32api.RegEnumValue (key, i)[0]
    #       self.code =re.sub ("([0-9]+)_..portOrder", "\\1", name)
    #       if self.code !=name:
    #         flag =1
    #         break
    #     except:
    #       break
    #   win32api.RegCloseKey (key)
    #   if flag: break
    # if not flag: return
    # really extract the secret install code from users.dat
    try:
      f =open (os.path.join (self.path, "users.dat"), "rb")
      usersdat =f.read()
      f.close()
    except:
      raise ValueError, "Desktop not initialized: %s" %self.path
    pos =13
    for i in range (struct.unpack ("<H", usersdat[:2])[0]):    # count
      code, userlen =struct.unpack ("<H2xB", usersdat[pos:pos +5])
      pos =pos +5
      thisuser, dirlen =struct.unpack ("%dsB" %userlen,
                                       usersdat[pos:pos +userlen +1])
      pos =pos +userlen +1
      userdir, flag =struct.unpack ("%dsB" %dirlen,
                                    usersdat[pos:pos +dirlen +1])
      pos =pos +dirlen +1
      pos =pos +(flag and 42 or 10) # if flag is nonzero, next user 
record
           # starts 42 bytes later; else next user record starts 10
           # bytes later
      pos =pos +2 # skip first two (0x01, 0x80) bytes of subsequent 
records
      if thisuser ==user:
        break
    if thisuser !=user:
      raise KeyError, "User not in desktop: %s" %user
    self.user =user
    self.code =code
    self.userdir =userdir
    # search all HotMgr subkeys for the default user's Install directory
    # name, and form the path to this directory
    key =win32api.RegOpenKeyEx (self.palmroot, self.palmsync,
                                0, win32con.KEY_READ)
    for i in range (64):
      try:
        subkey =win32api.RegEnumKey (key, i)
        key1 =win32api.RegOpenKeyEx (self.palmroot,
                                     self.palmsync +"\\" +subkey,
                                     0, win32con.KEY_READ)
        try:
          name =win32api.RegQueryValueEx (key1, "Name")[0]
          if name =="Install":
            self.idir =os.path.join (self.path, self.userdir,
                       win32api.RegQueryValueEx (key1, "Directory")[0])
            win32api.RegCloseKey (key1)
            break
        except:
          pass
        win32api.RegCloseKey (key1)
      except:
        win32api.RegCloseKey (key)
        return
    win32api.RegCloseKey (key)

  def install (self, path):
    if (path[-4:] !=".pdb") and (path[-4:] !=".pqa") and (path[-4:] 
!=".prc"):
      raise ValueError, "File type is not Palm: %s" %os.path.basename 
(path)
    shutil.copy2 (path, self.idir)
    key =win32api.RegOpenKeyEx (self.palmroot, self.palmsync,
                                0, win32con.KEY_WRITE)
    win32api.RegSetValueEx (key, "Install%d" %self.code, 0,
                            win32con.REG_DWORD, 1)
    win32api.RegCloseKey (key)


# test code
if __name__ =="__main__":
  pi =PalmInstall()
  print pi.user
  print pi.code
  print pi.idir
  pi.setuser ("Blorg") # whoever you are
  print pi.user
  print pi.code
  print pi.idir
  pi.install ("csm0177u.prc") # whatever file you have


-------------------------------------------------------------
Is there a heap anywhere in the python modules?
http://www.faqts.com/knowledge-base/view.phtml/aid/2820
-------------------------------------------------------------
Fiona Czuczman
François Pinard

Here is a draft for a simple Heap module.  This one has been tested.  
See the `test()' function near the end to see an example of usage.


"""\
Handle priority heaps.

Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for all 
k, counting elements from 0.  For the sake of comparison, unexisting 
elements are considered to be infinite. The interesting property of a 
heap is that a[0] is always its smallest element.
"""

class Heap:

    def __init__(self, compare=cmp):
        """\
Set a new heap.  If COMPARE is given, use it instead of built-in 
comparison.

COMPARE, given two items, should return negative, zero or positive 
depending on the fact the first item compares smaller, equal or greater 
than the second item.
"""
        self.compare = compare
        self.array = []

    def __call__(self):
        """\
A heap instance, when called as a function, return its smallest item.
"""
        return self.array[0]

    def __len__(self):
        """\
Return the number of items in the current heap instance.
"""
        return len(self.array)

    def push(self, item):
        """\
Add ITEM to the current heap instance.
"""
        array = self.array
        compare = self.compare
        array.append(item)
        high = len(array) - 1
        while high > 0:
            low = (high-1)/2
            if compare(array[low], array[high]) <= 0:
                break
            array[low], array[high] = array[high], array[low]
            high = low

    def pop(self):
        """\
Remove and return the smallest item from the current heap instance.
"""
        array = self.array
        compare = self.compare
        item = array[0]
        if len(array) == 1:
            del array[0]
        else:
            array[0] = array.pop()
            low, high = 0, 1
            while high < len(array):
                if ((high+1 < len(array)
                     and compare(array[high], array[high+1]) > 0)):
                    high = high+1
                if compare(array[low], array[high]) <= 0:
                    break
                array[low], array[high] = array[high], array[low]
                low, high = high, 2*high+1
        return item

def test(n=2000):
    heap = Heap()
    for k in range(n-1, -1, -1):
        heap.push(k)
    for k in range(n):
        assert k+len(heap) == n
        assert k == heap.pop()


-------------------------------------------------------------
What is the use of a heap data structure?
http://www.faqts.com/knowledge-base/view.phtml/aid/2821
-------------------------------------------------------------
Fiona Czuczman
Courageous

A heap priority queue has the property such that the elements
can be inserted and pulled out in a user-defined order in O(log N)
time. So, for example:

heap.push(7)
heap.push(3)
heap.push(9)
heap.push(2)

would be popped()

as 2,3,7,9

Obviously such a data structure is only needed when appending
onto the end all the time isn't possible (otherwise you'd
just use something like a fifo, both pushing and popping in
O(1)).


-------------------------------------------------------------
How can I import constants from one module to another without explicitly listing each constant?
http://www.faqts.com/knowledge-base/view.phtml/aid/2822
-------------------------------------------------------------
Fiona Czuczman
Emile van Sebille

from constants import A
from constants import B
from constants import C

Can be simplified to:

from constants import *

will put A, B, C, etc into the current namespace


-------------------------------------------------------------
What is the Python code that will print primes below 1000?
http://www.faqts.com/knowledge-base/view.phtml/aid/2823
-------------------------------------------------------------
Fiona Czuczman
François Pinard

import re
for n in range(2, 1000):
    if not re.match('(11+)\\1+$', '1'*n):
        print n


## Edited Entries ##############################################


-------------------------------------------------------------
How do I change the mouse pointer to the default 'wait' icon during a short operation in tkinter?
http://www.faqts.com/knowledge-base/view.phtml/aid/2773
-------------------------------------------------------------
Fiona Czuczman
Fredrik Lundh, John Grayson

Use:

root.config(cursor="wait")
root.config(cursor="")

Or:

Look at page 369 of John Grayson's book - Python and Tkinter Programming

You might want to look at Pmw's BLT busy cursor 
for a full busy cursor implementation.







More information about the Python-list mailing list