"""
Module to compute centroidal voronoi tesselation mesh from an existing mesh of
convex cells.

In principle, this is easy to compute:

* Compute the centroids of the cells.
* Invert the face_node_connectivity index array.
* For every node, find the connected faces.
* Use the connected faces to find the centroids.
* Order the centroids around the vertex in a counter-clockwise manner.

Dealing with the mesh exterior (beyond which no centroids are located) is the
tricky part. Refer to the docstrings and especially the visual examples in the
developer documentation.
"""
from typing import Tuple

import numpy as np
import pandas as pd
from scipy import sparse

from xugrid.constants import X_EPSILON, FloatArray, IntArray
from xugrid.ugrid.connectivity import renumber

def dot_product2d(U: FloatArray, V: FloatArray):
    return U[:, 1] * V[:, 1] + U[:, 0] * V[:, 0]

def _centroid_pandas(i: IntArray, x: FloatArray, y: FloatArray):
    grouped = pd.DataFrame({"i": i, "x": x, "y": y}).groupby("i").mean()
    x_centroid = grouped["x"].values
    y_centroid = grouped["y"].values
    return x_centroid, y_centroid

def _centroid_scipy(i: IntArray, x: FloatArray, y: FloatArray):
    j = np.arange(len(i))
    coo_content = (x, (i, j))
    mat = sparse.coo_matrix(coo_content)
    n = mat.getnnz(axis=1)
    x_centroid = mat.sum(axis=1).flat / n
    mat.data = y
    y_centroid = mat.sum(axis=1).flat / n
    return x_centroid, y_centroid

def compute_centroid(i: IntArray, x: FloatArray, y: FloatArray):
    return _centroid_pandas(i, x, y)

def exterior_centroids(node_face_connectivity: sparse.csr_matrix):
    n, _ = node_face_connectivity.shape
    # Find exterior nodes NOT associated with any interior edge
    is_exterior_only = node_face_connectivity.getnnz(axis=1) == 1
    j = node_face_connectivity[is_exterior_only].indices
    i = np.arange(n)[is_exterior_only]
    return i, j

def interior_centroids(
    node_face_connectivity: sparse.csr_matrix,
    edge_face_connectivity: IntArray,
    edge_node_connectivity: IntArray,
    fill_value: int,
):
    # Find exterior nodes associated with interior edges
    is_exterior = edge_face_connectivity[:, 1] == fill_value
    exterior_nodes = np.unique(edge_node_connectivity[is_exterior].ravel())
    m_per_node = node_face_connectivity.getnnz(axis=1)
    is_interior_only = m_per_node > 1

    selected_nodes = exterior_nodes[is_interior_only[exterior_nodes]]
    selection = node_face_connectivity[selected_nodes]
    m_per_selected_node = selection.getnnz(axis=1)

    j = selection.indices
    i = np.repeat(selected_nodes, repeats=m_per_selected_node)
    return i, j

def exterior_vertices(
    edge_face_connectivity: IntArray,
    edge_node_connectivity: IntArray,
    fill_value: int,
    vertices: FloatArray,
    centroids: FloatArray,
    add_vertices: bool,
):
    is_exterior = edge_face_connectivity[:, 1] == fill_value
    exterior_nodes = edge_node_connectivity[is_exterior]
    # For every exterior node, project the centroids to exterior edges
    edge_vertices = vertices[exterior_nodes]
    face_i = edge_face_connectivity[is_exterior, 0]
    centroid_vertices = centroids[face_i]
    a = edge_vertices[:, 0, :]
    b = edge_vertices[:, 1, :]
    V = b - a
    U = centroid_vertices - a
    # np.dot(U, V) doesn't do the desired thing here
    projected_vertices = a + ((dot_product2d(U, V) / dot_product2d(V, V)) * V.T).T

    # Create the numbering pointing to these new vertices.
    # Discard vertices that overlap with e.g. circumcenters.
    keep = np.linalg.norm(projected_vertices - centroid_vertices, axis=1) > (
        X_EPSILON * X_EPSILON
    )
    face_i = face_i[keep]
    vertices_keep = projected_vertices[keep]
    n_centroid = len(centroids)
    i_keep = exterior_nodes[keep].ravel()
    n = n_centroid + len(vertices_keep)
    j_keep = np.repeat(np.arange(n_centroid, n), 2)
    n_interpolated = 0

    # We add a substitution value for the actual vertex
    if add_vertices:
        n_new = len(projected_vertices)
        i = exterior_nodes.ravel()
        order = np.argsort(i)
        jj = np.repeat(np.arange(n_new), 2)[order]
        to_interpolate = projected_vertices[jj]
        interpolated = 0.5 * (to_interpolate[::2] + to_interpolate[1::2])
        n_interpolated = len(interpolated)
        i_keep = np.concatenate([i_keep, i[order][::2]])
        j_keep = np.concatenate([j_keep, np.arange(n, n + n_interpolated)])
        vertices_keep = np.concatenate([vertices_keep, interpolated])
        # Create face index: the face of the original mesh associated with every
        # voronoi vertex is a centroid. The exterior vertices are an exception to
        # this: these are associated with two faces. So we set a value of -1 here.
        face_i = np.concatenate([face_i, np.full(n_interpolated, -1)])

    return i_keep, j_keep, vertices_keep, face_i, n_interpolated

def exterior_topology(
    edge_face_connectivity: IntArray,
    edge_node_connectivity: IntArray,
    node_face_connectivity: sparse.csr_matrix,
    fill_value: int,
    vertices: FloatArray,
    centroids: FloatArray,
    add_vertices: bool,
):
    """
    The exterior topology of this voronoi tesselation consists of three kinds
    of vertices:

    * Centroids of faces that have a vertex located on the exterior, but have
      no exterior edges. These centroids are used twice in the resulting
      voronoi mesh topology.
    * Centroids of faces that have an exterior edge. These centroids are used
      once.
    * Vertices of the intersection of (infinite) rays with the mesh exterior.
      These vertices are used twice; these intersections are the orthogonal
      projection of the centroid of the face on its exterior edges.
    * Original vertices of the mesh exterior. These vertices are used once, and
      are always located in between the projected vertices.

    The last ones are trickiest, as they may create concave angles; with a
    concave angle in a polygon, we cannot easily compute the counter clockwise
    order of the vertices to form a polygon. However, since these vertices are
    always located in between the projected vertices, we can introduce a
    subsitute: a linear interpolation of the two projected vertices. We
    can then utilize this interpolated vertex to compute the counter clockwise
    order, and then replace it by the original vertex -- which then may
    introduce a concave angle.

    A note on the index arrays:

    * i refers to the node number of the original mesh.
    * In principle, j refers to the face number (and associated centroids) of
    the original mesh; exterior vertices require new numbers.

    Finally, in the resulting new (voronoi) face_node_connectivity, i becomes
    the face number, and j becomes the node number.
    """
    i0, j0 = interior_centroids(
        node_face_connectivity,
        edge_face_connectivity,
        edge_node_connectivity,
        fill_value,
    )
    i1, j1 = exterior_centroids(node_face_connectivity)
    i2, j2, projected_vertices, face_i, n_interpolated = exterior_vertices(
        edge_face_connectivity,
        edge_node_connectivity,
        fill_value,
        vertices,
        centroids,
        add_vertices,
    )

    i = np.concatenate([i0, i1, i2])
    j = np.concatenate([j0, j1, j2])
    _, n_face = node_face_connectivity.shape
    vor_vertices = np.concatenate([centroids, projected_vertices])
    face_i = np.concatenate([np.arange(n_face), face_i])
    orig_vertices = vertices[i][-n_interpolated:]

    # Now form valid counter-clockwise polygons
    voronoi_vertices = vor_vertices[j]
    x = voronoi_vertices[:, 0]
    y = voronoi_vertices[:, 1]
    centroid_x, centroid_y = compute_centroid(i, x, y)
    renumbered_i = renumber(i)
    dx = x - centroid_x[renumbered_i]
    dy = y - centroid_y[renumbered_i]
    angle = np.arctan2(dy, dx)
    # Sort to create a counter clockwise oriented polygon.
    # Use a lexsort to make sure nodes are grouped together.
    order = np.lexsort((angle, i))
    i = i[order]
    j = j[order]

    # If add_vertices is True, we have substituted interpolated points before
    # to generate the proper ordering. We overwrite those substituted points
    # here by their possibly concave true vertices.
    if add_vertices:
        vor_vertices[-n_interpolated:] = orig_vertices

    return vor_vertices, i, j, face_i

def voronoi_topology(
    node_face_connectivity: sparse.csr_matrix,
    vertices: FloatArray,
    centroids: FloatArray,
    edge_face_connectivity: IntArray = None,
    edge_node_connectivity: IntArray = None,
    fill_value: int = None,
    add_exterior: bool = False,
    add_vertices: bool = False,
) -> Tuple[FloatArray, sparse.csr_matrix]:
    """
    Compute the centroidal voronoi tesslation (CVT) of an existing mesh of
    (convex!) cells using connectivity index arrays.

    If the exterior boundary of the mesh forms a concave polygon, this will
    result in some concave voronoi cells as well. Since concave cells are often
    undesirable, there are three options for dealing with the exterior
    boundary:

    * if ``add_exterior=True`` and ``add_vertices=True``, infinite voronoi rays
      (projections) are intersected at exterior edges and all exterior vertices
      are included. If the mesh exterior forms a concave polygon, the resulting
      tesselation will contain concave cells as well.
    * if ``add_exterior=True`` and ``add_vertices=False``, the infinite voronoi
      rays are intersected, but no exterior vertices are included. This will
      always result in convex voronoi cells if the original cells are convex.
    * if ``add_exterior=False`` and ``add_vertices=False``, no vertices on the
      exterior edges are considered. Only centroids of the original mesh are
      considered. This will always result in convex voronoi cells if the
      original cells are convex.

    A direct correspondence exists between the voronoi vertices and the
    original faces: the vertices of the voronoi polygons are the centroids of
    the original faces; and the intersected rays "belong" to a single face too.
    This is not the case when all exterior vertices are included: these may
    correspond to multiple faces of the original mesh. These vertices are
    marked by a face_index of -1.

    Parameters
    ----------
    node_face_connectivity : csr matrix
    vertices: ndarray of floats with shape ``(n_vertex, 2)``
    centroids: ndarray of floats with shape ``(n_centroid, 2)``
    edge_face_connectivity: ndarray of integers with shape ``(n_edge, 2)``, optional
    edge_node_connectivity: ndarray of integers with shape ``(n_edge, 2)``, optional
    fill_value: int, optional
        Fill value for edge_face_connectivity.
    add_exterior: bool, optional
        Whether to consider exterior edges of the original mesh, or to consider
        exclusively centroids.
    add_vertices: bool, optional
        Whether to use existing exterior vertices.

    Returns
    -------
    nodes: ndarray of floats with shape ``(n_vertex, 2)``
    face_node_connectivity: scipy.sparse.csr_matrix
    face_index: ndarray of ints with shape ``(n_vertex,)``
        Connects the nodes of the voronoi topology to the faces of the original
        grid. Exterior vertices (when ``add_vertices=True``) are given an index
        of -1.
    """
    if add_exterior:
        if any(
            arg is None
            for arg in [edge_face_connectivity, edge_node_connectivity, fill_value]
        ):
            raise ValueError(
                "edge_face_connectivity, edge_node_connectivity, fill_value "
                "must be provided if add_exterior is True."
            )

    # Avoid overlapping polygons: if exterior is included, the exterior
    # algorithm will construct those polygons. If exterior is not included, we
    # take any valid internal polygon we can construct: at least a triangle.
    ncol_per_row = node_face_connectivity.getnnz(axis=1)
    if add_exterior:
        is_exterior = edge_face_connectivity[:, 1] == fill_value
        exterior_nodes = edge_node_connectivity[is_exterior]
        valid = np.full(len(vertices), True)
        valid[exterior_nodes.ravel()] = False
        valid = np.repeat(valid, ncol_per_row)
    else:
        valid = np.repeat(ncol_per_row >= 3, ncol_per_row)

    # Grab the centroids for all these faces.
    coo = node_face_connectivity.tocoo()
    node_i = coo.row[valid]
    face_i = coo.col[valid]
    voronoi_centroids = vertices[node_i]
    voronoi_vertices = centroids[face_i]
    # Compute the angle between voronoi centroids and vertices.
    x = voronoi_vertices[:, 0] - voronoi_centroids[:, 0]
    y = voronoi_vertices[:, 1] - voronoi_centroids[:, 1]
    angle = np.arctan2(y, x)
    # Now sort to create a counter clockwise oriented polygon.
    # Use a lexsort to make sure nodes are grouped together.
    order = np.lexsort((angle, node_i))
    j = face_i[order]

    if add_exterior:
        vor_vertices, exterior_i, exterior_j, face_i = exterior_topology(
            edge_face_connectivity,
            edge_node_connectivity,
            node_face_connectivity,
            fill_value,
            vertices,
            centroids,
            add_vertices,
        )
        offset = node_i.max() + 1 if len(node_i > 0) else 0
        i = np.concatenate([node_i, exterior_i + offset])
        j = np.concatenate([j, exterior_j])
    else:
        vor_vertices = centroids[np.unique(face_i)]
        face_i = np.arange(face_i.max() + 1)
        i = node_i
        j = renumber(j)

    i = renumber(i)
    coo_content = (j, (i, j))
    face_node_connectivity = sparse.coo_matrix(coo_content)
    return vor_vertices, face_node_connectivity, face_i


# Exercises for 17/03/20

# Exercise 1: Sort the numbers from the original list into even and odd numbers and insert into new lists
list = [10, 111, 24, 56, 78, 75, 65, 80]

even_list = []
odd_list = []

for number in list:
    if number % 2 == 0:
        even_list.append(number)
    else:
        odd_list.append(number)

print(even_list)
print(odd_list)

# Exercise 2: Giving the description for a film rating
film_rating = input("What is the film rating? ")

if film_rating == "universal":
    print("all age groups can watch this film")
elif film_rating == "pg":
    print("General viewing, but some scenes may be unsuitable for young children.")
elif film_rating == "12" or film_rating == "12a":
    print("Films classified 12A and video works classified 12 contain material that is not generally suitable for children aged under 12. No one younger than 12 may see a 12A film in a cinema unless accompanied by an adult.")
elif film_rating.lower() == "15":
    print("No one younger than 15 may see a 15 film in a cinema.")
elif film_rating.lower() == "18":
    print("No one younger than 18 may see an 18 film in a cinema.")
else:
    print("this is not a correct rating, please use universal, pg, 12, 12a, 15, 18")

# Exercise 3: Fizzbuzz
number = int(input("Give me a number: "))

if number % 3 == 0 and number % 5 == 0:
    print("{} is a fizzbuzz number!".format(number))
elif number % 3 == 0:
    print("{} is a fizz number".format(number))
elif number % 5 == 0:
    print("{} is a buzz number!".format(number))
else:
    print("Unfortunately, {} is neither a fizz, buzz nor a fizzbuzz number!".format(number))


#!/usr/bin/env python
from .abstract_reader import AbstractReader
from Alfarvis.basic_definitions import DataType, ResultObject, CommandStatus, DataObject
from Alfarvis.commands.Stat_ListColumns import StatListColumns
from Alfarvis.commands.Stat_Container import StatContainer
from Alfarvis.printers import Printer
from Alfarvis.windows import PropertyEditor
import pandas as pd
import re
import numpy as np
from Alfarvis.Toolboxes.DataGuru import DataGuru

class ReadAlgo(AbstractReader):

    @classmethod
    def data_type(self):
        return DataType.algorithm_arg

    def createProperties(self, file_path):
        data = pd.read_csv(file_path)
        properties = {}
        for column in data.columns:
            if column == 'Model':
                continue
            column_data = data[column][0]
            if column_data == 'TRUE':
                column_data = True
            elif column_data == 'False':
                column_data = False
            elif column_data == None:
                column_data = "None"
            properties[str(column)] = column_data
        return properties, str(data['Model'][0])

    def updateModel(self, result_data):
        properties = result_data[1]
        model_name = result_data[2]
        print("Properties: ", properties)
        result_data[0] = DataGuru.createModel(properties, model_name)

    def read(self, file_path, keyword_list):
        try:
            property_data, model_name = self.createProperties(file_path)
            model = DataGuru.createModel(property_data, model_name)
        except:
            Printer.Print("File not found")
            return ResultObject(None, None, None, CommandStatus.Error)

        command_status = CommandStatus.Success
        result_data = [model, property_data, model_name, self.updateModel]
        result_object = ResultObject(
            result_data, keyword_list, DataType.algorithm_arg, command_status,
            add_to_cache=True)
        result_object.createName(keyword_list)

        if (PropertyEditor.parent_widget is None or
            PropertyEditor.property_editor_class is None):
            Printer.Print("Cannot modify algorithm properties in non-GUI mode")
        else:
            property_editor = PropertyEditor.property_editor_class(result_object)
            PropertyEditor.addPropertyEditor(property_editor)

        return result_object


a = "welcome"
b = "to"
c = "the"
d = "Hotel"
e = "California"

list1 = [d, e]
print ("list1 " + str(list1))

list2 = [a, b, c]
list3 = list1 + list2
print ("list3" + str(list3))

list4 = list3[4:1:-1]
print ("list4" + str(list4))
list5 = []
list4.reverse ()

for x in range (0, len(list4)):
    list5.append(list4[x])

list5.insert(3,list1)
print ("list5 " + str(list5))

f ="Plenty"
g ="of"
h ="room"
i ="at"

list6 = [f, g, h, i]
list6.append (c)
print ("list6 " + str(list6))

x = 0
list7 = []
for item in list3:
    if item[x] != "t":
        list7.append(item)
print ("list7 " + str(list7))

list8 = 2 * list6
list8.remove("at")
print ("list8" + str(list8))


'''
-Medium-

There are n points on a road you are driving your taxi on. The n points on the road are
labeled from 1 to n in the direction you are going, and you want to drive from point 1 to
point n to make money by picking up passengers. You cannot change the direction of the taxi.

The passengers are represented by a 0-indexed 2D integer array rides, where
rides[i] = [starti, endi, tipi] denotes the ith passenger requesting a ride from point
start_i to point end_i who is willing to give a tip_i dollar tip.

For each passenger i you pick up, you earn endi - starti + tipi dollars. You may only
drive at most one passenger at a time.

Given n and rides, return the maximum number of dollars you can earn by picking up the
passengers optimally.

Note: You may drop off a passenger and pick up a different passenger at the same point.

Example 1:

Input: n = 5, rides = [[2,5,4],[1,5,1]]
Output: 7
Explanation: We can pick up passenger 0 to earn 5 - 2 + 4 = 7 dollars.
Example 2:

Input: n = 20, rides = [[1,6,1],[3,10,2],[10,12,3],[11,12,2],[12,15,2],[13,18,1]]
Output: 20
Explanation: We will pick up the following passengers:
- Drive passenger 1 from point 3 to point 10 for a profit of 10 - 3 + 2 = 9 dollars.
- Drive passenger 2 from point 10 to point 12 for a profit of 12 - 10 + 3 = 5 dollars.
- Drive passenger 5 from point 13 to point 18 for a profit of 18 - 13 + 1 = 6 dollars.
We earn 9 + 5 + 6 = 20 dollars in total.

Constraints:

1 <= n <= 10^5
1 <= rides.length <= 3 * 10^4
rides[i].length == 3
1 <= start_i < end_i <= n
1 <= tip_i <= 10^5

'''

from typing import List
from collections import defaultdict
from bisect import bisect_left
class Solution:
    def maxTaxiEarnings(self, n: int, rides: List[List[int]]) -> int:
        rideStartAt = defaultdict(list)
        for s, e, t in rides:
            rideStartAt[s].append([e, e - s + t])  # [end, dollar]

        dp = [0] * (n + 1)
        for i in range(n - 1, 0, -1):
            for e, d in rideStartAt[i]:
                dp[i] = max(dp[i], dp[e] + d)
            dp[i] = max(dp[i], dp[i + 1])

        return dp[1]

    def maxTaxiEarnings2(self, n, rides):
        rides = sorted(rides)
        S = [i[0] for i in rides]

        m = len(rides)
        dp = [0]*(m+1)
        # dp[i] is the max earning starting at i-th ride
        # base case: dp[m] = 0 (zero earnings)
        # work backwards
        for k in range(m-1, -1, -1):
            s,e,t = rides[k]
            temp = bisect_left(S, e) # the ride which start at temp has eranings dp[temp]
            dp[k] = max(dp[k+1], e - s + t + dp[temp]) # earning at ride k

        return dp[0]

if __name__ == "__main__":
    print(Solution().maxTaxiEarnings(5, [[2,5,4],[1,5,1]]))
    print(Solution().maxTaxiEarnings2(5, [[2,5,4],[1,5,1]]))


from tkinter import *
import pandas
from random import choice

BACKGROUND_COLOR = "#B1DDC6"

current_card={} # create empty dict
learning_words = {} # initial learrning words

#--------------------brain ------------------------------------

try:
    data_df = pandas.read_csv("data/words_to_learn.csv")
except FileNotFoundError: # if running for first time read from origninal french words data
    original_data = pandas.read_csv("data/french_words.csv")
    learning_words = original_data.to_dict(orient="records")
else:

    learning_words = data_df.to_dict(orient="records")
# this creates a list [{french:word,english:meaning},...]

def card_next():
    global current_card,timer_flip
    window.after_cancel(timer_flip) # cancel the timer when card is clicked
    current_card = choice(learning_words) #
    canvas.itemconfig(title,text = "French",fill="black")
    canvas.itemconfig(word,text = current_card["French"],fill="black")
    canvas.itemconfig(background,image=front_image)
    timer_flip = window.after(3000,func =card_flip) # set up new flip timer to wait for 3 secs

def card_flip():
    canvas.itemconfig(title,text = "English", fill="white")
    canvas.itemconfig(word,text = current_card["English"],fill="white")
    canvas.itemconfig(background,image=back_image)

def known_words():
    learning_words.remove(current_card)
    data = pandas.DataFrame(learning_words)
    data.to_csv("data/words_to_learn.csv",index=False)
    # index is false to avoid multiple columns of indexes being created each time the function is run
    card_next()

#--------------------UI Interface------------------------------------

window = Tk()
window.title("Flash cards")
window.config(padx = 50, pady=50, bg=BACKGROUND_COLOR)

#auto flip
timer_flip = window.after(3000,func =card_flip) # run the cardflip after 3 seconds

# Canvas
canvas = Canvas(width=800,height=526,bg=BACKGROUND_COLOR,highlightthickness=0)
front_image = PhotoImage(file="images/card_front.png")
back_image = PhotoImage(file="images/card_back.png")
background = canvas.create_image(400,263,image=front_image)

title = canvas.create_text(400,150,text="",font=("Ariel",40,"italic"))

word = canvas.create_text(400,263,text="",font=("Ariel",60 ,"bold"))
canvas.grid(column=0,row=0, columnspan=2)

# buttons
wrong_image = PhotoImage(file="images/wrong.png")
unknown_button = Button(image=wrong_image,highlightthickness=0,command=card_next)
unknown_button.grid(column=0, row=1)

right_image = PhotoImage(file="images/right.png")
known_button = Button(image=right_image,highlightthickness=0,command=known_words)
known_button.grid(column=1, row=1)

card_next()

window.mainloop()


# 클래스 상속
# 부모클래스로 부터 변수, 함수들을 물려받아 새로운 클래스를 만드는 과정
# 한번 정의된 데이터유형(함수,클래스)을 필요에 따라 다시 재활용해서 반복되는 코드를 줄일수 있음
# 상속의 장점 - 중복코드 배제, 유지보수 용이, 통일성 유지, 다형성 구현 용이

# class 클래스이름(부모클래스)

# 스타크래프트 유닛을 상속개념을 이용해서 구현
# 테란 진영 유닛을 클래스로 작성
# 해병대, 의무관, 화염방사병
#

# class 해병대:  # 공격력 10인 유닛
#     def __init__(self, life, energy, attack):
#         self.name = self.__class__.name
#         self.life = life
#         self.energy = energy
#         self.attack = 10
#
#     def __str__(self):
#         msg = '%s %s %s %s' % \
#               (self.name, self.life, self.energy, self.attack)
#         return msg
#     def attack(self):
#         print('플라즈마 소총으로 공격중')
#
#
# class 의무관:  # 공격력 1인 유닛
#     def __init__(self, life, energy, attack):
#         self.name = self.__class__.name
#         self.life = life
#         self.energy = energy
#         self.attack = 1
#
#     def __str__(self):
#         msg = '%s %s %s %s' % \
#               (self.name, self.life, self.energy, self.attack)
#         return msg
#
#     def heal(self):
#         print('지정한 유닛을 치료중')
#
#
# class 화염방사병:  # 공격력 20인 유닛
#     def __init__(self, life, energy, attack):
#         self.name = self.__class__.name
#         self.life = life
#         self.energy = energy
#         self.attack = 20
#
#     def __str__(self):
#         msg = '%s %s %s %s' % \
#               (self.name, self.life, self.energy, self.attack)
#         return msg
#
#     def attack(self):
#         print('화염방사기로 공격중')

class unit:  # 테란 유닛의 조상클래스
    def __init__(self, life, energy):
        self.name = self.__class__.__name__
        self.life = life
        self.energy = energy

    def __str__(self):
        msg = '%s %s %s' % \
              (self.name, self.life, self.energy)
        return msg
    def attack(self):
        pass

class marine(unit):
    def __init__(self,life,energy):
        super().__init__(life,energy)  # 부모클래스에 생성된 생성자를 호출
        self.power =10

    def __str__(self):
        # 메서드 오버라이딩 : 함수 재정의
        # 상속관계에 있어서 부모 클래스에서 정의된 함수를
        # 자식 클래스에 적합하도록 재작성하는 것을 의미
        msg = super().__str__()
        return ('%s %s') % (msg, self.power)

    def attack(self):
        print('플라즈마 소총으로 공격중')

marine1 = marine(100,100)
print(marine1)
marine1.attack()

class firebat(unit):

    def attack(self):
        print('화염방사기 공격중')

firebat1 = firebat(200,100)
print(firebat1)
firebat1.attack()

class medic(unit):

    def attack(self):
        print('치료중')

medic1 = medic(150,200)
print(medic1)
medic1.attack()

print()

# 성적 처리 프로그램에 상속개념을 적용해서 작성
# MidSungJuk - 이름, 국어, 영어, 수학, 총점, 평균, 학점
# FinalSungJuk - 이름, 국어, 영어, 수학, 과학, 미술, 총점, 평균, 학점

class SungJuk:
    def __init__(self, name, kor, eng, mat):
        self.name = self.__class__.__name__
        self.kor = kor
        self.eng = eng
        self.mat = mat
        self.tot = 0
        self.mean =0
        self.grd = '가'

    def __str__(self):
        msg = '성적결과 %s %s %s %s %s %s %s' % \
              (self.name,self.kor,self.eng,self.mat,self.tot,self.mean,self.grd)
        return msg

    def computeSungjuk(self):
        self.tot = self.kor + self.eng +self.mat
        self.mean = self.tot/3

    def computeGrade(self):
        print('학점 계산중')

class MidSungJuk(SungJuk):
    pass

sj1 = MidSungJuk('혜교',99,98,97)
sj1.computeSungjuk()
print(sj1)

class FinalSungJuk(SungJuk):
    def __init__(self, name, kor, eng, mat, sci, art):
        super().__init__(name,kor,eng,mat)
        self.sci = sci
        self.art = art

    def __str__(self):
        msg = super().__str__()
        msg = '%s %s %s' % (msg, self.sci, self.art)
        return msg

    def computeSungjuk(self):
        super().computeSungjuk()
        self.tot = self.tot + self.sci + self.art
        self.mean = self.tot / 5

sj2 = FinalSungJuk('지수',99,98,97,96,95)
sj2.computeSungjuk()
print(sj2)


def logs(ctx, past, follow, hide_time):
    """Get job logs.

    Uses [Caching](/references/polyaxon-cli/#caching)

    Examples:

    \b
    ```bash
    $ polyaxon job -j 2 logs
    ```

    \b
    ```bash
    $ polyaxon job logs
    ```
    """
    user, project_name, _job = get_job_or_local(ctx.obj.get('project'), ctx.obj.get('job'))

    if past:
        try:
            response = PolyaxonClient().job.logs(
                user, project_name, _job, stream=False)
            get_logs_handler(handle_job_info=False,
                             show_timestamp=not hide_time,
                             stream=False)(response.content.decode().split('\n'))
            print()

            if not follow:
                return
        except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
            if not follow:
                Printer.print_error('Could not get logs for job `{}`.'.format(_job))
                Printer.print_error('Error message `{}`.'.format(e))
                sys.exit(1)

    try:
        PolyaxonClient().job.logs(
            user,
            project_name,
            _job,
            message_handler=get_logs_handler(handle_job_info=False, show_timestamp=not hide_time))
    except (PolyaxonHTTPError, PolyaxonShouldExitError, PolyaxonClientException) as e:
        Printer.print_error('Could not get logs for job `{}`.'.format(_job))
        Printer.print_error('Error message `{}`.'.format(e))
        sys.exit(1)


# constantes
import os
import random

import readchar

POS_X = 0
POS_Y = 1

num_of_map_objects = 4

obstacle_definition = """\
#############################
                        #####
##################       ####
####    ##########          #
#######                  ####
#####     ######    #########
#########               #####
############       ##########
###   ##########         ####
###  ##    ######       #####
###                     #####
#######    ######       #####
#############################\
"""

# x = width
# y = height

my_position = [0, 1]

map_objects = []

end_game = False
died = False

# Create obstacle map

obstacle_definition = [list(row) for row in obstacle_definition.split("\n")]
map_width = len(obstacle_definition[0])
map_height = len(obstacle_definition)

# Main Loop
while not end_game:

    os.system("cls")
    # Generate random objects on the map

    while len(map_objects) < num_of_map_objects:
        new_position = [random.randint(0, map_width - 1), random.randint(0, map_height - 1)]

        if new_position not in map_objects and new_position != my_position and \
                obstacle_definition[new_position[POS_Y]][new_position[POS_X]] != "#":
            map_objects.append(new_position)

    # Draw map
    print("+" + "-" * map_width * 2 + "+")

    for coordinate_y in range(map_height):
        print("|", end="")

        for coordinate_x in range(map_width):

            char_to_draw = "  "
            object_in_cell = None

            for map_object in map_objects:
                if map_object[POS_X] == coordinate_x and map_object[POS_Y] == coordinate_y:
                    char_to_draw = " *"
                    object_in_cell = map_object

            if my_position[POS_X] == coordinate_x and my_position[POS_Y] == coordinate_y:
                char_to_draw = " @"

            if obstacle_definition[coordinate_y][coordinate_x] == "#":
                char_to_draw = "##"

            print("{}".format(char_to_draw), end="")
        print("|")

    print("+" + "-" * map_width * 2 + "+")

    # Ask user where he wants to move
    # direction = input("Donde te quieres mover? [WASD]: ")
    direction = readchar.readchar().decode()
    new_position = None
    if direction == "w":
        new_position = [my_position[POS_X],  (my_position[POS_Y] - 1) % map_width]

    elif direction == "s":
        new_position = [my_position[POS_X], (my_position[POS_Y] + 1) % map_width]

    elif direction == "a":
        new_position = [(my_position[POS_X] - 1) % map_width, my_position[POS_Y]]

    elif direction == "d":
        new_position = [(my_position[POS_X] + 1) % map_width, my_position[POS_Y]]

    elif direction == "q":
        end_game = True

    if new_position:
        if obstacle_definition[new_position[POS_Y]][new_position[POS_X]] != "#":
            my_position = new_position

    os.system("cls")


import time
import pandas as pd
import numpy as np

# 在liwc基础上，选出与谣言最不相似的新闻
fact = pd.read_csv("liwc_res_data_articles.json['content'].csv")
rumors = pd.read_csv("liwc_res_rumors_positive_content_cleaned.csv")
basket = list(range(fact.iloc[:, 0].size))
picked = list()
print(basket)
start_time = time.time()
for i in range(rumors.iloc[:, 0].size):
    if i % 100 == 0:
        print(i)
    choice = 0
    ri = np.array(rumors.iloc[i].tolist()[1:])
    f0 = np.array(fact.iloc[0].tolist()[1:])
    max_dist = np.sum((ri-f0)**2)
    for j in range(len(basket)-1):
        fi = np.array(fact.iloc[j].tolist()[1:])
        dist = np.sum((ri-fi)**2)
        # print(dist, j)
        if dist > max_dist:
            max_dist = dist
            choice = j
    picked.append(basket.pop(choice))
    # print("choose", choice)
    # time.sleep(30)
end_time = time.time()

print("time cost: ", end_time - start_time)
print(len(basket), basket)
print(len(picked), picked)
print(len(basket)+len(picked))

new_fact = fact.iloc[picked]
new_fact.to_csv("data_articles_as_far_as.csv", index=False)


# Leia N, calcule e escreva os N primeiros termos de seqüência (1, 3, 6, 10, 15,...)

def main():
    n = int(input('>>> '))

    y = 1
    x = 2
    contador = 1
    p = 1

    print('{}'.format(1), end=' ')

    while True:
        y = y + x
        x = x + 1
        contador = contador + 1

        if contador > n:
            break

        print('-> {}'.format(y), end=' ')

main()


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

img = cv.imread('../Images & Videos/smilies.jpg', 0)
img = cv.resize(img, (300, 300))
img = cv.bitwise_not(img)
template = np.zeros(img.shape)
# finding threshold
ret, img = cv.threshold(img, 127, 255, 0)
contours, hierarchy = cv.findContours(img, cv.RETR_CCOMP, cv.CHAIN_APPROX_SIMPLE)
for i in range(len(contours)):
    if hierarchy[0][i][3] == -1:
        cv.drawContours(template, contours, i, (255, 255, 255), -1)
plt.imshow(img, cmap='gray')
plt.show()
# cv.imshow('show',template)
# cv.waitKey(0)
# cv.destroyAllWindows()


#!/usr/bin/env python3
import os
import re
import sys
from colorama import Fore, Back, Style
import argparse

EmbyLibrary = './EmbyLibrary'
ConvertDir = './convert'

CATEGORY = {
    'Movie': {
        '1': 'Movies',
        '2': 'Animation Movies',
    },
    'Series': {
        '1': 'TV',
        '2': 'Animation Series',
    }
}

CATEGORY_INPUT = 0
TEST_MODE = True
# https://psarips.top/
listOfWordsPSA = '66CH|2160p|HDR|imax|10bit|BluRay|6CH|x265|HEVC-PSA|1080p|WEBRip|8CH|2CH|720p|web-dl|remastered|REAL|REPACK|BrRip'
listOfWordsPSA = listOfWordsPSA.split('|')

def is_linux():
    """
    is_linux()
    Returns True if running on Linux, False otherwise
    """
    return os.name == 'posix'

def set_folder_user_group(folder, user, group):
    """
    set_folder_user_group(folder, user, group)
    Sets the group of the folder
    """
    if is_linux():
        os.system(f'chown -R {user}:{group} {folder}')

def get_dirs(path):
    """
    get_dirs(path)
    Returns a list of all directories in the path
    """
    dirs = [path]
    for i in os.listdir(path):
        if os.path.isdir(os.path.join(path, i)):
            dirs.extend(get_dirs(os.path.join(path, i)))
    return dirs

def combine_path_from_category(category):
    """
    combine_path_from_category(category)
    Combines the path from the category
    """
    path = []
    for value in CATEGORY[category].values():
        path += get_dirs(os.path.join(EmbyLibrary, value))
    return path

def get_media_files_in_dir(path):
    """
    get_media_files_in_dir(path)
    Returns a list of all media files in the path
    """
    media_files = []
    for i in os.listdir(path):
        if os.path.isfile(os.path.join(path, i)):
            if i.endswith('.mkv') or i.endswith('.mp4') or i.endswith('.txt'):
                media_files.append(i)
    return media_files

def find_file_type(file):
    """
    find_file_type(file)
    Returns the file type as a string
    """
    for i in range(len(file)):
        if file[i] == '.':
            return file[i+1:]
    return ''

def remove_word_from_list(list):
    """
    remove_word_from_list(list, words)
    Removes all elements from list containing the word
    """
    temp = []
    for i in range(len(list)):
        if 'Season' not in list[i]:
            if ord(list[i][-1]) < ord('A') or ord(list[i][-1]) > ord('Z'):
                if ord(list[i][-1]) != ord('#'):
                    temp.append(list[i])
    return temp

def find_season(file):
    """
    find_season(file)
    Returns the season number as a string
    """
    for i in range(len(file)):
        if file[i] == 'S':
            if file[i+1].isdigit():
                season = file[i+1]
                if file[i+2].isdigit():
                    season += file[i+2]
                    return season
                else:
                    return season
    return '-1'

def find_episode(file):
    """
    find_episode(file)
    Returns the episode number as a string
    """
    for i in range(len(file)):
        if file[i] == 'E':
            if file[i+1].isdigit():
                episode = file[i+1]
                if file[i+2].isdigit():
                    episode += file[i+2]
                    return episode
                else:
                    return episode
    return '-1'

def find_title(file):
    """
    find_title(file)
    Returns the title as a string
    """

    if find_episode(file) != '-1':
        return file[file.index(f'E{find_episode(file)}')+4:file.index(".")]
    elif find_year(file) != '-1':
        return file[file.index(find_year(file))+5:file.index(".")]
    return ''

def remove_words(file, words):
    """
    remove_words(file, words)
    Removes words from file name
    """
    for word in words:
        file = re.sub(word, '', file, flags=re.I)
    return file

def remove_dot(file):
    """
    remove_dot(file)
    Removes the dot from the file name
    """
    temp = os.path.splitext(file)
    file = re.sub('\.', ' ', temp[0])
    file = file.strip()
    return file + temp[1]

def find_movie_name(file):
    """
    find_movie_name_in_season(file)
    Returns the movie name as a string
    """
    for i in range(len(file)):
        if file[i] == 'S':
            if file[i+1].isdigit():
                movie = file[:i]
                movie = movie.strip()
                if find_year(movie) != '-1':
                    return movie[:movie.index(find_year(movie))-1]
                else:
                    return movie
    return file[:file.index(find_year(file))-1]

def find_year(file):
    """
    find_year(file)
    Returns the year as a string
    """
    for i in range(len(file)):
        if file[i].isdigit():
            if file[i+1].isdigit():
                if file[i+2].isdigit():
                    if file[i+3].isdigit():
                        year = file[i:i+4]
                        return year
    return '-1'

def find_movie_name_with_year(file):
    """
    find_movie_name_with_year(file)
    Returns the movie name with year as a string
    """
    if find_year(file) != '-1':
        return f'{find_movie_name(file)} ({find_year(file)})'
    else:
        return find_movie_name(file)

def movie_path_in_list(file) -> str:
    """
    movie_path_in_list(file)
    Returns path if movie in th list, '' otherwise
    """
    global CATEGORY_INPUT
    origin_file = os.path.join(ConvertDir, file)
    file = remove_words(file, listOfWordsPSA)
    file = remove_dot(file)

    if find_season(file) != '-1':
        category_str = 'Series'
    else:
        category_str = 'Movie'
    combine_path = remove_word_from_list(
        combine_path_from_category(category_str))
    for i in range(len(combine_path)):
        if find_movie_name(file) in combine_path[i]:
            value = os.path.normpath(combine_path[i]).split(os.path.sep)[1]
            CATEGORY_INPUT = get_key(value, CATEGORY[category_str])
            move_file_into_folder(
                origin_file, file, category_str, combine_path[i])
            return combine_path[i]
    create_folder_movie(file, category_str)
    move_file_into_folder(origin_file, file, category_str, '')
    return ''

# get key from value
def get_key(value, dict):
    for key, val in dict.items():
        if val == value:
            return key
    return '-1'

def create_folder_movie(file, category_str):
    """
    create_folder_movie(file)
    Creates a folder for the movie
    """
    global CATEGORY_INPUT

    temp = 'Create folder for ' + Fore.GREEN + file + Style.RESET_ALL + ' in ?🧐\n'

    for key, value in CATEGORY[category_str].items():
        temp += f"{key}. {value}\n"

    CATEGORY_INPUT = input(temp)
    create_folder_helper(file, category_str)

def create_folder_helper(file, category_str):
    """
    create_folder_helper(category_str, category, file)
    Function helper for create_folder_movie
    """
    alphabet_path = os.path.join(
        EmbyLibrary, CATEGORY[category_str][CATEGORY_INPUT], file[0])
    if not os.path.exists(alphabet_path):
        print_create_folder_with_color(alphabet_path)
        if not TEST_MODE:
            os.makedirs(alphabet_path)

    name_path = os.path.join(alphabet_path, find_movie_name_with_year(file))
    if not os.path.exists(name_path):
        print_create_folder_with_color(name_path)
        if not TEST_MODE:
            os.makedirs(name_path)

    if find_season(file) != '-1':
        season_path = os.path.join(
            name_path, 'Season ' + str(int(find_season(file))))
        if not os.path.exists(season_path):
            print_create_folder_with_color(season_path)
            if not TEST_MODE:
                os.makedirs(season_path)

def print_create_folder_with_color(path):
    """
    print_create_folder_with_color(path)
    Prints the folder to create with color
    """
    print(f'🏠 Create folder {Fore.GREEN}{path}{Style.RESET_ALL}')

def print_move_file_with_color(origin_file, new_name):
    """
    print_move_file_with_color(origin_file, file, category_str, path)
    Prints the file to move with color
    """
    print(
        f'💔 Move file {Fore.GREEN}{origin_file}{Style.RESET_ALL} to {Fore.MAGENTA}{new_name}{Style.RESET_ALL}')

def move_file_into_folder(origin_file, file, category_str, des_path):
    """
    move_file_into_folder(file)
    Moves the file into the folder
    """
    if des_path == '':
        des_path = os.path.join(
            EmbyLibrary, CATEGORY[category_str][CATEGORY_INPUT], file[0], find_movie_name_with_year(file))

    title = find_title(file)
    if title != '':
        title = ' '+title
    else:
        title = ''
    if find_season(file) != '-1':
        season_path = os.path.join(
            des_path, 'Season ' + str(int(find_season(file))))
        # move file to season folder if file not in season folder
        if not os.path.exists(os.path.join(season_path, file)):
            new_name = os.path.join(
                season_path, f'{find_movie_name_with_year(file)} S{find_season(file)}E{find_episode(file)}{title}.{find_file_type(file)}')
            print_move_file_with_color(origin_file, new_name)
            if not TEST_MODE:
                os.rename(origin_file, new_name)
        else:
            print(f'- {origin_file} already in {season_path}')
    else:
        # move file to movie folder if file not in movie folder
        if not os.path.exists(os.path.join(des_path, file)):
            new_name = os.path.join(
                des_path, f'{find_movie_name_with_year(file)}{title}.{find_file_type(file)}')
            print_move_file_with_color(origin_file, new_name)
            if not TEST_MODE:
                os.rename(origin_file, new_name)
        else:
            print(f'- {origin_file} already in {des_path}')

def less_indent_formatter(prog): return argparse.RawTextHelpFormatter(
    prog, max_help_position=5)

def interactive():
    parser = argparse.ArgumentParser(
        description=f'Easy app to move file to Emby library',
        formatter_class=less_indent_formatter)
    parser.add_argument('-m', '--mode', metavar='MODE', choices=['t', 'm'],  help='''
t - Dry run without moving files
m - Move files to Emby library
    ''', required=True)
    args = parser.parse_args()
    return args

def main():
    global TEST_MODE
    args = interactive()
    print(Fore.RED + 'This script is only for Linux')
    print(Style.RESET_ALL)
    args = interactive()
    if args.mode == 't':
        TEST_MODE = True
    else:
        TEST_MODE = False
    if TEST_MODE:
        print(Fore.RED + 'Running in Test Mode')
        print(Style.RESET_ALL)

    media_files = get_media_files_in_dir(ConvertDir)
    set_folder_user_group(ConvertDir, 'emby', 'dietpi')
    for file in media_files:
        movie_path_in_list(file)

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print('\n\nExiting')
        sys.exit(0)
    print('Done')


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

import tkinter as tk

window = tk.Tk()
window.title('CheckButton')
window.geometry('400x300')

l = tk.Label(
    window,
    text = 'empty',
    width = 15,
    bg = 'yellow'
)
l.pack()

def print_selection():
    if ((var1.get()==1) & (var2.get()==0)):
        l.config(text='I love only python.')

    elif ((var1.get()==0) & (var2.get()==1)):
        l.config(text='I love only c.')
    elif ((var1.get()==1) & (var2.get()==1)):
        l.config(text='I love both.')
    else:
        l.config(text='I do not love either.')

var1 = tk.IntVar()
c1 = tk.Checkbutton(
    window,
    text = 'python',
    variable = var1,
    onvalue = 1, # 当选中这个 Checkbutton 时，onvalue 的值放到 var1 中，然后将 var1 的值赋值给 variable
    offvalue = 0,
    command = print_selection,
)
c1.pack()

var2 = tk.IntVar()
c1 = tk.Checkbutton(
    window,
    text = 'c',
    variable = var2,
    onvalue = 1, # 当选中这个 Checkbutton 时，onvalue 的值放到 var1 中，然后将 var1 的值赋值给 variable
    offvalue = 0,
    command = print_selection,
)
c1.pack()

window.mainloop()


from __future__ import print_function
from __future__ import division
from __future__ import absolute_import

import inspect

import numpy
import matplotlib
import matplotlib.pyplot as plt

import PythonTools.Debug as DEBUG

cdict = {'red':   [(0.0,  0.0, 0.0),(0.475,  1.0, 1.0),(0.525,  1.0, 1.0),
            (1.0,  1.0, 1.0)],
         'green': [(0.0,  0.0, 0.0),(0.475,  1.0, 1.0),(0.525,  1.0, 1.0),
            (1.0,  0.0, 0.0)],
         'blue':  [(0.0,  1.0, 1.0),(0.475,  1.0, 1.0),(0.525,  1.0, 1.0),
            (1.0,  0.0, 0.0)]
        }
rwb_cmap = matplotlib.colors.LinearSegmentedColormap('rwb_colormap', cdict, 256)

def find_axes(x_axis, y_axis, x_range, y_range, flag_verbose = False):
    """
    croc.Plotting.find_axis

    INPUT:
    - x_axis, y_axis (ndarray): the axes
    - x_range, y_range (array): the ranges to be plotted
        Possible cases:
        - [min, max]: plot range min to max
        - [0, 0]: plot the whole range
        - [0, -1]: use the range from the other axis. If both have this, it will plot both axes complete. (ie. it is identical to both having [0,0])

    OUTPUT:
    - xmin, xmax, ymin, ymax: a value

    CHANGELOG
    - 20110910 RB: init

    """
    DEBUG.verbose("find axes", flag_verbose)

    # x_min and x_max are determined by y
    if x_range[0] == 0 and x_range[1] == -1:

        # they are both dependent on each other, plot everything
        if y_range[0] == 0 and y_range[1] == -1:
            x_min = x_axis[0]
            x_max = x_axis[-1]
            y_min = y_axis[0]
            y_max = y_axis[-1]

        # take the whole y-axis, the same for the x-axis
        # it may extend beyond the range of the data
        elif y_range[0] == 0 and y_range[1] == 0:
            x_min = y_axis[0]
            x_max = y_axis[-1]
            y_min = y_axis[0]
            y_max = y_axis[-1]

        # take part of the y-axis, the same for the x-axis
        # it may extend beyond the range of the data
        else:
            x_min = y_range[0]
            x_max = y_range[1]
            y_min = y_range[0]
            y_max = y_range[1]

    else:
        # plot the whole x-axis
        if x_range[0] == 0 and x_range[1] == 0:
            x_min = x_axis[0]
            x_max = x_axis[-1]
        # plot only part of the x-axis
        else:
            x_min = x_range[0]
            x_max = x_range[1]

        # plot the whole y-axis
        if y_range[0] == 0 and y_range[1] == 0:
            y_min = y_axis[0]
            y_max = y_axis[-1]
        # use the range of the x-axis
        elif y_range[0] == 0 and y_range[1] == -1:
            y_min = x_min
            y_max = x_max
        # use the specified range
        else:
            y_min = y_range[0]
            y_max = y_range[1]
    if flag_verbose:
        DEBUG.verbose("  axes found: x_min: " + str(x_min) + ", x_max: " + str(x_max) + ", y_min: " + str(y_min) + ", y_max: " + str(y_max), flag_verbose)

    return x_min, x_max, y_min, y_max

def find_axes_indices(axis, val_min, val_max, flag_verbose = False):
    """
    Find the indices of values val_min and val_max in axis, such that val_min and val_max are included.
    Because the intended use is to slice an array data[val_min_i:val_max_i], 1 is added to val_max_i.
    If the val_min or val_max exceed the axis, then the index is 0 or -1, respectively.

    BEHAVIOR:
    axis = [3,4,5,6]
    if val_min == 4.5: val_min_i = 1
    if val_min == 5: val_min_i = 1
    if val_min == 1: val_min_i = 0

    if val_max = 4.5: val_max_i = 3: axis[0:3] = [3,4,5]
    if val_max = 4: val_max_i = 2: axis[0:2] = [3,4]
    if val_max = 10: val_max_i = -1: axis[0:-1] = [3,4,5]

    CHANGELOG:
    201108xx/RB: originated in contourplot
    20130213/RB: moved to separate function. Better handling of edge cases.

    """
    if val_min > val_max:
        DEBUG.printWarning("val_min > val_max ({v1} and {v2}), will give strange result.".format(v1 = val_min, v2 = val_max), inspect.stack())

    temp = numpy.where(axis < val_min)
    if len(temp[0]) == 0:
        val_min_i = 0
    else:
        val_min_i = temp[0][-1]

    temp = numpy.where(axis > val_max)
    if len(temp[0]) == 0:
        val_max_i = -1
    else:
        val_max_i = temp[0][0] + 1
        if val_max_i == len(axis):
            val_max_i = -1

    return val_min_i, val_max_i

def make_contours_2d(data, zlimit = 0, contours = 21, flag_verbose = False):
    """
    zlimit = 0, show all, not don't care about centering around zero
    zlimit = -1, show all, centered around zero
    zlimit = all else, use that, centered around zero
    zlimit = [a,b], plot from a to b

    CHANGELOG:
    201108xx/RB: started in Plotting module
    20130213/RB: moved to Functions module
    """

    DEBUG.verbose("make contours 2D", flag_verbose)

    if zlimit == 0:
        ma = numpy.amax(data)
        mi = numpy.amin(data)
        if flag_verbose:
            DEBUG.verbose("  zlimit = 0, min: " + str(mi) + ", max: " + str(ma), flag_verbose)
        return numpy.linspace(mi, ma, num=contours)

    elif zlimit == -1:
        ma = numpy.amax(data)
        mi = numpy.amin(data)
        if flag_verbose:
            DEBUG.verbose("  zlimit = 0, min: " + str(mi) + ", max: " + str(ma), flag_verbose)

        if abs(mi) > abs(ma):
            ma = abs(mi)
        else:
            ma = abs(ma)
        return numpy.linspace(-ma, ma, num=contours)

    elif type(zlimit) == list:
        DEBUG.verbose("  zlimit == list", flag_verbose)
        return numpy.linspace(zlimit[0], zlimit[1], num=contours)

    else:
        DEBUG.verbose("  zlimit is linspace", flag_verbose)
        return numpy.linspace(-abs(zlimit), abs(zlimit), num=contours)

def truncate_data(data, x_axis, y_axis, x_min_i, x_max_i, y_min_i, y_max_i, flag_verbose = False):
    """
    Truncate data in a non-default way.
    x_axis = [1,2,3,4,5]
    x_min_i = 0
    if x_max_i == 2: x_axis = [1,2]
    if x_max_i == 4: x_axis = [1,2,3,4]
    if x_max_i == -1: x_axis = [1,2,3,4,5]

    CHANGELOG:
    20130213: was in Plotting.contourplot function, moved to Functions module, now handles x_max_i == -1
    """

    DEBUG.verbose("Truncate data", flag_verbose)

    if x_max_i == -1:
        DEBUG.verbose("  x_max == -1", flag_verbose)
        data = data[:,x_min_i:]
        x_axis = x_axis[x_min_i:]
    else:
        DEBUG.verbose("  x_max != -1", flag_verbose)
        data = data[:,x_min_i:x_max_i]
        x_axis = x_axis[x_min_i:x_max_i]

    if y_max_i == -1:
        DEBUG.verbose("  y_max == -1", flag_verbose)
        data = data[y_min_i:,:]
        y_axis = y_axis[y_min_i:]
    else:
        DEBUG.verbose("  y_max != -1", flag_verbose)
        data = data[y_min_i:y_max_i,:]
        y_axis = y_axis[y_min_i:y_max_i]

    return data, x_axis, y_axis

def find_subplots(n_plots, flag_verbose = 0):
    """
    Crocodile.Resources.Functions.find_subplots()

    Take the required number of subplots and find how many plots there should be horizontally and vertically. It is either NxN plots, or (N+1)xN plots.

    INPUT:
    - n_plots (int, >0): the number of plots

    OUTPUT:
    - x, y (int): the number of plots horizontally and vertically

    CHANGELOG
    - 20160413-RB: started function

    """
    DEBUG.verbose("find_subplots({n_plots})".format( n_plots = n_plots), flag_verbose)

    if n_plots < 1:
        return 0, 0

    t = numpy.sqrt(n_plots)

    x = numpy.floor(t)
    y = numpy.floor(t)

    if x * y < n_plots:
        x += 1

    if x * y < n_plots:
        y += 1

    DEBUG.verbose("n_plots: {n_plots}, x: {x}, y: {y}".format( n_plots = n_plots, x = x, y = y), flag_verbose)

    return int(x), int(y)

### SPECTROMETER FUNCTIONS ###

def spectrometer_axis(**kwargs):
    """

    """

    settings = {
        "grating_blaze_l_mm": 150,
        "center_wl_nm": 1e7/1603,
        "f_mm": 257,
        "spacing_mm": 0.525,
        "n_pixels": 32,
        "center_pixel": 16,
        "gamma_deg": 15,
        "half_angle_deg": 11.83,
        "order": 1
    }

    if "center_wl_nm" in kwargs:
        settings["center_wl_nm"] = kwargs["center_wl_nm"]
    elif "center_wl_cm" in kwargs:
        settings["center_wl_nm"] = 1e7 / kwargs["center_wl_cm"]

    if "grating_blaze_l_mm" in kwargs:
        settings["grating_blaze_l_mm"] = kwargs["grating_blaze_l_mm"]

    if "f_mm" in kwargs:
        settings["f_mm"] = kwargs["f_mm"]

    if "spacing_mm" in kwargs:
        settings["spacing_mm"] = kwargs["spacing_mm"]

    if "n_pixels" in kwargs:
        settings["n_pixels"] = kwargs["n_pixels"]

    if "gamma_deg" in kwargs:
        settings["gamma_deg"] = kwargs["gamma_deg"]

    if "half_angle_deg" in kwargs:
        settings["half_angle_deg"] = kwargs["half_angle_deg"]

    if "order" in kwargs:
        settings["order"] = kwargs["order"]

    a, alpha, beta, theta, phi = calculate_angels(settings)

    array = numpy.zeros(settings["n_pixels"])

    for pixel in range(settings["n_pixels"]):

        angle = -numpy.arctan( (pixel - settings["center_pixel"]) * settings["spacing_mm"] / settings["f_mm"])
        array[pixel] = a * (numpy.sin(alpha) + numpy.sin(beta + angle)) / settings["order"]

    return array, 1e7 / array

def calculate_angels(settings):

    a = 1e6 / settings["grating_blaze_l_mm"] # nm per line
    phi = settings["half_angle_deg"] * numpy.pi / 180

    theta = numpy.arcsin(
        settings["center_wl_nm"] * settings["order"] / (2 * a * numpy.cos(phi))
    )

    alpha = theta + phi
    beta = theta - phi

    return a, alpha, beta, theta, phi


#!/usr/bin/env python3
from aquachain.aquakeys import Keystore
from aquachain.aquatool import AquaTool
from tkinter import Frame
from tkinter import IntVar, Tk, PhotoImage
from aquachaintk.toolbar import Toolbar, NoButton
from aquachaintk.scenes import StartPage, ThemedFrame, LogoPath
from aquachaintk.scenes import PageNone, PageAbout, PageReceive, PageWallets
import os
LogoPath = os.path.join(os.path.dirname(__file__), 'aquachain.png')
class TestApplication(Tk):
    def __init__(self):
        Tk.__init__(self)

        # self.wm_geometry(newGeometry='800x400-100+100')
        self.version = 'Aquachain TK v0.0.3'
        self.configure(background='black')
        self.logo = PhotoImage(file=LogoPath)
        self.head_difficulty = IntVar()
        self.head_number = IntVar()
        self.head_timing = IntVar()
        self.head_timestamp = IntVar()
        self.total_supply = IntVar()

        self.head_difficulty.set(0)
        self.head_number.set(0)
        self.head_timing.set(0)
        self.head_timestamp.set(0)
        self.total_supply.set(0)

        # connect to aquachain node
        self.aqua = None
        self.aqua = AquaTool(rpchost='https://c.onical.org')

        # get latest block from aquachain node
        self.head = self.aqua.gethead()

        # keys
        self.keystore = Keystore()
        self.hdkeys = []
        self.addresses = []

        # TK
        self._mainframe = Frame(self, background='green')
        self._mainframe.pack(side='top', anchor='n', expand=True, fill='both')
        self._framename = ''

        self.buttons = btns = {
            'Quit': NoButton(text='Quit',
                command=self.quit, width=13),
            'Lock': NoButton(text='Lock',
                command=self.lock, width=13),
            'PageWallets': NoButton(text='Wallets',
                command=self.switch_frame, arg=PageWallets, width=13),
            'PageAbout': NoButton(text='About',
                command=self.switch_frame, arg=PageAbout, width=13),
            'PageAbout': NoButton(text='Recv',
                command=self.switch_frame, arg=PageReceive, width=13),
        }
        self._toolbar = Toolbar(self._mainframe, app=self, logo=self.logo)
        self._toolbar.addbtns(btns)
        self._toolbar.grid(sticky='nw', columnspan=1, column=0, row=0)

        # take it away
        # self._leftcol = Frame(self, background='blue')
        self._frame = ThemedFrame(self._mainframe, app=self, background='teal', height='100')

        self.homepage()
    def quit(self):
        quit()
    def lock(self):
        quit()
    def homepage(self):
        # self.switch_frame(/StartPage)
        self.switch_frame(StartPage)
    def switch_frame(self, frame_class):
        """Destroys current frame and replaces it with a new one."""
        self._framename = frame_class.__name__
        new_frame = frame_class(parent=self._mainframe,app=self)
        if self._frame is not None:
            print('deleting:',self._frame)
            self._frame.destroy()
        self._frame = new_frame
        self._frame.grid(sticky='ne',ipadx=100, column=1, row=0)
        print('switchin to framename:', self._framename)

if __name__ == '__main__':
    win = TestApplication()
    win.switch_frame(StartPage)
    win.mainloop()


import numpy as np
import pytest
from numpy import linalg
from conftest import unit_box, points
from devito import clear_cache, Operator, configuration
from devito.logger import info
from examples.seismic import demo_model, Receiver
from examples.seismic.acoustic import acoustic_setup

pytestmark = pytest.mark.skipif(configuration['backend'] == 'yask' or
                                configuration['backend'] == 'ops',
                                reason="testing is currently restricted")

presets = {
    'constant': {'preset': 'constant-isotropic'},
    'layers': {'preset': 'layers-isotropic', 'ratio': 3},
}

class TestAdjoint(object):

    def setup_method(self, method):
        # Some of these tests are memory intensive as it requires to store the entire
        # forward wavefield to compute the gradient (nx.ny.nz.nt). We therefore call
        # 'clear_cache()' to release any remaining memory from the previous tests or
        # previous instances (different parametrizations) of these tests
        clear_cache()

    @pytest.mark.parametrize('mkey, shape, kernel, space_order, nbpml', [
        # 1 tests with varying time and space orders
        ('layers', (60, ), 'OT2', 4, 10), ('layers', (60, ), 'OT2', 8, 10),
        ('layers', (60, ), 'OT4', 4, 10), ('layers', (60, ), 'OT4', 8, 10),
        # 2D tests with varying time and space orders
        ('layers', (60, 70), 'OT2', 4, 10), ('layers', (60, 70), 'OT2', 8, 10),
        ('layers', (60, 70), 'OT2', 12, 10), ('layers', (60, 70), 'OT4', 4, 10),
        ('layers', (60, 70), 'OT4', 8, 10), ('layers', (60, 70), 'OT4', 12, 10),
        # 3D tests with varying time and space orders
        ('layers', (60, 70, 80), 'OT2', 4, 10), ('layers', (60, 70, 80), 'OT2', 8, 10),
        ('layers', (60, 70, 80), 'OT2', 12, 10), ('layers', (60, 70, 80), 'OT4', 4, 10),
        ('layers', (60, 70, 80), 'OT4', 8, 10), ('layers', (60, 70, 80), 'OT4', 12, 10),
        # Constant model in 2D and 3D
        ('constant', (60, 70), 'OT2', 8, 14), ('constant', (60, 70, 80), 'OT2', 8, 14),
    ])
    def test_adjoint_F(self, mkey, shape, kernel, space_order, nbpml):
        """
        Adjoint test for the forward modeling operator.
        The forward modeling operator F generates a shot record (measurements)
        from a source while the adjoint of F generates measurments at the source
        location from data. This test uses the conventional dot test:
        < Fx, y> = <x, F^T y>
        """
        tn = 500.  # Final time

        # Create solver from preset
        solver = acoustic_setup(shape=shape, spacing=[15. for _ in shape], kernel=kernel,
                                nbpml=nbpml, tn=tn, space_order=space_order,
                                **(presets[mkey]), dtype=np.float64)

        # Create adjoint receiver symbol
        srca = Receiver(name='srca', grid=solver.model.grid,
                        time_range=solver.geometry.time_axis,
                        coordinates=solver.geometry.src_positions)

        # Run forward and adjoint operators
        rec, _, _ = solver.forward(save=False)
        solver.adjoint(rec=rec, srca=srca)

        # Adjoint test: Verify <Ax,y> matches  <x, A^Ty> closely
        term1 = np.dot(srca.data.reshape(-1), solver.geometry.src.data)
        term2 = linalg.norm(rec.data.reshape(-1)) ** 2
        info('<Ax,y>: %f, <x, A^Ty>: %f, difference: %4.4e, ratio: %f'
             % (term1, term2, (term1 - term2)/term1, term1 / term2))
        assert np.isclose((term1 - term2)/term1, 0., rtol=1.e-10)

    @pytest.mark.parametrize('space_order', [4, 8, 12])
    @pytest.mark.parametrize('shape', [(60,), (60, 70), (40, 50, 30)])
    def test_adjoint_J(self, shape, space_order):
        """
        Adjoint test for the FWI Jacobian operator.
        The Jacobian operator J generates a linearized shot record (measurements)
        from a model perturbation dm while the adjoint of J generates the FWI gradient
        from an adjoint source (usually data residual). This test uses the conventional
        dot test:
        < Jx, y> = <x ,J^T y>
        """
        tn = 500.  # Final time
        nbpml = 10 + space_order / 2
        spacing = tuple([10.]*len(shape))
        # Create solver from preset
        solver = acoustic_setup(shape=shape, spacing=spacing,
                                nbpml=nbpml, tn=tn, space_order=space_order,
                                preset='layers-isotropic', dtype=np.float64)

        # Create initial model (m0) with a constant velocity throughout
        model0 = demo_model('layers-isotropic', ratio=3, vp_top=1.5, vp_bottom=1.5,
                            spacing=spacing, space_order=space_order, shape=shape,
                            nbpml=nbpml, dtype=np.float64, grid=solver.model.grid)

        # Compute the full wavefield u0
        _, u0, _ = solver.forward(save=True, m=model0.m)

        # Compute initial born perturbation from m - m0
        dm = (solver.model.m.data - model0.m.data)

        du, _, _, _ = solver.born(dm, m=model0.m)

        # Compute gradientfrom initial perturbation
        im, _ = solver.gradient(du, u0, m=model0.m)

        # Adjoint test: Verify <Ax,y> matches  <x, A^Ty> closely
        term1 = np.dot(im.data.reshape(-1), dm.reshape(-1))
        term2 = linalg.norm(du.data.reshape(-1))**2
        info('<Jx,y>: %f, <x, J^Ty>: %f, difference: %4.4e, ratio: %f'
             % (term1, term2, (term1 - term2)/term1, term1 / term2))
        assert np.isclose((term1 - term2)/term1, 0., rtol=1.e-10)

    @pytest.mark.parametrize('shape, coords', [
        ((11, 11), [(.05, .9), (.01, .8)]),
        ((11, 11, 11), [(.05, .9), (.01, .8), (0.07, 0.84)])
    ])
    def test_adjoint_inject_interpolate(self, shape, coords, npoints=19):
        """
        Verify that p.inject is the adjoint of p.interpolate for a
        devito SparseFunction p
        """
        a = unit_box(shape=shape)
        a.data[:] = 0.
        c = unit_box(shape=shape, name='c', grid=a.grid)
        c.data[:] = 27.

        assert a.grid == c.grid
        # Inject receiver
        p = points(a.grid, ranges=coords, npoints=npoints)
        p.data[:] = 1.2
        expr = p.inject(field=a, expr=p)
        # Read receiver
        p2 = points(a.grid, name='points2', ranges=coords, npoints=npoints)
        expr2 = p2.interpolate(expr=c)
        Operator(expr + expr2)(a=a, c=c)
        # < P x, y > - < x, P^T y>
        # Px => p2
        # y => p
        # x => c
        # P^T y => a
        term1 = np.dot(p2.data.reshape(-1), p.data.reshape(-1))
        term2 = np.dot(c.data.reshape(-1), a.data.reshape(-1))
        assert np.isclose((term1-term2) / term1, 0., atol=1.e-6)


'''
训练，测试代码
'''

import os
import sys
from tensorflow.keras.optimizers import Adam

from asrt.model_speech import ModelSpeech
from asrt.speech_model_zoo import SpeechModel251BN
from asrt.data_loader import DataLoader
from asrt.speech_features import SpecAugment, Spectrogram
from asrt.language_model import ModelLanguage

audio_length = 1600
audio_feature_length = 200
channels = 1

# 默认输出的拼音的表示大小是1428，即1427个拼音 + 1个空白块
output_size = 1428

op = sys.argv[1]
fn = sys.argv[2]

if op == 'train':
    sm251bn = SpeechModel251BN(
        input_shape=(audio_length, audio_feature_length, channels),
        output_size=output_size
    )
    feat = SpecAugment()
    train_data = DataLoader('train')
    opt = Adam(lr=0.0001, beta_1=0.9, beta_2=0.999, decay=0.0, epsilon=10e-8)
    model_speech = ModelSpeech(sm251bn, feat, max_label_length=64)
    model_speech.train_model(optimizer=opt, data_loader=train_data, epochs=30, save_step=1, batch_size=16, last_epoch=0)
    model_speech.save_model('save_model/' + sm251bn.get_model_name())

elif op == 'dev':
    sm251bn = SpeechModel251BN(
        input_shape=(audio_length, audio_feature_length, channels),
        output_size=output_size
    )
    feat = Spectrogram()
    evalue_data = DataLoader('dev')
    model_speech = ModelSpeech(sm251bn, feat, max_label_length=64)
    model_speech.load_model('save_model/' + sm251bn.get_model_name() + '.model.h5')
    model_speech.evaluate_model(data_loader=evalue_data, data_count=-1, out_report=True, show_ratio=True,
                                show_per_step=100)

elif op == 'test':
    sm251bn = SpeechModel251BN(
        input_shape=(audio_length, audio_feature_length, channels),
        output_size=output_size
    )
    feat = Spectrogram()
    model_speech = ModelSpeech(sm251bn, feat, max_label_length=64)
    model_speech.load_model('save_model/' + sm251bn.get_model_name() + '.model.h5')
    res = model_speech.recognize_speech_from_file(filename=fn)
    print('[声学模型语音识别结果:{}]'.format(res))

    model_language = ModelLanguage('model_language')
    model_language.load_model()
    res = model_language.pinyin_to_text(res)
    print('[语音识别最终结果:{}]'.format(res))


from datasets.davisDataset import Davis
from datasets.dtiMinorDataset import DtiMinor
# import your dataset here

def select_dataset(base_path, dataset_params):
    """
       Dataset selection must be stated here.
    """

    dataset_name = dataset_params.name

    if dataset_name == 'Davis':
        dataset = Davis(base_path,
                        force_download=dataset_params.force_download,
                        load_from_raw=dataset_params.load_from_raw)
    elif dataset_name == 'dtiMinor':
        dataset = DtiMinor(base_path,
                           force_download=dataset_params.force_download,
                           load_from_raw=dataset_params.load_from_raw)
    ###########################################################################
    # ==================== INITIALIZE YOUR DATASET HERE ===================== #
    # elif dataset_name == 'Your dataset name':
    #   dataset = ...
    ###########################################################################
    else:
        raise ValueError(f'No dataset is stated for {dataset_name} in select_dataset.py file.')

    return dataset


def get_input_to_int(prompt) -> int:
  ret = 0
  while True:
    text = input(prompt)
    try:
      ret = int(text)
      break
    except ValueError:
      print("Input a valid integer!")
  return ret

def sieve_eratostnenes(max) -> list:
  primes = []
  for x in range(2, max + 1):
    primes.append(x)
  for x in range(2, max + 1):
    for p in primes:
      if p > x and p % x == 0:
          primes.remove(p)
  return primes

primes = sieve_eratostnenes(get_input_to_int("Limit for the sieve: "))
print(primes, len(primes))


import sys
import re
import os
import smtplib
import json
from email.mime.text import MIMEText

def main():
    cred = json.loads(open("%s/.maildetails"%(os.environ["HOME"]), "r").read())

    from_addr = cred["from"]
    to_addr = sys.argv[1]
    message = sys.argv[2]
    msg = MIMEText(message)
    msg['Subject'] = "SCRIPTNOTIF"
    msg['From'] = from_addr
    msg['To'] = to_addr

    s = smtplib.SMTP("smtp.gmail.com:587")
    s.starttls()
    s.login(cred["user"], cred["pw"])
    s.sendmail(from_addr, [to_addr], msg.as_string())
    s.quit()

if __name__ == "__main__":
    main()


from django import forms
from django.core.validators import FileExtensionValidator
from crispy_forms.helper import FormHelper
from .models import ReportSet, Template, Field, RuleSet, Report, Submission
from account.models import Group, Profile

def form_horizontal():
    helper = FormHelper()
    helper.form_tag = False
    helper.form_class = 'form-horizontal'
    helper.label_class = 'col-lg-2'
    helper.field_class = 'col-lg-8'
    return helper

class ReportSetForm(forms.ModelForm):
    class Meta:
        model = ReportSet
        fields = ['name', 'group']

    def __init__(self, user, *args, **kwargs):
        super(ReportSetForm, self).__init__(*args, **kwargs)
        # limit group options based on user
        self.fields['group'].queryset = Group.objects.filter(profiles__user=user)
        # If you pass FormHelper constructor a form instance
        # It builds a default layout with all its fields
        self.helper = form_horizontal()

class TemplateForm(forms.ModelForm):
    class Meta:
        model = Template
        fields = ['name']

    def __init__(self, *args, **kwargs):
        super(TemplateForm, self).__init__(*args, **kwargs)
        self.helper = form_horizontal()

class FieldForm(forms.ModelForm):
    class Meta:
        model = Field
        fields = ['name', 'dtype']

    def __init__(self, *args, **kwargs):
        super(FieldForm, self).__init__(*args, **kwargs)
        self.helper = form_horizontal()

class FieldImportForm(forms.Form):
    docfile = forms.FileField(
        widget=forms.FileInput(attrs={'accept': ".csv"}),
        label='Upload',
        help_text='max. 42 meabytes',
        validators = [FileExtensionValidator(allowed_extensions=['csv'])]
    )

    def __init__(self, *args, **kwargs):
        super(FieldImportForm, self).__init__(*args, **kwargs)
        self.helper = form_horizontal()

class RuleSetForm(forms.ModelForm):
    class Meta:
        model = RuleSet
        fields = ['field', 'rule', 'argument', 'action', 'error_message']
        help_texts = {
            'argument': 'if multiple arguments, seperated by comma(,); date argument format: 2019-01-01',
            'action': 'Warning: flagged but submission will be accepted; Error: submission will be rejected',
        }

    def __init__(self, tpk, *args, **kwargs):
        super(RuleSetForm, self).__init__(*args, **kwargs)
        self.fields['field'].queryset = Field.objects.filter(template=tpk)
        self.helper = form_horizontal()

class ReportForm(forms.ModelForm):
    class Meta:
        model = Report
        fields = ['name', 'method', 'templates']

    def __init__(self, rspk, *args, **kwargs):
        super(ReportForm, self).__init__(*args, **kwargs)
        self.fields['templates'].queryset = Template.objects.filter(report_set=rspk)
        self.helper = form_horizontal()

class SubmissionForm(forms.ModelForm):
    class Meta:
        model = Submission
        fields = ['template', 'upload']

    def __init__(self, rpk, *args, **kwargs):
        super(SubmissionForm, self).__init__(*args, **kwargs)
        self.fields['template'].queryset = Template.objects.filter(reports__id=rpk)
        self.fields['upload'].widget = forms.FileInput(attrs={'accept': ".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})
        self.fields['upload'].help_text = 'csv/xlsx, one sheet only'
        self.fields['upload'].validators = [FileExtensionValidator(allowed_extensions=['csv', 'xlsx'])]
        self.helper = form_horizontal()


import sys
import socket
import logging
import signal
from threading import Thread
from socket_handler import handler
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
from ftp_handler import SQLiteAuthorizer

# Config part
logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s - %(levelname)s - %(message)s")
port = 7979

def signal_handler(signal, frame):
    # Add SIGINT handler for killing the threads
    logging.info("Caught Ctrl+C, shutting down...")
    fileserver.close_all()
    server.close()
    sys.exit()

if __name__ == "__main__":
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(("0.0.0.0", port))  # Bind to all address
    server.listen()

    host = socket.gethostbyname(socket.gethostname())
    logging.info("Listen at %s:%d", host, port)
    logging.info("Server started...")

    signal.signal(signal.SIGINT, signal_handler)

    FTPhandler = FTPHandler
    FTPhandler.authorizer = SQLiteAuthorizer()
    fileserver = FTPServer(("", port + 1), FTPhandler)  # win 下 FTPD 监听有问题 请改成本机地址
    ftp_thread = Thread(target=fileserver.serve_forever, daemon=True)
    ftp_thread.start()

    while True:
        conn, addr = server.accept()
        socket_thread = Thread(target=handler, daemon=True,
                               args=(conn, addr))
        socket_thread.start()


import torch
import warnings
import datetime
from pathlib import Path
from argparse import ArgumentParser
from pydatagrand.train.ner_seq_trainer import Trainer
from torch.utils.data import DataLoader
from pydatagrand.io.bert_seq_processor import BertProcessor
from pydatagrand.common.tools import init_logger, logger
from pydatagrand.common.tools import seed_everything
from pydatagrand.configs.base import config
from pydatagrand.model.nn.bert_lstm_crf import BERTLSTMCRF
from pydatagrand.model.nn.bert_lstm_crf_mdp import BERTLSTMCRFMDP
from pydatagrand.callback import ModelCheckpoint
from pydatagrand.callback import TrainingMonitor
from pydatagrand.callback import BertAdam
from pydatagrand.callback import BERTReduceLROnPlateau
from torch.utils.data import RandomSampler, SequentialSampler
from pydatagrand.callback import Lookahead
warnings.filterwarnings("ignore")

def run_train(args):
    processor = BertProcessor(vocab_path=args.pretrain_model / 'vocab.txt', do_lower_case=args.do_lower_case)
    processor.tokenizer.save_vocabulary(str(args.model_path))
    label_list = processor.get_labels()
    label2id = {label: i for i, label in enumerate(label_list)}

    train_data = processor.get_train(config['data_dir'] / f"{args.data_name}_train_fold_{args.fold}.pkl")
    train_examples = processor.create_examples(lines=train_data,
                                               example_type='train',
                                               cached_file=config[
                                                'data_dir'] / f"cached_train_seq_examples")
    train_features = processor.create_features(examples=train_examples,
                                               max_seq_len=args.train_max_seq_len,
                                               cached_file=config[
                                                'data_dir'] / "cached_train_seq_features_{}".format(
                                                args.train_max_seq_len))
    train_dataset = processor.create_dataset(train_features, is_sorted=args.sorted)
    if args.sorted:
        train_sampler = SequentialSampler(train_dataset)
    else:
        train_sampler = RandomSampler(train_dataset)
    train_dataloader = DataLoader(train_dataset, sampler=train_sampler, batch_size=args.train_batch_size)

    valid_data = processor.get_dev(config['data_dir'] / f'{args.data_name}_valid_fold_{args.fold}.pkl')
    valid_examples = processor.create_examples(lines=valid_data,
                                               example_type='valid',
                                               cached_file=config[
                                            'data_dir'] / f"cached_valid_seq_examples")
    valid_features = processor.create_features(examples=valid_examples,
                                               max_seq_len=args.eval_max_seq_len,
                                               cached_file=config[
                                                'data_dir'] / "cached_valid_seq_features_{}".format(
                                                args.eval_max_seq_len))
    valid_dataset = processor.create_dataset(valid_features)
    valid_sampler = SequentialSampler(valid_dataset)
    valid_dataloader = DataLoader(valid_dataset, sampler=valid_sampler, batch_size=args.eval_batch_size)
    logger.info("initializing model")
    if args.do_mdp:
        model = BERTLSTMCRFMDP
    else:
        model = BERTLSTMCRF
    if args.resume_path:
        args.resume_path = Path(args.resume_path)
        model = model.from_pretrained(args.resume_path, label2id=label2id, device=args.device)
    else:
        model = model.from_pretrained(args.pretrain_model,label2id=label2id,device=args.device)
    model = model.to(args.device)
    t_total = int(len(train_dataloader) / args.gradient_accumulation_steps * args.epochs)

    bert_param_optimizer = list(model.bert.named_parameters())
    lstm_param_optimizer = list(model.bilstm.named_parameters())
    crf_param_optimizer = list(model.crf.named_parameters())
    linear_param_optimizer = list(model.classifier.named_parameters())
    no_decay = ['bias', 'LayerNorm.bias', 'LayerNorm.weight']
    optimizer_grouped_parameters = [
        {'params': [p for n, p in bert_param_optimizer if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01,
         'lr': args.learning_rate},
        {'params': [p for n, p in bert_param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay': 0.0,
         'lr': args.learning_rate},
        {'params': [p for n, p in lstm_param_optimizer if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01,
         'lr': 0.001},
        {'params': [p for n, p in lstm_param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay': 0.0,
         'lr': 0.001},
        {'params': [p for n, p in crf_param_optimizer if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01,
         'lr': 0.001},
        {'params': [p for n, p in crf_param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay': 0.0,
         'lr': 0.001},
        {'params': [p for n, p in linear_param_optimizer if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01,
         'lr': 0.001},
        {'params': [p for n, p in linear_param_optimizer if any(nd in n for nd in no_decay)], 'weight_decay': 0.0,
         'lr': 0.001}
    ]
    if args.optimizer == 'adam':
        optimizer = BertAdam(optimizer_grouped_parameters, lr=args.learning_rate,
                             warmup=args.warmup_proportion, t_total=t_total)
    elif args.optimizer == 'lookahead':
        base_optimizer = BertAdam(optimizer_grouped_parameters, lr=args.learning_rate,
                             warmup=args.warmup_proportion, t_total=t_total)
        optimizer = Lookahead(base_optimizer,k=5,alpha=0.5)
    else:
        raise ValueError("unknown optimizer")
    lr_scheduler = BERTReduceLROnPlateau(optimizer, lr=args.learning_rate, mode=args.mode, factor=0.5, patience=5,
                                         verbose=1, epsilon=1e-8, cooldown=0, min_lr=0, eps=1e-8)
    if args.fp16:
        try:
            from apex import amp
        except ImportError:
            raise ImportError("Please install apex from https://www.github.com/nvidia/apex to use fp16 training.")
        model, optimizer = amp.initialize(model, optimizer, opt_level=args.fp16_opt_level)

    logger.info("initializing callbacks")
    train_monitor = TrainingMonitor(file_dir=config['figure_dir'], arch=args.arch)
    model_checkpoint = ModelCheckpoint(checkpoint_dir=args.model_path,mode=args.mode,monitor=args.monitor,
                                       arch=args.arch,save_best_only=args.save_best)

    # **************************** training model ***********************
    logger.info("***** Running training *****")
    logger.info("  Num examples = %d", len(train_examples))
    logger.info("  Num Epochs = %d", args.epochs)
    logger.info("  Total train batch size (w. parallel, distributed & accumulation) = %d",
                args.train_batch_size * args.gradient_accumulation_steps * (
                    torch.distributed.get_world_size() if args.local_rank != -1 else 1))
    logger.info("  Gradient Accumulation steps = %d", args.gradient_accumulation_steps)
    logger.info("  Total optimization steps = %d", t_total)
    trainer = Trainer(n_gpu=args.n_gpu,
                      model=model,
                      logger=logger,
                      optimizer=optimizer,
                      lr_scheduler=lr_scheduler,
                      label2id = label2id,
                      training_monitor=train_monitor,
                      fp16=args.fp16,
                      resume_path=args.resume_path,
                      grad_clip=args.grad_clip,
                      model_checkpoint=model_checkpoint,
                      gradient_accumulation_steps=args.gradient_accumulation_steps)
    trainer.train(train_data=train_dataloader, valid_data=valid_dataloader, epochs = args.epochs,seed=args.seed)

def run_test(args):
    from pydatagrand.callback import ProgressBar
    from pydatagrand.train.ner_utils import get_entities
    from pydatagrand.common.tools import save_pickle

    processor = BertProcessor(args.model_path / 'vocab.txt', args.do_lower_case)
    label_list = processor.get_labels()
    label2id = {label: i for i, label in enumerate(label_list)}
    id2label = {i: label for i, label in enumerate(label_list)}
    if args.use_mdp:
        model = BERTLSTMCRFMDP
    else:
        model = BERTLSTMCRF
    model = model.from_pretrained(args.resume_path, label2id=label2id, device=args.device)
    model.to(args.device)
    max_seq_len = args.eval_max_seq_len
    tokenizer = processor.tokenizer
    test_data = []
    with open(str(config['data_dir'] / 'test.txt'), 'r') as fr:
        for line in fr:
            line = line.strip("\n")
            test_data.append(line)
    test_result_path = config['result_dir'] / f'{args.arch}_test_submit_{str(datetime.date.today())}.txt'
    fw = open(str(test_result_path), 'w')
    pbar = ProgressBar(n_total=len(test_data),desc='Testing')
    pred_tags = []
    for step, line in enumerate(test_data):
        token_a = line.split("_")
        tokens = tokenizer.tokenize(token_a)
        valid = [1] * len(tokens)
        if len(tokens) >= max_seq_len - 1:
            tokens = tokens[0:(max_seq_len - 2)]
            valid = valid[0:(max_seq_len - 2)]
        ntokens = []
        segment_ids = []
        ntokens.append("[CLS]")
        segment_ids.append(0)
        valid.insert(0, 1)
        for i, token in enumerate(tokens):
            ntokens.append(token)
            segment_ids.append(0)
        ntokens.append("[SEP]")
        segment_ids.append(0)
        valid.append(1)
        input_ids = tokenizer.convert_tokens_to_ids(ntokens)
        input_mask = [1] * len(input_ids)
        input_lens = len(input_ids)
        input_ids = torch.tensor([input_ids], dtype=torch.long)
        segment_ids = torch.tensor([segment_ids], dtype=torch.long)
        input_mask = torch.tensor([input_mask], dtype=torch.long)
        input_lens = torch.tensor([input_lens], dtype=torch.long)
        input_ids = input_ids.to(args.device)
        input_mask = input_mask.to(args.device)
        segment_ids = segment_ids.to(args.device)
        input_lens = input_lens.cpu().detach().numpy().tolist()
        model.eval()
        with torch.no_grad():
            features = model(input_ids=input_ids, token_type_ids=segment_ids, attention_mask=input_mask)
            tags, _ = model.crf._obtain_labels(features, id2label, input_lens)
        tags = tags[0][1:-1]
        pred_tags.append(tags)
        label_entities = get_entities(tags, id2label,args.markup)
        if len(label_entities) == 0:
            record = "_".join(token_a) + "/o"
        else:
            labels = []
            label_entities = sorted(label_entities, key=lambda x: x[1])
            o_s = 0
            for i, entity in enumerate(label_entities):
                begin = entity[1]
                end = entity[2]
                tag = entity[0]
                if begin != o_s:
                    labels.append("_".join(token_a[o_s:begin]) + "/o")
                labels.append("_".join(token_a[begin:end + 1]) + f"/{tag}")
                o_s = end + 1
                if i == len(label_entities) - 1:
                    if o_s <= len(token_a) - 1:
                        labels.append("_".join(token_a[o_s:]) + "/o")
            record = "  ".join(labels)
        fw.write(record + "\n")
        pbar(step=step)
    fw.close()
    save_pickle(pred_tags, file_path=str(config['result_dir'] / f'{args.arch}_test_tags.pkl'))

def main():
    parser = ArgumentParser()
    parser.add_argument("--arch", default='bert_lstm_crf', type=str)
    parser.add_argument("--do_train", action='store_true')
    parser.add_argument("--do_test", action='store_true')
    parser.add_argument("--save_best", action='store_true')
    parser.add_argument("--do_lower_case", action='store_true')
    parser.add_argument('--do_mdp',action='store_true',help='whether use multi-sample dropout')
    parser.add_argument('--data_name', default='datagrand', type=str)
    parser.add_argument('--optimizer',default='adam',type=str,choices=['adam','lookahead'])
    parser.add_argument('--markup',default='bios',type=str,choices=['bio','bios'])
    parser.add_argument('--checkpoint', default=900000, type=int)
    parser.add_argument("--epochs", default=30.0, type=int)
    parser.add_argument('--fold',default=0,type=int)
    parser.add_argument("--resume_path", default='', type=str)
    parser.add_argument("--mode", default='max', type=str)
    parser.add_argument("--monitor", default='valid_f1', type=str)
    parser.add_argument("--local_rank", type=int, default=-1)
    parser.add_argument("--sorted", default=1, type=int, help='1:True  0:False ')
    parser.add_argument("--n_gpu", type=str, default='0', help='"0,1,.." or "0" or "" ')
    parser.add_argument('--gradient_accumulation_steps', type=int, default=1)
    parser.add_argument("--train_batch_size", default=24, type=int)
    parser.add_argument('--eval_batch_size', default=48, type=int)
    parser.add_argument("--train_max_seq_len", default=128, type=int)
    parser.add_argument("--eval_max_seq_len", default=512, type=int)
    parser.add_argument('--loss_scale', type=float, default=0)
    parser.add_argument("--warmup_proportion", default=0.05, type=float)
    parser.add_argument("--weight_decay", default=0.01, type=float)
    parser.add_argument("--adam_epsilon", default=1e-8, type=float)
    parser.add_argument("--grad_clip", default=5.0, type=float)
    parser.add_argument("--learning_rate", default=1e-4, type=float)
    parser.add_argument('--seed', type=int, default=42)
    parser.add_argument("--no_cuda", action='store_true')
    parser.add_argument('--fp16', action='store_true')
    parser.add_argument('--fp16_opt_level', type=str, default='O1')
    args = parser.parse_args()

    args.pretrain_model = config['checkpoint_dir'] / f'lm-checkpoint-{args.checkpoint}'
    args.device = torch.device(f"cuda" if torch.cuda.is_available() and not args.no_cuda else "cpu")
    args.arch = args.arch + f"_{args.markup}_fold_{args.fold}"
    if args.do_mdp:
        args.arch += "_mdp"
    if args.optimizer == 'lookahead':
        args.arch += "_lah"
    args.model_path = config['checkpoint_dir'] / args.arch
    args.model_path.mkdir(exist_ok=True)
    # Good practice: save your training arguments together with the trained model
    torch.save(args, args.model_path / 'training_args.bin')
    seed_everything(args.seed)
    init_logger(log_file=config['log_dir'] / f"{args.arch}.log")
    logger.info("Training/evaluation parameters %s", args)

    if args.do_train:
        run_train(args)

    if args.do_test:
        run_test(args)

if __name__ == '__main__':
    main()


def search_algorithm(problem, data_structure):
    """
    Search the deepest nodes in the search tree first.

    Your search algorithm needs to return a list of actions that reaches the
    goal. Make sure to implement a graph search algorithm.

    To get started, you might want to try some of these simple commands to
    understand the search problem that is being passed in:

    print "Start:", problem.getStartState()
    print "Is the start a goal?", problem.isGoalState(problem.getStartState())
    print "Start's successors:", problem.getSuccessors(problem.getStartState())
    """
    "*** YOUR CODE HERE ***"

    #Initialise data structure
    data_structure.push([(problem.getStartState(), "Start", 0)])
    states_visited = []

    while not data_structure.isEmpty():

        #Current state
        all_prev_states = data_structure.pop() #Path to current positon - all previous states
        position_current = all_prev_states[-1][0] #Current postion

        #i. Check if the current postion is the goal
        if problem.isGoalState(position_current):
            #Return the actions executed to reach the goal state
            actions_previous = [i[1] for i in all_prev_states]
            actions_previous = actions_previous[1:] #Discard starting state
            return actions_previous

        #ii. Check if the current state has been visited
        if position_current not in states_visited:
            #Append current state to visited
            states_visited.append(position_current)

        #Inspect successors
        successors = problem.getSuccessors(position_current)

        for successor in successors:
            position_successor = successor[0] #position of
            action_successor = successor[1] #direction needed to take to get to position

            if position_successor not in visited:
                #Get path taken to reach this state
                path_successors = all_prev_states
                #Append the successor path
                path_successors.append(successor)
                #Push to data structure
                data_structure.push(path_successors)

    #Return False if the search fails
    return False

def search_algorithm2(problem, structure):
    """
    Defines a general algorithm to search a graph.
    Parameters are structure, which can be any data structure with .push() and .pop() methods, and problem, which is the
    search problem.
    """

    # Push the root node/start into the data structure in this format: [(state, action taken, cost)]
    # The list pushed into the structure for the second node will look something like this:
    # [(root_state, "Stop", 0), (new_state, "North", 1)]
    structure.push([(problem.getStartState(), "Stop", 0)])

    # Initialise the list of visited nodes to an empty list
    visited = []

    # While the structure is not empty, i.e. there are still elements to be searched,
    while not structure.isEmpty():
        # get the path returned by the data structure's .pop() method
        path = structure.pop()

        # The current state is the first element in the last tuple of the path
        # i.e. [(root_state, "Stop", 0), (new_state, "North", 1)][-1][0] = (new_state, "North", 1)[0] = new_state
        curr_state = path[-1][0]

        # if the current state is the goal state,
        if problem.isGoalState(curr_state):
            # return the actions to the goal state
            # which is the second element for each tuple in the path, ignoring the first "Stop"
            return [x[1] for x in path][1:]

        # if the current state has not been visited,
        if curr_state not in visited:
            # mark the current state as visited by appending to the visited list
            visited.append(curr_state)

            # for all the successors of the current state,
            for successor in problem.getSuccessors(curr_state):
                # successor[0] = (state, action, cost)[0] = state
                # if the successor's state is unvisited,
                if successor[0] not in visited:
                    # Copy the parent's path
                    successorPath = path[:]
                    # Set the path of the successor node to the parent's path + the successor node
                    successorPath.append(successor)
                    # Push the successor's path into the structure
                    structure.push(successorPath)

    # If search fails, return False
    return False