<commit_before>#
# statistics_dlg.py <mike@peacecorps.org.cv>
#
# TODO: Refactor graph classes into BarGraph, PieChart, and Histogram, rather
# than ScheduleGraph, GradesGraph, and EasinessGraph
#

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from numpy import arange
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

from mnemosyne.libmnemosyne.component_manager import database
from mnemosyne.libmnemosyne.utils import numeric_string_cmp
from ui_statistics_dlg import Ui_StatisticsDlg

class StatGraph(FigureCanvas):

    """Base canvas class for creating graphs with Matplotlib."""

    def __init__(self, parent=None, width=5, height=4, dpi=100, color='white',
                 scope=None):
        self.fig = Figure(figsize=(width, height), dpi=dpi, facecolor=color,
                          edgecolor=color)
        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QSizePolicy.MinimumExpanding,
                                   QSizePolicy.MinimumExpanding)
        self.setParent(parent)
        self.axes = self.fig.add_subplot(111)
        self.generate_figure(scope)
        #FigureCanvas.updateGeometry(self)

    def generate_figure(self, scope):
        pass

    def display_message(self, msg):
        self.axes.clear()
        self.axes.set_xticklabels('')
        self.axes.set_yticklabels('')
        self.axes.set_xticks((0.0,))
        self.axes.set_yticks((0.0,))
        self.axes.text(0.5, 0.5, msg, transform=self.axes.transAxes,
                       horizontalalignment='center', verticalalignment='center')

class ScheduleGraph(StatGraph):

    """Graph of card scheduling statistics."""

    def generate_figure(self, scope):
        if scope == 'all_time':
            self.generate_histogram()
        else:
            self.generate_bar_graph(scope)

    def generate_bar_graph(self, scope):

        """Create a bar graph of card scheduling statistics."""

        BAR_WIDTH = 1.0
        HALF_WIDTH = BAR_WIDTH / 2.0
        xticklabels = lambda i, j: map(lambda x: "+%d" % x, range(i, j))
        scope_vars_map = {'next_week': {'range': range(0, 7, 1),
                                        'bar_colors': ('r', 'g', 'b', 'c', 'm',
                                                       'y', 'k'),
                                        'xlabel': 'Days',
                                        'xticklabels': ['Today'] +
                                                       xticklabels(1, 7)},
                          'next_month': {'range': range(6, 28, 7),
                                         'bar_colors': ('r', 'g', 'b', 'c'),
                                         'xlabel': 'Weeks',
                                         'xticklabels': ['This week'] +
                                                        xticklabels(1, 4)},
                          'next_year':  {'range': range(30, 365, 30),
                                         'bar_colors': 'red',
                                         'xlabel': 'Months',
                                         'xticklabels': xticklabels(0, 12)}}
        scope_vars = scope_vars_map[scope]
        range_ = scope_vars['range']
        self.axes.set_ylabel('Number of Cards Scheduled')
        self.axes.set_xlabel(scope_vars['xlabel'])
        values = []
        old_cumulative = 0
        for days in range_:
            cumulative = database().scheduled_count(days)
            values.append(cumulative - old_cumulative)
            old_cumulative = cumulative

        # No cards scheduled for this time frame.
        if max(values) == 0:
            self.display_message('No stats available.')
            return

        xticks = arange(len(values)) + HALF_WIDTH
        bar_colors = ('r', 'g', 'b', 'c', 'm', 'y', 'k')
        self.axes.bar(xticks, values, BAR_WIDTH, align='center',
                      color=bar_colors, alpha=0.7, linewidth=0)
        self.axes.set_xticks(xticks)
        self.axes.set_xticklabels(scope_vars['xticklabels'], fontsize='small')

        # Pad the right side of the graph if the last value is zero. Otheriwse,
        # the graph ends at the final xtick label, which looks ugly.
        if values[-1] == 0:
            _, xmax = self.axes.set_xlim()
            self.axes.set_xlim(xmax=xmax+HALF_WIDTH)

        max_value = max(values)
        tick_interval = round((max_value / 4.0) + 1)
        self.axes.set_yticks(arange(tick_interval, max_value + tick_interval,
                                    tick_interval))
        self.axes.set_ylim(ymax=max_value + 0.5 * tick_interval)
        for label in self.axes.get_yticklabels():
            label.set_size('small')

        # Add exact numeric values above each bar. The text padding is based
        # on the average height of non-zero bars. This gives a reasonable
        # padding for most data, but looks ugly when one bar is *much* larger
        # than the others. Note that bool() can be used as the filter function
        # since bool(0) == False.
        avg = lambda s: sum(s) / len(s)
        avg_height = avg(filter(bool, values))
        pad = avg_height * 1.05 - avg_height
        for i in range(len(values)):
            height = values[i]
            if height == 0: continue
            self.axes.text(xticks[i], height + pad, '%d' % height, ha='center',
                           va='bottom', fontsize='small')

    def generate_histogram(self):

        """Create a histogram of card scheduling statistics."""

        self.axes.set_ylabel('Number of Cards Scheduled')
        self.axes.set_xlabel('Days')
        xs = [c.next_rep for c in database().cards]
        if len(xs) == 0:
            self.display_message('No stats available.')
            return
        self.axes.hist(xs, facecolor='red', alpha=0.7)
        self.axes.grid(True)

class GradesGraph(StatGraph):

    """Graph of card grade statistics."""

    def __init__(self, parent=None, width=4, height=4, dpi=100, color='white',
                 scope=None):
        # Pie charts look better on a square canvas.
        StatGraph.__init__(self, parent, width, height, dpi, color, scope)

    def generate_figure(self, scope):

        """Create a pie chart of card grade statistics."""

        self.axes.set_title('Number of cards per grade level')
        grades = [0] * 6 # There are six grade levels
        for card in database().cards:
            cat_names = [c.name for c in card.fact.cat]
            if scope == 'all_categories__' or scope in cat_names:
                grades[card.grade] += 1

        if max(grades) == 0:
            self.display_message('No stats available.')
            return

        # Only print percentage on wedges > 5%.
        autopctfn = lambda x: '%1.1f%%' % x if x > 5 else ''
        self.axes.pie(grades, explode=(0.05, 0, 0, 0, 0, 0), autopct=autopctfn,
                      labels=['Grade %d' % g if grades[g] > 0 else ''
                              for g in range(0, len(grades))],
                      colors=('r', 'm', 'y', 'g', 'c', 'b'), shadow=True)

class EasinessGraph(StatGraph):

    """Graph of card easiness statistics."""

    def generate_figure(self, scope):
        """
        Create a histogram of easiness values for every card.

        scope -- a category name or the string 'all_categories__'

        """
        self.axes.set_ylabel('Number of cards')
        self.axes.set_xlabel('Easiness')
        xs = []
        for card in database().cards:
            cat_names = [c.name for c in card.fact.cat]
            if scope == 'easiness_all_categories' or scope in cat_names:
                xs.append(card.easiness)
        if len(xs) == 0:
            self.display_message('No stats available.')
            return
        self.axes.hist(xs, facecolor='red', alpha=0.7)
        self.axes.grid(True)

class StatisticsDlg(QDialog, Ui_StatisticsDlg):

    # TODO: Factor out duplicated code from add_*_stats() methods.

    def __init__(self, parent=None, name=None, modal=0):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.add_schedule_stats()
        self.add_grades_stats()
        self.add_easiness_stats()

    def add_schedule_stats(self):
        """Add graphs for schedule statistics to the sched tab."""
        bg_color = self.background_color()
        scopes = self.page_names_for_stacked_widget(self.sched_stack)
        self.add_graphs_for_scopes(ScheduleGraph, scopes, bg_color)

    def add_grades_stats(self):
        """
        Add graphs for grade statistics to the grade tab.

        Fist, add items to the QComboBox and corresponding pages to the
        QStackedWidget for each category in the database. Then, add the graph
        for each category to the pages of the stacked widget.

        """
        # TODO: get rid of duplicate code (see the update_categories_combobox
        # method in add_cards_dlg.py) by overriding QComboBox's sorting method.
        sorted_categories = sorted(database().category_names(),
                                   cmp=numeric_string_cmp)
        self.add_items_to_combo_box_and_stacked_widget(sorted_categories,
                                                       self.grades_combo,
                                                       self.grades_stack)
        bg_color = self.background_color()
        scopes = self.page_names_for_stacked_widget(self.grades_stack)
        self.add_graphs_for_scopes(GradesGraph, scopes, bg_color)

    def add_easiness_stats(self):
        """
        Add graphs for easiness statistics to the easiness tab.

        """
        sorted_categories = sorted(database().category_names(),
                                   cmp=numeric_string_cmp)
        self.add_items_to_combo_box_and_stacked_widget(sorted_categories,
                                                       self.easiness_combo,
                                                       self.easiness_stack)
        bg_color = self.background_color()
        scopes = self.page_names_for_stacked_widget(self.easiness_stack)
        self.add_graphs_for_scopes(EasinessGraph, scopes, bg_color)

    def add_items_to_combo_box_and_stacked_widget(self, items, combo, stack):
        """
        Add each item in list to the specified combo box and stack widget.

        items -- a list of strings that will be used as both the combo box
                 text and the new stack widget page name.
        combo -- the QComboBox to which the items will be added.
        stack -- the QStackWidget to which the pages will be added.

        """
        for name in items:
            combo.addItem(QString(name))
            widget = QWidget()
            widget.setObjectName(name)
            stack.addWidget(widget)
            setattr(self, name, widget)

    def add_graphs_for_scopes(self, graph_type, scopes, bg='white'):
        """
        Add a graph of type <graph_type> for each scope.

        graph_type -- the type of graph to add. Must be an actual classname.
        scopes -- a list of keywords on which the graph specializes it's output,
                  e.g. ('daily', 'weekly', 'monthly', 'all_time').

        Keyword Arguments:
        bg -- the background color for the graph (default 'white').

        """
        for scope in scopes:
            parent = getattr(self, scope)
            layout_name = scope + '_layout'
            setattr(self, layout_name, QVBoxLayout(parent))
            layout = getattr(self, layout_name)
            layout.setObjectName(layout_name)
            graph_name = scope + '_graph'
            graph = graph_type(parent, scope=scope, color=bg)
            setattr(self, graph_name, graph)
            graph.setObjectName(graph_name)
            layout.addWidget(graph)

    def background_color(self):
        """
        Return this window's background color.

        Sadly, this won't work on OS X, XP, or Vista since they use native
        theme engines for drawing, rather than the palette. See:
        http://doc.trolltech.com/4.4/qapplication.html#setPalette

        """
        if self.style().objectName() == 'macintosh (Aqua)':
            bg_color = '0.91'
        else:
            r, g, b, _ = self.palette().color(self.backgroundRole()).getRgb()
            bg_color = map(lambda x: x / 255.0, (r, g, b))
        return bg_color

    def page_names_for_stacked_widget(self, stack):
        """
        Return a list of page names for the given stacked widget.

        stack -- a QStackWidget

        """
        # TODO: move this function into utils.py
        names = []
        for i in range(0, stack.count()):
            names.append(stack.widget(i).objectName().__str__())
        return names
<commit_msg>Gave stack widgets unique names by prepending object id<commit_after>#
# statistics_dlg.py <mike@peacecorps.org.cv>
#
# TODO: Refactor graph classes into BarGraph, PieChart, and Histogram, rather
# than ScheduleGraph, GradesGraph, and EasinessGraph
#

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from numpy import arange
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

from mnemosyne.libmnemosyne.component_manager import database
from mnemosyne.libmnemosyne.utils import numeric_string_cmp
from ui_statistics_dlg import Ui_StatisticsDlg

class StatGraph(FigureCanvas):

    """Base canvas class for creating graphs with Matplotlib."""

    def __init__(self, parent=None, width=5, height=4, dpi=100, color='white',
                 scope=None):
        self.fig = Figure(figsize=(width, height), dpi=dpi, facecolor=color,
                          edgecolor=color)
        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QSizePolicy.MinimumExpanding,
                                   QSizePolicy.MinimumExpanding)
        self.setParent(parent)
        self.axes = self.fig.add_subplot(111)
        self.generate_figure(scope)
        #FigureCanvas.updateGeometry(self)

    def generate_figure(self, scope):
        pass

    def display_message(self, msg):
        self.axes.clear()
        self.axes.set_xticklabels('')
        self.axes.set_yticklabels('')
        self.axes.set_xticks((0.0,))
        self.axes.set_yticks((0.0,))
        self.axes.text(0.5, 0.5, msg, transform=self.axes.transAxes,
                       horizontalalignment='center', verticalalignment='center')

class ScheduleGraph(StatGraph):

    """Graph of card scheduling statistics."""

    def generate_figure(self, scope):
        if scope == 'all_time':
            self.generate_histogram()
        else:
            self.generate_bar_graph(scope)

    def generate_bar_graph(self, scope):

        """Create a bar graph of card scheduling statistics."""

        BAR_WIDTH = 1.0
        HALF_WIDTH = BAR_WIDTH / 2.0
        xticklabels = lambda i, j: map(lambda x: "+%d" % x, range(i, j))
        scope_vars_map = {'next_week': {'range': range(0, 7, 1),
                                        'bar_colors': ('r', 'g', 'b', 'c', 'm',
                                                       'y', 'k'),
                                        'xlabel': 'Days',
                                        'xticklabels': ['Today'] +
                                                       xticklabels(1, 7)},
                          'next_month': {'range': range(6, 28, 7),
                                         'bar_colors': ('r', 'g', 'b', 'c'),
                                         'xlabel': 'Weeks',
                                         'xticklabels': ['This week'] +
                                                        xticklabels(1, 4)},
                          'next_year':  {'range': range(30, 365, 30),
                                         'bar_colors': 'red',
                                         'xlabel': 'Months',
                                         'xticklabels': xticklabels(0, 12)}}
        scope_vars = scope_vars_map[scope]
        range_ = scope_vars['range']
        self.axes.set_ylabel('Number of Cards Scheduled')
        self.axes.set_xlabel(scope_vars['xlabel'])
        values = []
        old_cumulative = 0
        for days in range_:
            cumulative = database().scheduled_count(days)
            values.append(cumulative - old_cumulative)
            old_cumulative = cumulative

        # No cards scheduled for this time frame.
        if max(values) == 0:
            self.display_message('No stats available.')
            return

        xticks = arange(len(values)) + HALF_WIDTH
        bar_colors = ('r', 'g', 'b', 'c', 'm', 'y', 'k')
        self.axes.bar(xticks, values, BAR_WIDTH, align='center',
                      color=bar_colors, alpha=0.7, linewidth=0)
        self.axes.set_xticks(xticks)
        self.axes.set_xticklabels(scope_vars['xticklabels'], fontsize='small')

        # Pad the right side of the graph if the last value is zero. Otheriwse,
        # the graph ends at the final xtick label, which looks ugly.
        if values[-1] == 0:
            _, xmax = self.axes.set_xlim()
            self.axes.set_xlim(xmax=xmax+HALF_WIDTH)

        max_value = max(values)
        tick_interval = round((max_value / 4.0) + 1)
        self.axes.set_yticks(arange(tick_interval, max_value + tick_interval,
                                    tick_interval))
        self.axes.set_ylim(ymax=max_value + 0.5 * tick_interval)
        for label in self.axes.get_yticklabels():
            label.set_size('small')

        # Add exact numeric values above each bar. The text padding is based
        # on the average height of non-zero bars. This gives a reasonable
        # padding for most data, but looks ugly when one bar is *much* larger
        # than the others. Note that bool() can be used as the filter function
        # since bool(0) == False.
        avg = lambda s: sum(s) / len(s)
        avg_height = avg(filter(bool, values))
        pad = avg_height * 1.05 - avg_height
        for i in range(len(values)):
            height = values[i]
            if height == 0: continue
            self.axes.text(xticks[i], height + pad, '%d' % height, ha='center',
                           va='bottom', fontsize='small')

    def generate_histogram(self):

        """Create a histogram of card scheduling statistics."""

        self.axes.set_ylabel('Number of Cards Scheduled')
        self.axes.set_xlabel('Days')
        xs = [c.next_rep for c in database().cards]
        if len(xs) == 0:
            self.display_message('No stats available.')
            return
        self.axes.hist(xs, facecolor='red', alpha=0.7)
        self.axes.grid(True)

class GradesGraph(StatGraph):

    """Graph of card grade statistics."""

    def __init__(self, parent=None, width=4, height=4, dpi=100, color='white',
                 scope=None):
        # Pie charts look better on a square canvas.
        StatGraph.__init__(self, parent, width, height, dpi, color, scope)

    def generate_figure(self, scope):

        """Create a pie chart of card grade statistics."""

        self.axes.set_title('Number of cards per grade level')
        grades = [0] * 6 # There are six grade levels
        for card in database().cards:
            cat_names = [c.name for c in card.fact.cat]
            if scope == 'all_categories__' or scope in cat_names:
                grades[card.grade] += 1

        if max(grades) == 0:
            self.display_message('No stats available.')
            return

        # Only print percentage on wedges > 5%.
        autopctfn = lambda x: '%1.1f%%' % x if x > 5 else ''
        self.axes.pie(grades, explode=(0.05, 0, 0, 0, 0, 0), autopct=autopctfn,
                      labels=['Grade %d' % g if grades[g] > 0 else ''
                              for g in range(0, len(grades))],
                      colors=('r', 'm', 'y', 'g', 'c', 'b'), shadow=True)

class EasinessGraph(StatGraph):

    """Graph of card easiness statistics."""

    def generate_figure(self, scope):
        """
        Create a histogram of easiness values for every card.

        scope -- a category name or the string 'all_categories__'

        """
        self.axes.set_ylabel('Number of cards')
        self.axes.set_xlabel('Easiness')
        self.axes.set_title(scope)
        xs = []
        for card in database().cards:
            cat_names = [c.name for c in card.fact.cat]
            if scope == 'easiness_all_categories' or scope in cat_names:
                xs.append(card.easiness)
        if len(xs) == 0:
            self.display_message('No stats available.')
            return
        self.axes.hist(xs, facecolor='red', alpha=0.7)
        self.axes.grid(True)

class StatisticsDlg(QDialog, Ui_StatisticsDlg):

    # TODO: Factor out duplicated code from add_*_stats() methods.

    def __init__(self, parent=None, name=None, modal=0):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.add_schedule_stats()
        self.add_grades_stats()
        self.add_easiness_stats()

    def add_schedule_stats(self):
        """Add graphs for schedule statistics to the sched tab."""
        bg_color = self.background_color()
        scopes = self.page_names_for_stacked_widget(self.sched_stack)
        widgets = self.pages_for_stacked_widget(self.sched_stack)
        self.add_graphs_for_scopes(ScheduleGraph, scopes, widgets, bg_color)

    def add_grades_stats(self):
        """
        Add graphs for grade statistics to the grade tab.

        Fist, add items to the QComboBox and corresponding pages to the
        QStackedWidget for each category in the database. Then, add the graph
        for each category to the pages of the stacked widget.

        """
        # TODO: get rid of duplicate code (see the update_categories_combobox
        # method in add_cards_dlg.py) by overriding QComboBox's sorting method.
        sorted_categories = sorted(database().category_names(),
                                   cmp=numeric_string_cmp)
        self.add_items_to_combo_box(sorted_categories, self.grades_combo)
        self.add_pages_to_stacked_widget(sorted_categories, self.grades_stack)
        bg_color = self.background_color()
        scopes = self.page_names_for_stacked_widget(self.grades_stack)
        widgets = self.pages_for_stacked_widget(self.grades_stack)
        self.add_graphs_for_scopes(GradesGraph, scopes, widgets, bg_color)

    def add_easiness_stats(self):
        """
        Add graphs for easiness statistics to the easiness tab.

        """
        sorted_categories = sorted(database().category_names(),
                                   cmp=numeric_string_cmp)
        self.add_items_to_combo_box(sorted_categories, self.easiness_combo)
        self.add_pages_to_stacked_widget(sorted_categories, self.grades_stack)
        bg_color = self.background_color()
        scopes = self.page_names_for_stacked_widget(self.easiness_stack)
        widgets = self.pages_for_stacked_widget(self.easiness_stack)
        self.add_graphs_for_scopes(EasinessGraph, scopes, widgets, bg_color)

    def add_items_to_combo_box(self, items, combo):
        """
        Add each item in list to the specified combo box and stack widget.

        items -- a list of strings that will be used as both the combo box
                 text and the new stack widget page name.
        combo -- the QComboBox to which the items will be added.

        """
        for name in items:
            combo.addItem(QString(name))

    def add_pages_to_stacked_widget(self, names, stack):
        """
        Create and add a list of widgets with specified objectNames to the
        specified stacked widget. Return a list of the created widgets.

        names -- the list of strings to use as objectNames for the widgets
                 that will be added to add to the stack.
        stack -- a QStackedWidget.

        """
        widgets = []
        for name in names:
            widget = QWidget()
            widget.setObjectName(name)
            setattr(self, str(id(widget)) + '_' + name, widget)
            stack.addWidget(widget)
            widgets.append(widget)
        return widgets

    def add_graphs_for_scopes(self, graph_type, scopes, widgets, bg='white'):
        """
        Add a graph of type <graph_type> for each scope.

        graph_type -- the type of graph to add. Must be an actual classname.
        scopes -- a list of keywords on which the graph specializes it's output,
                  e.g. ('daily', 'weekly', 'monthly', 'all_time').
        widgets -- a list of widgets that will be used as parent widgets for
                   the graphs.

        Keyword Arguments:
        bg -- the background color for the graph (default 'white').

        Raises:
        ArgumentError if len(scopes) != len(widgets)
        """
        if len(scopes) != len(widgets):
            raise ArgumentError, "Widgets and scopes lists must be same length."
        for i, name in enumerate(scopes):
            parent = widgets[i]
            layout_name = name + '_layout'
            setattr(self, layout_name, QVBoxLayout(parent))
            layout = getattr(self, layout_name)
            layout.setObjectName(layout_name)
            graph_name = name + '_graph'
            graph = graph_type(parent, scope=name, color=bg)
            graph.setObjectName(graph_name)
            setattr(self, str(id(graph)) + '_' + graph_name, graph)
            layout.addWidget(graph)

    def background_color(self):
        """
        Return this window's background color.

        Sadly, this won't work on OS X, XP, or Vista since they use native
        theme engines for drawing, rather than the palette. See:
        http://doc.trolltech.com/4.4/qapplication.html#setPalette

        """
        if self.style().objectName() == 'macintosh (Aqua)':
            bg_color = '0.91'
        else:
            r, g, b, _ = self.palette().color(self.backgroundRole()).getRgb()
            bg_color = map(lambda x: x / 255.0, (r, g, b))
        return bg_color

    def page_names_for_stacked_widget(self, stack):
        """
        Return a list of page names for the given stacked widget.

        stack -- a QStackWidget

        """
        # TODO: move this function into utils.py
        names = []
        for i in range(0, stack.count()):
            names.append(stack.widget(i).objectName().__str__())
        return names

    def pages_for_stacked_widget(self, stack):
        """
        Return widget objects that make up the pages for the specified stack.

        stack -- a QStackWidget.
        """
        widgets = []
        for i in range(0, stack.count()):
            widgets.append(stack.widget(i))
        return widgets

<|endoftext|>


<commit_before># Copyright (c) 2015 Ultimaker B.V.
# Uranium is released under the terms of the AGPLv3 or higher.

from UM.Qt.ListModel import ListModel
from UM.Application import Application
from UM.Logger import Logger
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry #For getting the possible profile writers to write with.
from UM.Settings.Profile import Profile
from UM.Settings import SettingsError

from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal, pyqtProperty, QUrl

from UM.i18n import i18nCatalog
catalog = i18nCatalog("uranium")

class ProfilesModel(ListModel):
    IdRole = Qt.UserRole + 1
    NameRole = Qt.UserRole + 2
    ActiveRole = Qt.UserRole + 3
    ReadOnlyRole = Qt.UserRole + 4
    ValueRole = Qt.UserRole + 5
    SettingsRole = Qt.UserRole + 6

    def __init__(self, parent = None):
        super().__init__(parent)

        self._add_use_global = False

        self.addRoleName(self.IdRole, "id")
        self.addRoleName(self.NameRole, "name")
        self.addRoleName(self.ActiveRole, "active")
        self.addRoleName(self.ReadOnlyRole, "readOnly")
        self.addRoleName(self.ValueRole, "value")
        self.addRoleName(self.SettingsRole, "settings")

        self._manager = Application.getInstance().getMachineManager()

        self._manager.profilesChanged.connect(self._onProfilesChanged)
        self._manager.activeProfileChanged.connect(self._onActiveProfileChanged)
        self._manager.profileNameChanged.connect(self._onProfileNameChanged)
        self._onProfilesChanged()

    addUseGlobalChanged = pyqtSignal()

    def setAddUseGlobal(self, add):
        if add != self._add_use_global:
            self._add_use_global = add
            self._onProfilesChanged()
            self.addUseGlobalChanged.emit()

    ##  Whether to add a "Use Global Profile" entry.
    @pyqtProperty(bool, fset = setAddUseGlobal, notify = addUseGlobalChanged)
    def addUseGlobal(self):
        return self._add_use_global

    @pyqtSlot(str)
    def removeProfile(self, name):
        profile = self._manager.findProfile(name)
        if not profile:
            return

        self._manager.removeProfile(profile)

    @pyqtSlot(str, str)
    def renameProfile(self, old_name, new_name):
        profile = self._manager.findProfile(old_name)
        if not profile:
            return

        profile.setName(new_name)

    @pyqtSlot(str, result = bool)
    def checkProfileExists(self, name):
        profile = self._manager.findProfile(name)
        if profile:
            return Truegit

        return False

    @pyqtSlot(QUrl, result="QVariantMap")
    def importProfile(self, url):
        path = url.toLocalFile()
        if not path:
            error_str = "Not a valid path. If this problem persists, please report a bug."
            error_str = i18nCatalog.i18nc("@info:status", error_str)
            return {"status":"error", "message":error_str}

        for profile_reader_id, profile_reader in self._manager.getProfileReaders():
            try:
                profile = profile_reader.read(path) #Try to open the file with the profile reader.
            except Exception as e:
                #Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None.
                Logger.log("e", "Failed to import profile from %s: %s", path, str(e))
                return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", path, str(e)) }
            if profile: #Success!
                profile.setReadOnly(False)
                try:
                    self._manager.addProfile(profile) #Add the new profile to the list of profiles.
                except SettingsError.DuplicateProfileError as e:
                    count = 2
                    name = "{0} {1}".format(profile.getName(), count) #Try alternative profile names with a number appended to them.
                    while self._manager.findProfile(name) != None:
                        count += 1
                        name = "{0} {1}".format(profile.getName(), count)
                    profile.setName(name)
                    self._manager.addProfile(profile)
                    return { "status": "duplicate", "message": catalog.i18nc("@info:status", "Profile was imported as {0}", name) }
                else:
                    return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) }

        #If it hasn't returned by now, none of the plugins loaded the profile successfully.
        return { "status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type.", path) }

    @pyqtSlot(str, QUrl, str, result="QVariantMap")
    def exportProfile(self, name, url, fileType):
        #Input checking.
        path = url.toLocalFile()
        if not path:
            error_str = "Not a valid path. If this problem persists, please report a bug."
            error_str = i18nCatalog.i18nc("@info:status", error_str)
            return {"status":"error", "message":error_str}

        profile = self._manager.findProfile(name)
        if not profile:
            error_str = "Profile not found. If this problem persists, please report a bug."
            error_str = i18nCatalog.i18nc("@info:status", error_str)
            return {"status":"error", "message":error_str}

        #Parse the fileType to deduce what plugin can save the file format.
        #TODO: This parsing can be made unnecessary by storing for each plugin what the fileType string is in complete (in addition to the {(description,extension)} dict).
        #fileType has the format "<description> (*.<extension>)"
        split = fileType.rfind(" (*.") #Find where the description ends and the extension starts.
        if split < 0: #Not found. Invalid format.
            Logger.log("e", "Invalid file format identifier %s", fileType)
            error_str = catalog.i18nc("@info:status", "Invalid file format: {0}", fileType)
            return {"status":"error", "message":error_str}
        description = fileType[:split]
        extension = fileType[split + 4:-1] #Leave out the " (*." and ")".
        if not path.endswith("." + extension): #Auto-fill the extension if the user did not provide any.
            path += "." + extension

        good_profile_writer = None
        for profile_writer_id, profile_writer in self._manager.getProfileWriters(): #Find which profile writer can write this file type.
            meta_data = PluginRegistry.getInstance().getMetaData(profile_writer_id)
            if "profile_writer" in meta_data:
                for supported_type in meta_data["profile_writer"]: #All file types this plugin can supposedly write.
                    supported_extension = supported_type.get("extension", None)
                    if supported_extension == extension: #This plugin supports a file type with the same extension.
                        supported_description = supported_type.get("description", None)
                        if supported_description == description: #The description is also identical. Assume it's the same file type.
                            good_profile_writer = profile_writer
                            break
            if good_profile_writer: #If we found a writer in this iteration, break the loop.
                break

        success = False
        try:
            success = good_profile_writer.write(path, profile)
        except Exception as e:
            Logger.log("e", "Failed to export profile to %s: %s", path, str(e))
            error_str = catalog.i18nc("@info:status", "Failed to export profile to <filename>{0}</filename>: <message>{1}</message>", path, str(e))
            return {"status":"error", "message":error_str}
        if not success:
            Logger.log("w", "Failed to export profile to %s: Writer plugin reported failure.", path)
            error_str = catalog.i18nc("@info:status", "Failed to export profile to <filename>{0}</filename>: Writer plugin reported failure.", path)
            return {"status":"error", "message":error_str}
        m = Message(catalog.i18nc("@info:status", "Exported profile to <filename>{0}</filename>", path))
        m.show()

    ##  Gets a list of the possible file filters that the plugins have
    #   registered they can open.
    #
    #   \return A list of strings indicating file name filters for a file
    #   dialog.
    @pyqtSlot(result = "QVariantList")
    def getFileNameFiltersRead(self):
        filters = []
        all_supported = []
        for extension, description in self._manager.getSupportedProfileTypesRead().items(): #Format the file types that can be read correctly for the open file dialog.
            all_supported.append("*." + extension)
            filters.append(description + " (*." + extension + ")")
        filters.insert(0, catalog.i18nc("@item:inlistbox", "All supported files") + "(" + " ".join(all_supported) + ")") #An entry to show all file extensions that are supported.
        filters.append(catalog.i18nc("@item:inlistbox", "All Files (*)")) #Also allow arbitrary files, if the user so prefers.
        return filters

    ##  Gets a list of the possible file filters that the plugins have
    #   registered they can write.
    #
    #   \return A list of strings indicating file name filters for a file
    #   dialog.
    @pyqtSlot(result = "QVariantList")
    def getFileNameFiltersWrite(self):
        filters = []
        for extension, description in self._manager.getSupportedProfileTypesWrite().items(): #Format the file types that can be written correctly for the save file dialog.
            filters.append(description + " (*." + extension + ")")
        filters.append(catalog.i18nc("@item:inlistbox", "All Files (*)")) #Also allow arbitrary files, if the user so prefers.
        return filters

    def _onProfilesChanged(self):
        self.clear()

        if self._add_use_global:
            self.appendItem({
                "id": 1,
                "name": catalog.i18nc("@item:inlistbox", "- Use Global Profile -"),
                "active": False,
                "readOnly": True,
                "value": "global",
                "settings": None
            })

        profiles = self._manager.getProfiles()
        profiles.sort(key = lambda k: k.getName())
        for profile in profiles:
            settings_dict = profile.getChangedSettings()
            settings_list = []
            for key, value in settings_dict.items():
                setting = self._manager.getActiveMachineInstance().getMachineDefinition().getSetting(key)
                settings_list.append({"name": setting.getLabel(), "value": value})
            settings_list = sorted(settings_list, key = lambda setting:setting["name"])
            self.appendItem({
                "id": id(profile),
                "name": profile.getName(),
                "active": self._manager.getActiveProfile() == profile,
                "readOnly": profile.isReadOnly(),
                "value": profile.getName(),
                "settings": settings_list
            })

    def _onActiveProfileChanged(self):
        active_profile = self._manager.getActiveProfile()
        for index in range(len(self.items)):
            self.setProperty(index, "active", id(active_profile) == self.items[index]["id"])

    def _onProfileNameChanged(self, profile):
        index = self.find("id", id(profile))
        if index != -1:
            self.setProperty(index, "name", profile.getName())
<commit_msg>Removed typo.<commit_after># Copyright (c) 2015 Ultimaker B.V.
# Uranium is released under the terms of the AGPLv3 or higher.

from UM.Qt.ListModel import ListModel
from UM.Application import Application
from UM.Logger import Logger
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry #For getting the possible profile writers to write with.
from UM.Settings.Profile import Profile
from UM.Settings import SettingsError

from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal, pyqtProperty, QUrl

from UM.i18n import i18nCatalog
catalog = i18nCatalog("uranium")

class ProfilesModel(ListModel):
    IdRole = Qt.UserRole + 1
    NameRole = Qt.UserRole + 2
    ActiveRole = Qt.UserRole + 3
    ReadOnlyRole = Qt.UserRole + 4
    ValueRole = Qt.UserRole + 5
    SettingsRole = Qt.UserRole + 6

    def __init__(self, parent = None):
        super().__init__(parent)

        self._add_use_global = False

        self.addRoleName(self.IdRole, "id")
        self.addRoleName(self.NameRole, "name")
        self.addRoleName(self.ActiveRole, "active")
        self.addRoleName(self.ReadOnlyRole, "readOnly")
        self.addRoleName(self.ValueRole, "value")
        self.addRoleName(self.SettingsRole, "settings")

        self._manager = Application.getInstance().getMachineManager()

        self._manager.profilesChanged.connect(self._onProfilesChanged)
        self._manager.activeProfileChanged.connect(self._onActiveProfileChanged)
        self._manager.profileNameChanged.connect(self._onProfileNameChanged)
        self._onProfilesChanged()

    addUseGlobalChanged = pyqtSignal()

    def setAddUseGlobal(self, add):
        if add != self._add_use_global:
            self._add_use_global = add
            self._onProfilesChanged()
            self.addUseGlobalChanged.emit()

    ##  Whether to add a "Use Global Profile" entry.
    @pyqtProperty(bool, fset = setAddUseGlobal, notify = addUseGlobalChanged)
    def addUseGlobal(self):
        return self._add_use_global

    @pyqtSlot(str)
    def removeProfile(self, name):
        profile = self._manager.findProfile(name)
        if not profile:
            return

        self._manager.removeProfile(profile)

    @pyqtSlot(str, str)
    def renameProfile(self, old_name, new_name):
        profile = self._manager.findProfile(old_name)
        if not profile:
            return

        profile.setName(new_name)

    @pyqtSlot(str, result = bool)
    def checkProfileExists(self, name):
        profile = self._manager.findProfile(name)
        if profile:
            return True

        return False

    @pyqtSlot(QUrl, result="QVariantMap")
    def importProfile(self, url):
        path = url.toLocalFile()
        if not path:
            error_str = "Not a valid path. If this problem persists, please report a bug."
            error_str = i18nCatalog.i18nc("@info:status", error_str)
            return {"status":"error", "message":error_str}

        for profile_reader_id, profile_reader in self._manager.getProfileReaders():
            try:
                profile = profile_reader.read(path) #Try to open the file with the profile reader.
            except Exception as e:
                #Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None.
                Logger.log("e", "Failed to import profile from %s: %s", path, str(e))
                return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", path, str(e)) }
            if profile: #Success!
                profile.setReadOnly(False)
                try:
                    self._manager.addProfile(profile) #Add the new profile to the list of profiles.
                except SettingsError.DuplicateProfileError as e:
                    count = 2
                    name = "{0} {1}".format(profile.getName(), count) #Try alternative profile names with a number appended to them.
                    while self._manager.findProfile(name) != None:
                        count += 1
                        name = "{0} {1}".format(profile.getName(), count)
                    profile.setName(name)
                    self._manager.addProfile(profile)
                    return { "status": "duplicate", "message": catalog.i18nc("@info:status", "Profile was imported as {0}", name) }
                else:
                    return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) }

        #If it hasn't returned by now, none of the plugins loaded the profile successfully.
        return { "status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type.", path) }

    @pyqtSlot(str, QUrl, str, result="QVariantMap")
    def exportProfile(self, name, url, fileType):
        #Input checking.
        path = url.toLocalFile()
        if not path:
            error_str = "Not a valid path. If this problem persists, please report a bug."
            error_str = i18nCatalog.i18nc("@info:status", error_str)
            return {"status":"error", "message":error_str}

        profile = self._manager.findProfile(name)
        if not profile:
            error_str = "Profile not found. If this problem persists, please report a bug."
            error_str = i18nCatalog.i18nc("@info:status", error_str)
            return {"status":"error", "message":error_str}

        #Parse the fileType to deduce what plugin can save the file format.
        #TODO: This parsing can be made unnecessary by storing for each plugin what the fileType string is in complete (in addition to the {(description,extension)} dict).
        #fileType has the format "<description> (*.<extension>)"
        split = fileType.rfind(" (*.") #Find where the description ends and the extension starts.
        if split < 0: #Not found. Invalid format.
            Logger.log("e", "Invalid file format identifier %s", fileType)
            error_str = catalog.i18nc("@info:status", "Invalid file format: {0}", fileType)
            return {"status":"error", "message":error_str}
        description = fileType[:split]
        extension = fileType[split + 4:-1] #Leave out the " (*." and ")".
        if not path.endswith("." + extension): #Auto-fill the extension if the user did not provide any.
            path += "." + extension

        good_profile_writer = None
        for profile_writer_id, profile_writer in self._manager.getProfileWriters(): #Find which profile writer can write this file type.
            meta_data = PluginRegistry.getInstance().getMetaData(profile_writer_id)
            if "profile_writer" in meta_data:
                for supported_type in meta_data["profile_writer"]: #All file types this plugin can supposedly write.
                    supported_extension = supported_type.get("extension", None)
                    if supported_extension == extension: #This plugin supports a file type with the same extension.
                        supported_description = supported_type.get("description", None)
                        if supported_description == description: #The description is also identical. Assume it's the same file type.
                            good_profile_writer = profile_writer
                            break
            if good_profile_writer: #If we found a writer in this iteration, break the loop.
                break

        success = False
        try:
            success = good_profile_writer.write(path, profile)
        except Exception as e:
            Logger.log("e", "Failed to export profile to %s: %s", path, str(e))
            error_str = catalog.i18nc("@info:status", "Failed to export profile to <filename>{0}</filename>: <message>{1}</message>", path, str(e))
            return {"status":"error", "message":error_str}
        if not success:
            Logger.log("w", "Failed to export profile to %s: Writer plugin reported failure.", path)
            error_str = catalog.i18nc("@info:status", "Failed to export profile to <filename>{0}</filename>: Writer plugin reported failure.", path)
            return {"status":"error", "message":error_str}
        m = Message(catalog.i18nc("@info:status", "Exported profile to <filename>{0}</filename>", path))
        m.show()

    ##  Gets a list of the possible file filters that the plugins have
    #   registered they can open.
    #
    #   \return A list of strings indicating file name filters for a file
    #   dialog.
    @pyqtSlot(result = "QVariantList")
    def getFileNameFiltersRead(self):
        filters = []
        all_supported = []
        for extension, description in self._manager.getSupportedProfileTypesRead().items(): #Format the file types that can be read correctly for the open file dialog.
            all_supported.append("*." + extension)
            filters.append(description + " (*." + extension + ")")
        filters.insert(0, catalog.i18nc("@item:inlistbox", "All supported files") + "(" + " ".join(all_supported) + ")") #An entry to show all file extensions that are supported.
        filters.append(catalog.i18nc("@item:inlistbox", "All Files (*)")) #Also allow arbitrary files, if the user so prefers.
        return filters

    ##  Gets a list of the possible file filters that the plugins have
    #   registered they can write.
    #
    #   \return A list of strings indicating file name filters for a file
    #   dialog.
    @pyqtSlot(result = "QVariantList")
    def getFileNameFiltersWrite(self):
        filters = []
        for extension, description in self._manager.getSupportedProfileTypesWrite().items(): #Format the file types that can be written correctly for the save file dialog.
            filters.append(description + " (*." + extension + ")")
        filters.append(catalog.i18nc("@item:inlistbox", "All Files (*)")) #Also allow arbitrary files, if the user so prefers.
        return filters

    def _onProfilesChanged(self):
        self.clear()

        if self._add_use_global:
            self.appendItem({
                "id": 1,
                "name": catalog.i18nc("@item:inlistbox", "- Use Global Profile -"),
                "active": False,
                "readOnly": True,
                "value": "global",
                "settings": None
            })

        profiles = self._manager.getProfiles()
        profiles.sort(key = lambda k: k.getName())
        for profile in profiles:
            settings_dict = profile.getChangedSettings()
            settings_list = []
            for key, value in settings_dict.items():
                setting = self._manager.getActiveMachineInstance().getMachineDefinition().getSetting(key)
                settings_list.append({"name": setting.getLabel(), "value": value})
            settings_list = sorted(settings_list, key = lambda setting:setting["name"])
            self.appendItem({
                "id": id(profile),
                "name": profile.getName(),
                "active": self._manager.getActiveProfile() == profile,
                "readOnly": profile.isReadOnly(),
                "value": profile.getName(),
                "settings": settings_list
            })

    def _onActiveProfileChanged(self):
        active_profile = self._manager.getActiveProfile()
        for index in range(len(self.items)):
            self.setProperty(index, "active", id(active_profile) == self.items[index]["id"])

    def _onProfileNameChanged(self, profile):
        index = self.find("id", id(profile))
        if index != -1:
            self.setProperty(index, "name", profile.getName())
<|endoftext|>


<commit_before>import tensorflow as tf

gan = tf.Graph()

with gan.as_default():

	z = tf.random_normal([100, 32], mean=-1, stddev=4)
	x = tf.placeholder(tf.float32, shape=[784])
	real = tf.zeros(shape=[], dtype=tf.float32)
	fake = tf.ones(shape=[], dtype=tf.float32)

	W_discriminator_layer1 = tf.get_variable(name='W_1', shape=[784, 800])
	b_discriminator_layer1 = tf.get_variable(name='b_1', shape=[800])
	W_generator_layer1 = tf.get_variable(name='W_2', shape=[32, 784])
	b_generator_layer1 = tf.get_variable(name='b_2', shape=[784])
	W_discriminator_layer2 = tf.get_variable(name='W_3', shape=[784, 800])
	b_discriminator_layer2 = tf.get_variable(name='b_3', shape=[800])

	W_discriminator_real = tf.get_variable(name='W_4', shape=[800, 1])
	b_discriminator_real = tf.get_variable(name='b_4', shape=[1])

	W_discriminator_fake = tf.get_variable(name='W_5', shape=[800, 1])
	b_discriminator_fake = tf.get_variable(name='b_5', shape=[1])

	G_z = tf.nn.relu_layer(z, W_generator_layer1, b_generator_layer1)

	# Discriminator

	D_x = tf.nn.relu_layer(x, W_discriminator_layer1, b_discriminator_layer1)
	D_G_z = tf.nn.relu_layer(G_z, W_discriminator_layer2, b_discriminator_layer2)

	D_x_probability = tf.sigmoid(tf.matmul(D_x, W_discriminator_real)+b_discriminator_real)
	D_G_z_probability = tf.sigmoid(tf.matmul(D_G_z, W_discriminator_fake)+b_discriminator_fake)

	W_2 = tf.get_variable(name='W_2', shape=[800, 800])

<commit_msg>working gan<commit_after>import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

gan = tf.Graph()
batch = 100

with gan.as_default():

	z = tf.random_normal([batch, 32, 1], mean=-1, stddev=4)
	y_inp = tf.placeholder(tf.float32, [batch, 10])
	y = tf.expand_dims(y_inp, axis= -1)
	x_inp = tf.placeholder(tf.float32, shape=[batch, 784])
	x = tf.expand_dims(x_inp, axis= -1)
	fake = tf.ones(shape=[], dtype=tf.float32)

	W_discriminator_layer1 = tf.get_variable(name='W_1', shape=[784, 800])
	b_discriminator_layer1 = tf.get_variable(name='b_1', shape=[800, 1])
	W_generator_layer1 = tf.get_variable(name='W_2', shape=[32, 784])
	b_generator_layer1 = tf.get_variable(name='b_2', shape=[784, 1])
	W_discriminator_layer2 = tf.get_variable(name='W_3', shape=[784, 800])
	b_discriminator_layer2 = tf.get_variable(name='b_3', shape=[800, 1])

	W_softmax = tf.get_variable(name='W_4', shape=[800, 10])
	b_softmax = tf.get_variable(name='b_4', shape=[10, 1])

	# W_discriminator_real = tf.get_variable(name='W_4', shape=[800, 1])
	# b_discriminator_real = tf.get_variable(name='b_4', shape=[1])

	# W_discriminator_fake = tf.get_variable(name='W_5', shape=[800, 1])
	# b_discriminator_fake = tf.get_variable(name='b_5', shape=[1])

	# Generator
	G_z_ind = []
	g_input = tf.unstack(z)

	# G_z = tf.stack(G_z_ind)

	# Discriminator

	d_input = tf.unstack(x)
	D_x_ind = []
	D_G_z_ind = []
	D_loss = []
	G_loss =[]
	G_display_batch = []
	y_loss = []

	for b in range(0, batch):
		G = tf.nn.relu(tf.matmul(W_generator_layer1, g_input[b], transpose_a = True) + b_generator_layer1)
		G_z_ind.append(G)
		D = tf.nn.relu(tf.matmul(W_discriminator_layer1, d_input[b], transpose_a = True) + b_discriminator_layer1)
		D_x_ind.append(D)
		D_G_z_ind.append(tf.nn.relu(tf.matmul(W_discriminator_layer2, G_z_ind[b], transpose_a = True) + b_discriminator_layer2))
		D_x_probability = tf.sigmoid(D_x_ind[b])
		D_G_z_probability = tf.sigmoid(D_G_z_ind[b])
		D_loss.append((-1*tf.reduce_mean(tf.log(D_x_probability))) +  (-1*tf.reduce_mean(tf.log(fake - D_G_z_probability))))
		G_loss.append(tf.reduce_mean(tf.log(D_x_probability)) + tf.reduce_mean(tf.log(fake - D_G_z_probability)))
		G_display = tf.reshape(tf.squeeze(G, axis=-1), [28, 28, 1])
		G_display_batch.append(G_display)
		y_pred = tf.nn.softmax(tf.matmul(W_softmax, D, transpose_a=True) + b_softmax)
		y_loss.append(-tf.reduce_mean(y_pred*tf.log(tf.clip_by_value(y,1e-10,1.0))))

	cross_entropy = tf.reduce_mean(tf.stack(y_loss))

	G_z = tf.stack(G_display_batch)

	J_D = tf.reduce_mean(tf.stack(D_loss))
	J_G = tf.reduce_mean(tf.stack(G_loss))

	opt_D = tf.train.AdamOptimizer()
	opt_G = tf.train.AdamOptimizer()
	opt_cross_entropy = tf.train.AdamOptimizer()
	train_opt_D = opt_D.minimize(J_D)
	train_opt_G = opt_G.minimize(J_G)
	train_opt_classifier = opt_cross_entropy.minimize(cross_entropy)

	# D_x_probability = tf.sigmoid(tf.matmul(D_x, W_discriminator_real)+b_discriminator_real)
	# D_G_z_probability = tf.sigmoid(tf.matmul(D_G_z, W_discriminator_fake)+b_discriminator_fake)

	summary_D = tf.summary.scalar('Discriminator loss', J_D) # , name='discriminator')
	summary_C = tf.summary.scalar('Classifier loss', cross_entropy) # , name='cross entropy')
	summary_G = tf.summary.scalar('Generator loss', J_G) # , name='generator')
	# summary_G_hist = tf.summary.histogram("histogram loss", J_G)
	summary_I = tf.summary.image('img', G_z, 10)
	summary_op = tf.summary.merge_all()

	init = tf.global_variables_initializer()

	saver = tf.train.Saver()

with tf.Session(graph=gan) as sess:

	mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
	sess.run(init)
	train_writer = tf.summary.FileWriter('summary_directory')
	# c_D = []
	# c_G = []
	# c_C = []

	for k in range(1, 50):

		print 'epoch - - - - - - - - >', k

		if k%20 == 0:
			save_path = saver.save(sess, "model_gan")

		batch_xs, batch_ys = mnist.train.next_batch(batch)
		for keep_D_ahead in range(0, 10):
			T_D, T_C, J_D_loss, J_C_loss, summary_full = sess.run([train_opt_D, train_opt_classifier, J_D, cross_entropy, summary_op], feed_dict={x_inp: batch_xs, y_inp: batch_ys})
			print J_C_loss, 'classifier loss'
			print J_D_loss, 'Discriminator loss'
			# c_D.append(sess.run(tf.summary.scalar('Discriminator loss', J_D, name='discriminator'), feed_dict={x_inp: batch_xs, y_inp: batch_ys}))
			# c_C.append(sess.run(tf.summary.scalar('Classifier loss', cross_entropy, name='cross entropy'), feed_dict={x_inp: batch_xs, y_inp: batch_ys}))

		T_G, J_G_loss = sess.run([train_opt_G, J_G], feed_dict={x_inp: batch_xs})
		print J_G_loss, 'Generator loss'
		# c_G.append(sess.run(tf.summary.scalar('Generator loss', J_G, name='generator'), feed_dict={x_inp: batch_xs}))

	# train_writer.add_summary(tf.summary.merge(c_D))
	# train_writer.add_summary(tf.summary.merge(c_G))
	# train_writer.add_summary(tf.summary.merge(c_C))

	# summary_display = sess.run(tf.summary.image('img', G_z, 1))
	train_writer.add_summary(summary_full)

<|endoftext|>


<commit_before>from .phjRROR import phjOddsRatio
from .phjRROR import phjRelativeRisk
from .phjSelectData import phjSelectCaseControlDataset
from .phjGetData import phjReadDataFromExcelNamedCellRange
from .phjGetDBData import phjGetDataFromDatabase
from .phjGetDBData import phjReadTextFromFile
from .phjMatrices import phjBinaryVarsToSquareMatrix
<commit_msg>Update __init__.py<commit_after>from .phjRROR import phjOddsRatio
from .phjRROR import phjRelativeRisk
from .phjSelectData import phjSelectCaseControlDataset
from .phjGetData import phjReadDataFromExcelNamedCellRange
from .phjGetDBData import phjGetDataFromDatabase
from .phjGetDBData import phjReadTextFromFile
from .phjMatrices import phjBinaryVarsToSquareMatrix
from .phjCleanUKPostcodes import phjCleanUKPostcodeVariable
<|endoftext|>


<commit_before>def get():
    with open('/etc/resolv.conf', 'r') as f:
        lines = f.readlines()
    ns = [x for x in lines if x.strip().startswith('nameserver')]
    return map(lambda x: x.split()[1], ns)
<commit_msg>That was really bad idea<commit_after>def get():
    return list(set(pillar['mesos-dns']['configuration'].get('resolvers', [])))
<|endoftext|>


<commit_before>from .phjRROR import phjOddsRatio
from .phjRROR import phjRelativeRisk
from .phjSelectData import phjSelectCaseControlDataset
from .phjGetData import phjReadDataFromExcelNamedCellRange
from .phjGetDBData import phjGetDataFromDatabase
from .phjGetDBData import phjReadTextFromFile
from .phjMatrices import phjBinaryVarsToSquareMatrix
from .phjCleanUKPostcodes import phjCleanUKPostcodeVariable
from .phjCalculateProportions import phjCalculateBinomialProportions
from .phjCalculateProportions import phjCalculateMultinomialProportions
<commit_msg>Update __init__.py<commit_after>from .phjRROR import phjOddsRatio
from .phjRROR import phjRelativeRisk
from .phjSelectData import phjSelectCaseControlDataset
from .phjGetData import phjReadDataFromExcelNamedCellRange
from .phjGetDBData import phjGetDataFromDatabase
from .phjGetDBData import phjReadTextFromFile
from .phjMatrices import phjBinaryVarsToSquareMatrix
from .phjCleanUKPostcodes import phjCleanUKPostcodeVariable
from .phjCalculateProportions import phjCalculateBinomialProportions
from .phjCalculateProportions import phjCalculateMultinomialProportions
from .phjExploreData import phjViewLogOdds
from .phjExtFuncs import getJenksBreaks
<|endoftext|>


<commit_before>#!/usr/bin/python2.4 -tt
# Copyright 2010 Google Inc.
# Licensed under the Apache License, Version 2.0
# http://www.apache.org/licenses/LICENSE-2.0

# Google's Python Class
# http://code.google.com/edu/languages/google-python-class/

# Additional basic string exercises

# D. verbing
# Given a string, if its length is at least 3,
# add 'ing' to its end.
# Unless it already ends in 'ing', in which case
# add 'ly' instead.
# If the string length is less than 3, leave it unchanged.
# Return the resulting string.
def verbing(s):
    if len(s) >= 3:
        if s[-3:] == 'ing':
            ending = 'ly'
        else:
            ending = 'ing'
    else:
        ending = ''

    return s + ending

# E. not_bad
# Given a string, find the first appearance of the
# substring 'not' and 'bad'. If the 'bad' follows
# the 'not', replace the whole 'not'...'bad' substring
# with 'good'.
# Return the resulting string.
# So 'This dinner is not that bad!' yields:
# This dinner is good!
def not_bad(s):
    # http://docs.python.org/library/stdtypes.html#string-methods
    if 'not' in s and 'bad' in s:
        not_index = s.find('not')
        bad_index = s.find('bad')

        if not_index < bad_index:
            good_string_start = s[:not_index]
            good_string_end_index = bad_index + len('bad')
            good_string_end = s[good_string_end_index:]
            good_string = good_string_start + 'good' + good_string_end
        else:
            good_string = s
    else:
        good_string = s

    return good_string

# F. front_back
# Consider dividing a string into two halves.
# If the length is even, the front and back halves are the same length.
# If the length is odd, we'll say that the extra char goes in the front half.
# e.g. 'abcde', the front half is 'abc', the back half 'de'.
# Given 2 strings, a and b, return a string of the form
#  a-front + b-front + a-back + b-back
def front_back(a, b):
    # integer division truncates, so a_back may be shorter than a_front
    a_back_desired_length = len(a) / 2
    a_front = a[:-a_back_desired_length]
    a_back = a[-a_back_desired_length:]

    b_back_desired_length = len(b) / 2
    b_front = b[:-b_back_desired_length]
    b_back = b[-b_back_desired_length:]

    return a_front + b_front + a_back + b_back

# Simple provided test() function used in main() to print
# what each function returns vs. what it's supposed to return.
def test(got, expected):
    if got == expected:
        prefix = ' OK '
    else:
        prefix = '  X '
    print '%s got: %s expected: %s' % (prefix, repr(got), repr(expected))

# main() calls the above functions with interesting inputs,
# using the above test() to check if the result is correct or not.
def main():
    print 'verbing'
    test(verbing('hail'), 'hailing')
    test(verbing('swiming'), 'swimingly')
    test(verbing('do'), 'do')

    print
    print 'not_bad'
    test(not_bad('This movie is not so bad'), 'This movie is good')
    test(not_bad('This dinner is not that bad!'), 'This dinner is good!')
    test(not_bad('This tea is not hot'), 'This tea is not hot')
    test(not_bad("It's bad yet not"), "It's bad yet not")

    print
    print 'front_back'
    test(front_back('abcd', 'xy'), 'abxcdy')
    test(front_back('abcde', 'xyz'), 'abcxydez')
    test(front_back('Kitten', 'Donut'), 'KitDontenut')

if __name__ == '__main__':
    main()
<commit_msg>In string2.py change shebang. Let MacVim spf13 reformat whitespace.<commit_after>#!/usr/bin/python -tt
# Copyright 2010 Google Inc.
# Licensed under the Apache License, Version 2.0
# http://www.apache.org/licenses/LICENSE-2.0

# Google's Python Class
# http://code.google.com/edu/languages/google-python-class/

# Additional basic string exercises

# D. verbing
# Given a string, if its length is at least 3,
# add 'ing' to its end.
# Unless it already ends in 'ing', in which case
# add 'ly' instead.
# If the string length is less than 3, leave it unchanged.
# Return the resulting string.
def verbing(s):
    if len(s) >= 3:
        if s[-3:] == 'ing':
            ending = 'ly'
        else:
            ending = 'ing'
    else:
        ending = ''

    return s + ending

# E. not_bad
# Given a string, find the first appearance of the
# substring 'not' and 'bad'. If the 'bad' follows
# the 'not', replace the whole 'not'...'bad' substring
# with 'good'.
# Return the resulting string.
# So 'This dinner is not that bad!' yields:
# This dinner is good!
def not_bad(s):
    # http://docs.python.org/library/stdtypes.html#string-methods
    if 'not' in s and 'bad' in s:
        not_index = s.find('not')
        bad_index = s.find('bad')

        if not_index < bad_index:
            good_string_start = s[:not_index]
            good_string_end_index = bad_index + len('bad')
            good_string_end = s[good_string_end_index:]
            good_string = good_string_start + 'good' + good_string_end
        else:
            good_string = s
    else:
        good_string = s

    return good_string

# F. front_back
# Consider dividing a string into two halves.
# If the length is even, the front and back halves are the same length.
# If the length is odd, we'll say that the extra char goes in the front half.
# e.g. 'abcde', the front half is 'abc', the back half 'de'.
# Given 2 strings, a and b, return a string of the form
#  a-front + b-front + a-back + b-back
def front_back(a, b):
    # integer division truncates, so a_back may be shorter than a_front
    a_back_desired_length = len(a) / 2
    a_front = a[:-a_back_desired_length]
    a_back = a[-a_back_desired_length:]

    b_back_desired_length = len(b) / 2
    b_front = b[:-b_back_desired_length]
    b_back = b[-b_back_desired_length:]

    return a_front + b_front + a_back + b_back

# Simple provided test() function used in main() to print
# what each function returns vs. what it's supposed to return.
def test(got, expected):
    if got == expected:
        prefix = ' OK '
    else:
        prefix = '  X '
    print '%s got: %s expected: %s' % (prefix, repr(got), repr(expected))

# main() calls the above functions with interesting inputs,
# using the above test() to check if the result is correct or not.
def main():
    print 'verbing'
    test(verbing('hail'), 'hailing')
    test(verbing('swiming'), 'swimingly')
    test(verbing('do'), 'do')

    print
    print 'not_bad'
    test(not_bad('This movie is not so bad'), 'This movie is good')
    test(not_bad('This dinner is not that bad!'), 'This dinner is good!')
    test(not_bad('This tea is not hot'), 'This tea is not hot')
    test(not_bad("It's bad yet not"), "It's bad yet not")

    print
    print 'front_back'
    test(front_back('abcd', 'xy'), 'abxcdy')
    test(front_back('abcde', 'xyz'), 'abcxydez')
    test(front_back('Kitten', 'Donut'), 'KitDontenut')

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before># coding=utf-8
"""
Higher-level commands to package directories on the filesystem.
"""
from __future__ import absolute_import

import logging
import shutil
import tempfile
from contextlib import contextmanager

from pathlib import Path

from eodatasets import package, serialise

_LOG = logging.getLogger(__name__)

def package_newly_processed_data_folder(driver, input_data_paths, destination_path, parent_dataset_paths,
                                        metadata_expand_fn=None,
                                        hard_link=False,
                                        additional_files=None):
    """
    Package an input folder. This is assumed to have just been packaged on the current host.

    (we record host and date information)

    If this is an older dataset, use `package_existing_data_folder` instead.

    The package is created inside the given destination directory, named using
    the ga_label ("dataset id").

    Output is moved into place atomically once fully written.

    Set hard_link=True to hard link instead of copy unmodified files to the output directory (a large speedup)

    :type driver: eodatasets.drivers.DatasetDriver
    :type input_data_paths: list[pathlib.Path]
    :type destination_path: pathlib.Path
    :type metadata_expand_fn: (eodatasets.type.DatasetMetadata) -> None
    :type parent_dataset_paths: list[pathlib.Path]
    :type hard_link: bool

    :param additional_files: Additional files to record in the package.
    :type additional_files: list[Path]
    """
    return _package_folder(
        driver, input_data_paths, destination_path,
        _source_datasets_from_paths(driver, parent_dataset_paths),
        package.init_locally_processed_dataset,
        hard_link=hard_link,
        metadata_expand_fn=metadata_expand_fn,
        additional_files=additional_files
    )

def package_existing_data_folder(driver, input_data_paths, destination_path, parent_dataset_paths,
                                 metadata_expand_fn=None,
                                 additional_files=None,
                                 hard_link=False):
    """
    Package an input folder of possibly unknown origin.

    The package is created inside the given destination directory, named using
    the ga_label ("dataset id").

    Output is moved into place atomically once fully written.

    Set hard_link=True to hard link instead of copy unmodified files to the output directory (a large speedup)

    :type driver: eodatasets.drivers.DatasetDriver
    :type input_data_paths: list[pathlib.Path]
    :type destination_path: pathlib.Path
    :type metadata_expand_fn: (eodatasets.type.DatasetMetadata) -> None
    :type parent_dataset_paths: list[pathlib.Path]

    :param additional_files: Additional files to record in the package.
    :type additional_files: tuple[Path]

    :type hard_link: bool
    :return:
    """
    return _package_folder(
        driver, input_data_paths, destination_path,
        _source_datasets_from_paths(driver, parent_dataset_paths),
        package.init_existing_dataset,
        hard_link=hard_link,
        metadata_expand_fn=metadata_expand_fn,
        additional_files=additional_files
    )

def _source_datasets_from_paths(driver, parent_dataset_paths):
    parent_datasets = {}
    for parent in parent_dataset_paths:
        metadata = serialise.read_dataset_metadata(parent)
        source_id = metadata.product_type
        parent_datasets.update({source_id: metadata})
    return parent_datasets

def _package_folder(driver, input_data_paths, destination_path, source_datasets,
                    init_dataset,
                    metadata_expand_fn=None,
                    hard_link=True,
                    additional_files=None):
    """
    Package a folder into a destination directory as the dataset id. The output is written atomically.

    Output is moved into place atomically once fully written.

    :type driver: eodatasets.drivers.DatasetDriver
    :type input_data_paths: list[pathlib.Path]
    :type destination_path: pathlib.Path
    :type source_datasets: dict[str, eodatasets.type.DatasetMetadata]
    :type metadata_expand_fn: (eodatasets.type.DatasetMetadata) -> None
    :type init_dataset: callable
    :type hard_link: bool

    :param additional_files: Additional files to record in the package.
    :type additional_files: tuple[Path]

    :return: list of (created packages, already existing packages)
    """
    created_packages = []
    existing_packages = []

    for dataset_folder in input_data_paths:
        dataset_folder = Path(dataset_folder)

        with temp_dir(prefix='.packagetmp.', base_dir=destination_path) as temp_output_dir:
            dataset = init_dataset(dataset_folder, source_datasets)
            if metadata_expand_fn is not None:
                metadata_expand_fn(dataset)

            dataset_id = package.package_dataset(  # Also updates dataset
                dataset_driver=driver,
                dataset=dataset,
                image_path=dataset_folder,
                target_path=temp_output_dir,
                hard_link=hard_link,
                additional_files=additional_files
            )

            # Output package permissions should match the parent dir.
            shutil.copymode(str(destination_path), str(temp_output_dir))
            packaged_path = destination_path / dataset_id

            if packaged_path.exists():
                _LOG.warning('Package already exists: %r', packaged_path)
                existing_packages.append(packaged_path)
                shutil.rmtree(temp_output_dir, ignore_errors=True)
            else:
                # Move finished folder into place.
                temp_output_dir.rename(packaged_path)
                created_packages.append(packaged_path)
                _LOG.info('Completed package %r', packaged_path)

    return created_packages, existing_packages

@contextmanager
def temp_dir(prefix="", base_dir=None):
    temp_output_dir = Path(tempfile.mkdtemp(prefix=prefix, dir=str(base_dir)))
    try:
        yield Path(temp_output_dir)
    finally:
        # Clean up if still exists
        with ignored(OSError):
            shutil.rmtree(str(temp_output_dir), ignore_errors=True)

@contextmanager
def ignored(*exceptions):
    try:
        yield
    except exceptions:
        pass
<commit_msg>Fix exception during package cleanup<commit_after># coding=utf-8
"""
Higher-level commands to package directories on the filesystem.
"""
from __future__ import absolute_import

import logging
import shutil
import tempfile
from contextlib import contextmanager

from pathlib import Path

from eodatasets import package, serialise

_LOG = logging.getLogger(__name__)

def package_newly_processed_data_folder(driver, input_data_paths, destination_path, parent_dataset_paths,
                                        metadata_expand_fn=None,
                                        hard_link=False,
                                        additional_files=None):
    """
    Package an input folder. This is assumed to have just been packaged on the current host.

    (we record host and date information)

    If this is an older dataset, use `package_existing_data_folder` instead.

    The package is created inside the given destination directory, named using
    the ga_label ("dataset id").

    Output is moved into place atomically once fully written.

    Set hard_link=True to hard link instead of copy unmodified files to the output directory (a large speedup)

    :type driver: eodatasets.drivers.DatasetDriver
    :type input_data_paths: list[pathlib.Path]
    :type destination_path: pathlib.Path
    :type metadata_expand_fn: (eodatasets.type.DatasetMetadata) -> None
    :type parent_dataset_paths: list[pathlib.Path]
    :type hard_link: bool

    :param additional_files: Additional files to record in the package.
    :type additional_files: list[Path]
    """
    return _package_folder(
        driver, input_data_paths, destination_path,
        _source_datasets_from_paths(driver, parent_dataset_paths),
        package.init_locally_processed_dataset,
        hard_link=hard_link,
        metadata_expand_fn=metadata_expand_fn,
        additional_files=additional_files
    )

def package_existing_data_folder(driver, input_data_paths, destination_path, parent_dataset_paths,
                                 metadata_expand_fn=None,
                                 additional_files=None,
                                 hard_link=False):
    """
    Package an input folder of possibly unknown origin.

    The package is created inside the given destination directory, named using
    the ga_label ("dataset id").

    Output is moved into place atomically once fully written.

    Set hard_link=True to hard link instead of copy unmodified files to the output directory (a large speedup)

    :type driver: eodatasets.drivers.DatasetDriver
    :type input_data_paths: list[pathlib.Path]
    :type destination_path: pathlib.Path
    :type metadata_expand_fn: (eodatasets.type.DatasetMetadata) -> None
    :type parent_dataset_paths: list[pathlib.Path]

    :param additional_files: Additional files to record in the package.
    :type additional_files: tuple[Path]

    :type hard_link: bool
    :return:
    """
    return _package_folder(
        driver, input_data_paths, destination_path,
        _source_datasets_from_paths(driver, parent_dataset_paths),
        package.init_existing_dataset,
        hard_link=hard_link,
        metadata_expand_fn=metadata_expand_fn,
        additional_files=additional_files
    )

def _source_datasets_from_paths(driver, parent_dataset_paths):
    parent_datasets = {}
    for parent in parent_dataset_paths:
        metadata = serialise.read_dataset_metadata(parent)
        source_id = metadata.product_type
        parent_datasets.update({source_id: metadata})
    return parent_datasets

def _package_folder(driver, input_data_paths, destination_path, source_datasets,
                    init_dataset,
                    metadata_expand_fn=None,
                    hard_link=True,
                    additional_files=None):
    """
    Package a folder into a destination directory as the dataset id. The output is written atomically.

    Output is moved into place atomically once fully written.

    :type driver: eodatasets.drivers.DatasetDriver
    :type input_data_paths: list[pathlib.Path]
    :type destination_path: pathlib.Path
    :type source_datasets: dict[str, eodatasets.type.DatasetMetadata]
    :type metadata_expand_fn: (eodatasets.type.DatasetMetadata) -> None
    :type init_dataset: callable
    :type hard_link: bool

    :param additional_files: Additional files to record in the package.
    :type additional_files: tuple[Path]

    :return: list of (created packages, already existing packages)
    """
    created_packages = []
    existing_packages = []

    for dataset_folder in input_data_paths:
        dataset_folder = Path(dataset_folder)

        with temp_dir(prefix='.packagetmp.', base_dir=destination_path) as temp_output_dir:
            dataset = init_dataset(dataset_folder, source_datasets)
            if metadata_expand_fn is not None:
                metadata_expand_fn(dataset)

            dataset_id = package.package_dataset(  # Also updates dataset
                dataset_driver=driver,
                dataset=dataset,
                image_path=dataset_folder,
                target_path=temp_output_dir,
                hard_link=hard_link,
                additional_files=additional_files
            )

            # Output package permissions should match the parent dir.
            shutil.copymode(str(destination_path), str(temp_output_dir))
            packaged_path = destination_path / dataset_id

            if packaged_path.exists():
                _LOG.warning('Package already exists: %r', packaged_path)
                existing_packages.append(packaged_path)
                shutil.rmtree(str(temp_output_dir), ignore_errors=True)
            else:
                # Move finished folder into place.
                temp_output_dir.rename(packaged_path)
                created_packages.append(packaged_path)
                _LOG.info('Completed package %r', packaged_path)

    return created_packages, existing_packages

@contextmanager
def temp_dir(prefix="", base_dir=None):
    temp_output_dir = Path(tempfile.mkdtemp(prefix=prefix, dir=str(base_dir)))
    try:
        yield Path(temp_output_dir)
    finally:
        # Clean up if still exists
        with ignored(OSError):
            shutil.rmtree(str(temp_output_dir), ignore_errors=True)

@contextmanager
def ignored(*exceptions):
    try:
        yield
    except exceptions:
        pass
<|endoftext|>


<commit_before>from __future__ import unicode_literals

from spacy.en import English

import pytest

@pytest.mark.models
def test_vec(EN):
    hype = EN.vocab['hype']
    assert hype.orth_ == 'hype'
    assert 0.08 >= hype.vector[0] > 0.07

@pytest.mark.models
def test_capitalized(EN):
    hype = EN.vocab['Hype']
    assert hype.orth_ == 'Hype'
    assert 0.08 >= hype.vector[0] > 0.07
<commit_msg>Fix test for word vector<commit_after>from __future__ import unicode_literals

from spacy.en import English

import pytest

@pytest.mark.models
def test_vec(EN):
    hype = EN.vocab['hype']
    assert hype.orth_ == 'hype'
    assert -0.7 >= hype.vector[0] > -0.8

@pytest.mark.models
def test_capitalized(EN):
    hype = EN.vocab['Hype']
    assert hype.orth_ == 'Hype'
    assert -0.7 >= hype.vector[0] > -0.8
<|endoftext|>


<commit_before>""":mod:`cliche.people` --- Artists, teams, and editors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

"""
from sqlalchemy.orm import relationship
from sqlalchemy.schema import Column, ForeignKey
from sqlalchemy.sql.functions import now
from sqlalchemy.types import Date, DateTime, Integer

from .orm import Base
from .name import Nameable

__all__ = 'Person', 'Team', 'TeamMembership'

class Person(Nameable):
    """People i.e. artists, editors."""

    #: (:class:`int`) The primary key integer.
    id = Column(Integer, ForeignKey(Nameable.id), primary_key=True)

    #: (:class:`datetime.date`) The date of birth.
    dob = Column(Date)

    #: (:class:`datetime.date`) The date of death.
    dod = Column(Date)

    #: (:class:`datetime.datetime`) The created time.
    created_at = Column(DateTime(timezone=True),
                        nullable=False,
                        default=now(),
                        index=True)

    #: (:class:`collections.abc.MutableSet`) The set of
    #: :class:`TeamMembership`\ s he/she has.
    memberships = relationship('TeamMembership',
                               cascade='delete, merge, save-update',
                               collection_class=set)

    #: (:class:`collections.abc.MutableSet`) The set of :class:`Team`\ s
    #: he/she belongs to.
    teams = relationship('Team',
                         secondary='team_memberships',
                         collection_class=set)

    #: (:class:`collections.abc.MutableSet`) The set of
    #: :class:`cliche.work.Credit`\ s that the person has.
    credits = relationship('Credit',
                           cascade='delete, merge, save-update',
                           collection_class=set)

    __tablename__ = 'people'
    __repr_columns__ = [id]
    __mapper_args__ = {
        'polymorphic_identity': 'people',
    }

class Team(Nameable):
    """Teams (including ad-hoc teams)."""

    #: (:class:`int`) The primary key integer.
    id = Column(Integer, ForeignKey(Nameable.id), primary_key=True)

    #: (:class:`datetime.datetime`) The created time.
    created_at = Column(DateTime(timezone=True),
                        nullable=False,
                        default=now(),
                        index=True)

    #: (:class:`collections.abc.MutableSet`) The set of
    #: :class:`TeamMembership`\ s that the team has.
    memberships = relationship('TeamMembership',
                               cascade='delete, merge, save-update',
                               collection_class=set)

    #: (:class:`collections.abc.MutableSet`) The members :class:`Person` set.
    members = relationship(Person,
                           secondary='team_memberships',
                           collection_class=set)

    #: (:class:`collections.abc.MutableSet`) The set of
    #: :class:`cliche.work.Credit`\ s in which the team was involved.
    credits = relationship('Credit', collection_class=set)

    __tablename__ = 'teams'
    __repr_columns__ = [id]
    __mapper_args__ = {
        'polymorphic_identity': 'teams',
    }

class TeamMembership(Base):
    """Team memberships to people."""

    #: (:class:`int`) :class:`Team.id` of :attr:`team`.
    team_id = Column(Integer, ForeignKey(Team.id), primary_key=True)

    #: (:class:`Team`) The team that the :attr:`member` belongs to.
    team = relationship(Team)

    #: (:class:`int`) :class:`Person.id` of :attr:`member`.
    member_id = Column(Integer, ForeignKey(Person.id), primary_key=True)

    #: (:class:`Person`) The member who is a member of the :attr:`team`.
    member = relationship(Person)

    #: (:class:`datetime.datetime`) The added time.
    created_at = Column(DateTime(timezone=True), nullable=False, default=now())

    __tablename__ = 'team_memberships'
    __repr_columns__ = team_id, member_id
<commit_msg>preserve discriminator<commit_after>""":mod:`cliche.people` --- Artists, teams, and editors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

"""
from sqlalchemy.orm import relationship
from sqlalchemy.schema import Column, ForeignKey
from sqlalchemy.sql.functions import now
from sqlalchemy.types import Date, DateTime, Integer

from .name import Nameable
from .orm import Base
from .sqltypes import prevent_discriminator_from_changing

__all__ = 'Person', 'Team', 'TeamMembership'

class Person(Nameable):
    """People i.e. artists, editors."""

    #: (:class:`int`) The primary key integer.
    id = Column(Integer, ForeignKey(Nameable.id), primary_key=True)

    #: (:class:`datetime.date`) The date of birth.
    dob = Column(Date)

    #: (:class:`datetime.date`) The date of death.
    dod = Column(Date)

    #: (:class:`datetime.datetime`) The created time.
    created_at = Column(DateTime(timezone=True),
                        nullable=False,
                        default=now(),
                        index=True)

    #: (:class:`collections.abc.MutableSet`) The set of
    #: :class:`TeamMembership`\ s he/she has.
    memberships = relationship('TeamMembership',
                               cascade='delete, merge, save-update',
                               collection_class=set)

    #: (:class:`collections.abc.MutableSet`) The set of :class:`Team`\ s
    #: he/she belongs to.
    teams = relationship('Team',
                         secondary='team_memberships',
                         collection_class=set)

    #: (:class:`collections.abc.MutableSet`) The set of
    #: :class:`cliche.work.Credit`\ s that the person has.
    credits = relationship('Credit',
                           cascade='delete, merge, save-update',
                           collection_class=set)

    __tablename__ = 'people'
    __repr_columns__ = [id]
    __mapper_args__ = {
        'polymorphic_identity': 'people',
    }

class Team(Nameable):
    """Teams (including ad-hoc teams)."""

    #: (:class:`int`) The primary key integer.
    id = Column(Integer, ForeignKey(Nameable.id), primary_key=True)

    #: (:class:`datetime.datetime`) The created time.
    created_at = Column(DateTime(timezone=True),
                        nullable=False,
                        default=now(),
                        index=True)

    #: (:class:`collections.abc.MutableSet`) The set of
    #: :class:`TeamMembership`\ s that the team has.
    memberships = relationship('TeamMembership',
                               cascade='delete, merge, save-update',
                               collection_class=set)

    #: (:class:`collections.abc.MutableSet`) The members :class:`Person` set.
    members = relationship(Person,
                           secondary='team_memberships',
                           collection_class=set)

    #: (:class:`collections.abc.MutableSet`) The set of
    #: :class:`cliche.work.Credit`\ s in which the team was involved.
    credits = relationship('Credit', collection_class=set)

    __tablename__ = 'teams'
    __repr_columns__ = [id]
    __mapper_args__ = {
        'polymorphic_identity': 'teams',
    }

class TeamMembership(Base):
    """Team memberships to people."""

    #: (:class:`int`) :class:`Team.id` of :attr:`team`.
    team_id = Column(Integer, ForeignKey(Team.id), primary_key=True)

    #: (:class:`Team`) The team that the :attr:`member` belongs to.
    team = relationship(Team)

    #: (:class:`int`) :class:`Person.id` of :attr:`member`.
    member_id = Column(Integer, ForeignKey(Person.id), primary_key=True)

    #: (:class:`Person`) The member who is a member of the :attr:`team`.
    member = relationship(Person)

    #: (:class:`datetime.datetime`) The added time.
    created_at = Column(DateTime(timezone=True), nullable=False, default=now())

    __tablename__ = 'team_memberships'
    __repr_columns__ = team_id, member_id

prevent_discriminator_from_changing(Person.type)
prevent_discriminator_from_changing(Team.type)
<|endoftext|>


<commit_before>import collections
import copy
import os
import typing

import mitmproxy.options
import mitmproxy.types

from mitmproxy import command
from mitmproxy.tools.console.commander.commander import CommandBuffer

class CommandHistory:
    def __init__(self, size: int = 300) -> None:
        self.saved_commands: typing.Deque[str] = collections.deque(
            maxlen=size
        )
        self.index: int = 0

        self.filter: str = ''
        self.filtered_index: int = 0
        self.filtered_commands: typing.Deque[str] = collections.deque()
        self.filter_active: bool = True

        _command_history_path = os.path.join(os.path.expanduser(mitmproxy.options.CONF_DIR), 'command_history')
        _history_lines = open(_command_history_path, 'r').readlines()

        self.command_history_file = open(_command_history_path, 'w')

        for l in _history_lines:
            self.add_command(l.strip(), True)

    @property
    def last_index(self):
        return len(self.saved_commands) - 1

    @property
    def last_filtered_index(self):
        return len(self.filtered_commands) - 1

    @command.command("command_history.clear")
    def clear_history(self):
        self.saved_commands.clear()
        self.index = 0
        self.command_history_file.truncate(0)
        self.command_history_file.seek(0)
        self.command_history_file.flush()
        self.filter = ''
        self.filtered_index = 0
        self.filtered_commands.clear()
        self.filter_active = True

    @command.command("command_history.next")
    def get_next(self) -> str:
        if self.last_index == -1:
            return ''

        if self.filter != '':
            if self.filtered_index < self.last_filtered_index:
                self.filtered_index = self.filtered_index + 1
            ret = self.filtered_commands[self.filtered_index]
        else:
            if self.index == -1:
                ret = ''
            elif self.index < self.last_index:
                self.index = self.index + 1
                ret = self.saved_commands[self.index]
            else:
                self.index = -1
                ret = ''

        return ret

    @command.command("command_history.prev")
    def get_prev(self) -> str:
        if self.last_index == -1:
            return ''

        if self.filter != '':
            if self.filtered_index > 0:
                self.filtered_index = self.filtered_index - 1
            ret = self.filtered_commands[self.filtered_index]
        else:
            if self.index == -1:
                self.index = self.last_index
            elif self.index > 0:
                self.index = self.index - 1

            ret = self.saved_commands[self.index]

        return ret

    @command.command("command_history.filter")
    def set_filter(self, command: str) -> None:
        """
        This is used when the user starts typing part of a command
        and then press the "up" arrow. This way, the results returned are
        only for the command that the user started typing
        """
        if command.strip() == '':
            return

        if self.filter != '':
            last_filtered_command = self.filtered_commands[-1]
            if command == last_filtered_command:
                self.filter = ''
                self.filtered_commands = []
                self.filtered_index = 0
        else:
            self.filter = command
            _filtered_commands = [c for c in self.saved_commands if c.startswith(command)]
            self.filtered_commands = collections.deque(_filtered_commands)

            if command not in self.filtered_commands:
                self.filtered_commands.append(command)

            self.filtered_index = self.last_filtered_index

        # No commands found, so act like no filter was added
        if len(self.filtered_commands) == 1:
            self.add_command(command)
            self.filter = ''

    @command.command("command_history.cancel")
    def restart(self) -> None:
        self.index = -1
        self.filter = ''
        self.filtered_commands = []
        self.filtered_index = 0

    @command.command("command_history.add")
    def add_command(self, command: str, execution: bool = False) -> None:
        if command.strip() == '':
            return

        if execution:
            if command in self.saved_commands:
                self.saved_commands.remove(command)

            self.saved_commands.append(command)

            _history_str = "\n".join(self.saved_commands)
            self.command_history_file.truncate(0)
            self.command_history_file.seek(0)
            self.command_history_file.write(_history_str)
            self.command_history_file.flush()

            self.restart()
        else:
            if command not in self.saved_commands:
                self.saved_commands.append(command)
<commit_msg>Fix to check if command_history file exists prior to trying to read it<commit_after>import collections
import copy
import os
import typing

import mitmproxy.options
import mitmproxy.types

from mitmproxy import command
from mitmproxy import ctx
from mitmproxy.tools.console.commander.commander import CommandBuffer

class CommandHistory:
    def __init__(self, size: int = 300) -> None:
        self.saved_commands: typing.Deque[str] = collections.deque(
            maxlen=size
        )
        self.index: int = 0

        self.filter: str = ''
        self.filtered_index: int = 0
        self.filtered_commands: typing.Deque[str] = collections.deque()
        self.filter_active: bool = True

        _command_history_path = os.path.join(os.path.expanduser(ctx.options.confdir), 'command_history')
        _history_lines = []
        if os.path.exists(_command_history_path):
            _history_lines = open(_command_history_path, 'r').readlines()

        self.command_history_file = open(_command_history_path, 'w')

        for l in _history_lines:
            self.add_command(l.strip(), True)

    @property
    def last_index(self):
        return len(self.saved_commands) - 1

    @property
    def last_filtered_index(self):
        return len(self.filtered_commands) - 1

    @command.command("command_history.clear")
    def clear_history(self):
        self.saved_commands.clear()
        self.index = 0
        self.command_history_file.truncate(0)
        self.command_history_file.seek(0)
        self.command_history_file.flush()
        self.filter = ''
        self.filtered_index = 0
        self.filtered_commands.clear()
        self.filter_active = True

    @command.command("command_history.next")
    def get_next(self) -> str:
        if self.last_index == -1:
            return ''

        if self.filter != '':
            if self.filtered_index < self.last_filtered_index:
                self.filtered_index = self.filtered_index + 1
            ret = self.filtered_commands[self.filtered_index]
        else:
            if self.index == -1:
                ret = ''
            elif self.index < self.last_index:
                self.index = self.index + 1
                ret = self.saved_commands[self.index]
            else:
                self.index = -1
                ret = ''

        return ret

    @command.command("command_history.prev")
    def get_prev(self) -> str:
        if self.last_index == -1:
            return ''

        if self.filter != '':
            if self.filtered_index > 0:
                self.filtered_index = self.filtered_index - 1
            ret = self.filtered_commands[self.filtered_index]
        else:
            if self.index == -1:
                self.index = self.last_index
            elif self.index > 0:
                self.index = self.index - 1

            ret = self.saved_commands[self.index]

        return ret

    @command.command("command_history.filter")
    def set_filter(self, command: str) -> None:
        """
        This is used when the user starts typing part of a command
        and then press the "up" arrow. This way, the results returned are
        only for the command that the user started typing
        """
        if command.strip() == '':
            return

        if self.filter != '':
            last_filtered_command = self.filtered_commands[-1]
            if command == last_filtered_command:
                self.filter = ''
                self.filtered_commands = []
                self.filtered_index = 0
        else:
            self.filter = command
            _filtered_commands = [c for c in self.saved_commands if c.startswith(command)]
            self.filtered_commands = collections.deque(_filtered_commands)

            if command not in self.filtered_commands:
                self.filtered_commands.append(command)

            self.filtered_index = self.last_filtered_index

        # No commands found, so act like no filter was added
        if len(self.filtered_commands) == 1:
            self.add_command(command)
            self.filter = ''

    @command.command("command_history.cancel")
    def restart(self) -> None:
        self.index = -1
        self.filter = ''
        self.filtered_commands = []
        self.filtered_index = 0

    @command.command("command_history.add")
    def add_command(self, command: str, execution: bool = False) -> None:
        if command.strip() == '':
            return

        if execution:
            if command in self.saved_commands:
                self.saved_commands.remove(command)

            self.saved_commands.append(command)

            _history_str = "\n".join(self.saved_commands)
            self.command_history_file.truncate(0)
            self.command_history_file.seek(0)
            self.command_history_file.write(_history_str)
            self.command_history_file.flush()

            self.restart()
        else:
            if command not in self.saved_commands:
                self.saved_commands.append(command)
<|endoftext|>