# -*- coding: utf-8 -*-
# @Time    : 2019/12/25 11:32
# @Author  : 张茹飞
# @Email   : 1106815482@qq.com
# @File    : teachers.py
# @Software: PyCharm

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication
import sys
import sql_class
data=sql_class.Mysqlpython()
answer_question=[]
account_n=0
# self.dialog=Dialog
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(1266, 850)
        self.dialog=Dialog
        self.gridLayout = QtWidgets.QGridLayout(Dialog)
        self.gridLayout.setObjectName("gridLayout")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem)
        self.textBrowser = QtWidgets.QTextBrowser(Dialog)
        self.textBrowser.setMinimumSize(QtCore.QSize(400, 600))
        self.textBrowser.setMaximumSize(QtCore.QSize(400, 600))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.textBrowser.setFont(font)
        self.textBrowser.setObjectName("textBrowser")
        self.horizontalLayout_3.addWidget(self.textBrowser)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem1)
        self.textEdit = QtWidgets.QTextEdit(Dialog)
        self.textEdit.setMinimumSize(QtCore.QSize(400, 600))
        self.textEdit.setMaximumSize(QtCore.QSize(400, 600))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.textEdit.setFont(font)
        self.textEdit.setObjectName("textEdit")
        self.horizontalLayout_3.addWidget(self.textEdit)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_3.addItem(spacerItem2)
        self.gridLayout.addLayout(self.horizontalLayout_3, 2, 0, 1, 2)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem3)
        self.pushButton_2 = QtWidgets.QPushButton(Dialog)
        self.pushButton_2.setMinimumSize(QtCore.QSize(120, 25))
        self.pushButton_2.setMaximumSize(QtCore.QSize(120, 30))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.pushButton_2.setFont(font)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout.addWidget(self.pushButton_2)
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setMinimumSize(QtCore.QSize(120, 25))
        self.pushButton.setMaximumSize(QtCore.QSize(120, 30))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.pushButton.setFont(font)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        self.pushButton_5 = QtWidgets.QPushButton(Dialog)
        self.pushButton_5.setMinimumSize(QtCore.QSize(120, 25))
        self.pushButton_5.setMaximumSize(QtCore.QSize(120, 30))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.pushButton_5.setFont(font)
        self.pushButton_5.setObjectName("pushButton_5")
        self.horizontalLayout.addWidget(self.pushButton_5)
        self.pushButton_6 = QtWidgets.QPushButton(Dialog)
        self.pushButton_6.setMinimumSize(QtCore.QSize(120, 25))
        self.pushButton_6.setMaximumSize(QtCore.QSize(120, 30))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.pushButton_6.setFont(font)
        self.pushButton_6.setObjectName("pushButton_6")
        self.horizontalLayout.addWidget(self.pushButton_6)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem4)
        self.pushButton_3 = QtWidgets.QPushButton(Dialog)
        self.pushButton_3.setMinimumSize(QtCore.QSize(120, 25))
        self.pushButton_3.setMaximumSize(QtCore.QSize(120, 30))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.pushButton_3.setFont(font)
        self.pushButton_3.setObjectName("pushButton_3")
        self.horizontalLayout.addWidget(self.pushButton_3)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem5)
        self.pushButton_4 = QtWidgets.QPushButton(Dialog)
        self.pushButton_4.setMinimumSize(QtCore.QSize(120, 25))
        self.pushButton_4.setMaximumSize(QtCore.QSize(120, 30))
        font = QtGui.QFont()
        font.setPointSize(18)
        self.pushButton_4.setFont(font)
        self.pushButton_4.setObjectName("pushButton_4")
        self.horizontalLayout.addWidget(self.pushButton_4)
        spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem6)
        self.gridLayout.addLayout(self.horizontalLayout, 4, 0, 1, 2)
        self.label = QtWidgets.QLabel(Dialog)
        font = QtGui.QFont()
        font.setPointSize(24)
        self.label.setFont(font)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 2)
        spacerItem7 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
        self.gridLayout.addItem(spacerItem7, 1, 1, 1, 1)
        spacerItem8 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem8, 3, 0, 1, 1)
        spacerItem9 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.gridLayout.addItem(spacerItem9, 5, 0, 1, 1)

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.pushButton_2.setText(_translate("Dialog", "上一条"))
        self.pushButton.setText(_translate("Dialog", "下一条"))
        self.pushButton_5.setText(_translate("Dialog", "同意"))
        self.pushButton_6.setText(_translate("Dialog", "不同意"))
        self.pushButton_3.setText(_translate("Dialog", "提交答案"))
        self.pushButton_4.setText(_translate("Dialog", "退    出"))
        self.label.setText(_translate("Dialog", "教师答疑"))
        answer_question.clear()
        self.obtin()
        if len(answer_question)!=0:

            if answer_question[0][1] == None:
                self.textBrowser.setText(
                    "第" + str(account_n + 1) + "条，" + "共" + str(len(answer_question)) + "条" + '\n' +
                    "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + "无人作答")
            else:
                self.textBrowser.setText(
                    "第" + str(account_n + 1) + "条，" + "共" + str(len(answer_question)) + "条" + '\n' +
                    "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + answer_question[account_n][1])

        self.pushButton_4.clicked.connect(self.go_main)
        self.pushButton_2.clicked.connect(self.previous)
        self.pushButton.clicked.connect(self.Next)
        self.pushButton_5.clicked.connect(self.agree)
        self.pushButton_6.clicked.connect(self.reject)
        self.pushButton_3.clicked.connect(self.submit)

    #todo 获取所有faq的数据，并显示结果，
    def obtin(self):
        global answer_question
        answer_question.clear()
        sql_account = data.Search("SELECT question,answer FROM faq")
        regedit_information = list(sql_account)
        for i in regedit_information:
            answer_question.append(list(i))
        print(answer_question)
    def previous(self):
        global account_n
        if len(answer_question)!=0:
            if account_n != 0:
                account_n -= 1
                if answer_question[account_n][1]==None:
                    self.textBrowser.setText("第"+str(account_n+1)+"条，"+"共"+str(len(answer_question))+"条"+'\n'+
                        "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + "无人作答")
                else:
                    self.textBrowser.setText("第"+str(account_n+1)+"条，"+"共"+str(len(answer_question))+"条"+'\n'+
                        "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + answer_question[account_n][1])
            else:
                pass
    def Next(self):
        global  account_n
        if len(answer_question) != 0:
            if account_n < len(answer_question)-1:
                account_n += 1
                if answer_question[account_n][1]==None:
                    self.textBrowser.setText("第"+str(account_n+1)+"条，"+"共"+str(len(answer_question))+"条"+'\n'+
                        "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + "无人作答")
                else:
                    self.textBrowser.setText("第"+str(account_n+1)+"条，"+"共"+str(len(answer_question))+"条"+'\n'+
                        "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + answer_question[account_n][1])
            else:
                pass
    def agree(self):

        global account_n
        if len(answer_question) != 0:
            sql = "INSERT INTO questionbank(question,ansswer) VALUES ('%s','%s')" % (answer_question[account_n][0],answer_question[account_n][1] )

            print(sql)
            data.Operation(sql)

            sql = "DELEte FROM faq where question = '%s'" % answer_question[account_n][0]
            print(sql)
            data.Operation(sql)
            # 添加后刷新
            answer_question.clear()
            self.obtin()
            account_n = 0
            if len(answer_question) != 0:
                if answer_question[account_n][1] == None:
                    self.textBrowser.setText(
                        "第" + str(account_n + 1) + "条，" + "共" + str(len(answer_question)) + "条" + '\n' +
                        "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + "无人作答")
                else:
                    self.textBrowser.setText(
                        "第" + str(account_n + 1) + "条，" + "共" + str(len(answer_question)) + "条" + '\n' +
                        "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " +
                        answer_question[account_n][1])
            else:
                self.textBrowser.setText("无消息")
        else:
            self.textBrowser.setText("无消息")
    def reject(self):
        global account_n
        if len(answer_question) != 0:
            sql = "DELEte FROM faq where question = '%s'" % answer_question[account_n][0]
            print(sql)
            data.Operation(sql)
            #删除后刷新
            answer_question.clear()
            self.obtin()
            account_n=0
            if len(answer_question)!=0:
                if answer_question[account_n][1] == None:
                    self.textBrowser.setText("第" + str(account_n + 1) + "条，" + "共" + str(len(answer_question)) + "条" + '\n' +
                                             "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + "无人作答")
                else:
                    self.textBrowser.setText("第" + str(account_n + 1) + "条，" + "共" + str(len(answer_question)) + "条" + '\n' +
                                             "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " +
                                             answer_question[account_n][1])
            else:
                self.textBrowser.setText("无消息")
        else:
            self.textBrowser.setText("无消息")
    def submit(self):
        global account_n

        if answer_question:

                #有答案，覆盖

                if self.textEdit.toPlainText():
                    print("zhunb")
                    sql = "INSERT INTO questionbank(question,ansswer) VALUES ('%s','%s')" % ( answer_question[account_n][0], self.textEdit.toPlainText())
                    data.Operation(sql)
                    sql = "DELEte FROM faq where question = '%s'" % answer_question[account_n][0]
                    data.Operation(sql)
                    # 删除后刷新
                    answer_question.clear()
                    self.obtin()
                    account_n = 0
                    if len(answer_question) != 0:
                        if answer_question[account_n][1] == None:
                            self.textBrowser.setText(
                                "第" + str(account_n + 1) + "条，" + "共" + str(len(answer_question)) + "条" + '\n' +
                                "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " + "无人作答")
                        else:
                            self.textBrowser.setText(
                                "第" + str(account_n + 1) + "条，" + "共" + str(len(answer_question)) + "条" + '\n' +
                                "题目:       " + answer_question[account_n][0] + '\n' + "答案:       " +
                                answer_question[account_n][1])
                    else:
                        self.textBrowser.setText("无消息")
                else:
                    self.textBrowser.setText("无消息")
    def go_main(self):
        self.dialog.close()
if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = QtWidgets.QDialog()
    form.setWindowFlags(
        QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMaximizeButtonHint)
    ui = Ui_Dialog()
    ui.setupUi(form)
    form.show()
    sys.exit(app.exec_())


from collections.abc import Iterable
from contextlib import suppress
import copy
from enum import IntEnum
from functools import partial
import sys
import weakref
from weakref import WeakKeyDictionary, WeakSet

from matplotlib.axes import Axes
from matplotlib.container import Container
from matplotlib.figure import Figure
import numpy as np

from . import _pick_info

_default_bindings = dict(
    select=1,
    deselect=3,
    left="shift+left",
    right="shift+right",
    up="shift+up",
    down="shift+down",
    toggle_enabled="e",
    toggle_visible="v",
)
_default_annotation_kwargs = dict(
    bbox=dict(
        boxstyle="round,pad=.5",
        fc="yellow",
        alpha=.5,
        ec="k",
    ),
    arrowprops=dict(
        arrowstyle="->",
        connectionstyle="arc3",
        shrinkB=0,
        ec="k",
    ),
)
_default_annotation_positions = [
    dict(position=(-15, 15), anncoords="offset points",
         horizontalalignment="right", verticalalignment="bottom"),
    dict(position=(15, 15), anncoords="offset points",
         horizontalalignment="left", verticalalignment="bottom"),
    dict(position=(15, -15), anncoords="offset points",
         horizontalalignment="left", verticalalignment="top"),
    dict(position=(-15, -15), anncoords="offset points",
         horizontalalignment="right", verticalalignment="top"),
]
_default_highlight_kwargs = dict(
    # Only the kwargs corresponding to properties of the artist will be passed.
    # Line2D.
    color="yellow",
    markeredgecolor="yellow",
    linewidth=3,
    markeredgewidth=3,
    # PathCollection.
    facecolor="yellow",
    edgecolor="yellow",
)

class _MarkedStr(str):
    """A string subclass solely for marking purposes."""

def _mouse_event_matches(event, spec):
    """
    Return whether a mouse event "matches" an event spec, which is either a
    single mouse button, or a mapping matched against ``vars(event)``, e.g.
    ``{"button": 1, "key": "control"}``.
    """
    if isinstance(spec, int):
        spec = {"button": spec}
    return all(getattr(event, k) == v for k, v in spec.items())

def _get_rounded_intersection_area(bbox_1, bbox_2):
    """Compute the intersection area between two bboxes rounded to 8 digits."""
    # The rounding allows sorting areas without floating point issues.
    bbox = bbox_1.intersection(bbox_1, bbox_2)
    return round(bbox.width * bbox.height, 8) if bbox else 0

def _iter_axes_subartists(ax):
    r"""Yield all child `Artist`\s (*not* `Container`\s) of *ax*."""
    yield from ax.collections
    yield from ax.images
    yield from ax.lines
    yield from ax.patches
    yield from ax.texts

def _is_alive(artist):
    """Check whether *artist* is still present on its parent axes."""
    return bool(artist
                and artist.axes
                and (artist.container in artist.axes.containers
                     if isinstance(artist, _pick_info.ContainerArtist) else
                     artist in _iter_axes_subartists(artist.axes)))

def _reassigned_axes_event(event, ax):
    """Reassign *event* to *ax*."""
    event = copy.copy(event)
    event.xdata, event.ydata = (
        ax.transData.inverted().transform((event.x, event.y)))
    return event

class HoverMode(IntEnum):
    NoHover, Persistent, Transient = range(3)

class Cursor:
    """
    A cursor for selecting Matplotlib artists.

    Attributes
    ----------
    bindings : dict
        See the *bindings* keyword argument to the constructor.
    annotation_kwargs : dict
        See the *annotation_kwargs* keyword argument to the constructor.
    annotation_positions : dict
        See the *annotation_positions* keyword argument to the constructor.
    highlight_kwargs : dict
        See the *highlight_kwargs* keyword argument to the constructor.
    """

    _keep_alive = WeakKeyDictionary()

    def __init__(self,
                 artists,
                 *,
                 multiple=False,
                 highlight=False,
                 hover=False,
                 bindings=None,
                 annotation_kwargs=None,
                 annotation_positions=None,
                 highlight_kwargs=None):
        """
        Construct a cursor.

        Parameters
        ----------

        artists : List[Artist]
            A list of artists that can be selected by this cursor.

        multiple : bool, default: False
            Whether multiple artists can be "on" at the same time.  If on,
            cursor dragging is disabled (so that one does not end up with many
            cursors on top of one another).

        highlight : bool, default: False
            Whether to also highlight the selected artist.  If so,
            "highlighter" artists will be placed as the first item in the
            :attr:`extras` attribute of the `Selection`.

        hover : `HoverMode`, default: False
            Whether to select artists upon hovering instead of by clicking.
            (Hovering over an artist while a button is pressed will not trigger
            a selection; right clicking on an annotation will still remove it.)
            Possible values are

            - False, alias `HoverMode.NoHover`: hovering is inactive.
            - True, alias `HoverMode.Persistent`: hovering is active;
              annotations remain in place even after the mouse moves away from
              the artist (until another artist is selected, if *multiple* is
              False).
            - 2, alias `HoverMode.Transient`: hovering is active; annotations
              are removed as soon as the mouse moves away from the artist.

        bindings : dict, optional
            A mapping of actions to button and keybindings.  Valid keys are:

            ================ ==================================================
            'select'         mouse button to select an artist
                             (default: :data:`.MouseButton.LEFT`)
            'deselect'       mouse button to deselect an artist
                             (default: :data:`.MouseButton.RIGHT`)
            'left'           move to the previous point in the selected path,
                             or to the left in the selected image
                             (default: shift+left)
            'right'          move to the next point in the selected path, or to
                             the right in the selected image
                             (default: shift+right)
            'up'             move up in the selected image
                             (default: shift+up)
            'down'           move down in the selected image
                             (default: shift+down)
            'toggle_enabled' toggle whether the cursor is active
                             (default: e)
            'toggle_visible' toggle default cursor visibility and apply it to
                             all cursors (default: v)
            ================ ==================================================

            Missing entries will be set to the defaults.  In order to not
            assign any binding to an action, set it to ``None``.  Modifier keys
            (or other event properties) can be set for mouse button bindings by
            passing them as e.g. ``{"button": 1, "key": "control"}``.

        annotation_kwargs : dict, default: {}
            Keyword argments passed to the `annotate
            <matplotlib.axes.Axes.annotate>` call.

        annotation_positions : List[dict], optional
            List of positions tried by the annotation positioning algorithm.
            The default is to try four positions, 15 points to the NW, NE, SE,
            and SW from the selected point; annotations that stay within the
            axes are preferred.

        highlight_kwargs : dict, default: {}
            Keyword arguments used to create a highlighted artist.
        """

        artists = [*artists]
        # Be careful with GC.
        self._artists = [weakref.ref(artist) for artist in artists]

        for artist in artists:
            type(self)._keep_alive.setdefault(artist, set()).add(self)

        self._multiple = multiple
        self._highlight = highlight

        self._visible = True
        self._enabled = True
        self._selections = []
        self._selection_stack = []
        self._last_auto_position = None
        self._callbacks = {"add": [], "remove": []}
        self._hover = hover

        self._suppressed_events = WeakSet()
        connect_pairs = [
            ("pick_event", self._on_pick),
            ("key_press_event", self._on_key_press),
        ]
        if hover:
            connect_pairs += [
                ("motion_notify_event", self._on_hover_motion_notify),
                ("button_press_event", self._on_hover_button_press),
            ]
        else:
            connect_pairs += [
                ("button_press_event", self._on_nonhover_button_press),
            ]
            if not self._multiple:
                connect_pairs.append(
                    ("motion_notify_event", self._on_nonhover_button_press))
        self._disconnectors = [
            partial(canvas.mpl_disconnect, canvas.mpl_connect(*pair))
            for pair in connect_pairs
            for canvas in {artist.figure.canvas for artist in artists}]

        bindings = {**_default_bindings,
                    **(bindings if bindings is not None else {})}
        unknown_bindings = {*bindings} - {*_default_bindings}
        if unknown_bindings:
            raise ValueError("Unknown binding(s): {}".format(
                ", ".join(sorted(unknown_bindings))))
        bindings_items = list(bindings.items())
        for i in range(len(bindings)):
            action, key = bindings_items[i]
            for j in range(i):
                other_action, other_key = bindings_items[j]
                if key == other_key:
                    raise ValueError(
                        f"Duplicate bindings: {key} is used for "
                        f"{other_action} and for {action}")
        self.bindings = bindings

        self.annotation_kwargs = (
            annotation_kwargs if annotation_kwargs is not None
            else copy.deepcopy(_default_annotation_kwargs))
        self.annotation_positions = (
            annotation_positions if annotation_positions is not None
            else copy.deepcopy(_default_annotation_positions))
        self.highlight_kwargs = (
            highlight_kwargs if highlight_kwargs is not None
            else copy.deepcopy(_default_highlight_kwargs))

    @property
    def artists(self):
        """The tuple of selectable artists."""
        # Work around matplotlib/matplotlib#6982: `cla()` does not clear
        # `.axes`.
        return tuple(filter(_is_alive, (ref() for ref in self._artists)))

    @property
    def enabled(self):
        """Whether clicks are registered for picking and unpicking events."""
        return self._enabled

    @enabled.setter
    def enabled(self, value):
        self._enabled = value

    @property
    def selections(self):
        r"""The tuple of current `Selection`\s."""
        for sel in self._selections:
            if sel.annotation.axes is None:
                raise RuntimeError("Annotation unexpectedly removed; "
                                   "use 'cursor.remove_selection' instead")
        return tuple(self._selections)

    @property
    def visible(self):
        """
        Whether selections are visible by default.

        Setting this property also updates the visibility status of current
        selections.
        """
        return self._visible

    @visible.setter
    def visible(self, value):
        self._visible = value
        for sel in self.selections:
            sel.annotation.set_visible(value)
            sel.annotation.figure.canvas.draw_idle()

    def _get_figure(self, aoc):
        """Return the parent figure of artist-or-container *aoc*."""
        if isinstance(aoc, Container):
            try:
                ca, = {artist for artist in (ref() for ref in self._artists)
                       if isinstance(artist, _pick_info.ContainerArtist)
                          and artist.container is aoc}
            except ValueError:
                raise ValueError(f"Cannot find parent figure of {aoc}")
            return ca.figure
        else:
            return aoc.figure

    def _get_axes(self, aoc):
        """Return the parent axes of artist-or-container *aoc*."""
        if isinstance(aoc, Container):
            try:
                ca, = {artist for artist in (ref() for ref in self._artists)
                       if isinstance(artist, _pick_info.ContainerArtist)
                          and artist.container is aoc}
            except ValueError:
                raise ValueError(f"Cannot find parent axes of {aoc}")
            return ca.axes
        else:
            return aoc.axes

    def add_selection(self, pi):
        """
        Create an annotation for a `Selection` and register it.

        Returns a new `Selection`, that has been registered by the `Cursor`,
        with the added annotation set in the :attr:`annotation` field and, if
        applicable, the highlighting artist in the :attr:`extras` field.

        Emits the ``"add"`` event with the new `Selection` as argument.  When
        the event is emitted, the position of the annotation is temporarily
        set to ``(nan, nan)``; if this position is not explicitly set by a
        callback, then a suitable position will be automatically computed.

        Likewise, if the text alignment is not explicitly set but the position
        is, then a suitable alignment will be automatically computed.
        """
        # pi: "pick_info", i.e. an incomplete selection.
        # Pre-fetch the figure and axes, as callbacks may actually unset them.
        figure = self._get_figure(pi.artist)
        axes = self._get_axes(pi.artist)
        get_cached_renderer = (
            figure.canvas.get_renderer
            if hasattr(figure.canvas, "get_renderer")
            else axes.get_renderer_cache)  # matplotlib <3.6.
        renderer = get_cached_renderer()
        if renderer is None:
            figure.canvas.draw()  # Needed below anyways.
            renderer = get_cached_renderer()
        ann = axes.annotate(
            _pick_info.get_ann_text(*pi), xy=pi.target,
            xytext=(np.nan, np.nan),
            horizontalalignment=_MarkedStr("center"),
            verticalalignment=_MarkedStr("center"),
            visible=self.visible,
            zorder=np.inf,
            **self.annotation_kwargs)
        # Move the Annotation's ownership from the Axes to the Figure, so that
        # it gets drawn even above twinned axes.  But ann.axes must stay set,
        # so that e.g. unit converters get correctly applied.
        ann.remove()
        ann.axes = axes
        figure.add_artist(ann)
        ann.draggable(use_blit=not self._multiple)
        extras = []
        if self._highlight:
            hl = self.add_highlight(*pi)
            if hl:
                extras.append(hl)
        sel = pi._replace(annotation=ann, extras=extras)
        self._selections.append(sel)
        self._selection_stack.append(sel)
        for cb in self._callbacks["add"]:
            cb(sel)

        # Check that `ann.axes` is still set, as callbacks may have removed the
        # annotation.
        if ann.axes and ann.xyann == (np.nan, np.nan):
            fig_bbox = figure.get_window_extent()
            ax_bbox = axes.get_window_extent()
            overlaps = []
            for idx, annotation_position in enumerate(
                    self.annotation_positions):
                ann.set(**annotation_position)
                # Work around matplotlib/matplotlib#7614: position update is
                # missing.
                ann.update_positions(renderer)
                bbox = ann.get_window_extent(renderer)
                overlaps.append(
                    (_get_rounded_intersection_area(fig_bbox, bbox),
                     _get_rounded_intersection_area(ax_bbox, bbox),
                     # Avoid needlessly jumping around by breaking ties using
                     # the last used position as default.
                     idx == self._last_auto_position))
            auto_position = max(range(len(overlaps)), key=overlaps.__getitem__)
            ann.set(**self.annotation_positions[auto_position])
            self._last_auto_position = auto_position
        else:
            if isinstance(ann.get_horizontalalignment(), _MarkedStr):
                ann.set_horizontalalignment(
                    {-1: "right", 0: "center", 1: "left"}[
                        np.sign(np.nan_to_num(ann.xyann[0]))])
            if isinstance(ann.get_verticalalignment(), _MarkedStr):
                ann.set_verticalalignment(
                    {-1: "top", 0: "center", 1: "bottom"}[
                        np.sign(np.nan_to_num(ann.xyann[1]))])

        if (extras
                or len(self.selections) > 1 and not self._multiple
                or not figure.canvas.supports_blit):
            # Either:
            #  - there may be more things to draw, or
            #  - annotation removal will make a full redraw necessary, or
            #  - blitting is not (yet) supported.
            figure.canvas.draw_idle()
        elif ann.axes:
            # Fast path, only needed if the annotation has not been immediately
            # removed.
            ann.draw(renderer)
            figure.canvas.blit()
        # Removal comes after addition so that the fast blitting path works.
        if not self._multiple:
            for sel in self.selections[:-1]:
                self.remove_selection(sel)
        return sel

    def add_highlight(self, artist, *args, **kwargs):
        """
        Create, add, and return a highlighting artist.

        This method is should be called with an "unpacked" `Selection`,
        possibly with some fields set to None.

        It is up to the caller to register the artist with the proper
        `Selection` (by calling ``sel.extras.append`` on the result of this
        method) in order to ensure cleanup upon deselection.
        """
        hl = _pick_info.make_highlight(
            artist, *args,
            **{"highlight_kwargs": self.highlight_kwargs, **kwargs})
        if hl:
            artist.axes.add_artist(hl)
            return hl

    def connect(self, event, func=None):
        """
        Connect a callback to a `Cursor` event; return the callback.

        Two events can be connected to:

        - callbacks connected to the ``"add"`` event are called when a
          `Selection` is added, with that selection as only argument;
        - callbacks connected to the ``"remove"`` event are called when a
          `Selection` is removed, with that selection as only argument.

        This method can also be used as a decorator::

            @cursor.connect("add")
            def on_add(sel):
                ...

        Examples of callbacks::

            # Change the annotation text and alignment:
            lambda sel: sel.annotation.set(
                text=sel.artist.get_label(),  # or use e.g. sel.index
                ha="center", va="bottom")

            # Make label non-draggable:
            lambda sel: sel.draggable(False)

        Note that when a single event causes both the removal of an "old"
        selection and the addition of a "new" one (typically, clicking on an
        artist when another one is selected, or hovering -- both assuming that
        ``multiple=False``), the "add" callback is called *first*.  This allows
        it, in particular, to "cancel" the addition (by immediately removing
        the "new" selection) and thus avoid removing the "old" selection.
        However, this call order may change in a future release.
        """
        if event not in self._callbacks:
            raise ValueError(f"{event!r} is not a valid cursor event")
        if func is None:
            return partial(self.connect, event)
        self._callbacks[event].append(func)
        return func

    def disconnect(self, event, cb):
        """
        Disconnect a previously connected callback.

        If a callback is connected multiple times, only one connection is
        removed.
        """
        try:
            self._callbacks[event].remove(cb)
        except KeyError:
            raise ValueError(f"{event!r} is not a valid cursor event")
        except ValueError:
            raise ValueError(f"Callback {cb} is not registered to {event}")

    def remove(self):
        """
        Remove a cursor.

        Remove all `Selection`\\s, disconnect all callbacks, and allow the
        cursor to be garbage collected.
        """
        for disconnectors in self._disconnectors:
            disconnectors()
        for sel in self.selections:
            self.remove_selection(sel)
        for s in type(self)._keep_alive.values():
            with suppress(KeyError):
                s.remove(self)

    def _on_pick(self, event):
        # Avoid creating a new annotation when dragging a preexisting
        # annotation (if multiple = True).  To do so, rely on the fact that
        # pick_events (which are used to implement dragging) trigger first (via
        # Figure's button_press_event, which is registered first); when one of
        # our annotations is picked, registed the corresponding mouse event as
        # "suppressed".  This can be done via a WeakSet as Matplotlib will keep
        # the event alive while being propagated through the callbacks.
        # Additionally, also rely on this mechanism to update the "current"
        # selection.
        for sel in self._selections:
            if event.artist is sel.annotation:
                self._suppressed_events.add(event.mouseevent)
                self._selection_stack.remove(sel)
                self._selection_stack.append(sel)
                break

    def _on_nonhover_button_press(self, event):
        if _mouse_event_matches(event, self.bindings["select"]):
            self._on_select_event(event)
        if _mouse_event_matches(event, self.bindings["deselect"]):
            self._on_deselect_event(event)

    def _on_hover_motion_notify(self, event):
        if event.button is None:
            # Filter away events where the mouse is pressed, in particular to
            # avoid conflicts between hover and draggable.
            self._on_select_event(event)

    def _on_hover_button_press(self, event):
        if _mouse_event_matches(event, self.bindings["deselect"]):
            # Still allow removing the annotation by right clicking.
            self._on_deselect_event(event)

    def _filter_mouse_event(self, event):
        # Accept the event iff we are enabled, and either
        # - no other widget is active, and this is not the second click of a
        #   double click (to prevent double selection), or
        # - another widget is active, and this is a double click (to bypass
        #   the widget lock), or
        # - hovering is active (in which case this is a motion_notify_event
        #   anyways).
        return (self.enabled
                and (event.canvas.widgetlock.locked() == event.dblclick
                     or self._hover))

    def _on_select_event(self, event):
        if (not self._filter_mouse_event(event)
                # See _on_pick.  (We only suppress selects, not deselects.)
                or event in self._suppressed_events):
            return
        # Work around lack of support for twinned axes.
        per_axes_event = {ax: _reassigned_axes_event(event, ax)
                          for ax in {artist.axes for artist in self.artists}}
        pis = []
        for artist in self.artists:
            if (artist.axes is None  # Removed or figure-level artist.
                    or event.canvas is not artist.figure.canvas
                    or not artist.get_visible()
                    or not artist.axes.contains(event)[0]):  # Cropped by axes.
                continue
            pi = _pick_info.compute_pick(artist, per_axes_event[artist.axes])
            if pi:
                pis.append(pi)
        # The any() check avoids picking an already selected artist at the same
        # point, as likely the user is just dragging it.  We check this here
        # rather than not adding the pick_info to pis at all, because in
        # transient hover mode, selections should be cleared out only when no
        # candidate picks (including such duplicates) exist at all.
        pi = min((pi for pi in pis
                  if not any((pi.artist, tuple(pi.target))
                             == (other.artist, tuple(other.target))
                             for other in self._selections)),
                 key=lambda pi: pi.dist, default=None)
        if pi:
            self.add_selection(pi)
        elif not pis and self._hover == HoverMode.Transient:
            for sel in self.selections:
                if event.canvas is sel.annotation.figure.canvas:
                    self.remove_selection(sel)

    def _on_deselect_event(self, event):
        if not self._filter_mouse_event(event):
            return
        for sel in self.selections[::-1]:  # LIFO.
            ann = sel.annotation
            if event.canvas is not ann.figure.canvas:
                continue
            if ann.contains(event)[0]:
                self.remove_selection(sel)
                break
        else:
            if self._highlight:
                for sel in self.selections[::-1]:
                    if any(extra.contains(event)[0] for extra in sel.extras):
                        self.remove_selection(sel)
                        break

    def _on_key_press(self, event):
        if event.key == self.bindings["toggle_enabled"]:
            self.enabled = not self.enabled
        elif event.key == self.bindings["toggle_visible"]:
            self.visible = not self.visible
        if not self._selections or not self.enabled:
            return
        sel = self._selection_stack[-1]
        for key in ["left", "right", "up", "down"]:
            if event.key == self.bindings[key]:
                self.remove_selection(sel)
                self.add_selection(_pick_info.move(*sel, key=key))
                break

    def remove_selection(self, sel):
        """Remove a `Selection`."""
        self._selections.remove(sel)
        self._selection_stack.remove(sel)
        # <artist>.figure will be unset so we save them first.
        figures = {artist.figure for artist in [sel.annotation] + sel.extras}
        # ValueError is raised if the artist has already been removed.
        with suppress(ValueError):
            sel.annotation.remove()
        for artist in sel.extras:
            with suppress(ValueError):
                artist.remove()
        for cb in self._callbacks["remove"]:
            cb(sel)
        for figure in figures:
            figure.canvas.draw_idle()

def cursor(pickables=None, **kwargs):
    """
    Create a `Cursor` for a list of artists, containers, and axes.

    Parameters
    ----------

    pickables : Optional[List[Union[Artist, Container, Axes, Figure]]]
        All artists and containers in the list or on any of the axes or
        figures passed in the list are selectable by the constructed `Cursor`.
        Defaults to all artists and containers on any of the figures that
        :mod:`~matplotlib.pyplot` is tracking.  Note that the latter will only
        work when relying on pyplot, not when figures are directly instantiated
        (e.g., when manually embedding Matplotlib in a GUI toolkit).

    **kwargs
        Keyword arguments are passed to the `Cursor` constructor.
    """

    # Explicit check to avoid a confusing
    # "TypeError: Cursor.__init__() got multiple values for argument 'artists'"
    if "artists" in kwargs:
        raise TypeError(
            "cursor() got an unexpected keyword argument 'artists'")

    if pickables is None:
        # Do not import pyplot ourselves to avoid forcing the backend.
        plt = sys.modules.get("matplotlib.pyplot")
        pickables = [
            plt.figure(num) for num in plt.get_fignums()] if plt else []
    elif (isinstance(pickables, Container)
          or not isinstance(pickables, Iterable)):
        pickables = [pickables]

    def iter_unpack_figures(pickables):
        for entry in pickables:
            if isinstance(entry, Figure):
                yield from entry.axes
            else:
                yield entry

    def iter_unpack_axes(pickables):
        for entry in pickables:
            if isinstance(entry, Axes):
                yield from _iter_axes_subartists(entry)
                containers.extend(entry.containers)
            elif isinstance(entry, Container):
                containers.append(entry)
            else:
                yield entry

    containers = []
    artists = [*iter_unpack_axes(iter_unpack_figures(pickables))]
    for container in containers:
        contained = [*filter(None, container.get_children())]
        for artist in contained:
            with suppress(ValueError):
                artists.remove(artist)
        if contained:
            artists.append(_pick_info.ContainerArtist(container))

    return Cursor(artists, **kwargs)


class Node:     # class for creating node
    def __init__(self, data):
       self.data = data   # Data and Address of next node
       self.next = None

    def get_element(self):      #for getting the elements
            return self.data

    def set_element(self,num):
            self.data=num

class Stack:

    def __init__(self):
        self.head = None

    def push(self, data):       # push/adding elements in stack
        if self.head is None:
            self.head = Node(data)
        else:
            new_node = Node(data)
            new_node.next = self.head
            self.head = new_node

    def search(self):   # for searching the elements in a stack
            n=input("Enter Student :")
            tmp=self.head
            while tmp != None:
                if(n==tmp.get_element()):
                    print("Student Found")
                    break
                tmp=tmp.next
            else:
                    print("Student not found")

    def pop(self):     # for deleting the elements from stack
        if self.head is None:
            return None
        else:
            popped = self.head.data
            self.head = self.head.next
            return popped

    def display(self):  # for display all contents
            tmp=self.head
            while tmp != None:
                print(tmp.get_element())
                tmp=tmp.next

a_stack = Stack()   # creating the object of a class "Stack"
while True:
    print('1. push <value>')        # Menu
    print('2. pop')
    print('3. search')
    print('4. Display')
    print('5. Exit')
    ch = int(input('What would you like to do? '))

    if ch == 1:
        a=input("Enter element :")
        a_stack.push(a)
    elif ch == 2:
        popped = a_stack.pop()
        if popped is None:
            print('Stack is empty.')
        else:
            print('Popped value: ', popped) #display the deleted element
    elif ch == 3:
        a_stack.search()

    elif ch == 4:
        a_stack.display()

    elif ch == 5:   # Exit/ close
        break

'''
OUTPUT :
1. push <value>
2. pop
3. search
4. Display
5. Exit
What would you like to do? 1
Enter element :a
1. push <value>
2. pop
3. search
4. Display
5. Exit
What would you like to do? 1
Enter element :b
1. push <value>
2. pop
3. search
4. Display
5. Exit
What would you like to do? 1
Enter element :c
1. push <value>
2. pop
3. search
4. Display
5. Exit
What would you like to do? 4
c
b
a
1. push <value>
2. pop
3. search
4. Display
5. Exit
What would you like to do? 2
Popped value:  c
1. push <value>
2. pop
3. search
4. Display
5. Exit
What would you like to do? 2
Popped value:  b
1. push <value>
2. pop
3. search
4. Display
5. Exit
What would you like to do? 3
Enter Student :a
Student Found
1. push <value>
2. pop
3. search
4. Display
5. Exit
What would you like to do?
'''


import os
import re
from urlparse import urljoin
from datetime import datetime, date, timedelta
import time
from collections import namedtuple
import math

import requests
from bs4 import BeautifulSoup

BASE_URL = 'http://www.ecb.co.uk/'

HLS_HOST = 'https://secure.brightcove.com/'
HLS_URL_FMT = urljoin(HLS_HOST, 'services/mobile/streaming/index/master.m3u8?videoId={}')

PLAYER_THUMB_URL_FMT = 'https://ecb-resources.s3.amazonaws.com/player-photos/{}/480x480/{}.png'

SEARCH_URL = 'https://content-ecb.pulselive.com/search/ecb/'
VIDEO_LIST_URL = 'https://content-ecb.pulselive.com/content/ecb/EN/'
TOURNAMENTS_URL = 'https://cricketapi-ecb.pulselive.com/tournaments/'

_Video = namedtuple('Video', 'title url thumbnail date duration')
_Entity = namedtuple('Entity', 'name id reference thumbnail')

def _video_query_params(reference, page, page_size=10):
    '''Returns a dictionary of query params for a list of videos'''
    return dict(
        contentTypes='video',
        references=reference if reference is not None else '',
        page=page - 1,
        pageSize=page_size
    )

def _search_query_params(term, page, page_size=10):
    '''Returns a dictionary of query params for the JSON search api'''
    return dict(
        type='VIDEO',
        fullObjectResponse=True,
        terms=term,
        size=page_size,
        start=(page - 1) * page_size
    )

def _tournaments_query_params(team_ids,
                              match_types,
                              weeks_ago,
                              weeks_ahead):
    '''Returns a dictionary of query params for the list of tournaments'''
    query_params = dict(
        teamIds=','.join(map(str, team_ids)),
        startDate=date.today() - timedelta(weeks=weeks_ago),
        endDate=date.today() + timedelta(weeks=weeks_ahead),
        sort='desc')
    if match_types is not None:
        query_params['matchTypes'] = ','.join(
            str(t).replace(' ', '_').upper() for t in match_types
        )
    return query_params

def _soup(path=''):
    '''Returns a BeautifulSoup tree for the specified path'''
    url = urljoin(BASE_URL, path)
    response = requests.get(url)
    return BeautifulSoup(response.text, 'html.parser')

def _date_from_str(date_str, fmt='%d %B %Y'):
    '''Returns a data object from a string.
       datetime.strptime is avoided due to a Python issue in Kodi'''
    return datetime(*(time.strptime(date_str, fmt)[0:6])).date()

def _date_json(json_item):
    '''Returns a date object from the JSON item.
       The date can be one of two formats'''
    date_str = json_item['date']
    for fmt in ['%Y-%m-%dT%H:%M', '%d/%m/%Y %H:%M']:
        try:
            return _date_from_str(date_str.strip(), fmt=fmt)
        except ValueError as exc:
            continue
    raise exc

def _thumbnail_variant(video):
    '''Returns the url for the "Media Thumbnail - Squared Medium" thumbnail'''
    if video['thumbnail'] is None:
        return
    return (variant['url'] for variant in video['thumbnail']['variants']
            if variant['tag']['id'] == 981).next()

def england():
    '''Returns an Entity for the England Men team'''
    return _Entity(
        name='England',
        id=11,
        reference='cricket_team:11',
        thumbnail=None
    )

def counties():
    '''Generator for an Entity for each county team'''
    for county in _soup('/county-championship/teams')('div', 'partners__item'):
        team_id = int(os.path.basename(county.a['href']))
        yield _Entity(
            name=county.a.text,
            id=team_id,
            reference='cricket_team:{}'.format(team_id),
            thumbnail=county.img['src']
        )

def player_categories():
    '''Generator for an Entity representing each form of the game'''
    for tab in _soup('/england/men/players').find_all(
            'div', attrs={'data-ui-args': re.compile(r'{ "title": "\w+" }')}):
        yield _Entity(
            name=tab['data-ui-tab'],
            id=None,
            reference=None,
            thumbnail=None
        )

def players(category='Test'):
    '''Generator for England players currently playing in the provided form of the game'''
    soup = _soup('/england/men/players').find('div', attrs={'data-ui-tab': category})
    for player in soup('section', 'profile-player-card'):
        player_id = player.img['data-player']
        yield _Entity(
            name=player.img['alt'],
            id=player_id,
            reference='cricket_player:{}'.format(player_id),
            thumbnail=PLAYER_THUMB_URL_FMT.format(category.lower(), player_id)
        )

def _tournaments(team_ids,
                 match_types=None,
                 weeks_ago=26,
                 weeks_ahead=4):
    for tournament in requests.get(
            url=TOURNAMENTS_URL,
            params=_tournaments_query_params(team_ids, match_types, weeks_ago, weeks_ahead)
        ).json()['content']:
        yield _Entity(
            name=tournament['description'],
            id=tournament['id'],
            thumbnail=None,
            reference='cricket_tournament:{}'.format(tournament['id'])
        )

def england_tournaments():
    '''Returns a generator for all tournaments played by the England Men'''
    return _tournaments([england().id], ['Test', 'ODI', 'T20I'])

def county_tournaments():
    '''Generator for all tournaments played by a county, excluding tour matches'''
    for tournament in _tournaments([county.id for county in counties()], weeks_ahead=0):
        if not re.search(' in [A-Z]', tournament.name):
            yield tournament

def _video(video):
    return _Video(
        title=video['title'],
        url=HLS_URL_FMT.format(video['mediaId']),
        thumbnail=_thumbnail_variant(video),
        date=_date_json(video),
        duration=video['duration']
    )

def _videos(videos_json):
    '''Generator for all videos from a particular page'''
    for video in videos_json['content']:
        yield _video(video)

def videos(reference=None, page=1, page_size=10):
    '''Returns a generator for videos matching a reference string,
       and the number of pages'''
    videos_json = requests.get(
        url=VIDEO_LIST_URL,
        params=_video_query_params(reference, page, page_size)
    ).json()
    npages = videos_json['pageInfo']['numPages']
    return _videos(videos_json), npages

def _search_results(search_results_json):
    '''Generator for videos matching a search term'''
    results = search_results_json['hits']['hit']
    for result in results:
        video = result['response']
        yield _video(video)

def search_results(term, page=1, page_size=10):
    '''Returns a generator for search results and the number of pages'''
    search_results_json = requests.get(
        url=SEARCH_URL,
        params=_search_query_params(term, page, page_size)
    ).json()
    total = search_results_json['hits']['found']
    npages = int(math.ceil(float(total) / page_size))
    return _search_results(search_results_json), npages


import datetime
import json
import boto3
import os

def lambda_handler(event, context):
    print('## ENVIRONMENT VARIABLES')
    print(os.environ['AWS_LAMBDA_LOG_GROUP_NAME'])
    print(os.environ['AWS_LAMBDA_LOG_STREAM_NAME'])

    DYNAMODB_ENDPOINT_URL = 'http://%s:4566' % os.environ['LOCALSTACK_HOSTNAME']
    print(DYNAMODB_ENDPOINT_URL)
    print('## EVENT')
    print(event)

    dynamodb = boto3.resource('dynamodb', endpoint_url=DYNAMODB_ENDPOINT_URL)
    print(dynamodb)
    #dynamodb = boto3.client('dynamodb', endpoint_url="http://localhost:4566")
    table = dynamodb.Table('GPS_data')
    print(table)

    for record in event['Records']:

        payload=record['body']
        print(payload)
        payload=json.loads(str(payload))

        player_id = payload['player_id']
        print("ciaooooo")
        measure_data = datetime.datetime.strptime(payload['timestamp'], "%Y-%m-%d %H:%M:%S")

        latitude = payload['latitude']
        longitude =payload['longitude']
        print(player_id)
        print(latitude)
        print(longitude)
        print(measure_data)
        game_id=payload['game_id']
        munition=payload['munition']
        item = {
            'player_id': player_id,
            'timestamp': str(measure_data),
            'latitude': latitude,
            'longitude': longitude,
            'game_id':game_id,
            'munition':munition
        }
        table.put_item(Item=item)

        print(item)


#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Developed by Shangchen Zhou <shangchenzhou@gmail.com>

from easydict import EasyDict as edict
import os
import socket

__C     = edict()
cfg     = __C

#
# Common
#
__C.CONST                               = edict()
__C.CONST.DEVICE                        = 'all'                   # '0'
__C.CONST.NUM_WORKER                    = 1                       # number of data workers
__C.CONST.WEIGHTS                       = './ckpt/best-ckpt.pth.tar'
__C.CONST.TRAIN_BATCH_SIZE              = 1
__C.CONST.TEST_BATCH_SIZE               = 1
#
# Dataset
#
__C.DATASET                             = edict()
__C.DATASET.DATASET_NAME                = 'VideoDeblur'       # VideoDeblur, VideoDeblurReal

#
# Directories
#
__C.DIR                                 = edict()
__C.DIR.OUT_PATH = './output'

if cfg.DATASET.DATASET_NAME == 'VideoDeblur':
    __C.DIR.DATASET_JSON_FILE_PATH = './datasets/VideoDeblur.json'
    __C.DIR.DATASET_ROOT = '/data/DeepVideoDeblurringDataset/'
    __C.DIR.IMAGE_BLUR_PATH = os.path.join(__C.DIR.DATASET_ROOT,'%s/%s/input/%s.jpg')
    __C.DIR.IMAGE_CLEAR_PATH = os.path.join(__C.DIR.DATASET_ROOT,'%s/%s/GT/%s.jpg')
# real
elif cfg.DATASET.DATASET_NAME == 'VideoDeblurReal':
    __C.DIR.DATASET_JSON_FILE_PATH = './datasets/VideoDeblurReal.json'
    __C.DIR.DATASET_ROOT = '/data/qualitative_datasets/'
    __C.DIR.IMAGE_BLUR_PATH = os.path.join(__C.DIR.DATASET_ROOT,'%s/%s/input/%s.jpg')
    __C.DIR.IMAGE_CLEAR_PATH = os.path.join(__C.DIR.DATASET_ROOT,'%s/%s/input/%s.jpg')

#
# data augmentation
#
__C.DATA                                = edict()
__C.DATA.STD                            = [255.0, 255.0, 255.0]
__C.DATA.MEAN                           = [0.0, 0.0, 0.0]
__C.DATA.CROP_IMG_SIZE                  = [320, 448]              # Crop image size: height, width
__C.DATA.GAUSSIAN                       = [0, 1e-4]               # mu, std_var
__C.DATA.COLOR_JITTER                   = [0.2, 0.15, 0.3, 0.1]   # brightness, contrast, saturation, hue
__C.DATA.SEQ_LENGTH                     = 20

#
# Network
#
__C.NETWORK                             = edict()
__C.NETWORK.DEBLURNETARCH               = 'DeblurNet'             # available options: DeblurNet
__C.NETWORK.LEAKY_VALUE                 = 0.1
__C.NETWORK.BATCHNORM                   = False
__C.NETWORK.PHASE                       = 'test'                 # available options: 'train', 'test', 'resume'

#
# Training
#

__C.TRAIN                               = edict()
__C.TRAIN.USE_PERCET_LOSS               = True
__C.TRAIN.NUM_EPOCHES                   = 400                    # maximum number of epoches
__C.TRAIN.LEARNING_RATE                 = 1e-4
__C.TRAIN.LR_MILESTONES                 = [80,160,250]
__C.TRAIN.LR_DECAY                      = 0.1                    # Multiplicative factor of learning rate decay
__C.TRAIN.MOMENTUM                      = 0.9
__C.TRAIN.BETA                          = 0.999
__C.TRAIN.BIAS_DECAY                    = 0.0                    # regularization of bias, default: 0
__C.TRAIN.WEIGHT_DECAY                  = 0.0                    # regularization of weight, default: 0
__C.TRAIN.PRINT_FREQ                    = 10
__C.TRAIN.SAVE_FREQ                     = 10                     # weights will be overwritten every save_freq epoch

__C.LOSS                                = edict()
__C.LOSS.MULTISCALE_WEIGHTS             = [0.3, 0.3, 0.2, 0.1, 0.1]

#
# Testing options
#
__C.TEST                                = edict()
__C.TEST.VISUALIZATION_NUM              = 10
__C.TEST.PRINT_FREQ                     = 5
if __C.NETWORK.PHASE == 'test':
    __C.CONST.TEST_BATCH_SIZE           = 1


# Import packages
import os
import cv2
import numpy as np
import tensorflow as tf
import math
import time

# Import utilites
from utils import label_map_util
from utils import visualization_utils as vis_util
import filter_def

f_list = []

def load_models() :
    # load models 시작시간
    code_start = time.time()
    config= tf.compat.v1.ConfigProto()
    config.gpu_options.allow_growth = True
    session= tf.compat.v1.Session(config=config)

    # Name of the directory containing the object detection module we're using
    MODEL_NAME = 'models'
    LABELMAP_NAME = 'labelmap'

    # 결과 출력(cv.imwrite)해서 확인하려면 output 경로 수정
    # output_dir = "test_images_output\\"

    # Grab path to current working directory
    CWD_PATH = os.getcwd()

    model_list = os.listdir(CWD_PATH+"\\"+MODEL_NAME)
    labelmap_list = os.listdir(CWD_PATH+"\\"+LABELMAP_NAME)

    # =========================================================================
    # model 에 따라서 바뀌는 값들 배열
    sess = {}
    detection_graph = {}
    categories = {}
    category_index = {}
    i = 0
    # 모델 불러오는 부분 => 반복 (여러 모델 불러오기)
    for model, labelmap in zip(model_list, labelmap_list):
        # print(str(len(model_list))+"개 중에 "+str(i+1)+"번째 모델 불러오는 중")
        # print(model+", "+labelmap)

        # Path to frozen detection graph .pb file, which contains the model that is used for object detection.
        PATH_TO_CKPT = os.path.join(CWD_PATH, MODEL_NAME, model)
        # print("model_path : "+PATH_TO_CKPT)

        # Path to label map file
        PATH_TO_LABELS = os.path.join(CWD_PATH, LABELMAP_NAME, labelmap)
        # print("label_path : "+PATH_TO_LABELS)

        # Number of classes the object detector can identify
        # max_num_classes 를 지정해주는 값
        # 최대 라벨 개수로 지정해주면 될 것 같음
        # label class 개수보다 작은 값이 들어가면 N/A 라고 나옴
        NUM_CLASSES = 2

        # Load the label map.
        # Label maps map indices to category names
        # Here we use internal utility functions, but anything that returns a
        # dictionary mapping integers to appropriate string labels would be fine
        label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
        categories[i] = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES,
                                                                    use_display_name=True)
        category_index[i] = label_map_util.create_category_index(categories[i])
        # print(category_index[i])

        # Load the Tensorflow model into memory.
        # Tensorflow 모델을 메모리에 로드
        # detection_graph 배열로 만들어서 이름 바꿔주면서 image 넣기
        detection_graph[i] = tf.Graph()
        with detection_graph[i].as_default():
            od_graph_def = tf.compat.v1.GraphDef()
            with tf.io.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
                # print(PATH_TO_CKPT)
                serialized_graph = fid.read()
                od_graph_def.ParseFromString(serialized_graph)
                tf.import_graph_def(od_graph_def, name='')

            sess[i] = tf.Session(graph=detection_graph[i])
        i = i + 1
    # print("모델 불러오는데 걸리는 시간 : "+str(round(time.time() - code_start,5)))
    # ==========================================================================

    return sess, detection_graph, category_index

def detect_fake(face_list, video, number,count, sess, detection_graph, category_index) :
    code_start = time.time()

    # Name of the directory containing the object detection module we're using
    MODEL_NAME = 'models'
    # Grab path to current working directory
    CWD_PATH = os.getcwd()
    model_list = os.listdir(CWD_PATH + "\\" + MODEL_NAME)

    PATH_TO_VIDEO = video
    # Open video file
    f_list = face_list
    # print(str(len(f_list)))
    # print("load_models : " + str(f_list))

    video = cv2.VideoCapture(PATH_TO_VIDEO)
    face_num = 0
    num = number
    c= count
    print("flist : "+str(len(f_list)))
    # f_num =0
    while (video.isOpened()):
        # 몇번째 프레임인지 출력
        # print(face_num)
        # Acquire frame and expand frame dimensions to have shape: [1, None, None, 3]
        # 프레임을 획득하고 모양을 갖도록 프레임 크기를 확장합니다. [1, None, None, 3]
        # i.e. a single-column array, where each item in the column has the pixel RGB value
        # 즉, 열의 각 항목에 픽셀 RGB 값이있는 단일 열 배열
        ret, frame = video.read()
        # f_num += f_list[face_num][0]
        # print(f_num)
        # if f_num == 0:
        #     print('얼굴없다 탈주!')
        #     break
        frame_expanded = np.expand_dims(frame, axis=0)
        if (int(video.get(1)) % num == c ):

            # 모델 개수만큼 반복
            for j in range(len(sess)):
                # print(j)
                if f_list is None : break
                # 얼굴 좌표 찾기
                (left, right, top, bottom) = f_list[face_num]
                # 소수점 올림, 내림 /  ceil 올림, floor 내림
                left = math.floor(left)
                right = math.ceil(right)
                top = math.floor(top)
                bottom = math.ceil(bottom)
                height = bottom - top
                width = right - left
                # print(left, right, top, bottom)

                # left > 0인 경우 얼굴 좌표가 있는 것
                # 얼굴이 있는 경우 모델 통과
                if left != 0 and height>0 and width>0:
                    # (left, right, top, bottom)
                    # print(top - int(round(height / 6)), bottom+int(round(height / 6)))
                    # print(left - int(round(width / 6)), right + int(round(width / 6)))
                    # print(model_list[j])
                    model_name = model_list[j].split('.')[0]
                    # image = frame[int(top - 50):int(bottom + 50), int(left - 50):int(right + 50)]
                    # 각 부위별로 크롭하고
                    # 필터를 거침
                    # image = frame
                    # image = frame[int(top):int(bottom), int(left):int(right)]
                    image = frame[int(top - int(round(height / 6))):int(bottom+int(round(height / 6))),
                             int(left - int(round(width / 6))):int(right + int(round(width / 6)))]
                    if 'face' in model_name :
                        #image = frame[int(top-50):int(bottom+50), int(left-50):int(right+50)]
                        if 'noise' in model_name:
                            f_image = filter_def.face_noise(image)
                        # elif 'black' in model_name :
                        #     image = filter_def.face_black_area_color(image)
                    elif 'eye' in model_name:
                        # image = frame[int(top):int(bottom -int(round(height/2))),
                        #             int(left):int(right)]
                        # if 'brow_2_line' in model_name:
                        #     image = filter_def.eyebrow_doubleline(image)
                        if 'line_1' in model_name:
                            f_image = filter_def.eyebrow_vertical_line(image)
                    elif 'nose' in model_name:
                        # image = frame[int(top + int(round(height / 4))):int(bottom - int(round(height / 4))),
                        #             int(left):int(right)]
                                    # int(left + int(round(width / 4))):int(right - int(round(width / 4)))]
                        if 'noise' in model_name:
                            f_image = filter_def.nose_noise(image)
                        elif 'in_b' in model_name:
                            f_image = filter_def.nose_in_b(image)
                    elif 'mouth' in model_name:
                        # image = frame[int(top + int(round(height / 2))):int(bottom),
                        #             int(left):int(right)]
                        if 'ul' in model_name:
                            f_image = filter_def.mouth_h_b(image)

                    # 크롭, 필터까지 다 거친 이미지 배열
                    image_np_expanded = np.expand_dims(f_image, axis=0)

                    image_tensor = detection_graph[j].get_tensor_by_name('image_tensor:0')
                    # Each box represents a part of the image where a particular object was detected.
                    # 각 상자는 특정 물체가 감지된 이미지의 일부를 나타냅니다.
                    boxes = detection_graph[j].get_tensor_by_name('detection_boxes:0')
                    # Each score represent how level of confidence for each of the objects.
                    # 각 점수는 각 객체에 대한 신뢰 수준을 나타냅니다.
                    # Score is shown on the result image, together with the class label.
                    # 점수는 클래스 라벨과 함께 결과 이미지에 표시됩니다.
                    scores = detection_graph[j].get_tensor_by_name('detection_scores:0')
                    classes = detection_graph[j].get_tensor_by_name('detection_classes:0')
                    num_detections = detection_graph[j].get_tensor_by_name('num_detections:0')

                    # Perform the actual detection by running the model with the image as input
                    # 이미지를 입력으로 하여 모델을 실행하여 실제 감지 수행
                    # 여기서 모델을 거친다
                    # start_time = time.time()
                    (boxes, scores, classes, num_detections) = sess[j].run(
                        [boxes, scores, classes, num_detections],
                        # feed_dict = {image_tensor: frame_expanded})
                        feed_dict={image_tensor:image_np_expanded})

                    # elapsed_time = time.time() - start_time
                    # label_str = ""
                    # Draw the results of the detection (aka 'visualize the results')
                    # 탐지 결과 그리기 (일명 '결과 시각화')
                    label_str = vis_util.visualize_boxes_and_labels_on_image_array(
                        image,
                        np.squeeze(boxes),
                        np.squeeze(classes).astype(np.int32),
                        np.squeeze(scores),
                        category_index[j],
                        use_normalized_coordinates=True,
                        line_thickness=4,
                        min_score_thresh=0.1)
                    # 모델 거친 결과 출력
                    if label_str!= "": print(label_str)
                # print('inference time cost: {}'.format(elapsed_time))
                # else : print('얼굴이 전부 없거나 얼굴이 없음')
                # 박스 확인용 이미지 출력
                # output_dir = './test_videos/'+model_name+'/'
                # if not os.path.exists('./test_videos/'):
                #     os.mkdir('./test_videos/')
                # if not os.path.exists(output_dir):
                #     os.mkdir(output_dir)
                # # print(output_dir+model_name+"_"+str(face_num)+'.jpg')
                # cv2.imwrite(output_dir+model_name+"_"+str(face_num)+'.jpg', image)
                # else : print('얼굴 없음')
            # 300 프레임, 프레임 개수 만큼만 반복
            # if(face_num != 299) :
            face_num += 1
            if face_num >= len(face_list) : break

            # All the results have been drawn on the frame,
            # so it's time to display it.
            # 프레임에 그림을 그리고 이미지로 보여줌
            cv2.imshow('Object detector', frame)
            cv2.imwrite('./test_videos/frame/' + str(face_num) + '.jpg', frame)

            # Press 'q' to quit
            if cv2.waitKey(1) == ord('q'):
                break

    # Clean up
    video.release()
    cv2.destroyAllWindows()
    load_model_time = time.time() - code_start
    # print()

    return load_model_time


'''
Created on 30 ÎœÎ±Ï� 2017

@author: Sugar
'''

import json
import jsonpickle
from JSONoutputObjectDefinitions import *

def __assignDefaultInputs__(outObject):
    #outObject.platform="xgene2"
    outObject.board="UCY"
    outObject.chip="normal"
    outObject.total_dram_size=8

    dim_id1=dim_id()
    dim_id1.manufacturer="crucial"
    dim_id1.size=8
    dim_id1.model="CT102472BA1886D"
    dim_id1.part_number=""
    dim_ids=[]
    dim_ids.append(dim_id1)

    outObject.dim_ids=dim_ids

def generateDefaultInputs(out_file_name): #function for writting down an expOut object with some default inputs.. The output file can be automatically unboxed into a expOut object with importDefaultInputs funtion

    out_file=open(out_file_name,'w')

    outObject= expOut()
    __assignDefaultInputs__(outObject)
    frozen=jsonpickle.encode(outObject)

    out_file.write(frozen)

#def generateInputFile(out_file_name): #function for generating an expOut object that at the same time will bb used for input to the characterization framework.. The output file can be automatically unboxed into a expOut object with importInput funtion

#    out_file=open(out_file_name,'w')

#    outObject= expOut()
#    __assignDefaultInputs__(outObject)
#    outObject.w
#    frozen=jsonpickle.encode(outObject)

#    out_file.write(frozen)

def importInput(input_file):
    with open(input_file) as default_inputs:
        json_string=default_inputs.read().replace('\n',' ')
        #out=json.load(default_inputs)
    out=jsonpickle.decode(json_string)
    return out
    #for dim_id in out.dim_ids:
    #   print(dim_id.model)
    #print(out.dim_ids[0],)

def returnJsonAsString(json_obj):
    return(jsonpickle.encode(json_obj,unpicklable=False))

def __testJsonOutput__():
    with open("files/test") as f:
        lines = f.read().splitlines()

    jsonArray=[]
    print("[")
    for line in lines:
        #print("original line is " +line)
        newObject= expOut()
        newObject.board="UCY"
        newObject.chip="normal"
        cores=str(line).split(" ")[1]
        frequency=str(line).split(" ")[2]
        for core in str(cores).split(","):
            newObject.core_to_freq.append(int(frequency))
        newObject.core_vol=int(str(line).split(" ")[5])
        newObject.os_version="4.3.0-3.06.21+uniserver.161005.aarch64"
        newObject.soc_freq=2400
        newObject.soc_vol=980
        newObject.system_crash=True
        benchmark=str(str(line).split(" ")[7])#.split[1]
        workload_ins=workload()
        workload_ins.name=benchmark
        workload_ins.cores=cores.replace(","," ")
        workload_ins.inputs="native"
        newObject.workloads.append(workload_ins)
        frozen=jsonpickle.encode(newObject)
        print(frozen+",")
        #jsonArray.append(frozen)
    print("]")
    #frozen=jsonpickle.encode(jsonArray,unpicklable=False)
    #print(frozen)

#generateDefaultInputs("C:/Users/zhadji01/workspace/CharacterizationFramework/inputs/xg2_normal_1dim.json");
#importInput("C:/Users/zhadji01/workspace/CharacterizationFramework/inputs/xg2_normal_1dim.json")


import pygame
from webbrowser import open
from .logic_game import LogicGame
from .constants import *
from .search_algorithm import ASTS

class Puzzle:
    def __init__(self):
        pygame.init()  # initializing pygame

        self.__puzzle = LogicGame(N)  # 3x3 is the default

        # Screen is initialized with init_game method
        self.screen = None

        # Create a Font object
        self.font = pygame.font.SysFont('Arial', size=font_size, bold=True)

        # Create an object to help update the grid
        self.clock = pygame.time.Clock()

        # Loading images used in the game
        self.background = pygame.transform.scale(pygame.image.load('puzzle/media/background.jpg'), size)

        self.grid = [pygame.transform.scale(pygame.image.load(f'puzzle/media/number_0{i}.png'), (side, side))
                     for i in range(1, 9)]
        self.rects = [(spacing_grid + side * j, top_spacing + side * i)
                      for i in range(self.puzzle.n)
                      for j in range(self.puzzle.n)]

        self.button_play = pygame.transform.scale(pygame.image.load('puzzle/media/play.png'),
                                                  (width - 2*side_spacing, height_button))
        self.button_play_rect = self.button_play.get_rect(topleft=(side_spacing, bottom_spacing))

        self.button_info = pygame.transform.scale(pygame.image.load('puzzle/media/info.png'),
                                                  (width_button, height_button))
        self.button_info_rect = self.button_info.get_rect(topright=(width - spacing_grid, spacing))

        self.button_return = pygame.transform.scale(pygame.image.load('puzzle/media/play_left.png'),
                                                    (font_size * 3 / 2, font_size * 3 / 2))
        self.button_return_rect = self.button_return.get_rect(topleft=(spacing_grid, spacing))

        self.button_solve = pygame.transform.scale(pygame.image.load('puzzle/media/forward.png'),
                                                   (font_size * 3 / 2, font_size * 3 / 2))
        self.button_solve_rect = self.button_solve.get_rect(topright=(width - spacing_grid, spacing))

        self.button_refresh = pygame.transform.scale(pygame.image.load('puzzle/media/refresh.png'),
                                                     (side * self.puzzle.n, side * self.puzzle.n))
        self.button_refresh.set_alpha(180)
        self.button_refresh_rect = self.button_refresh.get_rect(topleft=(self.rects[0]))

        self.button_time = pygame.transform.scale(pygame.image.load('puzzle/media/empty.png'),
                                                  (font_size * 4, font_size * 3 / 2))
        self.button_time_rect = self.button_time.get_rect(topleft=(spacing_grid + spacing,
                                                                   self.rects[-1][1] + side + 3 * spacing))

        self.button_moves = pygame.transform.scale(pygame.image.load('puzzle/media/empty.png'),
                                                   (font_size * 4, font_size * 3 / 2))
        self.button_moves_rect = self.button_moves.get_rect(topright=(width - (spacing_grid + spacing),
                                                                      self.rects[-1][1] + side + 3 * spacing))

    def init_game(self):  # method that start the game
        # Creating a display Surface
        self.screen = pygame.display.set_mode(size)
        pygame.display.set_caption("Puzzle Game")

        while True:
            self.main_screen()
            self.play()

    def main_screen(self):
        # Preparing the main screen
        self.screen.blit(self.background, (0, 0))

        self.screen.blit(self.button_play, self.button_play_rect)
        self.screen.blit(self.button_info, self.button_info_rect)

        self.display_puzzle()

        pygame.display.flip()  # displaying the screen

        while True:
            # Getting input from user
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    exit(0)  # leaving the game

                if event.type == pygame.MOUSEBUTTONDOWN:
                    if self.button_play_rect.collidepoint(event.pos):
                        return
                    if self.button_info_rect.collidepoint(event.pos):
                        open('https://github.com/filipemedeiross', new=2)

            # Performing the presentation animation
            coord_0 = self.puzzle.is_empty
            self.puzzle.random_move()
            coord_1 = self.puzzle.is_empty

            if coord_0 != coord_1:
                self.update_puzzle(coord_0, coord_1)

            # Updating clock and grid display
            self.clock.tick(2)

            pygame.display.update(self.rects[0], (side*self.puzzle.n, side*self.puzzle.n))

    def play(self):
        time = moves = 0  # auxiliary variables

        # Displaying fixed screen elements
        self.screen.blit(self.background, (0, 0))  # overriding home screen buttons

        self.screen.blit(self.button_return, self.button_return_rect)

        self.screen.blit(self.button_solve, self.button_solve_rect)

        self.screen.blit(self.button_moves, self.button_moves_rect)

        moves_text = self.font.render(f'{moves}', True, COLOR_FONT)
        self.screen.blit(moves_text, (self.button_moves_rect.centerx - (moves_text.get_width() / 2),
                                      self.button_moves_rect.centery - (moves_text.get_height() / 2)))

        self.display_puzzle()

        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    exit(0)

                if event.type == pygame.MOUSEBUTTONDOWN:
                    if self.button_return_rect.collidepoint(event.pos):
                        self.puzzle.update()  # update the grid
                        return

                if self.puzzle.won:
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        if self.button_refresh_rect.collidepoint(event.pos):
                            time = moves = 0  # auxiliary variables

                            moves_text = self.font.render(f'{moves}', True, COLOR_FONT)
                            self.screen.blit(self.button_moves, self.button_moves_rect)
                            self.screen.blit(moves_text, (self.button_moves_rect.centerx - (moves_text.get_width() / 2),
                                                          self.button_moves_rect.centery - (moves_text.get_height() / 2)))

                            self.clock.tick()  # update the clock

                            self.puzzle.update()  # update the grid
                            self.display_puzzle()

                    continue

                if event.type == pygame.KEYDOWN:
                    coord_0 = self.puzzle.is_empty

                    if event.key == pygame.K_UP:
                        self.puzzle.move('u')
                    if event.key == pygame.K_DOWN:
                        self.puzzle.move('d')
                    if event.key == pygame.K_RIGHT:
                        self.puzzle.move('r')
                    if event.key == pygame.K_LEFT:
                        self.puzzle.move('l')

                    coord_1 = self.puzzle.is_empty

                    if coord_0 != coord_1:
                        self.update_puzzle(coord_0, coord_1)

                        moves += 1

                        self.screen.blit(self.button_moves, self.button_moves_rect)

                        moves_text = self.font.render(f'{moves}', True, COLOR_FONT)
                        self.screen.blit(moves_text, (self.button_moves_rect.centerx - (moves_text.get_width() / 2),
                                                      self.button_moves_rect.centery - (moves_text.get_height() / 2)))

                        if self.puzzle.won:
                            self.screen.blit(self.button_refresh, self.button_refresh_rect)

                if event.type == pygame.MOUSEBUTTONDOWN:
                    if self.button_solve_rect.collidepoint(event.pos):
                        solution = ASTS(self.puzzle.grid)
                        solution.search()

                        for action in solution.actions:
                            coord_0 = self.puzzle.is_empty

                            self.puzzle.move(action)

                            coord_1 = self.puzzle.is_empty

                            self.update_puzzle(coord_0, coord_1)

                            time += self.clock.tick(2)

                            pygame.display.update(self.rects[0], (side * self.puzzle.n, side * self.puzzle.n))

                        self.screen.blit(self.button_refresh, self.button_refresh_rect)

            if not self.puzzle.won:
                # Game time
                time += self.clock.tick(10)

                self.screen.blit(self.button_time, self.button_time_rect)

                time_text = self.font.render(f'{time // 1000 // 60}:{time // 1000 % 60}', True, COLOR_FONT)
                self.screen.blit(time_text, (self.button_time_rect.centerx - (time_text.get_width() / 2),
                                             self.button_time_rect.centery - (time_text.get_height() / 2)))

            pygame.display.flip()

    def display_puzzle(self):
        self.screen.blit(self.background, self.rects[0],
                         area=(self.rects[0], (side * self.puzzle.n, side * self.puzzle.n)))

        # Displaying fixed screen elements
        for num, pos in zip(self.puzzle.grid.flatten(), self.rects):
            if num:
                self.screen.blit(self.grid[num - 1], pos)

    def update_puzzle(self, coord_0, coord_1):
        index_0 = coord_0[0]*N + coord_0[1]
        index_1 = coord_1[0]*N + coord_1[1]

        # Drawing the moved element
        self.screen.blit(self.grid[self.puzzle[coord_0] - 1], self.rects[index_0])

        # Cleaning up the white space
        self.screen.blit(self.background, self.rects[index_1],
                         area=(self.rects[index_1], (side, side)))

    @property
    def puzzle(self):
        return self.__puzzle

if __name__ == '__main__':
    puzzle = Puzzle()

    puzzle.init_game()


import PIL
from PIL import Image
import os
import sqlite3

def drawmap(db, dst_dir):
    org_dir = os.getcwd()
    pic_dir = org_dir + '/pic/'
    mapimg = Image.open(pic_dir + 'map.png')
    #Uk victory
    uksupplyimg = Image.open(pic_dir + 'uk_supply.png')
    if db.execute("select location from card where cardid = 225;").fetchall()[0][0] == "played":
        mapimg.paste(uksupplyimg, (174-14, 130-15), uksupplyimg)
    if db.execute("select location from card where cardid = 226;").fetchall()[0][0] == "played":
        mapimg.paste(uksupplyimg, (649-14, 185-15), uksupplyimg)
    #Fr home/victory
    frhomeimg = Image.open(pic_dir + 'fr_home.png')
    if (db.execute("select location from card where cardid = 222;").fetchall()[0][0] == "played") and (db.execute("select control from space where spaceid = 12;").fetchall()[0][0] == "Axis"):
        mapimg.paste(frhomeimg, (470-14, 172-15), frhomeimg)
    else:
        mapimg.paste(frhomeimg, (503-14, 264-15), frhomeimg)

    if db.execute("select location from card where cardid = 228;").fetchall()[0][0] == "played":
        frsupplyimg = Image.open(pic_dir + 'fr_supply.png')
        mapimg.paste(frsupplyimg, (576-14, 491-15), frsupplyimg)
    #Su home
    if db.execute("select location from card where cardid = 277;").fetchall()[0][0] == "played":
        suhomeimg = Image.open(pic_dir + 'su_home.png')
        sunohomeimg = Image.open(pic_dir + 'su_nohome.png')
        mapimg.paste(suhomeimg, (1002-14, 82-15), suhomeimg)
        mapimg.paste(sunohomeimg, (803-14, 170-15), sunohomeimg)
    #Ch home
    chhomeimg = Image.open(pic_dir + 'ch_home.png')
    if db.execute("select location from card where cardid = 345;").fetchall()[0][0] == "played":
        mapimg.paste(chhomeimg, (1009-14, 311-15), chhomeimg)
    else:
        mapimg.paste(chhomeimg, (1127-14, 316-15), chhomeimg)

    '''if db.execute("select location from card where cardid = 209;").fetchall()[0][0] == "played":
        usvictoryimg = Image.open('us_victory.png')
        usvictoryimg = usvictoryimg.resize((45, 39), Image.ANTIALIAS)
        mapimg.paste(usvictoryimg, (977, 290), usvictoryimg)'''
    geaimg = Image.open(pic_dir + 'ge_army.png')
    jpaimg = Image.open(pic_dir + 'jp_army.png')
    itaimg = Image.open(pic_dir + 'it_army.png')
    ukaimg = Image.open(pic_dir + 'uk_army.png')
    suaimg = Image.open(pic_dir + 'su_army.png')
    usaimg = Image.open(pic_dir + 'us_army.png')
    fraimg = Image.open(pic_dir + 'fr_army.png')
    chaimg = Image.open(pic_dir + 'ch_army.png')
    ukaimg = ukaimg.transpose(Image.FLIP_LEFT_RIGHT)
    suaimg = suaimg.transpose(Image.FLIP_LEFT_RIGHT)
    usaimg = usaimg.transpose(Image.FLIP_LEFT_RIGHT)
    fraimg = fraimg.transpose(Image.FLIP_LEFT_RIGHT)
    chaimg = chaimg.transpose(Image.FLIP_LEFT_RIGHT)
    genimg = Image.open(pic_dir + 'ge_navy.png')
    jpnimg = Image.open(pic_dir + 'jp_navy.png')
    itnimg = Image.open(pic_dir + 'it_navy.png')
    uknimg = Image.open(pic_dir + 'uk_navy.png')
    sunimg = Image.open(pic_dir + 'su_navy.png')
    usnimg = Image.open(pic_dir + 'us_navy.png')
    frnimg = Image.open(pic_dir + 'fr_navy.png')
    uknimg = uknimg.transpose(Image.FLIP_LEFT_RIGHT)
    sunimg = sunimg.transpose(Image.FLIP_LEFT_RIGHT)
    usnimg = usnimg.transpose(Image.FLIP_LEFT_RIGHT)
    frnimg = frnimg.transpose(Image.FLIP_LEFT_RIGHT)
    gefimg = Image.open(pic_dir + 'ge_air.png')
    jpfimg = Image.open(pic_dir + 'jp_air.png')
    itfimg = Image.open(pic_dir + 'it_air.png')
    ukfimg = Image.open(pic_dir + 'uk_air.png')
    sufimg = Image.open(pic_dir + 'su_air.png')
    usfimg = Image.open(pic_dir + 'us_air.png')
    frfimg = Image.open(pic_dir + 'fr_air.png')
    chfimg = Image.open(pic_dir + 'ch_air.png')
    gefimg = gefimg.rotate(-45)
    jpfimg = jpfimg.rotate(-45)
    itfimg = itfimg.rotate(-45)
    ukfimg = ukfimg.rotate(-45)
    sufimg = sufimg.rotate(-45)
    usfimg = usfimg.rotate(-45)
    frfimg = frfimg.rotate(-45)
    chfimg = chfimg.rotate(-45)
    width = gefimg.size[0]
    height = gefimg.size[1]
    gefimg = gefimg.resize((int(width*2/3), int(height*2/3)), Image.ANTIALIAS)
    jpfimg = jpfimg.resize((int(width*2/3), int(height*2/3)), Image.ANTIALIAS)
    itfimg = itfimg.resize((int(width*2/3), int(height*2/3)), Image.ANTIALIAS)
    ukfimg = ukfimg.resize((int(width*2/3), int(height*2/3)), Image.ANTIALIAS)
    sufimg = sufimg.resize((int(width*2/3), int(height*2/3)), Image.ANTIALIAS)
    usfimg = usfimg.resize((int(width*2/3), int(height*2/3)), Image.ANTIALIAS)
    frfimg = frfimg.resize((int(width*2/3), int(height*2/3)), Image.ANTIALIAS)
    chfimg = chfimg.resize((int(width*2/3), int(height*2/3)), Image.ANTIALIAS)
    ukfimg = ukfimg.transpose(Image.FLIP_LEFT_RIGHT)
    sufimg = sufimg.transpose(Image.FLIP_LEFT_RIGHT)
    usfimg = usfimg.transpose(Image.FLIP_LEFT_RIGHT)
    frfimg = frfimg.transpose(Image.FLIP_LEFT_RIGHT)
    chfimg = chfimg.transpose(Image.FLIP_LEFT_RIGHT)
    army = {'ge':geaimg,'jp':jpaimg,'it':itaimg,'uk':ukaimg,'su':suaimg,'us':usaimg,'fr':fraimg,'ch':chaimg}
    navy = {'ge':genimg,'jp':jpnimg,'it':itnimg,'uk':uknimg,'su':sunimg,'us':usnimg,'fr':frnimg}
    air_force = {'ge':gefimg,'jp':jpfimg,'it':itfimg,'uk':ukfimg,'su':sufimg,'us':usfimg,'fr':frfimg,'ch':chfimg}
    land_list = db.execute("select distinct location from piece where type = 'army' and location != 'none';").fetchall()
    sea_list = db.execute("select distinct location from piece where type = 'navy' and location != 'none';").fetchall()
    air_list = db.execute("select distinct location from piece where type = 'air' and location != 'none';").fetchall()
    for land in land_list:
        piece_list = db.execute("select control from piece where type = 'army' and location = :space and control not in (select control from piece where type = 'air' and location = :space);", {'space':land[0]}).fetchall()
        posx = db.execute("select distinct posx from space where spaceid = :space;", {'space':land[0]}).fetchall()[0][0]-27
        posy = db.execute("select distinct posy from space where spaceid = :space;", {'space':land[0]}).fetchall()[0][0]-16
        for piece in piece_list:
            mapimg.paste(army[piece[0]], (posx, posy), army[piece[0]])
            posy -= 20
        if land in air_list:
            piece_list = db.execute("select control from piece where type = 'air' and location = :space;", {'space':land[0]}).fetchall()
            posx = db.execute("select distinct posx from space where spaceid = :space;", {'space':land[0]}).fetchall()[0][0]-20
            for piece in piece_list:
                mapimg.paste(air_force[piece[0]], (posx, posy), air_force[piece[0]])
                posy -= 20
    for sea in sea_list:
        piece_list = db.execute("select control from piece where type = 'navy' and location = :space and control not in (select control from piece where type = 'air' and location = :space);", {'space':sea[0]}).fetchall()
        posx = db.execute("select distinct posx from space where spaceid = :space;", {'space':sea[0]}).fetchall()[0][0]-35
        posy = db.execute("select distinct posy from space where spaceid = :space;", {'space':sea[0]}).fetchall()[0][0]-16
        for piece in piece_list:
            mapimg.paste(navy[piece[0]], (posx, posy), navy[piece[0]])
            posy += 20
        if sea in air_list:
            piece_list = db.execute("select control from piece where type = 'air' and location = :space;", {'space':sea[0]}).fetchall()
            posx = db.execute("select distinct posx from space where spaceid = :space;", {'space':sea[0]}).fetchall()[0][0]-20
            for piece in piece_list:
                mapimg.paste(air_force[piece[0]], (posx, posy), air_force[piece[0]])
                posy += 20

    pos = {'x':120, 'y':780}
    for country in ['ge', 'jp', 'it', 'uk', 'su', 'us', 'fr', 'ch']:
        remain_army_count = db.execute("select count(*) from piece where control = :country and type = 'army' and location = 'none';", {'country':country}).fetchall()[0][0]
        remain_navy_count = db.execute("select count(*) from piece where control = :country and type = 'navy' and location = 'none';", {'country':country}).fetchall()[0][0]
        remain_air_count = db.execute("select count(*) from piece where control = :country and type = 'air' and location = 'none';", {'country':country}).fetchall()[0][0]
        for i in range(remain_army_count):
            mapimg.paste(army[country].resize((int(width*1/2), int(height*1/2)), Image.ANTIALIAS), (pos['x'], pos['y']), army[country].resize((int(width*1/2), int(height*1/2)), Image.ANTIALIAS))
            pos['y'] -= 15
        for i in range(remain_navy_count):
            mapimg.paste(navy[country].resize((int(width*1/2), int(height*1/2)), Image.ANTIALIAS), (pos['x'], pos['y']), navy[country].resize((int(width*1/2), int(height*1/2)), Image.ANTIALIAS))
            pos['y'] -= 15
        for i in range(remain_air_count):
            mapimg.paste(air_force[country].resize((int(width*1/2), int(height*1/2)), Image.ANTIALIAS), (pos['x'], pos['y']), air_force[country].resize((int(width*1/2), int(height*1/2)), Image.ANTIALIAS))
            pos['y'] -= 15
        pos['x'] += 30
        pos['y'] = 780

    mapimg.save(dst_dir + "/tmp.jpg", format="JPEG")


from unittest import mock

from oslo_utils import timeutils

from masakari import exception
from masakari.objects import vmove
from masakari.tests.unit.objects import test_objects
from masakari.tests import uuidsentinel

NOW = timeutils.utcnow().replace(microsecond=0)

fake_vmove = {
    'created_at': NOW,
    'updated_at': None,
    'deleted_at': None,
    'deleted': False,
    'id': 1,
    'uuid': uuidsentinel.fake_vmove,
    'notification_uuid': uuidsentinel.fake_notification,
    'instance_uuid': uuidsentinel.fake_instance,
    'instance_name': 'fake_vm',
    'source_host': 'fake_host1',
    'dest_host': None,
    'start_time': None,
    'end_time': None,
    'status': 'pending',
    'type': 'evacuation',
    'message': None
    }

class TestVMoveObject(test_objects._LocalTest):

    @mock.patch('masakari.db.vmove_get_by_uuid')
    def test_get_by_uuid(self, mock_api_get):

        mock_api_get.return_value = fake_vmove

        vmove_obj = vmove.VMove.get_by_uuid(
            self.context, uuidsentinel.fake_vmove)
        self.compare_obj(vmove_obj, fake_vmove)

        mock_api_get.assert_called_once_with(self.context,
                                             uuidsentinel.fake_vmove)

    def _vmove_create_attributes(self):

        vmove_obj = vmove.VMove(context=self.context)
        vmove_obj.uuid = uuidsentinel.fake_vmove
        vmove_obj.notification_uuid = uuidsentinel.fake_notification
        vmove_obj.instance_uuid = uuidsentinel.fake_instance
        vmove_obj.instance_name = 'fake_vm1'
        vmove_obj.source_host = 'fake_host1'
        vmove_obj.status = 'pending'
        vmove_obj.type = 'evacuation'

        return vmove_obj

    @mock.patch('masakari.db.vmove_create')
    def test_create(self, mock_vmove_create):

        mock_vmove_create.return_value = fake_vmove
        vmove_obj = self._vmove_create_attributes()
        vmove_obj.create()

        self.compare_obj(vmove_obj, fake_vmove)
        mock_vmove_create.assert_called_once_with(self.context, {
            'uuid': uuidsentinel.fake_vmove,
            'notification_uuid': uuidsentinel.fake_notification,
            'instance_uuid': uuidsentinel.fake_instance,
            'instance_name': 'fake_vm1',
            'source_host': 'fake_host1',
            'status': 'pending',
            'type': 'evacuation'
        })

    @mock.patch('masakari.db.vmoves_get_all_by_filters')
    def test_get_limit_and_marker_invalid_marker(self, mock_api_get):
        vmove_uuid = uuidsentinel.fake_vmove
        mock_api_get.side_effect = (exception.
                                    MarkerNotFound(marker=vmove_uuid))

        self.assertRaises(exception.MarkerNotFound,
                          vmove.VMoveList.get_all,
                          self.context, limit=5, marker=vmove_uuid)

    @mock.patch('masakari.db.vmove_update')
    def test_save(self, mock_vmove_update):

        mock_vmove_update.return_value = fake_vmove

        vmove_obj = self._vmove_create_attributes()
        vmove_obj.uuid = uuidsentinel.fake_vmove
        vmove_obj.save()

        self.compare_obj(vmove_obj, fake_vmove)
        (mock_vmove_update.assert_called_once_with(
            self.context, uuidsentinel.fake_vmove,
            {'uuid': uuidsentinel.fake_vmove,
             'notification_uuid': uuidsentinel.fake_notification,
             'instance_uuid': uuidsentinel.fake_instance,
             'instance_name': 'fake_vm1',
             'source_host': 'fake_host1',
             'status': 'pending',
             'type': 'evacuation'}))


texto = 'Ah o amor... que nasce não'\
        'sei onde, vem não sei como, e dói não sei porquê.'

# cont = 0
# letra_proc = input('Entre com a letra que quer ver: ')
# cont_letra = 0
#
# while cont < len(texto):
#      if texto[cont].upper() == letra_proc.capitalize():
#         cont_letra += 1
#
#     cont += 1
#
# print(f'A letra {letra_proc} apareceu {cont_letra}X.')

i = 0
mais_aparec = ''
quant_x = 0

while i < len(texto):
    letra = texto[i]
    quant = texto.count(letra)
    i += 1
    if letra == ' ':
        continue

    if quant > quant_x:
        mais_aparec = letra
        quant_x = quant

print(f'A letra {mais_aparec} apareceu {quant_x}X.')