"""
Defines bridge classes to display and edit text with `Pango markup`_

.. _Pango markup:
    https://docs.gtk.org/Pango/pango_markup.html

.. data:: UIButtonTrigger

    Type alias for visual element to show/hide editor in view duo.  See
    `Gtk.MenuButton`_.

.. _Gtk.MenuButton:
    https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/MenuButton.html

.. data:: UiDisplayTextMarkup

    Type alias for visual element to display a text attribute.  The
    element supports `Pango markup`_ but is not editable.  See
    `Gtk.Label`_.

.. _Gtk.Label:
    https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Label.html

.. data:: UiAnchor

    Type alias for visual element that anchors a :class:`.EditorTextMarkup`.
    See `Gtk.Widget`_.

.. _Gtk.Widget:
   https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Widget.html

.. data:: UiEditorTextMarkup

    Type alias for visual element to edit a text attribute.  The
    element is editable and supports embedding `Pango markup`_.  See
    `Gtk.Entry`_.

.. _Gtk.Entry:
   https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Entry.html

.. data:: UiTextMarkup

    Type alias for element to store text formatted with `Pango markup`_.
    See `Gtk.EntryBuffer`_ and :data:`UiEditorTextMarkup`.

.. _Gtk.EntryBuffer:
   https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/EntryBuffer.html

.. data:: ViewDuoTextMarkup

    Type alias for visual element with components to both display and
    edit a text attribute.  See :data:`.UiDisplayTextMarkup` and
    :data:`.UiEditorTextMarkup`.

"""
import gi  # type: ignore[import]
import logging
import typing

import factsheet.bridge_gtk.bridge_text as BTEXT
import factsheet.view.ui as VUI

gi.require_version('Gdk', '3.0')
from gi.repository import Gdk   # type: ignore[import]  # noqa: E402
from gi.repository import GLib  # noqa: E402
from gi.repository import GObject as GO  # noqa: E402
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk   # noqa: E402
from gi.repository import Pango    # noqa: E402

logger = logging.getLogger('Main.bridge_text_markup')

UiDisplayTextMarkup = typing.Union[Gtk.Label]
UiAnchor = typing.Union[Gtk.Widget]
UiEditorTextMarkup = typing.Union[Gtk.Entry]
UiLabel = typing.Union[Gtk.Label]
UiPopoverEditorMarkup = typing.Union[Gtk.Popover]
UiSite = typing.Union[Gtk.Box]
UiTextMarkup = typing.Union[Gtk.EntryBuffer]
UiButtonTrigger = typing.Union[Gtk.MenuButton]
UiViewDuoMarkup = typing.Union[Gtk.Box]

def x_b_tm_escape_text_markup(p_markup: str) -> str:
    """Return text without markup errors.

    Escape `Pango markup`_ errors.  Raise other GLib errors.

    :param p_markup: text that may contain markup errors.
    """
    ALL = -1
    NO_ACCEL_CHAR = '0'
    try:
        _, _, _, _ = Pango.parse_markup(p_markup, ALL, NO_ACCEL_CHAR)
    except GLib.Error as err:
        if 'g-markup-error-quark' == err.domain:
            p_markup = GLib.markup_escape_text(p_markup, ALL)
        else:
            raise
    return p_markup

class DisplayTextMarkup:
    """Editor for text stored in a given :class:`.x_b_tm_ModelTextMarkup`.

    Provides visual element that support editing both text and embedded
    `Pango markup`_.

    .. attribute:: _UI_DEFINITION

        Constant that defines layout and format of visual element for
        the markup text editor.  Visual element property (that is,
        ``ui_view``) can change the layout and format of individual
        editors.

    .. warning:: Treat a :class:`.EditorTextMarkup` object like a GTK
        widget.  In particular, use the editor's visual element only in
        one GTK container and drop all references to the visual
        element when destroying the element.
    """

    def __init__(self, p_model: 'x_b_tm_ModelTextMarkup') -> None:
        """Initialize store for text and collection of displays.

        :param p_model: model that contains storage for displays.
        """
        """Initialize visual element of editor.

        :param p_model: model that contains storage for editor.
        """
        # self._ui_model = p_model.ui_model
        get_object = VUI.GetUiElementByStr(p_string_ui=self._UI_DEFINITION)
        self._ui_view = get_object('ui_view')

        markup = x_b_tm_escape_text_markup(p_model.text)
        self._ui_view.set_label(markup)

        _ = self._ui_view.connect('destroy', self.on_destroy, p_model.ui_model)
        self._id_delete = (
            p_model.ui_model.connect('deleted-text', self.on_change))
        self._id_insert = (
            p_model.ui_model.connect('inserted-text', self.on_change))

    def on_change(self, p_ui_model: UiTextMarkup, *_args):
        """Refresh display views when text is inserted or deleted."""
        markup = x_b_tm_escape_text_markup(p_ui_model.get_text())
        self._ui_view.set_markup(markup)

    def on_destroy(self, _ui_view: UiDisplayTextMarkup,
                   p_ui_model: UiTextMarkup) -> None:
        """Stop refreshing display view that is being destroyed.

        :param _ui_view: visual element of display being destroyed. (Unused)
        :param p_ui_model: storage element of display being destroyed.
        """
        if hasattr(self, 'ui_view'):  # Guard: duplicate destruction.
            del self._ui_view
            ID_INVALID = 0
            GO.signal_handler_disconnect(p_ui_model, self._id_delete)
            self._id_delete = ID_INVALID
            GO.signal_handler_disconnect(p_ui_model, self._id_insert)
            self._id_insert = ID_INVALID

    @property
    def ui_view(self) -> UiDisplayTextMarkup:
        """Return editor for text and markup formatting."""
        return self._ui_view

    _UI_DEFINITION = """<?xml version="1.0" encoding="UTF-8"?>
        <!-- Generated with glade 3.38.2 -->
        <interface>
          <requires lib="gtk+" version="3.24"/>
          <object class="GtkLabel" id="ui_view">
            <property name="visible">True</property>
            <property name="halign">start</property>
            <property name="use-markup">True</property>
            <property name="selectable">True</property>
            <property name="ellipsize">end</property>
            <property name="width-chars">15</property>
            <property name="xalign">0</property>
          </object>
        </interface>
        """

class EditorTextMarkup:
    """Editor for text stored in a given :class:`.x_b_tm_ModelTextMarkup`.

    Provides visual element that support editing both text and embedded
    `Pango markup`_.

    .. attribute:: _UI_DEFINITION

        Constant that defines layout and format of visual element for
        the markup text editor.  Visual element property (that is,
        ``ui_view``) can change the layout and format of individual
        editors.

    .. warning:: Treat a :class:`.EditorTextMarkup` object like a GTK
        widget.  In particular, use the editor's visual element only in
        one GTK container and drop all references to the visual
        element when destroying the element.
    """

    _UI_DEFINITION = """<?xml version="1.0" encoding="UTF-8"?>
        <!-- Generated with glade 3.38.2 -->
        <interface>
          <requires lib="gtk+" version="3.24"/>
          <object class="GtkEntry" id="ui_view">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="halign">start</property>
            <property name="width-chars">45</property>
            <property name="primary-icon-name"
                >emblem-default-symbolic</property>
            <property name="secondary-icon-name"
                >edit-delete-symbolic</property>
            <property name="primary-icon-tooltip-text"
                translatable="yes">Click to accept changes.</property>
            <property name="secondary-icon-tooltip-text"
                translatable="yes">Click to cancel changes.</property>
          </object>
        </interface>
        """

    def __init__(self, p_model: 'x_b_tm_ModelTextMarkup') -> None:
        """Initialize visual element of editor.

        :param p_model: model that contains storage for editor.
        """
        self._ui_view = UiEditorTextMarkup(buffer=p_model.ui_model)

    @property
    def ui_view(self) -> UiEditorTextMarkup:
        """Return editor for text and markup formatting."""
        return self._ui_view

def format_editor_markup(p_editor: EditorTextMarkup) -> None:
    """Apply formatting to visual element of editor.

    Set editor width and add icons to accept and cancel editing.
    Include tooltips for icons.

    :param p_editor: editor to format.
    """
    p_editor.ui_view.set_halign(Gtk.Align.START)
    N_WIDTH_EDIT = 45
    p_editor.ui_view.set_width_chars(N_WIDTH_EDIT)
    NAME_ICON_PRIMARY = 'emblem-default-symbolic'
    p_editor.ui_view.set_icon_from_icon_name(
        Gtk.EntryIconPosition.PRIMARY, NAME_ICON_PRIMARY)
    TOOLTIP_PRIMARY = 'Click to accept changes.'
    p_editor.ui_view.set_icon_tooltip_markup(
        Gtk.EntryIconPosition.PRIMARY, TOOLTIP_PRIMARY)
    NAME_ICON_SECONDARY = 'edit-delete-symbolic'
    p_editor.ui_view.set_icon_from_icon_name(
        Gtk.EntryIconPosition.SECONDARY, NAME_ICON_SECONDARY)
    TOOLTIP_SECONDARY = 'Click to cancel changes.'
    p_editor.ui_view.set_icon_tooltip_markup(
        Gtk.EntryIconPosition.SECONDARY, TOOLTIP_SECONDARY)

class x_b_tm_ModelTextMarkup(BTEXT.ModelText[UiTextMarkup]):
    """Text storage with support for editing and `Pango markup`_.  See
    `Gtk.EntryBuffer`_.

    See :class:`.ModelText` regarding equality.

    .. _Gtk.EntryBuffer:
        https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/EntryBuffer.html
    """

    def _get_persist(self) -> BTEXT.PersistText:
        """Return text storage element in form suitable for persistent
        storage.
        """
        return self._ui_model.get_text()

    def _new_ui_model(self) -> UiTextMarkup:
        """Return ``UiTextMarkup`` with signal connections."""
        ui_model = UiTextMarkup()
        _ = ui_model.connect('deleted-text', lambda *_a: self.set_stale())
        _ = ui_model.connect('inserted-text', lambda *_a: self.set_stale())
        return ui_model

    def _set_persist(self, p_persist: BTEXT.PersistText) -> None:
        """Set text storage element from content in persistent form.

        :param p_persist: persistent form for text storage element
            content.
        """
        ALL = -1
        self._ui_model.set_text(p_persist, ALL)

class PopupEditorMarkup:
    """Facade for visual element to pop up markup text editor.

    :class:`.PopupEditorMarkup` contains a visual element to pop
    up a markup text editor (:class:`.EditorTextMarkup`).  The element
    contains text to identify the editor's contents (such as Name or
    Title).  You may include `Pango markup`_ in the identifying text.
    An anchor visual element determines where the editor pops up.

    .. attribute:: _UI_DEFINITION

        Constant that defines layout and format of visual element that
        pops up for the markup text editor.

    .. admonition:: To maintainer

        Treat a :class:`.PopupEditorMarkup` object like a user
        interface toolkit element.  In particular, use the pop up editor
        only with one toolkit container and drop all references to the
        pop up editor when destroying the element.

    .. admonition:: To maintainer

        Each property with prefix ``ui_`` is a user interface toolkit
        element. Such properties should only be accessed in
        :mod:`.Element` or :mod:`.View` classes.  You can use toolkit
        element properties to change the layout and format of individual
        pop up editors.
    """

    def __init__(self, p_model: x_b_tm_ModelTextMarkup) -> None:
        """Initialize visual elements.

        :param p_model: model containing markup text.
        """
        get_object = VUI.GetUiElementByStr(p_string_ui=self._UI_DEFINITION)
        self._ui_view = get_object('ui_view')
        editor = EditorTextMarkup(p_model)
        self._ui_editor = editor.ui_view
        site_editor = get_object('site_editor')
        EXPAND_OKAY = True
        FILL_OKAY = True
        N_PADDING = 0
        site_editor.pack_start(
            self._ui_editor, EXPAND_OKAY, FILL_OKAY, N_PADDING)
        self._ui_label = get_object('ui_label')

    def set_anchor(self, p_anchor: UiAnchor) -> None:
        """Set anchor to determine editor pop up position.

        :param p_anchor: editor appears relative to this visual element.

        .. warning:: Gtk.MenuButton may use method set_popover in place
            of this method.
        """
        self._ui_view.set_relative_to(p_anchor)

    def set_label(self, p_text: str) -> None:
        """Set text to identify editor.

        :param p_test: identifying text, which may contain `Pango markup`_.
        """
        self._ui_label.set_label(p_text)

    @property
    def ui_editor(self) -> UiEditorTextMarkup:
        """Return visual element for markup text editor."""
        return self._ui_editor

    @property
    def ui_label(self) -> UiLabel:
        """Return visual element that identifies editor contents."""
        return self._ui_label

    @property
    def ui_view(self) -> UiPopoverEditorMarkup:
        """Return visual element to popup editor."""
        return self._ui_view

    _UI_DEFINITION = """<?xml version="1.0" encoding="UTF-8"?>
        <!-- Generated with glade 3.38.2 -->
        <interface>
          <requires lib="gtk+" version="3.20"/>
          <object class="GtkPopover" id="ui_view">
            <property name="can-focus">False</property>
            <property name="position">bottom</property>
            <property name="constrain-to">none</property>
            <child>
              <object class="GtkBox" id="site_editor">
                <property name="visible">True</property>
                <property name="can-focus">False</property>
                <property name="spacing">6</property>
                <child>
                  <object class="GtkLabel" id="ui_label">
                    <property name="visible">True</property>
                    <property name="can-focus">False</property>
                    <property name="label" translatable="yes"
                        ><b>Oops!</b></property>
                    <property name="use-markup">True</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
              </object>
            </child>
          </object>
        </interface>
        """

class ViewDuoMarkup:
    """View-model pair of visual elements to display and edit markup text.

    A view duo contains a display and a popup editor for markup text.
    Display shows formatted text when markup is valid.  It shows text
    with embedded markup when there is a markup error.  User can popup
    editor to edit both text and embedded markup.  The formatted text in
    the display updates as the user edits the markup text.  User can
    cancel edit and discard changes.

    Class :class:`.PariViewDuoTextMarkup` creates a view duo and pairs
    the view duo with a given markup text model.  When the app destroys
    a component visual element of view duo, view duo stops updating the
    component.  The view duo holds a reference to its top-level visual
    element until the view duo is destroyed.

    .. admonition:: To maintainer

        An alternative way to pair view duos with a markup text model is
        to implement a factory that produces paired view duos from a
        markup text model.  The factory maintains the collection of view
        duos paired with the markup text model.  This was the initial
        approach used with markup text display and editor views.

        * Pro: centralizes collection of view duos for a model

        * Con: combines pairing with management of view duo collection

        * Con: no guarantee of one factory per model

        :class:`.ViewDuoMarkup` makes pairing a distinct action
        independent from view duo collection management.  Collection
        management may be implemented separately as needed.
    """

    def __init__(self, p_model: x_b_tm_ModelTextMarkup, p_label: str = 'Item'
                 ) -> None:
        """Initialize internal components and their connections.

        :param p_model: model containing markup text.
        :param p_label: text to identify view duo to user (such as, 'Title').
        """
        # self._model = p_model
        self._text_restore = ''

        get_object = VUI.GetUiElementByStr(p_string_ui=self._UI_DEFINITION)
        self._ui_view = get_object('ui_view')
        self._ui_button = get_object('ui_button_edit')
        self._display = DisplayTextMarkup(p_model)
        self._popup = PopupEditorMarkup(p_model)
        self._popup.set_label(p_label)

        self.fill_display()
        self.link_popup()

    def fill_display(self) -> None:
        """Populate display component of view duo.

        Override this method to change the format of the display.
        """
        EXPAND_OKAY = True
        FILL_OKAY = True
        N_PADDING = 6
        self._ui_view.pack_start(
            self._display.ui_view, EXPAND_OKAY, FILL_OKAY, N_PADDING)

    def link_popup(self) -> None:
        """Link popup editor to view duo components.

        Popup includes editor along with button to show/hide editor..
        """
        self._ui_button.set_popover(self._popup.ui_view)
        _ = self._ui_button.connect(
            'toggled', self.on_toggled, self._popup.ui_editor)

        _ = self._popup.ui_editor.connect(
            'activate', lambda _: self._ui_button.clicked())
        _ = self._popup.ui_editor.connect('icon-press', self.on_icon_press)

    def on_icon_press(self, p_ui_editor: UiEditorTextMarkup,
                      p_icon: Gtk.EntryIconPosition, _event: Gdk.Event
                      ) -> None:
        """End edit and if user cancels edit, restore text.

        Primary icon accepts edits.  Secondary icon cancels edits.

        :param p_ui_editor: editor visual element.
        :param p_icon: identifies icon user clicked.
        :param _event: user interface event (unused).
        """
        if Gtk.EntryIconPosition.SECONDARY == p_icon:
            p_ui_editor.set_text(self._text_restore)
        self._ui_button.clicked()

    def on_toggled(self, p_ui_button: UiButtonTrigger,
                   p_ui_editor: UiEditorTextMarkup) -> None:
        """Record restore text before edit begins and clear after edit ends.

        :param p_ui_button: button user clicked.
        :param p_ui_editor: editor visual element.
        """
        if p_ui_button.get_active():
            self._text_restore = p_ui_editor.get_text()
        else:
            self._text_restore = ''

    @property
    def ui_button(self) -> UiViewDuoMarkup:
        """Return visual element of view duo."""
        return self._ui_button

    @property
    def ui_view(self) -> UiViewDuoMarkup:
        """Return visual element of view duo."""
        return self._ui_view

    _UI_DEFINITION = """<?xml version="1.0" encoding="UTF-8"?>
        <!-- Generated with glade 3.38.2 -->
        <interface>
          <requires lib="gtk+" version="3.20"/>
          <object class="GtkBox" id="ui_view">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="spacing">6</property>
            <child>
              <object class="GtkMenuButton" id="ui_button_edit">
                <property name="visible">True</property>
                <property name="can-focus">True</property>
                <property name="receives-default">True</property>
                <child>
                  <object class="GtkImage">
                    <property name="visible">True</property>
                    <property name="can-focus">False</property>
                    <property name="icon-name"
                        >document-edit-symbolic</property>
                    <property name="icon_size">2</property>
                  </object>
                </child>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
          </object>
        </interface>
        """


import csv
import numpy as np
from sklearn import datasets, linear_model
from sklearn.metrics import mean_absolute_error, mean_squared_error

if __name__ == '__main__':
    train_data_name = 'train_data_regression.csv'
    test_data_name = 'test_data_regression.csv'
    train_data = np.genfromtxt(train_data_name, delimiter=',')

    feature_data = train_data[:, 1:-1]
    label_data = train_data[:, -1]

    train_features = feature_data[0:-200, :]
    train_labels = label_data[0:-200]
    val_features = feature_data[-200:, :]
    val_labels = label_data[-200:]

    regr = linear_model.LinearRegression()
    regr.fit(feature_data, label_data)
    #regr.fit(train_features, train_labels)
    #pred = regr.predict(val_features)
    #mae = mean_absolute_error(pred, val_labels)

    test_data = np.genfromtxt(test_data_name, delimiter=',')
    test_data = test_data[:, 1:]
    pred = regr.predict(test_data)
    print(pred)
    nums = np.arange(100)
    with open('submit.csv', mode='w') as submit:
        submit_writer = csv.writer(submit, delimiter=',')
        submit_writer.writerow(['', 'Predict'])
        for i in range(100):
            submit_writer.writerow(['%i' % i, '%f' % pred[i]])
        submit_writer.writerow([])


# -*- coding: utf-8 -*-
import os

import numpy as np
import pandas as pd
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QDialog, QMessageBox, QTableWidgetItem, QFileDialog, QAction

from QSExt.GUI.QtGUI.Ui_PreviewRiskDataDlg import Ui_Dialog
from QuantStudio.RiskDataBase.RiskDB import FactorRT

class PreviewRiskDataDlg(QDialog, Ui_Dialog):
    def __init__(self, risk_db, table_name, idt, parent=None):
        super(PreviewRiskDataDlg, self).__init__(parent)
        self.setupUi(self)
        self.RiskDB = risk_db
        self.RT = self.RiskDB.getTable(table_name)
        self.DT = idt
        self.RiskData = self.RT.readCov(dts=[self.DT], ids=None).iloc[0]
        self.IDs = self.RiskData.index.tolist()
        self.setWindowTitle("预览: "+self.DT.strftime("%Y-%m-%d %H:%M:%S.%f"))
        self.PreviewTable.addAction(QAction("去除缺失", self.PreviewTable, triggered=self.dropNA))
        self.populatePreviewTable()
        self.populateID()
        if isinstance(self.RT, FactorRT):
            self.populateFactor()
        else:
            self.PreviewFactorRiskButton.setEnabled(False)
            self.PreviewSpecificRiskButton.setEnabled(False)
    def populatePreviewTable(self):
        self.PreviewTable.clear()
        nRow, nCol = self.RiskData.shape
        if self.RowNumLimitCheckBox.isChecked(): nRow = min(nRow, self.RowNumSpinBox.value())
        if self.ColNumLimitCheckBox.isChecked(): nCol = min(nCol, self.ColNumSpinBox.value())
        self.PreviewTable.setColumnCount(nCol)
        self.PreviewTable.setHorizontalHeaderLabels(self.RiskData.columns[:nCol].tolist())
        self.PreviewTable.setRowCount(nRow)
        self.PreviewTable.setVerticalHeaderLabels(self.RiskData.index[:nRow].tolist())
        for i in range(nRow):
            for j in range(nCol):
                self.PreviewTable.setItem(i, j, QTableWidgetItem(str(self.RiskData.iloc[i, j])))
        return 0
    def populateFactor(self):
        FactorNames = self.RT.FactorNames
        self.FactorList.clear()
        self.FactorList.addItems(FactorNames)
        self.FactorListLabel.setText("因子: %d" % len(FactorNames))
        return 0
    def populateID(self):
        self.IDList.clear()
        self.IDList.addItems(self.IDs)
        self.IDListLabel.setText("ID: %d" % len(self.IDs))
        return 0
    def dropNA(self):
        self.RiskData = self.RiskData.dropna(how="all", axis=0)
        if self.RiskData.shape[1]>1:
            self.RiskData = self.RiskData.loc[:, self.RiskData.index]
            self.RiskData = self.RiskData.dropna(how="any", axis=0)
            self.RiskData = self.RiskData.loc[:, self.RiskData.index]
        return self.populatePreviewTable()
    @pyqtSlot()
    def on_PreviewFactorRiskButton_clicked(self):
        self.RiskData = self.RT.readFactorCov(dts=[self.DT]).iloc[0]
        return self.populatePreviewTable()
    @pyqtSlot()
    def on_PreviewSpecificRiskButton_clicked(self):
        self.RiskData = self.RT.readSpecificRisk(dts=[self.DT], ids=None).iloc[0]
        self.RiskData = pd.DataFrame(self.RiskData)
        self.RiskData.columns = ["SpecificRisk"]
        return self.populatePreviewTable()
    @pyqtSlot()
    def on_PreviewRiskButton_clicked(self):
        self.RiskData = self.RT.readCov(dts=[self.DT], ids=None).iloc[0]
        return self.populatePreviewTable()
    @pyqtSlot()
    def on_Export2CSVButton_clicked(self):
        FilePath, _ = QFileDialog.getSaveFileName(self, "导出数据", os.getcwd()+os.sep+"RiskData.csv", "csv (*.csv)")
        if not FilePath: return 0
        self.RiskData.to_csv(FilePath)
        return QMessageBox.information(self, "完成", "导出数据完成!")


from app import db, Products, Purchases, Customers

db.drop_all()
db.create_all()

person1 = Customers(name='Femi')
person2 = Customers(name='Tiwa')

db.session.add(person1)
db.session.add(person2)
db.session.commit()

item1 = Products(name='shampoo')
item2 = Products(name='conditioner')
db.session.add(item1)
db.session.add(item2)
db.session.commit()

purchase1 = Purchases(customer = person1, product = item1)
purchase2 = Purchases(customer = person2, product = item1)
purchase3 = Purchases(customer = person2, product = item2)
db.session.add(purchase1)
db.session.add(purchase2)
db.session.add(purchase3)
db.session.commit()


import conn_auth
import csv
from tweet_csv_converter import run
import time

def get_all_tweets(screen_name):

    #Twitter only allows access to a users most recent 3240 tweets with this method

    csvfile = open('%s_tweets.csv' % screen_name[1:], 'w')
    fieldnames = ['tweet_id', 'date', 'tweet_text']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()

    #initialize a list to hold all the tweepy Tweets
    alltweets = []

    api = conn_auth.get_twitter_auth()

    #make initial request for most recent tweets (200 is the maximum allowed count)
    new_tweets = api.user_timeline(screen_name = screen_name,count=200)
    for tweet in new_tweets:
        if '$' not in tweet.text:
            new_tweets.remove(tweet)
    #save most recent tweets
    alltweets.extend(new_tweets)

    for tweet in alltweets:
            writer.writerow({'tweet_id':tweet.id_str,
                            'date':tweet.created_at,
                            'tweet_text':tweet.text.encode('utf-8')})

    #save the id of the oldest tweet less one
    oldest = alltweets[-1].id - 1

    #keep grabbing tweets until there are no tweets left to grab
    while len(new_tweets) > 0:

        print("getting tweets before %s" % (oldest))

        #all subsiquent requests use the max_id param to prevent duplicates
        new_tweets = api.user_timeline(screen_name = screen_name,count=200,max_id=oldest)
        for tweet in new_tweets:
            writer.writerow({'tweet_id':tweet.id_str,
                            'date':tweet.created_at,
                            'tweet_text':tweet.text.encode('utf-8')})

        #save most recent tweets
        alltweets.extend(new_tweets)

        #update the id of the oldest tweet less one
        oldest = alltweets[-1].id - 1

        print("...%s tweets downloaded so far" % (len(alltweets)))
    csvfile.close()
    return('%s_tweets.csv' % screen_name[1:])

def run_tweet_to_table(source, conn):
    csvf = get_all_tweets(screen_name=source)
    run(csvf, conn)
    print('DONE')


#!/usr/bin/python3
# -*- coding:utf-8 -*-

# 2014 year

import sys, os

try:
  #from dict_dir import A
  from optparse import OptionParser
except ImportError:
    sys.exit("no optparse module found")

class MyError(Exception):

	def __init__(self, message, errors):
		super().__init__(message)

		#pass #sys.exit("please type with --help first")

#-i /var/www/eruditor/view -e .html -t b -s paliko
#-i /var/www/eruditor/view -e .html -t b -s paliko -r "saxli pali"

#-i /var/www/eruditor/view -e .html -t b -s "\"http://www.onlineolimpiada/\""
#-i /var/www/eruditor/view -e .html -t b -s "\"http://www.onlineolimpiada/\"" -r  "\"http://www.onlineolimpiada/new/\""

class Repl:
	def __init__(self,kwargs):
	    try:
	        self.input       = kwargs['path']
	        self.search      = kwargs['search']
	        self.replace     = kwargs['replace']
	        self.type        = kwargs['type']
	        self.end         = kwargs['end']

	        self.iterator    = 0

	        self.action = 'search_' if not self.replace else 'replace_'
	    except KeyError:
	        print("parameters error")

	def find(self):

		if not (self.input and os.path.exists(self.input)):
			raise Exception("input path not found!!!")

		self.ret_array = []
		self.iterator = 0
		for (a,b,c) in os.walk(self.input):
			for file in c:
				if not os.path.isfile(os.path.join(a,file)):continue
				if self.end:
				  if not file.endswith(self.end):continue
				file_name = os.path.join(a,file)

				getattr(self,self.action)(file_name)

		for x in self.ret_array:
		    print(x)
		print('sum:',self.iterator)

	def replace_(self,file):
	    iter,line = 0,0
	    mode = 'r' if self.type == 's' else 'rb'
	    mode_w = 'w' if self.type == 's' else 'wb'
	    count_ = 0
	    line_ = []
	    ret = "".encode()
	    with open(file,mode) as op:
	      for x in op:
	          line += 1
	          if self.search.encode() in x:
	              ret += x.replace(self.search.encode(),self.replace.encode())
	              line_.append(line)
	              len_ = len(x.split(self.search.encode())) - 1
	              count_ += len_
	              self.iterator += len_
	          else:
	              ret += x
	    if count_:
	       self.ret_array.append(dict(count = count_,file = file,line = line_))
	       with open(file,mode_w) as w:
	          w.write(ret)

	def search_(self,file):
		if not (self.search):raise Exception("please specify search string!")
		iter,line = 0,0
		mode = 'r' if self.type == 's' else 'rb'
		count_ = 0
		line_ = []
		with open(file, mode) as op:
		  for x in op:
		      line += 1
		      if self.search.encode() in x:
		          line_.append(line)
		          len_ = len(x.split(self.search.encode())) - 1
		          count_ += len_
		          self.iterator += len_
		if count_:self.ret_array.append(dict(count = count_,file = file,line = line_))

if __name__ == "__main__":

    parser = OptionParser()
    parser.add_option("-p", "--pathToSearch", dest="path",help="destination path")#myfindfile
    parser.add_option("-s", "--search", dest="search", help="string what need to found") # -s paliko
    parser.add_option("-r", "--replace", dest="replace",help="if parameter is present then replacing string") # -r pali
    parser.add_option("-t", "--type", dest="type",help="binary or string; if string then don`t works with binnary files!") # -t s || b
    parser.add_option("-e", "--end", dest="end",help="endswith; if need only specific files example: .py will find only python files. same as *.py in linux!") # -e .py

    (options, args) = parser.parse_args()

    a = Repl(vars(options))
    try:
    	a.find()
    except Exception as e:
    	print(str(e))


def calculate_change(payment, cost):
    change = payment - cost
    fifty_th_count = int(change / 50000)
    print("50000::", fifty_th_count)
    change %= (fifty_th_count * 50000)
    print("rest::", change)
    ten_th_count = int(change / 10000)
    print("10000::", ten_th_count)
    change %= (ten_th_count * 10000)
    print("rest::", change)
    five_th_count = int(change / 5000)
    print("5000::", five_th_count)
    change %= (five_th_count * 5000)
    print("rest::", change)
    one_th_count = int(change / 1000)
    print("1000::", one_th_count)
    change %= (one_th_count * 1000)
    print("rest::", change)

payment = int(input("payment?: "))
cost = int(input("cost?: "))

calculate_change(payment, cost)


import numpy as np

# # numpy的boolean行索引
#
# x =np.array([[1,2],[3,4]])
# print(x[0,1])
#
# # 花式索引：可以使用一个整形数组
# x = np.arange(24).reshape(2,3,4)
# print(x)
#
# # 数组的转置
# print("数组的转置")
# k = np.arange(12).reshape(3,4)
# print(k)
#
# print(k.T)
#
# # 点乘 （内积）  列和行一样  A行 = B列
#
#
# # 高位数组的轴对象  维度   向右旋转90度
# x = np.arange(24).reshape(2,3,4)  # 0,1,2 轴
#
# k = k.transpose(1,0,2)
# print(k.shape)
#
# k = k.swapaxes(0,2)  # 只是调整两个轴
#
#
# # numpy的基本统计方法
#
# k.mean()
#
# k.mean(axis=0)  # 对列求均值， 1= 对每一行求均值
#
#
# # 数组求和
# print(k.sum())
# print(k.sum(axis=0))
#
#
# print(",排序")
# x =  np.array([6,1,3],[1,5,2])
#
# x.sort()
# print(x)

# ndarray的存储

x = np.array([[1, 6, 2], [6, 1, 3], [1, 5, 2]])
np.save("file", x)

y = np.load("file.npy")
print(y)

# 随机数
x = np.random.randint(0, 2, size=10000)

print((x > 2).sum())

print("where 函数")

cond = np.array([True, False, False, False])
u = np.where(cond, -2, 2) # 相当于三木运算符

print(u)


# -*- coding: utf-8 -*-
from datetime import datetime
from odoo import models, fields, api
from odoo.exceptions import ValidationError
import requests
import urllib
import base64
import os
from ..get_domain import get_line_ids

class xian_metro(models.Model):

    _name = 'xian_metro.xian_metro'
    _order = 'id desc'
    _rec_name = 'rules_name'
    _description = '规章制度'
    _inherit = ['mail.thread', 'mail.activity.mixin']

    # _inherit = 'fuenc_station.station_base'
    line_id = fields.Many2many('cdtct_dingtalk.cdtct_dingtalk_department','line_id_site_id_ref','line_id','site_id',string='线路', track_visibility='onchange')
    site_id = fields.Many2many('cdtct_dingtalk.cdtct_dingtalk_department', 'xian_metro_site_id_rel','xian_metro_id','site_id',string='站点', track_visibility='onchange')
    profession_kind = fields.Many2one('xian_metro.professional', string='专业分类', track_visibility='onchange')
    rank_kind = fields.Many2one('add_class.add_class', string='级别分类', track_visibility='onchange')
    rules_id = fields.Char(string='规章编号', track_visibility='onchange')
    rules_name = fields.Char(string='规章名称', track_visibility='onchange')
    # load_line = fields.Selection([('one', '一号线'), ('two', '二号线'), ('three', '三号线')], string='线路', default='one')
    # station_id = fields.Many2one('cdtct_dingtalk.cdtct_dingtalk_department',string='站点')
    details = fields.Binary(string='内容', track_visibility='onchange')
    file_name = fields.Char(string="File Name")
    operation_peison = fields.Char(string='操作人',default=lambda self: self.default_person_id(), track_visibility='onchange')
    operation_time = fields.Datetime(string='操作时间', default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"), track_visibility='onchange')
    url = fields.Char(string='url')
    release_time = fields.Date(string='发布实施日期', track_visibility='onchange')
    rule_regulations_browse = fields.Selection([('one','内容显示'),('zero','内容不显示')],default='zero')

    # @api.onchange('line_id')
    # def change_line_id(self):
    #     lis = []
    #     if not self.line_id:
    #         self.site_id = ''
    #     else:
    #         line_id = self.line_id
    #         for i in line_id:
    #             lis.append(i.departmentId)
    #
    #         child_department_ids = self.env['cdtct_dingtalk.cdtct_dingtalk_department'].search(
    #             [('parentid', 'in', lis)]).ids
    #         site_domain = [('id', 'in', list(set(child_department_ids)))]
    #
    #         return {'domain': {'site_id': site_domain,
    #                            }
    #                 }

    def wrapper(self, *args, **kwargs):
        ding_user = self.env.user.dingtalk_user
        department_ids = ding_user.user_property_departments
        line_ids = []
        for department_id in department_ids:
            if department_id.department_hierarchy == 3:
                id = self.env['cdtct_dingtalk.cdtct_dingtalk_department'].search(
                    [('departmentId', '=', department_id.parentid)]).id

                line_ids.append(id)

        return line_ids
        # print(line_ids)

    # 自动获取操作人的姓名
    @api.model
    def default_person_id(self):
        if self.env.user.id ==1:
            return

        return self.env.user.dingtalk_user.name

    @api.model
    def xian_metro_type(self):
        return {
            'name': '新增规章',
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'xian_metro.xian_metro',
            'context': self.env.context,
            # 'flags': {'initial_mode': 'edit'},
            'target': 'new',
        }

    def profession_kind_edit(self):
        return {
            'profession_kind': '专业分类',
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'xian_metro.xian_metro',
            'context': self.env.context,
            'flags': {'initial_mode': 'edit'},
            'res_id': self.id,
            'target': 'new',
        }

    def xian_metro_delete(self):
        self.env['xian_metro.xian_metro'].search([('id', '=', self.id)]).unlink()

    # 用来展示文件的样式
    @api.model
    def create(self, params):
        lis_line = []
        # lis_site =[]
        file_binary = params['details']
        for i in params.get('line_id'):
            for line in i[2]:
                char_line = self.env['cdtct_dingtalk.cdtct_dingtalk_department'].search([('id','=',line)])
                lis_line.append(char_line.name)
        # file = os.path.splitext(params.get('file_name'))
        # filename,type = file
        # if type != '.pdf':
        #     raise ValidationError('上传的文件需要时pdf文件，请重新改选择')
        file_name = params.get('file_name', self.file_name)
        if file_binary:
            url = self.env['qiniu_service.qiniu_upload_bucket'].upload_data(
                'funenc_xa_station', file_name, base64.b64decode(file_binary))
            token = self.env['qiniu_service.qiniu_upload_bucket'].get_upload_token('funenc_xa_station')
            print(token)
            params['url'] = url
            params['file_name'] = file_name
            params['rule_regulations_browse'] = 'one'
        # url, key = self.env['qiniu_service.qiniu_upload_bucket'].upload_file(
        #     file_binary, 'pdf')
        # params['url'] = url
        # params['file_name'] = key
        return super(xian_metro, self).create(params)

    def view_details(self):
        url = self.url
        if url:
            return {
                "type": "ir.actions.act_url",
                "url": url,
                "target": "new"
            }

    def file_kind_load(self):
        # view_form = self.env.ref('funenc_xa_station.add_operation_form_test').id
        # return {
        #     'name': '新增规范',
        #     'type': 'ir.actions.act_window',
        #     "views": [[view_form, "form"]],
        #     'res_model': 'xian_metro.xian_metro',
        #     'res_id': self.id,
        #     'flags': {'initial_mode': 'readonly'},
        #     'target': 'new',
        # }
        return {
            'type':'ir.actions.act_url',
            'url':'/funenc_xa_station/test_test?id=%d'%self.id,
        }

    @api.model
    def get_xian_metro_list(self):
        xian_metro = self.search_read([], ['id', 'rules_id', 'profession_kind', 'url'])
        for xian in xian_metro:
            xian['profession_kind'] =  xian['profession_kind'][1]

        return xian_metro

    def get_day_plan_publish_action(self):
        #  规章制度可见规则 admin 可见全部 站务一二分账号分别可见站务一二分部， 线路下面人员可见相关线路规章
        if self.env.user.id == 1:
            domain = []
        elif self.user_has_groups('base.group_system'):

            if self.env.user.name == '客运一部':
                parent_department = self.env['cdtct_dingtalk.cdtct_dingtalk_department'].search([('name', '=','客运一部')])
            else:
                # 客运二部账号
                parent_department = self.env['cdtct_dingtalk.cdtct_dingtalk_department'].search([('name', '=', '客运二部')])

            child_department_ids = self.env['cdtct_dingtalk.cdtct_dingtalk_department'].search(
                [('parentid', '=', parent_department.departmentId)]).ids
            domain = [('line_id', 'in', child_department_ids)]

        else:
            # 根据人物属性获取domain
            ding_user = self.env.user.dingtalk_user
            department_ids = ding_user.user_property_departments
            line_ids = []
            for department_id in department_ids:
                if department_id.department_hierarchy == 2:
                    line_ids.append(department_id.id)

                elif department_id.department_hierarchy == 3:
                    id = self.env['cdtct_dingtalk.cdtct_dingtalk_department'].search(
                        [('departmentId', '=', department_id.parentid)]).id

                    line_ids.append(id)

            domain = [('line_id', 'in', list(set(line_ids)))]

        view_form = self.env.ref('funenc_xa_station.add_operation_tree').id

        return {
            'name': '规章制度',
            'type': 'ir.actions.act_window',
            'domain':domain,
            "views": [[view_form, "tree"]],
            'res_model': 'xian_metro.xian_metro',
            'context': self.env.context,
        }


from unicodedata import normalize
from collections import defaultdict
import logging

# ------------------------------------------------
# Gramps module
# ------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale

HAVE_ICU = False
try:
    from icu import Locale, Collator

    HAVE_ICU = True
except ImportError:
    try:
        from PyICU import Locale, Collator

        HAVE_ICU = True
    except ImportError:
        pass

LOG = logging.getLogger(".NarrativeWeb")
COLLATE_LANG = glocale.collation

class U_ENUM_OUT_OF_SYNC_ERROR(Exception):  # pylint: disable=invalid-name
    """
    Exception to match the error in the ICU AlphabetiIndex
    """

    pass

# See : http://www.gramps-project.org/bugs/view.php?id = 4423

# Contraction data taken from CLDR 22.1. Only the default variant is considered.
# The languages included below are, by no means, all the langauges that have
# contractions - just a sample of langauges that have been supported

# At the time of writing (Feb 2013), the following langauges have greater that
# 50% coverage of translation of Gramps: bg Bulgarian, ca Catalan, cs Czech, da
# Danish, de German, el Greek, en_GB, es Spanish, fi Finish, fr French, he
# Hebrew, hr Croation, hu Hungarian, it Italian, ja Japanese, lt Lithuanian, nb
# Noregian Bokmål, nn Norwegian Nynorsk, nl Dutch, pl Polish, pt_BR Portuguese
# (Brazil), pt_P Portugeuse (Portugal), ru Russian, sk Slovak, sl Slovenian, sv
# Swedish, vi Vietnamese, zh_CN Chinese.

# Key is the language (or language and country), Value is a list of
# contractions. Each contraction consists of a tuple. First element of the
# tuple is the list of characters, second element is the string to use as the
# index entry.

# The DUCET contractions (e.g. LATIN CAPIAL LETTER L, MIDDLE DOT) are ignored,
# as are the supresscontractions in some locales.

CONTRACTIONS_DICT = {
    # bg Bulgarian validSubLocales="bg_BG" no contractions
    # ca Catalan validSubLocales="ca_AD ca_ES"
    "ca": [(("l·", "L·"), "L")],
    # Czech, validSubLocales="cs_CZ" Czech_Czech Republic
    "cs": [(("ch", "cH", "Ch", "CH"), "CH")],
    # Danish validSubLocales="da_DK" Danish_Denmark
    "da": [(("aa", "Aa", "AA"), "Å")],
    # de German validSubLocales="de_AT de_BE de_CH de_DE de_LI de_LU" no
    # contractions in standard collation.
    # el Greek validSubLocales="el_CY el_GR" no contractions.
    # es Spanish validSubLocales="es_419 es_AR es_BO es_CL es_CO es_CR es_CU
    # es_DO es_EA es_EC es_ES es_GQ es_GT es_HN es_IC es_MX es_NI es_PA es_PE
    # es_PH es_PR es_PY es_SV es_US es_UY es_VE" no contractions in standard
    # collation.
    # fi Finish validSubLocales="fi_FI" no contractions in default (phonebook)
    # collation.
    # fr French no collation data.
    # he Hebrew validSubLocales="he_IL" no contractions
    # hr Croation validSubLocales="hr_BA hr_HR"
    "hr": [
        (("dž", "Dž", "DŽ"), "DŽ"),
        (("lj", "Lj", "LJ"), "Ǉ"),
        (("Nj", "NJ", "nj"), "Ǌ"),
    ],
    # Hungarian hu_HU for two and three character contractions.
    "hu": [
        (("cs", "Cs", "CS"), "CS"),
        (("dzs", "Dzs", "DZS"), "DZS"),  # order is important
        (("dz", "Dz", "DZ"), "DZ"),
        (("gy", "Gy", "GY"), "GY"),
        (("ly", "Ly", "LY"), "LY"),
        (("ny", "Ny", "NY"), "NY"),
        (("sz", "Sz", "SZ"), "SZ"),
        (("ty", "Ty", "TY"), "TY"),
        (("zs", "Zs", "ZS"), "ZS"),
    ],
    # it Italian no collation data.
    # ja Japanese unable to process the data as it is too complex.
    # lt Lithuanian no contractions.
    # Norwegian Bokmål
    "nb": [(("aa", "Aa", "AA"), "Å")],
    # nn Norwegian Nynorsk validSubLocales="nn_NO"
    "nn": [(("aa", "Aa", "AA"), "Å")],
    # nl Dutch no collation data.
    # pl Polish validSubLocales="pl_PL" no contractions
    # pt Portuguese no collation data.
    # ru Russian validSubLocales="ru_BY ru_KG ru_KZ ru_MD ru_RU ru_UA" no
    # contractions
    # Slovak,  validSubLocales="sk_SK" Slovak_Slovakia
    # having DZ in Slovak as a contraction was rejected in
    # http://unicode.org/cldr/trac/ticket/2968
    "sk": [(("ch", "cH", "Ch", "CH"), "Ch")],
    # sl Slovenian validSubLocales="sl_SI" no contractions
    # sv Swedish validSubLocales="sv_AX sv_FI sv_SE" default collation is
    # "reformed" no contractions.
    # vi Vietnamese validSubLocales="vi_VN" no contractions.
    # zh Chinese validSubLocales="zh_Hans zh_Hans_CN zh_Hans_SG" no contractions
    # in Latin characters the others are too complex.
}

# The comment below from the glibc locale sv_SE in
# localedata/locales/sv_SE :
#
# % The letter w is normally not present in the Swedish alphabet. It
# % exists in some names in Swedish and foreign words, but is accounted
# % for as a variant of 'v'.  Words and names with 'w' are in Swedish
# % ordered alphabetically among the words and names with 'v'. If two
# % words or names are only to be distinguished by 'v' or % 'w', 'v' is
# % placed before 'w'.
#
# See : http://www.gramps-project.org/bugs/view.php?id = 2933
#

# HOWEVER: the characters V and W in Swedish are not considered as a special
# case for several reasons. (1) The default collation for Swedish (called the
# 'reformed' collation type) regards the difference between 'v' and 'w' as a
# primary difference. (2) 'v' and 'w' in the 'standard' (non-default) collation
# type are not a contraction, just a case where the difference is secondary
# rather than primary. (3) There are plenty of other languages where a
# difference that is primary in other languages is secondary, and those are not
# specially handled.

def first_letter(string, rlocale=glocale):
    """
    Receives a string and returns the first letter
    """
    if string is None or len(string) < 1:
        return " "

    norm_unicode = normalize("NFKC", str(string))
    contractions = CONTRACTIONS_DICT.get(rlocale.collation)
    if contractions is None:
        contractions = CONTRACTIONS_DICT.get(rlocale.collation.split("_")[0])

    if contractions is not None:
        for contraction in contractions:
            count = len(contraction[0][0])
            if len(norm_unicode) >= count and norm_unicode[:count] in contraction[0]:
                return contraction[1]

    # no special case
    return norm_unicode[0].upper()

if HAVE_ICU:

    def primary_difference(prev_key, new_key, rlocale=glocale):
        """
        Try to use the PyICU collation.
        If we generate a report for another language, make sure we use the good
        collation sequence
        """
        collate_lang = Locale(rlocale.collation)
        collation = Collator.createInstance(collate_lang)
        collation.setStrength(Collator.PRIMARY)
        return collation.compare(prev_key, new_key) != 0

else:

    def primary_difference(prev_key, new_key, rlocale=glocale):
        """
        The PyICU collation is not available.

        Returns true if there is a primary difference between the two parameters
        See http://www.gramps-project.org/bugs/view.php?id=2933#c9317 if
        letter[i]+'a' < letter[i+1]+'b' and letter[i+1]+'a' < letter[i]+'b' is
        true then the letters should be grouped together

        The test characters here must not be any that are used in contractions.
        """

        return rlocale.sort_key(prev_key + "e") >= rlocale.sort_key(
            new_key + "f"
        ) or rlocale.sort_key(new_key + "e") >= rlocale.sort_key(prev_key + "f")

def get_index_letter(letter, index_list, rlocale=glocale):
    """
    This finds the letter in the index_list that has no primary difference from
    the letter provided. See the discussion in get_first_letters above.
    Continuing the example, if letter is Å and index_list is A, then this would
    return A.

    @param: letter     -- The letter to find in the index_list
    @param: index_list -- The list of all first letters in use
    @param: rlocale    -- The locale to use
    """
    for index in index_list:
        if not primary_difference(letter, index, rlocale):
            return index

    LOG.warning("Initial letter '%s' not found in alphabetic navigation list", letter)
    LOG.debug("filtered sorted index list %s", index_list)
    return letter

# ------------------------------------------------------------
#
# AlphabeticIndex (local non-ICU version)
#
# ------------------------------------------------------------
class AlphabeticIndex:
    """
    Approximately emulate the ICU AlphabeticIndex
    """

    def __init__(self, rlocale):
        self.rlocale = rlocale
        self._record_list = []
        # self.index_list = []

        self._bucket_list = []
        self._dirty = False
        self._bucket = -1
        self._record = -1
        # Externally available properties
        self.bucketLabel = ""  # pylint: disable=invalid-name
        self.recordName = ""  # pylint: disable=invalid-name
        self.recordData = ""  # pylint: disable=invalid-name
        self.bucketRecordCount = 0  # pylint: disable=invalid-name

    def __create_index(self):
        """
        Internal routine to create the Alphabetic Index
        """
        # The first letter (or letters if there is a contraction) are extracted
        # from all the records in the _record_list. There may be duplicates, and
        # there may be letters where there is only a secondary or tertiary
        # difference, not a primary difference.
        index_list = []
        for name, dummy_data in self._record_list:
            ltr = first_letter(name, self.rlocale)
            index_list.append(ltr)
        # The list is sorted in collation order.
        index_list.sort(key=self.rlocale.sort_key)
        # For each group with secondary or tertiary differences, the first in
        # collation sequence is retained. For example, assume the default
        # collation sequence (DUCET) and names Ånström and Apple. These will
        # sort in the order shown. Å and A have a secondary difference. If the
        # first letter from these names was chosen then the index entry would be
        # Å. This is not desirable. Instead, the initial letters are extracted
        # (Å and A). These are sorted, which gives A and Å. Then the first of
        # these is used for the index entry.

        # now remove letters where there is not a primary difference
        first = True
        prev_index = None
        for nkey in index_list[:]:
            # iterate over a slice copy
            if first or primary_difference(prev_index, nkey, self.rlocale):
                first = False
                prev_index = nkey
            else:
                index_list.remove(nkey)

        # finally construct the buckets and contents
        bucket_dict = defaultdict(list)
        for name, data in sorted(
            self._record_list, key=lambda x: self.rlocale.sort_key(x[0])
        ):
            letter = first_letter(name, self.rlocale)
            letter = get_index_letter(letter, index_list, self.rlocale)
            bucket_dict[letter].append((name, data))

        self._bucket_list = sorted(
            bucket_dict.items(), key=lambda x: self.rlocale.sort_key(x[0])
        )

        self._dirty = False

    def addRecord(self, name, data):  # pylint: disable=invalid-name
        """
        Add a record to the index.

        Each record will be associated with an index Bucket based on the
        record's name. The list of records for each bucket will be sorted
        based on the collation ordering of the names in the index's locale.
        Records with duplicate names are permitted; they will be kept in the
        order that they were added.

        @param: name        --  The display name
                                for the Record. The Record will be placed in
                                a bucket based on this name.
        @param: data        --  An optional pointer to user data associated
                                with this item. When iterating the contents
                                of a bucket, both the data pointer the name
                                will be available for each Record.
        """
        self._record_list.append((name, data))
        self._dirty = True

    def resetBucketIterator(self):  # pylint: disable=invalid-name
        """
        Reset the Bucket iteration for this index.

        The next call to nextBucket() will restart the iteration at the
        first label.
        """
        if self._dirty:
            self.__create_index()
        self._bucket = -1
        self.bucketLabel = ""
        self._record = -1
        self.recordName = ""
        self.recordData = ""

    def nextBucket(self):  # pylint: disable=invalid-name
        """
        Advance the iteration over the Buckets of this index.

        Return false if there are no more Buckets.
        """
        if self._dirty:
            raise U_ENUM_OUT_OF_SYNC_ERROR
        self._bucket += 1
        self._record = -1
        if self._bucket < len(self._bucket_list):
            self.bucketLabel = self._bucket_list[self._bucket][0]
            self.bucketRecordCount = len(self._bucket_list[self._bucket][1])
            self.recordName = ""
            self.recordData = None
            return True
        else:
            return False

    def nextRecord(self):  # pylint: disable=invalid-name
        """
        Advance to the next record in the current Bucket.

        When nextBucket() is called, Record iteration is reset to just
        before the first Record in the new Bucket.
        """
        if self._dirty:
            raise U_ENUM_OUT_OF_SYNC_ERROR
        self._record += 1
        if self._record < len(self._bucket_list[self._bucket][1]):
            curr_bucket = self._bucket_list[self._bucket]
            bucket_value = curr_bucket[1]
            curr_record = bucket_value[self._record]
            self.recordName = curr_record[0]
            self.recordData = curr_record[1]
            return True
        else:
            self.recordName = ""
            self.recordData = None
            return False


def are_valid_indices(index1, index2, check_matrix):
    return 0 <= index1 < len(check_matrix) and 0 <= index2 < len(check_matrix[index1])

rows = int(input())

matrix = [[int(x) for x in input().split()] for _ in range(rows)]

bombs_coordinates = input().split()

for coordinates in bombs_coordinates:
    bomb_row, bomb_col = [int(x) for x in coordinates.split(",")]
    bomb_value = matrix[bomb_row][bomb_col]

    if bomb_value <= 0:
        continue
    else:
        matrix[bomb_row][bomb_col] = 0

    for row in range(bomb_row - 1, bomb_row + 2):
        for col in range(bomb_col - 1, bomb_col + 2):
            if are_valid_indices(row, col, matrix) and matrix[row][col] > 0:
                matrix[row][col] -= bomb_value

alive_cells = []

for r in matrix:
    alive_cells.extend([x for x in r if x > 0])

print(f"Alive cells: {len(alive_cells)}")
print(f"Sum: {sum(alive_cells)}")
[print(*m_row) for m_row in matrix]


# Master Thesis IMBRSea
# The Physics of Biodiversity:
# exploring the dynamics behind spatial biodiversity patterns
#
# contact: kobe.simoens@imbrsea.eu
# date: 01/08/2023
#
# Simulation of Mechanistic Model
#####################################
# SIMULATION GRID and related methods
#####################################

# ------------ IMPORT FROM OTHER FILES ---------------------

from parameters import*
from Local import*

# ----------------------------------------------------------

# ----------------- IMPORT MODULES -------------------------

import numpy as np
import pandas as pd
import random
import os
import shutil

# ----------------------------------------------------------

# ---------------------- GRID CLASS ------------------------
class Grid():

	# define constructor
	def __init__(self):

		# global grid = list of Local objects
		# Local defined in Local.py
		self.global_grid = []

		# import the grid cell coordinates
		# 'land_all_data_inc_working.csv' from Worm and Tittensor (2018)
		df_grid = pd.read_csv('land_all_data_inc_working.csv').iloc[:,[0,5,6]]
		# fill the grid with Local objects
		# Nlon / Nlat defined in parameters.py
		k = 0
		for i in range(0,Nlon):
			for j in range(0,Nlat):
				self.global_grid.append( Local(df_grid.iloc[k,1],df_grid.iloc[k,2],k+1) )
				k += 1

		# total number of species in the grid
		self.Nspec = 0
		# list of species in the grid: list of integers
		self.species = np.zeros(self.Nspec)
		# maximum integer value in the species list
		self.MaxSpec = 0

	# fill the grid befor the simulation
	# requires an initial number of species: Nspec
	def fillGrid(self,Nspec):

		# fill each Local object with populations
		# fillLocal defined in Local.py
		for loc in self.global_grid:
			loc.fillLocal(Nspec)
		# update species list
		self.Nspec = Nspec
		self.species = np.arange(0,Nspec)
		self.MaxSpec = np.max(self.species)

	# after a few turnovers, update the species list
	def updateSpecies(self):

		# list species identity of all local populations
		pop_list = np.array([])
		for cell in self.global_grid:
			pop_list = np.concatenate((pop_list,cell.populations))

		# list the identity of each population
		# add present species to the new species list
		# update species information
		self.species = np.array([])
		for i in range(0,self.MaxSpec+1):
			n = np.count_nonzero(pop_list == i)
			if(n != 0):
				self.species = np.append(self.species,i)

		self.Nspec = len(self.species)

	# print grid information to a csv file
	# requires an identifier 'step' to name the output file
	# best to use updateSpecies() before print
	def printGrid(self,step):

		# initialise lat and lon containers
		lon_list = np.zeros(len(self.global_grid))
		lat_list = np.zeros(len(self.global_grid))
		# initialise species container
		spec_list = np.zeros( (len(self.global_grid),self.Nspec) )

		# for each grid cell, collect diversity matrix
		# can take a while for many species
		for i in range(0,len(lat_list)):
			lon_list[i] = self.global_grid[i].lon
			lat_list[i] = self.global_grid[i].lat

			for j in range(0,self.Nspec):
				spec_list[i][j] = np.count_nonzero(self.global_grid[i].populations == self.species[j])

		# create pandas dataframe and write out to csv file
		darray = np.concatenate((lon_list, lat_list)).reshape((-1, 2), order='F')
		darray = np.concatenate( (darray,spec_list) ,axis=1)
		names_out = ['lon','lat'] + ['spec_' + str(int(ID)) for ID in self.species]
		df_out = pd.DataFrame(data=darray, columns=names_out)

		df_out.to_csv('Output/grid_' + str(int(step)).zfill(4) + '.csv')

	# get Moore neighbourhood of cell with index
	# assumes periodic longitudinal boundary conditions
	# assumes hard latitudinal boundary conditions
	# returns list of integers representing the species identity of local populations
	def getNeighbours(self,index):

		neighbours = np.array([])

		# 1
		# | - - . - - |
		# | x - . - o |
		# | - - . - - |
		if((index+1) % Nlon == 0):
			neighbours = np.concatenate((neighbours , self.global_grid[index-Nlon+1].populations))
		# - - -
		# - o x
		# - - -
		else:
			neighbours = np.concatenate((neighbours , self.global_grid[index+1].populations))
		# 2
		# | - - . - - |
		# | o - . - x |
		# | - - . - - |
		if((index) % Nlon == 0):
			neighbours = np.concatenate((neighbours , self.global_grid[index+Nlon-1].populations))
		# - - -
		# x o -
		# - - -
		else:
			neighbours = np.concatenate((neighbours , self.global_grid[index-1].populations))

		if(index >= Nlon):
			# 3
			# - x -
			# - o -
			# - - -
			neighbours = np.concatenate((neighbours , self.global_grid[index-Nlon].populations))

			# 4
			# | x - . - - |
			# | - - . - o |
			# | - - . - - |
			if((index+1) % Nlon == 0):
				neighbours = np.concatenate((neighbours , self.global_grid[index-Nlon-Nlon+1].populations))
			# - - x
			# - o -
			# - - -
			else:
				neighbours = np.concatenate((neighbours , self.global_grid[index-Nlon+1].populations))

			# 5
			# | - - . - x |
			# | o - . - - |
			# | - - . - - |
			if((index) % 45 == 0):
				neighbours = np.concatenate((neighbours , self.global_grid[index-1].populations))
			# x - -
			# - o -
			# - - -
			else:
				neighbours = np.concatenate((neighbours , self.global_grid[index-Nlon-1].populations))
	#	else: nothing
			# _ _ _
			# - o -
			# - - -

		if(index < len(self.global_grid)-Nlon):
			# 6
			# - - -
			# - o -
			# - x -
			neighbours = np.concatenate((neighbours , self.global_grid[index+Nlon].populations))

			# 7
			# | - - . - - |
			# | - - . - o |
			# | x - . - - |
			if((index+1) % Nlon == 0):
				neighbours = np.concatenate((neighbours , self.global_grid[index+1].populations))
			# - - -
			# - o -
			# - - x
			else:
				neighbours = np.concatenate((neighbours , self.global_grid[index+Nlon+1].populations))

			# 8
			# | - - . - - |
			# | o - . - - |
			# | - - . - x |
			if((index) % 45 == 0):
				neighbours = np.concatenate((neighbours , self.global_grid[index+Nlon+Nlon-1].populations))
			# - - -
			# - o -
			# x - -
			else:
				neighbours = np.concatenate((neighbours , self.global_grid[index+Nlon-1].populations))

	#	else: nothing
			# - - -
			# - o -
			# _ _ _

		return(neighbours)

	# select a random cell and return index
	def selectCell(self):

		i = random.randint(0,len(self.global_grid)-1)

		return(i)

	# do a single forward turnover
	def turnover(self):

		# select a random cell to be disturbed
		i = self.selectCell()

		# select local population to die
		old = random.randint(0,len(self.global_grid[i].populations)-1)

		# random number to check for migration
		r = random.uniform(0,1)
		# initialise pool of possible dispersers
		disp_pool = np.array([])

		# check for migration
		# Pdisp defined in parameters.py
		if(r < Pdisp):
			# migration: pool of dispersers = Moore neighbourhood
			disp_pool = self.getNeighbours(i)
		else:
			# no migration: pool of dispersors = local populations
			disp_pool = np.delete(self.global_grid[i].populations,old)

		# random number to check for speciation
		s = random.uniform(0,1)

		# check for speciation
		# Pspec defined in parameters.py
		if(s < Pspec):
			# update the species list
			self.global_grid[i].populations[old] = self.MaxSpec + 1
			self.MaxSpec += 1
		else:
			# select a disperser to take the free spot
			new = random.randint(0,len(disp_pool)-1)
			self.global_grid[i].populations[old] = disp_pool[new]

# ----------------------------------------------------------


"""
1. Clarification
2. Possible solutions
    - Dynamic programming
3. Coding
4. Tests
"""

# T=O(amount * n), S=O(amount), dp[i]: # ways to represent amount i
class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        dp = [1] + [0] * amount
        for coin in coins:
            for i in range(coin, amount + 1):
                dp[i] += dp[i - coin]
        return dp[amount]


import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="k40tools",
    version="0.0.1",
    install_requires=[
        "k40nano",
        "pynput"
    ],
    author="Tatarize",
    author_email="tatarize@gmail.com",
    description="K40 Tools",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/K40Nano/K40Tools",
    packages=setuptools.find_packages(),
    classifiers=(
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
        "Operating System :: OS Independent",
    ),
)


def PoprosheSdelaiBukvoiOdnoi (a,b):
    EstIliNet = 0
    for i in range (0,len(a),1):
        if b == a[i]:
            EstIliNet += 1
    if EstIliNet > 0:
        return True
    else:
        return False
print(PoprosheSdelaiBukvoiOdnoi([1,2,3,5],5))


def missing_parameter(v1, v2):
	number = -1
	v1 = list(v1.keys())
	v2 = list(v2)
	if len(v1)+1 == len(v2):
		pass
	else:
		try:
			assert False, "invalid parameters"
		except AssertionError as e:
			raise
	for item in v1:
		number +=1
		if v1[number] not in v2:
			try:
				assert False, "invalid parameters"
			except AssertionError as e:
				raise
	number = -1
	for item in v2:
		number +=1
		if v2[number] not in v1:
			return v2[number]

def juggle(dic):
	solve = 0.0
	standard = 'FDVBH'
	add_value = missing_parameter(dic, standard)
	if add_value =='F':
		solve = round((dic['B']*(round(dic['V']+dic['D'], 3))/dic['H'])-dic['D'], 3)
	if add_value =='H':
		solve = round((dic['B']*(round(dic['V']+dic['D'], 2))/ round(dic['F']+dic['D'], 2)))
	if add_value =='D':
		solve = (dic['B']*dic['V'] - dic['H']*dic['F'])/(dic['H']-dic['B'])
	if add_value =='B':
		solve = round((dic['H']*(round(dic['F']+dic['D'], 2))/ round(dic['V']+dic['D'], 2)))
	if add_value =='V':
		solve = round((dic['H']*(round(dic['F']+dic['D'], 2))/dic['B'])-dic['D'], 2)
	dic[add_value] = solve
	for item in list(dic.keys()):
		dic[item] = float(dic[item])
	return dic

def juggler(F=0, D=0, V=0, B=0, H=0, **kwargs):
	if len(kwargs)>=1:
		try:
			assert False, "invalid parameters"
		except AssertionError as e:
			raise
	number= -1
	dic = {'F' :F, 'D':D, 'V':V, 'B':B, 'H':H}
	length_dic = dic
	index_list = []
	solve = 0.0
	standard = 'FDVBH'
	for i in length_dic:
		number+=1
		if list(dic.values())[number] == 0:
			index_list.append(number)
	for i in index_list:
		del dic[list(dic.keys())[i]]
	if len(dic) != 4:
		try:
			assert False, "invalid parameters"
		except AssertionError as e:
			raise
	dic = juggle(dic)
	return dic


# -*- coding: utf-8 -*-
"""
Created on Sun Sep  4 18:02:43 2022

@author: Takodachi
"""

import requests
import jieba
import matplotlib.pyplot as plt
from bs4 import BeautifulSoup

# get web
response = requests.get("")

#soup解析
soup = BeautifulSoup(response.text, "html.parser")

#搜尋符合的節點
result = soup.find_all("")

#加入array
text = []
for r in result:
    text.append(r.select_one("a").getText())

#製作文本
words = ""
for t in text:
    words += str(t)

#斷詞 中文:Jieba 英文:NLTK
jieba.load_userdict('./userdict.txt')#客製化斷詞

#讀取和使用停用詞彙
def get_stopword_list(file):
    with open(file, encoding='utf-8')as f:
        stopword_list = [word.strip('\n') for word in f.readlines()]
    return stopword_list

def get_jieba_table(lst,v=None):
    jieba.set_dictionary("dict.txt")
    stop = get_stopword_list("stop2.txt")
    jie = list(jieba.cut(lst))
    list_difference = [element for element in jie if element not in stop]
    return list_difference

clean_table = get_jieba_table(words)
string = " ".join(clean_table)

#製作文本

#生成文字雲
import wordcloud
wc = wordcloud.WordCloud(background_color="white", repeat=True).generate(string)

#繪圖
plt.figure()
plt.imshow(wc, interpolation="bilinear")
plt.axis("off")
plt.show()


"""
退出登录接口
此接口耦合账号密码登录接口
"""
import unittest
import requests
from common.read_excel import *
import os
import yaml

class TestWithdraw(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        print("TestWithdraw模块用例")
        cls.data_list = excel_to_list("./data/test_data.xlsx", "withdraw")
        #   获取登陆身份令牌token
        current_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
        with open(current_path + '\\data' + '\\token.yaml', 'r') as f:
            cls.temp = yaml.load(f.read(), Loader=yaml.FullLoader)

    def test_withdraw(self):

        headers = {'authorization': self.temp['token']}

        case_data = get_test_data(self.data_list, 'test_withdraw')
        if not case_data:  # 有可能为None
            print("用例数据不存在")
        url = case_data.get('url')
        expect_res = case_data.get('expect_res')  # 期望数据

        response = requests.post(url=url, headers=headers)
        self.assertIn(expect_res, response.text)


import uuid
import random

from flask_mail import Message
from flask import Flask,Blueprint,render_template,request
from page_utils import Pagination
email=Blueprint('email',__name__,url_prefix='/email',template_folder='templates/email')
from databank import Confirm
from app import db2,mail

def gengenerateID():
    re = ""
    for i in range(10):
        re += chr(random.randint(65, 90))
    return re

@email.route('/email_captcha/',methods=[ 'POST'])
def email_captcha():

    email = request.form.get('email')
    if not email:
        return "missing param"
    '''
    生成随机验证码，保存到memcache中，然后发送验证码，与用户提交的验证码对比
    '''
    captcha = str(uuid.uuid1())[:6]  # 随机生成6位验证码
    while 1:
        ID = gengenerateID()
        str2 = Confirm.query.filter_by(id=ID).first()
        if not str2: break
    inf = Confirm(id=ID,secret=captcha)
    db2.session.add(inf)
    db2.session.commit()
    #给用户提交的邮箱发送邮件
    message = Message('外卖平台邮箱验证码', recipients=[email], body='您的验证码是：%s' % captcha)
    try:
        mail.send(message)  # 发送
    except:
        return "error"
    return ID


#Ziming Dong
#Student ID: 260951177

def find_delim(line):
    ''' （str) -> str
    The function takes a string as input representing a single line.
    A "delimiter" is a string that is used to separate columns of data on a single line.
    The function returns the most commonly used delimiter in the input string.

    >>> find_delim("cat\\tdog bat\\tcrab-cod")
    '\\t'
    >>> find_delim('You are so great,Bob')
    ' '
    >>> find_delim('1,2,3,4 5')
    ','
    '''
    #set dict_delim for 4 delimters
    dict_delim = {'\t':0, ',':0, ' ':0, '-':0}
    #set an empty dictionary and empty list
    dict_num = {}
    list_num = []
    #use for loop to check each character in line, if it is delimter,then add 1 to value in dict_delim
    for char in line:
        if char in dict_delim:
            dict_delim[char] += 1
    #use for loop to append value to list_num, and get dict_num
    for key in dict_delim:
        list_num.append(dict_delim[key])
        dict_num[dict_delim[key]] = key
    #find maximum number in list_num
    result_num = max(list_num)
    #return value in dict_num, when key is result_num
    return dict_num[result_num]

def clean_one(input_filename,output_filename):
    ''' (str,str) -> int
    The function takes as input two strings: the file name for a file to be read (input_filename),
    and file name for a file to be written (output_filename) respectively.
    The function will read the input_filename, make changes to each of the lines
    and write the new version to output_filename.

    >>> clean_one('small_raw_co2_data.txt', 'small_tab_sep_co2_data.tsv')
    10
    >>> clean_one('small_text.txt', 'small_tab_sep_text.tsv') #small_text is a file I created for testing, which contain 5 lines and 3 different countries
    5
    >>> clean_one('large_text.txt', 'large_tab_sep_text.tsv') #large_text is a file I created for testing, which contain 50 lines and 30 different countries
    50
    '''
    #open input and output file
    fobj_1 = open(input_filename,'r',encoding = 'utf-8')
    fobj_2 = open(output_filename,'w',encoding = 'utf-8')
    #make num equal to 0
    num = 0
    #use for loop to find most common delimter in each line and replace it with tab,num add 1, write line in output file
    for line in fobj_1:
        char = find_delim(line)
        line = line.replace(char,'\t')
        num += 1
        fobj_2.write(line)
    #close two file
    fobj_1.close()
    fobj_2.close()
    #return num
    return num

def final_clean(input_filename,output_filename):
    ''' (str,str) -> int
    The function takes as input two strings: the file name for a file to be read (input_filename),
    and file name for a file to be written (output_filename) respectively.
    The function will read the input_filename, make changes to each of the lines
    and write the new version to output_filename.

    >>> final_clean('small_tab_sep_co2_data.tsv', 'small_clean_co2_data.tsv')
    10
    >>> final_clean('small_tab_sep_text.tsv', 'small_clean_text.tsv') #small_tab_sep_text is file I get from clean_one('small_text.txt', 'small_tab_sep_text.tsv')
    5
    >>> final_clean('large_tab_sep_text.tsv', 'large_clean_text.tsv') #large_tab_sep_text is file I get from clean_one('large_text.txt', 'large_tab_sep_text.tsv')
    50
    '''
    #open two files and make num equal to 0
    fobj_1 = open(input_filename,'r',encoding = 'utf-8')
    fobj_2 = open(output_filename,'w',encoding = 'utf-8')
    num = 0
    #use for loop to check each line, and make it into a list
    for line in fobj_1:
        line_list = line.split('\t')
        #if length of list is equal or less than 5, then do as follow
        if len(line_list) <= 5:
            if ',' in line:
                line = line.replace(',','.')
            fobj_2.write(line)
            num += 1
            continue
        #use for loop
        for i in range(len(line_list)):
            #use try block to find year position
            try:
                int(line_list[i])
                #if year position is 2, which means before is no problem, so do as fllow
                if i is 2:
                    result = '.'.join(line_list[3:5])
                    new_line = '\t'.join([line_list[0],line_list[1],line_list[2],result,line_list[-1]])
                    fobj_2.write(new_line)
                    num += 1
                    break
                #get result_country and do as fllow
                result_country = ' '.join(line_list[1:i])
                if ',' in line_list[i+1]:
                    line_list[i+1] = line_list[i+1].replace(',','.')
                line = '\t'.join([line_list[0],result_country,line_list[i],line_list[i+1],line_list[i+2]])
                fobj_2.write(line)
                num += 1
                break
            #try block
            except ValueError:
                continue
    #close two file
    fobj_1.close()
    fobj_2.close()
    #return num
    return num
#end


def notas(medias, sit=False):
    """
    Função que recebe as médias de uma turma e retorna uma análise sobre esses dados.
    :param medias: um ou mais valores do tipo Float
    :param sit: parâmetro opcional, se for True exibirá também a situação da turma
    :return: tipo dict, retorna um dicionário no formato: {'total': x, 'maior': x, 'menor': x, 'média': x, 'situação': x} (situacao é exibido ou não de acordo com o parâmetro sit)
    """
    maior = menor = cont = soma = 0
    for m in medias:
        num = float(m)
        if cont == 0:
            maior = menor = num
        else:
            if num > maior:
                maior = num
            if num < menor:
                menor = num
        soma += num
        cont += 1
    mediageral = round((soma / len(medias)), 2)
    if not sit:
        return {'total': soma, 'maior': maior, 'menor': menor, 'média': mediageral}
    else:
        if mediageral <= 3:
            situacao = 'PÉSSIMA'
        elif mediageral <= 5.9:
            situacao = 'RUIM'
        elif mediageral <= 7.9:
            situacao = 'BOA'
        else:
            situacao = 'EXCELENTE'
        return {'total': soma, 'maior': maior, 'menor': menor, 'média': mediageral, 'situação': situacao}

notasTurma = input('Digite as notas da turma:').split(', ')
exibirSituacao = input('Deseja exibir a situação? (S/N)') in 'Ss'
print(notas(notasTurma, exibirSituacao))


import numpy as np
import copy

tree_count = 0
with open('Day 8/input.txt') as f:
    lines = f.readlines()

tab_of_trees = copy.deepcopy(lines)
for i, line in enumerate(lines):
    tab_of_trees[i] = list(line.replace('\n', ''))

forrest = np.asarray(tab_of_trees)
forrest.reshape((99, 99))
chopped_forrest = copy.deepcopy(forrest)

def count_trees_y(forrest, chopped_forrest):
    for i, col in enumerate(forrest):
        tallest_tree = -1
        for j, tree in enumerate(forrest[:,i]):
            if int(tree) > tallest_tree:
                tallest_tree = int(tree)
                chopped_forrest[j][i] = 'x'

def count_trees_x(forrest, chopped_forrest):
    for i, col in enumerate(forrest):
        tallest_tree = -1
        for j, tree in enumerate(col):
            if int(tree) > tallest_tree:
                tallest_tree = int(tree)
                chopped_forrest[i][j] = 'x'

print(forrest)
count_trees_y(forrest, chopped_forrest)
count_trees_y(np.flipud(forrest), np.flipud(chopped_forrest))
count_trees_x(forrest, chopped_forrest)
count_trees_x(np.fliplr(forrest), np.fliplr(chopped_forrest))

for row in chopped_forrest:
    for tree in row:
        if tree == 'x':
            tree_count += 1
print(tree_count)
with open('Day 8/output.txt', 'w') as g:
    for line in chopped_forrest:
        g.write(str(''.join(line))+'\n')


from copy import deepcopy

def CheckNumberOfSolutions(board):
    """
    Check how many solutions the board has.

    returns: int (0: no solutions, 1: one solution, 2: many solutions)
    """
    # check if board has any errors
    for i in range(9):
        for j in range(9):
            cell = board[i][j]
            if cell == '.':
                continue
            col = board[i][:j] + board[i][j+1:]
            row = [board[k][j] for k in range(i)] + [board[k][j] for k in range(i+1, 9)]
            box = board[i//3*3:i//3*3+3][j//3*3:j//3*3+3]
            if cell in col or cell in row or cell in box:
                return 0

    # check if board is full
    isFull = True
    for i in range(9):
        for j in range(9):
            if board[i][j] == '.':
                isFull = False
                break
        if not isFull:
            break
    if isFull:
        return 1

    # check how many solutions board has
    # get the first empty cell
    cellI = 0; cellJ = 0
    for i in range(9):
        for j in range(9):
            if board[i][j] == '.':
                cellI = i; cellJ = j
                break
        if board[i][j] == '.':
            break

    # try all numbers from 1 to 9
    sols = 0
    for num in range(1, 10):
        newBoard = deepcopy(board)
        newBoard[cellI][cellJ] = num
        sols += CheckNumberOfSolutions(newBoard)
        if sols > 1:
            return 2

    # return the number of solutions
    return sols


# -*- coding: utf-8 -*-
"""
Created on Wed May 12 16:42:09 2021

@author: sun73
"""
from molvs import standardize_smiles
from rdkit import Chem
from tqdm import tqdm

import os
import argparse
import pubchempy as pcp
import time
import re
from chemspipy import ChemSpider
cs = ChemSpider('2CCdzprbsgWZAUh5N9yhJtsGOYNIoJiz')

def PCPconvert(name):
    s = pcp.get_compounds(name,'name')
    try:
        return s[0].canonical_smiles
    except:
        return 'None'

def ChemSpiderConvert(name):
    results = cs.search(name)
    time.sleep(0.3)
    if len(results) == 0:
        return 'None'
    return results[0].smiles

def SmilesWithoutIsotopesToSmiles(smiles):
    mol = Chem.MolFromSmiles(smiles)
    atom_data = [(atom, atom.GetIsotope()) for atom in mol.GetAtoms()]
    for atom, isotope in atom_data:
        if isotope:
            atom.SetIsotope(0)
    smiles = Chem.MolToSmiles(mol)
    for atom, isotope in atom_data:
        if isotope:
            atom.SetIsotope(isotope)
    return smiles

def cation_valence_check(name):
    if '(l' in name:
        start = name.find('(l') + 1
        end = name.find('l)') + 1
        name = list(name)
        for i in range(start, end):
            if name[i] == 'l': name[i] = 'I'

        return ''.join(name)
    else:
        return name

def hydrate_check(name):
    words = name.split(' ')
    for word in words:
        if 'hydrate' in word:
            new_words = words.copy()
            new_words.remove(word)
            return ' '.join(new_words)
    return name

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--input_dir',type=str,
                        default='../All_LCC_Data/processed_data_temp/unprocessed_class')
    parser.add_argument('--output_dir',type=str,
                        default='../All_LCC_Data/processed_data_temp/label_processed')
    args = parser.parse_args()
    os.makedirs(args.output_dir, exist_ok=True)

    f = open(os.path.join(args.input_dir, 'class_names_reagent.txt'), 'r')
    names = f.readlines()
    f.close()

    g = open(os.path.join(args.input_dir, 'class_names_reagent_smiles.txt'), 'r')
    smiles_ = g.readlines()
    g.close()

    reagent_list = []
    z = open(os.path.join(args.output_dir, 'class_names_reagent_emerge_backup.txt'), 'w')
    dup = 0
    for i in tqdm(range(len(names))):
        name_ = names[i].strip('\n')
        name = cation_valence_check(name_)
        name = re.sub('\?', '-', name)
        name = hydrate_check(name)
        smiles = smiles_[i].strip('\n')
        if (smiles == '') or ('hydrate' in name_): # remove "hydrate" in the reagent name
            smiles = PCPconvert(name)
            if (('palladium' in name) and (('carbon' in name) or ('charcoal' in name))) or ('Pd/C' in name):
                smiles = 'C.[Pd]'
            elif smiles == 'None':
                smiles = ChemSpiderConvert(name)
        if smiles != 'None':
            try:
                smiles = SmilesWithoutIsotopesToSmiles(smiles)
                smiles = standardize_smiles(smiles)
            except:
                pass
            if smiles in reagent_list:
                print('\nDuplicate: ')
                print(name, smiles)
                dup += 1
            else:
                reagent_list.append(smiles)

        z.write(name_+'\t'+smiles+'\n')
    print('Total Duplicate Reagent Number: ',dup)
    z.close()

    f = open(os.path.join(args.input_dir, 'class_names_solvent.txt'), 'r')
    names = f.readlines()
    f.close()

    g = open(os.path.join(args.input_dir, 'class_names_solvent_smiles.txt'), 'r')
    smiles_ = g.readlines()
    g.close()

    print('--------------------------------------------')
    solvent_list = []
    dup = 0
    z = open(os.path.join(args.output_dir, 'class_names_solvent_emerge_backup.txt'), 'w')
    for i in tqdm(range(len(names))):
        name = names[i].strip('\n')
        name = re.sub('\?', '-', name)
        smiles = smiles_[i].strip('\n')
        if smiles == '':
            smiles = PCPconvert(name)
            if smiles == 'None':
                smiles = ChemSpiderConvert(name)
        if smiles != 'None':
            try:
                smiles = SmilesWithoutIsotopesToSmiles(smiles)
                smiles = standardize_smiles(smiles)
            except:
                pass
            if smiles in solvent_list:
                print('Duplicate: ')
                print(name, smiles)
                dup += 1
            else:
                solvent_list.append(smiles)
        z.write(name+'\t'+smiles+'\n')
    z.close()
    print('Total Duplicate Solvent Number: ',dup)


#! venv/bin/python
#_*_ encoding:utf-8 _*_
"""
@Python -V: 3.X
@SoftWave: Pycharm
@OS: Ubuntu
@Author: SKYNE
@Contact: 520@skyne.cn
@Time: 2018.4.1
"""

def bubbleSort(arr):
    bubble = [0] * (max(arr) - min(arr) + 1)

    for i in range(len(arr)):
        bubble[arr[i] - min(arr)] += 1

    result = []

    for i in range(len(bubble)):
        if bubble[i] != 0:
            result += [i + min(arr)] * bubble[i]

    return result

if __name__ == '__main__':

    from random import randint

    arr = []

    for i in range(10):
        arr.append(randint(1, 9999))

    print("The old array is {}".format(arr))

    result = bubbleSort(arr)

    print("The new array is {}".format(result))


import numpy as np
import cv2
from matplotlib import pyplot as plt

def compareHistograms(h1, h2):
    return cv2.compareHist(h1, h2, 1)

def getHist(s, xmax):
    xmin = 0
    #xmax = 256#65536
    step = 1
    values, bin_edges = np.histogram(s, np.linspace(2, xmax, (xmax-xmin)/step))
    values = np.float32(values)
    #values.convertTo(values, cv2.CV_32F);
    return values, bin_edges
    '''
    nbins = values.size
    plt.bar(bin_edges[:-1], values, width=bin_edges[1]-bin_edges[0], color='red', alpha=0.5)
    #plt.xlim(1,256)
    plt.ylim(0,8000)
    plt.hist(s, bins=nbins, alpha=0.5)
    '''
def showHist(s, values, bin_edges):
    nbins = values.size
    plt.bar(bin_edges[:-1], values, width=bin_edges[1]-bin_edges[0], color='red', alpha=0.5)
    #plt.xlim(1,256)
    plt.ylim(0,8000)
    plt.hist(s, bins=nbins, alpha=0.5)
    plt.show()

'''
def show(title):
    plt.suptitle(title)
    plt.show()
'''


from gherkin.parser import Parser as GherkinParser
import six

from .exceptions import StepException, UnknownStepException
from . import utils

if six.PY3:
    from importlib import reload
    from importlib.machinery import SourceFileLoader
else:
    from imp import load_source, reload

class Feature:
    def __init__(self, feature_dict, tester):
        self.tester = tester

        self.name = feature_dict['name']
        self.tags = [tag['name'][1:] for tag in feature_dict['tags']]

        self.tests = [Test(test_dict, self)
                      for test_dict in feature_dict['children']]

    def __str__(self):
        return self.name

    def __repr__(self):
        return '<{} ({})>'.format(self.__class__.__name__, str(self))

class Test:
    def __init__(self, test_dict, feature):
        self.feature = feature

        self.name = test_dict['name']
        self.tags = [tag['name'][1:] for tag in test_dict['tags']]

        self.steps = []
        step_type = 'given'
        for step_dict in test_dict['steps']:
            if step_dict['keyword'].lower().strip() == 'then':
                step_type = 'then'
            self.steps.append(Step(step_dict, step_type, self))

    def __str__(self):
        return self.name

    def __repr__(self):
        return '<{} ({})>'.format(self.__class__.__name__, str(self))

    def loop(self, obj, steps, *args, **kwargs):
        for idx, step in enumerate(steps):
            try:
                obj = step(obj, *args, **kwargs)
            except StepException as explain:
                if step.step_type == 'then':
                    return False, explain
                else:
                    # failed conditional i.e. not relevant
                    return None, explain
            if step.loop:
                for o in obj:
                    o_result, o_explain = self.loop(
                        o, steps[idx + 1:], *args, **kwargs)
                    if not o_result:
                        return o_result, o_explain
                return True, None
        return True, None

    def __call__(self, obj, *args, **kwargs):
        def output(res, msg):
            if kwargs.get('bdd_verbose'):
                return res, msg
            return res

        context = dict(kwargs)
        if 'bdd_verbose' in context:
            del context['bdd_verbose']

        res, msg = self.loop(obj, self.steps, *args, **context)
        return output(res, msg)

class Step:
    def __init__(self, step_dict, step_type, test):
        def _find_matching_expr(line):
            for regex, fn, loop in test.feature.tester.store.values():
                r = regex.match(line)
                if r:
                    return fn, loop, r.groups()
            msg = 'I didn\'t understand "{}"'.format(line)
            raise UnknownStepException(msg)

        self.test = test

        self.text = step_dict['text']
        self.step_type = step_type
        match = _find_matching_expr(self.text)
        self.expr_fn, self.loop, self.expr_groups = match

    def __str__(self):
        return '{} {}'.format(self.step_type.title(), self.text)

    def __repr__(self):
        return '<{} ({})>'.format(self.__class__.__name__, str(self))

    def __call__(self, *args, **kwargs):
        if self.expr_groups:
            args = args + self.expr_groups
        return self.expr_fn(*args, **kwargs)

class BDDTester:
    def __init__(self, step_path):
        self._load_step_definitions(step_path)
        self.gherkinparser = GherkinParser()

    def _load_step_definitions(self, filepath):
        reload(utils)
        if six.PY3:
            SourceFileLoader('', filepath).load_module()
        else:
            load_source('', filepath)
        self.store = dict(utils.store)

    def load_feature(self, feature_filepath):
        with open(feature_filepath) as f:
            feature_txt = f.read()
        return self._gherkinify_feature(feature_txt)

    def _gherkinify_feature(self, feature_txt):
        feature_dict = self.gherkinparser.parse(feature_txt)['feature']
        return Feature(feature_dict, self)


from tests.integration.integration_test_case import IntegrationTestCase
from tests.integration.questionnaire import SUBMIT_URL_PATH, THANK_YOU_URL_PATH

class TestQuestionnairePreviousLink(IntegrationTestCase):
    def test_previous_link_doesnt_appear_on_introduction(self):
        # Given
        self.launchSurvey("test_submit_with_custom_submission_text")
        # When we open the introduction
        # Then previous link does not appear
        self.assertNotInBody("Previous")

    def test_previous_link_appears_on_the_submit_page(self):
        # Given
        self.launchSurvey("test_submit_with_custom_submission_text")

        # When we proceed through the questionnaire
        self.post(action="start_questionnaire")
        self.assertInBody("Previous")
        self.post({"breakfast-answer": "Bacon"})
        self.assertInUrl(SUBMIT_URL_PATH)
        self.assertInBody("Previous")

    def test_previous_link_appears_on_the_submit_page_with_summary(self):
        # Given
        self.launchSurvey("test_submit_with_summary")

        # When we proceed through the questionnaire
        self.post()
        self.post({"dessert-answer": "Cake"})
        self.post({"dessert-confirmation-answer": "Yes"})
        self.post()
        self.assertInUrl(SUBMIT_URL_PATH)
        self.assertInBody("Previous")

    def test_previous_link_doesnt_appear_on_thank_you(self):
        # Given
        self.launchSurvey("test_submit_with_custom_submission_text")

        # When ee proceed through the questionnaire
        self.post(action="start_questionnaire")
        self.post({"breakfast-answer": "Eggs"})
        self.post()
        self.assertInUrl(THANK_YOU_URL_PATH)
        self.assertNotInUrl("Previous")

    def test_previous_link_appears_on_questions_preceded_by_another_question(self):
        # Given a survey with multiple questions
        self.launchSurvey("test_checkbox")

        # When I answer a question
        self.assertInUrl("mandatory-checkbox")
        self.post({"mandatory-checkbox-answer": "None"})

        # Then there should be a previous link on the current page
        self.assertInBody("Previous")

    def test_previous_link_appears_on_the_first_question_preceded_by_the_hub(self):
        # Given a survey with a hub enabled
        self.launchSurvey("test_hub_and_spoke")

        # When I answer go to the first question in a section
        self.assertInUrl("/")
        self.post()

        # Then there should be a previous link on the current page
        self.assertInBody("Previous")


#!/usr/bin/env python3

#Input is a csv file in format supplied by co-operative bank
#Output is a csv file in format required by YNAB 4

# Input file is selected by the user at runtime via a GUI
# Output file location may be passed as an argument

from sys import exit
from sys import argv
import csv
from tkinter import Tk
from tkinter.filedialog import askopenfilename
import tkinter.messagebox
import re
import datetime
import os.path
import csv

#Initialise variables
firstdatestr = '02/09/2016'
oldlinecount = 0
visaformat = False

#Set output file name
if len(argv) == 2:
    outfilepath = argv[1]
else: outfilepath = 'ynab.csv'

#Get input file name
tkinter.Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
# show an "Open" dialog box and return the path to the selected file
filename = askopenfilename(filetypes=[("CSV files","*.csv")],initialdir = 'C:/Users/Paul/Downloads/')

# Get from user the date of the first record to be processed
firstdatestr=input('From date in dd/mm/yyyy: ')
firstdateobj = datetime.datetime.strptime(firstdatestr, '%d/%m/%Y')

#open the input
try:
    infile = open(filename, "r")
    infile.close
except:
    print("Can't open file at",filename)

#open the output
try:
    outfile = open(outfilepath, "wb")
    outfile.close
except:
    print("Can't open file at",outfilepath)

# In python2 a b for binary mode prevents an extra return in the row terminator
# removed in python 3
with open (outfilepath,'w', newline='') as outfile:
    outwriter = csv.writer(outfile,)
    with open(filename) as csvfile:
        statement = csv.reader(csvfile, delimiter=',',quotechar='|', quoting=csv.QUOTE_MINIMAL,lineterminator='')
        linecount = 0
        for entry in statement:
            linecount = linecount + 1
            try:
                date = entry[0]
                description = entry[1]
                transactiontype = entry[2]
                income = entry[3]
                expense = entry[4]
                balance = entry[5]
            except:
                try:
                    # Visa format
                    date = entry[0]
                    description = entry[1]
                    transactiontype = ""
                    income = entry[2]
                    expense = entry[3]
                    balance = ""
                    visaformat = True
                except:
                    print("file format looks wrong")
                    exit(0)
            if linecount == 1:
                #check the file format
                if ((date == "Date") and (description == "Description")):#	Category	Memo	Money In	 Money Out	 Balance
                    #write the header
                    header = ['Date','Payee','Category','Memo','Outflow','Inflow']
                    outwriter.writerow(header)
                else:
                    print("file header looks wrong")
                    exit(0)
            else:
                #this is a data line, check date format
                if re.search(r'/[0-9][0-9]\/[0-9][0-9]\/20[0-9][0-9]/', date):
                    print("The date format is not supported at line %s , should be DD/MM/YYYY", linecount)
                #this is a valid transaction line
                # is line too old?
                try:
                    dateobj = datetime.datetime.strptime(date, '%Y-%m-%d')
                except:
                    #maybe the file was saved as csv from Excel
                    try:
                        dateobj = datetime.datetime.strptime(date, '%d/%m/%Y')
                    except:
                        print('Could not convert date', linecount, date)
                        continue
                if dateobj < firstdateobj:
                    #skip line
                    if oldlinecount == 0:
                        print('Line is too old', linecount,date)
                    oldlinecount = oldlinecount + 1
                    continue
                if transactiontype=="CHEQUE":
                    description = "Cheque Number " + description
                if transactiontype=="ATM":
                    transactiontype = description
                    description = "Transfer:Cash"
                if visaformat:
                    if expense != '':
                        expense = float(expense)*(-1)

                outline = [dateobj.strftime('%d/%m/%Y'),description,'',transactiontype,expense,income]
                print(linecount,outline)
                outwriter.writerow(outline)

print('found this many old lines',oldlinecount)
print('output sent to',outfilepath)


#!/usr/bin/env python
# coding: utf-8

# In[2]:

import urllib.request
from bs4 import BeautifulSoup as bs
import pandas as pd

def hollys_store(result):
    for page in range(1, 53):
        Hollys_url = "https://www.hollys.co.kr/store/korea/korStore2.do?pageNo=%d&sido=&gugun=&store="% page

        html = urllib.request.urlopen(Hollys_url)
        soupHollys = bs(html, 'html.parser')

        tag_tbody = soupHollys.find("tbody")
        for store in tag_tbody.find_all('tr'):
            store_td = store.find_all('td')
            s_name = store_td[1].text
            s_sido = store_td[0].string
            s_address = store_td[3].string
            s_phone = store_td[5].string

            result.append([s_name, s_sido, s_address, s_phone])

    return

def main():
    result = []
    print("Hollys store crawling >>>>>>>>>>>>>>>>>>>>>>>>")
    hollys_store(result)
    print(">>>")
    hollys_df = pd.DataFrame(result, columns=('store', 'si-do-gu', 'address',' phone'))
    hollys_df.to_csv('hollys.csv', encoding='cp949', mode='w', index=True)

if __name__ == '__main__':
    main()