def __init__(self, model, opt, maxiters, verbose=False, current_iteration=0, ipython_notebook=True, clear_after_finish=False):
        self.verbose = verbose
        if self.verbose:
            self.model = model
            self.iteration = current_iteration
            self.p_iter = self.iteration
            self.maxiters = maxiters
            self.len_maxiters = len(str(maxiters))
            self.opt_name = opt.opt_name
            self.model.add_observer(self, self.print_status)
            self.status = 'running'
            self.clear = clear_after_finish

            self.update()

            try:
                from IPython.display import display
                from ipywidgets import IntProgress, HTML, Box, VBox, HBox, FlexBox
                self.text = HTML(width='100%')
                self.progress = IntProgress(min=0, max=maxiters)
                #self.progresstext = Text(width='100%', disabled=True, value='0/{}'.format(maxiters))
                self.model_show = HTML()
                self.ipython_notebook = ipython_notebook
            except:
                # Not in Ipython notebook
                self.ipython_notebook = False

            if self.ipython_notebook:
                left_col = VBox(children=[self.progress, self.text], padding=2, width='40%')
                right_col = Box(children=[self.model_show], padding=2, width='60%')
                self.hor_align = FlexBox(children = [left_col, right_col], width='100%', orientation='horizontal')

                display(self.hor_align)

                try:
                    self.text.set_css('width', '100%')
                    left_col.set_css({
                             'padding': '2px',
                             'width': "100%",
                             })

                    right_col.set_css({
                             'padding': '2px',
                             })

                    self.hor_align.set_css({
                             'width': "100%",
                             })

                    self.hor_align.remove_class('vbox')
                    self.hor_align.add_class('hbox')

                    left_col.add_class("box-flex1")
                    right_col.add_class('box-flex0')

                except:
                    pass

                #self.text.add_class('box-flex2')
                #self.progress.add_class('box-flex1')
            else:
                self.exps = exponents(self.fnow, self.current_gradient)
                print('Running {} Code:'.format(self.opt_name))
                print('  {3:7s}   {0:{mi}s}   {1:11s}    {2:11s}'.format("i", "f", "|g|", "runtime", mi=self.len_maxiters))
Beispiel #2
0
 def _create_widget(self):
     self.addbtn = Button(description='Add')
     self.addbtn.on_click(self.add_row_handler)
     vbox = VBox([self.addbtn])
     vbox.add_class('repeat-innotation')
     return vbox
    def __init__(self,
                 model,
                 opt,
                 maxiters,
                 verbose=False,
                 current_iteration=0,
                 ipython_notebook=True,
                 clear_after_finish=False):
        self.verbose = verbose
        if self.verbose:
            self.model = model
            self.iteration = current_iteration
            self.p_iter = self.iteration
            self.maxiters = maxiters
            self.len_maxiters = len(str(int(maxiters)))
            self.opt_name = opt.opt_name
            self.opt = opt
            self.model.add_observer(self, self.print_status)
            self.status = 'running'
            self.clear = clear_after_finish

            self.update()

            try:  # pragma: no cover
                from IPython.display import display
                from ipywidgets import IntProgress, HTML, Box, VBox, HBox, FlexBox
                self.text = HTML(width='100%')
                self.progress = IntProgress(min=0, max=maxiters)
                #self.progresstext = Text(width='100%', disabled=True, value='0/{}'.format(maxiters))
                self.model_show = HTML()
                self.ipython_notebook = ipython_notebook
            except:
                # Not in Ipython notebook
                self.ipython_notebook = False

            if self.ipython_notebook:  # pragma: no cover
                left_col = VBox(children=[self.progress, self.text],
                                padding=2,
                                width='40%')
                right_col = Box(children=[self.model_show],
                                padding=2,
                                width='60%')
                self.hor_align = FlexBox(children=[left_col, right_col],
                                         width='100%',
                                         orientation='horizontal')

                display(self.hor_align)

                try:
                    self.text.set_css('width', '100%')
                    left_col.set_css({
                        'padding': '2px',
                        'width': "100%",
                    })

                    right_col.set_css({
                        'padding': '2px',
                    })

                    self.hor_align.set_css({
                        'width': "100%",
                    })

                    self.hor_align.remove_class('vbox')
                    self.hor_align.add_class('hbox')

                    left_col.add_class("box-flex1")
                    right_col.add_class('box-flex0')

                except:
                    pass

                #self.text.add_class('box-flex2')
                #self.progress.add_class('box-flex1')
            else:
                self.exps = exponents(self.fnow, self.current_gradient)
                print('Running {} Code:'.format(self.opt_name))
                print('  {3:7s}   {0:{mi}s}   {1:11s}    {2:11s}'.format(
                    "i", "f", "|g|", "runtime", mi=self.len_maxiters))
Beispiel #4
0
class SageExplorer(VBox):
    """Sage Explorer in Jupyter Notebook"""

    value = Any()

    def __init__(self, obj=None):
        """
        TESTS::

            sage: from sage_explorer.sage_explorer import SageExplorer
            sage: S = StandardTableaux(15)
            sage: t = S.random_element()
            sage: widget = SageExplorer(t)
        """
        super(SageExplorer, self).__init__()
        self.title = Title()
        self.propsbox = VBox() # Will be a VBox full of HBoxes, one for each property
        self.titlebox = VBox()
        self.titlebox.add_class('titlebox')
        self.titlebox.add_class('lightborder')
        self.titlebox.children = [self.title, self.propsbox]
        self.visualbox = Box()
        self.visualtext = Textarea('', rows=8)
        self.visualwidget = None
        self.visualbox.add_class('visualbox')
        self.visualbox.children = [self.visualtext]
        self.top = HBox([self.titlebox, self.visualbox], layout=justified_h_layout)
        self.menus = Accordion(selected_index=None)
        self.menusbox = VBox([Title("Menus", 2), self.menus])
        self.menusbox.add_class('catalog-menus')
        self.menusbox.add_class('lightborder')
        self.inputs = HBox()
        self.gobutton = Button(description='Run!', tooltip='Run the function or method, with specified arguments')
        self.output = HTML()
        self.worktab = VBox((self.inputs, self.gobutton, self.output))
        self.doc = HTML()
        self.doctab = HTML() # For the method docstring
        self.tabs = Tab((self.worktab, self.doctab)) # Will be used when a method is selected
        self.tabs.add_class('tabs')
        self.tabs.set_title(0, 'Call')
        self.tabs.set_title(1, 'Help')
        self.main = Box((self.doc, self.tabs))
        self.main.add_class('lightborder')
        self.tabs.add_class('invisible') # Hide tabs at first display
        self.bottom = HBox((self.menusbox, self.main), layout=main_h_layout)
        self.children = (self.top, self.bottom)
        self.history = []
        self.set_value(obj)

    def init_selected_menu_value(self):
        r"""
        From a menu selection, compute display elements for the widgets.

        TESTS::
            sage: from sage_explorer.sage_explorer import SageExplorer, ExploredMember
            sage: from sage.monoids.string_monoid import AlphabeticStrings
            sage: e = SageExplorer()
            sage: m = ExploredMember('AlphabeticStrings', member=AlphabeticStrings)
            sage: e.selected_menu_value = m
            sage: e.init_selected_menu_value()
            sage: 'string monoid on generators A-Z' in e.doc.value
            True
        """
        if self.value:
            """If we are exploring an object, all menu items are functions"""
            self.init_selected_func()
            return
        """We are on the catalogs page"""
        selected_obj = self.selected_menu_value # An ExplorerMember
        if not hasattr(selected_obj, 'member_type'):
            selected_obj.compute_member_type()
        if not hasattr(selected_obj, 'doc'):
            selected_obj.compute_doc()
        if 'function' in selected_obj.member_type or 'method' in selected_obj.member_type:
            self.doctab.value = to_html(selected_obj.doc)
            if not hasattr(selected_obj, 'args'):
                try:
                    selected_obj.member = selected_obj.member()
                except:
                    pass
            elif hasattr(selected_obj, 'defaults') and len(selected_obj.defaults) == len(selected_obj.args):
                try:
                    selected_obj.member = selected_obj.member(selected_obj.defaults)
                except:
                    pass
            return
        if 'class' in selected_obj.member_type:
            self.doc.value = to_html(selected_obj.doc)
            self.doctab.value = ''
            self.inputs.children = []
            self.tabs.remove_class('visible')
            self.tabs.add_class('invisible')
            self.doc.remove_class('invisible')
            self.doc.add_class('visible')
            return

    def init_selected_func(self):
        r"""
        From a menu selection, compute display elements for the widgets.

        TESTS::
            sage: from sage_explorer.sage_explorer import SageExplorer, ExploredMember
            sage: from sage.combinat.partition import Partition
            sage: p = Partition([3,3,2,1])
            sage: e = SageExplorer(p)
            sage: m = ExploredMember('conjugate', parent=p)
            sage: e.selected_menu_value = m
            sage: e.init_selected_func()
            sage: str(e.doctab.value[:100]) # For Python3 compatibility
            '<div class="docstring">\n    \n  <blockquote>\n<div><p>Return the conjugate partition of the partition '
        """
        self.output.value = ''
        func = self.selected_menu_value # An ExplorerMember
        if not hasattr(func, 'doc'):
            func.compute_doc()
        if not hasattr(func, 'origin'):
            func.compute_origin()
        self.doctab.value = to_html(func.doc)
        if func.overrides:
            self.doctab.value += to_html("Overrides:")
            self.doctab.value += to_html(', '.join([extract_classname(x, element_ok=True) for x in func.overrides]))
        inputs = []
        if not hasattr(func, 'args'):
            func.compute_argspec()
        try:
            shift = 0
            for i in range(len(func.args)):
                argname = func.args[i]
                if argname in ['self']:
                    shift = 1
                    continue
                default = ''
                if func.defaults and len(func.defaults) > i - shift and func.defaults[i - shift]:
                    default = func.defaults[i - shift]
                inputs.append(Text(description=argname, placeholder=str(default)))
        except:
            print (func, "attr?")
            print (func.args, func.defaults)
        self.inputs.children = inputs
        self.doc.remove_class('visible')
        self.doc.add_class('invisible')
        self.tabs.remove_class('invisible')
        self.tabs.add_class('visible')

    def get_title(self):
        r"""
        Get explorer general title.

        TESTS:
            sage: from sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p = Partition([3,3,2,1])
            sage: e = SageExplorer(p)
            sage: e.get_title()
            'Exploring: [3, 3, 2, 1]'
        """
        return "Exploring: %s" % repr(self.value)

    def get_members(self):
        r"""
        Get all members for object self.value.

        OUTPUT: List of `Member` named tuples.

        TESTS::
            sage: from sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p = Partition([3,3,2,1])
            sage: e = SageExplorer(p)
            sage: e.get_members()
            sage: e.members[2].name, e.members[2].privacy
            ('__class__', 'python_special')
            sage: e.members[68].name, e.members[68].origin, e.members[68].privacy
            ('_doccls', <class 'sage.combinat.partition.Partitions_all_with_category.element_class'>, 'private')
            sage: [(e.members[i].name, e.members[i].overrides, e.members[i].prop_label) for i in range(len(e.members)) if e.members[i].name == '_reduction']
            [('_reduction',
             [<class 'sage.categories.infinite_enumerated_sets.InfiniteEnumeratedSets.element_class'>,
              <class 'sage.categories.enumerated_sets.EnumeratedSets.element_class'>,
              <class 'sage.categories.sets_cat.Sets.Infinite.element_class'>,
              <class 'sage.categories.sets_cat.Sets.element_class'>,
              <class 'sage.categories.sets_with_partial_maps.SetsWithPartialMaps.element_class'>,
              <class 'sage.categories.objects.Objects.element_class'>],
             None)]
            sage: e = SageExplorer(Partition)
            sage: e.get_members()
        """
        if isclass(self.value):
            c0 = self.value
        else:
            c0 = self.value.__class__
        self.valueclass = c0
        members = []
        for name, member in getmembers(c0):
            if isabstract(member) or 'deprecated' in str(type(member)).lower():
                continue
            m = ExploredMember(name, member=member, parent=self.value)
            m.compute_member_type()
            m.compute_origin()
            m.compute_privacy()
            m.compute_property_label(CONFIG_PROPERTIES)
            members.append(m)
        self.members = members

    def get_attributes(self):
        r"""
        Get all attributes for object self.value.

        OUTPUT: List of `Attribute` named tuples.

        TESTS::
            sage: from sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p = Partition([3,3,2,1])
            sage: e = SageExplorer(p)
            sage: e.get_attributes()
            sage: e.attributes[0].privacy
            'python_special'
            sage: [e.attributes[i].origin for i in range(len(e.attributes)) if e.attributes[i].name in ['_doccls', '_dummy_attribute', 'young_subgroup']]
            [<class 'sage.combinat.partition.Partitions_all_with_category.element_class'>,
             <class 'sage.categories.sets_cat.Sets.element_class'>,
             <class 'sage.combinat.partition.Partitions_all_with_category.element_class'>]
        """
        if not hasattr(self, 'members'):
            self.get_members()
        attributes = []
        for m in self.members:
            if m.member_type.startswith('attribute'):
                attributes.append(m)
        self.attributes = attributes

    def get_methods(self):
        r"""
        Get all methods specifications for object self.value.

        TESTS::
            sage: from sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p = Partition([3,3,2,1])
            sage: e = SageExplorer(p)
            sage: e.get_methods()
            sage: [e.methods[i].privacy for i in range(len(e.methods)) if e.methods[i].name in ['_latex_coeff_repr', '_sage_', 'is_zero']]
            ['private', 'sage_special', None]
            sage: [e.methods[i].args for i in range(len(e.methods)) if e.methods[i].name in ['_unicode_art_', 'dual_equivalence_graph', 'upper_hook']]
            [['self'], ['self', 'directed', 'coloring'], ['self', 'i', 'j', 'alpha']]
            sage: e = SageExplorer(Partition)
            sage: e.get_methods()
        """
        if not hasattr(self, 'members'):
            self.get_members()
        methods = []
        for m in self.members:
            if not 'method' in m.member_type and not 'function' in m.member_type:
                continue
            m.compute_argspec()
            methods.append(m)
        self.methods = methods

    def compute(self):
        """Get some properties, depending on the object
        Create links between menus and output tabs"""
        obj = self.value
        if obj is None:
            self.make_index()
            return
        if isclass(obj):
            c0 = obj
        else:
            c0 = obj.__class__
        if not hasattr(self, 'objclass') or c0 != self.objclass:
            self.objclass = c0
            self.get_members()
            self.get_attributes()
            self.get_methods()
        self.classname = extract_classname(c0, element_ok=False)
        self.title.value = self.get_title()
        replace_widget_w_css(self.tabs, self.doc)
        visualwidget = get_widget(obj)
        if visualwidget:
            # Reset if necessary, then replace with visualbox
            self.visualbox.children = [self.visualtext]
            self.visualwidget = visualwidget
            def graphical_change(change):
                self.set_value(change.new)
            self.visualwidget.observe(graphical_change, names='value')
            replace_widget_hard(self.visualbox, self.visualtext, self.visualwidget)
        else:
            try:
                self.visualtext.value = repr(obj._ascii_art_())
            except:
                self.visualtext.value = repr(obj)
            if self.visualwidget:
                replace_widget_hard(self.visualbox, self.visualwidget, self.visualtext)
                self.visualwidget = None
        attributes_as_properties = [m for m in self.attributes if m.prop_label]
        methods_as_properties = [m for m in self.methods if m.prop_label]
        attributes = [m for m in self.attributes if not m in attributes_as_properties and not m.name in EXCLUDED_MEMBERS and not m.privacy in ['private', 'sage_special']]
        methods = [m for m in self.methods if not m in methods_as_properties and not m.name in EXCLUDED_MEMBERS and not m.privacy in ['private', 'sage_special']]
        props = [Title('Properties', 2)] # a list of HBoxes, to become self.propsbox's children
        # Properties
        for p in attributes_as_properties + methods_as_properties:
            try:
                value = p.member(obj)
            except:
                print ("Warning: Error in finding method %s" % p.name)
                value = None
            button = self.make_new_page_button(value)
            b_label = p.prop_label
            if type(value) is type(True):
                b_label += '?'
            else:
                b_label += ':'
            props.append(HBox([
                Label(b_label),
                button
            ]))
        if len(self.history) > 1:
            self.propsbox.children = props + [self.make_back_button()]
        else:
            self.propsbox.children = props
        # Object doc
        self.doc.value = to_html(obj.__doc__) # Initialize to object docstring
        # Methods (sorted by definition classes)
        self.selected_menu_value = c0
        bases = []
        basemembers = {}
        for c in getmro(c0):
            bases.append(c)
            basemembers[c] = []
        for m in methods:
            basemembers[m.origin].append(m.name)
        for c in basemembers:
            if not basemembers[c]:
                bases.remove(c)
        menus = []
        for i in range(len(bases)):
            c = bases[i]
            menus.append(Select(rows=12, options = [(m.name, m) for m in methods if m.name in basemembers[c]]
            ))
        self.menus.children = menus
        for i in range(len(bases)):
            c = bases[i]
            self.menus.set_title(i, extract_classname(c))
        def menu_on_change(change):
            self.selected_menu_value = change.new
            self.init_selected_menu_value()
        for menu in self.menus.children:
            menu.observe(menu_on_change, names='value')
        def compute_selected_method(button):
            args = []
            for i in self.inputs.children:
                try:
                    arg = i.value or i.placeholder
                    evaled_arg = eval_in_main(arg)
                    if not arg:
                        self.output.value = to_html("Argument '%s' is empty!" % i.description)
                        return
                    args.append(evaled_arg)
                except:
                    self.output.value = to_html("Could not evaluate argument '%s'" % i.description)
                    return
            try:
                if AlarmInterrupt:
                    alarm(TIMEOUT)
                out = self.selected_menu_value.member(obj, *args)
                if AlarmInterrupt:
                    cancel_alarm()
            except AlarmInterrupt:
                self.output.value = to_html("Timeout!")
            except Exception as e:
                self.output.value = to_html(e)
                return
            self.output.value = to_html(out)
        self.gobutton.description = 'Run!'
        self.gobutton.on_click(compute_selected_method)

    def make_back_button(self):
        r"""
        Make a button for getting back to the previous object.

        TESTS::
            sage: from sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p1 = Partition([3,3,2,1])
            sage: p2 = Partition([5,3,2])
            sage: e = SageExplorer(p1)
            sage: e.make_back_button()
            sage: e.set_value(p2)
            sage: e.make_back_button()
            Button(description=u'Back', icon=u'history', layout=Layout(width=u'7em'), style=ButtonStyle(), tooltip=u'Go back to previous object page')
        """
        if len(self.history) <= 1:
            return
        button = Button(description='Back', icon='history', tooltip="Go back to previous object page", layout=back_button_layout)
        button.on_click(lambda event: self.pop_value()) # No back button in this new (previous object) page
        return button

    def make_new_page_button(self, obj):
        r"""
        Make a button for fetching a new explorer with value `obj`.

        TESTS::
            sage: from sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p1 = Partition([3,3,2,1])
            sage: p2 = Partition([5,3,2])
            sage: e = SageExplorer(p1)
            sage: e.make_new_page_button(p2)
            Button(description=u'[5, 3, 2]', style=ButtonStyle(), tooltip=u'Will close current explorer and open a new one')
        """
        button = Button(description=str(obj), tooltip="Will close current explorer and open a new one")
        button.on_click(lambda b:self.set_value(obj))
        return button

    def display_new_value(self, obj):
        r"""
        A callback for the navigation button.
        """
        self.visualbox.children[0].value = str(obj)

    def get_value(self):
        r"""
        Return math object currently explored.

        TESTS::
            sage: from sage_explorer.sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p = Partition([3,3,2,1])
            sage: e = SageExplorer(p)
            sage: e.get_value()
            [3, 3, 2, 1]
        """
        return self.value

    def set_value(self, obj):
        r"""
        Set new math object `obj` to the explorer.

        TESTS::
            sage: from sage_explorer.sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p = Partition([3,3,2,1])
            sage: e = SageExplorer(p)
            sage: e.get_value()
            [3, 3, 2, 1]
            sage: from sage.combinat.tableau import Tableau
            sage: t = Tableau([[1,2,3,4], [5,6]])
            sage: e.set_value(t)
            sage: e.get_value()
            [[1, 2, 3, 4], [5, 6]]
        """
        self.history.append(obj)
        self.value = obj
        self.compute()

    def pop_value(self):
        r"""
        Set again previous math object to the explorer.

        TESTS::
            sage: from sage_explorer.sage_explorer import SageExplorer
            sage: from sage.combinat.partition import Partition
            sage: p = Partition([3,3,2,1])
            sage: e = SageExplorer(p)
            sage: from sage.combinat.tableau import Tableau
            sage: t = Tableau([[1,2,3,4], [5,6]])
            sage: e.set_value(t)
            sage: e.get_value()
            [[1, 2, 3, 4], [5, 6]]
            sage: e.pop_value()
            sage: e.get_value()
            [3, 3, 2, 1]
        """
        if self.history:
            self.history.pop()
        if self.history:
            self.value = self.history[-1]
        else:
            self.value = None
        self.compute()

    def make_index(self):
        try:
            from ._catalogs import catalogs
        except:
            print("To build the index page, we need some catalogs.")
            catalogs = []
        self.selected_object = None
        self.title.value = "Sage Explorer"
        self.visualbox.children = [Title("Index Page")]
        self.tabs.remove_class('invisible')
        self.tabs.add_class('visible')
        self.gobutton.description = 'Go!'
        menus = []
        for label, catalog in catalogs:
            menu = Select(rows=12, options=make_catalog_menu_options(catalog))
            menus.append(menu)
        self.menus.children = menus
        for i, (label, _) in enumerate(catalogs):
            self.menus.set_title(i, label)
        def menu_on_change(change):
            self.selected_object = change.new
            self.display_new_value(self.selected_object.name)
            self.doctab.value = to_html(change.new.doc)
            self.gobutton.on_click(lambda b:self.set_value(self.selected_object.member))
        for menu in self.menus.children:
            menu.observe(menu_on_change, names='value')