Ticket #11732: trac_11732_sagenb_interact.patch

File trac_11732_sagenb_interact.patch, 9.9 KB (added by Julian Rüth, 11 years ago)
  • sagenb/notebook/interact.py

    exporting patch:
    # HG changeset patch
    # User Julian Rüth <julian.rueth@gmail.com>
    Trac 11732: faster import of sage.interacts.all
    
    diff --git a/sagenb/notebook/interact.py b/sagenb/notebook/interact.py
    index 79fc5b1..3fd3845 100644
    a b import types 
    155155# Sage libraries
    156156from jsmath import math_parse
    157157from sagenb.misc.misc import srange, sage_eval, Color, is_Matrix
     158from sage.misc.cachefunc import cached_method
    158159
    159160# SAGE_CELL_ID is a module scope variable that is always set equal to
    160161# the current cell id (of the executing cell).  Code that sets this is
    class slider_generic(control): 
    30383039    def __init__(self, vmin, vmax=None, step_size=None, label=None, display_value=True):
    30393040        control.__init__(self, label=label)
    30403041        self.__display_value = display_value
    3041         if isinstance(vmin, list):
    3042             vals = vmin
     3042        self.__vmin = vmin
     3043        self.__vmax = vmax
     3044        self.__step_size = step_size
     3045
     3046    @cached_method
     3047    def values(self):
     3048        """
     3049        Returns list of values that this slider takes on, in order.
     3050
     3051        OUTPUT:
     3052
     3053        - a list
     3054
     3055        .. note:: This is a reference to a mutable list.
     3056
     3057        EXAMPLES::
     3058
     3059            sage: sagenb.notebook.interact.slider(1,10,1/2).values()
     3060            [1, 3/2, 2, 5/2, 3, 7/2, 4, 9/2, 5, 11/2, 6, 13/2, 7, 15/2, 8, 17/2, 9, 19/2, 10]
     3061        """
     3062        if isinstance(self.__vmin, list):
     3063            vals = self.__vmin
    30433064        else:
    3044             if vmax is None:
    3045                 vmax = vmin
    3046                 vmin = 0
     3065            if self.__vmax is None:
     3066                self.__vmax = self.__vmin
     3067                self.__vmin = 0
    30473068
    30483069            #Compute step size; vmin and vmax are both defined here
    30493070            #500 is the length of the slider (in px)
    3050             if step_size is None:
    3051                 step_size = (vmax-vmin)/499.0
    3052             elif step_size <= 0:
     3071            if self.__step_size is None:
     3072                self.__step_size = (self.__vmax-self.__vmin)/499.0
     3073            elif self.__step_size <= 0:
    30533074                raise ValueError, "invalid negative step size -- step size must be positive"
    30543075
    30553076            #Compute list of values
    3056             num_steps = int(math.ceil((vmax-vmin)/float(step_size)))
     3077            num_steps = int(math.ceil((self.__vmax-self.__vmin)/float(self.__step_size)))
    30573078            if num_steps <= 2:
    3058                 vals = [vmin, vmax]
     3079                vals = [self.__vmin, self.__vmax]
    30593080            else:
    3060                 vals = srange(vmin, vmax, step_size, include_endpoint=True)
    3061                 if vals[-1] != vmax:
     3081                vals = srange(self.__vmin, self.__vmax, self.__step_size, include_endpoint=True)
     3082                if vals[-1] != self.__vmax:
    30623083                    try:
    3063                         if vals[-1] > vmax:
    3064                             vals[-1] = vmax
     3084                        if vals[-1] > self.__vmax:
     3085                            vals[-1] = self.__vmax
    30653086                        else:
    3066                             vals.append(vmax)
     3087                            vals.append(self.__vmax)
    30673088                    except (ValueError, TypeError):
    30683089                        pass
    30693090               
    30703091        #Is the list of values is small (len<=50), use the whole list.
    30713092        #Otherwise, use part of the list.
    30723093        if len(vals) == 0:
    3073             self.__values = [0]   
     3094            return [0]
    30743095        elif(len(vals)<=500):
    3075             self.__values = vals
     3096            return vals
    30763097        else:
    30773098            vlen = (len(vals)-1)/499.0
    3078             self.__values = [vals[(int)(i*vlen)] for i in range(500)]
    3079 
    3080     def values(self):
    3081         """
    3082         Returns list of values that this slider takes on, in order.
    3083 
    3084         OUTPUT:
    3085 
    3086         - a list
    3087 
    3088         .. note:: This is a reference to a mutable list.
    3089 
    3090         EXAMPLES::
    3091 
    3092             sage: sagenb.notebook.interact.slider(1,10,1/2).values()
    3093             [1, 3/2, 2, 5/2, 3, 7/2, 4, 9/2, 5, 11/2, 6, 13/2, 7, 15/2, 8, 17/2, 9, 19/2, 10]
    3094         """
    3095         return self.__values
     3099            return [vals[(int)(i*vlen)] for i in range(500)]
    30963100
    30973101    def display_value(self):
    30983102        """
    class slider(slider_generic): 
    31553159            Slider: alpha [1--|x|---2/3]           
    31563160        """
    31573161        slider_generic.__init__(self, vmin, vmax, step_size, label, display_value)
    3158 
    3159         # determine the best choice of index into the list of values
    3160         # for the user-selected default.
    3161         if default is None:
    3162             self.__default = 0
    3163         else:
    3164             try:
    3165                 i = self.values().index(default)
    3166             except ValueError:
    3167                 # here no index matches -- which is best?
    3168                 try:
    3169                     v = [(abs(default - self.values()[j]), j) for j in range(len(self.values()))]
    3170                     m = min(v)
    3171                     i = m[1]
    3172                 except TypeError: # abs not defined on everything, so give up
    3173                     i = 0
    3174             self.__default = i
     3162        self.__default = default
    31753163
    31763164    def __repr__(self):
    31773165        """
    class slider(slider_generic): 
    31903178                  self.values()[0],
    31913179             self.values()[self.default_index()], self.values()[-1])
    31923180
    3193 
     3181    @cached_method
    31943182    def default_index(self):
    31953183        """
    31963184        Return default index into the list of values.
    class slider(slider_generic): 
    32043192            sage: slider(2, 5, 1/2, 3, 'alpha').default_index()
    32053193            2
    32063194        """
    3207         return self.__default
     3195        # determine the best choice of index into the list of values
     3196        # for the user-selected default.
     3197        if self.__default is None:
     3198            return 0
     3199        else:
     3200            try:
     3201                i = self.values().index(self.__default)
     3202            except ValueError:
     3203                # here no index matches -- which is best?
     3204                try:
     3205                    v = [(abs(self.__default - self.values()[j]), j) for j in range(len(self.values()))]
     3206                    m = min(v)
     3207                    i = m[1]
     3208                except TypeError: # abs not defined on everything, so give up
     3209                    i = 0
     3210            return i
    32083211
    32093212    def render(self, var):
    32103213        """
    class slider(slider_generic): 
    32293232            sage: slider(2, 5, 2/7, 3, 'alpha').render('x')
    32303233            Slider Interact Control: alpha [2--|20/7|---5]
    32313234        """
    3232         return Slider(var, self.values(), self.__default, label=self.label(), display_value=self.display_value())
     3235        return Slider(var, self.values(), self.default_index(), label=self.label(), display_value=self.display_value())
    32333236
    32343237
    32353238class range_slider(slider_generic):
    class range_slider(slider_generic): 
    32713274            Range Slider: alpha [1--|3==7|---10]
    32723275        """
    32733276        slider_generic.__init__(self, vmin, vmax, step_size, label, display_value)
     3277        self.__default = default
    32743278
    3275         # determine the best choice of index into the list of values
    3276         # for the user-selected default.
    3277         if default is None:
    3278             self.__default = (0, 1)
    3279         elif not isinstance(default,tuple) or len(default)!=2:
    3280             raise TypeError("default value must be None or a 2-tuple.")
    3281         else:
    3282             dlist = []
    3283             for i in [0, 1]:
    3284                 try:
    3285                     d = self.values().index(default[i])
    3286                 except ValueError:
    3287                     # here no index matches -- which is best?
    3288                     try:
    3289                         v = [(abs(default[i] - self.values()[j]), j) for j in range(len(self.values()))]
    3290                         m = min(v)
    3291                         d = m[1]
    3292                     except TypeError: # abs not defined on everything, so give up
    3293                         d = 0
    3294                 dlist.append(d)
    3295             self.__default = (dlist[0], dlist[1])
    32963279
    32973280    def __repr__(self):
    32983281        """
    class range_slider(slider_generic): 
    33113294             self.values()[self.default_index()[0]],
    33123295             self.values()[self.default_index()[1]], self.values()[-1])
    33133296
     3297    @cached_method
    33143298    def default_index(self):
    33153299        """
    33163300        Return default index into the list of values.
    class range_slider(slider_generic): 
    33243308            sage: range_slider(2, 5, 1/2, (3,4), 'alpha').default_index()
    33253309            (2, 4)
    33263310        """
    3327         return self.__default
     3311        # determine the best choice of index into the list of values
     3312        # for the user-selected default.
     3313        if self.__default is None:
     3314            return (0, 1)
     3315        elif not isinstance(self.__default,tuple) or len(self.__default)!=2:
     3316            raise TypeError("default value must be None or a 2-tuple.")
     3317        else:
     3318            dlist = []
     3319            for i in [0, 1]:
     3320                try:
     3321                    d = self.values().index(self.__default[i])
     3322                except ValueError:
     3323                    # here no index matches -- which is best?
     3324                    try:
     3325                        v = [(abs(self.__default[i] - self.values()[j]), j) for j in range(len(self.values()))]
     3326                        m = min(v)
     3327                        d = m[1]
     3328                    except TypeError: # abs not defined on everything, so give up
     3329                        d = 0
     3330                dlist.append(d)
     3331            return (dlist[0], dlist[1])
    33283332
    33293333    def render(self, var):
    33303334        """
    class range_slider(slider_generic): 
    33493353            sage: range_slider(2, 5, 2/7, (3,4), 'alpha').render('x')
    33503354            Range Slider Interact Control: alpha [2--|20/7==4|---5]
    33513355        """
    3352         return RangeSlider(var, self.values(), self.__default, label=self.label(), display_value=self.display_value())
     3356        return RangeSlider(var, self.values(), self.default_index(), label=self.label(), display_value=self.display_value())
    33533357
    33543358       
    33553359class selector(control):