from openpyxl import Workbook, load_workbook
import calendar
from datetime import datetime, timedelta, date
import os
from reportlab.platypus import SimpleDocTemplate, Table
from botdata import XL_FILE_PATH, SOLO_XL_FILE_PATH, SOLO_XL_FILE

class Meal:
    def __init__(self, filec: str) -> None:
        # targeted xlsx file, store meal data(date, meal of a person)
        self.xl_file = filec

    async def __xl2pdf(self, date: datetime):
        """
        save the sheet as pdf
        Args:
            None
        Return:
            None
        """
        wb = load_workbook(self.xl_file)
        sheet = wb.active

        # creating the pdf
        pdf_filename = f"{XL_FILE_PATH}/Month{date.month}.pdf"

        # Convert sheet data to a list of lists
        data = []
        for row in sheet.iter_rows(values_only=True):
            data.append(row)

        # Create the PDF document and add the table
        doc = SimpleDocTemplate(pdf_filename)
        table = Table(data)

        # Build the PDF document
        elements = [table]
        doc.build(elements)

    async def getDaysInMonth(self, year: int, month: int):
        """
        return number of days in the following month of the year
        """
        last_day = calendar.monthrange(year, month)[1]
        return last_day

    async def initializeSheet(self, names: list):
        """
        this method will only called first day of the month to create and initialize the sheet.
        previous date will be removed as new sheet will be created
        """
        # adding dates in the sheet creating date
        present_day = datetime.now()

        # only initialize new sheet at the first day of the month
        if present_day.day == 1:
            # if there is already a xl_file in the directory then we have to save the previous sheet as pdf
            for filename in os.listdir(SOLO_XL_FILE_PATH): #
                if filename == SOLO_XL_FILE:
                    await self.__xl2pdf(present_day - timedelta(1))
                    break

            year = date.today().year
            month = date.today().month
            num_of_days_in_month = await self.getDaysInMonth(year, month)

            # creating workbook and sheet
            # workbook = load_workbook(self.xl_file)
            workbook = Workbook()
            sheet1 = workbook.active

            # adding dates in the 1st column
            for i in range(0, num_of_days_in_month):
                next_day = (datetime.now() + timedelta(days=i)
                            ).strftime("%d-%m-%Y")
                cell = sheet1.cell(row=i + 2, column=1)
                cell.value = next_day

            # adding names in the 1st row
            for i, ele in enumerate(names):
                cell = sheet1.cell(row=1, column=i + 2)
                cell.value = ele

            # in the beginning set all the members meal into 11 for rest of the days in the month
            for nm in names:
                await self.writeAllMeal(present_day, nm, '11')
            # saving the sheet
            workbook.save(filename=self.xl_file)

    async def readMeal(self, date: datetime, name: str = 'All') -> dict:
        """
        return meal of a specific date.
        Args:
            date(DD-MM-YYYY) : date of meal
            name(optional) : name of a particular participant
        Return:
            dict    : name with number of meal
        """
        wb = load_workbook(self.xl_file)
        sheet1 = wb.active
        all_meals = {
            'Adil': 0,
            'Elias': 0,
            'Labib': 0,
            'Nahid': 0,
            'Nurul': 0,
            'Pallob': 0,
            'Prottus': 0,
            'Swadhin': 0
        }

        # calculating date_row from inputed date
        date_row = date.day + 1

        # converting datetime -> str
        date = date.strftime('%d-%m-%Y')

        # getting all the meals from that that row and saving in the dict
        for meal_number in range(2, 10):
            cell = sheet1.cell(row=1, column=meal_number)
            cell_head = cell.value  # cell_head represent the name belong to the cell
            cell = sheet1.cell(row=date_row, column=meal_number)
            # assigning the meal info in the dict from xlsx file
            all_meals[cell_head] = str(cell.value)

        # if no name provided, return all meal, else particular name meal
        if name == 'All':
            return all_meals
        else:
            return {name: all_meals[name]}

    async def writeAMeal(self, date: datetime, name: str, total_meal: str) -> None:
        """
        Write meal for a particular person
        Args:
            date(datetime object)    : date of the meal
            name    : meal holder name
            total_meal : number of meals(meal can be 00, 11, 01, 10)
        Return:
            None
        """
        # edit meal from current date to future dates. not previous dates
        present_day = datetime.today().date()
        if (date >= present_day):
            wb = load_workbook(self.xl_file)
            sheet1 = wb.active
            # finding the row of date
            date_row = date.day + 1
            date = date.strftime("%d-%m-%Y")  # converting datetime -> str

            # finding the name culumn
            name_col = 0
            for c in range(2, 10):
                cell = sheet1.cell(row=1, column=c)
                if cell.value == name:
                    name_col = c
                    break
            # setting the meal
            sheet1.cell(row=date_row, column=name_col).value = str(total_meal)
            wb.save(self.xl_file)

    async def writeAllMeal(self, date: datetime, name: str, total_meal: str):
        """
        write all the meal from 'date' to last date of the into total_meal
        Args:
            date(datetime object)    : date of the meal
            name    : meal holder name
            total_meal : number of meals(meal can be '00', '11', '01', '10')
        Return:
            None
        """
        present_day = datetime.today().date()
        # write meal only for today and next days. not previous days
        if (date >= present_day):
            total_days = await self.getDaysInMonth(date.year, date.month)
            reminding_days = total_days - date.day
            for i in range(reminding_days + 1):
                await self.writeAMeal(date + timedelta(i), name, total_meal)


from django.urls import path
from django.views.generic import TemplateView

from . import views

app_name = 'content'
urlpatterns = [
    path('docs/', views.Docs, name='docs'),
    path('opama/mateo_torres', views.Opama_Mateo_Torres, name='opama_mateo_torres'),
    path('opama/lucho_benitez/', views.Opama_Lucho_Benitez, name='opama_lucho_benitez'),
    path('opama/karl_niebuhr/', views.Opama_Karl_Niebuhr, name='opama_karl_niebuhr'),
]


import kate
import os
import sys

from copy import copy

def get_project_plugin():
    mainWindow = kate.mainInterfaceWindow()
    projectPluginView = mainWindow.pluginView("kateprojectplugin")
    return projectPluginView

def is_version_compatible(version):
    if not version:
        return True
    version_info = version.split(".")
    if len(version_info) == 0:
        return False
    elif len(version_info) == 1:
        return int(version_info[0]) == sys.version_info.major
    elif len(version_info) == 2:
        return int(version_info[0]) == sys.version_info.major and \
            int(version_info[1]) == sys.version_info.minor
    else:
        return int(version_info[0]) == sys.version_info.major and \
            int(version_info[1]) == sys.version_info.minor and \
            int(version_info[2]) == sys.version_info.micro

def add_extra_path(extra_path):
    if not getattr(sys, "original_path", None):
        sys.original_path = copy(sys.path)
        sys.original_modules = sys.modules.keys()
    else:
        i = len(sys.path) - 1
        while i >= 0:
            path = sys.path[i]
            if not path in sys.original_path:
                del sys.path[i]
            i = i - 1
        for module in sys.modules.keys():
            if not module in sys.original_modules:
                del sys.modules[module]
    extra_path.reverse()
    for path in extra_path:
        if not path in sys.path:
            sys.path.insert(0, path)
    sys.path_importer_cache = {}

def add_environs(environs):
    for key, value in environs.items():
        if key in os.environ:
            os.environ.pop(key)
        os.environ.setdefault(key, value)


from fastapi import APIRouter, status, HTTPException
from sqlalchemy.orm import Session
from fastapi import Depends
from fastapi_pagination import Page
from fastapi_pagination.ext.sqlalchemy import paginate

from db.sessions import get_db
from schemas.blog import ShowBlog, CreateBlog, UpdateBlog
from db.repository.blog import create_new_blog, retreive_blog, list_blogs, update_blog, delete_blog
from typing import List
from db.models.user import User
from apis.v1.route_login import get_current_user
from fastapi_cache.decorator import cache

router = APIRouter()

@router.post("/blog", response_model=ShowBlog, status_code=status.HTTP_201_CREATED)
async def create_blog(blog: CreateBlog, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    blog = create_new_blog(blog=blog, db=db, author_id=current_user.id)
    return blog

@router.get("/blog/{id}", response_model=ShowBlog)
@cache(expire=60)
async def get_blog(id: int, db: Session = Depends(get_db)):
    blog = retreive_blog(id=id, db=db)
    if not blog:
        raise HTTPException(detail=f"Запись блога с id {id} не существует", status_code=status.HTTP_404_NOT_FOUND)
    return blog

@router.get("/blogs", response_model=Page[ShowBlog])
@cache(expire=60)
async def get_all_published(db: Session = Depends(get_db)):
    blogs = list_blogs(db=db)
    return paginate(blogs)

@router.put("/blog/{id}", response_model=ShowBlog)
async def update_a_blog(id: int, blog: UpdateBlog, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    blog = update_blog(id=id, blog=blog, author_id=current_user.id, db=db)
    if not blog:
        raise HTTPException(detail=f"Запись блога с id {id} не существует", status_code=status.HTTP_404_NOT_FOUND)
    return blog

@router.delete("/delete/{id}")
def delete_a_blog(id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
    message = delete_blog(id=id, author_id=current_user.id, db=db)
    if message.get("error"):
        raise HTTPException(detail=message.get("error"), status_code=status.HTTP_400_BAD_REQUEST)
    return {"msg": f"Успешно удалена запись с id {id}"}


import logging
import threading
import oc.logging

from kubernetes import client, watch

logger = logging.getLogger(__name__)

@oc.logging.with_logger()
class ODKubernetesWatcher:

    def __init__(self):
        self.orchestrator = oc.od.orchestrator.ODOrchestratorKubernetes()
        self.thead_event = None
        self.watch = None
        self.DEFAULT_K8S_WATCHER_TIMEOUT_SECONDS = 10

    def loopforevent( self ):
        self.logger.debug('' )
        self.watch = watch.Watch()
        while( True ): #  inifity loop stop when watch.stop
            try:
                # watch list_namespaced_pod waiting for a valid ip addr
                events = self.watch.stream(  self.orchestrator.kubeapi.list_namespaced_pod, namespace=self.orchestrator.namespace, timeout_seconds=self.DEFAULT_K8S_WATCHER_TIMEOUT_SECONDS)
                if self.watch._stop :
                    return  # stop this thread
                for event in events:
                    # event must be a dict, else continue
                    if not isinstance(event,dict):
                        self.logger.error( 'event type is %s, and should be a dict, skipping event', type( event ))
                        continue

                    # event dict must contain a type
                    event_type = event.get('type')
                    if event_type == 'MODIFIED':
                        self.logger.debug( f"event {event_type} receive" )
                        # event dict must contain a object
                        pod_event = event.get('object')
                        # if podevent type is pod
                        if isinstance( pod_event, client.models.v1_pod.V1Pod ) :
                            self.logger.debug( f"{event_type} -> {pod_event.metadata.name}" )
                            podtype = pod_event.metadata.labels.get( 'type' )
                            if podtype == self.orchestrator.applicationtype :
                                self.logger.debug( f"{event_type} -> {pod_event.metadata.name}:{podtype}" )
                                if isinstance( pod_event.status, client.models.v1_pod_status.V1PodStatus ):
                                    if not isinstance(pod_event.status.container_statuses, list):
                                        continue
                                    state = pod_event.status.container_statuses[0].state
                                    if isinstance( state.terminated, client.models.v1_container_state_terminated.V1ContainerStateTerminated ):
                                        self.logger.debug( f"{event_type} -> {pod_event.metadata.name} phase: {pod_event.status.phase} reason:{state.terminated.reason}" )
                                        if state.terminated.reason == 'Completed':
                                            self.orchestrator.removePod( pod_event )

                    if event_type == 'DELETED':
                        self.logger.debug( f"event {event_type} receive" )
                        # event dict must contain a object
                        pod_event = event.get('object')
                        # if podevent type is pod
                        if isinstance( pod_event, client.models.v1_pod.V1Pod ) :
                            self.logger.debug( f"{event_type} -> {pod_event.metadata.name}" )
                            podtype = pod_event.metadata.labels.get( 'type' )
                            if podtype == self.orchestrator.x11servertype :
                                self.logger.debug( f"{event_type} -> {pod_event.metadata.name}:{podtype}" )
                                desktop = self.orchestrator.pod2desktop( pod_event )
                                oc.od.composer.detach_container_from_network(desktop.name)
            except Exception as e:
                self.logger.debug( e )
                pass

    def start(self):
        self.logger.debug('starting watcher thread')
        self.thead_event = threading.Thread(target=self.loopforevent)
        self.thead_event.start() # infinite loop until events.close()

    def stop(self):
        self.logger.debug('ODKubernetesWatcher thread stopping')
        if isinstance( self.thead_event, threading.Thread ):
            while self.thead_event.is_alive():
                self.logger.debug('thread watcher is alive')
                if isinstance(self.watch, watch.Watch ) :
                    self.logger.debug('ODKubernetesWatcher watch closing')
                    self.watch.stop() # this will stop the thread self.thead_event
                    self.logger.debug('ODKubernetesWatcher watch closed')

                self.logger.debug('ODKubernetesWatcher join start timeout=5')
                self.thead_event.join(timeout=5)
                self.logger.debug('ODKubernetesWatcher join done')
            else:
                self.logger.debug('thread watcher is not alive')

        self.watch = None
        self.thead_event = None

        self.logger.debug('ODKubernetesWatcher thread stopped')


import glob
import cv2
import numpy as np
from utils import *

def pca(img, n_components=9):
    """
    Perform PCA dimensionality reduction on the input image
    :param img: a numpy array of shape (n_samples, dim_images)
    :param n_components: number of principal components for projection
    :return: image in PCA projection, a numpy array of shape (n_samples, n_components)
    """

    # Compute the covariance matrix
    cov_mat = np.cov(img.T)

    # Compute the eigenvectors and eigenvalues
    eig_val_cov, eig_vec_cov = np.linalg.eig(cov_mat)

    # Make a list of (eigenvalue, eigenvector) tuples
    eig_pairs = [
        (np.abs(eig_val_cov[i]), eig_vec_cov[:, i]) for i in range(len(eig_val_cov))
    ]

    # Select n_components eigenvectors with largest eigenvalues, obtain subspace transform matrix
    eig_pairs.sort(key=lambda x: x[0], reverse=True)
    eig_pairs = np.array(eig_pairs)
    matrix_w = np.hstack(
        [eig_pairs[i, 1].reshape(img.shape[1], 1) for i in range(n_components)]
    )

    # Return samples in new subspace
    return np.dot(img, matrix_w), matrix_w

def inverse_pca(img, components):
    """
    Obtain the reconstruction after PCA dimensionality reduction
    :param img: Reduced image, a numpy array of shape (n_samples, n_components)
    :param components: a numpy array of size (original_dimension, n_components)
    :return:
    """
    reconstruct = np.dot(img, components.T).astype(int)
    return reconstruct.reshape(-1,28,28)

def mds(data, n_components=2):
    """
    Apply multidimensional scaling (aka Principal Coordinates Analysis)
    :param data: nxn square distance matrix
    :param n_components: number of components for projection
    :return: projected output of shape (n_components, n)
    """

    # Center distance matrix
    center(data)

    # Make a list of (eigenvalue, eigenvector) tuples
    eig_val_cov, eig_vec_cov = np.linalg.eig(data)
    eig_pairs = [
        (np.abs(eig_val_cov[i]), eig_vec_cov[:, i]) for i in range(len(eig_val_cov))
    ]

    # Select n_components eigenvectors with largest eigenvalues, obtain subspace transform matrix
    eig_pairs.sort(key=lambda x: x[0], reverse=True)
    eig_pairs = np.array(eig_pairs)
    matrix_w = np.hstack(
        [eig_pairs[i, 1].reshape(data.shape[1], 1) for i in range(n_components)]
    )

    # Return samples in new subspace
    return matrix_w

def isomap(data, n_components=2, n_neighbors=6, dist=False):
    """
    Dimensionality reduction with isomap algorithm
    :param data: input image matrix of shape (n,m) if dist=False, square distance matrix of size (n,n) if dist=True
    :param n_components: number of components for projection
    :param n_neighbors: number of neighbors for distance matrix computation
    :param dist: boolean indicating the data type
    :return: Projected output of shape (n_components, n)
    """
    if not dist:
        # Compute distance matrix
        data, _ = distance_mat(data, n_neighbors)

    # Compute shortest paths from distance matrix
    from sklearn.utils.graph import graph_shortest_path
    graph = graph_shortest_path(data, directed=False)
    graph = -0.5 * (graph ** 2)

    # Return the MDS projection on the shortest paths graph
    return mds(graph, n_components)

def LLE(data, neighbors_idx=None, n_components=2, n_neighbors=6):
    """
    Dimensionality reduction with FastLLE algorithm
    :param data: input image matrix of shape (n,m)
    :param n_components: number of components for projection
    :param n_neighbors: number of neighbors for the weight extraction
    :return: Projected output of shape (n_components, n)
    """
    if neighbors_idx is None:
        # Compute the nearest neighbors
        _, neighbors_idx = distance_mat(data, n_neighbors)

    n = data.shape[0]
    w = np.zeros((n, n))
    for i in range(n):
        # Center the neighbors matrix
        k_indexes = neighbors_idx[i, :]
        neighbors = data[k_indexes, :] - data[i, :]

        # Compute the corresponding gram matrix
        gram_inv = np.linalg.pinv(np.dot(neighbors, neighbors.T))

        # Setting the weight values according to the lagrangian
        lambda_par = 2/np.sum(gram_inv)
        w[i, k_indexes] = lambda_par*np.sum(gram_inv, axis=1)/2
    m = np.subtract(np.eye(n), w)
    values, u = np.linalg.eigh(np.dot(np.transpose(m), m))
    return u[:, 1:n_components+1]

def demo():
    images = []
    for path in glob.glob("four_dataset/*.jpg"):
        images.append(cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2GRAY))
    flat_images = np.array(images).reshape(982, -1)
    for k in [2, 16, 64, 256]:
        # Perform PCA transform
        pca_images, components = pca(flat_images, k)

        # Check the dimension of the reduced dataset
        print(pca_images.shape)

        # Reconstruct from PCA reduction
        reconstruct = inverse_pca(pca_images, components)

        # Compute MSE between original image and reconstructed image
        mse = [mean_square_error(a,b) for a,b in zip(images, reconstruct)]
        print("Dimension {}, best MSE: {}, worst MSE: {}, MSE over all samples: {}".format(k, min(mse), max(mse), sum(mse)/len(mse)))

        # Save visualization of reductions on four0.jpg
        cv2.imwrite("output/pca_{}.jpg".format(k), reconstruct[0])

if __name__ == "__main__":
    data = np.load("digits-labels.npz")

    # Select columns of five
    d = data['d']
    l = data['l']
    five_idx = np.argwhere(l == 5)
    d_fives = d[:, five_idx].squeeze().T

    # Perform PCA
    transform_pca, components = pca(d_fives, n_components=2)
    print(transform_pca.shape)
    show(transform_pca, d_fives, 'output/pca.png')

    # Perform Isomap
    distances, neighbors_idx = distance_mat(d_fives)
    transform_isomap = isomap(distances, dist=True)
    print(transform_isomap.shape)
    show(transform_isomap, d_fives, 'output/isomap.png')

    # Perform LLE
    transform_lle = LLE(d_fives, neighbors_idx)
    print(transform_lle.shape)
    show(transform_lle, d_fives, 'output/lle.png')


"""
Script per calcular paràmetres de EiR.
Aleix Martínez Vinent
Maig 2020
"""
import numpy as np
import scipy.constants as sci
import cmath
C = 3*(10**8)
e0=sci.epsilon_0
mu0=sci.mu_0
pi = np.pi
m = 10**(-3)
k = 10**3
M = 10**6
G = 10**9
directivity={7:[0.782,0.138],7.5:[0.824,0.146],8:[0.865,0.157],8.5:[0.892,0.165],9:[0.918,0.169],9.5:[0.935,0.174],10:[0.943,0.179],10.5:[0.957,0.182],11:[0.964,0.185]}

def log_periodic(fmin,fmax,dire):
    """
    Entrada:
    \t - Frequencia minima [Hz]
    \t - Frequencia maxima [Hz]
    \t - Directivitat [dBi]

    Sortida:
    \t - Vector de longitud dels dipols [m]
    \t - Vector de longituds entre dipols [m]

    """
    N = int(np.log10(fmin/fmax)/(np.log10(directivity[dire][0]))+1)
    L = [C/fmin]
    S = []
    for i in range(0,N):
        L.append(directivity[int(dire)][0]*L[i])
        S.append(2*directivity[int(dire)][1]*L[i])
    print(f"\n \n Nombre de branques: {len(L)} \n \n")
    return L,S

def horn(G,f,a,b,dB=True):
    """
    Entrada:
    \t - Guany [dBi]
    \t - Frequencia del guany [Hz]
    \t - a [m]
    \t - b [m]

    Sortida:
    \t - xi
    \t - roe [m]
    \t - roh [m]
    \t - a1 [m]
    \t - b1 [m]
    \t - pe [m]
    \t - ph [m]

    """
    if dB == True:
        G0=10**(G/10)
    xi=G0/(2*pi*np.sqrt(2*pi))
    wl=C/f
    pujar = False
    mod = 0.5
    X1=((np.sqrt(2*xi)-(b/wl))**2)*(2*xi-1)
    X2=(((G0/(2*pi))*(np.sqrt(3/(2*pi)))*(1/np.sqrt(xi))-(a/wl))**2)*(((G0**2)/(6*(pi**3)))*(1/xi)-1)
    D=np.abs(X1-X2)+1
    xant=0
    xalt=0
    xbaix=0

    """Obtencio de xi"""
    while np.abs(X1-X2)>0.0005:
        xant = xi
        Dant = D
        D = np.abs(X1-X2)

        if Dant > D:                       # Si diferència entre X1 i X2 era major abans, anem per bon camí
            mod*=0.9                                # Disminuim increment per no passar-nos i anar interpolant valor
            if pujar == False:
                xi -=mod
            else:
                xi+=mod

        else:                              # Si diferencia era menor abans, ens estem allunyant del valor correcte. Si abans haviem pujat ara haurem de baixar el valor de xi.
            mod*=0.91                                # Fem un increment major perque el d'abans era incorrecte i així tornem cap enrrera.
            if pujar == False:                              # Si abans haviem baixat, hem de tornar cap enrrera i pujar
                xi+=mod
                pujar = True
            else:                                           # Si abans haviem pujat, hem de tornar cap enrrera i baixar
                xi-=mod
                pujar = False
        X1=((np.sqrt(2*xi)-(b/wl))**2)*(2*xi-1)
        X2=(((G0/(2*pi))*(np.sqrt(3/(2*pi)))*(1/np.sqrt(xi))-(a/wl))**2)*(((G0**2)/(6*(pi**3)))*(1/xi)-1)

    print(f"\n \n Valor de x: {xi} \n ")
    print(str(X1) + " = " + str(X2))

    """Obtencio dels demes parametres"""
    roe=xi*wl
    roh=(wl/xi)*(G0**2)/(8*(pi**3))
    a1=(G0/(2*pi))*wl*np.sqrt(3/(2*pi*xi))
    b1=np.sqrt(2*xi)*wl
    pe=(b1-b)*np.sqrt(-(1/4)+(roe/b1)**2)
    ph=(a1-a)*np.sqrt(-(1/4)+(roh/a1)**2)
    return xi,roe,roh,a1,b1,pe,ph

def patch(f,er,d):
    """
    Dissenya una antena de patch a partir dels seguents parametres:
    \t - Frequencia de funcionament [Hz]
    \t - Permitivitat del substrat [F/m]
    \t - Gruixor del substrat [m]

    """
    wl=C/f
    W = (1/(2*f*np.sqrt(e0*mu0)))*np.sqrt(2/(er+1))
    ereff = (er+1)/2+(er-1)/(2*np.sqrt(1+(12*d/W)))
    dL = 0.412*d*(ereff + 0.3)*((W/d)+0.264)/((ereff-0.258)*((W/d)+0.8))
    L = (1/(2*f*np.sqrt(ereff)*np.sqrt(e0*mu0)))-(2*dL)
    Za = (90*(er**2)*((L/W)**2))/(er-1)
    df = (16*(er-1)*L*d)/(3*np.sqrt(2)*(er**2)*wl*W)
    if W > 3*wl:
        return W,dL,L,ereff,8*(W/wl),Za,df

    else:
        return W,dL,L,ereff,8.2,Za,df

def max_range(f,Pt,Dt,Dr,Pl):
    """
    Calcula distància màxima que pot viatjar un senyal transmes per una antena per ser rebuda per una altra a partir dels seguents parametres:
    \t - Frequencia de funcionament [Hz]
    \t - Potencia transmesa [W]
    \t - Directivitat antena transmissora [dBi]
    \t - Directivitat antena receptora [dBi]
    \t - Sensibilitat d'antena receptora [dB]

    Retorna distancia en km.
    """
    L0=Dt+Dr + 10*np.log10(Pt*1000)-Pl
    r=10**((L0-32.5-20*np.log10(f/(10**6)))/20)
    return r

def min_sensibility(f,r,Pt,Dt,Dr):
    """
    Calcula sensibilitat mínima [dBi] que ha de tenir antena per rebre un senyal transmes per una antena a una certa distancia a partir dels seguents parametres:
    \t - Frequencia de funcionament [Hz]
    \t - Distància entre les dues antenes [m]
    \t - Potencia transmesa [W]
    \t - Directivitat antena transmissora [dBi]
    \t - Directivitat antena receptora [dBi]
    \t - Sensibilitat d'antena receptora [dBm]

    """
    return 10*np.log10(Pt*1000)+Dt+Dr-(32.5+20*np.log10(f/(10**6))+20*np.log10(r/1000))

def recieved_power(f,r1,CS,Pt,Dt,B=False,Dr=0,r2=0):
    """
    Calcula potencia rebuda per un radar. Dos modes de funcionament: per mateixa antena o per dues.

    1 sola antena:
    \t - Frequencia de funcionament [Hz]
    \t - Distància de l'objecte [m]
    \t - Cross Section de l'objecte [m^2]
    \t - Potencia transmesa [W]
    \t - Directivitat antena [dBi]
    \t - True (1 sola antena)

    2 antenes:
    \t - Frequencia de funcionament [Hz]
    \t - Distància entre radar emissor i l'objecte [m]
    \t - Cross Section de l'objecte [m^2]
    \t - Potencia transmesa [W]
    \t - Directivitat antena emissora [dBi]
    \t - False (1 sola antena)
    \t - Directivitat antena receptora [dBi]
    \t - Distància entre radar receptor i l'objecte [m]

    """
    wl=C/f
    Dt=10**(Dt/10)
    Dr=10**(Dr/10)
    if B==True:
        Pl=(Pt*CS*(Dt**2)*(wl**2))/(((4*pi)**3)*(r1**4))
    else:
        Pl=((Pt*CS*Dr*Dt)/(4*pi))*((wl/(4*pi*r1*r2))**2)
    return 10*np.log10(Pl)

def cross_section(f,r1,Pt,Pl,Dt,B=False, dB=False,Dr=0,r2=0):
    """
    Calcula cross section d'un objecte observat per un radar. Dos modes de funcionament: per mateixa antena o per dues.

    1 sola antena:
    \t - Frequencia de funcionament [Hz]
    \t - Distància de l'objecte [m]
    \t - Potencia transmesa [W]
    \t - Potencia rebuda [W]
    \t - Directivitat antena [dBi]
    \t - True (1 sola antena)
    |t - Directivitat expressat en dB [bool]

    2 antenes:
    \t - Frequencia de funcionament [Hz]
    \t - Distància entre radar emissor i l'objecte [m]
    \t - Potencia transmesa [W]
    \t - Potencia rebuda [W]
    \t - Directivitat antena emissora [dBi]
    \t - False (2 antenes)
    \t - Directivitat antena receptora [dBi]
    \t - Distància entre radar receptor i l'objecte [m]
    |t - Directivitat expressat en dB [bool]

    """
    wl=C/f
    if dB == True:
        Dt=10**(Dt/10)
        Dr=10**(Dr/10)

    if B==True:
        CS=(Pl/Pt)*((((4*pi)**3)*(r1**4))/((Dt**2)*(wl**2)))
    else:
        CS=(Pl/Pt)*(((4*pi)/(Dt*Dr))*(1/((wl/(4*pi*r1*r2))**2)))
    return CS
"""
def polar_to_rect_S(S11,S12,S21,S22,radians = False):
    if radians == False:
        if S11[1]>=0:
            S11[1]=S11[1]*(pi/180)
        else:
            S11[1]=(365-S11[1])*(pi/180)
        if S12[1]>=0:
            S12[1]=S12[1]*(pi/180)
        else:
            S12[1]=(365-S12[1])*(pi/180)
        if S21[1]>=0:
            S21[1]=S21[1]*(pi/180)
        else:
            S21[1]=(365-S21[1])*(pi/180)
        if S22[1]>=0:
            S22[1]=S22[1]*(pi/180)
        else:
            S22[1]=(365-S22[1])*(pi/180)

    c1 = [cmath.rect(S11[0],S11[1]), cmath.rect(S12[0],S12[1])]
    c2 = [cmath.rect(S21[0],S21[1]), cmath.rect(S22[0],S22[1])]
    x = [c1, c2]

    return x
"""

def polar_to_rect_S(S11,S12,S21,S22,radians = False):
    if radians == False:
            S11[1]=np.deg2rad(S11[1])
            S12[1]=np.deg2rad(S12[1])
            S21[1]=np.deg2rad(S21[1])
            S22[1]=np.deg2rad(S22[1])
    c1 = [cmath.rect(S11[0],S11[1]), cmath.rect(S12[0],S12[1])]
    c2 = [cmath.rect(S21[0],S21[1]), cmath.rect(S22[0],S22[1])]
    x = [c1, c2]

    return x

def polar_to_rect(P, radians = False):
    if radians == False:
        if P[1]>=0:
            P[1]=P[1]*(pi/180)
        else:
            P[1]=(365-P[1])*(pi/180)
        return cmath.rect(P[0],P[1])

def rect_to_polar(X,todegrees=True):
    P = cmath.polar(X)
    if todegrees==False:
        return P
    else:
        C = (P[0], P[1]*(180/pi))
        return C

def transistor_amplifier(Z0,Zs,Zl,S):
    LS = ((Zs-Z0)/(Zs+Z0))
    LL = ((Zl-Z0)/(Zl+Z0))
    Lin = S[0][0] + ((S[0][1]*S[1][0]*LL)/(1-(S[1][1]*LL)))
    Lout = S[1][1] + ((S[0][1]*S[1][0]*LS)/(1-(S[0][0]*LS)))

    if (LL == LS):
        GT = np.abs(S[1][0])**2
    else:
        GT = ((np.abs(S[1][0])**2)*(1-(np.abs(LS)**2))*(1-(np.abs(LL)**2)))/((np.abs(1-(LS*Lin))**2)*(np.abs(1-(S[1][1]*LL))**2))

    return GT, LS, LL, Lin, Lout, 10*np.log10(GT)

def two_port_TAMP(Z0,Zs,Zl,S,unilateral=False):
    LS = ((Zs-Z0)/(Zs+Z0))
    LL = ((Zl-Z0)/(Zl+Z0))
    Lin = S[0][0] + ((S[0][1]*S[1][0]*LL)/(1-(S[1][1]*LL)))
    G0 =np.abs(S[1][0])**2
    GT = (1-(np.abs(LL)**2))/(np.abs(1-(S[1][1]*LL))**2)
    if unilateral == False:
        GS = (1-(np.abs(LS)**2))/(np.abs(1-(LS*Lin))**2)
    else:
        GS = (1-(np.abs(LS)**2))/(np.abs(1-(LS*S[0][0]))**2)
    G = GS*G0*GT
    return G, 10*np.log10(G)

def rollet(S):
    diff = S[0][0]*S[1][1]-S[0][1]*S[1][0]
    K = (1-np.abs(S[0][0])**2-np.abs(S[1][1])**2+np.abs(diff)**2)/(2*np.abs(S[0][1]*S[1][0]))
    if K > 1:
        unconditional = True
    else:
        unconditional = False

    return unconditional, K, diff

def stability_circles(S):
    diff = S[0][0]*S[1][1]-S[0][1]*S[1][0]
    CL = np.conj(S[1][1]-(diff*np.conj(S[0][0])))/(np.abs(S[1][1])**2-np.abs(diff)**2)
    RL = np.abs((S[0][1]*S[1][0])/((np.abs(S[1][1])**2)-(np.abs(diff)**2)))
    CS = np.conj(S[0][0]-(diff*np.conj(S[1][1])))/(np.abs(S[0][0])**2-np.abs(diff)**2)
    RS = np.abs((S[0][1]*S[1][0])/((np.abs(S[0][0])**2)-(np.abs(diff)**2)))
    return CL, RL, CS, RS

def LS_LL_LIN_LOUT(Z0,Zs,Zl,S):
    LS = ((Zs-Z0)/(Zs+Z0))
    LL = ((Zl-Z0)/(Zl+Z0))
    Lin = S[0][0] + ((S[0][1]*S[1][0]*LL)/(1-(S[1][1]*LL)))
    Lout = S[1][1] + ((S[0][1]*S[1][0]*LS)/(1-(S[0][0]*LS)))
    return LS, LL, Lin, Lout

def amp_max_gain(Z0,Zs,Zl,S):
    LS,LL,Lin,Lout = LS_LL_LIN_LOUT(Z0,Zs,Zl,S)
    if (Lin == np.conj(LS) and Lout == np.conj(LL)):
        conj = True
    if (S[0][1]<=0.01):
        uni = True
    if conj == True:
        GT_MAX = (1/(1-(np.abs(LS)**2)))*(np.abs(S[1][0])**2)*((1-(np.abs(LL)**2))/np.abs(1-(S[1][1]*LL))**2)
    elif uni == True:
        GT_MAX = (1/(1-(np.abs(S[0][0])**2)))*(np.abs(S[1][0])**2)*(1/np.abs(1-(S[1][1]*LL))**2)
    else:
        return 0
    return GT_MAX

def spec_gain_mal(Z0,Zs,Zl,S,Gs=1,Gs_MAX=0, Gl=1, Gl_MAX=0):
        LS,LL,Lin,Lout = LS_LL_LIN_LOUT(Z0,Zs,Zl,S)
        if Gs == 0 and Gs_MAX == 0:
            gs =(1-(np.abs(S[0][0])**2))*((1-(np.abs(LS)**2))/(np.abs(1-(S[0][0]*LS))**2))
        elif Gs_MAX == 0:
            gs = Gs/(1/(1-(np.abs(S[0][0])**2)))
        else:
            gs = Gs/Gs_MAX

        if Gl == 0 and Gl_MAX == 0:
            gl =(1-(np.abs(S[1][1])**2))*((1-(np.abs(LL)**2))/(np.abs(1-(S[1][1]*LL))**2))
        elif Gl_MAX == 0:
            gl = Gl/(1/(1-(np.abs(S[1][1])**2)))
        else:
            gl = Gl/Gl_MAX

        CS = (gs*np.conj(S[0][0]))/(1-(1-gs)*(np.abs(S[0][0])**2))
        RS = (np.sqrt(1-gs)*(1-(np.abs(S[0][0])**2)))/(1-(1-gs)*(np.abs(S[0][0])**2))
        CL = (gl*np.conj(S[1][1]))/(1-(1-gl)*(np.abs(S[1][1])**2))
        RL = (np.sqrt(1-gl)*(1-(np.abs(S[1][1])**2)))/(1-(1-gl)*(np.abs(S[1][1])**2))
        return CS, RS, CL, RL

def spec_gain(Z0,S,Gs, Gl, polar=True, dB=True, Gs_MAX=0, Gl_MAX=0):
        if dB == True:
            Gs = 10**(Gs/10)
            Gl = 10**(Gl/10)

        if Gs_MAX == 0:
            gs = Gs/(1/(1-(np.abs(S[0][0])**2)))
        else:
            gs = Gs/Gs_MAX
        if Gl_MAX == 0:
            gl = Gl/(1/(1-(np.abs(S[1][1])**2)))
        else:
            gl = Gl/Gl_MAX

        CS = (gs*np.conj(S[0][0]))/(1-(1-gs)*(np.abs(S[0][0])**2))
        RS = (np.sqrt(1-gs)*(1-(np.abs(S[0][0])**2)))/(1-(1-gs)*(np.abs(S[0][0])**2))
        CL = (gl*np.conj(S[1][1]))/(1-(1-gl)*(np.abs(S[1][1])**2))
        RL = (np.sqrt(1-gl)*(1-(np.abs(S[1][1])**2)))/(1-(1-gl)*(np.abs(S[1][1])**2))
        if polar == True:
            return rect_to_polar(CS),RS,rect_to_polar(CL),RL
        return CS, RS, CL, RL

def low_noise_amp(Z0, RN, Lopt, NF, NFmin,dB=True,polarinput=True):
    """
    Parameters
    ----------
    Z0 : float
        Characteristic impedance.
    RN : float
        Equivalent noise resistance of transistor.
    Lopt : complex (rectangular)
        OPtimum source reflection coefficient (Ls).
    NF : float
        Desired Noise Figure.
    NFmin : float
        Minimum Noise Figure of System.
    dB : boolean, optional
        True if NF and NFmin are in dB. The default is True.

    Returns
    -------
    N

    CNF : complex
        Circle center.
    RNF : float
        Radius of constant NF circle.

    """
    if polarinput == True:
        Lopt = polar_to_rect(Lopt)
    if dB==True:
        NF = 10**(NF/10)
        NFmin = 10**(NFmin/10)
    N = (np.abs(1+Lopt)**2)*((NF-NFmin)/((4*RN)/(Z0)))
    CNF = Lopt/(N+1)
    RNF = np.sqrt(N*(N+1-(np.abs(Lopt)**2)))/(N+1)
    return N,CNF,RNF

def required_PN(C,S,I,BW):
    """

    Parametres
    ----------
    C : float
        Nivell desitjat de senyal (dBm).
    S : float
        Nivell desitjat de canal adjacent (dB).
    I : float
        Nivell no desitjat de senyal de soroll (dBm).
    BW : float
        Amplada de banda del filtre IF (Hz).

    Retorna
    -------
    L : float
        Maxim soroll de fase per aconseguir un aïllament de canal adjacent de S (paràmetre entrada) (dBc/Hz).

    """
    L = C -S -I -10*np.log10(BW)
    return L

def GC_LC(PIF,PRF):
    """
    Retorna Gc (Conversion Gain) i Lc (Conversion Loss)
    """
    return 10*np.log10(PIF/PRF),20*np.log10(10*np.log10(PIF/PRF))

Transciever Parameters Calculation Libraries/Calcul_Params_EIR.py


import threading
from enum import Enum
from typing import Any

import cv2
import numpy as np
from numpy import dtype
from numpy.core import generic
from numpy.core.records import ndarray

from build.Release import moving_average_module

class BackSubTyp(Enum):
    """
    Simple class to distinguish between the background subtraction types
    """
    MOG_OPEN_CV = 0
    KNN_OPEN_CV = 1
    MOVING_AVERAGE_PYTHON = 2
    MOVING_AVERAGE_C_WRAPPER = 3

class ThreshHoldTyp(Enum):
    """Simple class to distinguish between the threshold types"""
    ADAPTIV = 0
    MANUAL = 1
    OTSU = 2

class ThreshCalculationTyp(Enum):
    MEDIAN = 0
    MEDIAN_WEIGHTED = 1
    MEAN = 2
    MEAN_WEIGHTED = 3

class BackSubProcessor:
    def __init__(self, history: int = 10, sampling_rate: int = 1):
        """
        Parent Class of Back Sub Processors
        Each processor creates its own thread
        Sequence of a normal calculation:
        1. apply(frame) to set the next frame.
        2. _calculate() A function that waits for an event to start
        the correct calculation.
        Prevents so-called race conditions.
        In addition, self._calculation_lock is used.
        3. processed.frame, our finished image is generated with the help of _apply_filter().
        Each processor must overwrite _apply_filter.
        The OpenCV use their apply method here.
        Other subclasses can use the threads in a similar way. Or extend the methods to save frames in apply,
        for example.
        :param history: The number of frames to consider for background calculation
        :param sampling_rate: The rate at which frames are sampled for background calculation
        """
        self.processed_frame = None
        self._calculation_lock = threading.Lock()
        self._calculation_event = threading.Event()
        self._current_frame = None
        self._history = history
        self._sampling_rate = sampling_rate

    def apply(self, frame):
        """
        Each processor sets the current frame here
        and signals the calculation thread to start
        """
        self._current_frame = frame
        self._calculation_event.set()

    def start_calculation_thread(self):
        # Simple starting the calculation thread
        _calculation_thread = threading.Thread(target=self._calculate)
        _calculation_thread.daemon = True
        _calculation_thread.start()

    def _calculate(self):
        while True:
            self._calculation_event.wait()  # Wait for the event to be set
            self._calculation_event.clear()  # Clear the event
            with self._calculation_lock:
                self.processed_frame = self._apply_filter(self._current_frame)

    def _apply_filter(self, frame) -> ndarray[Any, dtype[generic]]:
        """
        Should return ndarray[Any, dtype[generic]]
        or simple the processed Frame!
        Will raise a NotImplementedError
        """
        raise NotImplementedError("Subclasses must implement _apply_filter")

class MogOpenCV(BackSubProcessor):
    def __init__(self, history=10):
        """
        Simple MOG implementation of open cv
        """
        super().__init__(history=history)
        self.backSub = cv2.createBackgroundSubtractorMOG2(history=self._history, detectShadows=False)

    def _apply_filter(self, frame):
        return self.backSub.apply(frame)

class KnnOpenCV(BackSubProcessor):
    def __init__(self, history=10):
        super().__init__(history=history)
        self.backSub = cv2.createBackgroundSubtractorKNN(history=self._history, detectShadows=False)

    def _apply_filter(self, frame):
        """
        Simple KNN implementation of open cv
        """
        return self.backSub.apply(frame)

class MovingAverageCWrapper(BackSubProcessor):
    def __init__(self, history):
        """
        Self implemented c wrapped moving average
        cv2.createBackgroundSubtractor Style
        """
        super().__init__(history=history)
        self.backSub = moving_average_module.MovingAverage(history, ThreshHoldTyp.MANUAL.value, 20)

    def _apply_filter(self, frame) -> ndarray[Any, dtype[generic]]:
        """
        returns a py::array_t<uint8_t> -> ndarray[Any, dtype[generic]]
        """
        return self.backSub.apply(frame)

class MovingAveragePython(BackSubProcessor):
    def __init__(self, history=10, omega_a=.2, omega_i=.8, omega_c=.5,
                 calculation_type=ThreshCalculationTyp.MEDIAN_WEIGHTED,
                 thresholding_typ=ThreshHoldTyp.ADAPTIV, threshold_manual=120):
        super().__init__(history=history)
        self._omega_a = omega_a
        self._omega_i = omega_i
        self._omega_c = omega_c
        self._threshold_typ = thresholding_typ
        self._threshold = threshold_manual
        self._calculation_typ = calculation_type
        self._frame_queue = []

    def __frame(self, frame):
        if self._threshold_typ == ThreshHoldTyp.ADAPTIV:
            thresh = cv2.adaptiveThreshold(frame, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, -2)
        else:
            _, thresh = cv2.threshold(frame, self._threshold, 255, cv2.THRESH_BINARY)
        return thresh

    def _median_filter(self, _):
        return np.median(self._frame_queue, axis=0).astype(np.uint8)

    def _weighted_median_filter(self, frame):
        median = np.median(self._frame_queue, axis=0).astype(np.uint8)
        background = np.multiply(self._omega_a, frame) + np.multiply(self._omega_i, median)
        return np.divide(background, self._omega_c).astype(np.uint8)

    def _mean_filter(self, _):
        return np.mean(self._frame_queue, axis=0).astype(np.uint8)

    def _weighted_mean_filter(self, frame):
        mean = np.mean(self._frame_queue, axis=0).astype(np.uint8)
        background = np.multiply(self._omega_a, frame) + np.multiply(self._omega_i, mean)
        return np.divide(background, self._omega_c).astype(np.uint8)

    def _apply_filter(self, frame):
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        self._frame_queue.append(frame)
        if self._calculation_typ == ThreshCalculationTyp.MEDIAN:
            self._calculated_value = self._median_filter(frame)
        elif self._calculation_typ == ThreshCalculationTyp.MEDIAN_WEIGHTED:
            self._calculated_value = self._weighted_median_filter(frame)
        elif self._calculation_typ == ThreshCalculationTyp.MEAN:
            self._calculated_value = self._mean_filter(frame)
        elif self._calculation_typ == ThreshCalculationTyp.MEAN_WEIGHTED:
            self._calculated_value = self._weighted_mean_filter(frame)
        result_frame = cv2.absdiff(self._calculated_value, frame)
        return self.__frame(result_frame)

# BackSubProcessor Dictionary
BackSubProcessors = {
    BackSubTyp.MOG_OPEN_CV: MogOpenCV(),
    BackSubTyp.KNN_OPEN_CV: KnnOpenCV(),
    BackSubTyp.MOVING_AVERAGE_C_WRAPPER: MovingAverageCWrapper(1000),
    BackSubTyp.MOVING_AVERAGE_PYTHON: MovingAveragePython()
}


import sys

from setuptools import setup

requires = ['tweepy']

if sys.version_info < (2, 6):
    requires.append('simplejson')

setup(
    name = 'tweet-archiver',
    version = '0.2',
    author = 'Alex Muller',
    author_email = 'alex@mullr.net',
    description = 'Get full Tweet metadata given a list of status IDs.',
    long_description = open('README.rst').read(),
    zip_safe = True,
    packages = ['tweet_archiver'],
    include_package_data=True,
    install_requires = requires,
    entry_points = {
        'console_scripts' : [
            'tweet-archiver = tweet_archiver:main'
        ]
    }
)


# seti={1,2,3,3,4,5,6,7}
# print(seti)
# print(type(seti))

#add value is set

mix={1,2,3,4,5,'khan'}
# mix.add('ali')
# mix.discard(5)
# mix.remove(4)
# mix.clear()
# print(len(mix))
# dd=mix.copy()
# dd.clear()
# print(dd)
# print(mix)
#print(type(mix))

# union use "|" this somble
# s1,s2={1,2,3,4,5,},{4,5,6,7,8,9}
# print(s1)
# print(s2)
# print("union of s1 and s2 is",s1|s2)
#
# # intersection this "&" simbol is use
#
# print(f"the intersection of {s1} and {s2} is ==",s1&s2)

# s1={1,2,3,4,5}
# s2={4,5,6,7,8}
# s1-=s2
# print(s1)


from poker_game_runner.state import Observation
from poker_game_runner.utils import Range, HandType

"""
  This bot plays differently depending on the amount of players left in the hand.
  This is very important in poker as
    more poeple = more hands that can beat your hand,
    and less people = less hands that can beat your hand (if any).
"""

class Bot:

  def __init__(self) -> None:
    self.r25 = Range("55+, A2s+, K5s+, Q8s+, J8s+, T9s, A8o+, K9o+, QTo+, JTo") # top 25%
    self.r20 = Range("55+, A3s+, K7s+, Q8s+, J9s+, T9s, A9o+, KTo+, QJo") # top 20%
    self.r16 = Range("66+, A5s+, K9s+, Q9s+, JTs, ATo+, KJo+, QJo") # 16%
    self.r10 = Range("77+, A9s+, KTs+, QJs, AJo+, KQo") # 10%
    self.r6 = Range("88+, ATs+, KJs+, AKo") # 6%

  def get_name(self):
      return "position_bot"

  def act(self, obs: Observation):
    if obs.current_round == 0: #preflop
      return self.do_preflop(obs)
    else:
      return self.do_postflop(obs)

  def do_preflop(self, obs:Observation):
    active_player_count = len(obs.get_active_players())

    if active_player_count <= 2:
      r = self.r25
    elif active_player_count == 3:
      r = self.r20
    elif active_player_count == 4 or active_player_count == 5:
      r = self.r16
    elif active_player_count == 6 or active_player_count == 7:
      r = self.r10
    else:
      r = self.r6

    if r.is_hand_in_range(obs.my_hand):
      return obs.get_fraction_pot_raise(1) # raise 1 pot
    else:
      return 0

  def do_postflop(self, obs:Observation):
    active_player_count = len(obs.get_active_players())
    r = False
    my_hand_type = obs.get_my_hand_type()

    if active_player_count <= 3:
      r = self.is_hand_ace_or_king_or_better(obs)
    elif active_player_count == 4 or active_player_count == 5:
      r = my_hand_type >= HandType.PAIR and my_hand_type.value > obs.get_board_hand_type().value
    elif active_player_count == 6 or active_player_count == 7:
      r = my_hand_type >= HandType.TWOPAIR and my_hand_type.value > obs.get_board_hand_type().value+1
    else:
      r = my_hand_type >= HandType.THREEOFAKIND and my_hand_type.value > obs.get_board_hand_type().value+1

    if r:
      return obs.get_fraction_pot_raise(1) # raise 1 pot
    else:
      return 0

  def is_hand_ace_or_king_or_better(self, obs:Observation):
    my_hand_type = obs.get_my_hand_type()
    return my_hand_type >= HandType.PAIR or self.is_card_rank_in_hand('A', obs.my_hand) or self.is_card_rank_in_hand('K', obs.my_hand)

  def is_card_rank_in_hand(self, rank, hand):
    return rank in hand[0] or rank in hand[1]


def digitos_unicos(str_n):
	for i in range(len(str_n) - 1):
		if str_n[i] is str_n[i + 1]:
			return False
		i += 1
	return True

def soma_par(str_n):
	soma = 0
	for n in str_n:
		soma += int(n)
	return soma % 2 is 0

def primeiro_igual_ultimo(str_n):
	first = str_n[0]
	last = str_n[len(str_n) - 1]
	return first is last

arquivo = open('telefones_ex5.txt', 'r')

for linha in arquivo.readlines():
	telefones = linha.split(" ")
arquivo.close()

validos = 0
for telefone in telefones:
	if digitos_unicos(telefone) and soma_par(telefone):
		if not primeiro_igual_ultimo(telefone):
			validos += 1
print(validos)

Python Para Zumbis/Lista de Exercícios V Google Developer Day 2010/exercicio05_lucas-nogueira-munhoz_05.py


# -*- coding: utf-8 -*-

import os
import pickle
import numpy as np
import pandas as pd
import re
from src.conf import config

base_dir = '/Users/jiananliu/Desktop/work/tencent/analyze/'
# date_dir = '12_19'
date_dir = 'short_time'
# data_type = '50w'
data_type = '7w'

result_dir = f"{base_dir}/result/"

debug_mode = False
def read_evaluate_file():
    file_name = os.path.join(base_dir, date_dir, f"item-eval-{data_type}.csv")
    df = pd.read_csv(file_name, sep='\t')

    columns = ['video_id', 'show_pv', 'comment_num', 'like_num', 'dislike_num',
               'comment_1_num', 'comment_0_num', 'comment_look_num',
               'not_interest_num', 'share_num', 'attention_num', #'report_num',
               'total_play_time', 'total_video_time', 'video_num', 'play_num',
               'finish_90_watch_num', 'finish_read_90_percent', 'skip_read_10_percent',
               'history_comment_cnt', 'history_share_cnt', 'history_favor_cnt',
               'history_collect_cnt', 'history_feedback_cnt', 'history_quality_score',
               'guid', 'puin_id', 'account_id', 'account_score', 'account_ctr',
               'account_level', 'playtimelevel_playcnt', 'account_expose',
               'account_click', 'cover_pic_score', 'content_clarity', 'new_good_cp']

    if debug_mode:
        select_columns1 = ['video_id', 'finish_read_90_percent', 'skip_read_10_percent',
                       'show_pv', 'play_num']
    else:
        select_columns1 = ['video_id', 'finish_read_90_percent', 'skip_read_10_percent',
                           'history_comment_cnt', 'history_share_cnt', 'history_favor_cnt',
                           'show_pv', 'play_num']

    return df[select_columns1]
    # das = df.to_json(orient='records')

def print_stat(df):
    # bb = df.to_dict(orient='records')
    # print(bb[len(bb) - 1])

    # 中位数、10%分位数、众数
    print(df['like_num'].median(), df['like_num'].quantile(0.1), df['like_num'].mode())
    like_num_df = df['like_num']
    play_num_df = df['play_num']
    expose_num_df = df['show_pv']

def get_url_df():
    url_file_name = os.path.join(base_dir, date_dir, "garlandliu_sptz_1605024076.csv")
    url_df = pd.read_csv(url_file_name, sep=',')
    url_df = url_df.rename(columns={'sShortVideoPlayUrl': 'url'})

    url_df['qbdocid'] = url_df['qbdocid'].apply(lambda x: int(re.sub('["=]', '', x)))
    url_df.drop_duplicates(subset=['qbdocid'], inplace=True)
    return url_df

def get_features_df():
    feature_file_name = os.path.join(base_dir, date_dir, "feature.csv")
    feature_df = pd.read_csv(feature_file_name, sep='\t')

    select_columns = ['commentNum', 'shareNum', 'praiseNum', 'collectNum',
                      'feedbackNum', 'seeingCommentNum', 'mainExposure',
                      'mainClick', 'floatExposure', 'floatClick']

    # return feature_df[select_columns]
    return feature_df

def join(df, url_df, feature_df):
    join_df = df.join(url_df.set_index('qbdocid'), on='video_id', how='inner')

    if 'url' in join_df.columns:
        join_df = join_df[~join_df['url'].str.contains('Android', na=False)]

    join_df = join_df.join(feature_df.set_index('video_id'), on='video_id', how='inner')

    final_df = join_df.reset_index(0)
    return final_df

def save_file(df, file_name):
    file_path = f'{result_dir}/{file_name}'
    df.to_csv(file_path)
    print(f'save to {file_path}')

def save_eval_result(file_name):
    file_name = f'{result_dir}/{file_name}'
    df = pd.read_csv(file_name, sep=',')
    df = df[df.eval('result >= 0')][['video_id', 'result']]
    videoI2result = dict(sorted(df.values.tolist()))

    result_file = os.path.join(base_dir, date_dir, f"result_{data_type}.pickle")
    result = {}
    if os.path.exists(result_file):
        with open(result_file, 'rb') as handle:
            result = pickle.load(handle)

    old_result_file = os.path.join(base_dir, date_dir, f"result_{data_type}_old.pickle")
    with open(old_result_file, 'wb') as handle:
        pickle.dump(result, handle, protocol=pickle.HIGHEST_PROTOCOL)
    print(f'copy old result to {old_result_file}')

    old_result_num = len(result)
    result.update(videoI2result)
    print(f'update result, old_num:{old_result_num} -> new_num:{len(result)}')

    with open(result_file, 'wb') as handle:
        pickle.dump(result, handle, protocol=pickle.HIGHEST_PROTOCOL)
    print(f'save result to {result_file}')
    print(result)

def print_dist_by_feature(df):
    print('-' * 20)
    post_confidence = 100
    c2_max_df = df[df.eval(f'c2_max >= {post_confidence}')]
    print(f'选取大于{int(post_confidence/10)}w消费作为置信度，一共:{len(c2_max_df[c2_max_df.eval("c2 == c2_max")])}条')

    data = []
    for col in cols:
        c2_max_df = c2_max_df[c2_max_df.eval('c2 == c2_max')]
        # print(f'{col}:')
        row = {'name': col}
        for i in np.arange(0.1, 1, 0.1):
            v = c2_max_df[col].quantile(i)
            # print(f'{int(i*100)}分位：{"%.4f" % c2_max_df[col].quantile(i)}')
            if col == 'floatClick':
                row[f'{int(i*100)}分位'] = str(int(v))
            else:
                row[f'{int(i * 100)}分位'] = f'{"%.2f" % (v * 100)}%'
        data.append(row)

    import pandas as pd
    from texttable import Texttable

    result_df = pd.DataFrame(data)
    tb = Texttable()
    tb.set_max_width(0)
    tb.set_cols_align(['l'] + ['l'] * 9)
    tb.set_cols_dtype(['t'] + ['t'] * 9)
    tb.header(result_df.columns)
    tb.add_rows(result_df.values, header=False)
    print(tb.draw())

if __name__ == '__main__':
    # df = read_evaluate_file()
    from src.tencent.analyze.upgrade_10w_time import process_middle_data
    df = process_middle_data.read_middle_data()

    scene_id = 3

    df = df[df.eval(f'scene == {scene_id}')]

    url_df = get_url_df()
    feature_df = get_features_df()
    df = join(df, url_df, feature_df)

    df['url'] = df['video_id'].apply(lambda x: f'https://v.html5.qq.com/node/videoPlayer?vid={x}')
    # df.loc[:, 'url2'] = lambda x: f'https://v.html5.qq.com/node/videoPlayer?vid={x}'
    df['video_id'] = df['video_id'].apply(lambda x: f'_{x}')
    df.eval('praise_percent = praiseNum/floatExposure', inplace=True)
    df.eval('ctr = floatClick/floatExposure', inplace=True)
    df.eval('collect_percent = collectNum/floatExposure', inplace=True)
    df.eval('share_percent = shareNum/floatExposure', inplace=True)
    df.eval('attention_percent = attention_num/floatExposure', inplace=True) #todo：
    df.eval('comment_percent = commentNum/floatExposure', inplace=True)
    df.eval('see_comment_percent = seeingCommentNum/floatExposure', inplace=True)

    reach_10w_num_range = [0, 1, 5] + list(range(10, 120, 10))
    # video_c2_df = df.pivot(index='video_id', columns='c2')[reach_10w_num_range]

    analyze_range = [(0, 10), (10, 20), (20, 40), (40, 60), (60, 100), (100, 10000)]
    cols = ['floatClick', 'finish_read_90_percent', 'skip_read_10_percent', 'praise_percent', 'praiseNum', 'ctr', 'collect_percent', 'collectNum', 'share_percent', 'shareNum', 'attention_percent', 'attention_num', 'comment_percent', 'commentNum', 'see_comment_percent', 'seeingCommentNum']
    # for i in range(0, 110, 10):
    for (start, end) in analyze_range:
        c2_max_df = df[df.eval(f'c2_max >= {start} and c2_max < {end}')]
        c2_max_df = c2_max_df[c2_max_df.eval('c2 == c2_max')]
        print('-' * 20)
        print(f'消费达到：{int(start/10)}w-{int(end/10)}w, count:{c2_max_df.video_id.count()}')
        s50_like_percent = c2_max_df[cols].quantile(0.5)
        print(f'50分位值:\n{s50_like_percent}')

    # -------------------
    print_dist_by_feature(df)

    df2 = df[df.eval('c2 == c2_max')]
    df2 = df2.reset_index(0)
    df2 = df2[['video_id'] + cols + ['url']]
    save_file(df2, 'short_3day_result.csv')


s = input()
t = input()
isSame = True
if len(s) != len(t):
    isSame = False
for i in s:
    if s.find(i) != t.find(i):
        isSame = False
        break
if isSame:
    print("true")
else:
    print("false")


from enum import Enum

class _PersonTypeEnum(Enum):
    e_type = 'E'
    m_type = 'M'
    gm_type = 'GM'

class Name():
    def __init__(self, first_name: str, second_name: str, last_name: str):
        self._first_name = first_name
        self._second_name = second_name
        self._last_name = last_name

class _Person:
    def __init__(self, name: Name,
                 salary: float,
                 account: int):
        self._name = name
        self._salary = salary
        self._account = account

    @property
    def name(self) -> str:
        raise NotImplementedError

class Employee(_Person):
    _type = _PersonTypeEnum.e_type

    @property
    def name(self) -> str:
        return f'{self._name} E'

class Manager(_Person):
    _type = _PersonTypeEnum.m_type

    @property
    def name(self) -> str:
        return f'{self._name} M'

class GeneralManager(_Person):
    _type = _PersonTypeEnum.gm_type

    @property
    def name(self) -> str:
        return f'{self._name} GM'

if __name__ == '__main__':
    print('start')
    e = [
        Employee(name=f'Артём{i} Михайлович Тугарёв', salary=15000. + i, account=1234 + i)
        for i in range(1000)
    ]
    e.append(Manager(name='Миша Михайлович Ф.', salary=30000, account=9876))
    e.append(GeneralManager(name='Jason Михайлович', salary=1030000, account=98764))
    e.append(GeneralManager(name='Jason Михайлович', salary=1130000, account=98766))

    salary = sum(_e._salary for _e in e)

    for _e in e:
        print(f'Привет, {_e.name}. Вот твоя зарплата {_e._salary}')


import hashlib as h
import sys

sha256sum = h.sha256()
ripe = h.new('ripemd160')

with open(sys.argv[1], 'rb') as filehash:
    while True:
        buf = filehash.read(65536)
        if not buf:
            break
        sha256sum.update(buf)

print(h.new('ripemd160', sha256sum.digest()).hexdigest())


class TestUtility:
    """Contains methods that would be used in writing tests efficiently."""

    @staticmethod
    def stringRange(inputOne, inputTwo=None, inputThree=None):
        """Returns a range of numbers similar to builtin `range` method only with elements being of the string type"""
        if inputTwo is None and inputThree is None and type(inputOne) == int:
            integerStart, integerEnd, step = 0, inputOne, 1
        elif type(inputOne) == int and type(inputTwo) == int and inputThree is None:
            integerStart, integerEnd, step = inputOne, inputTwo, 1
        elif type(inputOne) == int and type(inputTwo) == int and type(inputThree) is int:
            integerStart, integerEnd, step = inputOne, inputTwo, inputThree
        else:
            raise Exception("Invalid Input")
        return [str(idx) for idx in range(integerStart, integerEnd, step)]


# https://towardsdatascience.com/perplexity-intuition-and-derivation-105dd481c8f3
# https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse
import copy
import datetime
import json
import logging
import os
import time

import numpy as np
import pandas as pd
import torch
import torch.nn.functional as F
from torch.distributions import Categorical
from torch.nn.utils import clip_grad_norm_
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

from RL_toolbox.reward import Bleu_sf0
from RL_toolbox.reward import Bleu_sf2
from train.rl.truncation import mask_inf_truncature, truncations
# from train.train_functions import evaluate_policy
from utils.utils_train import create_logger, write_to_csv

logger = logging.getLogger()

class RLAlgo:
    def __init__(self, model, train_dataset, val_dataset, test_dataset, args, lm, max_len, alpha_lm, truncate_mode,
                 truncation_params=None, is_correction=False, baseline=True, s_min=1, s_max=-1):
        self.lm = lm
        self.model = model
        self.dataset_name = args.dataset
        self.train_dataset, self.val_dataset, self.test_dataset = train_dataset, val_dataset, test_dataset
        self.train_generator = DataLoader(dataset=train_dataset, batch_size=args.bs, drop_last=True,
                                          num_workers=args.num_workers)
        self.val_generator = DataLoader(dataset=val_dataset, batch_size=args.bs, drop_last=True,
                                        num_workers=args.num_workers)
        self.batch_size = args.bs
        self.lr = args.lr
        self.optimizer = torch.optim.Adam(params=model.parameters(), lr=self.lr)
        PAD_IDX = train_dataset.vocab_questions["<PAD>"]
        self.criterion = torch.nn.NLLLoss(ignore_index=PAD_IDX)
        self.mse = torch.nn.MSELoss(reduction="none")

        self.EPOCHS = args.ep
        self.grad_clip = args.grad_clip if args.grad_clip is not None else 5.
        self.print_interval = args.print_interval
        self.device = torch.device("cuda:{}".format(args.device_id) if torch.cuda.is_available() else "cpu")
        self.create_out_path(args)
        self.writer = SummaryWriter(log_dir=os.path.join(self.out_path, "runs"))

        self.train_function, self.eval_function = self.get_algo_functions(args)
        self.task = args.task
        self.check_batch()
        self.s_min = s_min
        self.s_max = s_max
        self.truncation_params = truncation_params
        self.truncation = truncations[truncate_mode](pretrained_lm=self.lm,
                                                     s_min=s_min, s_max=s_max,
                                                     truncation_params=truncation_params)  # adding the truncation class.
        self.reward_function = Bleu_sf2()
        self.gamma = 0.99
        self.max_len = max_len
        self.alpha_lm = alpha_lm
        self.language_metrics = {k: v for k, v in zip(["bleu-1", "bleu-2", "bleu"],
                                                      [Bleu_sf0(sf_id=args.bleu_sf, n_gram=2),
                                                       Bleu_sf0(sf_id=args.bleu_sf, n_gram=3),
                                                       Bleu_sf0(sf_id=args.bleu_sf, n_gram=4)])}
        self.writer_iteration = 0
        self.is_correction = is_correction
        self.baseline = baseline
        self.rl_all, self.vf_all, self.rewards_all, self.ranks_all = [], [], [], []
        self.dialog_all, self.in_va_all, self.log_probs_truncated_all = [], [], []
        self.episode_idx = 0
        self.update_iteration = 1

    def create_out_path(self, args):
        if args.model_path is not None:
            out_path = os.path.join(args.model_path, "eval_from_loaded_model")
            self.out_path = os.path.join(out_path,
                                         "{}".format(datetime.datetime.now().strftime("%Y%m%d-%H%M%S")))
        else:
            out_path = '{}_{}_{}_layers_{}_emb_{}_hidden_{}_pdrop_{}_gradclip_{}_bs_{}_lr_{}'.format(args.dataset,
                                                                                args.task,
                                                                                args.model,
                                                                                args.num_layers,
                                                                                args.emb_size,
                                                                                args.hidden_size,
                                                                                args.p_drop,
                                                                                args.grad_clip,
                                                                                args.bs, args.lr)
            if args.task == 'policy':
                out_path = out_path + '_cond-answer_{}'.format(args.condition_answer)
            self.out_path = os.path.join(args.out_path, out_path,
                                         "{}".format(datetime.datetime.now().strftime("%Y%m%d-%H%M%S")))
        if not os.path.exists(self.out_path):
            os.makedirs(self.out_path)
        out_file_log = os.path.join(self.out_path, 'training_log.log')
        self.logger = create_logger(out_file_log)
        self.out_csv = os.path.join(self.out_path, 'train_history.csv')
        self.out_lm_metrics = os.path.join(self.out_path, 'lm_metrics_sf{}.csv'.format(args.bleu_sf))
        self.model_path = os.path.join(self.out_path, 'model.pt')
        self.logger.info("hparams: {}".format(vars(args)))
        self.logger.info('train dataset length: {}'.format(self.train_dataset.__len__()))
        self.logger.info("val dataset length: {}".format(len(self.val_dataset)))
        if self.dataset_name == "vqa":
            self.logger.info("number of filtered entries:{}".format(len(self.train_dataset.filtered_entries)))
        self.logger.info('number of tokens: {}'.format(self.train_dataset.len_vocab))
        self._save_hparams(args, self.out_path)

    def _save_hparams(self, args, out_path):
        dict_hparams = vars(args)
        dict_hparams = {key: str(value) for key, value in dict_hparams.items()}
        config_path = os.path.join(out_path, "config.json")
        with open(config_path, 'w') as fp:
            json.dump(dict_hparams, fp, sort_keys=True, indent=4)

    def check_batch(self):
        if self.task == 'policy':
            (temp_inp, temp_tar), answers, img = self.train_dataset.__getitem__(0)
            if isinstance(img, tuple):
                feats = img[0]
            else:
                feats = img
            self.logger.info('img features shape:{}'.format(feats.shape))
        elif self.task == 'lm':
            if self.dataset_name == "clevr":
                temp_inp, temp_tar = self.train_dataset.__getitem__(0)
            elif self.dataset_name == "vqa":
                (temp_inp, temp_tar), _, _ = self.train_dataset.__getitem__(0)

        self.logger.info("input shape: {}".format(temp_inp.shape))
        self.logger.info("target shape: {}".format(temp_tar.shape))
        self.logger.info("input:{}".format(temp_inp))
        self.logger.info("target: {}".format(temp_tar))

    def get_algo_functions(self, args):
        train_function = self.train_one_epoch_policy
        eval_function = self.evaluate_policy
        return train_function, eval_function

    def get_answers_img_features(self, dataset, index):
        entry = dataset.filtered_entries[index]
        img_feats, _, _ = dataset.get_img_data(entry)
        answer, _ = dataset.get_answer_data(entry)
        return img_feats, answer

    def train(self):
        self.logger.info("start training...")
        train_loss_history, train_ppl_history, val_loss_history, val_ppl_history = [], [], [], []
        best_val_loss = None
        for epoch in range(self.EPOCHS):
            self.logger.info('epoch {}/{}'.format(epoch + 1, self.EPOCHS))
            train_loss, elapsed = self.train_function(train_generator=self.train_generator,
                                                      optimizer=self.optimizer,
                                                      criterion=self.criterion,
                                                      device=self.device,
                                                      grad_clip=self.grad_clip,
                                                      print_interval=self.print_interval)
            self.logger.info('train loss {:5.3f} '.format(train_loss))
            self.logger.info('time for one epoch...{:5.2f}'.format(elapsed))
            # val_loss = self.eval_function(model=self.model, val_generator=self.val_generator, criterion=self.criterion,
            #                              device=self.device)
            # self.logger.info('val loss: {:5.3f} - val perplexity: {:8.3f}'.format(val_loss, math.exp(val_loss)))

            # saving loss and metrics information.
            train_loss_history.append(train_loss)
            # train_ppl_history.append(math.exp(train_loss))
            # val_loss_history.append(val_loss)
            # val_ppl_history.append(math.exp(val_loss))
            self.logger.info('-' * 89)

            # Save the model if the validation loss is the best we've seen so far.
            if not best_val_loss or train_loss < best_val_loss:
                with open(self.model_path, 'wb') as f:
                    torch.save(self.model, f)
                best_val_loss = train_loss

        self.logger.info("saving loss and metrics information...")
        self.save_results()
        hist_keys = ['train_loss', 'train_ppl', 'val_loss', 'val_ppl']
        hist_dict = dict(zip(hist_keys, [train_loss_history, train_ppl_history, val_loss_history, val_ppl_history]))
        write_to_csv(self.out_csv, hist_dict)

    def _sample_(self, input, num_words=20, img_feats=None,
                 index_img=None,
                 answer=None, write=True):
        answer_ = answer[0].cpu().item() if answer is not None else answer
        input_idx = input
        with torch.no_grad():
            for i in range(num_words):
                img_feats = img_feats.to(self.device)
                answer = answer.to(self.device)
                logits, _ = self.model(state_text=input_idx, state_img=img_feats,
                                       state_answer=answer)  # output = logits (S, num_tokens)
                word_idx = logits[-1].squeeze().argmax()
                input_idx = torch.cat([input_idx, word_idx.view(1, 1)], dim=-1)
            words = self.val_dataset.question_tokenizer.decode(input_idx.squeeze().cpu().numpy())
        dict_words = words
        if write:
            out_file_generate = os.path.join(self.out_path,
                                             'generate_words_img_{}_answer_{}.txt'.format(index_img, answer_))
            with open(out_file_generate, 'w') as f:
                f.write(dict_words)
                f.close()

        return dict_words

    def _generate_text(self, input, temperatures=["greedy", 0.5, 1, 2], num_words=20, img_feats=None, index_img=None,
                       answer=None, write=True):
        dict_words = {k: [] for k in temperatures}
        for temp in temperatures:
            answer_ = answer[0].cpu().item() if answer is not None else answer
            input_idx = input
            with torch.no_grad():
                for i in range(num_words):
                    img_feats = img_feats.to(self.device)
                    answer = answer.to(self.device)
                    logits, _ = self.model(state_text=input_idx, state_img=img_feats,
                                           state_answer=answer)  # output = logits (S, num_tokens)

                    word_idx = logits[:, -1].squeeze().argmax()
                    input_idx = torch.cat([input_idx, word_idx.view(1, 1)], dim=-1)
                words = self.val_dataset.question_tokenizer.decode(input_idx.squeeze().cpu().numpy())
            dict_words[temp] = words
            if write:
                out_file_generate = os.path.join(self.out_path,
                                                 'generate_words_temp_{}_img_{}_answer_{}.txt'.format(temp, index_img,
                                                                                answer_))
                with open(out_file_generate, 'w') as f:
                    f.write(dict_words[temp])
                    f.close()

        return dict_words

    def generate_text(self, temperatures=["greedy", 0.5, 1, 2], words=20):
        input = self.test_dataset.vocab_questions["<SOS>"]
        input = torch.LongTensor([input]).view(1, 1).to(self.device)
        indexes = list(range(3))
        for index in indexes:
            print("Generating text conditioned on img: {}".format(index))
            img_feats, answer = self.get_answers_img_features(dataset=self.val_dataset, index=index)
            img_feats = img_feats.unsqueeze(0)
            _ = self._generate_text(input, temperatures=temperatures, num_words=words, img_feats=img_feats,
                                    index_img=index,
                                    answer=answer)

    def evaluate_policy(self, val_generator, criterion, device):
        self.model.eval()  # turn on evaluation mode which disables dropout.
        total_loss = 0.
        start_time = time.time()
        with torch.no_grad():
            for batch, ((inputs, targets), answers, img) in enumerate(val_generator):
                if isinstance(img, list):
                    feats = img[0]
                else:
                    feats = img
                answers = answers.squeeze()
                inputs, feats, answers = inputs.to(device), feats.to(device), answers.to(device)
                targets = targets.view(targets.size(1) * targets.size(0)).to(device)
                logits, _ = self.model(inputs, feats, answers)
                logits = logits.view(-1, logits.size(-1))
                log_probs = F.log_softmax(logits, dim=-1)
                total_loss += criterion(log_probs, targets).item()
        print("Evaluation time {:5.2f}".format(time.time() - start_time))
        return total_loss / (batch + 1)

    def compute_language_metrics(self, temperatures):
        """
        Compute different versions of BLEU: try smoothing techniques seven at first. then 5, 6.
        METEOR
        :return:
        """
        input = self.test_dataset.vocab_questions["<SOS>"]
        input = torch.LongTensor([input]).view(1, 1).to(self.device)
        dict_metrics = {k: 0. for k in self.language_metrics.keys()}
        result_metrics = {k: dict_metrics for k in temperatures}
        for ((inputs, targets), answers, img) in self.val_generator:
            if isinstance(img, list):
                feats = img[0]
            else:
                feats = img
            for i in range(targets.shape[0]):
                question_decoded = [self.val_dataset.question_tokenizer.decode(targets[i].cpu().numpy())]
                num_words = len(question_decoded[0].split(" ")) + 1
                if self.task == "lm":
                    dict_questions = self._generate_text(input, temperatures=temperatures, num_words=num_words,
                                                         write=False)
                elif self.task == "policy":
                    dict_questions = self._generate_text(input, temperatures=temperatures,
                                                         img_feats=feats[i].unsqueeze(0), answer=answers[i].view(1),
                                                         num_words=num_words, write=False)
                for temp in temperatures:
                    for name, metric in self.language_metrics.items():
                        result, _, _ = metric.get(dict_questions[temp], question_decoded, step_idx=None,
                                                  done=True)
                        result_metrics[temp][name] = result_metrics[temp][name] + result
        # getting the average
        result_metrics = {k: {k_: v_ / len(self.val_dataset) for k_, v_ in v.items()} for k, v in
                          result_metrics.items()}
        df = pd.DataFrame.from_dict(result_metrics)
        df.to_csv(self.out_lm_metrics, index_label="metrics", columns=temperatures)
        return result_metrics

    def update(self, log_probs, log_probs_truncated, gts, inputs, targets, feats, answers):

        self.model.zero_grad()
        logits, values = self.model(state_text=inputs, state_img=feats,
                                    state_answer=answers)
        values = values.squeeze()
        log_probs_all = F.log_softmax(logits, dim=-1)
        log_probs_actions = log_probs_all.gather(-1, targets.unsqueeze(dim=-1)).view(
            log_probs_all.size(0), log_probs_all.size(1))

        advs = gts.clone()
        if self.baseline:
            advs -= values.cpu().detach().view(gts.size(0), gts.size(1))

        log_probs_advs = log_probs_actions * advs
        if self.is_correction:
            is_ratios = torch.exp(log_probs.detach() - log_probs_truncated.detach())
            cumprod_ratios = torch.cumprod(is_ratios, dim=-1)
            log_probs_advs *= cumprod_ratios
        rl_loss_per_episode = -log_probs_advs.sum(dim=1)
        rl_loss = rl_loss_per_episode.mean()
        value_loss = torch.square(gts.view(-1) - values.view(-1)).sum()

        loss = rl_loss
        if self.baseline:
            loss += 0.5 * value_loss

        self.optimizer.zero_grad()
        loss.mean().backward()

        clip_grad_norm_(self.model.parameters(), self.grad_clip)
        self.optimizer.step()
        return loss, rl_loss, value_loss

    def train_one_epoch_policy(self, train_generator, optimizer, criterion, device, grad_clip,
                               print_interval=10):
        self.model.train()  # Turns on train mode which enables dropout.
        total_loss = 0.
        start_time = time.time()
        start_time_epoch = time.time()

        for batch, ((inputs, targets), answers, img) in enumerate(train_generator):
            if isinstance(img, list):
                feats = img[0]
            else:
                feats = img
            answers = answers.squeeze()
            inputs, feats, answers = inputs.to(device), feats.to(device), answers.to(device)
            inputs_ = inputs[:, 0:1].to(device)
            log_probs = torch.zeros((inputs.size(0), self.max_len)).to(self.device)
            ranks = torch.zeros_like(log_probs)
            in_valid_actions = torch.zeros_like(log_probs)
            log_probs_truncated = torch.zeros_like(log_probs)

            with torch.no_grad():
                for t in range(self.max_len):
                    log_probas_lm, logits_lm, origin_log_probs_lm = self.lm.forward(inputs_, 1.)
                    mask_valid_actions = self.truncation.get_mask(log_probas_lm, logits_lm)

                    sort_lm, sort_lm_ind = torch.sort(logits_lm, descending=True)
                    ranks[:, t] = (sort_lm_ind == targets[:, t].view(-1, 1)).nonzero()[:, -1]
                    # in_valid_actions[:, t] = (targets[:, t].view(-1, 1) == valid_actions).sum(dim=1)
                    logits_, _ = self.model(state_text=inputs_, state_img=feats,
                                            state_answer=answers)  # output = logits (S, num_tokens)
                    last_logits = (1 - self.alpha_lm) * logits_[:, -1, :] + self.alpha_lm * logits_lm
                    probs = F.softmax(last_logits, dim=-1)
                    dist = Categorical(probs)

                    dist_truncated = mask_inf_truncature(mask_valid_actions, logits_[:, -1, :], self.device,
                                                         logits_.size(-1))
                    sort_probs, sort_ind = torch.sort(dist_truncated.probs, descending=True)
                    sort_words = [self.train_dataset.question_tokenizer.decode(sort_ind[j, :10].numpy()).split() for j
                                  in range(sort_ind.size(0))]
                    logger.info("sort words {}".format(sort_words))
                    logger.info("sort probs {}".format(sort_probs[:, :10]))
                    actions = dist_truncated.sample().to(self.device)
                    log_probs_truncated[:, t] = torch.log(dist_truncated.probs.gather(-1, actions.view(-1, 1)).view(-1))
                    prob_actions = dist.probs.to(self.device).gather(-1, actions.view(-1, 1)).view(-1)
                    log_probs[:, t] = torch.log(prob_actions).to(self.device)
                    inputs_ = torch.cat([inputs_.to(device), actions.view(-1, 1)], dim=-1)

            gts, rewards, dialog, targets_dialog = self.compute_rewards(inputs_, targets)

            # estimate the loss using one MonteCarlo rollout
            inputs_sampled, targets_sampled = inputs_[:, :-1], inputs_[:, 1:]
            loss, rl_loss, value_loss = self.update(log_probs, log_probs_truncated, gts, inputs_sampled,
                                                    targets_sampled, feats, answers)

            total_loss += loss.mean().item()

            self.dialog_all.append([dialog[0], targets_dialog[0]])
            self.rewards_all.append(np.mean(rewards))
            self.vf_all.append(value_loss.detach().item())
            self.rl_all.append(rl_loss.detach().item())
            self.log_probs_truncated_all.append(log_probs_truncated.detach().tolist())
            self.in_va_all.append(in_valid_actions.mean(dim=0).tolist())
            ranks_median, _ = ranks.median(dim=-1)
            self.ranks_all.append(ranks_median.view(1, -1))

            # print loss every number of batches
            if (batch + 1) % print_interval == 0:
                print('loss for batch {}: {:5.3f}'.format(batch + 1, total_loss / (batch + 1)))
                print('time for {} training steps: {:5.2f}'.format(print_interval, time.time() - start_time))
                logger.debug('rl loss {}'.format(np.mean(self.rl_all[-print_interval:])))
                logger.debug('value loss {}'.format(np.mean(self.vf_all[-print_interval:])))
                logger.info("rewards:{}".format(np.mean(self.rewards_all[-print_interval:])))
                logger.info("convergence :{}".format(np.exp(np.mean(self.log_probs_truncated_all[-print_interval:]))))
                first_log_probs_tr = np.array(self.log_probs_truncated_all[-print_interval:])[:, :, 0]
                logger.info(" 1rst prob trunc :{}".format(np.exp(np.mean(first_log_probs_tr))))

                logger.info("dialog:{}".format(dialog[0]))
                logger.info("true dialog:{}".format(targets_dialog[0]))
                ranks_medians = torch.cat(self.ranks_all[-print_interval:], dim=0)
                logger.debug("ranks :{}".format(ranks_medians))
                self.writer.add_scalar("rewards", np.mean(rewards), self.writer_iteration)
                self.writer.add_scalar("vf_loss", value_loss.detach().item(), self.writer_iteration)
                self.writer.add_scalar("rl_loss", rl_loss.detach().item(), self.writer_iteration)
                self.writer_iteration += 1

                start_time = time.time()

            curr_loss = total_loss / (batch + 1)
            elapsed = time.time() - start_time_epoch
            self.episode_idx += 1

        return curr_loss, elapsed

    def compute_rewards(self, inputs_, targets):
        dialog = [self.train_dataset.question_tokenizer.decode(question) for question in
                  inputs_.cpu().numpy()]
        targets_dialog = [self.train_dataset.question_tokenizer.decode(question[:self.max_len]) for question
                          in targets.cpu().numpy()]

        rewards = [self.reward_function.get(dialog[t_], [targets_dialog[t_]], done=True)[0] for t_ in
                   range(len(dialog))]

        rewards_ = torch.zeros((inputs_.size(0), inputs_.size(1) - 1))
        rewards_[:, -1] = torch.tensor(rewards).view(-1)
        gts = torch.zeros((inputs_.size(0), inputs_.size(1) - 1))

        discounted_reward = 0
        for timestep in range(self.max_len):
            discounted_reward = rewards_[:, -timestep - 1] + (self.gamma * discounted_reward)
            gts[:, -timestep - 1] = discounted_reward

        return gts, rewards, dialog, targets_dialog

    def save_results(self):
        pd.DataFrame(self.rewards_all).to_csv(os.path.join(self.out_path, "rewards.csv"), index=False, header=False)
        pd.DataFrame(self.rl_all).to_csv(os.path.join(self.out_path, "rl_losses.csv"), index=False, header=False)
        pd.DataFrame(self.vf_all).to_csv(os.path.join(self.out_path, "vf_losses.csv"), index=False, header=False)
        pd.DataFrame(self.dialog_all).to_csv(os.path.join(self.out_path, "dialogs.csv"), index=False, header=False)
        pd.DataFrame(self.in_va_all).to_csv(os.path.join(self.out_path, "in_vas.csv"), index=False, header=False)

class PPO_algo(RLAlgo):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.K_epochs = 1
        self.eps_clip = 0.02
        self.new_model = copy.deepcopy(self.model)
        self.new_model.load_state_dict(self.model.state_dict())
        self.optimizer = torch.optim.Adam(params=self.new_model.parameters(), lr=self.lr)
        self.entropy_coeff = 0.01
        self.update_iteration = 1

    def update(self, log_probs, log_probs_truncated, gts, inputs, targets, feats, answers):

        self.model.zero_grad()
        old_logits, old_values = self.model(state_text=inputs, state_img=feats,
                                            state_answer=answers)
        old_values = old_values.squeeze()
        old_log_probs_all = F.log_softmax(old_logits, dim=-1)
        old_log_probs_actions = old_log_probs_all.gather(-1, targets.unsqueeze(dim=-1)).view(
            old_log_probs_all.size(0), old_log_probs_all.size(1))

        advs = gts.clone()
        if self.baseline:
            advs -= old_values.cpu().detach().view(gts.size(0), gts.size(1))

        for _ in range(self.K_epochs):
            self.model.zero_grad()
            logits, values = self.new_model(state_text=inputs, state_img=feats,
                                            state_answer=answers)
            values = values.squeeze()
            log_probs_all = F.log_softmax(logits, dim=-1)
            log_probs_actions = log_probs_all.gather(-1, targets.unsqueeze(dim=-1)).view(
                log_probs_all.size(0), log_probs_all.size(1))
            ratios = torch.exp(log_probs_actions - old_log_probs_actions.detach())
            if self.is_correction:
                # computing the Importance Sampling ratio (pi_theta_old / rho_theta_old)
                is_ratios = torch.exp(log_probs - log_probs_truncated.to(self.device))
                ratios = ratios * is_ratios
            surr1 = ratios * advs
            surr2 = torch.clamp(ratios, 1 - self.eps_clip, 1 + self.eps_clip) * advs
            surr = -torch.min(surr1, surr2)
            entropy_loss = self.entropy_coeff * Categorical(torch.exp(log_probs_all)).entropy()
            vf_loss = 0.5 * self.mse(values.squeeze(), gts)
            loss = surr.sum(dim=1).mean() + vf_loss.sum() - entropy_loss.sum()
            # take gradient step
            self.optimizer.zero_grad()
            loss.mean().backward()
            clip_grad_norm_(self.new_model.parameters(), self.grad_clip)
            self.optimizer.step()
        # return loss, rl_loss, value_loss
        self.model.load_state_dict(self.new_model.state_dict())
        return loss, surr.mean(), vf_loss.mean()


import rclpy
from rclpy.node import Node
from math import sqrt
import serial
import struct
import json
from mpu6050 import mpu6050
import time

from geometry_msgs.msg import Twist

MOTOR1 = b'\xf5'  # address serial motor 1
MOTOR2 = b'\xfa'  # address serial motor 2
MOTOR3 = b'\xff'  # address serial motor 3

FOWARD = b'\x66'  # turn motor foward
BACKWARD = b'\x62' 	# turn motor backward
STOP = b'\x73'	      	# stop motor

def serial_motor(vel1, vel2, vel3, serial):
    serial.write(MOTOR1)
    if vel1 < 0:
        serial.write(struct.pack("B", vel1 * -1))
        serial.write(FOWARD)
    if vel1 > 0:
        serial.write(struct.pack("B", vel1))
        serial.write(BACKWARD)
    if vel1 == 0:
        serial.write(struct.pack("B", 0))
        serial.write(STOP)

    serial.write(MOTOR2)
    if vel2 < 0:
        serial.write(struct.pack("B", vel2 * -1))
        serial.write(FOWARD)
    if vel2 > 0:
        serial.write(struct.pack("B", vel2))
        serial.write(BACKWARD)
    if vel2 == 0:
        serial.write(struct.pack("B", 0))
        serial.write(STOP)

    serial.write(MOTOR3)
    if vel3 < 0:
        serial.write(struct.pack("B", vel3 * -1))
        serial.write(FOWARD)
    if vel3 > 0:
        serial.write(struct.pack("B", vel3))
        serial.write(BACKWARD)
    if vel3 == 0:
        serial.write(struct.pack("B", 0))
        serial.write(STOP)

class OmninoDriverNode(Node):
    def __init__(self):
        super().__init__('omnino_driver')
        self.ser = serial.Serial('/dev/ttyS0', 9600)

        self.declare_parameter("wheel_r", 0.02)
        self.declare_parameter("robot_d", 0.07)

        self.r = self.get_parameter(
            "wheel_r").get_parameter_value().double_value
        self.d = self.get_parameter(
            "robot_d").get_parameter_value().double_value

        self.sub_ = self.create_subscription(
            Twist, 'cmd_vel', self.driver_callback, 10)

    def driver_callback(self, cmd_vel):
        vx = cmd_vel.linear.x
        vy = cmd_vel.linear.y
        w = cmd_vel.angular.z

        vel_1 = 1/self.r * (vx - self.d*w)
        vel_2 = 1/self.r * (-1/2*vx - sqrt(3)/2*vy - self.d*w)
        vel_3 = 1/self.r * (-1/2*vx + sqrt(3)/2*vy - self.d*w)

        serial_motor(vel_1, vel_2, vel_3, self.ser)

def main(args=None):
    ser = serial.Serial('/dev/ttyS0', 9600)
    sensor = mpu6050(0x68)
    vx, vy, w = 0, 1, 0
    r = 0.02
    d = 0.07
    vel_1 = 1/r * (vx - d*w) * 3.1415/180
    vel_2 = 1/r * (-1/2*vx - sqrt(3)/2*vy - d*w) * 3.1415/180
    vel_3 = 1/r * (-1/2*vx + sqrt(3)/2*vy - d*w) * 3.1415/180
    x, y, z = [], [], []
    i = 0
    print(vel_1, vel_2, vel_3)
    serial_motor(int(vel_1), int(vel_2), int(vel_3), ser)
    while(i < 50):
        print(i)
        accel_data = sensor.get_accel_data()
        ax, ay, az = accel_data['x'], accel_data['y'], accel_data['z']
        x.append(ax)
        y.append(ay)
        z.append(az)
        i += 0.5
        time.sleep(0.5)
    serial_motor(0,0,0,ser)
    with open('omnino.json', 'w') as outp:  # Overwrites any existing file.
        json.dump({'x': x, 'y': y, 'z': z}, outp)
    # rclpy.init(args=args)
    # omnino_driver_node = OmninoDriverNode()
    # rclpy.spin(omnino_driver_node)
    # omnino_driver_node.destroy_node()
    # rclpy.shutdown()

if __name__ == '__main__':
    main()


""" early_stopping: Early Stopping class to stop training loop """

import logging

class EarlyStopping:
    """
    EarlyStopping class, adapted from

    https://debuggercafe.com/using-learning-rate-scheduler-and-early-stopping-with-pytorch/
    """
    def __init__(self, patience: int, min_delta: float = 0.0) -> None:
        """
        Constructor

        Parameters
        ----------
        patience : int
            Number of epoch without decreasing validation loss
        min_delta : float, optional
            Minimum delta of decreasing loss, default 0.0
        """
        self.__patience__ = patience
        self.__min_delta__ = min_delta
        self.__go_on__ = True
        self.__best_loss__ = float("inf")
        self.__historical_best__ = float("inf")
        self.__counter__ = 0
        self.__loss__ = float("inf")
        return

    def logging_loss(self) -> None:
        """
        Logs loss

        Returns
        -------
        None
        """
        if not self.__go_on__:
            logging.info("Early stopping with validation loss {:.2e}".format(self.__loss__))
        return

    def current_loss(self, loss: float) -> None:
        """
        Updates loss value to evaluate if the training continues

        Parameters
        ----------
        loss : float
            Current validation loss

        Returns
        -------
        None, updates object
        """
        self.__loss__ = loss
        if (self.__best_loss__ - loss) > self.__min_delta__:
            self.__best_loss__ = loss
            self.__counter__ = 0
            return
        elif (self.__best_loss__ - loss) <= self.__min_delta__:
            self.__counter__ += 1
            if self.__counter__ >= self.__patience__:
                self.__go_on__ = False
            return

    def go_on(self) -> bool:
        """
        Whether continue training

        Returns
        -------
        bool
            True if continue training
        """
        return self.__go_on__

    def reset(self) -> None:
        """
        Resets early stopping

        Returns
        -------
        None
        """
        self.__go_on__ = True
        self.__best_loss__ = float("inf")
        self.__loss__ = float("inf")
        self.__counter__ = 0
        return

    def best_historical(self) -> bool:
        """
        If best historical is significant more than current best

        Returns
        -------
        bool
            Whether current best is less than best historical
        """
        if (self.__historical_best__ - self.__loss__) > self.__min_delta__:
            self.__historical_best__ = self.__loss__
            return True
        else:
            return False


# -*- coding: UTF-8 -*-
import sys
if sys.version[0] == '2':
	reload(sys)
	sys.setdefaultencoding("utf-8")

import os
import argparse
import json
import multiprocessing as multiprocess
from collections import Counter
import time

#优化效率后的通过f1找多fake span(为原数据集中的每个answer都找到对应的最匹配的fake span)
#处理最新训练集-27w

def parse_args():
	#usage python preprocess_yhl.py recall f1 a -n 8
	parser = argparse.ArgumentParser(description='Preprocess DuReader preprocessed dataset includs calculating parag scores and fake span scores.')

	path_settings = parser.add_argument_group('path settings')
	#, '../data/preprocessed/trainset_v1/zhidao.train.json'
	#6160负责跑search
	path_settings.add_argument('--train_files', nargs='+',
							   default=['../data/preprocessed/trainset_v1/search.train.json'],
							   help='list of files that contain the preprocessed train data')

	parser.add_argument('-n', '--n_processes', type=int, default=3,
						help="Number of processes (i.e., ) ")
	return parser.parse_args()

def scoreSpan(line):
	sample=json.loads(line)
	answer_num = len(sample['segmented_answers'])
	bestK_match = [(-1,-1,[-1,-1],None,0.0)] * answer_num#slot:(d_idx, p_idx, span_idxs, span_text, matchScore)

	for d_idx, doc in enumerate(sample['documents']):
		for p_idx, para_tokens in enumerate(doc['segmented_paragraphs']):#debug每个篇章选一个fake_span出来
			for a_idx, seg_answer_tokens in enumerate(sample['segmented_answers']):#为每个answer找到最匹配的fake_span
				answer_len=len(seg_answer_tokens)#为了计算recall

				answer_tokens = set([token for token in seg_answer_tokens if token not in ['，','。']])#去停用词？

				best_f1_score_p=0.0
				best_start_idx, best_end_idx = -1, -1
				best_span_tokens=None

				f1_score = 0#一旦找到全匹配，不再测试其他开始位置
				truncated_para_tokens = para_tokens[:1000]
				for start_tidx in range(len(truncated_para_tokens)):
					if truncated_para_tokens[start_tidx] not in answer_tokens:
						continue
					if f1_score==1.0:#在某个开始位置找到全匹配后，余下开始位置无需再探索...
						break
					#初始化第一个span
					end_tidx_init = len(truncated_para_tokens)-1
					span_len = end_tidx_init +1 - start_tidx#为了计算precision
					span_tokens = truncated_para_tokens[start_tidx: end_tidx_init+1]

					common = Counter(span_tokens) & Counter(seg_answer_tokens)
					num_same = sum(common.values())
					if num_same == 0:
						f1_score = 0
					else:
						p = 1.0 * num_same / span_len
						r = 1.0 * num_same / answer_len
						f1_score = (2 * p * r) / (p + r)#调和平均
					# print('针对answer token: ',seg_answer_tokens,'初始span token ', span_tokens,'num same: ',num_same,'p: ',p)
					if f1_score==0:#说明该开始位置对应的最长的可能span都没有相交部分
						break

					if f1_score > best_f1_score_p:
						# print('best_f1_score_p被更新【初始时】',f1_score)
						best_f1_score_p = f1_score
						best_start_idx, best_end_idx = start_tidx, end_tidx_init
						best_span_tokens = span_tokens
					if f1_score==1.0:#该开始位置，找到了最匹配span，结束位置再继续缩小无意义
							break
					#遍历其余span，参数在第一个span基础上变动
					for end_tidx in range(len(truncated_para_tokens) - 2, start_tidx - 1, -1):
						span_tokens = truncated_para_tokens[start_tidx: end_tidx + 1]
						# f1_score = f1_score(span_tokens, seg_answer_tokens)
						span_len-=1#参数变动_1
						if truncated_para_tokens[end_tidx+1] in seg_answer_tokens:
							num_same-=1#参数变动_2
						if num_same == 0:
							f1_score = 0
						else:
							p = 1.0 * num_same / span_len
							r = 1.0 * num_same / answer_len
							f1_score = (2 * p * r) / (p + r)#调和平均
						# print('针对answer token: ',seg_answer_tokens,'后续span token ', span_tokens,'num same: ',num_same,'p: ',p)
						if f1_score==0:
							break
						if f1_score > best_f1_score_p:
							# print('best_f1_score_p被更新【后续中】',f1_score)
							best_f1_score_p = f1_score
							best_start_idx, best_end_idx = start_tidx, end_tidx
							best_span_tokens = span_tokens
						if f1_score==1.0:#该开始位置，找到了最匹配span，结束位置再继续缩小无意义
							break

				#每个篇章下为每个answer选择一个最匹配的fake_span
				if best_f1_score_p > bestK_match[a_idx][-1]:
					bestK_match[a_idx]=(d_idx, p_idx, [best_start_idx, best_end_idx], ''.join(best_span_tokens), best_f1_score_p)#替换

	assert len(bestK_match) == answer_num, 'wrong with best k spans'
	# print(bestK_match)
	# print('\n')
	# sample['multi_spanScore_f1'] = bestK_match

	#用于返回的结果
	rst={}
	rst['question_id']=sample['question_id']
	rst['multi_spanScore_f1'] = bestK_match
	return json.dumps(rst, ensure_ascii=False)

if __name__ == '__main__':
	args=parse_args()
	print(args)

	print('开始计时....')
	start = time.time()

	for train_file in args.train_files:
		i = 0
		work = list()
		with open(train_file,'r') as f_in:
			(filepath, tempfilename) = os.path.split(train_file)
			(train_filename, extension) = os.path.splitext(tempfilename)
			out_filename = train_filename+'_multi_fakespan_opt'+extension
			out_file_path=os.path.join(filepath, out_filename)

			with open(out_file_path,'w') as f_out:
				with multiprocess.Pool(args.n_processes) as pool:
					for line in f_in:
						if i < 5000:
							work.append(line)#for trainset
							i += 1
						else:
							pool_res = pool.map(scoreSpan, work)
							f_out.write('\n'.join(pool_res)+'\n')

							work=list()
							work.append(line)
							i = 1

					if i > 0:#处理最后一批
						pool_res = pool.map(scoreSpan, work)
						f_out.write('\n'.join(pool_res))

		print('done 1...')
		time_elapsed = time.time()-start
		print('Training complete in {:.0f}min-{:.0f}s'.format(
			time_elapsed // 60, time_elapsed % 60)) # 打印出来时间

	print('deal with devset all done')

#DEBUG
# sample={}
# sample["documents"]=[]
# doc1={}
# doc1['segmented_paragraphs']=[["手", "账", "，", "指", "用于", "记事", "的", "本子", "。", "干扰1", "干扰2"]]
# sample["documents"].append(doc1)
# doc2={}
# doc2['segmented_paragraphs']=[["就是", "日程簿","，","干扰1", "干扰2"],["日程表", "。","干扰1", "干扰2"]]
# sample["documents"].append(doc2)

# sample["segmented_answers"] = [["记事", "的", "本子", "。"], ["日程", "簿", "，", "日程表", "。"]]

# scoreSpan(sample)


import tkinter as tk

from src.PetriNetModel.ModelFactory import ModelFactory
from src.PetriNetModel.ModelFactoryGui import Gui

from src.Utilities import handle_reset_button, \
    handle_simulation_speed, handle_save_q_button, handle_save_stats_button, handle_run_button

def main():
    root = tk.Tk()
    model_factory = ModelFactory()

    gui = Gui(model_factory, root)

    def clock():
        handle_reset_button(gui, model_factory)

        handle_run_button(gui)
        handle_save_q_button(gui)
        handle_save_stats_button(gui)

        handle_simulation_speed(gui, model_factory)
        model_factory.fire_hidden_transitions()

        root.after(gui.speed.value, clock)

    clock()
    root.mainloop()

if __name__ == '__main__':
    main()