import asyncio
import logging
from typing import Iterable, List, NoReturn, Optional, Tuple

import a_sync
from brownie import ZERO_ADDRESS, chain
from brownie.exceptions import ContractNotFound
from multicall.utils import raise_if_exception_in

from y import ENVIRONMENT_VARIABLES as ENVS
from y import constants, convert
from y.classes.common import ERC20
from y.datatypes import AnyAddressType, Block, UsdPrice
from y.decorators import stuck_coro_debugger
from y.exceptions import NonStandardERC20, PriceError, yPriceMagicError
from y.prices import convex, one_to_one, popsicle, solidex, yearn
from y.prices.band import band
from y.prices.chainlink import chainlink
from y.prices.dex import mooniswap
from y.prices.dex.balancer import balancer_multiplexer
from y.prices.dex.genericamm import generic_amm
from y.prices.dex.uniswap import uniswap_multiplexer
from y.prices.dex.uniswap.uniswap import uniswap_multiplexer
from y.prices.dex.uniswap.v2 import UniswapV2Pool
from y.prices.eth_derivs import creth, wsteth
from y.prices.gearbox import gearbox
from y.prices.lending import ib
from y.prices.lending.aave import aave
from y.prices.lending.compound import compound
from y.prices.stable_swap import (belt, ellipsis, froyo, mstablefeederpool,
                                  saddle)
from y.prices.stable_swap.curve import CurvePool, curve
from y.prices.synthetix import synthetix
from y.prices.tokenized_fund import basketdao, gelato, piedao, tokensets
from y.prices.utils import ypriceapi
from y.prices.utils.buckets import check_bucket
from y.prices.utils.sense_check import _sense_check
from y.utils.dank_mids import dank_w3
from y.utils.logging import get_price_logger

@a_sync.a_sync(default='sync')
async def get_price(
    token_address: AnyAddressType,
    block: Optional[Block] = None,
    fail_to_None: bool = False,
    ignore_pools: Tuple[UniswapV2Pool, CurvePool] = (),
    silent: bool = False
    ) -> Optional[UsdPrice]:
    '''
    Don't pass an int like `123` into `token_address` please, that's just silly.
    - ypricemagic accepts ints to allow you to pass `y.get_price(0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e)`
        so you can save yourself some keystrokes while testing in a console
    - (as opposed to `y.get_price("0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e")`)

    When `get_price` is unable to find a price:
    - If `silent == True`, ypricemagic will print an error message using standard python logging
    - If `silent == False`, ypricemagic will not log any error
    - If `fail_to_None == True`, ypricemagic will return `None`
    - If `fail_to_None == False`, ypricemagic will raise a PriceError
    '''
    block = block or await dank_w3.eth.block_number
    token_address = convert.to_address(token_address)
    try:
        return await _get_price(token_address, block, fail_to_None=fail_to_None, ignore_pools=ignore_pools, silent=silent)
    except (ContractNotFound, NonStandardERC20, PriceError) as e:
        symbol = await ERC20(token_address, asynchronous=True).symbol
        if not fail_to_None:
            raise yPriceMagicError(e, token_address, block, symbol) from e

@a_sync.a_sync(default='sync')
async def get_prices(
    token_addresses: Iterable[AnyAddressType],
    block: Optional[Block] = None,
    fail_to_None: bool = False,
    silent: bool = False,
    ) -> List[Optional[float]]:
    '''
    A more optimized way to fetch prices for multiple assets at the same block.

    # NOTE silent kwarg is currently disabled.
    In every case:
    - if `silent == True`, tqdm will not be used
    - if `silent == False`, tqdm will be used

    When `get_prices` is unable to find a price:
    - if `fail_to_None == True`, ypricemagic will return `None` for that token
    - if `fail_to_None == False`, ypricemagic will raise a yPriceMagicError
    '''

    if block is None:
        block = chain.height

    prices = await asyncio.gather(
        *[
            get_price(convert.to_address(token), block, fail_to_None=fail_to_None, silent=silent, sync=False)
            for token in token_addresses
        ],
        return_exceptions=True
    )

    if not fail_to_None:
        raise_if_exception_in(prices)
    else:
        for p in prices:
            if isinstance(p, Exception) and not isinstance(p, PriceError):
                raise p
    return prices

@a_sync.a_sync(cache_type='memory', ram_cache_ttl=ENVS.CACHE_TTL)
@stuck_coro_debugger
async def _get_price(
    token: AnyAddressType,
    block: Block,
    fail_to_None: bool = False,
    ignore_pools: Tuple[UniswapV2Pool, CurvePool] = (),
    silent: bool = False
    ) -> Optional[UsdPrice]:  # sourcery skip: remove-redundant-if

    try:
        # We do this to cache the symbol for later, otherwise some repr woudl break
        symbol = await ERC20(token, asynchronous=True).symbol
    except NonStandardERC20:
        symbol = None

    logger = get_price_logger(token, block, 'magic')
    logger.debug('fetching price for %s', symbol)
    logger._debugger = asyncio.create_task(_debug_tsk(symbol, logger))

    # Helps to detect stuck code
    try:
        if token == ZERO_ADDRESS:
            _fail_appropriately(logger, symbol, fail_to_None=fail_to_None, silent=silent)
            logger._debugger.cancel()
            return None

        if ypriceapi.should_use and token not in ypriceapi.skip_tokens:
            price = await ypriceapi.get_price(token, block)
            logger.debug("ypriceapi -> %s", price)
            if price is not None:
                logger.debug("%s price: %s", symbol, price)
                logger._debugger.cancel()
                return price

        price = await _exit_early_for_known_tokens(token, block=block)
        logger.debug("early exit -> %s", price)
        if price is not None:
            await _sense_check(token, price)
            logger.debug("%s price: %s", symbol, price)
            logger._debugger.cancel()
            return price

        # TODO We need better logic to determine whether to use uniswap, curve, balancer. For now this works for all known cases.
        if price is None:
            dexes = [uniswap_multiplexer]
            if curve:
                dexes.append(curve)
            liquidity = await asyncio.gather(*[dex.check_liquidity(token, block, ignore_pools=ignore_pools, sync=False) for dex in dexes])
            depth_to_dex = dict(zip(liquidity, dexes))
            dexes_by_depth = {depth: depth_to_dex[depth] for depth in sorted(depth_to_dex, reverse=True)}
            for dex in dexes_by_depth.values():
                method = 'get_price_for_underlying' if hasattr(dex, 'get_price_for_underlying') else 'get_price'
                price = await getattr(dex, method)(token, block, ignore_pools=ignore_pools, sync=False)
                logger.debug("%s -> %s", dex, price)
                if price:
                    break

        # If price is 0, we can at least try to see if balancer gives us a price. If not, its probably a shitcoin.
        if price is None or price == 0:
            new_price = await balancer_multiplexer.get_price(token, block=block, sync=False)
            logger.debug("balancer -> %s", price)
            if new_price:
                logger.debug("replacing price %s with new price %s", price, new_price)
                price = new_price

        if price is None:
            _fail_appropriately(logger, symbol, fail_to_None=fail_to_None, silent=silent)
        if price:
            await _sense_check(token, price)

        logger.debug("%s price: %s", symbol, price)
        # Don't need this anymore
        logger._debugger.cancel()
        return price
    except Exception as e:
        logger._debugger.cancel()
        raise e

async def _exit_early_for_known_tokens(
    token_address: str,
    block: Block
    ) -> Optional[UsdPrice]:  # sourcery skip: low-code-quality

    bucket = await check_bucket(token_address, sync=False)

    price = None

    if bucket == 'atoken':                  price = await aave.get_price(token_address, block=block, sync=False)
    elif bucket == 'balancer pool':         price = await balancer_multiplexer.get_price(token_address, block, sync=False)
    elif bucket == 'basketdao':             price = await basketdao.get_price(token_address, block, sync=False)

    elif bucket == 'belt lp':               price = await belt.get_price(token_address, block, sync=False)
    elif bucket == 'chainlink and band':    price = await chainlink.get_price(token_address, block, sync=False) or await band.get_price(token_address, block, sync=False)
    elif bucket == 'chainlink feed':        price = await chainlink.get_price(token_address, block, sync=False)

    elif bucket == 'compound':              price = await compound.get_price(token_address, block=block, sync=False)
    elif bucket == 'convex':                price = await convex.get_price(token_address,block, sync=False)
    elif bucket == 'creth':                 price = await creth.get_price_creth(token_address, block, sync=False)

    elif bucket == 'curve lp':              price = await curve.get_price(token_address, block, sync=False)
    elif bucket == 'ellipsis lp':           price = await ellipsis.get_price(token_address, block=block, sync=False)
    elif bucket == 'froyo':                 price = await froyo.get_price(token_address, block=block, sync=False)

    elif bucket == 'gearbox':               price = await gearbox.get_price(token_address, block=block, sync=False)
    elif bucket == 'gelato':                price = await gelato.get_price(token_address, block=block, sync=False)
    elif bucket == 'generic amm':           price = await generic_amm.get_price(token_address, block=block, sync=False)

    elif bucket == 'ib token':              price = await ib.get_price(token_address, block=block, sync=False)
    elif bucket == 'mooniswap lp':          price = await mooniswap.get_pool_price(token_address, block=block, sync=False)
    elif bucket == 'mstable feeder pool':   price = await mstablefeederpool.get_price(token_address,block=block, sync=False)

    elif bucket == 'one to one':            price = await one_to_one.get_price(token_address, block, sync=False)
    elif bucket == 'piedao lp':             price = await piedao.get_price(token_address, block=block, sync=False)
    elif bucket == 'popsicle':              price = await popsicle.get_price(token_address, block=block, sync=False)

    elif bucket == 'saddle':                price = await saddle.get_price(token_address, block, sync=False)
    elif bucket == 'solidex':               price = await solidex.get_price(token_address, block, sync=False)
    elif bucket == 'stable usd':            price = 1

    elif bucket == 'synthetix':             price = await synthetix.get_price(token_address, block, sync=False)
    elif bucket == 'token set':             price = await tokensets.get_price(token_address, block=block, sync=False)
    elif bucket == 'uni or uni-like lp':    price = await UniswapV2Pool(token_address).get_price(block=block, sync=False)

    elif bucket == 'wrapped gas coin':      price = await get_price(constants.WRAPPED_GAS_COIN, block, sync=False)
    elif bucket == 'wrapped atoken v2':     price = await aave.get_price_wrapped_v2(token_address, block, sync=False)
    elif bucket == 'wrapped atoken v3':     price = await aave.get_price_wrapped_v3(token_address, block, sync=False)

    elif bucket == 'wsteth':                price = await wsteth.wsteth.get_price(block, sync=False)
    elif bucket == 'yearn or yearn-like':   price = await yearn.get_price(token_address, block, sync=False)

    return price

def _fail_appropriately(
    logger: logging.Logger,
    symbol: str,
    fail_to_None: bool = False,
    silent: bool = False
    ) -> None:
    '''
    dictates how `magic.get_price()` will handle failures

    when `get_price` is unable to find a price:
        if `silent == True`, ypricemagic will print an error message using standard python logging
        if `silent == False`, ypricemagic will not log any error
        if `fail_to_None == True`, ypricemagic will return `None`
        if `fail_to_None == False`, ypricemagic will raise a PriceError
    '''
    if not silent:
        logger.warning(f"failed to get price for {symbol}")

    if not fail_to_None:
        raise PriceError(logger, symbol)

async def _debug_tsk(symbol: str, logger: logging.Logger) -> NoReturn:
    """Prints a log every 1 minute until the creating coro returns"""
    while True:
        await asyncio.sleep(60)
        logger.debug("price still fetching for %s", symbol)


#!/usr/bin/env python

"""noreg-training.py: Solution to the second assignment (no regularization)."""
__author__      = "David Bertoldi"

import tensorflow as tf
import torch
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import pandas as pd
import os

from mlxtend.plotting import plot_decision_regions
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, MinMaxScaler, LabelEncoder
from sklearn.metrics import confusion_matrix
from mlxtend.plotting import plot_confusion_matrix
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, LeakyReLU, Input, GaussianNoise, Dropout
from tensorflow.keras.models import Model
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from keras.utils import np_utils
from tensorflow.keras.regularizers import L1, L2
from tensorflow.keras.optimizers import Adam, Nadam, SGD
from tensorflow.keras.initializers import HeNormal, HeUniform

BASE_URL = 'https://github.com/DBertazioli/multi-mnist_custom/raw/master/final_dataset/'
SEED = 42
np.random.seed(SEED)
tf.random.set_seed(SEED)
torch.manual_seed(SEED)

def load_data():
	X_train_path = tf.keras.utils.get_file('X_train.npz', BASE_URL + 'X_train.npz')
	y_train_path = tf.keras.utils.get_file('y_train.npz', BASE_URL + 'y_train.npz')
	X_test_path = tf.keras.utils.get_file('X_test.npz', BASE_URL + 'X_test.npz')
	y_test_path = tf.keras.utils.get_file('y_test.npz', BASE_URL + 'y_test.npz')
	with np.load(X_train_path) as X_train, np.load(y_train_path) as y_train, np.load(X_test_path) as X_test, np.load(y_test_path) as y_test:
		return X_train["arr_0"], y_train["arr_0"], X_test["arr_0"], y_test["arr_0"]

def build_model(input_shape, classes, activation, initializer):
	model = Sequential()
	model.add(Dense(80, activation = activation, kernel_initializer=initializer, input_shape=input_shape))
	model.add(Dense(70, activation = activation,  kernel_initializer=initializer))
	model.add(Dense(classes, activation = "softmax", kernel_initializer=initializer))
	return model

def start():
	X_train, y_train, X_test, y_test = load_data()

	# Separate the test data
	X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.20, random_state=SEED, shuffle=True, stratify = None)

	#scaling
	X_train = X_train.astype('float32') / 255.
	X_val = X_val.astype('float32') / 255.
	X_test = X_test.astype('float32') / 255.

	print(X_test[0].shape)

	#flattening
	X_train = X_train.reshape((X_train.shape[0], np.prod(X_train.shape[1:])))
	X_val = X_val.reshape((X_val.shape[0], np.prod(X_val.shape[1:])))
	X_test = X_test.reshape((X_test.shape[0], np.prod(X_test.shape[1:])))

	#one-hot encoding
	Y_train = np_utils.to_categorical(y_train-1)
	Y_val = np_utils.to_categorical(y_val-1)
	Y_test = np_utils.to_categorical(y_test-1)

	input_dims = np.prod(X_test.shape[1:]) #784
	nb_classes = Y_train.shape[1]

	# configurations
	activation = 'sigmoid'
	optimizer = Adam(learning_rate=1e-03)
	initializer = HeNormal(seed=SEED)
	loss = 'categorical_crossentropy'
	e = 50
	bs = 256

	# model definition
	model = build_model((input_dims,), nb_classes, activation, initializer)
	model.compile(optimizer=optimizer, loss=loss, metrics=['categorical_accuracy'])
	model.summary()

	# Checkpoints
	mcp_save_acc = ModelCheckpoint('./noreg/acc2.hdf5',
									save_best_only=True,
									monitor='val_categorical_accuracy',
									mode='max')
	mcp_save_loss = ModelCheckpoint('./noreg/loss2.hdf5',
									save_best_only=True,
									monitor='val_loss',
									mode='min')

	early_stopping = EarlyStopping(monitor='val_categorical_accuracy',
									patience=100,
									min_delta=0.005,
									mode='max',
									restore_best_weights=True,
									verbose=1)

	# training
	history = model.fit(X_train,Y_train,
						epochs=e,
						batch_size=bs,
						validation_data = (X_val, Y_val),
						callbacks = [mcp_save_acc, mcp_save_loss])

	# plot training & validation accuracy values
	plt.plot(history.history['categorical_accuracy'])
	plt.plot(history.history['val_categorical_accuracy'])
	plt.title('Model accuracy')
	plt.ylabel('Accuracy')
	plt.xlabel('Epoch')
	plt.legend(['Train', 'Test'], loc='upper left')
	plt.savefig(format('./images/noreg/accuracy-{}-{}-{}-{}-{}.png', activation, loss, optimizer, e, bs))

	plt.clf()

	# plot training & validation loss values
	plt.plot(history.history['loss'])
	plt.plot(history.history['val_loss'])
	plt.title('Model loss')
	plt.ylabel('Loss')
	plt.xlabel('Epoch')
	plt.legend(['Train', 'Test'], loc='upper right')
	plt.savefig(format('./images/noreg/loss-{}-{}-{}-{}-{}.png', activation, loss, optimizer, e, bs))

def format(s, activation, loss, optimizer, e, bs):
	return s.format(activation if isinstance(activation, str) else type(activation).__name__,
					loss,
					type(optimizer).__name__,
					e,
					bs)

if __name__ == '__main__':
	start()


def oddEvenPos(n):
    user = []      #Pos - 1 2 3 4 5 6 7 . . .
    oddPos = 0     #List [9 5 7 4 1 3 6 . . .]
    evenPos = 0    #Index 0 1 2 3 4 5 6 . . .
    for i in range(n):      #   ^^
        ele = int(input())  #   ||
        user.append(ele)    #see here

    for a in range(1, len(user),2):
        evenPos = evenPos + user[a]
    for b in range(0, len(user),2):
        oddPos = oddPos + user[b]

    print("Odd position sum: {}".format(oddPos))
    return "Even position sum: {}".format(evenPos)

if __name__ =='__main__':
    n = int(input())
    print(oddEvenPos(n))

#odd sum = 9+7+1+6 = 23
#even sum = 5+4+3 = 12


# 4'. Задана натуральная степень k. Сформировать случайным образом список коэффициентов (значения от 0 до 100) многочлена и записать в файл многочлен степени k.

# Пример:

# k=2 => 2*x*2 + 4*x + 5 = 0 или x2 + 5 = 0 или 10*x*2 = 0
# k=3 => 2*x*3 + 4*x*2 + 4*x + 5 = 0 5'. Даны два файла, в каждом из которых находится запись многочлена.

from numpy.random import randint

def polinom(k):

    poli = ''
    for i in range(k+1):
        poli += f'{randint(0,101)}*x**{i}'
        if i != k:
            poli += ' + '
        else:
            poli += ' = 0'

    return poli

print(polinom(5))


#!/usr/local/bin/python3

# Bereken verschil in helderheid tussen twee objecten op basis van magnitude.
# Hens Zimmerman, 01-05-2016.

import math
import sys

def controleer_versie():
    """Controleer of we wel met de juiste python werken"""
    if not sys.version_info >= (3,0):
        print("Je hebt minstens python 3 nodig voor dit script")
        exit()

def magnitude_input():
    """Vraag om een magnitude"""
    num_str = input("Magnitude van eerste object: ").strip()
    try:
        return float(num_str);
    except:
        print("Dat is geen nummer")
        exit()

controleer_versie()

magnitude1 = magnitude_input()
magnitude2 = magnitude_input()

mag1_diff = pow(100, 1 / 5)

ratio = math.pow(10.0, (magnitude1 - magnitude2) / -mag1_diff)

print("Object 1 (magnitude {0}) is {1:.8f} keer zo helder als object 2 (magnitude {2})".
    format(magnitude1, ratio, magnitude2))


class Solution:
    def applyOperation(self, num1, num2, op):
        if op == "+": return num1 + num2
        if op == "-": return num1 - num2
        if op == "/": return num1 // num2
        if op == "*": return num1 * num2

    def calculate(self, s: str) -> int:
        precedence = {"+": 1, "-": 1, "*": 2, "/": 2}
        values = []
        ops = []

        i = 0

        while i < len(s):
            char = s[i]
            if char == " ":
                i += 1
                continue
            elif char.isdigit():
                i += 1
                val = int(char)
                while i < len(s) and s[i].isdigit():
                    val = (val*10) + int(s[i])
                    i += 1
                i -= 1
                values.append(val)
            else:
                while ops and precedence[ops[-1]] >= precedence[char]:
                    val2 = values.pop()
                    val1 = values.pop()
                    op = ops.pop()
                    values.append(self.applyOperation(val1, val2, op))
                ops.append(char)

            i += 1

        while ops:
            val2 = values.pop()
            val1 = values.pop()
            op = ops.pop()
            values.append(self.applyOperation(val1, val2, op))

        return values[0]


import streamlit as st
from PIL import Image
import model

st.set_page_config(page_title="Aerial Drone segmentation")
st.title("Aerial Drone segmentation")

# Developer information
developers = [
    {"name": "Ahmed Adel", "linkedin": "https://www.linkedin.com/in/ahmed23adel/"},
    {"name": "Nour Elding Hammido", "linkedin": "https://www.linkedin.com/in/nourhamedo/"},
    {"name": "Jihad", "linkedin": "https://www.linkedin.com/in/jihad-mahmoud-5804ab18b/"}
]

# Display developer information with links in the sidebar
st.sidebar.markdown("Developed by:")
for developer in developers:
    st.sidebar.markdown(f"[{developer['name']}]({developer['linkedin']})")
st.text("Pick an example image")
examples_img_names = ("000", "001", "002", "003", "004", "005", "006")
image_example_name = st.selectbox("Example Image: ",examples_img_names)

def show_example_image(image_example_name = "000"):
    if image_example_name not in examples_img_names:
        raise Exception("Image not found")
    img_orig_url = r'imgs/{}_orig.jpg'.format(image_example_name)
    img_ground_truth_url = r'imgs/{}_groundTruth.jpg'.format(image_example_name)
    img_mask_pred_url = r'imgs/{}_maskPred.png'.format(image_example_name)
    img_orig = Image.open(img_orig_url)
    mask_ground_truth = Image.open(img_ground_truth_url)
    img_mask_pred = Image.open(img_mask_pred_url)
    st.text("Original image")
    st.image(img_orig, width=600)
    st.text("Mask image original")
    st.image(mask_ground_truth, width=600)
    st.text("Mask image predicted")
    st.image(img_mask_pred, width=600)
show_example_image(image_example_name)

st.header("Now it's time to try your image")
uploaded_file = st.file_uploader("Upload your image", type=["jpg", "png"])
if uploaded_file is not None:
    if uploaded_file.type.split('/')[1] in ['jpg', 'jpeg', 'png']:
        st.write("File uploaded successfully!")
        st.image(uploaded_file, caption='Uploaded Image', width=500)
        image = Image.open(uploaded_file)
        st.subheader('Model prediction')
        mask = model.predict_img(image)
        st.image(mask, caption='mask Image predicted', width=500)

st.header("Model details")
st.text("""
I used PyTorch lightning for this project

Model details:
We used DeepLabV3Plus and resnet34 for feature extraction,\n and for optimization I used Adam, and cross entropy loss.

DeepLabV3Plus:
""")

model_arch = Image.open(r'model_arch.png')
st.image(model_arch, caption='Model architecture', width=500)

st.text("""
I used albumentations for transforms, it generates sunny, rainy effect and many more

For metric i used Accurate, jaccard index(IOS)
""")

# st.image(img, width=600)


from setuptools import setup
from setuptools import find_packages
from setuptools import Extension
import numpy

with open("README.md", "r") as f:
    documentation = f.read()

setup(
    name         = 'CAMELS_library',
    version      = "0.3",
    author       = 'Francisco Villaescusa-Navarro',
    author_email = 'villaescusa.francisco@gmail.com',
    description  = "Python routines to analyze the data from the simulations of the Cosmology and Astrophysics with MachinE Learning Simulations (CAMELS) project",
    url          = "https://github.com/franciscovillaescusa/CAMELS",
    license      = 'MIT',
    long_description_content_type = "text/markdown",
    long_description = documentation,
    packages=find_packages(where="library/"),
    include_dirs=[numpy.get_include()],
    install_requires=['scipy', 'h5py', 'Pylians', 'tables'],
    package_dir={'':'library/'},
    py_modules=['camels_library']
)


# -*- coding: utf-8 -*-
"""
Created on Wed Aug 18 11:23:15 2021

@author: User
"""

class Employee:
    empno=0
    salary=0
    grade=''

    def __init__(self,a,b,c):
        self.empno=a
        self.salary=b
        self.grade=c
        print('Constructor called')

    def show(self):
        print(self.empno)
        print(self.salary)
        print(self.grade)
    def __del__(self):
        print('Bye..')

obj=Employee(101,40000,"A")
obj.show()


'''Importamos la función de la serie del fichero funciones.py'''
import funciones as fun

print("Numero natural de empiezo de la serie")
try:
    num = int(input())
    fun.serie(num)
except ValueError as e:
    print("No has introducido un valor adecuado")


# Load required libraries
import sys
import argparse
import cv2
import math
import os
import numpy as np

# Function to extract desired frames
def video2pic_py(pathIn, pathOut, fps):

    # # Testing
    # pathIn  = "/home/david/Schreibtisch/IMG_0020 genet test.MP4"
    # pathOut = "/home/david/Schreibtisch/Test"
    # fps     = 1

    # Identify original file name
    filename = os.path.basename(pathIn)
    filename = os.path.splitext(filename)[0]

    # Start video
    vidcap = cv2.VideoCapture(pathIn)

    # Get duration of the video in milliseconds
    frame = vidcap.get(cv2.CAP_PROP_FPS)
    count = vidcap.get(cv2.CAP_PROP_FRAME_COUNT)
    duration = count / frame * 1000

    # Read images
    success, image = vidcap.read()
    count          = 0
    # success        = True

    # Extract frames
    while success:

        time = count * (1 / fps) * 1000
        if time > duration:
            break

        # Set video to location of the n-th frame
        vidcap.set(cv2.CAP_PROP_POS_MSEC, time)

        # Read that image
        success, image = vidcap.read()
        if success:
        # print ("Read a new frame: ", success)
            cv2.imwrite(pathOut + "/" + filename + "_Frame_%d.JPG" % count, image)
        count = count + 1

# # Function call
# if __name__ == "__main__":
#     print("aba")
#     a = argparse.ArgumentParser()
#     a.add_argument("--pathIn", help = "path to video")
#     a.add_argument("--pathOut", help = "path to images")
#     a.add_argument("--fps", help = "frames per second", type = int, default = 1)
#     args = a.parse_args()
#     print(args)
#     extractImages(args.pathIn, args.pathOut, args.fps)


from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_moons
import matplotlib.pyplot as plt
import mglearn

# 데이터 로드
X, y = make_moons(n_samples=100, noise=0.25, random_state=3)
X_train, X_test, y_train, y_test = train_test_split(X,y,stratify=y,random_state=42)

# 모델 학습
model = RandomForestClassifier(n_estimators=5, random_state=0)
model.fit(X_train, y_train)
pre = model.predict([X[0]])
print('예측값: ', pre, '실제값: ', y[0])

# 결정 경계 시각화
# 다섯 개의 결정트리 결정 경계
fig, axes = plt.subplots(2, 3, figsize=(20,10) )
for i, (ax, tree) in enumerate( zip( axes.ravel(), model.estimators_ ) ):
    ax.set_title("tree {}".format(i) )
    mglearn.plots.plot_tree_partition(X, y, tree, ax=ax)

# 랜덤포레스트로 만들어진 결정경계
axes[-1, -1].set_title("Random forest")
mglearn.plots.plot_2d_separator(model, X, fill=True, alpha=0.5, ax=axes[-1,-1] )
mglearn.discrete_scatter(X[:,0], X[:,1], y)

plt.show()


from __future__ import annotations
from abc import ABC, abstractmethod
from time import time

class FailsafeSocket:
    def __init__(self) -> None:
        self.queue = []
        self.states = {
            "offline": Offline(self),
            "online": Online(self),
            "pending": Pending(self),
        }
        self.change_state("offline")

    def change_state(self, state):
        self.state = self.states[state]

    def send(self, data):
        self.state.send(data)

class AbstractState(ABC):
    @abstractmethod
    def send(self) -> None:
        pass

class Offline(AbstractState):
    def __init__(self, FailsafeSocket):
        self.socket = FailsafeSocket

    def send(self, data) -> None:
        print(f"{type(self).__name__} {data} not sent ")

class Pending(AbstractState):
    def __init__(self, FailsafeSocket):
        self.socket = FailsafeSocket

    def send(self, data) -> None:
        self.socket.queue.append(data)
        print(f"{type(self).__name__} data {data} added to queue: {self.socket.queue}")

class Online(AbstractState):
    def __init__(self, FailsafeSocket):
        self.socket = FailsafeSocket

    def send(self, data) -> None:
        if len(data) > 5:
            self.socket.change_state("offline")
            print(f"{type(self).__name__} too long data {data}, change to noline")
            self.socket.queue = []
        else:
            self.socket.queue.append(data)
            print(f"{type(self).__name__} sent data: {self.socket.queue}")
            self.socket.queue = []

# 상태가 ON/OFF 일때 context의 send에서 분기가 있는 것이 아니라 해당 상태 객체에 정의된 메서드에 의해 할일을 수행
# 상태가 여러개라고 가저한다면 if 선언문을 제거할수 있고
# 상태의 변경에는 닫혀있지만 상태 확장에는 열려있음

if __name__ == "__main__":
    socket = FailsafeSocket()
    socket.send("1")
    socket.send("2")
    socket.send("3")
    socket.change_state("pending")
    socket.send("4")
    socket.send("5")
    socket.send("6")
    socket.change_state("online")
    socket.send("7")
    socket.send("8")
    socket.send("9")
    socket.send("11111111")
    socket.send("1")

    # socket1 = FailsafeSocket()
    # socket1.send("1")
    # socket1.send("2")
    # socket1.send("3")
    # socket1.change_state("pending")
    # socket1.send("4")
    # socket1.send("5")
    # socket1.send("6")
    # socket1.change_state("online")
    # socket1.send("7")
    # socket1.send("8")
    # socket1.send("9")

    # print(socket1 == socket)  # false
    # print(socket.state.socket == socket1.state.socket)  # false


from base_model import BaseModel
from collections import namedtuple

from sklearn.ensemble import AdaBoostRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.preprocessing import OneHotEncoder

import pandas as pd

class AdaBoostModel(BaseModel):
    def __init__(self, name, features, model_params):
        super().__init__(name, features)
        self.model = AdaBoostRegressor(
            DecisionTreeRegressor(random_state=69), **model_params
        )
        self.ohc = OneHotEncoder(sparse=False)

    def fit(self, data, train_indices, target_name, fit_params):
        if len(self.cat_features) > 0:
            self.ohc.fit(data[self.cat_features])
            transformed = self.ohc.transform(data[self.cat_features])
            # Create a Pandas DataFrame of the hot encoded column
            ohe_df = pd.DataFrame(transformed, columns=self.ohc.get_feature_names_out())
            # concat with original data
            preprocessed_data = pd.concat([data, ohe_df], axis=1)
            self.preprocessed_feature_columns = list(
                self.ohc.get_feature_names_out()
            ) + list(self.continuous_features)

        else:
            preprocessed_data = data
            self.preprocessed_feature_columns = self.continuous_features

        train = preprocessed_data.iloc[train_indices]
        X_train = train[self.preprocessed_feature_columns]
        y_train = train[[target_name]]

        self.model.fit(
            X_train,
            y_train,
            **fit_params,
        )

    def predict(self, test_data):
        if len(self.cat_features) > 0:
            transformed_cat_data = self.ohc.transform(
                test_data[self.cat_features],
            )
            ohe_df = pd.DataFrame(
                transformed_cat_data, columns=self.ohc.get_feature_names_out()
            )
            preprocessed_data = pd.concat(
                [test_data.reset_index(drop=True), ohe_df.reset_index(drop=True)],
                axis=1,
            )
            X_test = preprocessed_data[self.preprocessed_feature_columns]
        else:
            X_test = test_data[self.preprocessed_feature_columns]

        return self.model.predict(X_test)

Feature = namedtuple("feature", "name categorical")

features = [
    Feature("current_runs", False),
    Feature("naive_projection", False),
    Feature("current_wickets", False),
    Feature("overall_ball_n", False),
    Feature("batter_current_runs", False),
    Feature("mean_encoded_batting_team", False),
    Feature("ten_wicket_prediction", False),
    Feature("lose_all_wickets", True),
    Feature("batter_won_toss", True),
]

adaboost_model = AdaBoostModel(
    "adaboost",
    features,
    {"n_estimators": 300, "loss": "exponential", "random_state": 69},
)


# _*_ coding: utf-8 _*_
__author__ = 'LelandYan'
__date__ = '2019/2/28 8:03'

# Bag-of-N-gram

import pandas as pd
import json
from sklearn.feature_extraction.text import CountVectorizer

X_test = ['I sed about sed the lack','of any Actually']
# stop=words=None 表示去掉停用词，若改为stop_words='english' 则去掉停用词
count_vec = CountVectorizer(stop_words=None)
# 稀疏矩阵的表示方式
print(count_vec.fit_transform(X_test))
# 表示的统计的词频结果
print(count_vec.fit_transform(X_test).toarray())

print("\nvocabulary list:\n\n",count_vec.vocabulary_)

# f = open("yelp_academic_dataset_review.json")
# js = []
# for i in range(1000):
#     js.append(json.loads(f.readline()))
# f.close()
#
# review_df = pd.DataFrame(js)
"""
(?u)放在前面表示对匹配中的大小写不明显
紧接着的\b"和末尾的"\b"表示匹配两个词语的间隔(可以简单的理解为空格)
中间的"\w"表示匹配一个字母或数字或下划线或汉字，紧接着的"\w+“表示匹配一个或者多个字母或数字或下划线或汉字
所以这个正则表达式就会忽略掉单个的字符，因为它不满足这个正则表达式的匹配，因此我们可以给他改为”(?u)\b\w+\b"，这样就不会忽略单个的字符。
"""
# ngram_range：tuple (min_n, max_n) 要提取的不同n-gram的n值范围的下边界和上边界。 将使用n的所有值，使得min_n <= n <= max_n
# bow_converter = CountVectorizer(token_pattern='(?u)\\b\\w+\\b')
# bigram_converter = CountVectorizer(ngram_range=(2,2), token_pattern='(?u)\\b\\w+\\b')
# trigram_converter = CountVectorizer(ngram_range=(3,3), token_pattern='(?u)\\b\\w+\\b')


import os

from custom import ssl_single_env
env = ssl_single_env.AntEnv(render_mode="human", xml_file=os.getcwd()+"/../robotics/onshape/ssl_bot.xml")

observation, info = env.reset()

for _ in range(1000):
    action = env.action_space.sample()  # agent policy that uses the observation and info
    observation, reward, terminated, truncated, info = env.step(action)

    if terminated or truncated:
        observation, info = env.reset()

env.close()


import pytest

@pytest.mark.last
def test_artificial_intelligence(game_instance):
    attacker = game_instance[-2]
    game_engine = game_instance[-1]

    spawn_list = attacker.spawn_information_list[0]

    game_engine.get_game_history().end_turn()
    game_engine.get_game_history().active_player.act()

    units = game_engine._GameEngine__player_units[game_engine.get_game_history().active_player]

    units_compare = [(x.position, x.object_type) for x in units]
    spawn_compare = [(x.position, x.object_type) for x in spawn_list]

    assert set(spawn_compare).issubset(set(units_compare))

    game_engine.get_game_history().end_turn()


import pandas
import pandas as pd
import seaborn as sns
from matplotlib import rcParams

# allow output to span multiple output lines in the console
pd.set_option('display.max_columns', 500)

# switch to seaborn default stylistic parameters
# see the useful https://seaborn.pydata.org/tutorial/aesthetics.html
sns.set()
sns.set_context('paper') # 'talk' for slightly larger

# change default plot size
rcParams['figure.figsize'] = 9,7

#1
df = pd.read_csv("https://raw.githubusercontent.com/grbruns/cst383/master/airquality.csv")

#2
print(df[:1])

#3
print(df.dtypes)

#4
print(df.isna().sum())
print(df.isna().mean())

#5
print(df.isna().sum().count())


from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords

import WriteInFIle

def remove_stopWord(Text):
    # geting lists of: total input wordslist, stopwords from the file.
    WordsList = word_tokenize(Text)
    File = open("stopwords.txt", "r", encoding="utf-8")
    for sw in File:
     StopWords = word_tokenize(sw)

    # a variable to store the stowords found
     StopsIn = []

    # looping over each word
     for word in WordsList:
        if word in StopWords:
            # if the word is consider as a stopword, we remove it from the input text
            WordsList.pop(WordsList.index(word))
            if word not in StopsIn:
                # if the word found hasn't being saved yet, we save it in StopsIn list
                StopsIn.append(word)

    # rewriting the text
    newText = ""
    for word in WordsList:
        newText = newText + " " + word

    # returning a dict of the new text and the list of stops
    return newText

"""InputFile = open("Cyber crimes textes normalisés/cc9_norm.txt", "r")
for line in InputFile:
 stop = remove_stopWord(line)
 length = len(stop.split())
 if length >= 3 and length <= 50:
     WriteInFIle.writeInFile("Cyber Crimes textes WSpW/cc9_WSpW.txt", stop, 1)"""


from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy, reverse
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import ListView, CreateView, DeleteView, UpdateView, TemplateView
from django.utils.translation import ugettext as __

from blogs.forms import BlogPostForm, BlogCategoryForm
from blogs.models import BlogPost, BlogCategory, BlogImage, Template, SiteBlogTemplate
from wresume.utils import SiteAwareView

class BlogPostsView(LoginRequiredMixin, SiteAwareView, ListView):
    template_name = 'blogs/manager/post-list.html'
    extra_context = {'is_blog_posts': True, 'nav_section': 'blog'}
    context_object_name = 'posts'
    paginate_by = 10

    def get_queryset(self):
        return BlogPost.objects.filter(site=self.get_site())

class BlogCategoriesView(LoginRequiredMixin, SiteAwareView, ListView):
    template_name = 'blogs/manager/categories.html'
    extra_context = {'is_categories': True, 'nav_section': 'blog'}
    context_object_name = 'categories'

    def get_queryset(self):
        return BlogCategory.objects.filter(site=self.get_site())

class BlogCategoryDeleteView(LoginRequiredMixin, SuccessMessageMixin, View):
    success_url = reverse_lazy('blogs_public:categories')

    def get_success_message(self, cleaned_data):
        return __('{} has been deleted successfully'.format(cleaned_data['category']))

    def get(self, request, **kwargs):
        cat = get_object_or_404(BlogCategory, pk=kwargs.get('pk'))
        cat.delete()
        messages.success(request, self.get_success_message({'category': cat.category}))
        return HttpResponseRedirect(self.success_url)

class WritePostView(LoginRequiredMixin, SuccessMessageMixin, SiteAwareView, CreateView):
    template_name = 'blogs/manager/write.html'
    extra_context = {'is_write': True, 'nav_section': 'blog'}
    form_class = BlogPostForm
    success_url = reverse_lazy('blogs_public:list')

    def get_form_kwargs(self):
        kwargs = super(WritePostView, self).get_form_kwargs()
        kwargs['site'] = self.get_site()
        return kwargs

    def get_initial(self):
        init = super(WritePostView, self).get_initial()
        init['author'] = self.request.user.id
        init['site'] = self.get_site().id
        return init

    def get_success_message(self, cleaned_data):
        return __('{} has been created'.format(cleaned_data['title']))

    def get_queryset(self):
        return BlogPost.objects.filter(site=self.get_site())

class EditPostView(WritePostView, UpdateView):
    extra_context = {'is_write': True, 'nav_section': 'blog', 'page_title': 'Update Post'}
    success_url = reverse_lazy('blogs_public:list')

    def get_success_message(self, cleaned_data):
        return __('{} has been edited successfully'.format(cleaned_data['title']))

class DeletePostView(EditPostView):
    def get(self, request, *args, **kwargs):
        self.get_object().delete()
        messages.success(request, 'Post has been removed successfully')
        return HttpResponseRedirect(request.GET.get('next', reverse('blogs_public:list')))

class CreateCategoryView(LoginRequiredMixin, SuccessMessageMixin, SiteAwareView, CreateView):
    template_name = 'blogs/manager/create-category.html'
    extra_context = {'is_create_category': True, 'nav_section': 'blog'}
    form_class = BlogCategoryForm
    success_url = reverse_lazy('blogs_public:create-categories')

    def get_initial(self):
        init = super(CreateCategoryView, self).get_initial()
        init['site'] = self.get_site().id
        return init

    def get_success_message(self, cleaned_data):
        return __('{} has been created'.format(cleaned_data['category']))

    def get_queryset(self):
        return BlogCategory.objects.filter(site=self.get_site())

class BlogTemplatesView(LoginRequiredMixin, SuccessMessageMixin, SiteAwareView, ListView):
    extra_context = {'is_templates_list': True, 'nav_section': 'blog'}
    queryset = Template.objects.all()
    template_name = 'blogs/manager/templates.html'
    context_object_name = 'templates'

class ActivateBlogTemplateView(LoginRequiredMixin, SuccessMessageMixin, SiteAwareView, View):
    def get(self, request, pk, *args, **kwargs):
        SiteBlogTemplate.objects.filter(client=self.get_site()).delete()
        SiteBlogTemplate.objects.create(template_id=pk, client=self.get_site())
        template = get_object_or_404(Template, pk=pk)
        messages.success(request, __('%(temp)s is now active for %(site)s') % {'temp': template.name,
                                                                               'site': self.get_site().domain_url})
        return HttpResponseRedirect(request.GET.get('next', reverse('blogs_public:template-list')))

class DeActivateBlogTemplateView(LoginRequiredMixin, SuccessMessageMixin, SiteAwareView, View):
    def get(self, request, pk, *args, **kwargs):
        SiteBlogTemplate.objects.filter(client=self.get_site()).delete()
        template = get_object_or_404(Template, pk=pk)
        messages.success(
            request, __('%(temp)s has been deactivated for %(site)s') % {'temp': template.name,
                                                                         'site': self.get_site().domain_url}
        )
        return HttpResponseRedirect(request.GET.get('next', reverse('blogs_public:template-list')))

@method_decorator(csrf_exempt, name='dispatch')
class HandleEditorUpload(View):
    def post(self, request, *args, **kwargs):
        file = request.FILES.getlist('file')[0]
        bi = BlogImage.objects.create(image=file)
        return JsonResponse({'location': bi.image.url})


#!/usr/bin/env python
import rospy
import time

from std_msgs.msg import String

import cv2
from cv_bridge import CvBridge, CvBridgeError

from acrv_apc_2017_perception.srv import rgbd_object_proposal, rgbd_object_proposalRequest

import os

if __name__ == "__main__":
    rospy.init_node('refinenet_test_script')
    cv_bridge = CvBridge()
    image_rect = cv2.imread('/home/apc/cloudstor/acrv_apc_2017_data/data_regenerated/tote/tote_mixed_20170509/img_00107/color_rect.png')
    # image_rect = cv2.imread(os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'src/refinenet/VOC_DATA/img_00047/color_rect.png')))
    image_rect_hd = cv2.imread('/home/apc/cloudstor/acrv_apc_2017_data/data_regenerated/tote/tote_mixed_20170509/img_00107/color_hd_rect.png')
    # image_rect_hd = cv2.imread(os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'src/refinenet/VOC_DATA/img_00047/color_hd_rect.png')))
    service = rospy.ServiceProxy('refinenet_classification', rgbd_object_proposal)

    labels = ['windex', 'mesh_cup', 'shower_curtain', 'scotch_sponges', 'harry_potter_dvd', 'band_aid_tape', 'black_fashion_gloves', 'utility_brush']
    # labels = ['hanes_socks', 'utility_brush']
    # labels = ['pie_plates', 'composition_book', 'epsom_salts']
    # labels = [
    #     'flashlight',
    #     'balloons',
    #     'dove_soap',
    #     'laugh_out_loud_jokes',
    #     'expo_eraser',
    #     'speed_stick',
    #     'duct_tape',
    #     'oral_b_toothbrush',
    #     'fiskars_scissors_red',
    #     'poland_spring_water',
    #     'irish_spring_soap',
    #     'pets_bowl',
    #     'cool_shot_glue_sticks',
    #     'band_aid_tape',
    #     'spoon_and_fork',
    #     'crayons',
    # ]
    expected_labels = []
    for label in labels:
        expected_labels.append(String(label))

    im_msg = cv_bridge.cv2_to_imgmsg(image_rect)
    im_msg_hd = cv_bridge.cv2_to_imgmsg(image_rect_hd)

    req = rgbd_object_proposalRequest()
    req.color = im_msg
    req.color_hd = im_msg_hd
    req.expected_labels = expected_labels

    start = time.time()
    res = service.call(req)
    end = time.time()
    print('Took ' + str(end - start))

    for i in res.label:
        print(i)
    image_res = cv_bridge.imgmsg_to_cv2(res.classification)
    overlay_img = cv_bridge.imgmsg_to_cv2(res.overlay_img)
    cv2.imshow('result', image_res)
    cv2.imshow('overlay', overlay_img)
    cv2.waitKey(0)


import numpy as np
from sal.core.object import build, DataObject, DataSummary
from sal.dataclass.signal.error import Error, ErrorSummary

"""
Adding Signal Dimensions Classes
--------------------------------

A new signal dimension is defined by extending Dimension and defining an associated
DimensionSummary class. The dimension class is then registered with the Signal class
using the register decorator found in the sal.dataclass.signal.subobject module:

    @register
    class MyNewDimension(Dimension):
        etc...

Concrete classes derived from Dimension must populate three class attributes:

    CLASS: A string that uniquely identifies the class to the Signal class.
    VERSION: An integer specifying the version of the dimension class.
    SUMMARY_CLASS: The summary class associated with the dimension class.

The string attribute CLASS must be lower-case and contain only alphanumeric characters,
'_', '-' and no whitespace. e.g. CLASS = 'signal'

VERSION must be an integer greater than zero. The version of a data class should be
incremented if the storage representation of the class changes. This ensures it is simple
for developers to identify different representations of a data class stored in the data
system.

The SUMMARY_CLASS attribute must be a reference to the DimensionSummary class returned by the
Dimension when summary() is called. e.g. SUMMARY_CLASS = MyNewDimensionSummary

The from_dict() and to_dict() methods must be implemented. To simplify development of
to_dict() a helper method _new_dict() is provided. The _new_dict() method will return a
dictionary pre-populated with the common dimension class metadata keys.
"""

# TODO: add tests

class Dimension(DataObject):
    """
    Abstract base class representing a signal dimension.

    Provides a common interface for Dimension classes.
    """

    GROUP = 'signal_dimension'

    def __init__(self, length, units=None, error=None, temporal=False, description=None):
        """
        :param length: The length of the dimension.
        :param error: An ErrorSummary object or None (default=None)
        :param units: A string describing the data units (default='au').
        :param temporal: True if the dimension is a timebase, False otherwise.
        :param description: A string describing the signal (default='A signal.').
        """

        # validate inputs
        units = units or 'au'
        units = str(units)

        description = description or 'A coordinate dimension.'
        description = str(description)

        length = int(length)
        if length < 1:
            raise ValueError('A dimension must have a length of at least one element.')
        self.length = length

        if error:

            if not isinstance(error, Error):
                raise TypeError('Error must be an object of class Error.')

            if not error.shape_compatible((length, )):
                raise ValueError('The supplied error is not consistent with the length of the dimension data.')

        self.error = error

        self.temporal = bool(temporal)
        self.units = units
        super().__init__(description)

    def __len__(self):
        return self.length

    def _new_dict(self):

        v = super()._new_dict()

        v.update({
            'description': self.description,
            'units': self.units,
            'length': np.uint64(self.length),
            'temporal': self.temporal,
            'error': None
        })

        if self.error:
            v['error'] = self.error.to_dict()

        return v

class DimensionSummary(DataSummary):
    """
    The summary class base class for Dimension classes.

    See the Dimension class for more information.
    """

    GROUP = 'signal_dimension'

    def __init__(self, length, units=None, error=None, temporal=False, description=None):
        """
        :param length: The length of the dimension.
        :param error: An ErrorSummary object or None (default=None)
        :param units: A string describing the data units (default='au').
        :param temporal: True if the dimension is a timebase, False otherwise.
        :param description: A string describing the signal (default='A signal.').
        """

        # validate inputs
        units = units or 'au'
        units = str(units)

        description = description or 'A coordinate dimension.'
        description = str(description)

        length = int(length)
        if length < 1:
            raise ValueError('A dimension must have a length of at least one element.')
        self.length = length

        if error:
            if not isinstance(error, ErrorSummary):
                raise TypeError('Error must be an object of class ErrorSummary.')
        self.error = error

        self.temporal = bool(temporal)
        self.units = units
        super().__init__(description)

    def to_dict(self):
        return self._new_dict()

    @classmethod
    def from_dict(cls, d):

        if not cls.is_compatible(d):
            raise ValueError('The dictionary does not contain a serialised array dimension class.')

        # unpack error if present
        error = d['error']
        if error:
            error = build(error)

        c = cls(
            length=d['length'],
            description=d['description'],
            units=d['units'],
            error=error,
            temporal=d['temporal']
        )

        return c

    def _new_dict(self):

        v = super()._new_dict()

        v.update({
            'units': self.units,
            'length': np.uint64(self.length),
            'temporal': self.temporal,
            'error': None
        })

        if self.error:
            v['error'] = self.error.to_dict()

        return v


from flask import Flask
import utils

app = Flask(__name__)

#Вывод на главную страницу"""
@app.route("/")
def page_index():

   message = utils.get_all()
   return f'''

{message}
'''

#Вывод на страницу кандидата по номеру
@app.route("/candidates/<int:pk>")
def page_candidate(pk):
   message = utils.get_by_pk(pk)
   return f'''

{message}
'''

#Вывод на странцицу кандидатов с навыками

@app.route("/skills/<skill>")
def page_skills(skill):
   message = utils.get_by_skill(skill)
   return f'''

{message}
'''

app.run()


#!/usr/bin/env python3
"""
Creation of the SessionExpAuth class to
set the expiration date of a session
"""

from api.v1.auth.session_auth import SessionAuth
from datetime import datetime, timedelta
from os import getenv

class SessionExpAuth(SessionAuth):
    """
    A class that implements the session
    duration
    """

    ENV = getenv("SESSION_DURATION")

    def __init__(self):
        """Initializer"""
        try:
            self.session_duration = int(self.ENV) if self.ENV else 0
        except ValueError:
            self.session_duration = 0

    def create_session(self, user_id=None) -> str:
        """Creates a new session by calling
        the Super class's create_session method
        """
        session_id = super().create_session(user_id)
        if session_id:
            session_dictionary = {
                "user_id": user_id,
                "created_at": datetime.now(),
            }
            self.user_id_by_session_id[session_id] = session_dictionary
            return session_id
        return None

    def user_id_for_session_id(self, session_id=None):
        """
        Overload the superclass implementation of this
        method
        """
        session_dict = self.user_id_by_session_id.get(session_id)
        if session_id and session_dict:
            if self.session_duration <= 0:
                return session_dict.get("user_id")
            if session_dict.get("created_at"):
                time_exp = session_dict.get("created_at") + timedelta(
                    seconds=self.session_duration
                )
                if time_exp >= datetime.now():
                    return session_dict.get("user_id")
            return None
        return None


import re
import requests
import sys

from bs4 import BeautifulSoup

def scrape_gradconnection(url):
    domain_name = re.sub(r'^(.+\.com).+$', r'\1', url)

    page = requests.get(url)

    #print(page.text)   # Prints Entire Webpage (Inspect Element)
    soup = BeautifulSoup(page.content, 'html.parser')

    job_elements = soup.find_all("div", class_='campaign-box')

    app_name_list = []
    company_list = []
    app_link_list = []
    deadline_list = []

    for job_element in job_elements:
        app_name = str(job_element.find('h3'))[4: -5]

        company = str(job_element.find('p', class_='box-header-para'))[27: -4]

        app_link = str(job_element.find('a', class_='box-header-title'))
        app_link = domain_name + re.sub(r'^.+href=\"(.+?)\".+$', r'\1', app_link)

        deadline = str(job_element.find('span', class_='closing-in closing-in-button'))[54: -7].capitalize()

        app_name_list.append(app_name)
        company_list.append(company)
        app_link_list.append(app_link)
        deadline_list.append(deadline)

        print(app_name)
        print(company)
        print(app_link)
        print(deadline, end="\n"*2)
    return(app_name_list,company_list,app_link_list,deadline_list)

def print_usage():
    print('usage:')
    print('python3 main.py')
    print('python3 main.py <field> <job_type>')
    print('python3 main.py <field> <job_type> <ordering>')
    print('<field>: {}'.format(', '.join(mapping['gradconnection']['field'].keys())))
    print('<job_type>: {}'.format(', '.join(mapping['gradconnection']['job_type'].keys())))
    print('<ordering>: {}'.format(', '.join(mapping['gradconnection']['ordering'].keys())))

    exit()

mapping = {
    'gradconnection': {
        'domain': 'https://au.gradconnection.com/',
        'field': {
            'business': 'business-and-commerce',
            'civil': 'engineering-civil-structural',
            'electrical': 'engineering-electrical',
            'mechanical': 'engineering-mechanical',
            'software': 'engineering-software',
            'structual': 'engineering-civil-structural',
        },
        'func': scrape_gradconnection,
        'ordering': {
            'closing': 'earliest_closing_date',
            'newest': '-recent_job_created'
        },
        'job_type': {
            'grad': 'graduate-jobs',
            'intern': 'internships',
        }
    },
}


import copy
import csv
import time
from datetime import datetime

import numpy as np
import itertools

import pandas as pd

from Program_files.data_read import loc_cat

# np.random.seed(1)

def weighted_selection(categories, probabilities):
    """
    Use the provided probabilities to select a category and a station
    :param categories: list of stations in the three categories
    :param probabilities: list of probabilities for each category
    :return: chosen station
    """
    cat_list = []
    prob_list = []
    chosen = 69

    # Fill up a  list of categories and probabilities
    for i in range(len(categories)):
        category = categories[i]
        if len(category) >= 1:
            cat_list.append(i)
            prob_list.append(probabilities[i])
    prob_list = np.array(prob_list)
    total_probability = np.sum(prob_list)
    random_number = np.random.uniform(0, total_probability)
    cumulative_prob = 0

    # Make a choice based on cumulative probability
    for i in range(len(prob_list)):
        probability = prob_list[i]
        cumulative_prob += probability
        if random_number <= cumulative_prob:
            chosen = cat_list[i]
    try:
        chosen_category = categories[chosen]
        random_station = np.random.randint(0, len(chosen_category))
        station = chosen_category[random_station]
    except IndexError:
        print("Failure!! Empty categories given to weighted selection function")

    return station

def location_hider(player, possible_locations, loc_cat=loc_cat):
    """
    Get a possible location of the player from a list of possible locations. These are split into 3 categories and a
    weighted selection is performed to determine one station where the player can be.
    :param player: the player entity
    :param possible_locations: the previous list of possible locations
    :param loc_cat: data about the types of categories and their probabilities based on location categorisation
    :return: possible location of the player
    """
    cat_1 = []  # Only taxis
    cat_2 = []  # bus + taxi
    cat_3 = []  # underground + taxi + bus
    for location in possible_locations:
        station_info = player.get_station_info(station=location)
        bus_con = station_info[2]
        underground_con = station_info[3]
        if underground_con != [0]:
            cat_3.append(location)
        elif bus_con != [0]:
            cat_2.append(location)
        else:
            cat_1.append(location)

    categories = [cat_1, cat_2, cat_3]
    probabilities = [loc_cat[0][0] / loc_cat[0][1], loc_cat[1][0] / loc_cat[1][1], loc_cat[2][0] / loc_cat[2][1]]
    location = weighted_selection(categories=categories, probabilities=probabilities)
    return location

def Arrange_seekers(seeker_list, player):
    """
    Creates a list of locations for the seekers to move to during the reveal round.
    :param seeker_list: list of seekers
    :param player: Player entity
    :return: list containing the list of locations to move to
    """
    probabilities = [0.3, 0.3, 0.4]
    seeker_positions = []
    for seeker in seeker_list:
        seeker_positions.append(seeker.position)

    target_locations = []
    categories = [[], [], []]
    all_moves = player.generate_nodes(
        station_list=[player.position])  # get all possible accesible station from current position
    station_list = []
    for move in all_moves:
        station = move[1]
        if station not in station_list:
            station_list.append(station)

    for station in station_list:  # Rank them based on the category
        station_info = player.get_station_info(station=station)
        if station_info[4] != [0]:
            categories[2].append(station)
        elif station_info[3] != [0]:
            categories[1].append(station)
        else:
            categories[0].append(station)

    # If you have more connections than seekers
    if len(station_list) > len(seeker_list):
        for i in range(len(seeker_list)):
            to_add = weighted_selection(categories=categories, probabilities=probabilities)
            target_locations.append(to_add)
            for category in categories:
                if to_add in category:
                    category.remove(to_add)

    # If you have fewer connections than seekers
    # Use weighted selection to add stations to the list
    elif len(station_list) < len(seeker_list):
        for i in range(len(station_list)):
            target_locations.append(station_list[i])
        difference = abs(len(station_list) - len(seeker_list))

        for i in range(difference):
            to_add = weighted_selection(categories=categories, probabilities=probabilities)
            target_locations.append(to_add)
    else:
        for i in range(len(station_list)):
            target_locations.append(station_list[i])

    difference_combinations = []
    for i in range(len(seeker_positions)):
        position = seeker_positions[i]
        buffer = []
        seeker = seeker_list[i]
        for location in target_locations:
            if seeker.minimise_distance(destination=location, node_list=None)[0] != 0:
                buffer.append(player.get_distance_difference(station_1=position, station_2=location))
            else:
                buffer.append(1000000)
        difference_combinations.append(buffer)
    difference_combinations = np.array(difference_combinations)

    best_score = 1E24
    best_combination = None
    combos = itertools.permutations(range(len(target_locations)), len(seeker_list))

    ## Use itertools to find the best combination that reduces the overall distance
    for combo in combos:
        if len(set(combo)) == len(seeker_list):
            score = sum(difference_combinations[i][combo[i]] for i in range(len(seeker_list)))
            if score < best_score:
                best_score = score
                best_combination = combo

    # If there is any error, choose the latest combination
    if best_combination is None:
        for combo in combos:
            best_combination = combo

    chosen_targets = []
    for i in range(len(seeker_list)):
        try:
            chosen_targets.append(target_locations[best_combination[i]])
        except TypeError:
            chosen_targets.append(target_locations[i])

    return chosen_targets

def randomise_start_locations(Info, number_seekers):
    """
    Allocate random locations to seekers and player
    :param Info: Information about the stations
    :param number_seekers: number of seekers in the game
    :return: list of starting locations for the seekers and player
    """
    start_index = np.random.randint(0, len(Info), number_seekers + 1)
    while (len(set(start_index))) != len(start_index):
        start_index = np.random.randint(0, len(Info), number_seekers + 1)
    start_locations = []
    for i in range(number_seekers + 1):
        start_locations.append(Info[start_index[i]][0])
    # start_locations = [Info[start_index[0]][0],Info[start_index[1]][0], Info[start_index[2]][0], Info[start_index[3]][0] ]
    return start_locations

def write_loc_cat_file(file_name, loc_cat=loc_cat):
    """
    Update the csv file containing the location categorisatrion data
    :param file_name: name of the csv file
    :param loc_cat: data about the location categorisation
    :return:
    """
    file = open(file_name, "w", newline="")
    data = [{"a": loc_cat[0][0], "n": loc_cat[0][1]},
            {"a": loc_cat[1][0], "n": loc_cat[1][1]},
            {"a": loc_cat[2][0], "n": loc_cat[2][1]}]
    header = ["a", "n"]
    writer = csv.DictWriter(file, fieldnames=header)
    writer.writeheader()
    writer.writerows(data)

    return 0

def write_data_file(file_name, alpha_normal, gamma_normal, alpha_reveal, gamma_reveal, C, W, Caught, comments, Rounds,
                    coverage):
    """
    Write to the results file
    :param file_name: name of the results file
    :param alpha_normal: The alpha used for normal rounds
    :param gamma_normal: The gamma used for the normal rounds
    :param alpha_reveal: The alpha used for reveal rounds
    :param gamma_reveal: The gamma used for reveal rounds
    :param C: value of C used
    :param W: value of W used
    :param Caught: Boolean value showing if the seekers caught the player
    :param comments: Information about this run
    :param Rounds: Number of rounds played
    :param coverage: the average coverage of the seekers
    """
    file = open(file_name, "r")
    lines = file.readlines()
    read_data = pd.DataFrame(
        columns=["Date", "Caught", "Rounds", "C", "W", "Alpha_normal", "Gamma_normal", "Alpha_reveal", "Gamma_reveal",
                 "Coverage", "Comments"])
    for line in lines:
        line = line[:-1]
        columns = line.split(",")
        columns = columns[1:]

        if columns[0] != "Date":
            read_data.loc[len(read_data)] = columns
    file.close()
    date = datetime.now().strftime("%d/%m/%Y")
    data_to_add = [date, Caught, Rounds, C, W, alpha_normal, gamma_normal, alpha_reveal, gamma_reveal, coverage,
                   comments]
    read_data.loc[len(read_data)] = data_to_add
    read_data.to_csv(file_name)

def write_q_file(file_name, Q_values):
    """
    Write to the csv file containing information about the q-values for all the nodes
    :param file_name: name of the file
    :param Q_values: list containing the q-values for all the nodes
    """
    Q_Values_df = pd.DataFrame(columns=["origin", "destination", "transport", "value"])
    for entry in Q_values:
        Q_Values_df.loc[len(Q_Values_df)] = entry
    Q_Values_df.to_csv(file_name)

def update_centralised_q_values(seekers, Q_values):
    """
    Get the average of the q-values for all the seekers. These values are then written to the csv file
    :param seekers: list of seekers
    :param Q_values: the list of Q-values to be updated
    :return: Updated list of q-values
    """
    individual_values = []
    for i in range(len(Q_values)):
        buffer = []
        for seeker in seekers:
            seeker_q = seeker.q_values
            buffer.append(seeker_q[i][3])
        individual_values.append(buffer)

    for i in range(len(individual_values)):
        average = np.average(individual_values[i])
        Q_values[i][3] = average
    return Q_values

def update_possible_location_list(possible_locations, Info, seekers, ticket, player):
    """
    Update the list of possible locations using the previous list of possible locations and the last played ticket
    :param possible_locations: original list of possible locations
    :param Info: data about all the stations
    :param seekers: list of seekers
    :param ticket: The last ticket played by the player
    :param player: the player entity
    :return: updated list of possible locations
    """
    loc_seekers = []

    # Add the last played ticket to the player's inventory
    # This makes sure that the generate_nodes function works properly
    player.tickets[ticket] += 1
    for seeker in seekers:
        loc_seekers.append(seeker.position)

    if possible_locations is None:
        ## Find every station reachable using the provided ticket if there is no original list of possible locations
        possible_locations = []
        Info_list = Info

        # If a taxi was sed then every location is possible
        if ticket == 2:
            for i in range(len(Info)):
                if Info[i][0] not in loc_seekers:
                    possible_locations.append(Info[i][0])

        else:
            for i in range(len(Info)):
                station = Info[i][0]
                bus_con = Info[i][2]
                underground_con = Info[i][3]
                taxi_con = Info[i][4]
                con = [bus_con, underground_con, taxi_con]
                if station not in loc_seekers:
                    for j in range(len(Info_list)):
                        check = False
                        target = Info_list[j][0]
                        if target in con[ticket]:
                            check = True
                        if check and target not in possible_locations and target not in loc_seekers:
                            possible_locations.append(target)
    else:
        new_list = []
        for i in range(0, len(possible_locations)):
            station = possible_locations[i]
            if station not in loc_seekers:
                nodes = player.generate_nodes([station])
                # Add the stations that can be reached from the previous station using the specific ticket to the updated list
                for node in nodes:
                    if node[1] not in new_list and node[2] == ticket and node[1] not in loc_seekers:
                        new_list.append(node[1])

        # Update the list
        if len(new_list) > 0:
            possible_locations = new_list

    # Remove any duplicates
    for station in loc_seekers:
        if station in possible_locations:
            possible_locations.remove(station)

    # Remove the previously added ticket
    player.tickets[ticket] -= 1
    return possible_locations

def Selection(seekers, leaf_nodes, C, W):
    """
    Perform UCT selection for the MCTS
    :param seekers: list of seekers
    :param leaf_nodes: list containing all the leaf nodes to select from
    :param C: value of C in the UCT equation
    :param W: value of W in the UCT equation
    :return: the index of the chosen node in the leaf nodes list, the chosen node and the agent this node belongs to
    """
    selection_scores = []
    agent_list = []
    index_list = []
    for i in range(len(leaf_nodes)):
        agent = leaf_nodes[i]
        for k in range(len(agent)):
            node = agent[k]
            if node != 0 and node != 1:
                # Only perform UCT on valid leaf nodes
                v_i = seekers[i].UCT(parent=node[0], child=node[1], transport=node[2], C=C, W=W,
                                     Q_values=seekers[i].q_values,
                                     Visits=seekers[i].visits)
                selection_scores.append(v_i)
                agent_list.append(i)
                index_list.append(k)
            else:
                selection_scores.append(-69)
                agent_list.append(i)
                index_list.append(k)

    # Choose the node with the greatest score
    chosen_leaf_node_index = np.argmax(np.array(selection_scores))
    chosen_agent = agent_list[chosen_leaf_node_index]
    chosen_index = index_list[chosen_leaf_node_index]
    chosen_node = leaf_nodes[chosen_agent][chosen_index]

    return chosen_index, chosen_node, chosen_agent

def Expansion(Dummy_seekers, agent, chosen_leaf_node_index, seeker):
    """
    Add a node to the leaf node for MCTS
    :param Dummy_seekers: list of states of the seekers
    :param agent: index of the seeker that this expansion is happening for
    :param chosen_leaf_node_index: index of the leaf node to expand
    :param seeker: the seeker that this expansion is happening for
    :return: all possible moves for this seeker for this game state
    """
    seeker_locations = []
    chosen_state = Dummy_seekers[agent][chosen_leaf_node_index]

    # Get the positions of all seeker sin this game state
    for state in chosen_state:
        seeker_locations.append(state.position)

    check = []
    expanded_nodes = seeker.generate_nodes(station_list=[seeker.position])

    # Remove already occupied nodes
    for node in expanded_nodes:
        if node[1] not in seeker_locations:
            check.append(node)
    expanded_nodes = check
    return expanded_nodes

def Simulation(seekers, player, chosen_move, agent, possible_location, Round, Round_limit, coalition_reduction):
    """
    Simulate the rest of the game for MCTS
    :param seekers: list of seekers
    :param player: the player entity
    :param chosen_move: the first move made for the seeker
    :param agent: the agent this simulation belongs to
    :param possible_location: the location being chased by the seekers
    :param Round: the round for this simulation
    :param Round_limit: the maximum number of rounds
    :param coalition_reduction: coefficient for the coalition reduction function
    :return: reward obtained after the simulation is terminated
    """
    Dummy_positions = []
    Dummies = []

    for seeker in seekers:
        # Create copies of the seekers
        # This prevents the simulation from affecting the position and ticket count of the real seekers
        Dummies.append(copy.deepcopy(seeker))
        Dummy_positions.append(seeker.position)

    reward = 0

    # Create a copy of the player entity
    Player_sim = copy.deepcopy(player)
    Player_sim.position = possible_location
    Player_sim.get_info()
    Dummies = np.array(Dummies)
    try:
        Player_sim.tickets[chosen_move[2]] += 1
    except TypeError:
        useless = 0  # This does nothing

    sim_running = True

    # Move all other seekers once
    for i in range(agent + 1, len(Dummies)):
        best_move, ticket_to_use = Dummies[i].minimise_distance(destination=possible_location,
                                                                exclude_stations=Dummy_positions, node_list=[])

        if best_move != 0:
            Dummies[i].move(destination=best_move, ticket=ticket_to_use)
            Dummy_positions[i] = best_move
            Player_sim.tickets[ticket_to_use] += 1

    # Check if the seekers caught the player after this move
    for i in range(len(Dummies)):
        if Player_sim.caught(Dummies[i]):
            sim_running = False
            if i == agent:
                reward += 2
            else:
                reward += (1 - coalition_reduction) * 2

    while sim_running:
        # THis keeps track of how many simulation rounds have happened
        counter = 1

        # Player's move
        player_moves = []
        distances = []
        for Dummy in Dummies:
            # Find out what the furthest station is for the player to move to for this dummy
            max_distance_target, transport = Player_sim.maximise_distance(target=Dummy.position,
                                                                          seeker_locs=Dummy_positions)
            if max_distance_target != 0:
                # Add this to a list of possible moves and their average distance
                player_moves.append([Player_sim.position, max_distance_target, transport])
                distances.append(
                    Player_sim.get_average_distance_difference(station_1=max_distance_target,
                                                               station_2_list=Dummy_positions))

        if len(player_moves) > 0:
            # Choose a move and move the player
            move_chosen = player_moves[np.argmax(np.array(distances))]
            Player_sim.move(destination=move_chosen[1], ticket=move_chosen[2], print_warning=True)
            possible_location = Player_sim.position

        # Seekers' move
        for i in range(len(Dummies)):
            # Move the seekers to minimise the distance between them and the player
            best_move, ticket_to_use = Dummies[i].minimise_distance(destination=possible_location,
                                                                    exclude_stations=Dummy_positions, node_list=[])
            if best_move != 0:
                Dummies[i].move(destination=best_move, ticket=ticket_to_use)
                Dummy_positions[i] = best_move
                Player_sim.tickets[ticket_to_use] += 1

            if Dummies[i].caught(Player_sim):
                sim_running = False
                if i == agent:
                    reward += 2
                else:
                    reward += (1 - coalition_reduction) * 2

        Round += 1
        counter += 1
        reward = reward / counter
        if Round > Round_limit:
            sim_running = False

    del Dummies
    del Player_sim

    return reward

def MCTS(seekers, player, Round, Round_limit, possible_location, N, C, W, r, alpha, gamma, location_list):
    """
    Run the MCTS algorithm for this location
    :param seekers: list of seekers
    :param player: player entity
    :param Round: the current round
    :param Round_limit: the maximum number of rounds
    :param possible_location: one possible location of the player
    :param N: Number of iterations for the MCTS
    :param C: value of C for the UCT
    :param W: value of W for the UCT
    :param r: value of the coalition reduction for the Simulation
    :param alpha: value of alpha for backpropagation
    :param gamma: value of gamma for backpropagation
    :return: list of moves for the seekers and the average q-value for these moves
    """
    ## Initialise ##
    start_time = time.time()
    counter = 0

    # Create a list of nodes, leaf nodes and q values
    nodes = [[]]
    expanded_node_list = [[]]
    leaf_nodes = [[]]
    q_values = [[]]
    q_value_indexes = []
    seeker_locations = []
    Dummy_seekers = []
    for seeker in seekers:
        seeker_locations.append(seeker.position)
    check = []
    node_list = seekers[0].generate_nodes(station_list=[seekers[0].position])
    for node in node_list:
        if node[1] not in seeker_locations:
            check.append(node)
    node_list = check
    leaf_nodes[0] = copy.deepcopy(node_list)
    nodes[0] = copy.deepcopy(node_list)
    node_values = seekers[0].generate_node_scores(node_list=node_list, Q_values=seekers[0].q_values)
    q_values[0] = node_values

    # Create a snapshot of the state of the seekers for each move to be used later
    buffer = []
    for node in leaf_nodes[0]:
        buffer.append([copy.deepcopy(seekers[0]), copy.deepcopy(seekers[1]), copy.deepcopy(seekers[2]),
                       copy.deepcopy(seekers[3])])
    Dummy_seekers.append(buffer)

    for i in range(1, len(seekers)):
        Dummy_seekers.append([])
        leaf_nodes.append([])
        q_value_indexes.append([])
        q_values.append([])
        nodes.append([])
        expanded_node_list.append([])

    for i in range(len(leaf_nodes[0])):
        leaf_nodes[1].append(1)
        Dummy_seekers[1].append(1)
        expanded_node_list[1].append(1)

    # Check what the index of the possible location is in the list
    for i in range(len(location_list)):
        location = location_list[i]
        if location == possible_location:
            location_index = i

    while counter < N:

        ## Selection ##
        chosen_leaf_node_index, chosen_node, agent = Selection(seekers=seekers,
                                                               leaf_nodes=leaf_nodes, C=C, W=W)

        # Get the current location to search
        loc_to_simulate = copy.deepcopy(possible_location)
        if agent == 0:

            seeker = seekers[agent]
            Dummies = Dummy_seekers[agent]
            # Advance the state of the particular seeker for this specific leaf node
            try:
                (Dummies[chosen_leaf_node_index][agent]).move(destination=chosen_node[1], ticket=chosen_node[2],
                                                              print_warning=True)
            except TypeError:
                useless = 0  # This does nothing

            ## Simulation ##

            reward = Simulation(seekers=Dummies[chosen_leaf_node_index], player=player, chosen_move=chosen_node,
                                agent=agent, possible_location=loc_to_simulate, Round=Round, Round_limit=Round_limit,
                                coalition_reduction=r)

            ## Backpropagation ##
            current_value = q_values[agent][chosen_leaf_node_index]
            updated_value = seeker.Q_value_update(current_value=current_value, alpha=alpha, gamma=gamma, reward=reward,
                                                  list_values=[])

            q_values[agent][chosen_leaf_node_index] = updated_value

            counter += 1

            # Mark this leaf node as fully explored
            leaf_nodes[agent][chosen_leaf_node_index] = 0

            # Add leaf nodes for the next seeker to expand on
            leaf_nodes[agent + 1][chosen_leaf_node_index] = chosen_node
            # leaf_nodes[agent + 1].append(chosen_node)
            Dummy_seekers[agent + 1][chosen_leaf_node_index] = copy.deepcopy(Dummies[chosen_leaf_node_index])
            expanded_node_list[agent + 1][chosen_leaf_node_index] = []

        elif len(leaf_nodes[agent]) > 0 and agent <= len(seekers):
            Dummies = Dummy_seekers[agent]
            seeker = seekers[agent]

            ## Expansion ##
            expanded_nodes = Expansion(Dummy_seekers=Dummy_seekers, agent=agent,
                                       chosen_leaf_node_index=chosen_leaf_node_index, seeker=seeker)

            current_index = 0

            # Add a failsafe in case seeker is blocked on all sides
            if len(expanded_nodes) == 0:
                expanded_nodes.append(1)

            for i in range(len(expanded_nodes)):
                sim_node = expanded_nodes[i]

                # Choose a previously unchosen node and that becomes the expanded node
                if sim_node not in expanded_node_list[agent][chosen_leaf_node_index]:
                    # Add this to the list of nodes
                    nodes[agent].append(sim_node)
                    q_value_indexes[agent - 1].append(chosen_leaf_node_index)
                    try:
                        (Dummies[chosen_leaf_node_index][agent]).move(destination=sim_node[1], ticket=sim_node[2],
                                                                      print_warning=True)
                    except TypeError:
                        useless = 0  # This does nothing

                    # Add this to the expanded node list so it can not be chosen for this state again
                    expanded_node_list[agent][chosen_leaf_node_index].append(sim_node)

                    ## Simulation ##
                    # Check if a previous seeker is already at the possible target location
                    # If so, change the target location for better coverage

                    for i in range(len(Dummies[chosen_leaf_node_index])):
                        dummy = Dummies[chosen_leaf_node_index][i]
                        if dummy.position == loc_to_simulate and agent != i:
                            try:
                                loc_to_simulate = location_list[location_index + 1]
                                # print("changed location from %s to %s"%(possible_location,loc_to_simulate))
                            except IndexError:
                                loc_to_simulate = location_list[0]
                                # print("changed location from %s to %s" % (possible_location, loc_to_simulate))

                    reward = Simulation(seekers=Dummies[chosen_leaf_node_index], player=player, chosen_move=sim_node,
                                        agent=agent, possible_location=loc_to_simulate, Round=Round,
                                        Round_limit=Round_limit,
                                        coalition_reduction=r)
                    current_index = len(nodes[agent]) - 1

                    break

            ## Backpropagation ##
            try:
                current_value = seeker.get_Q_value(node=sim_node, Q_values=seeker.q_values)
                seeker.Update_visit_count(position=sim_node[1], Visits=seeker.visits)
                q_values[agent].append(current_value)
            except TypeError:
                # Only happens if a seeker is blocked on all sides
                q_values[agent].append(-10)

            # Create a path used by the q-value update function
            path = [current_index]  # Path of q_values indexes
            chosen_index = current_index
            path_values = []

            for k in reversed(range(0, agent)):
                try:
                    # Find the corresponding index in the data for the previous seeker
                    node_number = q_value_indexes[k][chosen_index]
                    path.append(node_number)
                    chosen_index = node_number
                except IndexError:
                    useless = 0  # This does nothing
            path.reverse()

            for j in range(len(path)):
                node_to_choose = path[j]
                value = q_values[j][node_to_choose]
                # Add the corresponding q-values to a list
                path_values.append(value)

            for j in range(len(path)):
                # update all the q-values in the path
                current_value = path_values[j]
                future_values = path_values[j:]
                updated_value = seekers[j].Q_value_update(current_value=current_value, alpha=alpha, gamma=gamma,
                                                          reward=reward,
                                                          list_values=future_values)
                path_values[j] = updated_value
                q_values[j][path[j]] = updated_value

            counter += 1

            if agent < len(seekers) - 1:
                # Add the chosen node as a new leaf node
                leaf_nodes[agent + 1].append(sim_node)
                # Add the updated state for the next node
                Dummy_seekers[agent + 1].append(copy.deepcopy(Dummies[chosen_leaf_node_index]))
                # Add this node to the list of nodes explored for this particular leaf node
                # This helps keep track of whether or not this leaf node is fully explored
                expanded_node_list[agent + 1].append([])

            # Undo the move made for the Simulation which updated the state
            try:
                Dummies[chosen_leaf_node_index][agent].position = sim_node[0]
                Dummies[chosen_leaf_node_index][agent].get_info()
                Dummies[chosen_leaf_node_index][agent].tickets[sim_node[2]] += 1
            except TypeError:
                useless = 0  # This does nothing

            # Remove fully explored leaf nodes
            check_sum = 0
            for node in expanded_nodes:
                if node in expanded_node_list[agent][chosen_leaf_node_index]:
                    check_sum += 1
            if check_sum == len(expanded_nodes):
                leaf_nodes[agent][chosen_leaf_node_index] = 0

        # Check if all nodes are explored
        all_done = []
        for seeker in seekers:
            all_done.append(0)
        for i in range(len(leaf_nodes)):
            node_list = leaf_nodes[i]
            length = len(node_list)
            check_sum = 0
            for node in node_list:
                if node == 0 or node == 1:
                    check_sum += 1
            if check_sum == length:
                all_done[i] = 1
        all_done = np.array(all_done)
        if np.sum(all_done) == len(seekers):
            counter = N + 42

    # Create a list of values to be checked
    final_values = q_values[0]
    chosen_index = np.argmax(final_values)
    path = [chosen_index]

    for i in range(0, len(q_value_indexes)):
        buffer = []
        buffer_index = []
        list = q_value_indexes[i]

        for k in range(len(list)):
            entry = list[k]
            if entry == chosen_index:
                buffer.append(q_values[i + 1][k])
                buffer_index.append(k)
        try:
            chosen_index = buffer_index[np.argmax(buffer)]
        except ValueError:
            # This only happens if no node is explored for this particular agent
            # Thus a random move for this agent is chosen
            nodes[i + 1] = seekers[i + 1].generate_nodes(station_list=[seekers[i + 1].position])
            chosen_index = np.random.randint(0, len(nodes[i + 1]))

        path.append(chosen_index)

    chosen_node = []
    chosen_q = []

    # Choose the list of moves with the highest q-values
    for i in range(len(path)):
        chosen_node.append(nodes[i][path[i]])
        try:
            chosen_q.append(q_values[i][path[i]])
        except IndexError:
            sub_value = seekers[i].get_Q_value(node=nodes[i][path[i]], Q_values=seekers[i].q_values)
            chosen_q.append(sub_value)

    average = np.average(chosen_q)
    end_time = time.time()
    del Dummy_seekers
    return chosen_node, average


#!/usr/bin/env python
import cv2
import numpy as np

distCoeffs = np.zeros((5), dtype=np.float)
print(distCoeffs)

def do_process():
    src = cv2.imread('yolo3.png')
    print('shape: ', src.shape)
    height,width,channel = src.shape
    center = np.array([int(width/2.0), int(height/2.0)])
    print(center)
    # find red markers in horizontal band and vertical band
    # horizontal band
    # the start point is left-up corner of cropped image
    hori_left_start = int(center[0]-height/5.0)
    verti_up_start = int(center[0]-width/5.0)
    hori_left_band = src[int(center[0]-height/5.0):int(center[0]+height/5.0), 10:int(width/2.0)]
    hori_right_band = src[int(center[0]-height/5.0):int(center[0]+height/5.0), int(width/2.0):width-10]
    verti_up_band = src[10:int(height/2.0) , int(center[0]-width/5.0):int(center[0]+width/5.0)]
    verti_down_band = src[int(height/2.0):height-10 , int(center[0]-width/5.0):int(center[0]+width/5.0)]
    # cv2.imshow('hori_left_band',hori_left_band)
    # cv2.imshow('hori_right_band',hori_right_band)
    # cv2.imshow('verti_up_band',verti_up_band)
    # cv2.imshow('verti_down_band',verti_down_band)

    hori_left_hsv = cv2.cvtColor(hori_left_band,cv2.COLOR_BGR2HSV)
    hori_right_hsv = cv2.cvtColor(hori_right_band,cv2.COLOR_BGR2HSV)
    verti_up_hsv = cv2.cvtColor(verti_up_band,cv2.COLOR_BGR2HSV)
    verti_down_hsv = cv2.cvtColor(verti_down_band,cv2.COLOR_BGR2HSV)
    hori_lower_hsv = np.array([0,50,50])
    hori_upper_hsv = np.array([30,255,255])
    verti_lower_hsv = np.array([0,50,50])
    verti_upper_hsv = np.array([100,255,255])

    hori_left_mask = cv2.inRange(hori_left_hsv, hori_lower_hsv, hori_upper_hsv)
    hori_right_mask = cv2.inRange(hori_right_hsv, hori_lower_hsv, hori_upper_hsv)
    verti_up_mask = cv2.inRange(verti_up_hsv, verti_lower_hsv, verti_upper_hsv)
    verti_down_mask = cv2.inRange(verti_down_hsv, verti_lower_hsv, verti_upper_hsv)
    # cv2.imshow('hori_left_mask', hori_left_mask)
    # cv2.imshow('hori_right_mask', hori_right_mask)
    # cv2.imshow('verti_up_mask', verti_up_mask)
    # cv2.imshow('verti_down_mask', verti_down_mask)

    #(B,G,R)=cv2.split(src)
    #sub_BR = cv2.subtract(B,R)
    #cv2.imshow('R',R)
    #cv2.imshow('G',G)
    #cv2.imshow('B',B) # use blue
    #cv2.imshow('sub_BR',sub_BR)
    # B = cv2.threshold(B,150,255,cv2.THRESH_BINARY)[1]
    # B = cv2.threshold(B,150,255,cv2.THRESH_BINARY)[1]
    # B = cv2.threshold(B,120,255,cv2.THRESH_BINARY)[1] # good external contours
    # B = cv2.threshold(B,100,255,cv2.THRESH_BINARY)[1] # good 1 internal circles
    #B = cv2.threshold(B,80,255,cv2.THRESH_BINARY)[1] # good 2 internal circles
    #B = cv2.threshold(B,70,255,cv2.THRESH_BINARY)[1] # not see internal circles
    #cv2.imshow('B_threshold',B)
    #contours, hierarchy = cv2.findContours(B,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    #contours, hierarchy = cv2.findContours(B,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
    # erode and dilate
    erode_kernel = np.ones((2, 2), np.uint8)
    hori_left_erosion = cv2.erode(hori_left_mask, erode_kernel, iterations=1)
    hori_right_erosion = cv2.erode(hori_right_mask, erode_kernel, iterations=1)
    verti_up_erosion = cv2.erode(verti_up_mask, erode_kernel, iterations=1)
    verti_down_erosion = cv2.erode(verti_down_mask, erode_kernel, iterations=1)
    #cv2.imshow('hori_erosion', hori_erosion)
    #cv2.imshow('verti_erosion', verti_erosion)

    dilate_kernel = np.ones((5, 5), np.uint8)
    hori_left_dilate = cv2.dilate(hori_left_erosion, dilate_kernel, iterations=1)
    hori_right_dilate = cv2.dilate(hori_right_erosion, dilate_kernel, iterations=1)
    verti_up_dilate = cv2.dilate(verti_up_erosion, dilate_kernel, iterations=1)
    verti_down_dilate = cv2.dilate(verti_down_erosion, dilate_kernel, iterations=1)
    # cv2.imshow('hori_left_dilate', hori_left_dilate)
    # cv2.imshow('hori_right_dilate', hori_right_dilate)
    # cv2.imshow('verti_up_dilate', verti_up_dilate)
    # cv2.imshow('verti_down_dilate', verti_down_dilate)

    # find contours
    hori_left_contours,hereachy= cv2.findContours(hori_left_dilate,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
    hori_right_contours,hereachy= cv2.findContours(hori_right_dilate,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
    print(len(hori_left_contours))
    print(len(hori_right_contours))

    cv2.drawContours(hori_left_band,hori_left_contours,-1,(0,255,255), thickness=1 )
    cv2.imshow('hori_left_contours',hori_left_band)
    cv2.drawContours(hori_right_band,hori_right_contours,-1,(0,255,255), thickness=1 )
    cv2.imshow('hori_right_contours',hori_right_band)

    verti_up_contours,hereachy = cv2.findContours(verti_up_dilate,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
    verti_down_contours,hereachy = cv2.findContours(verti_down_dilate,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
    print(len(verti_up_contours))
    print(len(verti_down_contours))
    cv2.drawContours(verti_up_band,verti_up_contours,-1,(0,255,255), thickness=1 )
    cv2.imshow('verti_up_contours',verti_up_band)
    cv2.drawContours(verti_down_band,verti_down_contours,-1,(0,255,255), thickness=1 )
    cv2.imshow('verti_down_contours',verti_down_band)

    #for i in hori_contours:

    cv2.waitKey(0)

if __name__ =="__main__":
    do_process()


grid = [list(l.strip()) for l in open("input/day12.txt").readlines()]
moves = [(1, 0), (-1, 0), (0, 1), (0, -1)]
test_grid = [list("Sabqponm"), list("abcryxxl"), list(
    "accszExk"), list("acctuvwj"), list("abdefghi")]

def find_start_end_letter(grid, letter):
    start, end, letters = None, None, list()
    for y in range(len(grid)):
        for x in range(len(grid[y])):
            if grid[y][x] == "S":
                start = (x, y)
                grid[y][x] = "a"
            if grid[y][x] == "E":
                end = (x, y)
                grid[y][x] = "z"
            if grid[y][x] == letter:
                letters.append((x, y))
    return start, end, letters, grid

def valid_move(a, b, grid, part):
    x1, y1 = a
    new_x, new_y = b
    if 0 <= new_x < len(grid[0]) and 0 <= new_y < len(grid):
        start_letter = grid[y1][x1]
        destination_letter = grid[new_y][new_x]
        if part == 1:
            return True if ord(destination_letter) - ord(start_letter) < 2 else False
        if part == 2:
            return True if ord(start_letter) - ord(destination_letter) < 2 else False
    return False

def find_shortest_length(grid, start, end, part):
    start_x, start_y = start
    length = 0
    visited = set()
    queue = list()
    queue.append((start_x, start_y, 0))
    while queue:
        x, y, length = queue.pop(0)
        if (x, y) == end or (x, y) in end:
            return length
        visited.add((x, y))
        for move in moves:
            move_x, move_y = move
            new_x, new_y = x + move_x, y + move_y
            if (x, y, length) not in queue:
                if (new_x, new_y) not in visited:
                    if valid_move((x, y), (new_x, new_y), grid, part):
                        queue.append((new_x, new_y, length + 1))
    return -1

# Test
# start, end, letters, grid = find_start_end_letter(test_grid, 'a')
start, end, letters, grid = find_start_end_letter(grid, 'a')

# part 1
print(find_shortest_length(grid, start, end, 1))

# part 2
print(find_shortest_length(grid, end, letters, 2))


# This problem was asked by Uber.
#
# Given an array of integers, return a new array such that each element at index i of
# the new array is the product of all the numbers in the original array except the one at i.
#
# For example, if our input was [1, 2, 3, 4, 5], the expected output would be [120, 60, 40, 30, 24].
# If our input was [3, 2, 1], the expected output would be [2, 3, 6]

import numpy as np
from functools import reduce

# using numpy
def arrayMultiplication(numbers):
    product = np.prod(numbers)
    return [product//i for i in numbers]

# by reduce
def arrayMultiplicationUsingResuce(numbers):
    product = reduce((lambda x,y:x*y), numbers)
    return [product//i for i in numbers]

if __name__ == "__main__":
    input = [1, 2, 3, 4, 5]
    print(arrayMultiplication(input))
    print(arrayMultiplicationUsingResuce(input))


#!/usr/bin/env python

# read a mongodb oplog, translate oplog entries to pymongo calls on another mongodb or tokumx database

import sys
import re
import time
from pymongo import MongoClient
import bson

def main():
    ts = None
    fromhost = 'localhost:33000'
    tohost = 'localhost:55000'
    verbose = 0;
    for arg in sys.argv[1:]:
        if arg == '--verbose':
            verbose += 1
            continue
        match = re.match("--ts=(.*):(.*)", arg)
        if match:
            ts = bson.Timestamp(int(match.group(1)), int(match.group(2)))
            if verbose: print("start after", ts)
            continue
        match = re.match("--fromhost=(.*)", arg)
        if match:
            fromhost = match.group(1)
            continue
        match = re.match("--tohost=(.*)", arg)
        if match:
            tohost = match.group(1)
            continue

    # connect to fromhost and tohost
    try:
        fromv = fromhost.split(':')
        fromc = MongoClient(fromv[0], int(fromv[1]))
    except:
        print(fromv, sys.exc_info())
        return 1
    try:
        tov = tohost.split(':')
        toc = MongoClient(tov[0], int(tov[1]))
    except:
        print(tov, sys.exc_info())
        return 1

    # run a tailable cursor over the from host connection's  oplog from a point in time
    # and replay each oplog entry on the to host connection
    db = fromc.local
    oplog = db.oplog.rs
    while 1:
        if ts is None:
            qs = {}
        else:
            qs = { 'ts': { '$gt': ts }}
        if verbose: print(qs)
        c = oplog.find(qs, tailable=True, await_data=True)
        if verbose: print(c)
        if c.count() == 0:
            time.sleep(1)
        else:
            for oploge in c:
                if verbose: print(oploge)
                op = oploge['op']
                this_ts = oploge['ts']
                replay(toc, op, oploge, verbose)
                ts = this_ts
    return 0
def replay(toc, op, oploge, verbose):
    if op == 'i':
        ns = oploge['ns'].split('.',1)
        assert len(ns) == 2
        o = oploge['o']
        if verbose: print("insert", ns, o)
        db = toc[ns[0]]
        col = db[ns[1]]
        col.insert(o)
    elif op == 'd':
        ns = oploge['ns'].split('.',1)
        assert len(ns) == 2
        o = oploge['o']
        if verbose: print("delete", ns, o)
        db = toc[ns[0]]
        col = db[ns[1]]
        col.remove(o)
    elif op == 'u':
        ns = oploge['ns'].split('.',1)
        assert len(ns) == 2
        o = oploge['o']
        o2 = oploge['o2']
        if verbose: print("update", ns, o, o2)
        db = toc[ns[0]]
        col = db[ns[1]]
        col.update(o2, o)
    elif op == 'c':
        ns = oploge['ns'].split('.',1)
        assert len(ns) == 2
        assert ns[1] == '$cmd'
        o = oploge['o']
        if verbose: print("command", ns, o)
        db = toc[ns[0]]
        db.command(o)
    elif op == 'n':
        if verbose: print("nop", oploge)
    else:
        print("unknown", oploge)
        assert 0
sys.exit(main())