"""Client for HTTP Requests

This module provides a Client object to interface with an API.

"""

import datetime
import json
import logging
import os
import requests
import time

from apps.apihandler.errors import UnprocessableEntity
from requests import HTTPError
from requests import Session
from requests.adapters import HTTPAdapter
#from requests.compat import urljoin
from requests.packages.urllib3.util.retry import Retry # type: ignore

basedir     = os.path.abspath(os.path.dirname(__file__))
logger      = logging.getLogger(__name__)

'''
/*
 *Urls for asking questions of the documents, retrieving the
 * answers, and giving feedback as to the goodness of references.
 */'''
class Client(Session):
    """GeneNetworkQA Client

    Constructs a :obj:`requests.Session` for GeneNetworkQA API requests with
    authorization, base URL, request timeouts, and request retries.

    Args:
        account (str): base address subdomain
        api_key (str): API key
        version (str, optional): API version, defaults to "v3"
        timeout (int, optional): :obj:`` timeout value, defaults to 5
        total (int, optioanl): :obj:`Retry` total value, defaults to 5
        backoff_factor (int, optional): :obj:`Retry` backoff_factor value, defaults to 30

    Usage::
        from genenetworkqa import Client
        gnqa = Client(account="account-name", api_key="XXXXXXXXXXXXXXXXXXX...")
    """

    def __init__(self, account, api_key, v="v3", timeout=5, total=5, backoff_factor=30) -> None:
        """
        """
        super().__init__()
        self.host = f"https://genenetwork.fahamuai.com/api/tasks"
        self.headers.update(self.getAuth(self.openAPIConfig()))
        self.baseUrl      = 'https://genenetwork.fahamuai.com/api/tasks'
        self.answerUrl    = self.baseUrl + '/answers'
        self.feedbackUrl  = self.baseUrl + '/feedback'
        adapter = TimeoutHTTPAdapter(
            timeout=timeout,
            max_retries=Retry(
                total=total,
                status_forcelist=[429, 500, 502, 503, 504],
                backoff_factor=backoff_factor,
            ),
        )
        self.mount("https://", adapter)
        self.mount("http://", adapter)

    def openAPIConfig(self):
        f = open(os.path.join(basedir, "api.config.json") , "rb" )
        result = json.load(f)
        f.close()
        return result

    def getAuth(self, api_config):
        return {"Authorization": "Bearer " + api_config['Bearer Token October 2023']}

    def ask(self, exUrl, *args, **kwargs):
        askUrl = self.baseUrl + exUrl
        res    = self.custom_request('POST', askUrl, *args, **kwargs)
        if (res.status_code != 200):
            return self.negativeStatusMsg(res), 0
        task_id = self.getTaskIDFromResult(res)
        return res, task_id

    def getAnswer(self, taskid, *args, **kwargs):
        query = self.answerUrl + self.extendTaskID(taskid)
        res   = self.custom_request('GET', query, *args, **kwargs)
        if (res.status_code != 200):
            return self.negativeStatusMsg(res), 0
        return res, 1

    def negativeStatusMsg(self, res):
        return 'Problems\n\tStatus code => {0}\n\tReason=> {res.reason}'.format(res.status_code, res.reason)

    def extendTaskID(self, task_id):
        return '?task_id=' + str(task_id['task_id'])

    def getTaskIDFromResult(self, res):
        return json.loads(res.text)

    def custom_request(self, method, url, *args, **kwargs):
        max_retries = 5
        retry_delay = 3

        print ('[{0}] Request begin'.format(datetime.datetime.now()))
        response = super().request(method, url, *args, **kwargs)
        print ('[{0}] Response arrival'.format(datetime.datetime.now()))

        i = 0
        for i in range(max_retries):
            try:
                print ('Raising status for response {0} -- {1}'.format(i+1, datetime.datetime.now()))
                response.raise_for_status()
            except requests.exceptions.RequestException as exc:
                code = exc.response.status_code
                if code == 422:
                    raise UnprocessableEntity(exc.request, exc.response)
                    #from exc
                elif i == max_retries - 1:
                    raise
            if response.ok:
                print('Status code for response is {0}'.format(response.status_code))
                # Give time to get all the data
                print ('[{0}] delay begin'.format(datetime.datetime.now()))
                time.sleep(retry_delay*3)
                print ('[{0}] delay   end'.format(datetime.datetime.now()))
                return response
            else:
                print ('[{1}] Retry {0}'.format(i+1, datetime.datetime.now()))
                time.sleep(retry_delay)
        return response

class TimeoutHTTPAdapter(HTTPAdapter):
    def __init__(self, timeout, *args, **kwargs):
        """TimeoutHTTPAdapter constructor.

        Args:
            timeout (int): How many seconds to wait for the server to send data before
                giving up.
        """
        self.timeout = timeout
        super().__init__(*args, **kwargs)

    def send(self, request, **kwargs):
        """Override :obj:`HTTPAdapter` send method to add a default timeout."""
        timeout = kwargs.get("timeout")
        if timeout is None:
            kwargs["timeout"] = self.timeout

        return super().send(request, **kwargs)


import numpy as np
import policy_value_net
import time
import game
from multiprocessing.dummy import Pool as ThreadPool

"""
    蒙特卡洛树搜索
    用于自我对弈和人机对弈
    自我对弈：自我对弈中再下每一步之前将当前局面喂进神经网络，得出当前局面的胜率和接下来每一步的概率，然后进行扩展和backup 以上步骤执行1600次以后
    输出下一步的位置
    然后根据子节点访问的次数进行softmax函数的概率转换
    最后根据加了狄利克雷噪声的概率分布随机取一个值作为下一步
"""

# 搜索树节点 每个节点包含其父子几点 这个节点的先验概率 访问次数 Q值 和 W值
class Node(object):
    def __init__(self, p, parent):
        self.p = p
        self.parent = parent
        self.N = 0
        self.Q = 0
        self.W = 0
        self.children = {}

    # 根据uct值选择值最大的子节点
    def select(self):
        return max(self.children.items(), key=lambda c: c[1].uct())

    # uct值
    def uct(self, c_puct=5.0):
        return self.Q + c_puct * self.p * (np.sqrt(self.parent.N)) / (self.N + 1)

    # 扩展节点
    def expand(self, act_probs):
        for act, prob in act_probs:
            if act not in self.children:
                self.children[act] = Node(prob, self)

    # 沿着扩展到叶子节点的路线回溯将边的统计数据更新
    def backup(self, leaf_value):
        self.W += leaf_value
        self.N += 1
        self.Q = self.W / self.N

    # 判断是否为叶子节点
    def is_leaf(self):
        return len(self.children) == 0

    def update_value(self, leaf_value):
        if self.parent:
            self.parent.update_value(-leaf_value)
        self.backup(leaf_value)

# 蒙特卡洛树
class MCTS(object):
    def __init__(self, net):
        self.net = net
        self.board = None
        self.root = None
        self.mul_process = 16
        self.pool = ThreadPool(self.mul_process)
        self.arg = [k for k in range(0, 400, 400 // self.mul_process)]

    def search(self, board, node, temp=1e-3):
        self.root = node
        self.board = board
        # self.reset_pool()
        # s_time = time.time()
        for _ in range(400):
            node = self.root
            board = self.board.clone()
            while not node.is_leaf():
                action, node = node.select()
                board.do_move(action)
            act_probs, value = self.net.get_value_policy(board)
            end, winner = board.game_end()
            if not end:
                node.expand(act_probs)
            else:
                if winner == -1:
                    value = 0.0
                else:
                    value = 1.0 if winner == board.current_player else -1.0
            node.update_value(-value)
        # for _ in self.arg:
        #     self.pool.apply_async(self.mc, args=())
        # self.pool.close()
        # self.pool.join()
        actions = []
        times = []
        for action, child in self.root.children.items():
            actions.append(action)
            times.append(child.N + 1e-10)
        action, pi = self.decision(actions, times, temp)
        for act, child in self.root.children.items():
            if action == act:
                # e_time = time.time()
                # print(f"Monte Carlo Tree Search takes {(e_time - s_time)} seconds")
                return action, child, pi

    def reset_pool(self):
        self.pool = ThreadPool(self.mul_process)

    @staticmethod
    def dirichlet_noise(probs, eps=0.25, alpha=0.1):
        return (1 - eps) * probs + eps * np.random.dirichlet(np.full(len(probs), alpha))

    def decision(self, acts, pi, temperature):
        pi = (1.0 / temperature) * np.log(pi)
        pi = np.exp(pi - np.max(pi))
        pi /= np.sum(pi)
        # pi = self.dirichlet_noise(pi)
        action = np.random.choice(acts, p=pi)
        return action, pi

# if __name__ == '__main__':
#     net = policy_value_net.Net()
#     b = game.Board()
#     act_probs, value = net.get_value_policy(b)
#     act, probs = map(np.array, zip(*act_probs))
#     n = Node(None, None)
#     mc = MCTS(net)
#     for i in range(100):
#         b = game.Board()
#         n = Node(None, None)
#         mc.search(b, n)


# -*- coding:utf-8 -*-
"""
@name:   maoyan.py
@time:   2019 / 03 / 24
@author: taifu
"""

import json
import requests
from requests.exceptions import RequestException
import re

# 获取网页源文件
def get_one_page(url):
    try:
        response = requests.get(url)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException:
        return None

# 单页解析
def parse_one_page(html):
    pattern = re.compile('
.*?board-index.*?>(\d+).*?data-src="(.*?)".*?name.*?>(.*?).*?star">(.*?)
.*?releasetime">(.*?)
.*?integer">(.*?).*?fraction">(.*?)', re.S)
    items = re.findall(pattern, html)
    for item in items:
        yield {
            'index': item[0],
            'image': item[1],
            'title': item[2],
            'actor': item[3].strip()[3:],
            'time': item[4].strip()[5:],
            'score': item[5]+item[6]
        }

# 保存到文件
def write_to_file(content):
    with open('maoyan.txt', 'a', encoding='utf-8') as f:
        f.write(json.dumps(content, ensure_ascii=False) + '\n')
        f.close()

# 爬取
def crawl(offset):
    url = 'https://maoyan.com/board/4?offset=' + str(offset)
    html = get_one_page(url)
    for item in parse_one_page(html):
        print(item)
        write_to_file(item)

# 入口
if __name__ == '__main__':
    for i in range(10):
        crawl(i*10)


"""Fetch paralogs from Ensembl

Example usage:
python3 src/get_paralogs.py --reuse
"""

import argparse
import os
import re
from time import sleep
import json as ljson
import gzip
import csv
import traceback

import requests

from lib import repo, module, ctx, organisms

# # Enable importing local modules when directly calling as script
# if __name__ == "__main__":
#     cur_dir = os.path.join(os.path.dirname(__file__))
#     sys.path.append(cur_dir + "/..")

# from lib import download_gzip

def fetch_genes(organism):
    """List genes symbols for an organism
    """

    ids_by_gene = {}
    genes_by_id = {}
    genes = []
    prefix = ''
    # E.g. https://raw.githubusercontent.com/eweitz/ideogram/master/dist/data/cache/homo-sapiens-genes.tsv
    genes_url = (
        "https://raw.githubusercontent.com/eweitz/ideogram/"
        f"master/dist/data/cache/genes/{slug(organism)}-genes.tsv.gz"
    )
    print('genes_url')
    print(genes_url)
    response = requests.get(genes_url)

    if response.status_code != 200:
        print(f"Status code {response.status_code} for {genes_url}")
        return [genes, prefix, ids_by_gene, genes_by_id]

    tsv_string = gzip.decompress(response.content).decode('utf-8')
    # print('tsv_string')
    # print(tsv_string)
    reader = csv.reader(tsv_string.splitlines(), delimiter="\t")
    for row in reader:
        if row[0][0] == '#':
            if '## prefix' in row[0]:
                prefix = row[0].split('prefix: ')[1]
                continue
        if len(row) < 4: continue
        # row: [chr, start, length, slim_id, symbol, description]
        gene = row[4] # more formally, gene symbol
        id = row[3]
        ids_by_gene[gene] = id
        genes_by_id[id] = gene
        genes.append(gene)

    return [genes, prefix, ids_by_gene, genes_by_id]

def slug(value):
    return value.lower().replace(" ", "-")

def lossy_optimize_paralogs(json_str):
    try:
        json = ljson.loads(json_str)
    except Exception as e:
        return []

    if "error" in json:
        return []

    trimmed_ids = []
    for h in json["data"][0]["homologies"]:
        trimmed_id = re.sub(r'[A-Za-z]+0+', '', h["id"])
        trimmed_ids.append(int(trimmed_id))
    return trimmed_ids

class EnsemblCache():

    def __init__(self, output_dir="data/", reuse=False):
        self.output_dir = output_dir
        self.tmp_dir = f"tmp/"
        self.reuse = reuse

        if not os.path.exists(self.output_dir):
            os.makedirs(self.output_dir)
        if not os.path.exists(self.tmp_dir):
            os.makedirs(self.tmp_dir)

    def fetch_paralogs(self, organism, genes, gene_dir):
        """For given genes, retrieve paralogs from Ensembl; write each to file
        """

        prev_error_pwids = []
        error_pwids = []

        error_path = gene_dir + "errors.csv"
        if os.path.exists(error_path):
            with open(error_path) as f:
                prev_error_pwids = f.read().split(",")
                error_pwids = prev_error_pwids

        for gene in genes:
            json_path = gene_dir + gene + ".json"

            if "/" in gene:
                print(f"Skipping gene with slash in name: {gene}")
                error_pwids.append(gene)
                continue

            if self.reuse:
                if os.path.exists(json_path):
                    print(f"Found cache; skip processing {gene}")
                    continue
                elif id in prev_error_pwids:
                    print(f"Found previous error; skip processing {gene}")
                    continue

            url = (
                f"https://rest.ensembl.org"
                f"/homology/symbol/{slug(organism).replace('-', '_')}/{gene}"
                f"?format=condensed&type=paralogues"
                f"&content-type=application/json"
            )

            print('url')
            print(url)

            try:
                sleep(0.1)
                paralogs = requests.get(url).text
            except Exception as e:
                print(f"Encountered error when stringifying JSON for {gene}")
                error_pwids.append(gene)
                with open(error_path, "w") as f:
                    f.write(",".join(error_pwids))
                sleep(0.1)
                continue

            print("Preparing and writing " + json_path)

            with open(json_path, "w") as f:
                f.write(paralogs)

    def optimize_paralogs(self, genes, ids_by_gene, genes_by_id, tmp_gene_dir, gene_dir):
        optimize_errors = []

        genes_by_paralogs = {}

        num_redundant_paralogs = 0
        seen_genes = {}

        rows = []
        for gene in genes:
        # for gene in genes[:50]: # Helpful for debugging

            # Disregard fusion genes and genes like "AC113554.1"
            if (
                "/" in gene or
                re.match(r'^(AC|AL|BX|AF)[0-9]+\.[0-9]$', gene) #or
                # re.match(r'^RNU[0-9]-', gene)
            ): continue

            # original_name = json_path.split("/")[-1]
            # gene = original_name.split(".json")[0]
            json_path = tmp_gene_dir + gene + '.json'
            # json_path = 'tmp/homo-sapiens/ACE2.json'
            if not os.path.exists(json_path):
                optimize_errors.append(gene)
                continue

            original_gene = gene
            # The same genes are often capitalized differently in different
            # organisms.  We can leverage this to decrease cache size by
            # ~2x.  E.g. human "MTOR" and orthologous mouse "Mtor".
            gene = gene.upper()

            if original_gene in seen_genes:
                continue

            # pwid = re.search(r"WP\d+", name).group() # pathway ID
            optimized_tsv_path = gene_dir + gene + ".tsv"

            # repo_url = f"https://github.com/{repo}/tree/main/"
            # code_url = f"{repo_url}src/{module}"
            # data_url = f"{repo_url}{optimized_tsv_path}"
            # wp_url = f"https://www.wikipathways.org/index.php/Pathway:{pwid}"
            # provenance = "\n".join([
            #     "<!--",
            #     f"  WikiPathways page: {wp_url}",
            #     f"  URL for this compressed file: {data_url}",
            #     # f"  Uncompressed GPML file: {original_name}",
            #     # f"  From upstream ZIP archive: {url}",
            #     f"  Source code for compression: {code_url}",
            #     "-->"
            # ])

            with open(json_path, 'rb') as f:
                json = f.read()

            if json.decode("utf-8") == '{"data": [homologies: []]}':
                print(f"Gene found, but no paralogs for {gene}")
                continue

            # print(f"Optimizing to create: {optimized_tsv_path}")

            try:
                paralogs = lossy_optimize_paralogs(json)

                if len(paralogs) == 0:
                    continue

                if original_gene not in ids_by_gene:
                    print('Missing gene in ids_by_gene: ' + original_gene)
                    # exit()
                    continue

                gene_id = ids_by_gene[original_gene]
                # print('paralogs, genes[:50], genes.index(genes_by_id[str(paralogs[0])])')
                # print(paralogs, genes[:50], genes.index(genes_by_id[str(paralogs[0])]))
                paralogs = list(set(paralogs))
                paralogs.sort()
                paralogs.append(int(gene_id))
                tmp_ids = paralogs
                tmp_ids.sort()
                # tmp_ids = sorted(tmp_ids, key=lambda p: genes.index(genes_by_id[str(p)]))

                tsv = "\t".join([str(i) for i in paralogs])
                tmp_tsv = "\t".join([str(i) for i in tmp_ids])

                # Many genes share all their paralogs (minus themselves) with
                # other genes.  This accounts for that, and compresses the
                # combined paralog cache size by ~3x.
                if "\t" in tsv:
                    if tmp_tsv in genes_by_paralogs:
                        pointer = genes_by_paralogs[tmp_tsv]
                        pointer_id = ids_by_gene[pointer]
                        tsv = '_' + pointer + "\t" + pointer_id
                        num_redundant_paralogs += 1
                    else:
                        genes_by_paralogs[tmp_tsv] = original_gene

                # Omit current gene from its own paralog list
                split_tsv = tsv.split("\t")
                if (gene_id in split_tsv):
                    split_tsv.remove(gene_id)

                tsv = "\t".join(split_tsv)
                tsv = gene_id + "\t" + tsv

                tsv = tsv.encode()
                seen_genes[original_gene] = 1
            except Exception as e:
                handled = "Encountered error converting TSV for gene"
                handled2 = "not well-formed"
                if handled in str(e) or handled2 in str(e):
                    # print('Handled an error')
                    print(e)
                    optimize_errors.append(original_gene)
                    continue
                else:
                    print('Encountered fatal error')
                    print(traceback.format_exc())
                    # raise Exception(e)
                    # print('json')
                    # print(json)
                    # exit()
                    continue

            with open(optimized_tsv_path, "wb") as f:
                f.write(tsv)

            tsv = tsv.decode('utf-8')
            if len(tsv) > 0:
                rows.append(f"{original_gene}\t{tsv}")

        print('num_redundant_paralogs')
        print(num_redundant_paralogs)
        num_errors = len(optimize_errors)
        if num_errors > 0:
            print(f"{num_errors} pathways had optimization errors:")
            print(",".join(optimize_errors))

        return rows

    def populate_by_org(self, organism):
        """Fill caches for a configured organism
        """
        tmp_gene_dir = self.tmp_dir + slug(organism) + "/"
        if not os.path.exists(tmp_gene_dir):
            os.makedirs(tmp_gene_dir)

        gene_dir = self.output_dir  + slug(organism) + "/"
        if not os.path.exists(gene_dir):
            os.makedirs(gene_dir)

        # gpml_dir = self.output_dir +  + organism + /"
        # if not os.path.exists(gpml_dir):
        #     os.makedirs(gpml_dir)

        [genes, prefix, ids_by_gene, genes_by_id] = fetch_genes(organism)
        # self.fetch_paralogs(organism, genes, tmp_gene_dir)
        print('len(genes)')
        print(len(genes))
        rows = self.optimize_paralogs(genes, ids_by_gene, genes_by_id, tmp_gene_dir, gene_dir)

        combined_dir = self.output_dir + "combined/"
        if not os.path.exists(combined_dir):
            os.makedirs(combined_dir)
        combined_path = combined_dir + slug(organism) + "-paralogs.tsv.gz"
        rows.insert(0, f"## prefix: {prefix}")
        combined = "\n".join(rows).encode()
        compressed_combined = gzip.compress(combined)
        with open(combined_path, "wb") as f:
            f.write(compressed_combined)
        print(f"Wrote {combined_path}")

    def populate(self):
        """Fill caches for all configured organisms

        Consider parallelizing this.
        """
        # organisms = ["Homo sapiens", "Mus musculus"] # Comment out to use all
        # organisms = ["Homo sapiens"] # Comment out to use all
        # organisms = ["Mus musculus"] # Comment out to use all
        # organisms = ["Caenorhabditis elegans"] # Comment out to use all
        for organism in organisms:
            self.populate_by_org(organism)

# Command-line handler
if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument(
        "--output-dir",
        help=(
            "Directory to put outcome data.  (default: %(default))"
        ),
        default="data/"
    )
    parser.add_argument(
        "--reuse",
        help=(
            "Whether to use previously-downloaded raw data"
        ),
        action="store_true"
    )
    args = parser.parse_args()
    output_dir = args.output_dir
    reuse = args.reuse

    EnsemblCache(output_dir, reuse).populate()


import pygame
import time
import random
from metodos import endGame, initGame

# inicia el pygame para el juego
pygame.init()
sizeScreen = (470, 600)
screen = pygame.display.set_mode(sizeScreen)
clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)  # Fuente para el texto
font2 = pygame.font.Font(None, 16)  # Fuente para el sub texto

# assets

# imgs
background = pygame.image.load("assets/calle.png")

moto = pygame.image.load("assets/moto.png")
motoScaled = pygame.transform.scale(moto, (20, 65))

carBlue = pygame.image.load("assets/carBlue.png")
carGreen = pygame.image.load("assets/carGreen.png")
carRed = pygame.image.load("assets/carRed.png")
carRose = pygame.image.load("assets/carRose.png")
carYellow = pygame.image.load("assets/carYellow.png")

piston = pygame.image.load("assets/piston.png")
pistonScaled = pygame.transform.scale(piston, (40, 90))
tyre = pygame.image.load("assets/tyre.png")
tyreScaled = pygame.transform.scale(tyre, (60, 60))

# sounds
breakSound = pygame.mixer.Sound('assets/audio/break.wav')
runSound = pygame.mixer.Sound('assets/audio/runmoto.wav')
pistonSound = pygame.mixer.Sound('assets/audio/piston.wav')
pistonMommentSound = pygame.mixer.Sound('assets/audio/pistonMoment.wav')
crashSound = pygame.mixer.Sound('assets/audio/crash.wav')

# general variables
backgroundPosition = 0
fps = 60
xMoto = 180
yMoto = 480
velocidadMovXMoto = 0
velocidadMovYMoto = 0
initialTime = pygame.time.get_ticks()
currentSeconds = 0
secondsToSubtract = 0
velocityGame = 2
powers = [pistonScaled]
play = True
# Lista de posiciones de los Elementos(carros, llantas y pistones)
elementsPositions = []
powerActive = False #Para saber cuando el poder esta activo
timePowerActive = 0 #para contabilizar el tiempo que el poder esta activo

initGame(screen) # Primera pantalla para el juego

# Función para agregar un nuevo elemento a la lista
def addElements():
    lane = random.randint(0, 1)  # Selección aleatoria de un carril
    xPos = 170 + lane * 60  # Posición X según el carril seleccionado
    yPos = -100 * (len(elementsPositions) * 3)   # Empieza arriba de la pantalla la operación funciona para poner más separados los elementos en la pantalla
    selectedElement = selectElements(random.randint(0, 6)) # Selección aleatoria de un elemento

    # Para centrar el piston el carril
    if selectedElement == pistonScaled:
        xPos += 15

    elementsPositions.append((xPos, yPos, selectedElement))  # Agregar el elemento a la lista

# Función para mover los carros
def updateElements():
    for i, (x, y, element) in enumerate(elementsPositions):
        y += velocityGame  # Velocidad de movimiento del elemento
        elementsPositions[i] = (x, y, element)  # Actualizar posición del elemento

        # Eliminar elementos que hayan salido de la pantalla
        if y > 600:
            elementsPositions.pop(i)

# este metodo controla el tiempo o velovdad del juego
def addVelocityGame():
    global velocityGame
    if currentSeconds % 10 == 0 and currentSeconds != 0:
        velocityGame += 0.01

# función para retornar un elemento según la posición
def selectElements(position):
    if position == 0:
        return carBlue
    elif position == 1:
        return carGreen
    elif position == 2:
        return carRed
    elif position == 3:
        return carRose
    elif position == 4:
        return carYellow
    if position == 5:
        return pistonScaled
    elif position == 6:
        return tyreScaled

# Bucle principal del juego
runSound.play(-1)
while play:
    addVelocityGame()
    # Calcular el tiempo transcurrido
    currentSeconds = pygame.time.get_ticks() - initialTime

    # Formatear el tiempo en segundos
    currentSeconds = currentSeconds // 1000

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            play = False
        # captura el evento de clickar una tecla
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                velocidadMovXMoto += -(velocityGame + 1)
            if event.key == pygame.K_RIGHT:
                velocidadMovXMoto += (velocityGame + 1)
            if event.key == pygame.K_UP:
                velocidadMovYMoto = -(velocityGame + 1)
            if event.key == pygame.K_DOWN:
                velocidadMovYMoto = (velocityGame + 1)
            if event.key == pygame.K_SPACE:
                if not powerActive:
                    if len(powers) > 0:
                        powers.pop(0)
                        timePowerActive = currentSeconds
                        powerActive = True
        # captura el evento de soltar una tecla
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                velocidadMovXMoto = 0
            if event.key == pygame.K_RIGHT:
                velocidadMovXMoto = 0
            if event.key == pygame.K_UP:
                velocidadMovYMoto = 0
            if event.key == pygame.K_DOWN:
                velocidadMovYMoto = 0

    backgroundPosition += velocityGame  # Velocidad de desplazamiento

    # Actualización de la posición de la moto con reglas para no salirse de la carretera
    xMoto += velocidadMovXMoto
    if xMoto <= 179 or xMoto >= 270:
        xMoto -= velocidadMovXMoto
        velocidadMovXMoto = 0

    yMoto += velocidadMovYMoto
    if yMoto >= 480 or yMoto <= 2:
        yMoto -= velocidadMovYMoto
        velocidadMovYMoto = 0

    # Dibujar fondo
    screen.blit(background, (0, backgroundPosition))
    screen.blit(background, (0, backgroundPosition - sizeScreen[1])) #este es para que se vea el fondo cuando se vaya acabando el primero

    # Dibujar elementos y controla colisiones
    for (x, y, element) in elementsPositions:
        elementDrawed = screen.blit(element, (x, y))
        # verificar colisiones con la moto, agrega sonidos y poderes
        if motoDrawed.colliderect(elementDrawed):
            if element == carBlue or element == carGreen or element == carRed or element == carRose or element == carYellow:
                runSound.stop()
                crashSound.play()
                play = False #para finalizar el juego
            elif element == pistonScaled:
                powers.append(element)
                pistonSound.play()
                elementsPositions.remove((x, y, element))
            elif element == tyreScaled:
                secondsToSubtract += 5
                breakSound.play()
                elementsPositions.remove((x, y, element))

    # Crea los textos para luego mostrarlos
    textTime = font.render("Time: " + str(currentSeconds) + " sec", True, (0, 0, 0))
    textTime2 = font.render("To subtract: " + str(secondsToSubtract) + " sec", True, (0, 0, 0))
    textTime3 = font.render("Power:" + str(len(powers)), True, (0, 0, 0))
    textTime4 = font2.render("press space for power", True, (0, 0, 0))
    textTime5 = font2.render("Power Active: " + str(powerActive), True, (0, 0, 0))

    # Mostrar el texto en la pantalla
    screen.blit(textTime, (10, 10))
    screen.blit(textTime2, (10, 40))
    screen.blit(textTime3, (10, 70))
    screen.blit(textTime4, (10, 100))
    screen.blit(textTime5, (10, 120))

    # muestra moto
    motoDrawed = screen.blit(motoScaled, (xMoto, yMoto))

# control del poder activado, si se encuentra activo vaciamos la lista de elementos, reproducimos sonido y lo desactivamos
    if not powerActive:
        # Generar nuevos carros aleatoriamente
        if random.random() < 0.05:  # Probabilidad de generar un nuevo carro en cada iteración
            addElements()   #agrega elementos al juego

        # Actualizar posición de los elementos
        updateElements()
    else:
        elementsPositions = []
        pistonMommentSound.play()
        if currentSeconds - timePowerActive >= 10:
            timePowerActive = 0 #reiniciamos el tiempo
            powerActive = False #apagamos el poder

    #reiniciamos posicion del fondo
    if backgroundPosition >= sizeScreen[1]:
        backgroundPosition = 0

    pygame.display.flip()
    clock.tick(fps)

# metodo para finalizar el juego
endGame(currentSeconds - secondsToSubtract)


# We can trigger an action once all parties reach the barrier.
# The callable could be a lambda or a function with no arguments.

from time import sleep
from random import random
from threading import Thread
from threading import Barrier

# action once all threads reach the barrier
def report():
    # report once all theads are done
    print('All threads have thier result')

def task(barrier: Barrier, number):
    value = random()*10
    sleep(value)
    print(f'Thread: {number} done; got: {value}')
    # wait on all other threads to complete
    barrier.wait()

# Because the main thread no longer needs to wait on the barrier,
# we can reduce the number of expected parties to reach the barrier to five,
# to match the five worker threads
barrier = Barrier(5, action=report)
for i in range(5):
    Thread(target=task, args=(barrier, i)).start()


import sys
import re

hcl_re = re.compile("#[0-9a-f]{6}")
expected_keys = {"byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"}
class Id :
    def __init__(self):
        self.d={}

    def parse(self,l) :
        kvs = (kv.split(':') for kv in l.split())
        self.d.update({kv[0]:kv[1] for kv in kvs})

    def check(self) :
        print("\n", self.d)
        r = expected_keys.intersection(self.d.keys())
        if len(r) < len(expected_keys):
            print("missing keys")
            return False

        byr = int(self.d["byr"])
        if byr < 1920 or 2002 < byr :
            print("invalid byr", byr)
            return False

        iyr = int(self.d["iyr"])
        if iyr < 2010 or 2020 < iyr :
            print("invalid iyr", iyr)
            return False

        eyr = int(self.d["eyr"])
        if eyr < 2020 or 2030 < eyr :
            print("invalid eyr", eyr)
            return False

        hgt = self.d["hgt"]
        if hgt.endswith("in") :
            h = int(hgt[:-2])
            if h < 59 or 76 < h :
                print("invalid hgt", hgt, h)
                return False
        elif hgt.endswith("cm") :
            h = int(hgt[:-2])
            if h < 150 or 193 < h :
                print("invalid hgt", hgt, h)
                return False
        else :
            print("invalid hgt", hgt)
            return False

        hcl = self.d["hcl"]
        if not hcl_re.match(hcl) :
            print("invalid hcl", hcl)
            return False

        ecl = self.d["ecl"]
        if not ecl in {"amb", "blu", "brn", "gry", "grn", "hzl", "oth"} :
            print("invalid ecl", ecl)
            return False

        pid = self.d["pid"]
        if not len(pid) == 9 :
            print("invalid pid", pid)
            return False
        p = int(pid)
        return True

with open(sys.argv[1]) as input:
    count = 0
    full_count = 0
    id = Id()
    for l in input :
        if 1 < len(l):
            id.parse(l)
        else :
            full_count += 1
            res = False
            try :
                res = id.check()
            except Exception as e :
                print(e)
                pass
            if res :
                count += 1
            print(res)
            id.d.clear()

    if len(id.d):
            full_count += 1
            res = False
            try :
                res = id.check()
            except Exception as e :
                print(e)
                pass
            if res :
                count += 1
            print(res)

    print(count, full_count, sep='/')


with open('14.txt') as file:
    str1 = file.read()

# example
example_str = '''498,4 -> 498,6 -> 496,6
503,4 -> 502,4 -> 502,9 -> 494,9'''

# # un/comment this to toggle example vs actual data
# str1 = example_str

#########

lst1 = str1.split('\n')

lst2 = [strng.split(' -> ') for strng in lst1]

lst3 = [[strng.split(',') for strng in sublst] for sublst in lst2]

lst = [[tuple([int(strng) for strng in pair]) for pair in sublst] for sublst in lst3]

print('lst is', lst[0])

lst_x = [[pair[0] for pair in sublst] for sublst in lst]

lst_y = [[pair[1] for pair in sublst] for sublst in lst]

pathwise_min_x = [min(sublst) for sublst in lst_x]
min_x = min(pathwise_min_x)
pathwise_max_x = [max(sublst) for sublst in lst_x]
max_x = max(pathwise_max_x)
pathwise_min_y = [min(sublst) for sublst in lst_y]
min_y = min(pathwise_min_y)
pathwise_max_y = [max(sublst) for sublst in lst_y]
max_y = max(pathwise_max_y)

print('x bounds are', min_x, 'and', max_x)

print('y bounds are', min_y, 'and', max_y)

print('max_y is', max_y)

# print('x bounds are', min(min(lst_x)), 'and', max(max(lst_x)))

# print('y bounds are', min(min(lst_y)), 'and', max(max(lst_y)))

print('minimum length path has', min([len(path) for path in lst]), 'points')

### part 1

# this function takes in two 2-element tuples -- (x,y)-coordinates -- which are either horizontally or vertically aligned, and returns a list of the tuples comprising the closed interval between them.
def straight_line(pair0, pair1):
    Delta = (0,0)
    if (pair0[0] == pair1[0]) and (pair0[1] != pair1[1]):
        dy = pair1[1] - pair0[1]
        Delta = (0, dy // abs(dy))
    if (pair0[0] != pair1[0]) and (pair0[1] == pair1[1]):
        dx = pair1[0] - pair0[0]
        Delta = (dx // abs(dx), 0)
    output = [pair0]
    current = pair0
    while current != pair1:
        current = tuple(map(sum, zip(current, Delta)))
        output.append(current)
    return output

blocks1 = set()

for path in lst:
    for i in range(len(path)-1):
        segment = straight_line(path[i], path[i+1])
        for pair in straight_line(path[i], path[i+1]):
            blocks1.add(pair)

# save for later
blocks2 = blocks1.copy()

counter1 = 0
fell_into_abyss = False
initial = (500, 0)
current = initial

while not fell_into_abyss:
    down = tuple(map(sum, zip(current, (0, 1))))
    down_left = tuple(map(sum, zip(current, (-1, 1))))
    down_right = tuple(map(sum, zip(current, (1, 1))))
    if down not in blocks1:
        current = down
    else:
        if down_left not in blocks1:
            current = down_left
        else:
            if down_right not in blocks1:
                current = down_right
            else:
                counter1 += 1
                blocks1.add(current)
                current = initial
    if current[1] > max_y:
        fell_into_abyss = True

print('counter1 is', counter1)

### part 2

# obviously don't literally add an infinite line. rather, the worst-case scenario is that a block moves only down-left or only down-right. so the x-coordinates can start at 500-(max_y+2) and end at 500+(max_y+2), give or take.

for i in range(2 * max_y + 10):
    blocks2.add((500-max_y-5+i, max_y+2))

counter2 = 0
source_blocked = False
initial = (500, 0)
current = initial

while not source_blocked:
    down = tuple(map(sum, zip(current, (0, 1))))
    down_left = tuple(map(sum, zip(current, (-1, 1))))
    down_right = tuple(map(sum, zip(current, (1, 1))))
    if down not in blocks2:
        current = down
    else:
        if down_left not in blocks2:
            current = down_left
        else:
            if down_right not in blocks2:
                current = down_right
            else:
                counter2 += 1
                blocks2.add(current)
                if current == (500, 0):
                    source_blocked = True
                current = initial

print('counter2 is', counter2)


from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import db
import datetime
import time
import logging

DRIVER = webdriver.Chrome()
DATE = None
logging.basicConfig(filename="log.log", level=logging.INFO)

ADDRESSES = {
    'soccer': 'https://www.myscore.com.ua/football',
    'hockey': 'https://www.myscore.com.ua/hockey/',
}

def open_selected_sport_completed_games(sport_name):
    c_address = ADDRESSES.get(sport_name)
    logging.info(f"open {c_address}")

    DRIVER.get(c_address)
    ul = DRIVER.find_element_by_css_selector('ul.tabs__list')
    items = ul.find_elements_by_tag_name("li")

    for item in items:
        if item.text == 'Завершенные':
            item.click()
            return

def get_all_leagues(sport_name):
    games = {}
    try:
        games_list = DRIVER.find_element_by_css_selector(f'div.sportName.{sport_name}')
        logging.info(f"there are completed {sport_name} games for today")

    except NoSuchElementException:
        logging.info(f"there are no completed {sport_name} games today")
        return

    items = games_list.find_elements_by_css_selector('div.event__header')
    (games_list.find_elements_by_class_name('event__match.event__match--oneLine'))

    for extended_item in items:
        try:
            extended_item.find_element_by_css_selector('div.event__expander.icon--expander.collapse').click()
        except NoSuchElementException:
            pass

    for item in items:
        title_box = item.find_element_by_css_selector('div.event__titleBox')
        country = title_box.find_element_by_css_selector('span.event__title--type').text
        league_name = title_box.find_element_by_css_selector('span.event__title--name').text
        item.find_element_by_css_selector('div.event__expander.icon--expander.expand').click()
        current_league_games = games_list.find_elements_by_css_selector('.event__match.event__match--oneLine')
        for game in current_league_games:
            id_ = game.get_attribute('id')
            stage = game.find_element_by_css_selector('div.event__stage').text
            if stage != 'Завершен':
                # delete canceled games
                current_league_games.remove(game)
                continue
            participant_home = game.find_element_by_css_selector('div.event__participant.event__participant--home').text
            participant_away = game.find_element_by_css_selector('div.event__participant.event__participant--away').text

            score_1, score_2 = None, None
            if sport_name == 'soccer':
                score_1, score_2 = game.find_elements_by_css_selector('span')
            elif sport_name == 'hockey':
                score_1 = game.find_element_by_css_selector('div.event__score.event__score--home').text
                score_2 = game.find_element_by_css_selector('div.event__score.event__score--away').text

            if score_1 is None or score_2 is None:
                continue

            game_obj = db.Game(id_, sport_name, participant_home, participant_away, score_1.text, score_2.text, country,
                               league_name)
            games[id_] = game_obj

        if len(current_league_games) == 0:
            # Deleting a record of the league if there were only canceled games in it
            items.remove(item)

        item.find_element_by_css_selector('div.event__expander.icon--expander.collapse').click()
    return games

if __name__ == '__main__':

    logging.info("---------Parser started---------")
    db.create_table()
    DATE = datetime.date.today()
    logging.info(f"set DATE {DATE}")

    while True:
        if DATE != datetime.date.today():
            db.drop_table()
            db.create_table()
            DATE = datetime.date.today()
            logging.info(f"set DATE {DATE}")

        for game_name in ADDRESSES:
            logging.info(f"started get info about {game_name}")
            open_selected_sport_completed_games(game_name)
            games = get_all_leagues(game_name)
            db.add_games(games)

        time.sleep(3600)


import threading
import os
import socket
import funcs
import queue
HOST = funcs.HOST #'172.16.30.20'
PORT = funcs.PORT
write_lock = threading.Lock()
socket_lock = threading.Lock()
write_queues = {}

def print_help():
	print('''
	Commands -

	req - 					Request name of connected users

	connect [users] room [room number] -    Connected requested users to your broadcast room no
						Use - connect user1,user2,user3..usern room desired_room_no

	roomchat - 				Broadcast message to any of your rooms
						Use - roomchat desired_room_no hello world!

	roomsend -				Broadcast a file to any of your rooms
						use - roomsend desired_room_no file1,file2...file_n
	q -					Quit

	h -					Help
		''')
room_lock = threading.Lock()
room_list = set()

def handle_recieve(sock):
	while True:
		try:
			uno , fno , size = funcs.recieve_header(sock)
			if fno == 999: # Message file to print
				msg = funcs.recieve_message(sock,size)
				print(msg)
			elif fno == 998:
				msg = funcs.recieve_message(sock,size)
				msg = msg.split(' ',1)
				newroom = msg[0]
				with room_lock:
					room_list.add(newroom)
				msg = msg[1]
				print("Connected to room " + newroom +" "+ msg)
			elif fno == 997:
				msg = funcs.recieve_message(sock,size)
				print(msg)
			elif fno < 997: # Other type of packets
				key = str(uno)+','+str(fno)
				if size == 0:
					handle_completion(key)
				else:
					data = funcs.recieve_data(sock,size)
					with write_lock:
						if write_queues.get(key,None):
							q = write_queues.get(key)
							q.put(data)
						else:
							msg = data.decode('utf-8')
							message = msg
							msg = msg.split(',') #filename,username
							file_name = msg[0]
							user_name = msg[1]
							print('Recieving File {} from {}'.format(file_name,user_name))
							q = queue.Queue()
							write_queues[key] = q
							write_thread = threading.Thread(target = write_file,args = [file_name,user_name,q],daemon = True)
							write_thread.start()
			else:
				print('Unknown Data recieved')
		except(ConnectionError):
			print('Srever Disconnected')
			break

def handle_file_send(sock,file_num,uno,file_name,user_name,room):
	if len(room) < 3:
		room = '0'*(3-len(room))+room
	print("handling file {} num {} room {}".format(file_name,file_num,room))
	f = open(file_name,'rb')
	with socket_lock:
		funcs.send_message(sock,uno,room+file_name+','+user_name,file_num)
	room = room.encode('utf-8')
	data = f.read(funcs.CHUNK_SIZE)
	while data != b'':
		data = room + data
		data = funcs.create_packet(uno,file_num,data)
		with socket_lock:
			funcs.send_data(sock,data)
		data = f.read(funcs.CHUNK_SIZE)
	#Sending closing information
	data = room + data
	data = funcs.create_packet(uno,file_num,data)
	with socket_lock:
		funcs.send_data(sock,data)

	print('File {} transfered'.format(file_name))
	f.close()

def handle_completion(key):
	with write_lock:
		q = write_queues[key]
	if q:
		q.put(None)
		del write_queues[key]

def write_file(file_name,user_name,q):

	f = open(file_name,'wb')
	while True:
		data = q.get()
		if data == None:
			print('File {} from {} completed'.format(file_name,user_name))
			f.close()
			break
		f.write(data)

if __name__ == '__main__':
	print_help()
	try :
		sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
		sock.connect((HOST,PORT))
		name , host_user_no = funcs.register_client(sock)
		file_no = 0
		recv_thread = threading.Thread(target = handle_recieve,args = [sock],daemon = True)
		recv_thread.start()
	except(ConnectionRefusedError,ConnectionError):
		print('The Server seems offline......\nPlease Try Again Later')
		exit()

	print('Connected to {} At {} '.format(HOST,PORT))

	while True:
		inp = input()
		try:
			inp = inp.split(' ',1)
			if 'h' == inp[0]:
				print_help()
			elif 'q' == inp[0]:
				exit()
			elif 'connect' == inp[0]:
				inp = inp[1]
				funcs.send_connect(sock,host_user_no,inp)
			elif 'roomchat' == inp[0]:
				inp = inp[1].split(' ',1)
				room = inp[0]
				with room_lock:
					if not room in room_list:
						print("Invalid room")
						continue
				message = name + ": " + inp[1]
				if len(room) <3:
					room = '0'*(3-len(room))+room
				message = room + message
				with socket_lock:
					funcs.send_message(sock,host_user_no,message)
			elif 'roomsend' == inp[0]:
				signal = inp[1].split(' ',1)
				room = signal[0]
				with room_lock:
					if not room in room_list:
						print("Invalid room")
						continue
				files = signal[1].split(',')
				for f in files:
					print('file {}'.format(f))
					file_no +=1
					send_thread = threading.Thread(target = handle_file_send,args=[sock,file_no,host_user_no,f,name,room],daemon = True)
					send_thread.start()
			elif 'req' == inp[0]:
				with socket_lock:
					funcs.send_message(sock,host_user_no,'',997)
			else:
				print('Wrong Message')
		except(ConnectionError):
			print('Server Disconnected')
			break


from rest_framework import serializers
import datetime
from persons.models import Person

'''
#Serializers can convert ---> Json
#Serializers can validate data
'''
#class PersonCustomSerilizer(serializers.Serializer):
#    text_field = serializers.CharField()

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = [
            'id',
            'Pid',
            'PersonName',
            'Person_sex',
            'Person_BDate',
            'Person_CDate'
        ]

    def validate_personName(self,value):
        if len(value) > 30:
            raise serializers.ValidationError("PersonName should not be more than 30 Char")
        return value
    def validate_personsex(self,value):
        if value not in ['M','F','N']:
            raise  serializers.ValidationError("PersonSex should be M F or N")
        return value
    def validate_personbdate(self,value):
        if datetime.datetime.strptime(value, '%Y-%m-%d'):
            raise serializers.ValidationError("Incorrect data format, should be YYYY-MM-DD")
        return value


import requests
import socket
import atexit
import os
global server

user = "User:"
bot = "Bot:"
ENDPOINT = "http://127.0.0.1:5001"
conversation_history = []
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("127.0.0.1", 12345))
def get_prompt(user_msg):
    return {
        "prompt": f"{user_msg}",
        "use_story": False,
        "use_memory": False,
        "use_authors_note": False,
        "use_world_info": False,
        "max_context_length": 2048,
        "max_length": 80,
        "rep_pen": 1.0,
        "rep_pen_range": 2048,
        "rep_pen_slope": 0.7,
        "temperature": 0.7,
        "tfs": 0.97,
        "top_a": 0.8,
        "top_k": 0,
        "top_p": 0.5,
        "typical": 0.19,
        "sampler_order": [6,0,1,3,4,2,5],
        "singleline": False,
        "sampler_seed": 69420, # Use specific seed for text generation?
        "sampler_full_determinism": False, # Always give same output with same settings?
        "frmttriminc": False, #Trim incomplete sentences
        "frmtrmblln": False, #Remove blank lines
        "stop_sequence": ["\n\n\n\n\n", f"{user}"]
        }
def handle_client(client_socket):
    try:
        client_socket.send(user.encode('utf-8'))
        while True:
            user_message = client_socket.recv(1024).decode('utf-8').strip()

            if len(user_message) < 1:
                bot_response = f"{bot}Please provide a valid input.\n"
            else:
                fullmsg = f"{conversation_history[-1] if conversation_history else ''}{user} {user_message}\n{bot} "
                prompt = get_prompt(fullmsg)
                response = requests.post(f"{ENDPOINT}/api/v1/generate", json=prompt)
                if response.status_code == 200:
                    results = response.json()['results']
                    text = results[0]['text']
                    response_text = text.split('\n')[0].replace("  ", " ")
                    conversation_history.append(f"{fullmsg}{response_text}\n")
                    bot_response = f"{bot} {response_text}\n"
                else:
                    bot_response = f"{bot} Unable to generate a response.\n"
            client_socket.send(bot_response.encode('utf-8'))
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        client_socket.close()
def main():
    os.system(f"clear")
    server.listen(5)
    print("Telnet server started. Listening for connections...")
    try:
        while True:
            client_socket, client_address = server.accept()
            print(f"Connection established with {client_address}")
            handle_client(client_socket)
    except KeyboardInterrupt:
        print("Server shutting down...")
        server.close()
def close_socket():
    server.close()
if __name__ == "__main__":
    atexit.register(close_socket)
    main()


"""
A module for customized PCA class for process monitoring and fault diagnosis.
Monitoring methodology is described in our book  'Machine Learning for Process Systems Engineering' (https://mlforpse.com/books/)
============================================================================
"""

# Version: 2022
# Author: Ankur Kumar @ MLforPSE.com
# License: BSD 3 clause

#%% Imports
from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats

#%% define class
class PDS_PCA(PCA):
    ''' This class wraps Sklearn's PCA class to provide the following additional methods

    1) computeMetrics: computes the monitoring indices for the supplied data
    2) computeThresholds: computes the thresholds / control limits for the monitoring indices from training data
    3) draw_monitoring_charts: Draw the monitoring charts for the training or test data
    4) detect_abnormalities: Detects if the observations are abnormal or normal samples
    5) get_contributions: Returns abnormality contributions for T2 and SPE for an observation vector

    Usage Example
    --------
    >>> from PDS_PCA import PDS_PCA
    >>> from sklearn.preprocessing import StandardScaler

    >>> X = np.random.rand(30,5)
    >>> scaler = StandardScaler()
    >>> X_normal = scaler.fit_transform(X)

    >>> pca = PDS_PCA()
    >>> pca.fit(X_normal, autoFindNLatents=True)
    >>> metrics_train = pca.computeMetrics(X_normal, isTrainingData=True)
    >>> T2_CL, SPE_CL = pca.computeThresholds(method='percentile')
    >>> pca.draw_monitoring_charts(metrics=metrics_train, title='training data')

    >>> X_test = scaler.transform(np.random.rand(30,5))
    >>> abnormalityFlags = pca.detect_abnormalities(X_test, title='Test data')
    '''

    def __init(self, **kws):
        self.eig_vals_all = None
        PCA.__init__(**kws)

    def fit(self, X, autoFindNLatents=False, varianceThreshold=0.9):
        """
        Extends the fit method of Sklearn PCA to allow in-built computation of the 'optimal' number of latents.

        Parameters:
        ---------------------
        X: ndarray of shape (n_samples, n_features)
            Training data, where n_samples is the number of samples and n_features is the number of features.

        autoFindNLatents: bool, optional (default False)
            Bool to indicate whether the number of latents is to be determined by the fit method.
            If True, number of latents that capture atleast varianceThreshold fraction of the total variance is chosen

        varianceThreshold: float, optional (default 0.9)
            Real value between 0 and 1.
            The number of PCs retained is such that fraction of variance captured is atleast varianceThreshold

        Returns
        ---------------------
        self: object
            fitted model
        """

        if autoFindNLatents:
            PCA.fit(self, X)
            self.eig_vals_all = self.explained_variance_ # to be used later for threshold calculations

            # decide # of PCs to retain
            explained_variance = 100*self.explained_variance_ratio_ # in percentage
            cum_explained_variance = np.cumsum(explained_variance) # cumulative % variance explained
            selected_Nlatent = np.argmax(cum_explained_variance >= varianceThreshold*100) + 1

            # print message for selected_Nlatent
            print('# of latents selected: ', selected_Nlatent)

            # plot cumulative % variance curve
            plt.figure()
            plt.plot(range(1,X.shape[1]+1), cum_explained_variance, 'r+', label = 'cumulative % variance explained')
            plt.plot(range(1,X.shape[1]+1), explained_variance, 'b+' , label = '% variance explained by each PC')
            plt.ylabel('Explained variance (in %)'), plt.xlabel('Principal component number')
            plt.title('Variance explained vs # of PCs'), plt.legend()
            plt.show()

            # store the computed optimal_Nlatents
            self.n_components = selected_Nlatent

        # call the original fit method of PCA class
        PCA.fit(self, X)
        if self.n_components == X.shape[1]:
            self.eig_vals_all = self.explained_variance_
        else:
            PCA_temp = PCA().fit(X)
            self.eig_vals_all = PCA_temp.explained_variance_

        return self

    def computeMetrics(self, X, isTrainingData=False):
        """
        computes the monitoring indices for the supplied data

        Parameters:
        ---------------------
        X: ndarray of shape (n_samples, n_features)
            n_samples is the number of samples and n_features is the number of features.

        isTrainingData: bool, optional (default False)
            If True, then the computed metrics are stored as object properties which are utilized during computation of metric thresholds

        Returns:
        ---------------------
        SPE: ndarray of shape (n_samples, )
            Also called Q metrics

        T2: ndarray of shape (n_samples, )
            Also called Hotelling's T-square.
        """

        # compute SPE
        Xscores = self.transform(X)
        X_reconstruct = self.inverse_transform(Xscores)
        X_error = X - X_reconstruct
        SPE = np.sum(X_error*X_error, axis = 1)

        # compute T2
        if isTrainingData:
            T_cov = np.cov(Xscores.T) # equivalent to np.diag(pca.explained_variance_)
            T_cov_inv = np.linalg.inv(T_cov)
            self.T_cov_inv = T_cov_inv

        T2 = np.zeros((X.shape[0],))
        for i in range(X.shape[0]):
            T2[i] = np.dot(np.dot(Xscores[i,:],self.T_cov_inv),Xscores[i,:].T)

        # save metrics for training data as attributes
        if isTrainingData:
            self.T2_train = T2
            self.SPE_train = SPE

        return T2, SPE

    def computeThresholds(self, method='percentile', percentile=99, alpha=0.01):
        """
        computes the thresholds / control limits for the monitoring indices from training data

        Parameters:
        ---------------------
        method: 'percentile' or 'statistical'; default 'percentile'

        percentile: int, optional (default 99)
            The percentile value to use if method='percentile'

        alpha: int, optional (default 99)
            The significance level to use if method='statistical'.
            Default value of 0.01 imples 99% control limit.

        Returns
        ---------------------
        T2_CL: float
            Control limit/threshold for T2 metric

        SPE_CL: float
            Control limit/threshold for SPE metric
        """

        if not hasattr(self, 'T2_train'):
            raise AttributeError('Training metrices not found. Run computeMetrics method before computing the thresholds.')

        if method == 'percentile':
            T2_CL = np.percentile(self.T2_train, percentile)
            SPE_CL = np.percentile(self.SPE_train, percentile)

        elif method == 'statistical':
            # parameters
            N = self.T2_train.shape[0]
            k = self.n_components
            m = len(self.eig_vals_all)

            # T2_CL
            T2_CL = k*(N**2-1)*scipy.stats.f.ppf(1-alpha,k,N-k)/(N*(N-k))

            # SPE_CL
            theta1 = np.sum(self.eig_vals_all[k:])
            theta2 = np.sum([self.eig_vals_all[j]**2 for j in range(k,m)])
            theta3 = np.sum([self.eig_vals_all[j]**3 for j in range(k,m)])
            if theta3 == 0:
                raise ValueError('Division by zero encountered. Statistical threshold computation for SPE_CL is not possible')
            h0 = 1-2*theta1*theta3/(3*theta2**2)
            z_alpha = scipy.stats.norm.ppf(1-alpha)
            SPE_CL = theta1*(z_alpha*np.sqrt(2*theta2*h0**2)/theta1+ 1 + theta2*h0*(1-h0)/theta1**2)**2

        else:
            raise ValueError('Incorrect choice of method parameter')

        # save control limits as attributes
        self.T2_CL = T2_CL
        self.SPE_CL = SPE_CL

        return T2_CL, SPE_CL

    def draw_monitoring_charts(self, metrics=None, title=''):
        """
        Draw the monitoring charts for the training or test data.
        The control limits are plotted as red dashed line.

        Parameters:
        ---------------------
        metrics: list or tuple of monitoring metrics (1D numpy arrays). Should follow the order (T2, SPE)
            If not specified, then the object's stored metrics from training data are used.

        title: str, optional
            Title for the charts
        """

        if metrics is None:
            metrics = (self.T2_train, self.SPE_train)

        # T2
        plt.figure()
        plt.plot(metrics[0], color='k', linestyle = ':', marker='o', markerfacecolor = 'C4')
        if hasattr(self, 'T2_CL'):
            plt.axhline(self.T2_CL, color = "red", linestyle = "-.")
        plt.xlabel('Sample #'), plt.ylabel('T2')
        plt.title(title), plt.show()

        # SPE
        plt.figure()
        plt.plot(metrics[1], color='k', linestyle = ':', marker='o', markerfacecolor = 'C4')
        if hasattr(self, 'SPE_CL'):
            plt.axhline(self.SPE_CL, color = "red", linestyle = "-.")
        plt.xlabel('Sample #'), plt.ylabel('SPE')
        plt.title(title), plt.show()

    def fit_4_monitoring(self, X, autoFindNLatents=False, varianceThreshold=0.9, method='percentile', percentile=99, alpha=0.01):
        """
        A utility method that calls the following model-training related methods in succession.

        fit(X, autoFindNLatents, varianceThreshold)
        computeMetrics(X, isTrainingData=True)
        computeThresholds(method, percentile, alpha)
        draw_monitoring_charts(title='training data')

        Note: Check doc string of individual methods for details on the method parameters.
        """

        self.fit(X, autoFindNLatents, varianceThreshold)
        self.computeMetrics(X, isTrainingData=True)
        self.computeThresholds(method, percentile, alpha)
        self.draw_monitoring_charts(title='training data')

        return self

    def detect_abnormalities(self, X, drawMonitoringChart=True, title=''):
        """
        Detects if the observations are abnormal or normal.
        Detection is based on the logic that for a 'normal' sample, the monitoring metrics should lie below their thresholds.

        Parameters:
        ---------------------
        X: ndarray of shape (n_samples, n_features)
            n_samples is the number of samples and n_features is the number of features.

        drawMonitoringChart: bool, optional (default True)
            If True, then the monitoring charts are also drawn.

        title: str, optional
            Title for the charts

        Returns:
        ---------------------
        abnormalityFlags: ndarray of shape (n_samples,)
            Returns True for abnormal samples and False for normal samples
        """

        T2, SPE = self.computeMetrics(X)
        abnormalityFlags = np.logical_or(T2 > self.T2_CL, SPE > self.SPE_CL)
        print('Number of abnormal sample(s): ', np.sum(abnormalityFlags))

        if drawMonitoringChart:
            self.draw_monitoring_charts(metrics=(T2, SPE), title=title)

        return abnormalityFlags

    def get_contributions(self, x, plotContributions=True, title=''):
        """
        Returns abnormality contributions for T2 and SPE metrics for an observation vector.

        Parameters:
        ---------------------
        x: ndarray of shape (n_features,)
            Observation sample where n_features is the number of features

        Returns:
        ---------------------
        T2_contributions: ndarray of shape (n_features,)
            Contains contribution made to the T2 metric from each feature

        SPE_contributions: ndarray of shape (n_features,)
            Contains contribution made to the SPE metric from each feature
        """

        # check consistency of x
        if x.ndim != 1:
            raise ValueError('get_contributions method expects a 1D observation sample')

        # T2 contribution
        P_matrix = self.components_.T
        D = np.dot(np.dot(P_matrix,self.T_cov_inv),P_matrix.T)
        D_sqrt = scipy.linalg.sqrtm(D).real
        T2_contri = np.dot(D_sqrt, x)**2

        # SPE contribution
        x = x[None,:] # convert 1D array to 2D
        x_reconstruct = self.inverse_transform(self.transform(x))
        x_error = x - x_reconstruct
        SPE_contri = (x_error*x_error)[0,:]

        # plots
        if plotContributions:
            plt.figure()
            plt.plot(range(1,len(T2_contri)+1), T2_contri, color='k', linestyle = ':', marker='o', markerfacecolor = 'C4')
            plt.xlabel('Variable #'), plt.ylabel('T$^2$ contribution plot')
            plt.grid(), plt.show()

            plt.figure()
            plt.plot(range(1,len(SPE_contri)+1), SPE_contri, color='k', linestyle = ':', marker='o', markerfacecolor = 'C4')
            plt.xlabel('Variable #'), plt.ylabel('SPE contribution plot')
            plt.grid(), plt.show()

        return T2_contri, SPE_contri


import re
import os
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--input", type = str)
parser.add_argument("--output", type = str)
parse = parser.parse_args()

def hasNumbers(inputString):
    return any(char.isdigit() for char in inputString)

def find_age(ss):
    exp1 = r'(\d+|\w{1,3})?周*岁'
    exp2 = r'年龄*(\w{1,3})'
    res1 = re.findall(exp1, ss)
    res2 = re.findall(exp2, ss)
    # print("res1: ",res1)
    # print("res2: ", res2)
    ans = []
    if len(res1) > 0:
        for i in res1:
            if hasNumbers(i):
                if len(re.findall('\d+',i)) != 0:
                    ans.append(re.findall('\d+',i)[0])
            else:
                if len(re.findall('[零一两二三四五六七八九十百]', i)) != 0:
                    ans.append(i)

    elif len(res2) > 0:
        for i in res2:
            if len(re.findall('\d', i)) != 0:
                f = 1
                for c in i:
                    if c not in "0123456789":
                        f = 0
                        break
                if f:
                    ans.append(i)
            elif len(re.findall('[零一两二三四五六七八九十百]', i)) != 0:
                ans.append(i)
    else: # 婴儿案例
        if ss.find("个月") != -1 and (ss.find("宝宝") != -1 or ss.find("婴儿") != -1):
            idx = ss.find("个月")
            tmp = ss[max(0,idx - 3): idx]
            f = 0
            for i, c  in enumerate(tmp[::-1]):
                if c not in "0123456789零一两二三四五六七八九十百":
                    break
                if c in "0123456789零一两二三四五六七八九十百":
                    f = 1
            if f == 1:
                ans.append(tmp[-i:])

    return ans

def convert2han(ss):
    mapping = {"0": "零", "1": "一", "2": "二", "3": "三", "4": "四", "5": "五", "6": "六", "7": "七", "8": "八", "9": "九"}
    n = len(ss)
    ans = ""
    if n == 1:
        ans = mapping[ss[0]]
    elif n == 2:
        ans += mapping[ss[0]] + "十"
        if ss[1] != "0":
            ans += mapping[ss[1]]
    else:
        ans += mapping[ss[0]] + "百"
        if ss[1] != "0":
            ans += mapping[ss[1]] + "十"
            if ss[2] != "0":
                ans += mapping[ss[2]]
        else:
            if ss[2] != "0":
                ans += "零" + mapping[ss[2]]

    return ans

def convert2num(ss):
    mapping = {
        "零":0,
        "一":1,
        "二":2,
        "三":3,
        "四":4,
        "五":5,
        "六":6,
        "七":7,
        "八":8,
        "九":9,
        "十":10,
        # "百":100,
    }
    if len(ss) == 1:
        return mapping[ss]
    elif len(ss) == 2:
        if ss[0] == "十": # 十二
            return 10 + mapping[ss[1]]
        elif ss[1] == "十": # 二十
            return 10 * mapping[ss[1]]
        elif ss[1] == "百": # 一百
            return 100 * mapping[ss[0]]
        else: # 一二，不正常的表达
            return mapping[ss[0]] * 10 + mapping[ss[1]]
    elif len(ss) == 3:
        if ss[1] == "十":# 一十五，二十六
            return mapping[ss[0]] * 10 + mapping[ss[-1]]
        elif ss[1] == "百": # 一百二
            return mapping[ss[0]] * 100 + mapping[ss[-1]] * 10
        else: # 一二三, 不正常的表达
            try:
                mapping[ss[0]] * 100 + mapping[ss[1]] * 10 + mapping[ss[2]]
            except:
                # print(ss)
                pass
    else: # len(ss) = 4 or len(ss) = 5
        bai = mapping[ss[:2][0]] * 100
        rest = ss[2:]
        num = bai
        if rest[0] == "零":
            num += mapping[rest[-1]]
        else:
            num += mapping[rest[0]] * 10
            if rest[-1] != "十":
                num += mapping[rest[-1]]
        return num

def write_file(sent, age = None, start = None, end = None, fo = None):
    if age is not None:
        entity = "]{Age}"
        sent = sent[:end] + entity + sent[end:]
        sent = sent[:start] + "[" + sent[start:]
    if fo is not None:
        fo.write(sent + "\n")
    else:
        print(sent)

def predict(sents, interactive = False):
    assert isinstance(sents, list)
    if interactive is False:
        fo = open(parse.output, "w", encoding = "utf-8")
    for s in sents:
        age = find_age(s)
        if len(age) == 0: # 样例中没有年龄实体
            if interactive is False:
                write_file(s, age = None, fo = fo)
            else:
                write_file(s, age = None, fo = None)
        else: # 样例中出现年龄
            age = age[0]
            begin = s.find(age)
            end = len(age)
            if hasNumbers(age):# 年龄以数字的形式出现
                age_d = age
                # print(age_d, s)
                start = 0
                while not age_d[start].isdigit():
                    start += 1
                end = len(age_d)
                while not age_d[end - 1].isdigit():
                    end -= 1
                new_age = age_d[start:end]
                end = len(new_age)
                # new_age = convert2han(age_d)
                # s = s.replace(age_d, new_age)
                # end = len(new_age)

            else: # 年龄以汉字的形式出现
                age_d = age

                start = 0

                while  age_d[start] not in "零一两二三四五六七八九十百":

                    start += 1
                end = len(age_d)
                while  age_d[end - 1] not in "零一两二三四五六七八九十百" :
                    end -= 1
                age = age_d[start:end]
                new_age = age.replace("两", "二")
                new_age = convert2num(new_age)
                new_age = str(new_age)
                s = s.replace(age, new_age)
                end = len(new_age)
            # s = s.replace(age, new_age)

            if new_age + "个月" in s: # 处理不满一岁或者一岁左右婴儿的情况,全部将婴儿换成1岁
                s = s.replace(new_age, "1")
                new_age = "1"
                s = s.replace("个月", "岁")

            begin = s.find(new_age)
            end = len(new_age)

            if interactive is False:
                write_file(s, new_age, begin, end + begin, fo)
            else:
                write_file(s, new_age, begin, begin + end, None)

    if interactive is False:
        fo.close()

if __name__ == "__main__":
    sents = []
    if parse.input is not None and parse.output is not None:
        with open(parse.input, "r", encoding = "utf-8") as f:
            for line in f:
                sents.append(line.strip())

        predict(sents, False)
    else:
        while True:
            print("Please input one sentence:")
            sent = input()
            if sent == "":
                break
            predict([sent], True)


# _*_ coding: utf-8 _*_
__author__ = 'wenliang'
__date__ = '2019/4/10 16:08'
import xadmin

from .models import UserAsk, EquipmentComments, UserFavorite, UserMessage, UserEquipment

class UserAskAdmin(object):
    list_display = ['name', 'mobile', 'equipment_name', 'add_time']
    search_fields = ['name', 'mobile', 'equipment_name']
    list_filter = list_display

class EquipmentCommentsAdmin(object):
    list_display = ['user', 'equipment', 'comments', 'add_time']
    search_fields = ['user', 'equipment', 'comments']
    list_filter = list_display

class UserFavoriteAdmin(object):
    list_display = ['user', 'fav_id', 'fav_type', 'add_time']
    search_fields = ['user', 'fav_id', 'fav_type']
    list_filter = list_display

class UserMessageAdmin(object):
    list_display = ['user', 'message', 'has_read', 'add_time']
    search_fields = ['user', 'message', 'has_read']
    list_filter = list_display

class UserEquipmentAdmin(object):
    list_display = ['user', 'equipment', 'add_time']
    search_fields = ['user', 'equipment']
    list_filter = list_display

xadmin.site.register(UserAsk, UserAskAdmin)
xadmin.site.register(EquipmentComments, EquipmentCommentsAdmin)
xadmin.site.register(UserFavorite, UserFavoriteAdmin)
xadmin.site.register(UserMessage, UserMessageAdmin)
xadmin.site.register(UserEquipment, UserEquipmentAdmin)


import json
import jsonschema
import random
from schema import schema
from multiprocessing import Process, Pipe
import pandas as pd
from pprint import pprint

def load_input(inp: str) -> dict:
    """The "setup" step for reading and validating input data.
    Input should be provided as JSON string following schema in schema.py

    Args:
        inp (str): JSON data

    Returns:
        dict: Parsed input data
    """
    print("Loading JSON data...")
    data = json.loads(inp)
    validate_input(data)
    print("Input is valid")
    return data

def validate_input(inp: dict) -> None:
    """Validates

    Args:
        inp (dict): JSON converted to dict

    Raises:
        e: raised if input is not matching the schema
    """
    try:
        jsonschema.validate(inp, schema=schema)
    except jsonschema.exceptions.ValidationError as e:
        raise e

def generate_rng_results(data: dict) -> list[dict]:
    """The "map" step, takes the input provided and returns generated results

    Args:
        data (dict): Input data, contains seed for random generator (random_seed),
            number of workers which should perform the task (n_workers), and number of samples
            to collect (n_sims).

    Returns:
        list[dict]: A list of two generated results, first: for each worker separately,
            second: for all workers cumulatively.
    """
    print("Assigning tasks to workers...")
    workers_occupancy = get_evenly_split_workers(data["n_sims"], data["n_workers"])
    results_workers, results_total = run_workers(workers_occupancy, data["random_seed"])
    print("Mapping finished")
    return [results_workers, results_total]

def rand_num_generator(seed: float):
    """Random number generator

    Args:
        seed (float): seed used by generator

    Yields:
        Iterator[float]: randomly generated number, from 0 to 1
    """
    random.seed(seed)
    while True:
        yield random.random()

def run_generator(connection, seed: float, n_sims: int):
    """Performs the simulation for a single worker and sends the results to the adult node

    Args:
        connection: Child of pipe connection for the computation process
        seed (float): seed used by generator
        n_sims (int): number of samples to collect
    """
    gen = rand_num_generator(seed)

    connection.send(pd.Series([next(gen) for _ in range(n_sims)]))
    connection.close()

def get_evenly_split_workers(n_sims: int, n_workers: int) -> list[int]:
    """
    Checks if n_sims is divisible by n_workers. If n_sims % n_workers == 0,
    then each worker can handle the same amount of simulations. If not,
    number of simulations is assigned to workers for the least difference between them.

    Example: n_sims = 11, n_workers = 3
    amount_1 = n_sims//n_workers = 3
    amount_2 = n_sims//n_workers + 1 = 4
    n_sims % n_workers == 2, which is the number of workers with amount_1
    the rest of the list is filled with amount_2
    therefore the resulting split is [4, 4, 3]

    Args:
        n_sims (int): total number of samples to collect
        n_workers (int): total number of workers

    Returns:
        list[int]: amount of samples to collect by each worker
    """
    if n_sims % n_workers == 0:
        worker_sims = [n_sims//n_workers for _ in range(n_workers)]
    else:
        worker_sims = []
        remainder = n_sims % n_workers
        for _ in range(remainder):
            worker_sims.append(n_sims//n_workers + 1)
        for _ in range(n_workers - remainder):
            worker_sims.append(n_sims//n_workers)
    return worker_sims

def run_workers(workers: list[int], seed: float) -> [pd.DataFrame, pd.DataFrame]:
    """Main process for running the computation. Creates separate processes for every worker.
    Every worker uses different seed, but for the same seed in input the results are deterministic.

    Args:
        workers (list[int]): amount of samples to collect by each worker
        seed (float): seed used by generators

    Returns:
        [pd.DataFrame, pd.DataFrame]: A list of two dataframes,
            first: all workers' results split into separate columns named worker_{i},
            second: all workers' results in a single column "Total".
    """
    processes = []
    parent_connections = []
    results, results_collective = pd.DataFrame(), pd.DataFrame()
    for i, worker in enumerate(workers):
        parent_conn, child_conn = Pipe()
        parent_connections.append(parent_conn)

        # increment the seed for each worker by 1, so the results are
        # deterministic, but each worker uses different seed to get different numbers
        process = Process(target=run_generator, args=(child_conn, seed+i, worker))
        processes.append(process)
    # starting, collecting and terminating processes
    for process in processes:
        process.start()
    for i, par_conn in enumerate(parent_connections):
        worker_res = par_conn.recv()
        results[f"worker_{i}"] = worker_res
        results_collective = pd.concat([results_collective, worker_res])
    for process in processes:
        process.join()

    results_collective.columns = ["Total"]

    return results, results_collective

def parse_results(data: dict, results: pd.DataFrame, results_collective: pd.DataFrame) -> str:
    """Save the results of computation into JSON summary in total and for each worker.

    Args:
        data (dict): input data, containing title of the summary and optional threshold field
        results (pd.DataFrame): all workers' results split into separate columns named worker_{i}
        results_collective (pd.DataFrame): all workers' results in a single column "Total"

    Returns:
        str: summary of calculations in JSON
    """
    summary = {"title": data["title"], "statistics": {}}
    stats = summary["statistics"]
    for res in results.columns:
        current_col = res
        stats[current_col] = reduce_col(results, current_col, data.get("threshold", 0))

    stats["Total"] = reduce_col(results_collective, "Total", data.get("threshold", 0))

    return json.dumps(summary)

def reduce_col(df: pd.DataFrame, colname: str, threshold: float) -> dict:
    """Generate statistics for calculations' results

    Args:
        df (pd.DataFrame): dataframe of calculations' results
        colname (str): name of the column to generate statistics for,
            either "worker_{i}" or "Total"
        threshold (float, optional): a limit for counting computed values
            greater or equal to threshold.
    Returns:
        dict: statistics for given column in dataframe
    """
    stats = {}
    stats["numof_samples"] = int(df[colname].count())
    stats["numof_samples_thresh"] = int(df[df[colname]>=threshold][colname].count())
    stats["max_result"] = float(df[colname].max())
    stats["min_result"] = float(df[colname].min())
    stats["median"] = float(df[colname].median())
    stats["count_distinct"] = int(df[colname].nunique())
    stats["sum"] = float(df[colname].sum())

    return stats

def full_computation(inp: str) -> dict:
    """Performs full computation in three steps:
    1. Setup - read input data, preparation.
    2. Map - generate random numbers.
    3. Reduce - provide summary statistics.

    Args:
        inp (str): JSON data

    Returns:
        dict: summar of calulations in JSON
    """
    inp_data = load_input(inp)
    results = generate_rng_results(inp_data)
    # results[0] - results per worker
    # results[1] - results collective
    return parse_results(inp_data, results[0], results[1])


import torch.nn as nn
from torchvision.models import densenet169
import numpy as np

def get_classify_model():
    model = densenet169(pretrained=True)
    for param in model.parameters():
        param.requires_grad = True
    in_feature = model.classifier.in_features
    model.classifier = nn.Sequential(nn.Linear(in_feature, 1, bias=True), nn.Sigmoid())

    return model


# reading a given sample Java class
# classread-constant-pool.py

import struct
import getopt
import sys

# see the specification at e.g.
# https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html

class Header():
    def __init__(self, magic, minor, major):
        self.magic = magic
        self.minor = minor
        self.major = major
    def __str__(self) -> str:
        return f"version: {self.major}.{self.minor}"

# CAFEBABE and version
def parse_header(cf):
    header = []
    magic = struct.unpack('!I', cf.read(4))
    minor, major = struct.unpack('!HH', cf.read(4))
    header.append(Header(magic, minor, major))
    return header

# cp_info {
#    u1 tag;
#    u1 info[];
# }
class ConstantPool():
    def __init__(self, tag, value):
        self.tag = tag
        self.value = value
    def __str__(self) -> str:
        return f"{self.tag:>2}: {self.value}"

def parse_constant_pool(f):
    constant_pool = []
    constant_pool_count = struct.unpack("!H", f.read(2))[0]

    for i in range(1, constant_pool_count):
        # read a tag
        tag = struct.unpack("!B", f.read(1))[0]

        # CONSTANT_Utf8_info {
        #    u1 tag;
        #    u2 length;
        #    u1 bytes[length];
        # }
        if tag == 1:
            length = struct.unpack("!H", f.read(2))[0]
            value = struct.unpack('!{}s'.format(length), f.read(length))[0].decode('utf-8')
            constant_pool.append(ConstantPool(tag, value))

        # CONSTANT_Integer_info {
        #    u1 tag;
        #    u4 bytes;
        # }
        elif tag == 3:
            value = struct.unpack("!i", f.read(4))[0]
            constant_pool.append(ConstantPool(tag, value))

        # CONSTANT_Float_info {
        #    u1 tag;
        #    u4 bytes;
        # }
        elif tag == 4:
            value = struct.unpack("!f", f.read(4))[0]
            constant_pool.append(ConstantPool(tag, value))

        # CONSTANT_Long_info {
        #    u1 tag;
        #    u4 high_bytes;
        #    u4 low_bytes;
        # }
        elif tag == 5:
            value = struct.unpack("!q", f.read(8))[0]
            constant_pool.append(ConstantPool(tag, value))
            i += 1  # skip as "long" extend over 2 tags

        # CONSTANT_Double_info {
        #    u1 tag;
        #    u4 high_bytes;
        #    u4 low_bytes;
        # }
        elif tag == 6:
            value = struct.unpack("!d", f.read(8))[0]
            constant_pool.append(ConstantPool(tag, value))
            i += 1  # skip as "double" extend over 2 tags

        # Class
        #   u1 tag;
        #   u2 index;
        elif tag == 7:  # Class
            index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, index))

        # CONSTANT_String_info {
        #    u1 tag;
        #    u2 string_index;
        # }
        elif tag == 8:
            index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, index))

        # CONSTANT_Fieldref_info {
        #    u1 tag;
        #    u2 class_index;
        #    u2 name_and_type_index;
        # }
        elif tag == 9:
            class_index = struct.unpack("!H", f.read(2))[0]
            name_and_type_index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, (class_index, name_and_type_index)))

        # CONSTANT_Methodref_info {
        #    u1 tag;
        #    u2 class_index;
        #    u2 name_and_type_index;
        # }
        elif tag == 10:
            class_index = struct.unpack("!H", f.read(2))[0]
            name_and_type_index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, (class_index, name_and_type_index)))

        # CONSTANT_InterfaceMethodref_info {
        #    u1 tag;
        #    u2 class_index;
        #    u2 name_and_type_index;
        # }
        elif tag == 11:
            class_index = struct.unpack("!H", f.read(2))[0]
            name_and_type_index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, (class_index, name_and_type_index)))

        # CONSTANT_NameAndType_info {
        #    u1 tag;
        #    u2 name_index;
        #    u2 descriptor_index;
        # }
        elif tag == 12:
            name_index = struct.unpack("!H", f.read(2))[0]
            descriptor_index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, (name_index, descriptor_index)))

        # CONSTANT_MethodHandle_info {
        #    u1 tag;
        #    u1 reference_kind;
        #    u2 reference_index;
        # }
        elif tag == 15:
            reference_kind = struct.unpack("!B", f.read(1))[0]
            reference_index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, (reference_kind, reference_index)))

        # CONSTANT_MethodType_info {
        #    u1 tag;
        #    u2 descriptor_index;
        # }
        elif tag == 16:
            descriptor_index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, descriptor_index))

        # CONSTANT_InvokeDynamic_info {
        #    u1 tag;
        #    u2 bootstrap_method_attr_index;
        #    u2 name_and_type_index;
        # }
        elif tag == 18:
            bootstrap_method_attr_index = struct.unpack("!H", f.read(2))[0]
            name_and_type_index = struct.unpack("!H", f.read(2))[0]
            constant_pool.append(ConstantPool(tag, (bootstrap_method_attr_index, name_and_type_index)))

    return constant_pool

#
def readclass(inputfile, verbose):

    with open(inputfile, "rb") as cf:

        # partial impl. marked by <--
        # ClassFile {
        #    u4             magic;                                  <--
        #    u2             minor_version;                          <--
        #    u2             major_version;                          <--
        #    u2             constant_pool_count;                    <--
        #    cp_info        constant_pool[constant_pool_count-1];   <--
        #    u2             access_flags;
        #    u2             this_class;
        #    u2             super_class;
        #    u2             interfaces_count;
        #    u2             interfaces[interfaces_count];
        #    u2             fields_count;
        #    field_info     fields[fields_count];
        #    u2             methods_count;
        #    method_info    methods[methods_count];
        #    u2             attributes_count;
        #    attribute_info attributes[attributes_count];
        # }

        h = parse_header(cf)
        cp = parse_constant_pool(cf)
        cf.close()

        if verbose == 1:
            for i, v1 in enumerate(h):
                print(f"{v1}")
            for i, v2 in enumerate(cp):
                print(f"#{i+1:0>{2}} {v2}")

#
def main(argv):
    inputfile = ''
    verbose = 0

    try:
        opts, args = getopt.getopt(argv,"vhi:",["ifile="])
    except getopt.GetoptError:
        print('classread-constant-pool.py -i <inputfile>')
        sys.exit(2)

    for opt, arg in opts:
        if opt == '-v':
            verbose = 1
        if opt == '-h':
            print('usage: classread-constant-pool.py -i <inputfile>')
            sys.exit()
        elif opt in ("-i", "--ifile"):
            inputfile = arg

    if verbose == 1:
        print("reading ..")
    readclass(inputfile, verbose)
    if verbose == 1:
        print("done.")

if __name__ == "__main__":
   main(sys.argv[1:])


#!/usr/bin/python3

"""
File: stateyasper.py
Description: Allows a statemachine to be converted to the visual representation.
             Implementation does not do any formatting of states.

Usage: Import "stateyasper.generate_yasper" and call the function with a statemachine object.
       Output is printed directly so output should be piped to a file.

"""

import generator
import sys

defaultS = " <place id='s{}'>\n       <name><text>{}</text> </name> <graphics>\n        <position x='{}' y='{}' />\n        <dimension x='20' y='20' />\n      </graphics>\n        </place>"

defaultT = "<transition id='s{}'> \n <graphics>\n <position x='330' y='{}' />\n <dimension x='32' y='32' />\n </graphics>\n </transition>"

def generate_yasper(statemachine):
    stateString  = "<?xml version='1.0' encoding='utf-8'?>\n"
    stateString +=  "<pnml>\n"
    stateString += "\t<net type='http://www.yasper.org/specs/epnml-1.1' id='do1'>\n"
    stateString += "\t<toolspecific tool='Yasper' version='1.2.4020.34351'>\n"
    stateString += "\t\t<roles xmlns='http://www.yasper.org/specs/epnml-1.1/toolspec' />\n"
    stateString += "\t</toolspecific>\n"

    transit, arcs = generate_transitions(statemachine.transitions)
    stateString += transit
    stateString += generate_places(statemachine.states)
    stateString += arcs

    return stateString + "\t</net> \n</pnml>"

def generate_places(states):
    x = 330
    y = 50
    output = ""

    for state in states:
        stateString = defaultS
        y += 100
        output += (stateString.format(state.name,state.name,x,y))
    return output

def generate_transitions(transitions):
    x = 330
    y = 70
    transitionNumber = 0
    output = ""
    arcs = ""

    for transition in transitions:
        y += 100
        transitionNumber += 1

        transitionString = defaultT
        stateInputString = defaultS

        # transitionName = "transition{}".format(transitionNumber)
        transitionName = "transition{}".format(transitionNumber)

        inputName = "{}{}".format("in" if transition.input else "out",transitionNumber)

        # This is the input
        output += stateInputString.format(inputName,inputName,x + 60,y)
        # trhis is the transiiton
        output += transitionString.format(transitionName,y)

        arcs += "<arc id='a{}' source='s{}' target='s{}' />\n".format("{}0".format(transitionNumber),transition.start.name,transitionName)
        arcs += "<arc id='a{}' source='s{}' target='s{}' />\n".format("{}5".format(transitionNumber),transitionName,transition.end.name)

        if transition.input:
            arcs += "<arc id='a{}' source='s{}' target='s{}' />\n".format("{}1".format(transitionNumber),inputName,transitionName)
        else:
            arcs += "<arc id='a{}' source='s{}' target='s{}' />\n".format("{}1".format(transitionNumber),transitionName,inputName)

    return output,arcs


#CLIENT CODE
#import socket library
import socket
#import subprocess library
import subprocess
#create an INET, STREAMing socket
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#reserve a port in your computer
clientsocket.connect(('localhost', 8000))
while True:
    test = subprocess.Popen(["netstat","-np","TCP"],stdout=subprocess.PIPE)
    output = test.communicate()[0]
    if (output.find(":22") >= 1):
        clientsocket.send('Somebody attempted to do SSH')
    else:
        clientsocket.send("SSH login not found")


# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def partition(self, head, x):
        """
        :type head: ListNode
        :type x: int
        :rtype: ListNode
        """
        smallS = smallE = bigS = bigE = None

        if (not head) : return head

        while (head):
            if (head.val >= x ):
                if (not bigS) :
                    bigS = bigE = head
                else:
                    bigE.next = head
                    bigE = head
            else:
                if (not smallS):
                    smallS = smallE = head
                else:
                    smallE.next = head
                    smallE = head

            head = head.next
        if (bigE): bigE.next = None

        if (smallE): smallE.next = bigS
        if (bigE): bigE.next = None

        if (smallS): return smallS
        if (bigS): return bigS


from django.shortcuts import render, redirect
from django.contrib import messages
import json
from . import stats

regions = ['BR', 'EUNE', 'EUW', 'JP', 'KR', 'LAN', 'LAS', 'NA', 'OCE', 'TR', 'RU']

def main(request):
    return render(request, 'lolstats/main.html', {})

def multisearch(request):
    if request.method == "POST":
        try:
            player_data = stats.multisearch(request)
        except stats.UnableToGetPlayerStats as e:
            messages.error(request, f"ERROR: {e}")
            return redirect('main')
        else:
            return render(request, 'lolstats/multisearched.html', {'player_data':player_data})
    else:
        return render(request, 'lolstats/multisearch.html', {})

def player(request):

    # Get user input and direct to player stats page
    player_name = request.GET.get('player_name')
    region = request.GET.get('region')

    # Ensure region and summoner name are valid
    if region not in regions:
        messages.error(request, "ERROR: Invalid Region")
        return redirect('main')
    if not player_name:
        messages.error(request, "ERROR: Must enter summoner")
        return redirect('main')

    return redirect('player_stats', region, player_name)

def player_stats(request, region: str, player_name: str):
    try:
        player_data = stats.player_data(request, region, player_name)
        player_stats = stats.player_stats(player_data['data'])
    except stats.UnableToGetPlayerStats as e:
        messages.error(request, f"ERROR: {e}")
        return redirect('main')

    # Item data needed for JS
    with open('lolstats/static/json/items_dd_alt.json', 'r', encoding='utf-8') as file:
        item_dd = json.load(file)

    return render(request, 'lolstats/player_stats.html', {'player_stats':player_stats, 'player_data':player_data, 'region':region, 'item_dd':item_dd})

def player_live(request, region: str, player_name: str):
    try:
        player_data = stats.player_live(request, region, player_name)
    except stats.UnableToGetPlayerStats as e:
        messages.error(request, f"ERROR: {e}")
        return redirect('main')
    else:
        return render(request, 'lolstats/player_live.html', {'player_data':player_data, 'region':region, 'player_name':player_name})

def view_404(request, exception=None):
    messages.error(request, "ERROR: 404 Not found")
    return redirect('main')

def view_500(request, exception=None):
    messages.error(request, "ERROR: 500 Server issue")
    return redirect('main')


import csv
from scipy.spatial import KDTree
from numpy import array, hstack
from coord import Coord
from collections import OrderedDict, defaultdict
import re

class StopList(object):
    def __init__(self):
        self.stops = OrderedDict()
        self.tree = None
        self.lines = OrderedDict()

    def getTree(self):
        if(self.tree is None):
            points = [array(s.point(), float) for s in self.stops.values()]
            self.tree = KDTree(array(points, float))
        return self.tree

    def findNearest(self, point):
        if(isinstance(point, Coord)):
            point = [point.lat, point.lon]

        nearestIdx = self.getTree().query(array(point, float))
        nearestStop = list(self.stops.values())[nearestIdx[1]]
        return nearestStop

    def addStop(self, row):
        newStop = Stop(self, row)
        self.stops[row['stop_id']] = newStop
        self.tree = None

    def addLine(self, row):
        newLine = Line(self, row)
        self.lines[row['route_id']] = newLine

    def loadCSV(self, csvpath):
        with open(csvpath) as csvfile:
            reader = csv.reader(csvfile)
            header = next(reader)
            for row in reader:
                self.addStop(dict(zip(header, row)))

    def loadLines(self, csvpath):
        with open(csvpath) as csvfile:
            reader = csv.reader(csvfile, delimiter='|')
            for (stop_id, lines) in reader:
                if stop_id in self.stops:
                    self.stops[stop_id].setLines(lines)

    def loadLineInfo(self, csvpath):
        with open(csvpath) as csvfile:
            reader = csv.reader(csvfile)
            header = next(reader)
            for row in reader:
                self.addLine(dict(zip(header, row)))

    def __getitem__(self, key):
        return self.stops[key]

    def getLine(self, id):
        return self.lines[id]

class Line(object):
    suffixes = defaultdict(lambda: None,
        MAX = 'Line'
    )
    def __init__(self, parent, csvrow):
        self.parent = parent

        for colname, val in csvrow.items():
            colname = colname.replace('route_','')
            setattr(self, colname, val)

    def getFriendlyName(self):
        return self.short_name if self.short_name else self.long_name

    def getAbbreviated(self):
        if(self.short_name):
            return (None, self.short_name)

        max = re.match(r'MAX (.*) Line', self.long_name)
        if(max):
            return ('MAX', max.group(1))

        psc = re.match(r'Portland Streetcar - (.*?)( Line)?$', self.long_name)
        if(psc):
            return ('Portland Streetcar', psc.group(1))

        return (self.long_name, None)

class Stop(object):
    def __init__(self, parent, csvrow):
        self.parent = parent

        for colname, val in csvrow.items():
            colname = colname.replace('stop_','')
            setattr(self, colname, val)

        self.lines = set()

    def getLatLon(self):
        return Coord(self.lat, self.lon)

    def point(self):
        return (self.lat, self.lon)

    def setLines(self, lines):
        self.lines.update(lines.split(','))

    def getServedBy(self):
        order = []
        groups = defaultdict(list)
        for line_id in sorted(self.lines, key=lambda s: int(s)):
            line = self.parent.getLine(line_id)
            (group, short) = line.getAbbreviated()
            groups[group].append(short)
            if(group not in order):
                order.append(group)

        parts = []
        for group in order:
            lines = groups[group]

            if(group is None):
                parts.append(('line ' if len(lines) == 1 else 'lines ') + ', '.join(lines))
            elif(len(lines) == 1 and lines[0] is None):
                parts.append(group)
            else:
                parts.append(group + ' ' + self.joinWithAnd(lines, Line.suffixes[group]))

        dirmatch = re.match('\w+bound', self.desc)
        direction = (dirmatch.group().lower() + ' ') if dirmatch else ''

        return ''.join([direction, self.joinWithAnd(parts)])

    def joinWithAnd(self, parts, suffix = None, suffix_s = None):
        if suffix is None:
            suffix = suffix_s = ''
        else:
            suffix = ' ' + suffix
            suffix_s = suffix + 's'

        if(len(parts) == 0):
            return ''
        if(len(parts) == 1):
            return parts[0] + suffix
        elif(len(parts) == 2):
            return ' and '.join(parts) + ' ' + suffix_s
        else:
            return ', '.join(parts[0:-1]) + ', and ' + parts[-1] + ' ' + suffix_s