Beispiel #1
0
class MultiProgressWidget(MultiProgressBar):
    """ Multiple progress bar Widget suitable for the notebook

    Displays multiple progress bars for a computation, split on computation
    type.

    See Also
    --------
    progress: User-level function <--- use this
    MultiProgress: Non-visualization component that contains most logic
    ProgressWidget: Single progress bar widget
    """
    def __init__(self, keys, scheduler=None, minimum=0, interval=0.1, func=key_split,
                 complete=False):
        super(MultiProgressWidget, self).__init__(keys, scheduler, func, interval, complete)
        from ipywidgets import VBox
        self.widget = VBox([])

    def make_widget(self, all):
        from ipywidgets import FloatProgress, HBox, VBox, HTML
        import cgi
        self.elapsed_time = HTML('')
        self.bars = {key: FloatProgress(min=0, max=1, description='', height = '10px')
                        for key in all}
        self.bar_texts = {key: HTML('', width = "140px") for key in all}
        self.bar_labels = {key: HTML('<div style=\"padding: 0px 10px 0px 10px; text-align:left; word-wrap: break-word;\">'
                                     + cgi.escape(key) + '</div>') for key in all}

        def key(kv):
            """ Order keys by most numerous, then by string name """
            return kv[::-1]

        key_order = [k for k, v in sorted(all.items(), key=key, reverse=True)]

        self.bar_widgets = VBox([ HBox([ self.bar_texts[key], self.bars[key], self.bar_labels[key] ]) for key in key_order ])
        self.widget.children = (self.elapsed_time, self.bar_widgets)

    def _ipython_display_(self, **kwargs):
        IOLoop.current().add_callback(self.listen)
        return self.widget._ipython_display_(**kwargs)

    def _draw_stop(self, remaining, status, exception=None, key=None, **kwargs):
        for k, v in remaining.items():
            if not v:
                self.bars[k].bar_style = 'success'

        """ TODO
        if status == 'error':
            self.bars[self.func(key)].bar_style = 'danger'
            self.elapsed_time.value = '<div style="padding: 0px 10px 5px 10px"><b>Warning:</b> the computation terminated due to an error after ' + format_time(self.elapsed) + '</div>'
        """

    def _draw_bar(self, remaining, all, status, **kwargs):
        if self.keys and not self.widget.children:
            self.make_widget(all)
        for k, ntasks in all.items():
            ndone = ntasks - remaining[k]
            self.elapsed_time.value = '<div style="padding: 0px 10px 5px 10px"><b>Elapsed time:</b> ' + format_time(self.elapsed) + '</div>'
            self.bars[k].value = ndone / ntasks if ntasks else 1.0
            self.bar_texts[k].value = '<div style="padding: 0px 10px 0px 10px; text-align: right">%d / %d</div>' % (ndone, ntasks)
Beispiel #2
0
class ProgressWidget(ProgressBar):
    """ProgressBar that uses an IPython ProgressBar widget for the notebook

    See Also
    --------
    progress: User function
    TextProgressBar: Text version suitable for the console
    """
    def __init__(
        self,
        keys,
        scheduler=None,
        interval="100ms",
        complete=False,
        loop=None,
        **kwargs,
    ):
        super().__init__(keys, scheduler, interval, complete)

        from ipywidgets import HTML, FloatProgress, HBox, VBox

        self.elapsed_time = HTML("")
        self.bar = FloatProgress(min=0, max=1, description="")
        self.bar_text = HTML("")

        self.bar_widget = HBox([self.bar_text, self.bar])
        self.widget = VBox([self.elapsed_time, self.bar_widget])

    def _ipython_display_(self, **kwargs):
        IOLoop.current().add_callback(self.listen)
        return self.widget._ipython_display_(**kwargs)

    def _draw_stop(self, remaining, status, exception=None, **kwargs):
        if status == "error":
            _, exception, _ = clean_exception(exception)
            self.bar.bar_style = "danger"
            self.elapsed_time.value = (
                '<div style="padding: 0px 10px 5px 10px"><b>Exception</b> '
                "<tt>" + repr(exception) + "</tt>:" +
                format_time(self.elapsed) + " " + "</div>")
        elif not remaining:
            self.bar.bar_style = "success"
            self.elapsed_time.value = (
                '<div style="padding: 0px 10px 5px 10px"><b>Finished:</b> ' +
                format_time(self.elapsed) + "</div>")

    def _draw_bar(self, remaining, all, **kwargs):
        ndone = all - remaining
        self.elapsed_time.value = (
            '<div style="padding: 0px 10px 5px 10px"><b>Computing:</b> ' +
            format_time(self.elapsed) + "</div>")
        self.bar.value = ndone / all if all else 1.0
        self.bar_text.value = (
            '<div style="padding: 0px 10px 0px 10px; text-align:right;">%d / %d</div>'
            % (ndone, all))
Beispiel #3
0
class ProgressWidget(ProgressBar):
    """ ProgressBar that uses an IPython ProgressBar widget for the notebook

    See Also
    --------
    progress: User function
    TextProgressBar: Text version suitable for the console
    """
    def __init__(self,
                 keys,
                 scheduler=None,
                 interval='100ms',
                 complete=False,
                 loop=None):
        super(ProgressWidget, self).__init__(keys, scheduler, interval,
                                             complete)

        from ipywidgets import FloatProgress, HBox, VBox, HTML
        self.elapsed_time = HTML('')
        self.bar = FloatProgress(min=0, max=1, description='', height='10px')
        self.bar_text = HTML('', width="140px")

        self.bar_widget = HBox([self.bar_text, self.bar])
        self.widget = VBox([self.elapsed_time, self.bar_widget])

    def _ipython_display_(self, **kwargs):
        IOLoop.current().add_callback(self.listen)
        return self.widget._ipython_display_(**kwargs)

    def _draw_stop(self, remaining, status, exception=None, **kwargs):
        if status == 'error':
            self.bar.bar_style = 'danger'
            self.elapsed_time.value = (
                '<div style="padding: 0px 10px 5px 10px"><b>Exception</b> '
                '<tt>' + repr(exception) + '</tt>:' +
                format_time(self.elapsed) + ' ' + '</div>')
        elif not remaining:
            self.bar.bar_style = 'success'
            self.elapsed_time.value = '<div style="padding: 0px 10px 5px 10px"><b>Finished:</b> ' + \
                format_time(self.elapsed) + '</div>'

    def _draw_bar(self, remaining, all, **kwargs):
        ndone = all - remaining
        self.elapsed_time.value = '<div style=\"padding: 0px 10px 5px 10px\"><b>Computing:</b> ' + \
            format_time(self.elapsed) + '</div>'
        self.bar.value = ndone / all if all else 1.0
        self.bar_text.value = '<div style="padding: 0px 10px 0px 10px; text-align:right;">%d / %d</div>' % (
            ndone, all)
Beispiel #4
0
class ProgressWidget(ProgressBar):
    """ ProgressBar that uses an IPython ProgressBar widget for the notebook

    See Also
    --------
    progress: User function
    TextProgressBar: Text version suitable for the console
    """

    def __init__(self, keys, scheduler=None, interval='100ms',
                 complete=False, loop=None):
        super(ProgressWidget, self).__init__(keys, scheduler, interval,
                                             complete)

        from ipywidgets import FloatProgress, HBox, VBox, HTML
        self.elapsed_time = HTML('')
        self.bar = FloatProgress(min=0, max=1, description='')
        self.bar_text = HTML('')

        self.bar_widget = HBox([self.bar_text, self.bar])
        self.widget = VBox([self.elapsed_time, self.bar_widget])

    def _ipython_display_(self, **kwargs):
        IOLoop.current().add_callback(self.listen)
        return self.widget._ipython_display_(**kwargs)

    def _draw_stop(self, remaining, status, exception=None, **kwargs):
        if status == 'error':
            self.bar.bar_style = 'danger'
            self.elapsed_time.value = (
                    '<div style="padding: 0px 10px 5px 10px"><b>Exception</b> '
                    '<tt>' + repr(exception) + '</tt>:' +
                    format_time(self.elapsed) + ' ' +
                    '</div>'
            )
        elif not remaining:
            self.bar.bar_style = 'success'
            self.elapsed_time.value = '<div style="padding: 0px 10px 5px 10px"><b>Finished:</b> ' + \
                format_time(self.elapsed) + '</div>'

    def _draw_bar(self, remaining, all, **kwargs):
        ndone = all - remaining
        self.elapsed_time.value = '<div style=\"padding: 0px 10px 5px 10px\"><b>Computing:</b> ' + \
            format_time(self.elapsed) + '</div>'
        self.bar.value = ndone / all if all else 1.0
        self.bar_text.value = '<div style="padding: 0px 10px 0px 10px; text-align:right;">%d / %d</div>' % (ndone, all)
Beispiel #5
0
class CrossSelect(SelectMultiple):
    """
    CrossSelect provides a two-tab multi-selection widget with regex
    text filtering. Items can be transferred with buttons between the
    selected and unselected options.
    """
    def __init__(self, *args, **kwargs):
        # Compute selected and unselected values
        options = kwargs.get('options', {})
        if isinstance(options, list):
            options = named_objs([(opt, opt) for opt in options])
        self._reverse_lookup = {v: k for k, v in options.items()}
        selected = [self._reverse_lookup[v] for v in kwargs.get('value', [])]
        unselected = [k for k in options if k not in selected]

        # Define whitelist and blacklist
        self._lists = {
            False: SelectMultiple(options=unselected),
            True: SelectMultiple(options=selected)
        }

        self._lists[False].observe(self._update_selection, 'value')
        self._lists[True].observe(self._update_selection, 'value')

        # Define buttons
        button_layout = Layout(width='50px')
        self._buttons = {
            False: Button(description='<<', layout=button_layout),
            True: Button(description='>>', layout=button_layout)
        }
        self._buttons[False].on_click(self._apply_selection)
        self._buttons[True].on_click(self._apply_selection)

        # Define search
        self._search = {
            False: Text(placeholder='Filter available options'),
            True: Text(placeholder='Filter selected options')
        }
        self._search[False].observe(self._filter_options, 'value')
        self._search[True].observe(self._filter_options, 'value')

        # Define Layout
        no_margin = Layout(margin='0')
        row_layout = Layout(margin='0',
                            display='flex',
                            justify_content='space-between')

        search_row = HBox([self._search[False], self._search[True]])
        search_row.layout = row_layout
        button_box = VBox([self._buttons[True], self._buttons[False]],
                          layout=Layout(margin='auto 0'))
        tab_row = HBox([self._lists[False], button_box, self._lists[True]])
        tab_row.layout = row_layout
        self._composite = VBox([search_row, tab_row], layout=no_margin)

        self.observe(self._update_options, 'options')
        self.observe(self._update_value, 'value')

        self._selected = {False: [], True: []}
        self._query = {False: '', True: ''}
        super(CrossSelect, self).__init__(*args, **dict(kwargs,
                                                        options=options))

    def _update_value(self, event):
        selected = [self._reverse_lookup.get(v, v) for v in event['new']]
        self._lists[True].options = selected
        self._lists[True].value = []
        self._lists[False].options = [
            o for o in self.options if o not in selected
        ]

    def _update_options(self, event):
        """
        Updates the options of each of the sublists after the options
        for the whole widget are updated.
        """
        self._reverse_lookup = {v: k for k, v in event['new'].items()}
        options = list(event['new'].keys()) if isinstance(
            event, dict) else event['new']
        self._selected[False] = []
        self._selected[True] = []
        self._lists[True].options = ['']
        self._lists[True].value = []
        self._lists[False].options = options
        self._lists[False].value = []
        self._apply_filters()

    def _apply_filters(self):
        self._filter_options({'owner': self._search[False]})
        self._filter_options({'owner': self._search[True]})

    def _filter_options(self, event):
        """
        Filters unselected options based on a text query event.
        """
        selected = event['owner'] is self._search[True]
        query = self._query[selected] if 'new' not in event else event['new']
        self._query[selected] = query
        other = self._lists[not selected].options
        options = [o for o in self.options if o not in other]
        if not query:
            self._lists[selected].options = options
            self._lists[selected].value = []
        else:
            try:
                match = re.compile(query)
                matches = list(filter(match.search, options))
                options = matches + [
                    opt for opt in options if opt not in matches
                ]
            except:
                matches = options
            self._lists[selected].options = options if options else ['']
            self._lists[selected].value = matches

    def _update_selection(self, event):
        """
        Updates the current selection in each list.
        """
        selected = event['owner'] is self._lists[True]
        self._selected[selected] = [v for v in event['new'] if v != '']

    def _apply_selection(self, event):
        """
        Applies the current selection depending on which button was
        pressed.
        """
        selected = event is self._buttons[True]
        new = self._selected[not selected]
        old = self._lists[selected].options
        other = self._lists[not selected].options

        merged = sorted([v for v in list(old) + list(new) if v != ''])
        leftovers = sorted([o for o in other if o not in new and o != ''])
        new_values = merged if selected else leftovers
        self._lists[selected].options = merged if merged else ['']
        self._lists[not selected].options = leftovers if leftovers else ['']
        self.value = [
            self._options_dict[o] for o in self._lists[True].options if o != ''
        ]
        self._apply_filters()

    def _ipython_display_(self, **kwargs):
        """
        Displays the composite widget.
        """
        self._composite._ipython_display_(**kwargs)

    def get_state(self, key=None, drop_defaults=False):
        # HACK: Lets this composite widget pretend to be a regular widget
        # when included into a layout.
        if key in ['value', '_options_labels']:
            return super(CrossSelect, self).get_state(key)
        return self._composite.get_state(key)
Beispiel #6
0
class MultiProgressWidget(MultiProgressBar):
    """ Multiple progress bar Widget suitable for the notebook

    Displays multiple progress bars for a computation, split on computation
    type.

    See Also
    --------
    progress: User-level function <--- use this
    MultiProgress: Non-visualization component that contains most logic
    ProgressWidget: Single progress bar widget
    """
    def __init__(
        self,
        keys,
        scheduler=None,
        minimum=0,
        interval=0.1,
        func=key_split,
        complete=False,
    ):
        super(MultiProgressWidget, self).__init__(keys, scheduler, func,
                                                  interval, complete)
        from ipywidgets import VBox

        self.widget = VBox([])

    def make_widget(self, all):
        from ipywidgets import FloatProgress, HBox, VBox, HTML

        self.elapsed_time = HTML("")
        self.bars = {
            key: FloatProgress(min=0, max=1, description="")
            for key in all
        }
        self.bar_texts = {key: HTML("") for key in all}
        self.bar_labels = {
            key:
            HTML('<div style="padding: 0px 10px 0px 10px;'
                 " text-align:left; word-wrap: "
                 'break-word;">' +
                 html_escape(key.decode() if isinstance(key, bytes) else key) +
                 "</div>")
            for key in all
        }

        def keyfunc(kv):
            """ Order keys by most numerous, then by string name """
            return kv[::-1]

        key_order = [
            k for k, v in sorted(all.items(), key=keyfunc, reverse=True)
        ]

        self.bar_widgets = VBox([
            HBox([self.bar_texts[key], self.bars[key], self.bar_labels[key]])
            for key in key_order
        ])
        self.widget.children = (self.elapsed_time, self.bar_widgets)

    def _ipython_display_(self, **kwargs):
        IOLoop.current().add_callback(self.listen)
        return self.widget._ipython_display_(**kwargs)

    def _draw_stop(self,
                   remaining,
                   status,
                   exception=None,
                   key=None,
                   **kwargs):
        for k, v in remaining.items():
            if not v:
                self.bars[k].bar_style = "success"
            else:
                self.bars[k].bar_style = "danger"

        if status == "error":
            # self.bars[self.func(key)].bar_style = 'danger'  # TODO
            self.elapsed_time.value = (
                '<div style="padding: 0px 10px 5px 10px"><b>Exception</b> ' +
                "<tt>" + repr(exception) + "</tt>:" +
                format_time(self.elapsed) + " " + "</div>")
        else:
            self.elapsed_time.value = (
                '<div style="padding: 0px 10px 5px 10px"><b>Finished:</b> ' +
                format_time(self.elapsed) + "</div>")

    def _draw_bar(self, remaining, all, status, **kwargs):
        if self.keys and not self.widget.children:
            self.make_widget(all)
        for k, ntasks in all.items():
            ndone = ntasks - remaining[k]
            self.elapsed_time.value = (
                '<div style="padding: 0px 10px 5px 10px"><b>Computing:</b> ' +
                format_time(self.elapsed) + "</div>")
            self.bars[k].value = ndone / ntasks if ntasks else 1.0
            self.bar_texts[k].value = (
                '<div style="padding: 0px 10px 0px 10px; text-align: right">%d / %d</div>'
                % (ndone, ntasks))
Beispiel #7
0
class Annotator(BaseAnnotator):
    """IPython widget to quickly annotate data sets.
    """
    def __init__(self, classes, history_length=10):
        super().__init__()
        self.history_length = int(history_length)
        self.last_repeat = 0
        self._build(classes)

    def build_display_value(self, item):
        """Build the display of the item being annotated.

        This class has to be overwritten in subclasses.

        :returns:
            an HTML reprensetation of the item to display.

        """
        return html.escape(repr(item))

    def clear(self):
        super().clear()
        self.last_repeat = 0

    def update_display(self):
        if self.current_item is None:
            self._html.value = "No data to annotate"
            self._info.value = "&nbsp;"

        else:
            reason, index, item = self.current_item
            self._html.value = self.build_display_value(item)
            self._info.value = html.escape("index: {}, reason: {}".format(
                index, reason))

        if len(self.annotations) > self.last_repeat:
            from ipywidgets import Button, Layout

            repeats = list(self._history.children)

            for idx in range(self.last_repeat, len(self.annotations)):
                annotation = self.annotations[idx]

                repeat_button = Button(
                    description=
                    f'{annotation["label"]} - {annotation["item"]!r}',
                    layout=Layout(width="50%"),
                )
                repeat_button.on_click(lambda b: self.repeat(idx))

                repeats = [repeat_button] + repeats

            self.last_repeat = len(self.annotations)

            repeats = repeats[:self.history_length]
            self._history.children = repeats

    def _build(self, classes):
        from ipywidgets import HTML, VBox, Layout, Box

        self._html = HTML(value="No data to annotate")
        self._info = HTML(value="&nbsp;")
        self._history = VBox(layout=Layout(margin="1em 0em 0em 0em"))

        self._widget = VBox([
            self._html,
            self._info,
            Box(
                [self._build_label_button(label) for label in classes],
                layout=Layout(flex_flow="row wrap"),
            ),
            self._history,
        ])

    def _build_label_button(self, label):
        from ipywidgets import Button

        if not isinstance(label, collections.abc.Mapping):
            label = {"label": label, "style": ""}

        else:
            label = dict(label)
            label.setdefault("style", "")

        b = Button(description=label["label"], button_style=label["style"])
        b.on_click(lambda b: self.annotate_current(label["label"]))
        return b

    def _ipython_display_(self, **kwargs):
        return self._widget._ipython_display_(**kwargs)