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
-~----------~----~----~----~------~----~------~--~---