GIGO: words unreadable aloud
Mishrogo Weedapeval
 

 

  Thursday 12 April 2007
Python Snippets for the BayPIGgies

Point Lobos Piggie Sign I contributed a comment (about Ruby's "Array#flatten" method) in a mailing list thread about python code snippets, and as a result I was asked to present some python snippets at tonight's meeting of the (SF) Bay Area Python Interest Group. So I picked four little bits of code. The code itself is at http://got.net/~landauer/sw/snippets/dl_snippets.tgz , or as separate python sources in that directory.


1. Invert Color

This snippet is a whole command-line command; it takes a string representing a (hex) html color value, and prints out its bitwise inverse (one's complement). It's non-scientific and pretty much unrelated to any optical notion of color complements. Inspired by a ruby version at http://www.bigbold.com/snippets/posts/show/582 . There are only two bits of note here:
  1. The join/map/lambda thing expands a three-hex-digit string into a six-digit string, by replicating each digit.
  2. I thought of using the unary "~" complement operator, but it turns on too many other bits.

def invert_color (color):
    if color[0] == '#':
        color = color[1:]
    if len(color) == 3:
        color = ''.join( map( lambda m,n: m+n, color, color ) )
    return "#%06X" % (int(color, 16) ^ 0xFFFFFF)
#
import sys
for a in sys.argv[1:]:
    print invert_color(a)


2. Undent (aka "margin")


Point Lobos China Cove Arch This function "undent" is nice to have in a utility library. It allows you to use nice source-relative indentation in triple-quoted strings, and it will strip off the extra indentation.

I posted this snippet of code on the BayPIGgies list in February (2007). It was inspired by Hal Fulton's "margin" method from his Ruby book The Ruby Way. This does its work at runtime, and isn't as strict as the similar recipe that's in the Python cookbook. It's short (just four lines of meat) and a bit easier to use (less cluttered-looking at usage site) than other, more efficient compile-time versions.

The code is very straightforward except for maybe the "rstrip" -- that removes the last line (of spaces and a newline).

import re
undent_pat = re.compile( r"^\s*\S(.*)$", re.M  )
def undent (str):
     return undent_pat.sub( r'\1', str.rstrip() )
#######################################
# Usage Example:
#
def getCustomerInfo(cust_id):
     sql  = undent( '''\
             |select customers.id as %s,
             |        sum(invoices.amount) as amount_total,
             |        blah as blah
             |   from customer 
             |   etc...
             ''')
     return sql % cust_id
print getCustomerInfo( '2345' )

Update: At the meeting, Drew pointed out that the standard library module "textwrap" has, since version 2.3, had a "dedent" function which does something similar (i.e., dedent does what the abovementioned cookbook recipe does).


3. My time/date stamp

See my "GIGO beH" posting for details. This command prints out my time/date stamp. No tricky code here.
import datetime
from string import digits as d, lowercase as lc, uppercase as uc
dom= '!' + d[1:] + uc[4:]      # Used for day of month
hms= d + uc + lc               # Used for mins, seconds.
now = datetime.datetime.now()
date_code= lc[ now.year - 2001 ] + lc[ now.month-1 ] + dom[ now.day ]
time_code= hms[ now.hour + 10 ] + hms[ now.minute ] +  hms[ now.second ]
print date_code + '_' + time_code

4. "flatten"

Because the flatten method was the subject of my contribution in the abovementioned email thread that got me into this trouble in the first place, I guess I ought to snip a bit of that here. This is a very minor tweak to Alex Martelli's cookbook version. Slightly shorter, probably slightly less clear, but I get to include a "no_can_do" function:
def can_do ( fn, exc = Exception ):
    try:          fn()
    except exc:   return 0
    else:         return 1
#
def no_can_do ( fn ):
    return not can_do( fn )
#
def isScalar(obj):
    return (    can_do( lambda: obj+'', TypeError ) or
             no_can_do( lambda: iter(obj) ) )
#
def flatten(sequence, scalarp=isScalar):
    for item in sequence:
        if scalarp(item):
            yield item
        else:
            for subitem in flatten(item, scalarp):
                yield subitem 



Finally, for no good reason, here's a link to the rest of those Point Lobos pix.
12:52:53 AM   comment/     


Click here to visit the Radio UserLand website. Click to see the XML version of this web page. © Copyright 2007 Doug Landauer .
Last update: 07/5/1; 00:02:33 .
Click here to send an email to the editor of this weblog.

April 2007
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
Mar   May

Previous/Next