Python Snippits That I Know I'll Be Hunting For In The Future (02 Apr 2003)

Some notes on the stuff I was talking about yesterday. People are welcome to jump in with comments if they like, but this is mostly for me to recognise when I've gone in a circle.

A terminal log from my knockup in Python. This uses setxattr and friends. It's a new toy in the kernel (go read the manpage) but only XFS supports it correctly. I think the terminal log pretty much speaks for itself

unsorted                 {e0cb6e07b63cd592cad592bbb2c4f37a}          
title                    Root                                         
keywords                 {904f3b6ed1f0bdc87cf11232eea4292b}          
comp                     {f3d00322003197219ed873a87135f09c}          
people                   {f2124f6ef95e9c0cb6899b32741ea969}          
types                    {89b870c400af24726b0095896587a10f}          

> ...unsorted 
> List:       
syncthreading.pdf        {Sync Threading}                             
TR-94-06.pdf             {Control Transfer in Operating System Ker... 
CIRCA_whitepaper.pdf     {CIRCA Technology Overview}                  
core_vulnerabilities.pdf {Advanced Buffer Overflows}                  
RC22534Rev1full.pdf      {Thirty Years Later: Lessons from the Mul... 

> ...syncthreading.pdf 
> List:                
title                    Sync Threading                               
type                     {PDF}                                        
filename                 syncthreading.pdf                            
author                   {Adam Langley}                               

> List:     
title                    Adam Langley                                 

> Pop   
> List: 
title                    Sync Threading                               
type                     {PDF}                                        
filename                 syncthreading.pdf                            
author                   {Adam Langley}                               

> :view 
xpdf /home/agl/lscape/1931bdf5e54e08edc866b00ff0f2a6a0&

In this model there are strings, objects, bags and lists (collectively elements). Objects are unordered (string, elements) pairs and most of the things in that log are objects. Bags are unordered sets of elements and lists are ordered vectors of elements.

That works to a point and I was just about to add backlinks to every object as bag of backlinks and a link called .backlinks. But, while links from objects are named the backlinks would never be. This is ok in some cases (such as structral links), but most of the time it matters that you were linked to with the name author because that has information value in the other direction as well.

So links are:

  • Properties: named at both ends, though it's important that each object knows which end it's on
  • Pointers: named at the source end only
  • Links: unnamed at both ends (bags and lists consist of these)
(if you are an RDF type, think of Properties as Triples. I may end up with an RDF model, but I'll make my own why there)

Now, should I allow multiple Properties with the same name from the same object or force them via a bag? Objects are going to have multiple incomming Properties with the same name, so I don't see why not.

Also need to think about indexes

Disabling terminal line buffering

from termios import *

CC = 6

def save (fd):
        return tcgetattr (fd)

def restore (fd, data):
        tcsetattr (fd, TCSAFLUSH, data)

def nobuffer (fd, when=TCSAFLUSH):
        """Disable terminal line buffering."""
        mode = tcgetattr (fd)

        mode[IFLAG] = mode[IFLAG] & ~(INPCK | ISTRIP | IXON)
        mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB)
        mode[CFLAG] = mode[CFLAG] | CS8
        mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON)
        mode[CC][VMIN] = 1
        mode[CC][VTIME] = 0
        tcsetattr(fd, when, mode)

Why on earth isn't fold an inbuilt function? (this is a left fold)

def fold (f, lst, init):
        cur = init

        for x in lst:
                cur = f (cur, x)
        return cur

Longest common prefix of two strings

def common_root (s1, s2):
	"Longest common prefix of two strings"
        n = min (len (s1), len (s2))

        for x in range (n):
                if (s1[x] != s2[x]):
                        return s1[:x]
        return s1[:n]

And tab completion

p = filter (lambda x : x.find (b) == 0, comps)
if (len (p) > 0):
	root = fold (common_root, p, p[0])
	if (len (root) > len (your_current_string)):
		your_current_string = root