Python Snippets for the BayPIGgies
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:
- The join/map/lambda thing expands a three-hex-digit
string into a six-digit string, by replicating each digit.
- 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")
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