import asyncio

import pytest

from nautilus_trader.adapters.binance.common.enums import BinanceAccountType
from nautilus_trader.adapters.binance.config import BinanceDataClientConfig
from nautilus_trader.adapters.binance.config import BinanceExecClientConfig
from nautilus_trader.adapters.binance.factories import BinanceLiveDataClientFactory
from nautilus_trader.adapters.binance.factories import BinanceLiveExecClientFactory
from nautilus_trader.adapters.binance.factories import _get_http_base_url
from nautilus_trader.adapters.binance.factories import _get_ws_base_url
from nautilus_trader.adapters.binance.futures.data import BinanceFuturesDataClient
from nautilus_trader.adapters.binance.futures.execution import BinanceFuturesExecutionClient
from nautilus_trader.adapters.binance.spot.data import BinanceSpotDataClient
from nautilus_trader.adapters.binance.spot.execution import BinanceSpotExecutionClient
from nautilus_trader.cache.cache import Cache
from nautilus_trader.common.clock import LiveClock
from nautilus_trader.common.enums import LogLevel
from nautilus_trader.common.logging import Logger
from nautilus_trader.msgbus.bus import MessageBus
from nautilus_trader.test_kit.mocks.cache_database import MockCacheDatabase
from nautilus_trader.test_kit.stubs.identifiers import TestIdStubs

class TestBinanceFactories:
    def setup(self):
        # Fixture Setup
        self.loop = asyncio.get_event_loop()
        self.clock = LiveClock()
        self.logger = Logger(
            clock=self.clock,
            level_stdout=LogLevel.DEBUG,
            bypass=True,
        )

        self.trader_id = TestIdStubs.trader_id()
        self.strategy_id = TestIdStubs.strategy_id()
        self.account_id = TestIdStubs.account_id()

        self.msgbus = MessageBus(
            trader_id=self.trader_id,
            clock=self.clock,
            logger=self.logger,
        )

        self.cache_db = MockCacheDatabase(
            logger=self.logger,
        )

        self.cache = Cache(
            database=self.cache_db,
            logger=self.logger,
        )

    @pytest.mark.parametrize(
        ("account_type", "is_testnet", "is_us", "expected"),
        [
            [
                BinanceAccountType.SPOT,
                False,
                False,
                "https://api.binance.com",
            ],
            [
                BinanceAccountType.MARGIN,
                False,
                False,
                "https://sapi.binance.com",
            ],
            [
                BinanceAccountType.ISOLATED_MARGIN,
                False,
                False,
                "https://sapi.binance.com",
            ],
            [
                BinanceAccountType.USDT_FUTURE,
                False,
                False,
                "https://fapi.binance.com",
            ],
            [
                BinanceAccountType.COIN_FUTURE,
                False,
                False,
                "https://dapi.binance.com",
            ],
            [
                BinanceAccountType.SPOT,
                False,
                True,
                "https://api.binance.us",
            ],
            [
                BinanceAccountType.MARGIN,
                False,
                True,
                "https://sapi.binance.us",
            ],
            [
                BinanceAccountType.ISOLATED_MARGIN,
                False,
                True,
                "https://sapi.binance.us",
            ],
            [
                BinanceAccountType.USDT_FUTURE,
                False,
                True,
                "https://fapi.binance.us",
            ],
            [
                BinanceAccountType.COIN_FUTURE,
                False,
                True,
                "https://dapi.binance.us",
            ],
            [
                BinanceAccountType.SPOT,
                True,
                False,
                "https://testnet.binance.vision",
            ],
            [
                BinanceAccountType.MARGIN,
                True,
                False,
                "https://testnet.binance.vision",
            ],
            [
                BinanceAccountType.ISOLATED_MARGIN,
                True,
                False,
                "https://testnet.binance.vision",
            ],
            [
                BinanceAccountType.USDT_FUTURE,
                True,
                False,
                "https://testnet.binancefuture.com",
            ],
        ],
    )
    def test_get_http_base_url(self, account_type, is_testnet, is_us, expected):
        # Arrange, Act
        base_url = _get_http_base_url(account_type, is_testnet, is_us)

        # Assert
        assert base_url == expected

    @pytest.mark.parametrize(
        ("account_type", "is_testnet", "is_us", "expected"),
        [
            [
                BinanceAccountType.SPOT,
                False,
                False,
                "wss://stream.binance.com:9443",
            ],
            [
                BinanceAccountType.MARGIN,
                False,
                False,
                "wss://stream.binance.com:9443",
            ],
            [
                BinanceAccountType.ISOLATED_MARGIN,
                False,
                False,
                "wss://stream.binance.com:9443",
            ],
            [
                BinanceAccountType.USDT_FUTURE,
                False,
                False,
                "wss://fstream.binance.com",
            ],
            [
                BinanceAccountType.COIN_FUTURE,
                False,
                False,
                "wss://dstream.binance.com",
            ],
            [
                BinanceAccountType.SPOT,
                False,
                True,
                "wss://stream.binance.us:9443",
            ],
            [
                BinanceAccountType.MARGIN,
                False,
                True,
                "wss://stream.binance.us:9443",
            ],
            [
                BinanceAccountType.ISOLATED_MARGIN,
                False,
                True,
                "wss://stream.binance.us:9443",
            ],
            [
                BinanceAccountType.USDT_FUTURE,
                False,
                True,
                "wss://fstream.binance.us",
            ],
            [
                BinanceAccountType.COIN_FUTURE,
                False,
                True,
                "wss://dstream.binance.us",
            ],
            [
                BinanceAccountType.SPOT,
                True,
                False,
                "wss://testnet.binance.vision",
            ],
            [
                BinanceAccountType.MARGIN,
                True,
                False,
                "wss://testnet.binance.vision",
            ],
            [
                BinanceAccountType.ISOLATED_MARGIN,
                True,
                False,
                "wss://testnet.binance.vision",
            ],
            [
                BinanceAccountType.USDT_FUTURE,
                True,
                False,
                "wss://stream.binancefuture.com",
            ],
        ],
    )
    def test_get_ws_base_url(self, account_type, is_testnet, is_us, expected):
        # Arrange, Act
        base_url = _get_ws_base_url(account_type, is_testnet, is_us)

        # Assert
        assert base_url == expected

    def test_create_binance_live_spot_data_client(self, binance_http_client):
        # Arrange, Act
        data_client = BinanceLiveDataClientFactory.create(
            loop=self.loop,
            name="BINANCE",
            config=BinanceDataClientConfig(  # (S106 Possible hardcoded password)
                api_key="SOME_BINANCE_API_KEY",  # Do not remove or will fail in CI
                api_secret="SOME_BINANCE_API_SECRET",  # Do not remove or will fail in CI
                account_type=BinanceAccountType.SPOT,
            ),
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        assert isinstance(data_client, BinanceSpotDataClient)

    def test_create_binance_live_futures_data_client(self, binance_http_client):
        # Arrange, Act
        data_client = BinanceLiveDataClientFactory.create(
            loop=self.loop,
            name="BINANCE",
            config=BinanceDataClientConfig(  # (S106 Possible hardcoded password)
                api_key="SOME_BINANCE_API_KEY",  # Do not remove or will fail in CI
                api_secret="SOME_BINANCE_API_SECRET",  # Do not remove or will fail in CI
                account_type=BinanceAccountType.USDT_FUTURE,
            ),
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        assert isinstance(data_client, BinanceFuturesDataClient)

    def test_create_binance_spot_exec_client(self, binance_http_client):
        # Arrange, Act
        exec_client = BinanceLiveExecClientFactory.create(
            loop=self.loop,
            name="BINANCE",
            config=BinanceExecClientConfig(  # (S106 Possible hardcoded password)
                api_key="SOME_BINANCE_API_KEY",  # Do not remove or will fail in CI
                api_secret="SOME_BINANCE_API_SECRET",  # Do not remove or will fail in CI
                account_type=BinanceAccountType.SPOT,
            ),
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        assert isinstance(exec_client, BinanceSpotExecutionClient)

    def test_create_binance_futures_exec_client(self, binance_http_client):
        # Arrange, Act
        exec_client = BinanceLiveExecClientFactory.create(
            loop=self.loop,
            name="BINANCE",
            config=BinanceExecClientConfig(  # (S106 Possible hardcoded password)
                api_key="SOME_BINANCE_API_KEY",
                api_secret="SOME_BINANCE_API_SECRET",
                account_type=BinanceAccountType.USDT_FUTURE,
            ),
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        assert isinstance(exec_client, BinanceFuturesExecutionClient)


from collections import defaultdict

def minWindow(s: str, t: str) -> str:
    countDict = defaultdict(int)
    for letter in t:
        countDict[letter] += 1

    lenS = len(s)
    start = 0
    end = 0
    if s[start] in countDict:
        countDict[s[start]] -= 1

    minLen = 10 ** 5 + 1
    minStr = ""
    while start <= end < lenS:
        # t의 모든 글자를 포함하는 substring
        if all(value <= 0 for value in countDict.values()):
            thisLen = end - start + 1
            if thisLen < minLen:
                minLen = thisLen
                minStr = s[start:end + 1]
            if s[start] in countDict:
                countDict[s[start]] += 1
            start += 1
        else:
            # substring에 t의 모든 글자가 들어가지 않아
            # end만 +1 해서 길이 늘려줌
            end += 1
            if end < lenS and s[end] in countDict:
                countDict[s[end]] -= 1
    return minStr

s = "a"
t = "aa"
print(minWindow(s, t))


"""
SCP SL SERVERS LIST LIB
BY ELYCRAFT
"""

### IMPORTS ###

import requests
import json

### CONSTANTES ###

HEADERS = {
    'authority': 'scplist.kr',
    'x-mod-sbb-ctype': 'xhr',
    'accept': 'application/json, text/plain, */*',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua': '"Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"',
    'content-type': 'application/json;charset=UTF-8',
    'origin': 'https://scplist.kr',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-mode': 'cors',
    'sec-fetch-dest': 'empty',
    'referer': 'https://scplist.kr/',
    'accept-language': 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
    'dnt': '1',
}

DATA = '{"search":"","countryFilter":[],"hideEmptyServer":false,"hideFullServer":false,"friendlyFire":"null","whitelist":"null","modded":"null","sort":"DISTANCE_ASC"}'

HEAVEN_RP = 34873 #For exemple

### FONCTIONS ###

def get_json(headers=HEADERS,data=DATA,local=False):
  """
  Prend un headers et un data (fournit par defaut) et local : requete ou fichier local.

  Keyword arguments:
    headers -- Headers de la requete
    data -- Data de la requete
    local -- Fichier local (True) ou non (False).
  """

  if local:

    with open("output.json", "rb") as fic:
        out_raw = fic.read()
  else:

    response = requests.post('https://scplist.kr/api/servers', headers=headers, data=data)
    out_raw = response.content
    with open("output.json", "wb") as fic:
        fic.write(out_raw)

  out_raw = json.loads(out_raw)
  servers_raw = out_raw["servers"]
  servers_raw = json.dumps(servers_raw)
  servers = json.loads(servers_raw)
  return servers

def search_players (serverId,serversJson):
  """
  Cherche dans le json et renvoi un str de l'entrée "players" d'un "serverId".

  Keyword arguments:
    serverId -- l'id du serveur dans le json
    serversJson -- la variable qui contient le json
  """

  for i in serversJson:

      if i['serverId'] == serverId:
          return i['players']
          break

def get_players(serverId):
  """
  Renvoi un tuple de l'entrée "players" d'un serveur.

  Keyword arguments:
    serverId -- l'id du serveur dans le json
  """
  a = search_players(serverId,get_json(local=False))
  return (a.split("/")[0],a.split("/")[1])

### MAIN ###

if __name__ == "__main__":
  print(get_players(HEAVEN_RP))


import asyncio
import dataclasses
import logging
import sys
import os
from bumble.core import BT_BR_EDR_TRANSPORT
from bumble.device import Device, ScoLink
from bumble.hci import HCI_Enhanced_Setup_Synchronous_Connection_Command
from bumble.hfp import DefaultCodecParameters, ESCO_PARAMETERS

from bumble.transport import open_transport_or_link

# -----------------------------------------------------------------------------
async def main() -> None:
    if len(sys.argv) < 3:
        print(
            'Usage: run_esco_connection.py <config-file>'
            '<transport-spec-for-device-1> <transport-spec-for-device-2>'
        )
        print(
            'example: run_esco_connection.py classic1.json'
            'tcp-client:127.0.0.1:6402 tcp-client:127.0.0.1:6402'
        )
        return

    print('<<< connecting to HCI...')
    hci_transports = await asyncio.gather(
        open_transport_or_link(sys.argv[2]), open_transport_or_link(sys.argv[3])
    )
    print('<<< connected')

    devices = [
        Device.from_config_file_with_hci(
            sys.argv[1], hci_transport.source, hci_transport.sink
        )
        for hci_transport in hci_transports
    ]

    devices[0].classic_enabled = True
    devices[1].classic_enabled = True

    await asyncio.gather(*[device.power_on() for device in devices])

    connections = await asyncio.gather(
        devices[0].accept(devices[1].public_address),
        devices[1].connect(devices[0].public_address, transport=BT_BR_EDR_TRANSPORT),
    )

    def on_sco(sco_link: ScoLink):
        connections[0].abort_on('disconnection', sco_link.disconnect())

    devices[0].once('sco_connection', on_sco)

    await devices[0].send_command(
        HCI_Enhanced_Setup_Synchronous_Connection_Command(
            connection_handle=connections[0].handle,
            **ESCO_PARAMETERS[DefaultCodecParameters.ESCO_CVSD_S3].asdict(),
        )
    )

    await asyncio.gather(
        *[hci_transport.source.terminated for hci_transport in hci_transports]
    )

# -----------------------------------------------------------------------------
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'DEBUG').upper())
asyncio.run(main())


import dataclasses
import enum
import functools
import os
import pathlib
import warnings
from importlib import import_module
from typing import Tuple, List

import numpy as np
import pandas as pd
from pinocchio import SE3, Quaternion
from pydrake.common import FindResourceOrThrow

PKG_PATH = pathlib.Path(__file__).parent
PROJECT_PATH = PKG_PATH.parent.parent

# override resources path from env
RESOURCES_PATH = PROJECT_PATH.joinpath("resources")
RESOURCES_PATH = pathlib.Path(
    os.environ.get("MANIPULATOR_RESOURCES_PATH", RESOURCES_PATH)
)
# override resources path from env
DATA_PATH = RESOURCES_PATH.joinpath("data")
DATA_PATH = pathlib.Path(os.environ.get("MANIPULATOR_DATA_PATH", DATA_PATH))

MODEL_PATH = RESOURCES_PATH.joinpath("model")

ROBOT_PATH = MODEL_PATH.joinpath("iiwa_description")
DRAKE_MOD_PATH = MODEL_PATH.joinpath("drake-mod")
INITIAL_STATES_FILE_NEW_PATTERN = "initial_states_%s_%s_%d.npy"
COLLECTED_DATA_FILE_NEW_PATTERN = "collected_data_%s_%s_%d.pkl"
FREE_TIME_SOLUTION_FILE_PATTERN = "free_time_%s_%s_%d.pkl"

DRAKE_SHARE_PATH = pathlib.Path("/opt/drake/share")
DRAKE_PATH = MODEL_PATH.joinpath("drake")

DEFAULT_MAX_DDP_ITERATIONS = 200

# This is not yet implemented by tqdm officially
# see: https://github.com/tqdm/tqdm/pull/950 and https://github.com/tqdm/tqdm/issues/614
TQDM_DISABLE = False
if os.environ.get("TQDM_DISABLE", False):
    TQDM_DISABLE = True

@dataclasses.dataclass
class WeldInfo:
    child: str
    xyz_rpy: Tuple[float, float, float, float, float, float] = None
    _parent: str = None  # None means WorldBody

    @property
    def parent(self):
        if self._parent is not None:
            raise ValueError(
                "Welding to frame other than world frame is not supported."
            )
        return self._parent

@dataclasses.dataclass
class IKModuleSpec:
    # ik_module_spec = (ik_module: str=module_name, free_joint_indices: List[int])
    # currently, we specify module name here as there is no well-established lazy module library in Python
    # the ik_module must contain a function named `get_ik` with signature:
    # (translation, rotation represented as SO3 matrix as a list of lists, free joint values) -> all joint values
    module_name: str
    free_joint_indices: List[int]
    # the ik_module is built to solve a specific link
    # for other links of interest, we need to apply a rigid transform
    # given pose of link a, wXa, i.e., pose of link a in world frame => wXb = wXa * aXb
    # given pose of link b, wXb, i.e., pose of link b in world frame => wXa = wXb * aXb.inverse()
    aXb: SE3 = None  # a: link of ik_module, b: link of interest

    @functools.cached_property
    def bXa(self):
        return self.aXb.inverse()  # noqa

    @functools.cached_property
    def module(self):
        return import_module(self.module_name)

    def get_ik_fn(self):
        if self.aXb is None:
            return self.module.get_ik

        def get_ik(translation, rotation, free_joint_values):
            pose = SE3(np.array(rotation), np.array(translation).reshape(-1, 1))  # wXb
            pose = pose * self.bXa  # wXa
            return self.module.get_ik(
                pose.translation.tolist(), pose.rotation.tolist(), free_joint_values
            )

        return get_ik

    def get_fk_fn(self):
        if self.aXb is None:
            return self.module.get_fk

        def get_fk(joint_values):
            trans, rotation = self.module.get_fk(joint_values)
            pose = SE3(np.array(rotation), np.array(trans).reshape(-1, 1))  # wXa
            pose = pose * self.aXb  # wXb
            return pose.translation.tolist(), pose.rotation.tolist()

        return get_fk

@dataclasses.dataclass
class ModelDefinitionConfig:
    # the path to model description file
    _model_file_path: str
    # this is used by Pinocchio: it will search package
    # (i.e., folder whose name is the same as package name) in this directory
    dir_containing_pkg: str
    # To load this model in Drake, one should configure the Parser as:
    # parser.package_map().Add(model_conf.pkg_name, model_conf.pkg_dir)
    pkg_dir: str  # the path to the package, used by Drake
    pkg_name: str  # This is the package name in the model description file when referring to meshes
    ee_name: str
    warn_msg: str = None
    weld_info: WeldInfo = None
    ik_module_spec: IKModuleSpec = None

    @property
    def model_file_path(self) -> str:
        if self.warn_msg:
            warning_msg = f"Model at {self._model_file_path}: {self.warn_msg}"
            warnings.warn(UserWarning(warning_msg))
        return self._model_file_path

    def print_to_str(self):
        return f"Model at: {self.model_file_path}"

class PreconfiguredModels(enum.Enum):
    # Since Drake v1.15.0, models data_process file are not ship with Drake.
    drake_iiwa14 = ModelDefinitionConfig(
        FindResourceOrThrow(
            "drake/manipulation/models/iiwa_description/urdf/iiwa14_no_collision.urdf"
        ),
        # from pydrake.multibody.parsing import PackageMap
        # PackageMap().GetPath("drake_models") returns the path to the drake_models package folder.
        # The folder is not named `drake_models` but some hash value.
        # Therefore, we can't provide the path to Pinocchio so that it can find the package `drake_models` in that path.
        # We thus disable loading this model using Pinocchio.
        "",
        pkg_dir="",
        pkg_name="",
        ee_name="iiwa_link_ee_kuka",
        weld_info=WeldInfo(
            "base",
        ),
    )
    drake_iiwa14_mod = ModelDefinitionConfig(
        str(DRAKE_MOD_PATH.joinpath("urdf", "iiwa14_no_collision.urdf")),
        str(DRAKE_MOD_PATH.parent),
        pkg_dir=str(DRAKE_MOD_PATH),
        pkg_name="drake-mod",
        ee_name="iiwa_link_ee_kuka",
        weld_info=WeldInfo(
            "base",
        ),
    )
    drake_iiwa14_mod_alpha = ModelDefinitionConfig(
        str(DRAKE_MOD_PATH.joinpath("urdf", "iiwa14_no_collision_alpha.urdf")),
        str(DRAKE_MOD_PATH.parent),
        pkg_dir=str(DRAKE_MOD_PATH),
        pkg_name="drake-mod",
        ee_name="iiwa_link_ee_kuka",
        weld_info=WeldInfo(
            "base",
        ),
    )
    planar = ModelDefinitionConfig(
        str(DRAKE_MOD_PATH.joinpath("urdf", "planar_iiwa14_no_collision.urdf")),
        str(DRAKE_MOD_PATH.parent),
        pkg_dir=str(DRAKE_MOD_PATH),
        pkg_name="drake-mod",
        ee_name="iiwa_link_ee_kuka",
        weld_info=WeldInfo(
            "base",
        ),
    )
    drake_iiwa14_mod_naive_collisions = ModelDefinitionConfig(
        str(DRAKE_MOD_PATH.joinpath("urdf", "iiwa14_naive_collision.urdf")),
        str(DRAKE_MOD_PATH.parent),
        pkg_dir=str(DRAKE_MOD_PATH),
        pkg_name="drake-mod",
        ee_name="iiwa_link_ee_kuka",
        weld_info=WeldInfo(
            "base",
        ),
    )

@dataclasses.dataclass(eq=False)
class ReachingConfigWithWaypoints:
    nq: int
    waypoints: List[np.ndarray]
    target_pose: SE3 = None

    def _complete_state(self, x: np.ndarray):
        if len(x) == self.nq:
            return np.r_[x, np.zeros(self.nq)]
        return x

    def __post_init__(self):
        self.waypoints = [self._complete_state(x) for x in self.waypoints]

    @property
    def initial(self):
        return self.waypoints[0]

    @property
    def terminal(self):
        if self.target_pose is not None:
            return self.target_pose
        return self.waypoints[-1]

    @property
    def q_initial(self):
        return self.initial[: self.nq]

    @property
    def q_terminal(self):
        return self.terminal[: self.nq]


class Solution:
    def eventualSafeNodes(self, graph: List[List[int]]) -> List[int]:
        n = len(graph)
        status = [0] * n

        def dfs(node: int) -> bool:
            if status[node] == 1:
                return False
            elif status[node] == 2:
                return True

            status[node] = 1

            for child in graph[node]:
                if not dfs(child):
                    return False

            status[node] = 2
            return True

        ans = []
        for node in range(n):
            if dfs(node):
                ans.append(node)

        return ans

Python3/802. Find Eventual Safe States.py


#!/bin/python3

numbers = []
with open('input.txt', 'r') as f:
    for line in f:
        number = int(line.strip())
        numbers.append(number)

for a in numbers:
    for b in numbers:
        if a + b == 2020:
            print("a: " + str(a))
            print("b: " + str(b))
            print("a*b: " + str(a*b))
            print("Done - Happy Christmas")
            exit()


import pandas as pd
import json

def create_id(df):
    df["id"] = df["Asignatura"] + df["Grupo"]
    return df

def cleaning_nan(df):
    df = df[df["Grupo"].notna()]
    return df

def concat_sort(df1, df2):
    df1 = df1.sort_values("id").reset_index(drop=True)
    df2 = df2.sort_values("id").reset_index(drop=True)
    df_complete = pd.concat([df1, df2], join="inner", axis=1)
    df_complete = df_complete.loc[:,~df_complete.columns.duplicated()]
    return df_complete

def to_json_api(df, career):
    courses_keys = df.columns.tolist()
    processed_courses = df.values.tolist()
    data = [dict(zip(courses_keys, course)) for course in processed_courses]
    api = {"courses": data}
    with open(f'{career}_data.json', 'w') as f:
        json.dump(api, f)

M_schedule = pd.read_csv("Web_scraper/Data2022_2/mechatronics_schedules.csv")
M_ocupability = pd.read_csv("Web_scraper/Data2022_2/mechatronics_ocupability.csv")
B_schedule = pd.read_csv("Web_scraper/Data2022_2/bionics_schedules.csv")
B_ocupability = pd.read_csv("Web_scraper/Data2022_2/bionics_ocupability.csv")
T_schedule = pd.read_csv("Web_scraper/Data2022_2/telematics_schedules.csv")
T_ocupability = pd.read_csv("Web_scraper/Data2022_2/telematics_ocupability.csv")

careers_dfs = [M_schedule, B_schedule, T_schedule, M_ocupability, B_ocupability, T_ocupability]
careers = {"Mechatronics": (M_schedule, M_ocupability), "Bionics": (B_schedule, B_ocupability), "Telematics": (T_schedule, T_ocupability)}

for career_df in careers_dfs:
    career_df = create_id(career_df)

for schedule_df in [M_schedule, B_schedule, T_schedule]:
    schedule_df = cleaning_nan(schedule_df)

for career_name in careers.keys():
    career_full = concat_sort(careers[career_name][0], careers[career_name][1])
    to_json_api(career_full, career_name)


import csv
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
import os
import statistics as s_tats
import time
from scipy.special import expit
import warnings
import pickle
import math
import pandas as pd
from scipy.stats.distributions import t

def linear_fit(x, a, b):
    return a*x + b

def post_analysis_qc(model, data, voltage_array, warning, wellID, endo_removed):
    include_summary = 1

    model_len = np.shape(model)
    data_len = np.shape(data)
    #print(model_midpoint)
    #print(data_midpoint)

    if model_len[0] % 2 == 0:
        model_midpoint = model_len[0] / 2
        data_midpoint = data_len[0] / 2
    else:
        model_midpoint = np.floor(model_len[0] / 2)
        data_midpoint = np.floor(data_len[0] / 2)

    discrepancy = 0.1*data[int(data_midpoint)]
    #if model[int(model_midpoint)] != data[int(data_midpoint)]:
    warning_addition = 0
    if not (discrepancy+data[int(data_midpoint)]) >= model[int(model_midpoint)] >= (data[int(data_midpoint)]-discrepancy):
        warning_addition = 0
        include_summary = 0
        if warning:
            warning = warning + ' and model midpoint varies too far from the data'
        else:
            #print(wellID + ' midpoint warn')
            warning = 'model midpoint varies too far from the data'

    #if warning_addition == 0:
        # Check that plateau was reached
        '''
        if model_len[0] < 2:
            return warning_addition
        final_model_point = model[model_len[0]-1]
        seclast_model_point = model[model_len[0]-2]
        lin_y_data = np.array([seclast_model_point, final_model_point])

        final_volt_point = voltage_array[model_len[0]-1]
        seclast_volt_point = voltage_array[model_len[0]-2]
        lin_x_data = np.array([seclast_volt_point, final_volt_point])

        warnings.filterwarnings('ignore')
        params, cov = optimize.curve_fit(linear_fit, lin_x_data, lin_y_data)
        lin_model = linear_fit(lin_x_data, params[0], params[1])
        '''
        '''
        plt.figure()
        plt.plot(lin_x_data, lin_y_data)
        plt.plot(lin_x_data, lin_model)
        plt.show()
        '''
        '''
        #print(params[0])
        if not 0.0025 >= params[0] >= -0.0025:
            include_summary = 0
            if not warning:
                warning = 'plateau not reached in model prediction'
            else:
                warning += ' and plateau not reached in model prediction'
        #print(warning)
        '''
        #Check for endogenous current
    if warning_addition == 0 and model_len[0] >= 4 and endo_removed == 'no':
        final_model_point = data[model_len[0] - 1]
        seclast_model_point = data[model_len[0] - 2]
        thridlast_model_point = data[model_len[0] - 3]
        fourthlast_model_point = data[model_len[0] - 4]

        #fifthlast_model_point = model[model_len[0] - 5]
        #sixthlast_model_point = model[model_len[0] - 6]

        last_lin_y_data = np.array([seclast_model_point, final_model_point])
        seclast_lin_y_data = np.array([thridlast_model_point, seclast_model_point])
        thirdlast_lin_y_data = np.array([fourthlast_model_point, thridlast_model_point])

        final_volt_point = voltage_array[model_len[0] - 1]
        seclast_volt_point = voltage_array[model_len[0] - 2]
        thirdlast_volt_point = voltage_array[model_len[0] - 3]
        fourthlast_volt_point = voltage_array[model_len[0] - 4]

        last_lin_x_data = np.array([seclast_volt_point, final_volt_point])
        seclast_lin_x_data = np.array([thirdlast_volt_point, seclast_volt_point])
        thirdlast_lin_x_data = np.array([fourthlast_volt_point, thirdlast_volt_point])

        warnings.filterwarnings('ignore')
        last_params, cov = optimize.curve_fit(linear_fit, last_lin_x_data, last_lin_y_data)
        last_lin_model = linear_fit(last_lin_x_data, last_params[0], last_params[1])

        warnings.filterwarnings('ignore')
        seclast_params, cov = optimize.curve_fit(linear_fit, seclast_lin_x_data, seclast_lin_y_data)
        seclast_lin_model = linear_fit(seclast_lin_x_data, seclast_params[0], seclast_params[1])

        warnings.filterwarnings('ignore')
        thirdlast_params, cov = optimize.curve_fit(linear_fit, thirdlast_lin_x_data, thirdlast_lin_y_data)
        thirdlast_lin_model = linear_fit(thirdlast_lin_x_data, thirdlast_params[0], thirdlast_params[1])

        if last_params[0] > 0.006:
            if last_params[0] > seclast_params[0]:
                if 0 <= seclast_params[0] <= 0.003:
                    if seclast_params[0] < thirdlast_params[0]:
                        if thirdlast_params[0] > 0.005:
                            warning_addition = 1
                            include_summary = 2
                            #print(wellID + ' endo current')
                            #print('final slope = ' + str(last_params[0]))
                            #print('mid slope = ' + str(seclast_params[0]))
                            #print('start slop = ' + str(thirdlast_params[0]))
                            if not warning:
                                warning = 'Endogenous Current exhibited'
                            else:
                                warning += ' and Endogenous Current Exhibited'

    elif warning_addition == 0 and model_len[0] < 4:
        if model_len[0] < 2:
            return [warning, include_summary]
        final_model_point = model[model_len[0] - 1]
        seclast_model_point = model[model_len[0] - 2]
        lin_y_data = np.array([seclast_model_point, final_model_point])

        final_volt_point = voltage_array[model_len[0] - 1]
        seclast_volt_point = voltage_array[model_len[0] - 2]
        lin_x_data = np.array([seclast_volt_point, final_volt_point])

        warnings.filterwarnings('ignore')
        params, cov = optimize.curve_fit(linear_fit, lin_x_data, lin_y_data)
        lin_model = linear_fit(lin_x_data, params[0], params[1])
        '''
        plt.figure()
        plt.plot(lin_x_data, lin_y_data)
        plt.plot(lin_x_data, lin_model)
        plt.show()
        '''
        # print(params[0])
        #if wellID == 'P02' or wellID == 'L01' or wellID == 'E02':
            #print(wellID)
            #print(params[0])

        if not 0.005 >= params[0] >= 0:
            include_summary = 0
            warning_addition = 1
            #print(wellID + ' plat')
            if not warning:
                warning = 'plateau not reached in model prediction'
            else:
                warning += ' and plateau not reached in model prediction'
        # print(warning)

    if warning_addition == 0:
        if model_len[0] < 2:
            return [warning, include_summary]
        final_model_point = model[model_len[0] - 1]
        seclast_model_point = model[model_len[0] - 2]
        lin_y_data = np.array([seclast_model_point, final_model_point])

        final_volt_point = voltage_array[model_len[0] - 1]
        seclast_volt_point = voltage_array[model_len[0] - 2]
        lin_x_data = np.array([seclast_volt_point, final_volt_point])

        warnings.filterwarnings('ignore')
        params, cov = optimize.curve_fit(linear_fit, lin_x_data, lin_y_data)
        lin_model = linear_fit(lin_x_data, params[0], params[1])
        '''
        plt.figure()
        plt.plot(lin_x_data, lin_y_data)
        plt.plot(lin_x_data, lin_model)
        plt.show()
        '''
        # print(params[0])

        if not 0.005 >= params[0] >= 0:
            include_summary = 0
            warning_addition = 1
            #print(wellID + ' plat'+ str(params[0]))
            if not warning:
                warning = 'plateau not reached in model prediction'
            else:
                warning += ' and plateau not reached in model prediction'
        # print(warning)
    return [warning, include_summary]

#def boltzmann_v05(x, V05, k):
def boltzmann_v05(x, V05, k, top, bottom):
    #return 1/(1+np.exp((V05-x)/k))
    return bottom + ((top-bottom)/(1+np.exp((V05-x)/k)))
    #return expit(-((V05-x)/k))

#def boltzmann_therm(x, G0, z):
def boltzmann_therm(x, G0, z, top, bottom):
    '''
    num = G0 - (z * 96485 / 1000*x)
    dom = 8.3145 * 298
    return expit(-(num / dom))
    '''
    #Y=1/(1+exp((deltaG0-z*F/1000*X)/(R*T)))
    return bottom + ((top-bottom)/(1 + np.exp((G0 - (z * 96485 / 1000*x))/(8.3145 * 298))))

def V05_analysis(voltage_array, norm_currs, rsq_thresh, returnV05, returnK, pos40mVCD, wellID):
    fit_parameters = np.array(['V05', 'k', 'top', 'bottom', 'RSquared', 'Warning'])
    # fit_parameters = np.append(fit_parameters)

    # print(wellID)
    # print(norm_currs[0])
    # print(norm_currs[-1])

    p0 = [20, 20, 1, 0]
    try:
        #params, cov = optimize.curve_fit(boltzmann_v05, voltage_array, norm_currs, p0, maxfev=50000)
        params, cov = optimize.curve_fit(boltzmann_v05, voltage_array, norm_currs, p0, maxfev=50000, bounds=([-np.inf, -np.inf, 0, -np.inf], [np.inf, np.inf, 4, np.inf]))

    except:
        print(voltage_array)
        print(norm_currs)

    V05 = params[0]
    k = params[1]
    top = params[2]
    bottom = params[3]

    sigma_params = np.sqrt(np.diagonal(cov))
    V05_sigma = sigma_params[0]
    k_sigma = sigma_params[1]
    top_sigma = sigma_params[2]
    bottom_sigma = sigma_params[3]

    if V05_sigma == 0:
        V05_sigma = math.inf
    if k_sigma == 0:
        k_sigma = math.inf
    if top_sigma == 0:
        top_sigma = math.inf
    if bottom_sigma == 0:
        bottom_sigma = math.inf

    alpha = 0.05

    tval = t.ppf(1 - alpha / 2.0, (len(voltage_array)-len(params)))
    '''
    V05_lower_ci = V05 - (1.96 * (V05_sigma / np.sqrt(len(voltage_array))))
    V05_upper_ci = V05 + (1.96 * (V05_sigma / np.sqrt(len(voltage_array))))
    k_lower_ci = k - (1.96 * (k_sigma / np.sqrt(len(voltage_array))))
    k_upper_ci = k + (1.96 * (k_sigma / np.sqrt(len(voltage_array))))
    top_lower_ci = top - (1.96 * (top_sigma / np.sqrt(len(voltage_array))))
    top_upper_ci = top + (1.96 * (top_sigma / np.sqrt(len(voltage_array))))
    bottom_lower_ci = bottom - (1.96 * (bottom_sigma / np.sqrt(len(voltage_array))))
    bottom_upper_ci = bottom + (1.96 * (bottom_sigma / np.sqrt(len(voltage_array))))
    '''
    V05_lower_ci = V05 - (tval * (V05_sigma))
    V05_upper_ci = V05 + (tval * (V05_sigma))
    k_lower_ci = k - (tval * (k_sigma))
    k_upper_ci = k + (tval * (k_sigma))
    top_lower_ci = top - (tval * (top_sigma))
    top_upper_ci = top + (tval * (top_sigma))
    bottom_lower_ci = bottom - (tval * (bottom_sigma))
    bottom_upper_ci = bottom + (tval * (bottom_sigma))

    V05_lower_ci = "{:.5f}".format(V05_lower_ci)
    V05_upper_ci = "{:.5f}".format(V05_upper_ci)
    k_lower_ci = "{:.5f}".format(k_lower_ci)
    k_upper_ci = "{:.5f}".format(k_upper_ci)
    top_lower_ci = "{:.5f}".format(top_lower_ci)
    top_upper_ci = "{:.5f}".format(top_upper_ci)
    bottom_lower_ci = "{:.5f}".format(bottom_lower_ci)
    bottom_upper_ci = "{:.5f}".format(bottom_upper_ci)

    V05_ci = str('(' + str(V05_lower_ci) + ' ,' + str(V05_upper_ci) + ')')
    k_ci = str('(' + str(k_lower_ci) + ' ,' + str(k_upper_ci) + ')')
    top_ci = str('(' + str(top_lower_ci) + ' ,' + str(top_upper_ci) + ')')
    bottom_ci = str('(' + str(bottom_lower_ci) + ' ,' + str(bottom_upper_ci) + ')')

    # model = boltzmann_v05(voltage_array, V05, k)
    model = boltzmann_v05(voltage_array, V05, k, top, bottom)
    warning = ''
    rsquare = 1 - sum((norm_currs - model) ** 2) / sum((norm_currs - s_tats.mean(norm_currs)) ** 2)

    # Check the Rsquared of the voltage region from -50 to -30mV
    volt_list = list(voltage_array)
    lower_volt_indx = [i for i in range(len(volt_list)) if -30 >= volt_list[i] >= -50]
    lower_rsquare = 'N/A'
    if len(lower_volt_indx) >= 2:
        lower_rsquare = 1 - sum((norm_currs[lower_volt_indx] - model[lower_volt_indx]) ** 2) / sum(
            (norm_currs[lower_volt_indx] - s_tats.mean(norm_currs[lower_volt_indx])) ** 2)

    fit_params_results = np.array([V05, V05_ci, k, k_ci, top, top_ci, bottom, bottom_ci, rsquare])

    V05_ok = 1
    if rsquare < rsq_thresh:
        warning = 'Fit of Whole Data-set Poor'
        #pos40mVCD = 'N/A'
        returnV05 = 'N/A'
        returnK = 'N/A'
        if not -50 <= V05 <= 50:
            V05_ok = 0
            #pos40mVCD = 'N/A'
            warning = 'Fit of Whole Data-set Poor and V05 outside of possible range of values'

    else:
        '''
        if lower_rsquare != 'N/A':
            if lower_rsquare < 0.1:
                warning = 'Fit of region from -50mV to -30mV Poor with RSquared = ' + str(lower_rsquare)

                returnV05 = V05
                returnK = k
                if not -50 <= V05 <= 50:
                    V05_ok = 0
                    returnV05 = 'V05'
                    returnK = 'V05'
                    warning = 'Fit of region from -50mV to -30mV Poor with RSquared = ' + str(
                        lower_rsquare) + ' and V05 outside of possible range of values'
            else:
                if not -50 <= V05 <= 50:
                    V05_ok = 0
                    warning = 'V05 outside of possible range of values'
                    returnV05 = 'V05'
                    returnK = 'V05'
                    #pos40mVCD = 'N/A'
                else:
                    returnV05 = V05
                    returnK = k
        else:
        '''
        if not -50 <= V05 <= 50:
            V05_ok = 0
            warning = 'V05 outside of possible range of values'
            returnV05 = 'V05'
            returnK = 'V05'
            #pos40mVCD = 'N/A'
        else:
            returnV05 = V05
            returnK = k

    return [returnV05, returnK, model, rsquare, V05_ok, fit_params_results, warning, V05, k, top, bottom, lower_volt_indx, pos40mVCD]

def therm_analysis(V05, k, top, bottom, returnDG, returnz):
    therm_fit_parameters = np.array(['G0', 'z', 'top', 'bottom'])
    G0 = (V05 / k) * (8.3145 * 298)
    z = (1 / k) / (96485 / (1000 * 8.3145 * 298))
    therm_top = top
    therm_bottom = bottom

    therm_param_results = np.array([G0, z, therm_top, therm_bottom])

    returnDG = G0
    returnz = z
    return [returnDG, returnz, therm_param_results, G0, z, therm_top, therm_bottom]

def therm_fit_analysis(voltage_array, norm_currs, rsq_thresh, returnDG, returnz, lower_volt_indx, pos40mVCD):

    therm_fit_parameters = np.array(['G0', 'G0 95% CI', 'z', 'z 95% CI', 'top', 'top 95% CI', 'bottom', 'bottom 95% CI', 'RSquared', 'Warning'])

    #therm_p0 = [2500, 155, 1, 0]
    v_list = list(voltage_array)
    therm_v_list = [i for i in range(len(v_list)) if v_list[i] != 0]
    therm_voltage_array = voltage_array[therm_v_list]
    therm_norm_currs = norm_currs[therm_v_list]

    if np.shape(therm_norm_currs)[0] < 4:
        return [returnDG, returnz, np.array([]), therm_norm_currs, therm_voltage_array,'N/A', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A', pos40mVCD]

    therm_params, therm_cov = optimize.curve_fit(boltzmann_therm, therm_voltage_array, therm_norm_currs,
                                                 maxfev=5000000, bounds=([-np.inf, -np.inf, 0, -np.inf], [np.inf, np.inf, 4, np.inf]))

    G0 = therm_params[0]
    z = therm_params[1]
    therm_top = therm_params[2]
    therm_bottom = therm_params[3]

    sigma_params = np.sqrt(np.diagonal(therm_cov))
    G0_sigma = sigma_params[0]
    z_sigma = sigma_params[1]
    top_sigma = sigma_params[2]
    bottom_sigma = sigma_params[3]

    alpha = 0.05

    tval = t.ppf(1 - alpha / 2.0, (len(voltage_array) - len(therm_params)))

    if G0_sigma == 0:
        G0_sigma = math.inf
    if z_sigma == 0:
        z_sigma = math.inf
    if top_sigma == 0:
        top_sigma = math.inf
    if bottom_sigma == 0:
        bottom_sigma = math.inf

    G0_lower_ci = G0 - (tval * (G0_sigma))
    G0_upper_ci = G0 + (tval * (G0_sigma))
    z_lower_ci = z - (tval * (z_sigma))
    z_upper_ci = z + (tval * (z_sigma))
    top_lower_ci = therm_top - (tval * (top_sigma))
    top_upper_ci = therm_top + (tval * (top_sigma))
    bottom_lower_ci = therm_bottom - (tval * (bottom_sigma))
    bottom_upper_ci = therm_bottom + (tval * (bottom_sigma))

    G0_lower_ci = "{:.5f}".format(G0_lower_ci)
    G0_upper_ci = "{:.5f}".format(G0_upper_ci)
    z_lower_ci = "{:.5f}".format(z_lower_ci)
    z_upper_ci = "{:.5f}".format(z_upper_ci)
    top_lower_ci = "{:.5f}".format(top_lower_ci)
    top_upper_ci = "{:.5f}".format(top_upper_ci)
    bottom_lower_ci = "{:.5f}".format(bottom_lower_ci)
    bottom_upper_ci = "{:.5f}".format(bottom_upper_ci)

    G0_ci = str('(' + str(G0_lower_ci) + ' ,' + str(G0_upper_ci) + ')')
    z_ci = str('(' + str(z_lower_ci) + ' ,' + str(z_upper_ci) + ')')
    top_ci = str('(' + str(top_lower_ci) + ' ,' + str(top_upper_ci) + ')')
    bottom_ci = str('(' + str(bottom_lower_ci) + ' ,' + str(bottom_upper_ci) + ')')

    # therm_model = boltzmann_therm(therm_voltage_array, G0, z)
    therm_model = boltzmann_therm(therm_voltage_array, G0, z, therm_top, therm_bottom)
    therm_rsquare = 1 - sum((therm_norm_currs - therm_model) ** 2) / sum(
        (therm_norm_currs - s_tats.mean(therm_norm_currs)) ** 2)

    therm_lower_rsquare = 'N/A'
    if len(lower_volt_indx) >= 2:
        therm_lower_rsquare = 1 - sum((therm_norm_currs[lower_volt_indx] - therm_model[lower_volt_indx]) ** 2) / sum(
            (therm_norm_currs[lower_volt_indx] - s_tats.mean(therm_norm_currs[lower_volt_indx])) ** 2)

    therm_param_results = np.array([G0, G0_ci, z, z_ci, therm_top, top_ci, therm_bottom, bottom_ci, therm_rsquare])
    therm_warning = ''

    if therm_rsquare < rsq_thresh:
        #pos40mVCD = 'N/A'
        returnDG = 'N/A'
        returnz = 'N/A'
        therm_warning = 'poor fit'
    else:
        '''
        if therm_lower_rsquare != 'N/A':

            if therm_lower_rsquare < 0.1:
                therm_warning = 'Fit of region from -50mV to -30mV Poor with RSquared = ' + str(therm_lower_rsquare)
                #pos40mVCD = 'N/A'
                #returnDG = 'N/A'
                returnDG = G0
                returnz = z
            else:
                returnDG = G0
                returnz = z

        else:
        '''
        returnDG = G0
        returnz = z

    return [returnDG, returnz, therm_model, therm_norm_currs, therm_voltage_array, therm_rsquare, therm_param_results, therm_warning, G0, z, therm_top, therm_bottom, pos40mVCD]

def ssAct_fit_py(input_file, output_dir, wellID, result_plots, num_sweeps, variant, rsq_thresh, summary_sweep_voltage, total_sweeps):
    # Initialise return value
    pos40mVCD = 'N/A'
    returnV05 = 'unset'
    returnDG = 'unset'
    returnK = 'unset'
    returnz = 'unset'

    numpy_pandas = 'pandas'

    if numpy_pandas == 'numpy':
        data = []
        with open(input_file) as csvfile:
            read = csv.reader(csvfile)
            for row in read:
                data.append(row)

        data = np.array(data)

        # Filtering the time data and removing noisy time regions
        time_us = data[1:, 0]
        #print(time_us)
        time_us = time_us.astype(np.float)
        # time_us = list(time_us)

        time_secs = time_us * 1e-6
        time_secs = list(time_secs)

        tot_range_time_indx_list = [i for i in range(len(time_secs)) if 1.3 >= time_secs[i] >= 1.205]
        #print('USING OLD PROTOCOL TIME RANGE')
        #tot_range_time_indx_list = [i for i in range(len(time_secs)) if 1.13 >= time_secs[i] >= 1.09]
        tot_range_time_indx_list = np.array(tot_range_time_indx_list)
        tot_range_time_indx_list = tot_range_time_indx_list.astype(int)

        time_secs = np.array(time_secs)
        time_secs = time_secs[tot_range_time_indx_list]

        time_secs = time_secs - 1.205

        time_ms = time_secs * 1e3

        # Extract the names of the actual sweeps
        sweepNumArray = data[0, 1:]
        voltage_array = data[2, 1:]
        voltage_array = voltage_array[1::2]
        voltage_array = voltage_array.astype(float)
        # Convert to mV units
        voltage_array = voltage_array * 1e3

        try:
            summary_sweep_index = list(voltage_array).index(summary_sweep_voltage)
            summary_sweep = sweepNumArray[2*summary_sweep_index]
            summary_sweep = summary_sweep.split('_')
            summary_sweep = int(summary_sweep[1])
        except:
            summary_sweep = 'N/A'

        dataArray = data[1:, 1:]
        #print(dataArray)
        #dataArray = dataArray.astype(np.float)
    else:
        data = pd.read_csv(input_file, sep=',', low_memory=False, header=None)

        # Filtering the time data and removing noisy time regions
        time_us = data.iloc[3:, 0].astype(float)

        time_secs = time_us * 1e-6

        tot_range_time_indx_list = [i for i in range(len(time_secs)) if 1.3 >= time_secs.iloc[i] >= 1.205]
        # print('USING OLD PROTOCOL TIME RANGE')
        # tot_range_time_indx_list = [i for i in range(len(time_secs)) if 1.13 >= time_secs[i] >= 1.09]
        #tot_range_time_indx_list = np.array(tot_range_time_indx_list)
        #tot_range_time_indx_list = tot_range_time_indx_list.astype(int)

        time_secs = time_secs.iloc[tot_range_time_indx_list]

        time_secs = time_secs - 1.205

        time_ms = time_secs * 1e3

        # Extract the names of the actual sweeps
        sweepNumArray = data.iloc[0, 1:]
        voltage_array = data.iloc[2, 1:]
        voltage_array = voltage_array.iloc[1::2]
        voltage_array = np.array(voltage_array).astype(float)
        # Convert to mV units
        voltage_array = voltage_array * 1e3

        try:
            summary_sweep_index = list(voltage_array).index(summary_sweep_voltage)
            summary_sweep = sweepNumArray.iloc[2 * summary_sweep_index]
            summary_sweep = summary_sweep.split('_')
            summary_sweep = int(summary_sweep[1])
        except:
            summary_sweep = 'N/A'

        dataArray = data.iloc[1:, 1:]
        # print(dataArray)
        # dataArray = dataArray.astype(np.float)

    # A matrix storing the results of the current densities for all the sweeps in the well
    current_dens_data = []
    current_dens_data.append([])
    #current_dens_data[0].append('SweepNum')
    current_dens_data[0].append('Voltage (mV)')
    current_dens_data[0].append('Current Density (pA/pF)')

    # create an 13 row result list

    for i in range(1, total_sweeps + 1):
        current_dens_data.append([])
        '''
        sw = i
        current_dens_data[i].append('Sweep' + str(sw))
        '''

    os.mkdir(os.path.join(result_plots, wellID))
    norm_currs = np.array([])     #array that stores the current densities which is then normalised using the minimum current dens
    #print((2*num_sweeps)-1)
    #print(np.shape(dataArray))
    for sweep in range(1, (2*num_sweeps), 2):
        #print(sweep)

        if numpy_pandas == 'numpy':
            actual_sweep = sweepNumArray[sweep]
            actual_sweep = actual_sweep.split('_')
            actual_sweep = int(actual_sweep[1])

            sweepData = dataArray[tot_range_time_indx_list, sweep]
            sweepData = np.array(sweepData).astype(float)

            capacitance = np.array(dataArray[0, sweep]).astype(float)
        else:
            actual_sweep = sweepNumArray.iloc[sweep]
            actual_sweep = actual_sweep.split('_')
            actual_sweep = int(actual_sweep[1])

            capacitance = float(dataArray.iloc[0, sweep])

            sweepData = dataArray.iloc[2:, sweep]
            sweepData = sweepData.iloc[tot_range_time_indx_list].astype(float)

        '''
        plt.figure()
        plt.plot(time_secs, sweepData)
        plt.title(wellID + ' ' + str(actual_sweep))
        plt.show()
        '''

        #print(sweepData)
        #time.sleep(4)

        #print(capacitance)

        min_curr_amp = min(sweepData)
        # Current density = minimum current amplitude / capacitance
        current_density = min_curr_amp / capacitance
        #current_density = min_curr_amp
        current_dens_data[actual_sweep].append(voltage_array[int(sweep/2)])
        current_dens_data[actual_sweep].append(current_density)

        #print(actual_sweep)
        #print(summary_sweep)
        if actual_sweep == summary_sweep:
            #pos40mVCD = 'current_density = ' + str(current_density) + ' min current =  ' + str(min_curr_amp) + ' capacitance = ' + str(capacitance)
            pos40mVCD = current_density

        norm_currs = np.append(norm_currs, min_curr_amp)

        fig = plt.figure()
        plt.plot(time_secs, sweepData)
        plt.xlabel('Time(s)')
        plt.ylabel('Current (pA)')
        plt.title('Raw Current Data Sweep' + str(actual_sweep) + ' ' + str(min_curr_amp))
        plt.savefig(os.path.join(result_plots, wellID, wellID + '_Sweep' + str(actual_sweep)) + '_image')
        with open(os.path.join(result_plots, wellID, wellID + '_Sweep' + str(actual_sweep)) + '.pickle', 'wb') as fig_file:
            pickle.dump(fig, fig_file)
        fig_file.close()
        plt.close(fig)

    #print(pos40mVCD)
    # Now fit the minimum current data to the boltzmann curves
    if len(norm_currs) < 8:
        if returnV05 == 'unset':
            returnV05 = 'N/A'
        if returnK == 'unset':
            returnK = 'N/A'
        if returnDG == 'unset':
            returnDG = 'N/A'
        if returnz == 'unset':
            returnz = 'N/A'

        return [pos40mVCD, returnV05, returnDG, returnK, returnz]

    #norm_currs = norm_currs[::-1]
    #voltage_array = voltage_array[::-1]
    #print(wellID)
    #print(norm_currs)
    #print(voltage_array)
    orig_norm_currs = norm_currs
    #print(norm_currs)
    #norm_currs = abs(norm_currs)
    max_normcurr = max(norm_currs)
    max_normcurr = min(norm_currs)
    #print()
    # norm_currs = norm_currs / max_normcurr
    norm_currs = np.divide(norm_currs, [max_normcurr])
    #print(norm_currs)

    fit_parameters = np.array(['V05', 'V05 95% CI', 'k', 'k 95% CI', 'top', 'top 95% CI', 'bottom', 'bottom 95% CI', 'RSquared', 'Warning'])

    [returnV05, returnK, model, rsquare, V05_ok, fit_params_results, warning, V05, k, top, bottom, lower_volt_indx, pos40mVCD] = V05_analysis(voltage_array, norm_currs, rsq_thresh, returnV05, returnK, pos40mVCD, wellID)

    [warning, include_summary] = post_analysis_qc(model, norm_currs, voltage_array, warning, wellID, 'no')

    if include_summary == 0:
        returnV05 = 'N/A'
        returnK = 'N/A'
    if include_summary == 2:
        norm_currs = orig_norm_currs[0:-1]
        # norm_currs = abs(norm_currs)
        # max_curr = max(norm_currs)
        max_curr = min(norm_currs)
        norm_currs = np.divide(norm_currs, [max_curr])
        voltage_array = voltage_array[0:-1]

        [returnV05, returnK, model, rsquare, V05_ok, fit_params_results, warning, V05, k, top, bottom, lower_volt_indx,
         pos40mVCD] = V05_analysis(voltage_array, norm_currs, rsq_thresh, returnV05, returnK, pos40mVCD, wellID)
        if warning:
            warning += ' and Endogenous Current Exhibited'
        else:
            warning = 'Endogenous Current Exhibited'
        [warning, include_summary] = post_analysis_qc(model, norm_currs, voltage_array, warning, wellID, 'yes')
        if include_summary == 0:
            returnV05 = 'N/A'
            returnK = 'N/A'
        include_summary = 2

    if rsquare > rsq_thresh and V05_ok == 1:
        therm_fit_parameters = np.array(['G0', 'z', 'top', 'bottom'])
        #therm_fit_parameters = np.array(['G0', 'G0 95% CI', 'z', 'z 95% CI', 'top', 'top 95% CI', 'bottom', 'bottom 95% CI', 'RSquared', 'Warning'])
        #[returnDG, returnz, therm_model, therm_norm_currs, therm_voltage_array, therm_rsquare, therm_param_results, therm_warning, G0, z, therm_top, therm_bottom, pos40mVCD] = therm_fit_analysis(voltage_array, norm_currs, rsq_thresh, returnDG, returnz, lower_volt_indx, pos40mVCD)
        [returnDG, returnz, therm_param_results, G0, z, therm_top, therm_bottom] = therm_analysis(V05, k, top, bottom, returnDG, returnz)

        '''
        if therm_model.any():
            if include_summary == 2:
                [therm_warning, include_therm_summary] = post_analysis_qc(therm_model, therm_norm_currs, therm_voltage_array, therm_warning, wellID, 'yes')
                if therm_warning:
                    therm_warning += ' and Endogenous Current Exhibited'
                else:
                    therm_warning = 'Endogenous Current Exhibited'
            else:
                [therm_warning, include_therm_summary] = post_analysis_qc(therm_model, therm_norm_currs, therm_voltage_array, therm_warning, wellID, 'no')
            if include_therm_summary == 0:
                returnDG = 'N/A'
                returnz = 'N/A'

            #IGNORE FROM HERE
            if include_therm_summary == 2:
            # Endogenous current observed in post-qc analysis, remove last element and re-analyse without endogenous current
                if np.shape(voltage_array)[0] >= 6:
                    therm_cds = orig_norm_currs[0:-1]
                    #therm_cds = abs(therm_cds)
                    therm_vs = voltage_array[0:-1]
                    #max_cd = max(therm_cds)
                    max_cd = min(therm_cds)
                    therm_cds = np.divide(therm_cds, [max_cd])
                    if therm_warning:
                        therm_warning += ' and Endogenous Current Exhibited'
                    else:
                        therm_warning += 'Endogenous Current Exhibited'
                    [returnDG, returnz, therm_model, therm_norm_currs, therm_voltage_array, therm_rsquare, therm_param_results, therm_warning, G0, z, therm_top, therm_bottom, pos40mVCD] = therm_analysis(therm_vs, therm_cds, rsq_thresh, returnDG, returnz, lower_volt_indx, pos40mVCD)
                    [therm_warning, include_therm_summary] = post_analysis_qc(therm_model, therm_norm_currs, therm_voltage_array, therm_warning, wellID)
                    if include_therm_summary == 0:
                        returnDG = 'N/A'
                        returnz = 'N/A'
            #IGNORE TO HERE

            fig = plt.figure()
            plt.plot(therm_voltage_array, therm_norm_currs, 'o')
            plt.plot(therm_voltage_array, therm_model)
            plt.title(wellID + ' Thermodynamic Boltzmann Curve')
            plt.xlabel('Voltages (mV)')
            plt.ylabel('Normalised Currrent')
            plt.savefig(os.path.join(result_plots, wellID, 'Thermodynamic_' + wellID)+'_image')
            with open(os.path.join(result_plots, wellID, 'Thermodynamic_' + wellID)+'.pickle', 'wb') as fig_file:
                pickle.dump(fig, fig_file)
            fig_file.close()
            '''

        #therm_param_results = np.append(therm_param_results, warning)
        therm_fit_parameters = np.vstack((therm_fit_parameters, therm_param_results))

        therm_file = os.path.join(output_dir, wellID + '_thermodynamic_parameters.csv')
        with open(therm_file, mode='w') as therm_output:
            result_writer = csv.writer(therm_output, delimiter=',', lineterminator='\n')
            for row in range(0, 2):
                result_writer.writerow(therm_fit_parameters[row])

    #if returnDG == 'N/A' or returnK == 'N/A' or returnV05 == 'N/A':
    #    pos40mVCD = 'N/A'

    if returnV05 == 'V05' or returnK == 'V05':
        returnV05 = 'N/A'
        returnK = 'N/A'

    if returnK == 'unset':
        returnK = 'N/A'

    if returnV05 == 'unset':
        returnV05 = 'N/A'

    if returnDG == 'unset':
        returnDG = 'N/A'

    if returnz == 'unset':
        returnz = 'N/A'

    if variant == 'neg_ctrl':
        returnK = 'N/A'
        returnV05 = 'N/A'
        returnDG = 'N/A'
        returnz = 'N/A'

    fit_params_results = np.append(fit_params_results, warning)
    fit_parameters = np.vstack((fit_parameters, fit_params_results))

    fig = plt.figure()
    plt.plot(voltage_array, norm_currs, 'o')
    plt.plot(voltage_array, model)
    plt.title(wellID + ' V05 Boltzmann Curve')
    plt.xlabel('Voltages (mV)')
    plt.ylabel('Normalised Currrent')
    plt.savefig(os.path.join(result_plots, wellID, 'V05_' + wellID)+'_image')
    with open(os.path.join(result_plots, wellID, 'V05_' + wellID)+ '.pickle', 'wb') as fig_file:
        pickle.dump(fig, fig_file)
    fig_file.close()
    plt.close(fig)

    V05_file = os.path.join(output_dir, wellID + '_V05_parameters.csv')
    with open(V05_file, mode='w') as V05_output:
        res_writer = csv.writer(V05_output, delimiter=',', lineterminator='\n')
        for row in range(0, 2):
            res_writer.writerow(fit_parameters[row])

    cd_file = os.path.join(output_dir, wellID + '_current_densities.csv')
    with open(cd_file, mode='w') as cd_output:
        res_cd_writer = csv.writer(cd_output, delimiter=',', lineterminator='\n')
        for row in range(0, total_sweeps + 1):
            res_cd_writer.writerow(current_dens_data[row])

    plt.close('all')
    #print(pos40mVCD)
    return [pos40mVCD, returnV05, returnDG, returnK, returnz]


#TwistedServer
import pickle
from traceback import print_exc
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor, stdio

from engine import debug, shared
import TwCLI, sh_netObject, sh_netMethod
from sv_netPlayer import Player

shared.objectManager=sh_netObject.ObjectManager()

#OBJECTS:
#0 = Server
#1 = Service
#1** = Players
#1**** = Units

INTERFACE="server"

class Server():
	def __init__(self):
		shared.objectManager.addEntry(0,0,self)
		self.ServerInfo={
		'name':"YARTS-Server",
		'desc':"Yet Another RTS Server",
		'region':'Europe',
		'country':'Norway'
		}

	def SI(self, Protocol=None):
		Protocol.sendMethod(1, "SI", [pickle.dumps(self.ServerInfo)])

class Service():
	def __init__(self):
		reactor.callLater(5, self.PingAll)
		self.connections=[]

	def ConnectionMade(self, proto):
		self.connections.append(proto)

	def ConnectionLost(self, proto, reason):
		shared.DPrint("Service", 1, "Connection to client lost: "+reason)
		try:
			shared.playerManager.DCONN(proto)
			self.connections.remove(proto)
		except KeyError:
			shared.DPrint("Service", 1, "Client not exsisting!")
		#proto.loseConnection()

	def PingAll(self):
		for x in self.connections:
			x.Ping()
			try:
				shared.DPrint("Service", 0, x.player.name+": "+str(x.ping))
			except:
				shared.DPrint("Service", 0, "UNINITIALIZED"+": "+str(x.ping))
		reactor.callLater(5, self.PingAll)

class PlayerManager():
	def __init__(self):
		shared.objectManager.addEntry(0, 1, self)
		self.Players={}
		self.Playern=0

	def sendMethodToAll(self, obj, func, arg):
		for x in self.Players:
			self.Players[x].protocol.sendMethod(obj, func, arg)

	#Network Responses
	def HI(self, name, Protocol=None):
		self.Playern+=1
		ply=Player(name, self.Playern, Protocol)
		self.sendMethodToAll(2, "NEW", [pickle.dumps(ply.getInfo())])
		#reactor.callLater(0.5, lambda: self.sendMethodToAll(1, "SI", [pickle.dumps(shared.Server.ServerInfo)])) Wtf were I even thinking here?
		self.Players[self.Playern]=ply
		print("Shook hands with: "+name)
		Protocol.player=ply
		Protocol.sendMethod(0, "HI", [str(self.Playern)])

	def PL(self, Protocol=None):
		FooList=[]
		for x in self.Players:
			FooList.append(self.Players[x].PlayerInfo)
		Protocol.sendMethod(1, "PL", [pickle.dumps(FooList)])

	def DCONN(self, Protocol=None):
		shared.DPrint("PlayerManager", 1, "Player: "+str(Protocol.player.ID)+" disconnected")
		del self.Players[Protocol.player.ID]

def Startup():
	shared.Server=Server()
	shared.Service=Service()
	cliFactory=TwCLI.CLIFactory()
	shared.playerManager=PlayerManager()

	reactor.listenTCP(1337, sh_netMethod.MethodFactory())
	reactor.run()


import re
from collections import defaultdict
from dataclasses import dataclass
from typing import Dict, List, FrozenSet

parse_name = re.compile(r"^# ALTERNATIVE NAME (\d+): (.*)$")
parse_choices = re.compile(r"^\{?([\d,]*)\}?,\{?([\d,]*)\}?$")

CandidateId = int

@dataclass
class VotingInfo:
    candidate_names: Dict[CandidateId, str]
    profiles: Dict[FrozenSet[int], int]

    @classmethod
    def default(cls) -> "VotingInfo":
        return VotingInfo(
            candidate_names={},
            profiles=defaultdict(int)
        )

    @classmethod
    def from_file(cls, fname: str) -> "VotingInfo":
        info = VotingInfo.default()

        with open(fname) as f:
            lines = f.read().split("\n")

        for line in lines:
            name_match = parse_name.findall(line)
            if len(name_match) != 0:
                candidate_id, candidate_name = name_match[0]
                candidate_id = int(candidate_id)
                info.candidate_names[candidate_id] = candidate_name

            # comment/data description
            if line.startswith("#"):
                continue

            line = line.strip()

            # empty line
            if len(line) == 0:
                continue

            count, _, choices_raw = line.partition(": ")
            count = int(count)

            try:
                pref_raw, _nonpref_raw = parse_choices.findall(choices_raw)[0]
            except IndexError:
                print(f"Failed to parse line '{line}'! Skipping.\n")
                continue

            def parse_list(raw):
                return frozenset({
                    int(e) for e in raw.split(",")
                    if len(e) != 0
                })

            # print(pref_raw, " - ", nonpref_raw)

            key = parse_list(pref_raw)
            info.profiles[key] += count

        return info

    @classmethod
    def from_files(cls, fnames: List[str]) -> "VotingInfo":
        info = VotingInfo.default()

        for fname in fnames:
            info.merge_with(VotingInfo.from_file(fname))

        return info

    def candidate_id_set(self):
        return set(self.candidate_names.keys())

    def merge_with(self, other: "VotingInfo"):
        self.candidate_names.update(other.candidate_names)

        for profile, count in other.profiles.items():
            self.profiles[profile] += count

    def format_candidate_ids(self, candidate_ids):
        return ", ".join(self.candidate_names[i] for i in candidate_ids)

def pref_frequencies(info: VotingInfo):
    in_pref = defaultdict(int)

    for prefs, count in info.profiles.items():
        for pref in prefs:
            in_pref[pref] += count

    return in_pref

def print_sorted_freq(freqs, info: VotingInfo):
    sorted_freqs = sorted(freqs.items(), key=lambda kv: -kv[1])

    for candidate_id, freq in sorted_freqs:
        print(f"{info.candidate_names[candidate_id]: <15}: {freq}")

if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser()

    parser.add_argument("paths", type=str, nargs="+")

    args = parser.parse_args()

    info = VotingInfo.from_files(args.paths)

    in_pref = pref_frequencies(info)

    print_sorted_freq(in_pref, info)


# Напишите программу, которая принимает две строки
# вида “a/b” - дробь с числителем и знаменателем.
# Программа должна возвращать сумму и произведение* дробей.
# Для проверки своего кода используйте модуль fractions.

from fractions import Fraction

fraction_1 = input('Введите первую дробь формата "a/b": ').split('/')
fraction_2 = input('Введите вторую дробь формата "a/b": ').split('/')

imported_1 = Fraction(int(fraction_1[0]), int(fraction_1[1]))
imported_2 = Fraction(int(fraction_2[0]), int(fraction_2[1]))

print(f'Проверка {imported_1 + imported_2}')
print(f'Проверка {imported_1 * imported_2}')

a = int(fraction_1[0])
b = int(fraction_1[1])
c = int(fraction_2[0])
d = int(fraction_2[1])

def gcd(x, y):                      # наибольший общий делитель (нод)
    while y != 0:
        (x, y) = (y, x % y)
    return x

def summa_fractions(a, b, c, d):
    x = a*d + b*c
    y = b*d
    z = gcd(x, y)
    return (f'{x//z}/{y//z}')

def multiply_fractions(a, b, c, d):   # умножаем числители и знаменатели,
    num = a * c                       # вычисляем их нод и делим оба ч и з на нод
    den = b * d
    common_factor = gcd(num, den)
    num //= common_factor
    den //= common_factor
    return (num, den)

product_num, product_den = multiply_fractions(a, b, c, d)

print(f'Собственная функция Сложение: {summa_fractions(a,b,c,d)}')
print(f"Собственная функция Произведение: {product_num}/{product_den}")


import random as rmd
import statistics as stc
import os
import time
import threading

os.system("cls")

def futasi_t(func):
    def wrapper(*args, **kwargs):
        kz_t = time.time()
        result = func(*args, **kwargs)
        vgz_t = time.time()
        print(f"Program futasi ido: {vgz_t - kz_t}")
    return wrapper
#oszály
class Main:
    def __init__(self, szamok) -> int:
        self.szamok = szamok

    @property
    @futasi_t
    def neg_min(self)->str:
        neg = 0
        poz = 0
        for s in self.szamok:
            if s < 0 and s != 0:
                neg += 1
            else:
                poz += 1
        #return f"Pozitiv számok száma: {poz} és negativ szamok szama: {neg}"
        print("-")
        print(f"Pozitiv számok száma: {poz} és negativ szamok szama: {neg}")

    @property
    @futasi_t
    def hets_szam(self):
        hetes = 0
        for s in self.szamok:
            if s == 7:
                hetes += 1
        #return f"Hetesek szama: {hetes}"
        print("-")
        print(f"Hetesek szama: {hetes}")

    @property
    @futasi_t
    def null_index(self):
        null_i = []
        for i, a in enumerate(self.szamok):
            if a == 0:
                null_i.append(i)
        print("-")
        print(f"A null értékű elemek indexei: {null_i}")

    @property
    @futasi_t
    def neg_avg(self):
        negs = []
        for s in self.szamok:
            if s<0:
                negs.append(s)
        atlag= stc.mean(negs)
        print("-")
        print(f"Negativ szamok átlaga {atlag}")

    @property
    @futasi_t
    def poz_min(self):
        """
        min = self.szamok[0]
        for s in self.szamok:
            if s>min & s>0:
                 min = s
        print("-")
        print(f"Pozitivok kozott a legkisebb {min}")
        """
        max_S = []
        for s in self.szamok:
            if s >0:
                max_S.append(s)
        print("-")
        print(f"Pozitiv kozott a legnagyobb {min(max_S)}")

    @property
    @futasi_t
    def max_neg(self):
        """
        max = self.szamok[0]
        for s in self.szamok:
            if s > max and s < 0 and s !=0:
                max = s
        print("-")
        print(f"Negativok kozott a legnagyobb {max}")
        """
        neg_S = []
        for s in self.szamok:
            if s <0:
                neg_S.append(s)
        print("-")
        print(f"Negativok kozott a legnagyobb {max(neg_S)}")

    def __str__(self):
        return f"{self.szamok}"

szamok = []
for i in range(28):
    szam = rmd.randint(-10, 10)
    szamok.append(szam)

os.system("cls")
if __name__ =="__main__":
    main = Main(szamok)
    print(main)
    t1 = threading.Thread(target=main.neg_min).start
    t2 = threading.Thread(target=main.hets_szam).start
    t3 = threading.Thread(target=main.null_index).start
    t4 = threading.Thread(target=main.neg_avg).start
    t5 = threading.Thread(target=main.poz_min).start
    t6 = threading.Thread(target=main.max_neg).start


import matplotlib
matplotlib.use("TkAgg")

import matplotlib.pyplot as plt

class PlotManager():
    def __init__(self, plotCount):
        self.off = False
        self.plots = {}

        self.plotCount = plotCount
        self.currentPlots = {}
        #plt.subplots_adjust(left=0.11, bottom=0.07, right=0.9, top=0.95, wspace=0.20, hspace=0.95)
        plt.ion()

    def addPlot(self, fig_title, axis_title, x_label, y_label, x, y, color='-r',
        x_limit=None, y_limit=None):
        if self.off: return
        if fig_title not in self.currentPlots:
            self.currentPlots[fig_title] = {
                'row':1,
                'column':1
            }

        fig = plt.figure(fig_title)
        ax  = fig.add_subplot(self.plotCount, 1, self.currentPlots[fig_title]['row'])
        #ax  = fig.add_subplot(211)
        ax.set_xlabel(x_label)
        ax.set_ylabel(y_label)
        ax.set_title(axis_title)
        if x_limit is not None:
            ax.set_xlim(*x_limit)
        if y_limit is not None:
            ax.set_ylim(*y_limit)
        ax.plot(x, y, color)

        self.currentPlots[fig_title]['row'] = self.currentPlots[fig_title]['row'] + 1

    def startPlot(self, fig_title, rows, columns, argsDict=None):
        if self.off: return
        figDict = {
            'num':fig_title,
            'edgecolor':'blue'
        }
        if argsDict is not None:
            argsDict = dict(figDict, **argsDict)
            fig, axis = plt.subplots(rows, columns, squeeze=False, **argsDict)
        else:
            fig, axis = plt.subplots(rows, columns, squeeze=False, **figDict)
        self.plots[fig_title] = {
            'figure':fig,
            'axis':axis,
            'rows': rows,
            'columns': columns,
            'cur_row' : 0,
            'cur_column' : 0
        }

    def addPlotN(self, fig_title, axis_title, x_label, y_label, x, y, color='-r',
        x_limit=None, y_limit=None):
        if self.off: return
        if fig_title not in self.plots:
            raise Exception("Need to call startplot before addplot")
        info = self.plots[fig_title]
        if info['cur_row'] >= info['rows'] or info['cur_column'] >= info['columns']:
            print(info)
            raise Exception("Exceeded specified plot row/columns")

        ax = info['axis'][info['cur_row'], info['cur_column']]

        info['cur_row'] = info['cur_row'] + 1
        if info['cur_row'] >= info['rows']:
            info['cur_row'] = 0
            info['cur_column'] = info['cur_column'] + 1

        ax.set_xlabel(x_label)
        ax.set_ylabel(y_label)
        ax.set_title(axis_title)
        if x_limit is not None:
            ax.set_xlim(*x_limit)
        if y_limit is not None:
            ax.set_ylim(*y_limit)
        ax.plot(x, y, color)

    def showPlots(self):
        if self.off: return
        plt.show()

    def reset(self, fig_title):
        if self.off: return
        fig = plt.figure(fig_title)
        plt.clf()
        self.currentPlots[fig_title] = {
            'row':1,
            'column':1
        }

    def TurnOff(self):
        self.off = True

if __name__ == "__main__":
    import numpy as np
    t = np.arange(1,30)
    y = np.arange(1,30) * 5
    PL = PlotManager(1)
    PL.addPlot("a", "t", "y", t, y)
    PL.showPlots()
    input('-')


import os, json, logging, boto3
from src.common.utils import Response
from src.handlers.RoomHandler import connect_to_room, disconnect_from_room, send_message_to_room, get_room_connections

dynamodb = boto3.resource('dynamodb')
logger = logging.getLogger("handler_logger")
logger.setLevel(logging.DEBUG)

# Notifications that server can send
CONNECTION_CONFIRMED = "CONNECTION_CONFIRMED"
CONNECTION_DISCONNECTED = "CONNECTION_DISCONNECTED"
NEW_BROADCAST_MESSAGE = "NEW_BROADCAST_MESSAGE"

# Socket action that server recieve
BROADCAST_MESSAGE = "BROADCAST_MESSAGE"
ECHO_MESSAGE = "ECHO_MESSAGE"

def connection_manager_api(event, context):
    """
    Handles connecting and disconnecting for the Websocket.
    """
    connectionId = event["requestContext"].get("connectionId")

    if event["requestContext"]["eventType"] == "CONNECT":
        logger.info("Connect requested")

        return Response(200, "Connect successful.")

    elif event["requestContext"]["eventType"] == "DISCONNECT":
        logger.info("Disconnect requested")

        roomId = get_connected_room(connectionId)
        remove_connection(connectionId)
        disconnect_from_room(connectionId, roomId)

        return Response(200, "Disconnect successful.")
    else:
        logger.error("Connection manager received unrecognized eventType.")
        return Response(500, "Unrecognized eventType.")

def connect_to_room_hanlder(event, context):
    body = event.get("body", "")
    data = json.loads(body)
    connectionId = event["requestContext"].get("connectionId")

    conenction_added_to_room = connect_to_room(connectionId, data["roomId"])
    conenction_saved = save_connection(connectionId, data["roomId"])

    _send_to_connection(connectionId, {
        "action" : CONNECTION_CONFIRMED,
        "data" : {
            "conenction_added_to_room" : conenction_added_to_room,
            "conenction_saved" : conenction_saved,
        }
    }, event)

    return Response(200, "Message echo-ed.")

def broadcast_message_hanlder(event, context):
    body = json.loads(event.get("body", ""))
    roomId = body["roomId"]
    message = body["message"]

    send_message_to_room(roomId, message)
    connections = get_room_connections(roomId)

    _send_to_connections(connections, {
        "action" : NEW_BROADCAST_MESSAGE,
        "data" : {
            "roomId" : roomId,
            "message" : {
                "message" : message,
            }
        }
    }, event)

    return Response(200, "Message echo-ed.")

def get_connected_room(connectionId):
    try:
        table = dynamodb.Table(os.environ['CONNECTION_TABLE_NAME'])
        response = table.get_item(
            Key = { 'id' : connectionId },
            AttributesToGet  = ["RoomID"]
        )
        return response["Item"]["RoomID"]
    except Exception as e:
        logger.info("Exception {}".format(e))
        return None

def remove_connection(connectionId):
    table = dynamodb.Table(os.environ['CONNECTION_TABLE_NAME'])
    table.delete_item(Key={ "id" : connectionId })

def save_connection(connectionId, roomId):
    try:
        # Add connectionId to the database
        table = dynamodb.Table(os.environ['CONNECTION_TABLE_NAME'])
        table.put_item(Item={
            "id" : connectionId,
            "RoomID" : roomId
        })
        return True
    except Exception as e:
        logger.info("Exception {}".format(e))
        return False

def echo_api(event, context):
    """
    When a message is sent on the socket, forward it to all connections.
    """
    logger.info("Message sent on WebSocket.")
    connectionId = event["requestContext"].get("connectionId")
    message = event.get("body", "")

    _send_to_connection(connectionId, message, event)

    return Response(200, "Message echo-ed.")

def _send_to_connection(connection_id, data, event):
    gatewayapi = boto3.client("apigatewaymanagementapi",
        endpoint_url = "https://" + event["requestContext"]["domainName"] + "/" + event["requestContext"]["stage"])

    return gatewayapi.post_to_connection(ConnectionId=connection_id, Data=json.dumps(data).encode('utf-8'))

def _send_to_connections(connections, data, event):
    for connection in connections:
        _send_to_connection(connection, data, event)


import hashlib
import json
import os
import pwd
import urllib

from django.utils.translation import ugettext_lazy as _

from dojango import forms
from madsonicUI.freenas import models, utils

class MadsonicForm(forms.ModelForm):

    class Meta:
        model = models.Madsonic
        widgets = {
            'madsonic_max_memory': forms.widgets.TextInput(),
            'madsonic_port': forms.widgets.TextInput(),
        }
        exclude = ('enable',)

    def __init__(self, *args, **kwargs):
        self.jail_path = kwargs.pop('jail_path')
        super(MadsonicForm, self).__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        obj = super(MadsonicForm, self).save(*args, **kwargs)

        rcconf = os.path.join(utils.madsonic_etc_path, "rc.conf")
        with open(rcconf, "w") as f:
            if obj.enable:
                f.write('madsonic_enable="YES"\n')

        conf_dir = os.path.join(utils.madsonic_etc_path, "madsonic")
        settingsfile = os.path.join(conf_dir, "config.ini")
        settings = {}

        for field in obj._meta.local_fields:
            if field.attname not in utils.madsonic_settings:
                continue
            info = utils.madsonic_settings.get(field.attname)
            value = getattr(obj, field.attname)
            _filter = info.get("filter")
            if _filter:
                settings[info.get("field")] = _filter(value)
            else:
                settings[info.get("field")] = value

        madsonic_ssl = str(obj.madsonic_ssl).lower()
        with open(settingsfile, 'w') as f:
            f.write('MADSONIC_MAX_MEMORY="%d"\n' % (obj.madsonic_max_memory, ))
            f.write('MADSONIC_SSL="%s"\n' % (madsonic_ssl, ))
            f.write('MADSONIC_PORT="%d"\n' % (obj.madsonic_port, ))
            f.write('MADSONIC_CONTEXT_PATH="%s"' % (obj.madsonic_context_path, ))

        os.system(os.path.join(utils.madsonic_pbi_path, "tweak-rcconf"))


def get_merge_files():
    len_dict = {}
    data_dict = {}

    with open('1.txt') as f:
        first_name = '1.txt'
        data_1 = f.readlines()
        data_dict[first_name] = data_1
        len_dict[first_name] = len(data_1)

    with open('2.txt') as f:
        second_name = '2.txt'
        data_2 = f.readlines()
        data_dict[second_name] = data_2
        len_dict[second_name] = len(data_2)

    with open('3.txt') as f:
        third_name = '3.txt'
        data_3 = f.readlines()
        data_dict[third_name] = data_3
        len_dict[third_name] = len(data_3)

    sorted_keys = sorted(len_dict, key=len_dict.get)
    sorted_dict = {}
    for i in sorted_keys:
        sorted_dict[i] = ''.join(data_dict[i])

    with open('result.txt', 'w+') as f:
        for item, v in sorted_dict.items():
            f.write(f'{item}\n{len_dict[item]}\n{sorted_dict[item]}\n')

get_merge_files()


# -*- coding: utf-8 -*-
# @Time    : 2020/3/16 0016 20:18
# @Author  : 王硕
# @Email   : ws2821@yeah.net
# @File    : demo02.py
# @Software: PyCharm
'''
随机密码生成。编写程序，在26个大、小写字母和10个数字组成的列表中随机生成1个密码，密码长度8位。
'''

import random as r

n = eval(input("请输入生成密码的位数:"))
ch = ''
for i in range(n):
    up = r.randint(65, 90)
    low = r.randint(97, 122)
    dic = r.randint(48, 57)
    tmp = r.randint(1, 3)
    if tmp == 1:
        ch += chr(up)
    elif tmp == 2:
        ch += chr(low)
    else:
        ch += chr(dic)
# .append([chr(j) for j in range(97, 122)], [(chr(k)) for k in range(48, 57)])


from turtle import Turtle

FONT = ("Courier", 20, "bold")

class Scoreboard(Turtle):

    def __init__(self):
        super().__init__()
        self.score = 1
        self.penup()
        self.hideturtle()
        self.goto(-280, 260)
        self.display_score()

    def display_score(self):
        self.write(f"Level:{self.score}", align='left', font=FONT)

    def increase_score(self):
        self.score += 1
        self.clear()
        self.write(f"Level:{self.score}", align='left', font=FONT)


import os

from sqlalchemy import create_engine
from sqlalchemy.types import BIGINT, NVARCHAR, DATETIME, DECIMAL, BOOLEAN, NUMERIC
from sqlalchemy.schema import CreateSchema

import pandas as pd
import numpy as np

#Define function to get column datatypes
def get_column_dtype(df):
    columntype_dict = {}

    #Get sql server datatype of each column
    for column in df:
        type = df[column].dtype
        sql_type = ''

        #Check if column is text
        if np.issubdtype(type,object):

            #Check text length
            max_len = df[column].astype(str).str.len().max()

            if max_len <= 50:
                sql_type = NVARCHAR(50)
            elif max_len <= 255:
                sql_type = NVARCHAR(255)
            else:
                sql_type = NVARCHAR

        #Check if column is int
        elif np.issubdtype(type,np.int64):
            sql_type = BIGINT

        #Check if column is decimal
        # elif np.issubdtype(type,float):
        #     sql_type= DECIMAL(12,2)
        # sql_type= NUMERIC(12,2)

        #Check if column is datetime
        elif np.issubdtype(type,np.datetime64):
            sql_type = DATETIME

        #Check if column is boolean
        elif np.issubdtype(type,np.bool_):
            sql_type = NVARCHAR(10)

        else:
            sql_type = NVARCHAR
        #Append column and sql datatype to dict
        columntype_dict[column] = sql_type
        # columntype_dict[column] = NVARCHAR

    return columntype_dict

# define function to read json, excel, or csv:
def file_to_df(filepath):
    filename, ext = os.path.splitext(os.path.basename(filepath))
    df = ''
    if ext == '.csv':
        df = pd.read_csv(filepath)
        print('Reading CSV')
    elif ext == '.json':
        df = pd.read_json(filepath)
        print('Reading JSON')
    elif ext == '.xlsx' or ext == '.xls':
        df = pd.read_excel(filepath)
        print('Reading Excel')
    else:pass
    return df

def import_table_to_sql(engine, df, table_name, schema):
    try:
        engine.execute(CreateSchema(schema))
        print(f"Created new schema: {schema}")
    except: pass
    try:
        type_dict = get_column_dtype(df)
        df.to_sql(
                table_name, engine, schema= schema
                ,if_exists = 'replace' , index = False
                ,chunksize= 1000
                ,dtype = type_dict
            )
        print(f"Successfully import data into {schema}.{table_name}")
    except Exception as e:
        print(f'Error {e}')

def import_files_to_sql(c_string, file_list:list):
    engine = create_engine(c_string, fast_executemany=True)
    #csv or json or excel
    for filepath in file_list:
        filename, ext = os.path.splitext(os.path.basename(filepath))

        table_name = filename

        schema = ext.replace('.', '')

        df_import = ''
        df_import = file_to_df(filepath)

        import_table_to_sql(engine, df_import, table_name, schema)

def import_folders_to_sql(c_string, folder_list:list):
    engine = create_engine(c_string, fast_executemany=True)
    for folderpath in folder_list:
        for file in os.listdir(folderpath):
            filepath = fr"{folderpath}\{file}"
            filename, ext = os.path.splitext(file)

            schema = ext.replace('.', '')

            df_import = ''

            try:
                df_import = file_to_df(filepath)
                if len(df_import) > 0:
                    table_name = filename
                    import_table_to_sql(engine, df_import, table_name, schema)
                else: pass
            except Exception as e:
                print(f'Error {e}')

def combine_and_import_folder_to_sql(c_string, folder_list:list):
    engine = create_engine(c_string, fast_executemany=True)
    for folder in folder_list:
        df_combine = pd.DataFrame([])
        for dirpath, dirs, files in os.walk(folder['directory']):
            if files != []:
                for file in files:
                    filepath = fr'{dirpath}\{file}'

                    df = ''
                    df = file_to_df(filepath)

                    df_combine = df_combine.append(df)

                    filename, ext = os.path.splitext(file)
                    schema = ext.replace('.', '')

        if len(df_combine) > 0:
            try:
                table_name = os.path.basename(folder)
                table_schema = schema
                import_table_to_sql(engine, df_combine, table_name, table_schema)

            except Exception as e:
                print(f'Error {e}')

        else: pass


'''Crie um código em python que teste se o site Pudim está acessível pelo computador usado'''
import urllib
import urllib.request
try:
    site = urllib.request.urlopen('http://www.pudim.com.br')
except:
    print('Deu erro!:( , não foi possível acessar o site no momento')
else:
    print('Tudo ok, Consegui acessar o site com Sucesso!! :)')
    #print(site.read) # acessa o conteudo do site lendo html


# 1.1 Is Unique: Implement an algorithm to determine if a string has all unique characters.
# What if you can't use additional data structures?
# Need to potentially check through the entire string in to find a character that may repeat: O(n) runtime

class Solution:

    def isUnique(string):
        unique_chars = []
        if len(string) > 128:   # ask if string is ASCII (128 characters) or UNICODE.
            return False
        for char in string:
            if char in unique_chars:
                return False
            else:
                unique_chars.append(char)
        return True


def prime(n):
     if n==2:
         return True
     for i in range(2,int(n**0.5)+1):
         if n%i==0:
             return False
     return True
n=int(input())
if n%2==0:
    for i in range(2,n):
         if prime(i)==True:
          for j in range(i,n):
             if i+j==n and prime(j)==True:
                 k=i
                 t=j
                 break
    print(n,"=",k,"+",t)
else:
    print("odd")