mailRe: Redesign of the relax data model: 2. A new run concept


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by Edward d'Auvergne on January 16, 2007 - 15:54:
On 1/16/07, Chris MacRaild <c.a.macraild@xxxxxxxxxxx> wrote:
On Mon, 2007-01-15 at 17:44 +1100, Edward d'Auvergne wrote:

[snip]

> > Some asides
> >
> > A.  I believe the runs that are passed around in relax are strings
> > which are then used to lookup data in a map. Why not just have
> > (runs/pipes) as objects... Then for example the call
> >
> > self.relax.data[self.relax.run]
> >
> > above becomes
> >
> > self.relax.run.data a much more object orientated and encapsulated
> structure
>
> You still need a list (array) or dictionary (hash) type structure to
> store multiple run objects.  'self.relax.data' would be a dictionary
> type object with key-value pairs, the key being the run name and the
> value being a standard class instance object containing all the data
> associated with the run as objects.  The dictionary would be more
> logical than an array in this case.
>

The issue here is whether the user and/or developer should be dealing
with a run name (a string) or the run object itself. Currently the user
creates a new run with:

run.create(run_name, run_type)

and then uses the string, run_name, to address the object. In this
idiom, a dictionary of runs is clearly an appropriate structure.

Alternatively, we could have the user create a run with:

my_run = run.create(run_type)

Then the user has the run as an object, which they can make current or
pass to relax commands as required. In this idiom, a dictionary of runs
is an unnecessary abstraction.

You have mentioned the run object idea before, although I can't find your post on the subject.


Currently, the relax interface is entirely script orientated, not object
orientated, so the alternative above is a fairly fundamental change in
interface design.

I don't favour an object orientated user interface, because oo tends to
be fairly intimdating to non-programmers. On the other hand, the relax
code-base could benefit from being more object orientated. So I propose
the following arrangement:

I have thought of your idea quite a bit, but am of the same opinion as that stated in your above paragraph. The idea of having the run objects as things that the user has at their fingertips to manipulate, pass to functions, etc is quite powerful. However it does add significant complexity to the prompt/script UI. I can clearly see the idea embedded in a GUI design though whereby the data pipe (previously called a run) is represented as a physical object (either in 2D or 3D) which can be manipulated and the user functions applied to.


all runs are stored in a dictionary, keyed by run name, but only the
run-selection machinery should access this dictionary. The current run
should be the object self.relax.data.run (or something simiar), and all
relax functions should operate on that object.

I agree, however I would extend this using the global variable ideas Gary proposed (https://mail.gna.org/public/relax-devel/2007-01/msg00013.html, Message-id: <f001463a0701071314i61276e67hde685fe3afb8fe42@xxxxxxxxxxxxxx>). So instead of using 'self.relax.data.run' the data container of the current run, which is located in the dictionary type object 'self.relax.data[]', could be aliased as say 'data_pipe' or 'current_pipe' and placed into '__builtin__'. Then any part of relax can access the data of the current data pipe by referring directly to 'current_pipe'. Maybe a better variable name would be 'cdp' (current data pipe)? Or maybe simply 'data'?

In addition, I don't believe the name 'run' encapsulates the concept
at all.  This name is a relic which is not at all related to its
current use (https://mail.gna.org/public/relax-devel/2006-10/msg00056.html,
Message-id: <1160555137.9523.70.camel@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>).
The current use of the name 'run' encapsulates the segregation of the
data.  This is why I prefer the words 'data pipe' or 'pipe' over
'run'.


Thus we would have user functions:

run.create(run_name, run_type):
    self.relax._runs[run_name] = new_run(run_type)

The 'new_run' would be an empty data container (a class instance) and the data pipe type would be a simple string variable inside this container. Hence:

pipe.create(pipe_name, pipe_type):
   self.relax.data[pipe_name] = PipeContainer(pipe_type)


run.make_current(run_name):
    self.relax.data.run = self.relax._runs[run_name]

I see the word 'switch' is a little more direct than 'make_current', although there may be even better alternatives. What do you think Chris?

pipe.switch(pipe_name):
   __builtin__.current_pipe = self.relax.data[pipe_name]


run.current():
    return self.relax.data.run.name

pipe.current(): return current_pipe.name

Having the name stored in the dictionary as a key and in the data pipe
container as the 'name' variable is a little redundant.  Maybe the
current pipe name should be stored as say 'self.relax.current_pipe'?


run.run_names():
    return self.relax._runs.keys()

pipe.display(): print "%20s%20s" % ('Data pipe name', 'Data pipe type') for key in self.relax.data: print "%20s%20s" % (key, self.relax.data[key].pipe_type)


run.delete(run_name):
    if run.current() == run_name:
        self.relax.data.run = None
    del self.relax._runs[run_name]

pipe.delete(pipe_name): if self.relax.current_pipe == pipe_name: __builtin__.data = None del self.relax.data[pipe_name]


run.delete_all():
    self.relax.data.run = None
    self.relax._runs = {}

pipe.delete_all(): __builtin__.current_pipe = None self.relax.data = PipeDictionary()

The point of 'PipeDictionary()' rather than {} is because many of the
objects in 'self.relax.data' are special.  They have their
'__repr__()' methods modified so that when you type the object name at
the prompt, you get a formatted printout rather than something like:

<__main__.Data instance at 0xb764732c>


This way the abstraction of the dictionary of runs is cleanly hidden
from the developer who chooses to work with objects, but the scripting
style of the user interface is maintained.

Don't forget that the dictionary type 'self.relax.data' is an object, as are the values corresponding to its keys - the data pipe containers. In Python, essentially everything is an object.

Edward



Related Messages


Powered by MHonArc, Updated Tue Jan 16 17:20:22 2007