# HG changeset patch # User Olivier Breuleux # Date 1227995329 18000 # Node ID 0ac4927e9d97e5052cd2587b3ea2f633e6ad239b # Parent cb8eabe7d941688473a72325b9842e3adbdb7e99 new stuff diff -r cb8eabe7d941 -r 0ac4927e9d97 pylearn/dbdict/newstuff.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pylearn/dbdict/newstuff.py Sat Nov 29 16:48:49 2008 -0500 @@ -0,0 +1,211 @@ + +from collections import defaultdict +import re + +################################################################################ +### resolve +################################################################################ + +def resolve(name): + symbols = name.split('.') + builder = __import__(symbols[0]) + for sym in symbols[1:]: + builder = getattr(builder, sym) + return builder + +################################################################################ +### dictionary +################################################################################ + +def convert(obj): + def kw(x): + x = x.lower() + return dict(true = True, + false = False, + none = None)[x] + for f in (int, float, kw): + try: + return f(obj) + except: + pass + return obj + +def flatten(obj): + d = {} + def helper(d, prefix, obj): + if isinstance(obj, (str, int, float)): + d[prefix] = convert(obj) + else: + if isinstance(obj, dict): + subd = obj + else: + subd = obj.state() + subd['__builder__'] = '%s.%s' % (obj.__module__, obj.__class__.__name__) + for k, v in subd.iteritems(): + pfx = '.'.join([prefix, k]) if prefix else k + helper(d, pfx, v) + helper(d, '', obj) + return d + +def expand(d): + def dd(): + return defaultdict(dd) + struct = dd() + for k, v in d.iteritems(): + if k == '': + raise NotImplementedError() + else: + keys = k.split('.') + current = struct + for k2 in keys[:-1]: + current = current[k2] + current[keys[-1]] = convert(v) + return struct + +def realize(d): + if not isinstance(d, dict): + return d + d = dict((k, realize(v)) for k, v in d.iteritems()) + if '__builder__' in d: + builder = resolve(d.pop('__builder__')) + return builder(**d) + return d + +def make(d): + return realize(expand(d)) + +################################################################################ +### errors +################################################################################ + +class UsageError(Exception): + pass + +################################################################################ +### parsing and formatting +################################################################################ + +def parse(*strings): + d = {} + for string in strings: + s1 = re.split(' *= *', string, 1) + s2 = re.split(' *:: *', string, 1) + if len(s1) == 1 and len(s2) == 1: + raise UsageError('Expected a keyword argument in place of "%s"' % s1[0]) + elif len(s1) == 2: + k, v = s1 + elif len(s2) == 2: + k, v = s2 + k += '.__builder__' + d[k] = v + return d + +def format_help(topic): + if topic is None: + return 'No help.' + elif hasattr(topic, 'help'): + help = topic.help() + else: + help = topic.__doc__ + ss = map(str.rstrip, help.split('\n')) + baseline = min([len(line) - len(line.lstrip()) for line in ss if line]) + s = '\n'.join([line[baseline:] for line in ss]) + s = re.sub(string = s, pattern = '\n{2,}', repl = '\n\n') + s = re.sub(string = s, pattern = '(^\n*)|(\n*$)', repl = '') + return s + +################################################################################ +### running +################################################################################ + +class Channel(object): + def abort(self): + raise StopIteration() + def checkpoint(self): + raise NotImplementedError() + def switch(self, job, *message): + raise NotImplementedError() + def broadcast(self, *message): + raise NotImplementedError() + def run(self): + pass + +class StandardChannel(Channel): + def __init__(self, runner): + self.runner = runner + def checkpoint(self): + pass + + + + + + + + +class Run(object): + + def __init__(self, type, arguments): + runner = getattr(self, 'run_%s' % type, None) + if not runner: + raise UsageError('Unknown runner: "%s"' % type) + self.type = type + self.runner = runner + self.arguments = arguments + if len(inspect.getargspec(runner)[0])-1 > len(arguments): + s = format_help(runner) + raise UsageError(s) + runner(*self.arguments) + + def run_cmdline(self, experiment, *strings): + """ + Usage: cmdline ... + + Run an experiment with parameters provided on the command + line. The symbol described by will be imported + using the normal python import rules and will be called with + the dictionary described on the command line. + + The signature of the function located at must + look like: + def my_experiment(state, channel): + ... + + Examples of setting parameters: + a=2 => state['a'] = 2 + b.c=3 => state['b']['c'] = 3 + p::mymodule.Something => state['p']['__builder__']=mymodule.Something + + Example call: + $EXE$ cmdline mymodule.my_experiment \\ + stopper::pylearn.stopper.nsteps \\ # use pylearn.stopper.nsteps + stopper.n=10000 \\ # the argument "n" of nsteps is 10000 + lr=0.03 + """ + state = expand(parse(*strings)) + self.experiment = resolve(experiment) + self.channel = StandardChannel(self, state) + self.channel.run() + #experiment(d, CmdlineChannel(self)) + #print flatten(d) + + def run_help(self, topic): + """ + Usage: help + + Get help for a topic. + """ + print format_help(getattr(self, 'run_%s' % topic, None)) + + + + + + + + + + + + +