http://github.com/devdave/DevDave-s-miscellanious-bucket
Includes: The complete mako Auto-render logic class + decorator for cherrypy and a proof of concept idea I am still working on to implement the command pattern in Python.
http://github.com/devdave/DevDave-s-miscellanious-bucket
Includes: The complete mako Auto-render logic class + decorator for cherrypy and a proof of concept idea I am still working on to implement the command pattern in Python.
I’ve been using PHP off and on as a language since sometime in the late 90’s when it was just PHP ( and not even PHP3 ). To be fair, the language has come a long way and beaten out some well financed rivals ( ASP & Coldfusion for example ) but it has also suffered along the way in the quality of it’s source code.
For the last 5 years, I’ve occasionally stared at PHP’s C macro-soup and soon after promptly stopped. My first real programming language was C when I was eleven years old, I know C like an old friend, but PHP’s source code is not C. It’s the dark side of C, a meta-language built on top of C via a fairly deep interdependent network of macro’s, defines, typedef’s, linked structs, and shit I didn’t know you could do with C.
Oh yeah and most of that crap is extremely terse, not documented, and inconsistently arranged. If I had a client who asked me to maintain PHP, I’d probably smile and every so carefully walked backwards out of the room. Really I must say I am impressed with PHP’s dedicated staff and volunteer engineering team. I don’t know how the hell they do it.
That said, I’ve been trying out various c/c++ IDE’s for linux and continually dissappointed. Code Lite seemed nice but its unworkable workspace idealogy pissed me off, Kdevelop is good but lacking in features, and etc etc. Recently I’ve had to do some Java code ( I’ve got a borderline irrational hatred towards the language since the 90’s ) and after trying IntelliJ for a day or two, I went back to the IDE I first used to learn Java… NetBeans. I’ve got to say, Netbeans has gotten a lot better since I last used it 12 years ago. And one of the things it has gotten really good at, is being a c/c++ IDE.
The IDE’s macro resolution and code intelligence features probably helped me jump years of effort into the future for understanding PHP by providing a macro resolution feature that visually converts the PHP meta language source code back into C. Whole sections of the languages design, construction, and its philosophy all became self-evident to me in the space of three hours.
Which leads to the end of this post, information maybe power… but only if it can be recognized as information and not noise… or in the case of PHP, a code base written by an infinite number of PCP snorting monkeys.
Usage: $~/looper runSomePythonScript.py
#!/usr/bin/python
import subprocess
import time, sys
PYTHON = '/usr/bin/python'
def main():
commands = [PYTHON]
commands.extend(sys.argv[1:])
print "Looping %s" % commands
while True:
subprocess.call(commands)
print "4 seconds to restart"
time.sleep(2)
if __name__ == "__main__":
main()
When writing maps/reduce functions for couch, its tedious to make a change, jump to the server console, push the code, then call the map/reduce via a web browser or curl. So I figured, cut at least 1 step out of the whole process and just page back and forth from the IDE to the browser while a tail of the couchdb error log spins by on a 2nd monitor.
import os
from os import path
import time
from stat import ST_MTIME
manifest = dict()
import subprocess
while 1:
time.sleep(3)
print "Scanning"
for root , dirs, files in os.walk("./_design/"):
for file in files:
filepath = path.join(root,file)
mtime = os.stat(filepath)[ST_MTIME]
if not filepath in manifest:
manifest[filepath] = mtime
else:
if mtime > manifest[filepath]:
print filepath, "is stale, updating."
subprocess.call(["/usr/bin/python", "push.py"] )
manifest[filepath] = mtime
As mentioned previously, CouchDBKit stores map/reduce functions on the local filesystem. An undocumented feature in the couchdbkit.designer module is the presence & functionality of the .couchappignore… thankfully the programmer left some comments.
# A .couchappignore file is a json file containing a
# list of regexps for things to skip
I assume this functions similar to .gitignore or SVN:ignore
import time, datetime
from couchdbkit.schema.properties import Property
class TimestampProperty(Property):
"""
"""
@staticmethod
def now(self):
return datetime.datetime.now()
def to_python(self, value):
if isinstance(value, basestring ):
try:
value = float(value)
value = datetime.datetime.fromtimestamp(value)
except ValueError, e:
raise e
elif isinstance( value, float):
try:
value = datetime.datetime.fromtimestamp(value)
except ValueError, e:
raise e
else:
#if it's not basestring or float... what the hell is it?
#@TODO remove on acceptance
raise Exception(value, [(k,getattr(value,k)) for k in dir(value)])
return value
def to_json(self, value):
if value is None:
return value
return time.mktime(value.timetuple())
I’ve been recommending “The Python Cookbook” to my peers and anyone who will listen. Its not an earth shattering, change your life book, and it doesn’t have a recipe for curing cancer. What it does have is some extremely well written solutions to common and uncommon problems so the recommendation to read the cookbook is made for those just getting into Python and who need a good source of examples for doing things in a more pythonic way.
Available @ Amazon via this link or directly from Oreilly here
In my so far unnanounced pet-project to make a delicious clone, I’ve been experimenting with CouchDB. Initially I started with python-couchdb and it worked well for importing data from my delicious data export, but then things started
getting difficult. The major issue was how to install & use views, authenticating, and so on.
Being unhappy with python-couchdb, I decided to try out couchdbkit and the initial trials have been mostly positive on interfacing with the couchdb server. One of the more outstanding features is the ability to push a directory stucture of maps/views from the local filesystem to couchdb.
Given a path structure like:
CouchDBkit will push viewName to databaseName ( note I may not have this exactly right just yet ).
Will see how couchdbkit does for performance and more involved tests.
from functools import wraps
def AutoRender(f):
name = f.__name__
f.exposed = True
#raise Exception([ name, [(k, getattr(f,k),"\n",) for k in dir(f)]])
@wraps(f)
def wrapper(self, *args, **kwargs):
cls = self.__class__.__name__.lower()
result = f(self, *args, **kwargs)
pathname = "%s/%s" % (cls, name, )
return Render(pathname , result ).gen()
wrapper.exposed = True
return wrapper
I often find it tedious in pretty much any language to have the following pattern:
Class MyController:
def action(self):
result = do_stuff()
return Render("MyController/action", { result : result } )
action.exposed = True
So with @AutoRender it assumes the above pattern to make things a little cleaner @ the application layer
class MyController:
@AutoRender
def action(self):
result = do_stuff()
return { result: result }
As much as Ruby annoys me with its syrupy breakfast cereal syntactic sugar, I do praise it for laying down an assortment of helpers and shortcuts for common tasks.
I follow the Cloudera twitter feed alongside Patrick Hunt’s feed phunt, so I thought it a point of interest that both mentioned a blog article about a new hashing methodolgy for memcache  ( something I am looking into at the moment ).
Blog article (Â http://dustin.github.com/2010/06/29/memcached-vbuckets.html )