Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Global options for elements set by their parents
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Andrew Mathas  
View profile  
 More options Oct 27 2012, 8:43 am
From: Andrew Mathas <andrew.mat...@sydney.edu.au>
Date: Sat, 27 Oct 2012 05:43:08 -0700 (PDT)
Local: Sat, Oct 27 2012 8:43 am
Subject: Global options for elements set by their parents

Travis has is writing a nice patch #13605 which implements global options
for partitions. Among other things, these options determine how partitions
are printed (as lists, using exponential notation, compactly, ...), whether
diagrams follow the English or French conventions, whether the default
ordering is the lexicographic or dominance etc.

I have been bugging him with suggestions and requests, of which the main
ones are:

   - each option should be accessible as an individual method
   - the naming of these methods should systematic to make it easier for
   other classes, which may themselves have options, to easily access these
   methods.

As a result of these discussions I'd like to suggest a general frameworkfor implementing global options for element classes which are controlled by
their parents (being a parent myself I am of course advocating for parental
control here!:).  

The reason for this post is to ask whether need a general options mechanism
for element classes and, if so, is anyone in favour of the approach
described below.

The main idea is that the parent inherits a generic method (see below) of
the form:

def options(self, *option, **options):
    r"""
    Print and set options for the element class of ``self``
    """"
    ....

which is used to set and print the options for the element class. In the
element_class the options to the method ``foo`` are methods of the form
``foo_option1``, ``foo_option2`` and so on. What the ``options`` method of
the parent does is simply set ``self.element.foo`` equal to the desired
option. The nice thing about this, is that the options do not add extra
overhead to the methods and they can be added to the element class simply
by adding appropriate methods:

def _repr__fuzzy(self): return 'I am fuzzy'
def _repr__focussed(self: return 'I am focussed'
_repr_=_repr_focussed  # the default

and then you can set the option with

sage: parentClass.options(_repr_='fuzzy')

This will set  _repr_  = _repr__fuzzy  --- or raise a ValueError if this is
not a valid option.

As a test case, I have implemented a prototype for partitions, however, the
code is completely general. Just as importantly, it seems to work quite
well. For those who want to see the details I will upload a patch
trac_13605?--generic_partition_options-am.patch to the queue shortly.

Here are some examples of how it works:
sage: mu=Partition([4,4,3,2,1,1,1]); mu    
[4, 4, 3, 2, 1, 1, 1]
sage: Partitions(4).options('_repr_')      # the default behaviour is to
print partitions as lists
list

Because of the underscores, using _repr_ as the option name seems slightly
"wrong", so I allow an alias which in this case is 'display':

sage: Partitions(4).options('display')
list
sage: Partitions(4).options(display='exp'); mu
1^3, 2, 3, 4^2
sage: mu._repr__exp()                      # this is what _repr_ now calls
1^3, 2, 3, 4^2
sage: Partitions(4).options(display='exp_high'); mu
4^2, 3, 2, 1^3
sage: Partitions(4).options(display='compact'); mu
1^3,2,3,4^2
sage: Partitions(4).options(display='compact_high'); mu
4^2,3,2,1^3
sage: Partitions(4).options(display='diagram');
sage: Partitions(4).options(convention='french'); mu
*
*
*
**
***
****
****
****
****
sage: Partitions(4).options(convention='english'); mu
****
****
***
**
*
*
*
sage: Partitions(4).options(cmp='dominance')
sage: Partition([3,1,1,1])>Partition([2,2,2])
False
sage: Partitions(4).options(cmp='lex')       # lexicographic ordering
sage: Partition([3,1,1,1])>Partition([2,2,2])
True
sage: Partitions(4).options(display='exp'); mu
1^3, 2, 3, 4^2
sage: Partitions(4).options(display='exp_high'); mu
4^2, 3, 2, 1^3
sage: Partitions(4).options(display='list'); mu
[4, 4, 3, 2, 1, 1, 1]
sage: Partitions(4).options(display='exp_low')
Traceback (most recent call last):
...
ValueError: exp_low is not a valid option for display

Above 'cmp' is an alias which controls the options of the four methods
'__lt__', '__le__', '__ge__' and '__gt__'. So aliases allow options to be
given sensible names and, in addition, they allow one option to change more
than one method.

With this scheme I am able to do everything which Travis does except
(possibly?) for passing arguments to methods. (Travis allows you to
globally set the character printed in a Ferrers diagram.) In the examples
above I use Partitions(4) only because I added the options method to
Partitions_n, rather than to Partitions_all, and these two classes are
completely independent of each other because partitions are not fully
integrated into the parent/element framework.

Please let me know what you think.

Cheers,
Andrew

----

To save you looking at the patch here is the options method

# the keys of option_alias are aliases to options, or groups of options.
option_alias = {'cmp':['__le__','__lt__','__ge__','__gt__'],
                'convention':['ferrers_diagram','_latex__diagram'],
                'display':['_repr_'],
                'latex':['_latex_']
                }

def options(self, *option, **options):
    r"""
    Print and set options for the element class of ``self``.

    Global options for the method ``foo`` of the element_class are methods
    with names of the form ``foo_<option name>``. For example, for
    :class:`Partition_class` the following optional methods for ``_repr_``
    are currently implemented::

    -_repr__list(self):
    -_repr__exp(self):
    -_repr__exp_high(self):
    -_repr__compact(self):
    -_repr__compact_high(self):
    -_repr__diagram(self):

    The global options can changed, and the current options printed, using
``self.options``:

    EXAMPLES::

        sage: mu=Partition([4,4,3,2,1,1,1]); mu
        [4, 4, 3, 2, 1, 1, 1]
        sage: Partitions(4).options('_repr_')
        list
        sage: Partitions(4).options(_repr_='exp'); mu
        1^3, 2, 3, 4^2
        sage: Partitions(4).options(_repr_='exp_high'); mu
        4^2, 3, 2, 1^3
        sage: Partitions(4).options(_repr_='compact'); mu
        1^3,2,3,4^2
        sage: Partitions(4).options(_repr_='compact_high'); mu
        4^2,3,2,1^3
        sage: Partitions(4).options(_repr_='diagram');
        sage: Partitions(4).options(convention='french'); mu
        *
        *
        *
        **
        ***
        ****
        ****
        ****
        ****
        sage: Partitions(4).options(convention='endlish'); mu
        ****
        ****
        ***
        **
        *
        *
        *
        sage: Partitions(4).options(cmp='dominance')
        sage: Partition([3,1,1,1])>Partition([2,2,2])
        False
        sage: Partitions(4).options(cmp='lex')
        sage: Partition([3,1,1,1])>Partition([2,2,2])
        True
        sage: Partitions(4).options(display='exp_low')
        Traceback (most recent call last):
        ...
        ValueError: exp_low is not a valid option for display

    The dictionary ``self.option_alias`` defines aliases for options
    so that the different options can be given more user friendly names.
For example,
    ``display`` is an option for ``_repr__``::

    EXAMPLES::

        sage: Partitions(4).options(display='exp'); mu
        1^3, 2, 3, 4^2
        sage: Partitions(4).options(display='exp_high'); mu
        4^2, 3, 2, 1^3
        sage: Partitions(4).options(display='list'); mu
        [4, 4, 3, 2, 1, 1, 1]

    The values of ``self.option_alias`` are lists of strings so that one
    option can change several different methods. For example, the ``cmp``
    option redefines the behaviour of the four comparison methods
    ``__le__``, ``__lt__``, ``__ge__`` and ``__gt__``. Note that we need
    need to append '__' to all method names which begin with '__' otherwise
    they are treated as inaccessible private methods.
    """
    # todo: when called with no arguments a list of all options should be
printed,
    #           ...probably needs to be done via something like
``self.options_doc``
    # --
    # print the current settings for the options in ``option``
    for opt in option:  
        try:
            opt_name=self.option_alias.get(opt,[opt])[0]
            current_opt=getattr(self.element_class,opt_name).__name__
            current_opt=current_opt[len(opt_name)+1:]
            if opt_name[:2]=='__':      # some trickery to avoid private
classes
                current_opt=current_opt[:-2]  # remove trailing '__'
            print current_opt[len(opt_name):]
        except AttributeError:
            raise ValueError, '%s is not a valid option' % opt
    # change the option settings for the options in ``options``  
    for opt in options:
        for opt_name in self.option_alias.get(opt,[opt]):
            if opt_name[:2]=='__':   # some trickery to avoid private
classes
                new_opt=opt_name+'_'+options[opt]+'__'
            else:
                new_opt=opt_name+'_'+options[opt]
            if hasattr(self.element_class,new_opt):
                new_opt=getattr(self.element_class,new_opt)
                setattr(self.element_class, opt_name, new_opt)
            else:
                raise ValueError, '%s is not a valid option for %s' %
(options[opt], opt)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.