I like this.  It is basically what I couldn't figure out how to  
reasonably do when I refactored expand.  It would remove the need for  
the dummy functions expand_log, expand_mul, and so on.  Also, do you  
think that powsimp() could benefit from this?  When I rewrote it  
several weeks ago, I added a switch "combine" to control the two  
different combining methods (see the docstring for more info).  So  
basically, you can do combine='exp' to only combine exponentials,  
combine='base' to only combine bases, and combine='all' (the default)  
to do both.  I think we could probably use your function to do  
exp=True and base=True.  Also, I think my dsolve hints function that I  
am writing could benefit from this.

If we do this, we will have to change documentation, as well as usage  
of several expand() functions in code and tests because currently,  
doing <log, mul, power_exp, ...>=True is a no-op, so it needs to be  
made clear that it isn't any longer.

Also, see my comments below.

Aaron Meurer
On Jul 12, 2009, at 3:02 AM, smichr wrote:

>
> I am wondering if the attached switch manager might be a way to get
> rid of having to maintain a lot of wrappers for at least expand() and
> maybe for other methods. The idea is this (using expand as an
> example):
>
> expr.expand() uses all default expansion methods
>
> expr.expand(log=False) uses all default expansions EXCEPT log (can
> also use log=0 instead of log=False)
>
> expr.expand(log=True) uses ONLY the log expansion (can also use log=1
> instead of log=True)
>
> expr.expand(mul=True,multinomial=True) uses ONLY the mul and
> multinomial expansion
>
> The change that would make this possible requires only that the
> default values for the different expansion methods be set to None and
> then a couple lines of code are added in the expand, so
>
> this...
>    def expand(self, deep=True, power_base=True, power_exp=True,
> mul=True, \
>           log=True, multinomial=True, basic=True, **hints):
>        hints['power_base'] = power_base
>        hints['power_exp'] = power_exp
>        hints['mul'] = mul
>        hints['log'] = log
>        hints['multinomial'] = multinomial
>        hints['basic'] = basic
>
> becomes this...
>    def expand(self, deep=True, power_base=None, power_exp=None,
> mul=None, \
>           log=None, multinomial=None, basic=None, **hints):
>        dhints={}  #<--- additional line
>        dhints['power_base'] = power_base
>        dhints['power_exp'] = power_exp
>        dhints['mul'] = mul
>        dhints['log'] = log
>        dhints['multinomial'] = multinomial
>        dhints['basic'] = basic
>        switch_manager(dhints, default=True) {}  #<--- additional line
>        hints.update(dhints) {}  #<--- additional line
>
> It's not mandatory to create a new dictionary if the hints has only
> True or False values in it. It's only necessary if hints has other
> values in it. In that case, the first and last additional lines marked
> above are not necessary, and dhints is changed to hints.
>
> ######## attachment
> """
> demonstration of managing multiple switches for a function
> """
>
> def switch_manager(opt_dict, default=True):
Maybe you should also add a default_dict=True that takes in a  
dictionary of default options, incase there is a function that uses  
**kwargs instead of default arguments.  It would also allow default  
options to be False instead of True, though I don't know how much that  
would complicate the rules that you have outlined below.
>    """Given a dictionary of switch values (True, False, or None)
>    return the dictionary with switches True or False according to
>    the following logic:
>
>    -if all swtiches have been set and there are no None values,
> change nothing;
>    -if all switches are neutral (value = None) set them all to the
> default value;
>    -if some switches are True and some are False then set the rest to
> the default value;
On the two lines below, I assume you mean "if one or more switches  
have been set to True and none are set to False".  It is a little  
ambiguous the way you have it.
>    -if one or more switches have been set to True then set the rest
> to False;
>    -if one or more switches have been set to False then set the rest
> to True.
>    """
>    vals = set(filter(lambda x: x != None, opt_dict.values()))
>    if len(vals) == len(opt_dict):
>        return #there are no switches in neutral (None) position
>
>    if not all(tmp in [True, False, None] for tmp in vals):
>        #actually, 1 or 0 will pass as True or False, too
>        raise ValueError('Expecting only True, False, or None
> options.')
>
>    #make default opposite of what was given
>    if not vals or len(vals) > 1:
>        pass #don't change the default
>    elif vals.pop() == True:
>        default = False
>    else:
>        default = True
>
>    #set None values to default
>    for k in opt_dict:
>        if opt_dict[k] == None:
>            opt_dict[k] = default
>
> def demo(a=None, b=None, c=None, **opts):
>    default_opts={} #these are the options which must take on a value
>    default_opts['a'] = a
>    default_opts['b'] = b
>    default_opts['c'] = c
>    switch_manager(default_opts, default=True)
>    opts.update(default_opts)
>
>    #do whatever you are going to do with the options
>    for k in sorted(opts):
>        print k,opts[k]
>
> print 'demo()=all true by default'
> demo()
> print 'demo(a=True) only a true'
> demo(a=True)
> print 'demo(a=True,b=True) only a and b true; equivalent to demo
> (c=False)'
> demo(a=True,b=True)
> print 'demo(a=True,b=False) c is true by default; equivalent to demo
> (b=False)'
> demo(a=True,b=False)
> print 'demo(b=False) only b false'
> demo(b=False)
> print 'demo(d=42) a,b,c have default True and d is 42'
> demo(d=42)
> print 'demo(a=False,d=42) b,c have default True and d is 42'
> demo(a=False,d=42)
> print 'demo(b=True,d=42) a,c False and d is 42'
> demo(b=True,d=42)
>
> ## output
> '''
> demo()=all true by default
> a True
> b True
> c True
> demo(a=True) only a true
> a True
> b False
> c False
> demo(a=True,b=True) only a and b true; equivalent to demo(c=False)
> a True
> b True
> c False
> demo(a=True,b=False) c is true by default; equivalent to demo(b=False)
> a True
> b False
> c True
> demo(b=False) only b false
> a True
> b False
> c True
> demo(d=42) a,b,c have default True and d is 42
> a True
> b True
> c True
> d 42
> demo(a=False,d=42) b,c have default True and d is 42
> a False
> b True
> c True
> d 42
> demo(b=True,d=42) a,c False and d is 42
> a False
> b True
> c False
> d 42
> '''
> >


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [email protected]
For more options, visit this group at http://groups.google.com/group/sympy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to