I gotta have my orange juice.

Jesu, Juva

Archive for the ‘Python’ Category

Python Timestamp Increment

leave a comment »

I composed this concise solution to ncm‘s “coding challenge” in November 2004. I’m not entirely satisfied with its elegance, but I’m pleased with its brevity.

def dateinc(s) :
  def carry(list, modulus) :
    if len(list) == 1 : return [list[0] // modulus[0], list[0] % modulus[0]]
    else              : q = carry(list[1:], modulus[1:]); return [(list[0] + q[0]) // modulus[0], (list[0] + q[0]) % modulus[0]] + q[1:]
  s = reduce(lambda x,y:x+y, map(lambda x : (x >= '0' and x <= '9') * x, s))
  result = map(lambda x,y:x+y, map(int,(s[0:4],s[4:6],s[6:8],s[8:10],s[10:12],s[12:14])),(0,-1,-1,0,0,1))
  modulus = [10000,12,[31,28,31,30,31,30,31,31,30,31,30,31][result[1]],24,60,60]
  if result[0] % 4 == 0 and (result[0] % 100 != 0 or result[0] % 400 == 0) :
    modulus[2] += 1                               # Account for leap day.
  result = carry(result, modulus)[1:]             # Carry the extra second.
  result[1:3] = map(lambda x:x+1, result[1:3])    # Readjust to 1-base.
  return reduce(lambda x,y:x+y, map(lambda x : (x < 10) * '0' + str(x), result))

I further reduced this as follows, turning the carry function into a one-liner that computes the carry in-place (and also using builtins wherever possible). I’m much more satisfied with this solution.

def dateinc(s) :
  s = reduce(lambda x,y:x.isdigit()*x+y.isdigit()*y, s)
  ans = map(int.__add__, map(int,(s[0:4],s[4:6],s[6:8],s[8:10],s[10:12],s[12:14])),(0,-1,-1,0,0,1))
  mod = [10000,12,[31,28,31,30,31,30,31,31,30,31,30,31][ans[1]],24,60,60]
  if ans[0] % 4 == 0 and (ans[0] % 100 != 0 or ans[0] % 400 == 0) : mod[2] += 1
  ans = map(lambda x:(ans[x] + reduce(int.__mul__, map(lambda y:ans[y]>=mod[y]-1,range(x+1,len(ans))),x!=len(ans)-1)) % mod[x], range(len(ans)))
  ans[1:3] = map(int.__add__,ans[1:3],[1,1])      # Readjust to 1-base.
  return reduce(str.__add__, map(lambda x : (x < 10) * '0' + str(x), ans))

Written by Scott Moonen

November 9, 2004 at 12:52 pm

Posted in Python

Tagged with

Python persistence

leave a comment »

I’ve implemented a rudimentary persistent object store in Python. It is implemented as a Python extension module that implements a set of persistent types: strings, integers, floats, lists, and dictionaries. Each of these are backed by the persistent object store, which is implemented using a memory-mapped file.

In addition, using a specially crafted Python base class for Python objects, Python objects may be stored in the object store (as dictionaries) and instantiated out of the object store.

The result is an persistent object graph (the root of which is a persistent dictionary) whose objects and attributes may be manipulated in-place using native Python syntax. Rudimentary locking is provided so that multiple Python threads / processes may concurrently manipulate the object store.


Some aspects of this system are:

  • It is a Python extension module written in C and C++.
  • It is tested on Linux. It will likely work on *BSD systems, though it is possible that the location of the mapped storage may need to be moved.
  • It is implemented in a hierarchical manner:
    • A page manager handles the allocation of 4kB pages within a memory-mapped file. It is multi-process safe. It is, in a sense, a glorified sbrk() for a memory-mapped file.
    • A heap manager abstracts the page manager’s services to manage the allocation and deallocation of arbitrary-sized storage segments within the memory-mapped file. It is essentially a malloc() and free() for a memory-mapped file. This is also multi-process safe.
    • An object manager manages five new base types (persistent int, float, string, list, and dictionary) backed by persistent storage, using the heap manager’s services. It also provides rudimentary locking facilities for concurrency-safeness.
    • The persist Python extension uses the object manager’s services to implement persistent types that mimic the equivalent Python types. Additionally, it has the ability to reinstantiate a Python object that was stored as a dictionary (using the appropriate Python base class). The object manager’s locking facilities are made available for application usage.
  • Only one file may be mapped at a time (because it is mapped to a fixed logical address).
  • It is available for use under the MIT license. Contact me if you are interested in using it.


Some examples of its use are a simple counter:

import persist

root = persist.root()
try :    root['x'] += 1                # Increment counter
except : root['x'] = 1                 # First pass; initialize
print "Content-type: text/html\n"
print "<p>You are visitor " + str(root['x']) + " to visit this site!</p>"

and rudimentary objects:

import persist
from pbase import pbase

class person (pbase) :
  def __init__(self, name = "", age = 0) :
    self.name = name
    self.age = age

  def printAge(self) :
    print "<p>" + self.name + " is " + str(self.age) + " years old</p>"

root = persist.root()

if not root.has_key('Joe') :            # First time through
  root['Joe'] = person('Joe', 27)
if not root.has_key('John') :           # First time through
  root['John'] = person("John", 29)

# On subsequent passes we will retrieve the objects stored on the first pass.

print "Content-type: text/html\n"


Written by Scott Moonen

October 1, 2004 at 11:07 am