Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Nov 25th, 2005, 1:51 PM   #1
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
Useful code snippets

Here's a few Python code snippets I've used in several programs, that might, possibly, maybe, be useful for others. Does anyone else have any pieces of code that might make life easier for other Python programmers?

def all(s):
   "Return true if all elements in an iterable sequence are true."
   for x in s:
      if not x:
         return False
   return True

def any(s):
   "Return true if any element in an iterable sequence is true."
   for x in s:
      if x:
         return True
   return False

class Cache:
   """
   Creates a functor that caches the output of a function.
   e.g.
      image_load = Cache(pygame.image.load)
      ball1 = image_load("ball.png")
      ball2 = image_load("ball.png")   # ball.png only loaded from disk once
   """
   def __init__(self, func):
      self.store = {}
      self.func  = func

   def __call__(self, key):
      try:
         return self.store[key]
      except KeyError:
         self.store[key] = self.func(key)
         return self.store[key]
Arevos is offline   Reply With Quote
Old Nov 25th, 2005, 3:37 PM   #2
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Posts: 1,785
Rep Power: 5 Sane will become famous soon enough
Your all/any function could be easily generalised and used in more contexts like so:

def get_instances(list, instance):
    i = 0
    for item in list: i += item==instance
    return i

print get_instances( [0, 1, False, True], True )

As well, that "any" function can be summarized in a simple condition:

if True in list: print "At least one true is in the list."
(and same to your "all" function: if False in list)

Nice Cache function though.

Last edited by Sane; Nov 25th, 2005 at 3:53 PM.
Sane is offline   Reply With Quote
Old Nov 25th, 2005, 4:23 PM   #3
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
Quote:
Originally Posted by Sane
Your all/any function could be easily generalised and used in more contexts like so:

def get_instances(list, instance):
    i = 0
    for item in list: i += item==instance
    return i

print get_instances( [0, 1, False, True], True )
That's not the point; they're syntax sugar for generators:
assert not any(x > 5 for x in s):
assert all(x <= 5 for x in s)
And get_instances isn't lazy evaluating, either...
Quote:
Originally Posted by Sane
As well, that "any" function can be summarized in a simple condition:

if True in list: print "At least one true is in the list."
(and same to your "all" function: if False in list)
You have a point there. I took the any and all functions from a proposal by Guido (he was arguing against reduce). Because Guido wrote it, I assumed (True in s) was not used because it would cause s to be evaluated fully, but some quick tests show this is not the case. I guess he wasn't thinking of efficiency at the time :o

Still, (True in (x > 5 for x in s)) doesn't seem as intuitive as any(x > 5 for x in s).

def any(s):
   return True in s

def all(s):
   return not False in s

Last edited by Arevos; Nov 25th, 2005 at 4:36 PM.
Arevos is offline   Reply With Quote
Old Nov 25th, 2005, 6:02 PM   #4
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
A general-purpose event queue that I sometimes use:
class EventQueue:
   """
   Contains a queue of events. When polled, the event queue calls the
   functions associated with the events' classes.

   e.g.
      class Event:
         pass
      queue = EventQueue()

      @queue.register(Event)
      def foobar(event):
         print event

      queue.push(Event())
      queue.poll()
   """
   def __init__(self):
      self.map = {}
      self.queue = []

   def register(self, event_type, function = None):
      """
      Use as a function: register(event_type, function)
      or as a decorator: @register(event_type)
    
      """
      def decorate(func):
         try:
            self.map[event_type].add(func)
         except KeyError:
            self.map[event_type] = set([func])
         return func
         
      if function != None:
         return decorate(function)
         
      return decorate

   def push(self, event):
      "Push an event onto the queue."
      self.queue.append(event)

   def poll(self):
      "Poll the queue."
      events = self.queue[:]
      self.queue = []
      for event in events:
         for func in self.map[event.__class__]:
            func(event)
Arevos is offline   Reply With Quote
Old Nov 27th, 2005, 1:42 PM   #5
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Posts: 1,785
Rep Power: 5 Sane will become famous soon enough
I've noticed I've used this one quite often in my code:

def get_between(string, start, end):
    return string.split(start)[-1].split(end)[0]

example:
print get_between("blah <a href='http://www.google.com'>blah</a> blah", 
    "href='", "'>")
>>> http://www.google.com
Sane is offline   Reply With Quote
Old Nov 27th, 2005, 4:44 PM   #6
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Posts: 1,785
Rep Power: 5 Sane will become famous soon enough
This snippet is useful for about every important program that you'd need to distribute to the public, for when needs to be kept updated (and is potentially full of bugs):

def show_error(caption, fileName):

    from tkMessageBox import showwarning          # error dialog box
    from sys import exc_info, exit                # exception info, system exit
    from time import ctime                        # current time and day

    error = '\n'.join(str(i) for i in exc_info()) # change all elements of exc_info to str, then join with newline

    stream = open(fileName, 'a')                  # open stream with append
    stream.write("%s: %s\n\n"%( ctime(), error )) # append error and time to an error log
    stream.close()                                # close stream

    showwarning( caption, error )                 # show error
    exit()                                        # exit program
It is used like so:

def main():
    print "This is our main function"
    print "Oops, this line is an error: %s"%(x)

try:
    main()
except SystemExit: pass
except:
    show_error('Program Error', 'errors.log')

And if your program is not using tkinter, then you just replace the 'showwarning' with a call to
win32api.MessageBox(0, message, caption)

Last edited by Sane; Nov 27th, 2005 at 5:00 PM.
Sane is offline   Reply With Quote
Old Nov 28th, 2005, 4:21 PM   #7
Cerulean
Professional Programmer
 
Cerulean's Avatar
 
Join Date: Apr 2005
Location: London, England
Posts: 459
Rep Power: 4 Cerulean is on a distinguished road
Quote:
Originally Posted by Sane
And if your program is not using tkinter, then you just replace the 'showwarning' with a call to
win32api.MessageBox(0, message, caption)
And what if it's not on Windows? Trying to show a message box with PyQt/wxPython/PyGTK would be cool, but a fallback of logging to a file is more or less a must.

On the debug topic, I had a generic debug function that worked some magic to find the name of the function that just called it and other interesting things. Will look around to see if I have it still.
Cerulean is offline   Reply With Quote
Old Dec 5th, 2005, 9:39 AM   #8
Dietrich
Professional Programmer
 
Dietrich's Avatar
 
Join Date: Feb 2005
Posts: 434
Rep Power: 4 Dietrich is on a distinguished road
Smile

Quote:
On the debug topic, I had a generic debug function that worked some magic to find the name of the function that just called it and other interesting things. Will look around to see if I have it still.
____________________
http://cerulean.pyresoft.com
Yes, we are waiting with bated breath!
__________________
I looked it up on the Intergnats!
Dietrich is offline   Reply With Quote
Old Mar 9th, 2006, 5:06 PM   #9
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Posts: 1,785
Rep Power: 5 Sane will become famous soon enough
Here's a semi-useful function I created when I ran into a problem while parsing html.

def splitwithout(text, s, void):
    res = []
    lt = -1
    on = (False,'')
    for t in range(len(text)):
        if text[t] in void:
            if not on[0]:
                on = (True, text[t])
            elif text[t] == on[1]:
                on = (False, '')
        if text[t] == s and not on[0]:
            res += [text[lt+1:t]]
            lt = t
    res += [text[lt+1:]]
    return res

It does what its name says, splits without (the instance of the items passed through void).

e.g.
print splitwithout("""a b "c d" e f 'g h i' j k l""",
                   " ",
                   ('"',"'"))
outputs:

>>> ['a', 'b', '"c d"', 'e', 'f', "'g h i'", 'j', 'k', 'l']

Notice how the spaces in between "c d" and 'g h i' were not split as split() would normally do (since I passed '"', "'" through void)? The point of this function is so I can do split an html tag by its spacing, without taking a space that could be inside the paramaters as well.

I wonder if this is actually faster then split() is.


Edit:

If you still don't see the point, here's what I was using it for.

def parse_tag(text, open = '<', close = '>'):
    first = splitwithout(text.split(open)[1].split(close)[0], ' ', ('"',"'"))
    
    tag = first[0]
    if tag == ' ':
        return False
    
    params = {}
    for p in first[1:]:
        pp = p.split('=')
        try:
            param = pp[0]
            val = pp[1].split(pp[1][0])[1]
        except IndexError: return False
        params[pp[0]] = val

    try:
        content = text.split(open+"/"+tag+close)[0].split(close)[1]
    except IndexError:
        return False

    return tag, params, content

tag, params, content = parse_tag("""<a href='http://google.ca' title="Hyperlink to Google.ca">Hyperlink</a>""")

print tag #'a'
print params #{'href': 'http://google.ca', 'title': 'Hyperlink to Google.ca'}
print content #Hyperlink
Very helpful I think.

Last edited by Sane; Mar 9th, 2006 at 5:17 PM.
Sane is offline   Reply With Quote
Old Mar 9th, 2006, 7:01 PM   #10
hydroxide
Programmer
 
Join Date: Apr 2005
Posts: 73
Rep Power: 4 hydroxide is on a distinguished road
Quote:
Originally Posted by Sane
def parse_tag(text, open = '<', close = '>'):
Were you aware of htmllib? It's in the stdlib and is built for parsing html...
(the documentation for it is fairly awful, though, so you'd have to google for examples of how to use it)

--OH.
hydroxide is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 8:11 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC