from typing import List

import numpy as np
import pandas as pd
from pandas.core.dtypes.common import is_string_dtype

from base_types import ValueFinderAbstract, CellValue

class ExactValueFinder(ValueFinderAbstract):
    condition_type = 'exact_cell_value'

    def __init__(self, cell_value: CellValue):
        self._cell_value = cell_value
        super().__init__()

    def get_all_indexes(self, axis: int) -> np.array:
        if self._cell_value:
            # cell_value не пустое значение
            if self.df is not None:
                seria = self.df[self.df.eq(self._cell_value.value)].notna().any(axis=axis)
            else:
                seria = self.sr.eq(self._cell_value.value)
        else:
            # exact_cell_value пустое значение.
            # Пустым значением могут быть варианты: '', None, np.NaN.
            # С None и np.NaN функция .isnull() справится, т.е. поставит True в нужную позицию.
            # А вот с '' не справится и поставит False. Потому предварительно '' необходимо заменить на None.
            if self.df is not None:
                seria = self.df.replace(to_replace={'': None}).isnull().any(axis=axis)
            else:
                seria = self.sr.replace(to_replace={'': None}).isnull()

        res = seria[seria].index.values
        return res

class ExactValuesFinder(ValueFinderAbstract):
    condition_type = 'exact_cell_values'

    def __init__(self, cell_values: List[CellValue]):
        self._cell_values = cell_values
        super().__init__()

    def get_all_indexes(self, axis: int) -> np.array:
        values = list(set([cell_value.value for cell_value in self._cell_values]))
        values_wo_nulls = [value for value in values if not pd.isnull(value)]
        empty_value_exists = any(pd.isnull(values))
        seria_nulls = None
        seria_wo_nulls = None
        if empty_value_exists:
            # В списке есть пустое значение, значит предстоит проверка на пустое значение. Значит необходимо
            # '' заменить на None в df
            if self.df is not None:
                seria_nulls = self.df.replace(to_replace={'': None}).isnull().any(axis=axis)
            else:
                seria_nulls = self.sr.replace(to_replace={'': None}).isnull()

        if len(values_wo_nulls):
            # В списке есть реальные значения
            if self.df is not None:
                seria_wo_nulls = self.df[self.df.isin(values_wo_nulls)].notna().any(axis=axis)
            else:
                seria_wo_nulls = self.sr.isin(values_wo_nulls)

        if seria_nulls is not None and seria_wo_nulls is not None:
            seria = seria_nulls + seria_wo_nulls
        elif seria_nulls is not None and seria_wo_nulls is None:
            seria = seria_nulls
        else:
            seria = seria_wo_nulls
        res = seria[seria].index.values
        return res

class RegexFinder(ValueFinderAbstract):
    """
    Only for string columns
    """
    condition_type = 'regex'

    def __init__(self, cell_value: CellValue):
        self._cell_value = cell_value
        super().__init__()

    def get_all_indexes(self, axis: int) -> np.array:
        pattern = self._cell_value.value
        if self.df is not None:
            seria = self.df. \
                apply(lambda s: s.astype(str).str.match(pattern, na=False) if is_string_dtype(s) else False). \
                any(axis=axis)
        else:
            # Т.к. это regex, то необходимо обязательно конвертировать в строку
            seria = self.sr.astype(str).str.match(pattern, na=False)
        res = seria[seria].index.values
        return res

class StartWithFinder(ValueFinderAbstract):
    condition_type = 'start_with'

    def __init__(self, cell_value: CellValue):
        self._cell_value = cell_value
        super().__init__()

    def get_all_indexes(self, axis: int) -> np.array:
        value = self._cell_value.value
        if self.df is not None:
            seria = self.df. \
                apply(lambda s: s.astype(str).str.startswith(value, na=False) if is_string_dtype(s) else False). \
                any(axis=axis)
        else:
            seria = self.sr.str.startswith(value, na=False)
        res = seria[seria].index.values
        return res

class EndWithFinder(ValueFinderAbstract):
    condition_type = 'end_with'

    def __init__(self, cell_value: CellValue):
        self._cell_value = cell_value
        super().__init__()

    def get_all_indexes(self, axis: int) -> np.array:
        value = self._cell_value.value
        if self.df is not None:
            seria = self.df. \
                apply(lambda s: s.astype(str).str.endswith(value, na=False) if is_string_dtype(s) else False). \
                any(axis=axis)
        else:
            seria = self.sr.str.endswith(value, na=False)
        res = seria[seria].index.values
        return res


import time

def gezidian():
    fileobj=open('zidian.txt','a',encoding='utf-8')
    list1=[]
    list2=['0','1','2','3','4','5','6','7','8','9','x']
    i=1
    while(i<=31):
        list1.append(str(i).zfill(2))

        ii=0
        while(ii<=999):

            iii=0
            while iii<=10:
                fileobj.write(list1[i-1])
                fileobj.write(str(ii).zfill(3))
                fileobj.write(list2[iii])
                fileobj.write('\n')
                iii+=1
            ii+=1
        i+=1

start = time.time()
gezidian()
end = time.time()
print(end-start)


# How to run
"""
pip install streamlit
pip install binance
pip install pandas

# Run the app
streamlit run app.py
"""
# Github link: https://github.com/Joel5212/CryptoCurrencyApp

import streamlit as st
# from binance import Client
import pandas as pd

st.markdown('''# **Crypto Price App powered by Binance API**
Simple UI displaying crypto prices using streamlit powered by Binance API.
''')

# Load market data from Binance API
df = pd.read_json('https://api.binance.us/api/v3/ticker/24hr')

# Print out all prices
st.header('**All Prices**')
# Display the datafram on streamlit
st.dataframe(df)
tickers = ['BTCUSDT','XRPUSDT',
 'TRXUSDT',
 'WAVESUSDT',
 'ZILUSDT',
 'ONEUSDT',
 'COTIUSDT',
 'SOLUSDT',
 'EGLDUSDT',
 'AVAXUSDT',
 'NEARUSDT',
 'FILUSDT',
 'AXSUSDT',
 'ROSEUSDT',
 'ARUSDT',
 'MBOXUSDT',
 'YGGUSDT',
 'BETAUSDT',
 'PEOPLEUSDT',
 'EOSUSDT',
 'ATOMUSDT',
 'FTMUSDT',
 'DUSKUSDT',
 'IOTXUSDT',
 'OGNUSDT',
 'CHRUSDT',
 'MANAUSDT',
 'XEMUSDT',
 'SKLUSDT',
 'ICPUSDT',
 'FLOWUSDT',
 'WAXPUSDT',
 'FIDAUSDT',
 'ENSUSDT',
 'SPELLUSDT',
 'LTCUSDT',
 'IOTAUSDT',
 'LINKUSDT',
 'XMRUSDT',
 'DASHUSDT',
 'MATICUSDT',
 'ALGOUSDT',
 'ANKRUSDT',
 'COSUSDT',
 'KEYUSDT',
 'XTZUSDT',
 'RENUSDT',
 'RVNUSDT',
 'HBARUSDT',
 'BCHUSDT',
 'COMPUSDT',
 'ZENUSDT',
 'SNXUSDT',
 'SXPUSDT',
 'SRMUSDT',
 'SANDUSDT',
 'SUSHIUSDT',
 'YFIIUSDT',
 'KSMUSDT',
 'DIAUSDT',
 'RUNEUSDT',
 'AAVEUSDT',
 '1INCHUSDT',
 'ALICEUSDT',
 'FARMUSDT',
 'REQUSDT',
 'GALAUSDT',
 'POWRUSDT',
 'OMGUSDT',
 'DOGEUSDT',
 'SCUSDT',
 'XVSUSDT',
 'ASRUSDT',
 'CELOUSDT',
 'RAREUSDT',
 'ADXUSDT',
 'CVXUSDT',
 'WINUSDT',
 'C98USDT',
 'FLUXUSDT',
 'ENJUSDT',
 'FUNUSDT',
 'KP3RUSDT',
 'ALCXUSDT',
 'ETCUSDT',
 'THETAUSDT',
 'CVCUSDT',
 'STXUSDT',
 'CRVUSDT',
 'MDXUSDT',
 'DYDXUSDT',
 'OOKIUSDT',
 'CELRUSDT',
 'RSRUSDT',
 'ATMUSDT',
 'LINAUSDT',
 'POLSUSDT',
 'ATAUSDT',
 'RNDRUSDT',
 'NEOUSDT',
 'ALPHAUSDT',
 'XVGUSDT',
 'KLAYUSDT',
 'DFUSDT',
 'VOXELUSDT',
 'LSKUSDT',
 'KNCUSDT',
 'NMRUSDT',
 'MOVRUSDT',
 'PYRUSDT',
 'ZECUSDT',
 'CAKEUSDT',
 'HIVEUSDT',
 'UNIUSDT',
 'SYSUSDT',
 'BNXUSDT',
 'GLMRUSDT',
 'LOKAUSDT',
 'CTSIUSDT',
 'REEFUSDT',
 'AGLDUSDT',
 'MCUSDT',
 'ICXUSDT',
 'TLMUSDT',
 'MASKUSDT',
 'IMXUSDT',
 'XLMUSDT',
 'BELUSDT',
 'HARDUSDT',
 'NULSUSDT',
 'TOMOUSDT',
 'NKNUSDT',
 'BTSUSDT',
 'LTOUSDT',
 'STORJUSDT',
 'ERNUSDT',
 'XECUSDT',
 'ILVUSDT',
 'JOEUSDT',
 'SUNUSDT',
 'ACHUSDT',
 'TROYUSDT',
 'YFIUSDT',
 'CTKUSDT',
 'BANDUSDT',
 'RLCUSDT',
 'TRUUSDT',
 'MITHUSDT',
 'AIONUSDT',
 'ORNUSDT',
 'WRXUSDT',
 'WANUSDT',
 'CHZUSDT',
 'ARPAUSDT',
 'LRCUSDT',
 'IRISUSDT',
 'UTKUSDT',
 'QTUMUSDT',
 'GTOUSDT',
 'MTLUSDT',
 'KAVAUSDT',
 'DREPUSDT',
 'OCEANUSDT',
 'UMAUSDT',
 'FLMUSDT',
 'UNFIUSDT',
 'BADGERUSDT',
 'PONDUSDT',
 'PERPUSDT',
 'TKOUSDT',
 'GTCUSDT',
 'TVKUSDT',
 'MINAUSDT',
 'RAYUSDT',
 'LAZIOUSDT',
 'AMPUSDT',
 'BICOUSDT',
 'CTXCUSDT',
 'FISUSDT',
 'BTGUSDT',
 'TRIBEUSDT',
 'QIUSDT',
 'PORTOUSDT',
 'DATAUSDT',
 'NBSUSDT',
 'EPSUSDT',
 'TFUELUSDT',
 'BEAMUSDT',
 'REPUSDT',
 'PSGUSDT',
 'WTCUSDT',
 'FORTHUSDT',
 'BONDUSDT',
 'ZRXUSDT',
 'FIROUSDT',
 'SFPUSDT',
 'VTHOUSDT',
 'FIOUSDT',
 'PERLUSDT',
 'WINGUSDT',
 'AKROUSDT',
 'BAKEUSDT',
 'ALPACAUSDT',
 'FORUSDT',
 'IDEXUSDT',
 'PLAUSDT',
 'VITEUSDT',
 'DEGOUSDT',
 'XNOUSDT',
 'STMXUSDT',
 'JUVUSDT',
 'STRAXUSDT',
 'CITYUSDT',
 'JASMYUSDT',
 'DEXEUSDT',
 'OMUSDT',
 'MKRUSDT',
 'FXSUSDT',
 'ETHUSDT',
 'ADAUSDT',
'BNBUSDT',
'SHIBUSDT']

# This variable will equal the symbol you chose
dropdown = st.selectbox("Pick your coin", tickers)
# Dataframe of one ticker
oneTicker = df[df['symbol'] == dropdown]
# Index of the ticker to pick values later
index = df[df['symbol']==dropdown].index.values.astype(int)[0]
st.dataframe(oneTicker)

# Creating row in website
with st.container():
    # Creating columns and displaying attributes in columns
    col1, col2, col3, col4, col5, col6 = st.columns(6)
    with col1:
        st.markdown('### **Price Change**')
        st.markdown('**' + str(oneTicker.loc[index].at['priceChange']) + '**')
    with col2:
        st.markdown('### **Price Change Percent**')
        st.markdown('**' + str(oneTicker.loc[index].at['priceChangePercent']) + '%**')
    with col3:
        st.markdown('### **Weighted Average Price**')
        st.markdown('**' + str(oneTicker.loc[index].at['weightedAvgPrice']) + '**')
    with col4:
        st.markdown('### **Previous Close Price**')
        st.markdown('**' + str(oneTicker.loc[index].at['prevClosePrice']) + '**')
    with col5:
        st.markdown('### **High Price**')
        st.markdown('**' + str(oneTicker.loc[index].at['highPrice']) + '**')
    with col6:
        st.markdown('### **Low Price**')
        st.markdown('**' + str(oneTicker.loc[index].at['lowPrice']) + '**')

# Data frames we will use
tickerDF = pd.read_json('https://api.binance.us/api/v3/ticker/24hr')
# Sort dataframe for gain loss
tickerDF = tickerDF.sort_values('priceChangePercent')
# Subset of data frame with symbol and volume
tickerSubsetDF = tickerDF[['symbol', 'volume']]

# Code to create bar chart
# Print out the header
st.header('**Volume Bar Chart**')
# Finding the tickers with the highest
tickerSubsetDF = tickerSubsetDF.sort_values('volume')
tickerSubsetLast10 = tickerSubsetDF.tail(10)
st.bar_chart(tickerSubsetLast10, x='symbol', y='volume')

# Side bar features
# Print 10 stocks with the highest gain percent
st.sidebar.markdown("# **Top Gainers**")
for i in range(10):
    st.sidebar.markdown('### **' + tickerDF.loc[i].at['symbol'] + '**')
    st.sidebar.markdown(str(tickerDF.loc[i].at['priceChangePercent']) + '%')

# Print 10 stocks with the lowest gain percent
st.sidebar.markdown("# **Top Losers**")
for i in range(len(tickerDF)-1, len(tickerDF)-11, -1):
    st.sidebar.markdown('### **' + tickerDF.loc[i].at['symbol'] + '**')
    st.sidebar.markdown(str(tickerDF.loc[i].at['priceChangePercent']) + '%')


import sys

import tflite_runtime.interpreter as tflite
import numpy as np

from PIL import Image
from skimage import transform

filepath = sys.argv[1];
print("File Path: ", filepath)

def load(filename):
    np_image = Image.open(filename)
    np_image = np.array(np_image).astype('float32')/255
    np_image = transform.resize(np_image, (28, 28, 1))
    np_image = np.expand_dims(np_image, axis=0)
    return np_image

image = load(filepath)

interpreter = tflite.Interpreter(model_path="./model.tflite")
interpreter.allocate_tensors()

input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

interpreter.set_tensor(input_details[0]['index'], image)

interpreter.invoke()

output_data = interpreter.get_tensor(output_details[0]['index'])
print("Model Prediction: ", np.argmax(output_data))
print("Model Confidence: {:02.2f}%".format(np.max(output_data)*100))

    #num = input("Choose number to predict: ")
    #num = int(num)


#  combine csv files,
# filter out world cups and championships,
# use urls to scrape results,

import pandas as pd
import requests
import json
import logging

logging.basicConfig(
    filename='ifsc_results_scraper_log.txt',
      level=logging.INFO,
      format='%(asctime)s:%(levelname)s:%(message)s'
      )

base_url = 'https://components.ifsc-climbing.org/results-api.php?api=event_full_results&result_url='
headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'
}

def fetch_results(endpoint):
    """Fetch results from given endpoint"""
    full_url = base_url + endpoint

    try:
        response = requests.get(full_url, headers=headers)
        response.raise_for_status()  # raises HTTPError if HTTP request returned unsuccessful status code
        print(f"Fetching results from {full_url}")
        return response.json()  # Convert to JSON
    except requests.RequestException as e:
        print("RequestException Error:", e) # Add this
        logging.error(f"Error fetching results from {full_url}: {e}")
        return None
    except json.JSONDecodeError:
        print("JSONDecodeError") # And this
        logging.error(f"Error decoding JSON from {full_url}")
        return None

def main():
    raw_df = '/Users/apple/Documents/PROGRAMMING/Data Analysis/ifsc_data/worldcups_and_championships.json'
    raw_df = pd.read_json(raw_df) #0: event_id, 1: comp_name, 2: comp

    all_comps = {
        'LEAD Women': pd.DataFrame(),
        'BOULDER Women': pd.DataFrame(),
        'COMBINED Women': pd.DataFrame(),
        'BOULDER&LEAD Women': pd.DataFrame(),
    }

    for i, row in raw_df.iterrows():

        try:
            comp_name = row.iloc[1]
            wc_json = row.iloc[2]

            for comp_dict in wc_json: # for each {e.g. lead W} comp in {e.g. Innsbruk 2018}

                results_url = comp_dict['results_url']
                comp_scraped = fetch_results(results_url)

                if comp_scraped:
                    new_row = {
                        'comp_name': comp_name,
                        'results': comp_scraped
                    }

                    # Check if the category is in all_comps
                    if comp_dict['category'] in all_comps:
                        # Convert new_row to a DataFrame and append it to the existing DataFrame
                        temp_df = pd.DataFrame([new_row])
                        all_comps[comp_dict['category']] = pd.concat([all_comps[comp_dict['category']], temp_df], ignore_index=True)

        except Exception as e:
            print((f"Unexpected error processing row {row}: {e}"))
            logging.error(f"Unexpected error processing row {row}: {e}")

    all_comps['LEAD Women'].to_json('/Users/apple/Documents/PROGRAMMING/Data Analysis/ifsc_data/Wlead.json', index=False)
    all_comps['BOULDER Women'].to_json('/Users/apple/Documents/PROGRAMMING/Data Analysis/ifsc_data/Wboulder.json', index=False)
    all_comps['COMBINED Women'].to_json('/Users/apple/Documents/PROGRAMMING/Data Analysis/ifsc_data/Wcombined.json', index=False)
    all_comps['BOULDER&LEAD Women'].to_json('/Users/apple/Documents/PROGRAMMING/Data Analysis/ifsc_data/Wboulderlead.json', index=False)

if __name__ == "__main__":
    main()


from sys import exit
""" Note: this program assumes that it is being executed from the
 root directory of a USB drive containing an installation of
 Enterprise.

 	It verifies syntax and whether all required files are present."""
def main():
	"""The program's main method."""
	installValid = True
	reason = ""

	configIsValid = verifyConfigurationFile("efi/boot/.MLUL-Live-USB")
	## Check if the Enterprise files are present.
	if ( not fileExists("efi/boot/boot.efi") and
		 not fileExists("efi/boot/bootX64.efi")
		):
		reason = "The EFI boot files are not present."
		installValid = False
	elif (not fileExists("efi/boot/.MLUL-Live-USB")):
		reason = "No Enterprise configuration file present."
		installValid = False

	## Verify that the configuration file is present.
	elif (not configIsValid):
		reason = "The configuration file is bad."
		installValid = False

	## Display whether or not everything's good.
	if (installValid):
		print("The installation is valid. All's good. :)")
		exit(0)
	else:
		print("The installation is invalid: {0}".format(reason))
		exit(1)

def verifyConfigurationFile(file):
	"""Verify whether Enterprise's configuration file
		is valid."""
	validKeys = ["family", "kernel", "initrd", "root"]
	verifyIsValid = True
	if not (fileExists(file)):
		return "bad: the file does not exist"

	## Open the file.
	file = open(file, 'r')

	## Read each line.
	lineNumber = 1
	n = 1 # We must read at least one byte.
	while True:
		chunk = file.read(n)
		if (chunk == ''):
			break
		else:
			line = chunk + file.readline()
			didSucceed, message = processConfigLine(line, validKeys)
			if not (didSucceed):
				print("Syntax error on line {0}: {1}" \
					.format(lineNumber, message))
				verifyIsValid = False
		lineNumber += 1
	return verifyIsValid

def processConfigLine(line, validKeys):
	"""Determine whether a configuration file's line starts
		with valid keys."""
	command = line.split(' ')[0]
	message = ""
	if (command.startswith('#')):
		return (True, message)
	keyIsValid = command in validKeys
	if not (keyIsValid):
		message = "key \"{0}\" is not valid".format(command)

	value = (keyIsValid, message)
	return value

def fileExists(file):
	"""Check if a file exists."""
	try:
		open(file)
		return True
	except IOError:
		return False

if  __name__ == '__main__':
    main()


import copy
from functools import partial
from inspect import Parameter, signature
from multiprocessing import get_logger
import traceback
from typing import Any, Tuple

from ice.llutil.argparser import as_list, isa
from ice.llutil.utils import auto_freeze_enabled

def _inplace_surrogate(cls, funcname):
    backupname = "__backup" + funcname
    setattr(cls, backupname, getattr(cls, funcname, None))
    def newfunc(self, *a, **k):
        try:
            cfg = object.__getattribute__(self, "_builder")
            if not cfg._frozen:
                try:
                    value = getattr(cfg, funcname)(*a, **k)
                except AttributeError as e:
                    get_logger().info(f"Try to automatically freeze due to AttributeError:\n{e.args[0]}")
                    self.auto_freeze()
                    if not cfg._frozen: raise
            if cfg._frozen:
                fn = getattr(cls, backupname)  # will get None instead of raise AttributeError if not hasattr(original_class, funcname), so
                if fn is None: raise AttributeError(funcname) # we raise it manually.
                value = fn(self, *a, **k)
        except AttributeError:
            # TODO: rephrase the exception handling part
            if funcname == "__getattribute__":
                if len(a) and a[0] in ('freeze', 'clone', 'update_params'):
                    return object.__getattribute__(cfg, *a)
                else:
                    try:
                        value = object.__getattribute__(cls, *a)
                    except AttributeError:
                        value = object.__getattribute__(self, *a)
            else:
                # assert False, f"{cls.__name__}.{funcname}({a}, {k}) frozen={cfg._frozen}\nAttributeError:{e}"
                raise
        return value
    setattr(cls, funcname, newfunc)

def configurable(cls):
    """This decorator delays the initialization of ``cls`` until ``freeze()``.

    Returns:
        decorated class which is now configurable.

    Example:

    >>> import ice
    >>>
    >>> @ice.configurable
    >>> class AClass:
    >>>     def __init__(self, a, b, c, d):
    >>>         self.a = a
    >>>         self.b = b
    >>>         self.c = c
    >>>         self.d = d
    >>>
    >>> # partial initialization.
    >>> i = AClass(b=0)
    >>>
    >>> # alter positional and keyword arguments afterwards.
    >>> i[0] = 2
    >>> i['b'] = 1
    >>> i.update({'c': 3, 'd': 4})
    >>> i.update(d=5)
    >>>
    >>> # unfrozen configurable can be printed as a legal construction python statement.
    >>> assert repr(i) == "AClass(a=2, b=1, c=3, d=5)"
    >>>
    >>> # real initialization of original object.
    >>> i.freeze()
    >>> assert i.a == 2 and i.b == 1
    """

    # do not wrap the same cls more than once.
    if is_configurable(cls):
        return cls

    # mark the cls so that is becomes a configurable class.
    cls.configurable_class_id = id(cls)

    try:
        object.__getattribute__(cls, "__freeze__")
    except AttributeError:
        # use the original initialization function as __freeze__.
        cls.__freeze__ = getattr(cls, "__init__")

    # substitute the original initialization function.
    def __new_init__(obj, *args, **kwds):
        if obj.configurable_class_id == cls.configurable_class_id:
            _Builder(cls, obj, *args, **kwds)
        else:  # called from subclass instance
            cls.__freeze__(obj, *args, **kwds)

    cls.__init__ = __new_init__

    # surrogate other functions
    _inplace_surrogate(cls, "__getattribute__")
    _inplace_surrogate(cls, "__getattr__")
    _inplace_surrogate(cls, "__str__")
    _inplace_surrogate(cls, "__getitem__")
    _inplace_surrogate(cls, "__setitem__")
    _inplace_surrogate(cls, "__call__")
    _inplace_surrogate(cls, "__repr__")
    _inplace_surrogate(cls, "extra_repr")
    _inplace_surrogate(cls, "__contains__")

    # return the modified cls
    return cls

def is_configurable(cls) -> bool:
    """check if a class or an object is configurable.

    Returns:
        bool

    Example:

    >>> import ice
    >>> import torch.nn as nn
    >>> ice.make_configurable(nn.Conv2d, nn.Linear)
    >>> assert ice.is_configurable(nn.Conv2d)

    """
    return getattr(cls, "configurable_class_id", None) in (id(cls), -1)

def has_builder(obj) -> bool:
    try:
        object.__getattribute__(obj, "_builder")
        return True
    except:
        return False

def frozen(obj):
    if is_configurable(obj):
        if has_builder(obj):
            builder = object.__getattribute__(obj, "_builder")
            return builder._frozen
        else:
            return obj._frozen
    else:
        return True  # view normal objects as a frozen version

def make_configurable(*classes):
    """This function converts multiple existing classes to configurables.

    Note:
        This have exactly the same effects of decorate each class with `@configurable` when defining the class.
        Each class only need to be decorated once, extra calling of conversion is ignored and has no side effects.

    Example:

    >>> import ice
    >>> import torch.nn as nn
    >>> ice.make_configurable(nn.Conv2d, nn.Linear)
    >>> assert ice.is_configurable(nn.Conv2d)

    """
    for cls in classes:
        configurable(cls)

def clone(obj, deepcopy=True):
    """clone configurables, containers, and ordinary objects recursively.

    Args:
        obj (configurable or list/dict of configurables): the configurable object to be cloned.
        deepcopy (bool, optional): copy resources by value. Defaults to True.

    Returns:
        Unfrozen copy of the original configurable.

    >>> import ice
    >>> import torch.nn as nn
    >>> ice.make_configurable(nn.Conv2d, nn.Linear)
    >>>
    >>> convcfg = nn.Conv2d(16, 8)
    >>>
    >>> conv1x1 = convcfg.clone()  # or ice.clone(convcfg)
    >>> conv1x1['kernel_size'] = 1
    >>> conv1x1.freeze()  # or ice.freeze(conv1x1)
    >>> assert conv1x1.kernel_size == (1, 1)
    >>>
    >>> conv3x3 = convcfg.clone()
    >>> conv3x3['kernel_size'] = 3
    >>> conv3x3.freeze()
    >>> assert conv3x3.kernel_size == (3, 3)
    """
    import torch
    if isinstance(obj, list):
        obj = [clone(x, deepcopy=deepcopy) for x in obj]
    elif isinstance(obj, tuple):
        obj = tuple(clone(x, deepcopy=deepcopy) for x in obj)
    elif isinstance(obj, dict):
        obj = obj.__class__({k: clone(v, deepcopy=deepcopy) for k, v in obj.items()})
    elif has_builder(obj):
        obj = objattr(obj, "_builder").clone(deepcopy=deepcopy)
    elif isinstance(obj, Configurable):
        obj = obj.clone()
    elif isinstance(obj, torch.Tensor):
        obj = obj.clone()
    elif deepcopy:
        obj = copy.deepcopy(obj)
    else:
        obj = copy.copy(obj)
    return obj

def freeze(obj):
    """freeze configurables recursively.

    **Freezing** is the process of building the configuration into real objects.
    Original `__init__()` functions of configurable classes declared by ``configurable``
     or ``make_configurable`` now will be called recursively to initialize the real instance,
     also known as the frozen version of a configurable.

    Args:
        obj (configurable or list/dict of configurables): the configurable object to be freeze.

    Returns:
        Frozen version of the original configurable.

    Note:
        Freezing happens in-place, ignoring the returned value is safe.
        If a user wants to reuse the configuration feature, he can clone() the
        object before or after frozen with the same effect.

    Example:
        See examples for ``configurable`` and ``clone``.
    """
    import torch
    if isinstance(obj, list):
        obj = [freeze(x) for x in obj]
    elif isinstance(obj, tuple):
        obj = tuple(freeze(x) for x in obj)
    elif isinstance(obj, dict):
        obj = obj.__class__({k: freeze(v) for k, v in obj.items()})
    elif has_builder(obj):
        obj = objattr(obj, "_builder").freeze()
    elif isinstance(obj, Configurable):
        obj = obj.freeze()
    elif isinstance(obj, torch.Tensor):
        obj = obj.clone()
    return obj

def objattr(obj, attrname):
    return object.__getattribute__(obj, attrname)

class Configurable:

    configurable_class_id = -1

    def __init__(self, *args, **kwds) -> None:
        try:
            objattr(self, "_cls")
        except AttributeError:
            self._obj = self
            self._cls = self.__class__

        param_signs = list(signature(self._cls.__freeze__).parameters.items())[1:]
        self._args_only = []
        self._args_only_count = 0
        self._args_only_names = {}
        self._args_or_kwds = {}
        self._argnames = []
        self._var_args = []
        self._var_args_name = None
        self._kwds_only = {}
        self._var_kwds = {}
        self._var_kwds_name = None
        for name, param in param_signs:
            if param.kind == Parameter.POSITIONAL_ONLY:
                self._args_only.append(param.default)
                self._args_only_names[name] = self._args_only_count
                self._args_only_count += 1
            elif param.kind == Parameter.POSITIONAL_OR_KEYWORD:
                self._args_or_kwds[name] = param.default
                self._argnames.append(name)
            elif param.kind == Parameter.VAR_POSITIONAL:
                self._var_args_name = name
            elif param.kind == Parameter.KEYWORD_ONLY:
                self._kwds_only[name] = param.default
            elif param.kind == Parameter.VAR_KEYWORD:
                self._var_kwds_name = name
            else:
                assert False, "unknown param kind"

        self._all_args_count = self._args_only_count + len(self._args_or_kwds)
        self._all_kwds_names = list(self._args_only_names.keys()) + self._argnames + [self._var_args_name, self._var_kwds_name] + list(self._kwds_only.keys())

        self._frozen = False
        self.update_params(*args, **kwds)

    def update_params(self, *args, **kwds):
        # if provided args for position-only params, all of them should be provided.
        if self._args_only_count and len(args):
            self._args_only = [None] * self._args_only_count
            for idx in range(self._args_only_count):
                try:
                    self._args_only[idx] = args[idx]
                except IndexError:
                    raise TypeError(f" {self._cls.__name__} missing 1 required position-only argument '{self._args_only_names[idx]}'.")
            args = args[idx+1:]
        # args or kwds
        if len(self._args_or_kwds) and len(args):
            for idx, arg in enumerate(args):
                self[self._args_only_count + idx] = arg
            args = args[idx+1:]
        # var_args
        if self._var_args_name is not None and len(args):
            self._var_args = args
            args = []
        if len(args):
            raise TypeError(f"{self._cls.__name__} doesn't accept variable position-only arguments.")
        # kwds
        for name, arg in kwds.items():
            self[name] = arg
        return self._obj

    def __getitem__(self, key):
        if isinstance(key, int):
            if key < 0:
                raise KeyError(key)
            elif key < self._args_only_count:
                return self._args_only[key]
            elif key < self._all_args_count:
                key = self._argnames[key - self._args_only_count]
                return self._args_or_kwds[key]
            else:
                raise KeyError(key)
        else:
            if key in self._args_or_kwds:
                return self._args_or_kwds[key]
            elif key in self._kwds_only:
                return self._kwds_only[key]
            elif key == self._var_args_name:
                return self._var_args
            elif key == self._var_kwds_name:
                return self._var_kwds
            elif key in self._args_only_names:
                idx = self._args_only_names[key]
                return self._args_only[idx]
            elif key in self._var_kwds:
                return self._var_kwds[key]
            else:
                raise KeyError(key)

    def __setitem__(self, key, value):
        if self._frozen:
            # traceback.print_stack()
            raise RuntimeError(f"Frozen configuration {self._cls.__name__} can not be altered, please use clone() at proper time.")
        if isa(key, tuple):
            for i in key:
                if i in self:
                    self.__setitem__(i, value)
                    break
            else:
                raise KeyError(key)
        else:
            if isinstance(key, int):
                if key < 0:
                    raise KeyError(key, value)
                elif key < self._args_only_count:
                    self._args_only[key] = value
                elif key < self._all_args_count:
                    key = self._argnames[key - self._args_only_count]
                    self._args_or_kwds[key] = value
                else:
                    raise KeyError(key, value)
            else:
                if key in self._args_or_kwds:
                    self._args_or_kwds[key] = value
                elif key in self._kwds_only:
                    self._kwds_only[key] = value
                elif key == self._var_args_name:
                    self._var_args = as_list(value)
                elif key == self._var_kwds_name:
                    if not isa(value, dict):
                        raise TypeError(f"direct assignment of '**{key}' argument of '{self._cls.__name__}' type should be a dict.")
                    self._var_kwds = value
                elif key in self._args_only_names:
                    idx = self._args_only_names[key]
                    self._args_only[idx] = value
                elif self._var_kwds_name is not None:
                    self._var_kwds[key] = value
                else:
                    raise KeyError(key, f"'{self._cls.__name__}' does not accept variable keywords arguments.")

    def __contains__(self, key):
        if isa(key, int):
            return key >= 0 and key < self._all_args_count
        elif isa(key, str):
            return key in self._all_kwds_names
        else:
            raise TypeError(key)

    def __str__(self):
        args = []
        if self._args_only_count:
            args.append(', '.join([str(arg) for arg in self._args_only]))
        if len(self._args_or_kwds):
            args.append(', '.join([f"{k}={v}" for k, v in self._args_or_kwds.items() if v != Parameter.empty]))
        if len(self._var_args):
            args.append(', '.join([str(arg) for arg in self._var_args]))
        if len(self._kwds_only):
            args.append(', '.join([f"{k}={v}" for k, v in self._kwds_only.items() if v != Parameter.empty]))
        if len(self._var_kwds):
            args.append(', '.join([f"{k}={v}" for k, v in self._var_kwds.items() if v != Parameter.empty]))
        args = ', '.join(args)
        return f"{objattr(self, '_cls').__name__}({args})"

    def extra_repr(self):
        return ''

    def __getattr__(self, attrname):
        if objattr(self, "_frozen"):
            raise AttributeError(f"\"{self._cls.__name__}\" does not have attribute \"{attrname}\".")
        else:
            raise AttributeError(f"Configurable \"{self._cls.__name__}\" is not frozen, which may be the reason of not having attribute \"{attrname}\".")

    def clone(self, deepcopy=True):
        return self._cls(
            *clone(self._args_only, deepcopy=deepcopy),
            *clone(self._args_or_kwds, deepcopy=deepcopy).values(),
            *clone(self._var_args, deepcopy=deepcopy),
            **clone(self._kwds_only, deepcopy=deepcopy),
            **clone(self._var_kwds, deepcopy=deepcopy)
            )

    def freeze(self):
        # make twice freezing legal.
        if self._frozen: return self._obj
        # mark as frozen so that orig__init__ will be able to manipulate the original instance via __getattribute__.
        self._frozen = True
        # initialize the class instance
        self._cls.__freeze__(self._obj, *self._args_only, *self._args_or_kwds.values(), *self._var_args, **self._kwds_only, **self._var_kwds)
        return self._obj

    def auto_freeze(self):

        if not auto_freeze_enabled(): return self._obj

        def all_args():
            for arg in self._args_only: yield arg
            for arg in self._args_or_kwds.values(): yield arg
            for arg in self._var_args: yield arg
            for arg in self._kwds_only.values(): yield arg
            for arg in self._var_kwds.values(): yield arg

        for arg in all_args():
            if arg is Parameter.empty:
                break
        else:
            self.freeze()

        return self._obj

    def __call__(self, *args: Any, **kwds: Any) -> Any:
        return self.clone().update_params(*args, **kwds).auto_freeze()

class _Builder(Configurable):
    """This class stores the arguments and meta informations that is needed by ``configurable`` decorator.

    This class is not intended to be visited directly by end user. See ``configurable`` for usage guide instead.
    """

    def __init__(self, cls, obj, *args, **kwds) -> None:
        self._cls = cls
        self._obj = obj
        super().__init__(*args, **kwds)
        object.__setattr__(obj, "_builder", self)
        self.auto_freeze()

    def __reduce__(self) -> Tuple[Any, ...]:
        assert not self._frozen, f"{self}"
        return (partial(self._cls, *self._args_only, *self._args_or_kwds.values(), *self._var_args, **self._kwds_only, **self._var_kwds), ())

    def __repr__(self):
        return str(self)


import datetime
import textwrap

def print_result(time_until_retire):
    current_year = datetime.date.today().year

    if time_until_retire > 0:
        print(textwrap.dedent(
            f"""\
            You have {time_until_retire} years left until you can retire.
            It's {current_year}, so you can retire in {current_year + time_until_retire}.
            """))
    else:
        print("You can already retire.")

age = int(input("What is your current age? "))
retirement_age = int(input("What age would you like to retire? "))

print_result(retirement_age - age)


import random

import disnake

import ddb.dice
from cogs5e.models.character import Character
from cogs5e.models.embeds import EmbedWithCharacter
from cogs5e.models.sheet.attack import Attack
from ddb.gamelog.context import GameLogEventContext
from ddb.gamelog.event import GameLogEvent
from gamedata import Monster
from gamedata.compendium import compendium
from gamedata.lookuputils import available
from utils import constants
from utils.functions import a_or_an

# ==== event helpers ====
async def action_from_roll_request(gctx, caster, roll_request):
    """
    Gets an action (spell or attack) from a character based on the roll request. None if it cannot be found.

    Prioritizes attack first, then spell if not found.

    :type gctx: ddb.gamelog.context.GameLogEventContext
    :type caster: cogs5e.models.sheet.statblock.StatBlock
    :type roll_request: ddb.dice.RollRequest
    :rtype: Attack or gamedata.spell.Spell
    """
    action_name = roll_request.action

    attack = next((a for a in caster.attacks if a.name == action_name), None)
    if attack is not None:
        return attack

    available_spells = await available(gctx, compendium.spells, "spell", gctx.discord_user_id)
    # noinspection PyUnresolvedReferences
    # this is a Spell
    spell = next((s for s in available_spells if s.name == action_name), None)

    if spell is not None:
        return spell
    return None

# ---- display helpers ----
def default_comment_getter(roll_request):
    """
    Given a RollRequest, return a function mapping RollRequestRolls to comments (strs).

    :type roll_request: ddb.dice.RollRequest
    :rtype: typing.Callable[[ddb.dice.RollRequestRoll], typing.Optional[str]]
    """
    if roll_request.action != "custom":
        if roll_request.context and roll_request.context.name:
            return lambda rr: f"{roll_request.context.name}: {roll_request.action}: {rr.roll_type.value.title()}"
        return lambda rr: f"{roll_request.action}: {rr.roll_type.value.title()}"
    else:
        return lambda _: None

def embed_for_caster(caster):
    if isinstance(caster, Character):
        return EmbedWithCharacter(character=caster, name=False)
    embed = disnake.Embed()
    embed.colour = random.randint(0, 0xFFFFFF)
    if isinstance(caster, Monster):
        embed.set_thumbnail(url=caster.get_image_url())
    return embed

def embed_for_action(gctx, action, caster, to_hit_roll=None, damage_roll=None):
    """
    Creates an embed for a character performing some action (attack or spell).

    Handles inserting the correct fields for to-hit and damage based on the action's automation and whether the rolls
    are present.

    :type gctx: GameLogEventContext
    :type action: Attack or gamedata.spell.Spell
    :type caster: cogs5e.models.sheet.statblock.StatBlock
    :type to_hit_roll: ddb.dice.tree.RollRequestRoll
    :type damage_roll: ddb.dice.tree.RollRequestRoll
    """
    embed = embed_for_caster(caster)
    automation = action.automation
    waiting_for_damage = False

    # set title
    if isinstance(action, Attack):
        attack_name = a_or_an(action.name) if not action.proper else action.name
        verb = action.verb or "attacks with"
        embed.title = f"{caster.get_title_name()} {verb} {attack_name}!"
    else:  # spell
        embed.title = f"{caster.get_title_name()} casts {action.name}!"

    # add to hit (and damage, either if it is provided or the action expects damage and it is not provided)
    meta_rolls = []
    if to_hit_roll is not None:
        meta_rolls.append(f"**To Hit**: {str(to_hit_roll.to_d20())}")
    if damage_roll is not None:
        if damage_roll.roll_kind == ddb.dice.RollKind.CRITICAL_HIT:
            meta_rolls.append(f"**Damage (CRIT!)**: {str(damage_roll.to_d20())}")
        else:
            meta_rolls.append(f"**Damage**: {str(damage_roll.to_d20())}")
    elif automation_has_damage(automation):
        meta_rolls.append("**Damage**: Waiting for roll...")
        waiting_for_damage = True

    # add dcs, texts
    if automation:
        for effect in automation_dfg(automation, enter_filter=action_enter_filter):
            # break if we see a damage and are waiting on a damage roll
            if effect.type == "damage" and waiting_for_damage:
                break

            # note: while certain fields here are AnnotatedStrings, it should never be annotated directly from the sheet
            # and GameLog events cannot trigger custom attacks, so this should be fine

            # save: add the DC
            if effect.type == "save":
                meta_rolls.append(f"**DC**: {effect.dc}\n{effect.stat[:3].upper()} Save")
            # text: add the text as a field
            elif effect.type == "text":
                text = effect.text
                if len(text) > 1020:
                    text = f"{text[:1020]}..."
                embed.add_field(name="Effect", value=text, inline=False)

    embed.insert_field_at(0, name="Meta", value="\n".join(meta_rolls), inline=False)

    # set footer
    embed.set_footer(text=f"Rolled in {gctx.campaign.campaign_name}", icon_url=constants.DDB_LOGO_ICON)
    return embed

def embed_for_basic_attack(gctx, action_name, caster, to_hit_roll=None, damage_roll=None):
    """
    Creates an embed for a character making an attack where the Avrae action is unknown.

    Handles inserting the correct fields for to-hit and damage.

    :type gctx: GameLogEventContext
    :type action_name: str
    :type caster: cogs5e.models.sheet.statblock.StatBlock
    :type to_hit_roll: ddb.dice.tree.RollRequestRoll
    :type damage_roll: ddb.dice.tree.RollRequestRoll
    """
    embed = embed_for_caster(caster)

    # set title
    embed.title = f"{caster.get_title_name()} attacks with {action_name}!"

    # add to hit (and damage, either if it is provided or the action expects damage and it is not provided)
    meta_rolls = []
    if to_hit_roll is not None:
        meta_rolls.append(f"**To Hit**: {str(to_hit_roll.to_d20())}")

    if damage_roll is not None:
        if damage_roll.roll_kind == ddb.dice.RollKind.CRITICAL_HIT:
            meta_rolls.append(f"**Damage (CRIT!)**: {str(damage_roll.to_d20())}")
        else:
            meta_rolls.append(f"**Damage**: {str(damage_roll.to_d20())}")
    else:
        meta_rolls.append("**Damage**: Waiting for roll...")

    embed.add_field(name="Meta", value="\n".join(meta_rolls), inline=False)

    # set footer
    embed.set_footer(text=f"Rolled in {gctx.campaign.campaign_name}", icon_url=constants.DDB_LOGO_ICON)
    return embed

# ---- automation tree helpers ----
def automation_dfg(automation, enter_filter=None):
    """
    Depth-first generator on automation.

    :type automation: cogs5e.models.automation.Automation
    :param enter_filter: A callable that takes an automation effect and returns the children to iterate over.
    """
    if enter_filter is None:
        enter_filter = lambda e: e.children

    def iterator(effects):
        for effect in effects:
            yield effect
            yield from iterator(enter_filter(effect))

    yield from iterator(automation.effects)

def automation_has_damage(automation):
    """Returns whether a given automation does damage."""
    if automation is None:
        return False

    for effect in automation_dfg(automation):
        if effect.type == "damage":
            return True
    return False

def action_enter_filter(effect):
    """Only enter an effect if it is top level or an attack."""
    if effect.type == "attack":
        return effect.children
    return []

# ---- attack state helper ----
class PendingAttack:
    """A cached attack that is waiting on a damage roll."""

    TTL = 60 * 2  # 2m

    def __init__(self, key: str, to_hit_event: GameLogEvent, message_id: int):
        self.key = key
        self.to_hit_event = to_hit_event
        self.message_id = message_id

    # ser/deser
    @classmethod
    def from_dict(cls, key, d):
        to_hit_event = GameLogEvent.from_dict(d["to_hit_event"])
        return cls(key, to_hit_event, d["message_id"])

    def to_dict(self):
        return {"to_hit_event": self.to_hit_event.to_dict(), "message_id": self.message_id}

    @classmethod
    async def create(
        cls, gctx: GameLogEventContext, roll_request: ddb.dice.RollRequest, to_hit_event: GameLogEvent, message_id: int
    ):
        """Creates and caches a new PendingAttack instance."""
        cache_key = await cls.cache_key_from_ctx(gctx, roll_request)
        inst = cls(cache_key, to_hit_event, message_id)
        await gctx.bot.rdb.jsetex(key=cache_key, data=inst.to_dict(), exp=cls.TTL)
        return inst

    @classmethod
    async def for_damage(cls, gctx: GameLogEventContext, roll_request: ddb.dice.RollRequest):
        """Gets the relevant PendingAttack instance from cache for a given damage RollRequest in context, or None."""
        cache_key = await cls.cache_key_from_ctx(gctx, roll_request)
        data = await gctx.bot.rdb.jget(cache_key)
        if data is None:
            return None
        return cls.from_dict(cache_key, data)

    # helpers
    @property
    def roll_request(self):
        return ddb.dice.RollRequest.from_dict(self.to_hit_event.data)

    async def delete(self, gctx):
        await gctx.bot.rdb.delete(self.key)

    @staticmethod
    async def cache_key_from_ctx(gctx: GameLogEventContext, roll_request: ddb.dice.RollRequest):
        action_name = roll_request.action
        return f"gamelog.pendingattack.{gctx.discord_user_id}.{gctx.event.entity_type}.{gctx.event.entity_id}.{action_name}"


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from contextvars import ContextVar

def main():
    var: ContextVar[int] = ContextVar('var', default=42)

    # The name of the variable. This is a read-only property.
    print(var.name)

    print(var.get())
    token = var.set(100)
    print(var.get())

    var.reset(token)
    print(var.get())

if __name__ == '__main__':
    main()

"""
$ py3 contextvars.ContextVar.py
var
42
100
42
"""

# references
# https://docs.python.org/3/library/contextvars.html#module-contextvars


import os
import subprocess
import fnmatch
from datetime import datetime

import numpy as np
import netCDF4 as nc

import read_host_info
sv = read_host_info.read_host_info()
data_dir = sv['out_dir'] + 'frc/'
out_dir = sv['out_dir'] + 'frc_clim/'

# -------------------- my inputs ---------------------------------------
my_year = 2008
tag = 'JRA55v1.1'

lon_min = 222
lon_max = 226
lat_min = 57
lat_max = 60

# lon_min = 0
# lon_max = 360
# lat_min = -90
# lat_max = 90

vlist = ['Qair', 'rain', 'snow', 'lwrad_down', 'swrad', 'Pair', 'Tair', 'Uwind', 'Vwind']
vlist2 = ['huss_10m', 'prrn', 'prsn', 'rlds', 'rsds', 'psl', 'tas_10m', 'uas_10m', 'vas_10m']
vlist3 = ['qair', 'rain', 'snow', 'lrf', 'srf', 'pair', 'tair', 'wind', 'wind']

# -------------------- funcitonals -------------------------------------
def recursive_glob(in_dir, pattern='*'):
    ''' Search recursively for files matching a specified pattern. '''

    matches = []
    for root, dirnames, filenames in os.walk(in_dir):
        for filename in fnmatch.filter(filenames, pattern):
            matches.append(os.path.join(root, filename))

    return matches

# -------------------- load data and calculate clim --------------------

for i2 in range(len(vlist3)):
# for i2 in range(1):
    flist = recursive_glob(data_dir, vlist[i2]+'*.nc')
    file_out = out_dir+vlist[i2]+'_clim.nc'

    # create output file
    subprocess.call('cp ' + flist[0] + ' ' + file_out, shell=True)
    fout = nc.Dataset(out_dir+vlist[i2]+'_clim.nc', 'a')

    for i, fn in enumerate(flist):
        fin = nc.Dataset(fn, 'r')
        if i == 0:
            time = fin.variables[vlist3[i2]+'_time'][:]
            data = fin.variables[vlist[i2]][:]
        else:
            time = np.concatenate((time, fin.variables[vlist3[i2]+'_time'][:]))
            data = np.concatenate((data, fin.variables[vlist[i2]][:]))
        fin.close()

    # # create dimensions
    # fout.createDimension('time', None)
    # fout.createDimension('latitude', eta)
    # fout.createDimension('longitude', xi)

    # # create variables
    # fout.createVariable('time', 'f8', ('time'))
    # fout.createVariable('latitude', 'f8', ('latitude'))
    # fout.createVariable('longitude', 'f8', ('longitude'))
    # fout.createVariable(vlist3[i2], 'f8', ('time', 'latitude', 'longitude'))

    pytime = nc.num2date(time, 'days since 1900-01-01')
    tbase = np.array([datetime(pyt.year, 1, 1) for pyt in pytime])
    tbase = nc.date2num(tbase, 'days since 1900-01-01')
    tbase2 = nc.date2num(datetime(my_year, 1, 1), 'days since 1900-01-01')
    yearday = time - tbase
    # time_clim = np.arange(0, 366, 0.125)
    time_clim = np.unique(yearday)
    data_clim = []

    for tc in time_clim:
        msk = yearday == tc
        data_clim.append(data[msk, :, :].mean(axis=0))

    data_clim = np.array(data_clim)

    fout.variables[vlist3[i2]+'_time'][:] = time_clim + tbase2
    fout.variables[vlist[i2]][:] = data_clim

    fout.close()
    print(out_dir+vlist[i2]+'_clim.nc'+' done...')


import time
import logging
import argparse
import requests
import pandas as pd
from tqdm import tqdm
from bs4 import BeautifulSoup

logger = logging.getLogger()
temps_debut = time.time()

def get_soup(url):
    return BeautifulSoup(requests.get(url).content, features="lxml")

def main():
    args = parse_args()

    with open(args.file) as f:
        parts_urls = f.read().splitlines()

    dict_parts = {}
    header_found = False
    for index, url in tqdm(
        enumerate(parts_urls), total=len(parts_urls), dynamic_ncols=True
    ):
        dict_part = {}
        logger.debug("url : %s", url)
        while True:
            try:
                soup_url = get_soup(url)
            except Exception as e:
                logger.error(e)
                continue
            break

        dict_part["Category"] = soup_url.find(
            "h3", {"class": "pageTitle--categoryTitle"}
        ).text
        dict_part["Name"] = soup_url.find("h1", {"class": "pageTitle"}).text
        logger.debug(
            "Extracting %s - {dict_part['Category']} - {dict_part['Name']} at {url}",
            index,
        )
        dict_part["Link"] = url
        rating = (
            soup_url.find("section", {"class": "xs-col-11"})
            .text.split("\n")[-3]
            .strip()
        )
        dict_part["Ratings"] = rating.split()[0].replace("(", "")
        dict_part["Average rating"] = rating.split()[-2]

        specs = soup_url.find("div", {"class": "specs"})
        specs_title = [title.text for title in specs.find_all("h3")]
        specs_value = [
            title.next_sibling.next_sibling.text.strip()
            for title in specs.find_all("h3")
        ]
        for t, v in zip(specs_title, specs_value):
            dict_part[str(t)] = str(v)

        # Prices per merchants
        table_merchants = soup_url.find("table", {"class": "xs-col-12"})
        if table_merchants:
            shops = [
                x.find("a")["href"].split("/")[2]
                for x in table_merchants.find_all("td", {"class": "td__logo"})
            ]
            prices = [
                x.text
                for x in table_merchants.find_all(
                    "td", {"class": "td__base priority--2"}
                )
            ]
            for s, p in zip(shops, prices):
                dict_part[f"Price {s}"] = str(p)
        else:
            logger.debug("No prices found.")

        # Reviews
        reviews = soup_url.find_all("div", {"class": "partReviews__review"})
        if reviews:
            list_reviews = []
            for review in reviews:
                id = review.find("div", {"class": "partReviews__name"}).find(
                    "a"
                )["href"]
                rating = len(
                    review.find(
                        "div", {"class": "partReviews__name"}
                    ).find_all("svg", {"class": "shape-star-full"})
                )
                text = review.find(
                    "div", {"class": "partReviews__writeup"}
                ).text
                list_reviews.append({"id": id, "rating": rating, "text": text})
            dict_part["Reviews"] = str(list_reviews)

        soup_url.decompose()

        dict_parts[index] = dict_part

        logger.debug("Exporting partial dict")
        new_dict = {k: [v] for k, v in dict_part.items()}
        df = pd.DataFrame(new_dict)
        with open(f"Exports/pcpartpicker-parts-data.csv", "a") as f:
            if header_found:
                df.to_csv(f, header=False)
            else:
                df.to_csv(f)
                header_found = True
        # if index > 30:
        #     break
        time.sleep(2)

    df = pd.DataFrame.from_dict(dict_parts, orient="index")
    categories = df.Category.unique()
    for category in categories:
        temp_df = df[df["Category"] == category]
        temp_df.dropna(axis=1, how="all", inplace=True)
        filename = f"Exports/pcpartpicker-parts-{category}-data.csv"
        print("Writing %s", filename)
        temp_df.to_csv(filename, sep=";")

    print("Runtime : %.2f seconds" % (time.time() - temps_debut))

def parse_args():
    parser = argparse.ArgumentParser(
        description="Scraper pcpartpicker.com (parts)"
    )
    parser.add_argument(
        "--debug",
        help="Display debugging information",
        action="store_const",
        dest="loglevel",
        const=logging.DEBUG,
        default=logging.INFO,
    )
    parser.add_argument(
        "-f",
        "--file",
        type=str,
        help="File containing the urls",
        default="Exports/list_parts_urls.txt",
    )
    args = parser.parse_args()

    logging.basicConfig(level=args.loglevel)
    return args

if __name__ == "__main__":
    main()


import os

def fileListFunc(filePathList):
    fileList = []
    for top, dirs, nondirs in os.walk(filePathList):
        for item in nondirs:
            fileList.append(os.path.join(top, item))
    return fileList

if __name__ == '__main__':
    path = r'E:\google drive'
    arr = fileListFunc(path)
    for a in range(len(arr)):
        print(arr[a])


import sys
import numpy as np
import mujoco
import mujoco_viewer

sys.path += [ "../controllers", "../modules" ]

from basic_control import gravity_compensator
from utils         import min_jerk_traj

# Call the xml model file + data for MuJoCo
dir_name   = '../models/my_robots/'
robot_name = 'double_pendulum.xml'
model = mujoco.MjModel.from_xml_path( dir_name + robot_name )
data  = mujoco.MjData( model )

# Create the viewer object
viewer = mujoco_viewer.MujocoViewer( model, data, hide_menus = True )

# Set numpy print options
np.set_printoptions( precision = 4, threshold = 9, suppress = True )

# Parameters for the simulation
T        = 8.                       # Total Simulation Time
dt       = model.opt.timestep       # Time-step for the simulation (set in xml file)
fps      = 30                       # Frames per second
n_frames = 0                        # The current frame of the simulation
speed    = 1.0                      # The speed of the simulator
t_update = 1./fps * speed           # Time for update

# The time-step defined in the xml file should be smaller than update
assert( dt <= t_update )

# Set the initial condition of the robot
q_init = np.array( [ 1.0, 1.0 ] )
data.qpos[ 0:2 ] = q_init
mujoco.mj_forward( model, data )

# The link masses of the robot
masses = np.array( [ 1. , 1. ] )

# The impedances of the robot
Kq = np.array( [ [ 29.5, 14.3 ], [ 14.3, 39.30 ] ] )
Bq = 0.1 * Kq

# The parameters of the minimum-jerk trajectory.
t0 = 1.
D  = 2.
qi = q_init
qf = q_init + np.array( [ 0.4, 0.4 ] )

# Save the references for the q and dq
q  = data.qpos[ 0:2 ]
dq = data.qvel[ 0:2 ]

while data.time <= T:

    mujoco.mj_step( model, data )

    # Calculate the Torque input for the robot
    # Torque 1: Gravity Compensation Torque
    tau_G = gravity_compensator( model, data, masses, [ "site_COM1", "site_COM2" ] )

    # Torque 2: First-order Joint-space Impedance Controller
    # Calculate the minimum-jerk trajectory
    q0  = np.zeros( model.nu )
    dq0 = np.zeros( model.nu )

    for i in range( model.nq ):
        q0[ i ], dq0[ i ], _ = min_jerk_traj( data.time, t0, t0 + D, qi[ i ], qf[ i ], D )

    tau_imp = Kq @ ( q0 - q ) + Bq @ ( dq0 - dq )

    # Summing up the torque
    data.ctrl[ : ] = tau_G + tau_imp

    # Update Visualization
    if( n_frames != ( data.time // t_update ) ):
        n_frames += 1
        viewer.render( )
        print( "[Time] %6.3f" % data.time )

# close
viewer.close()


import networkx as nx
import json
from itertools import combinations

def dispersion(network_json, u, exclude_nodes=None, normal=True):
    """ An python implementation of 'dispersion' as defined by Lars Backstrom
    and Jon Kleinberg here: http://arxiv.org/pdf/1310.6753v1.pdf
    :param network_json: a graphAlchemist network json object (example in ./data)
    :param u: the interger id of the ego node of the network
    :param exclude_nodes: a list of ids to exclude from dispersion score
    :param normal: return a dispersion score with basic normalization dispersion/embededness
    """

    exclude_nodes = []
    # initialize a networkx graph object
    G_u = nx.Graph()
    # and create a network from "network_json"
    for edge in network_json['edges']:
        start_node = edge['source']
        end_node = edge['target']
        if start_node in exclude_nodes or end_node in exclude_nodes:
            continue
        G_u.add_edge(start_node, end_node)

    dispersion = dict.fromkeys(G_u, 0.0)

    for v in G_u:
        if v == u:
            continue
        mutual = list(nx.all_simple_paths(G_u, u, v, cutoff=2))
        ST = set()
        embededness = len(mutual)
        for m in mutual:
            if (m[1] == u) or (m[1] == v):
                continue
            else:
                ST.add(m[1])

        possib = combinations(ST, 2)
        total = 0
        #each possible path between s and t
        for p in possib:
            s = p[0]
            t = p[1]
            #iterate through the neigbors of s
            neighbors_s = list(G_u.neighbors_iter(s))
            neighbors_t = list(G_u.neighbors_iter(t))
            Q = []
            for n in neighbors_s:
                #if one of the neigbors is t, no dispersion tick
                if (n == t):
                    score = False
                    break
                #if one of the neighbors is not the ego node, or the node we are
                #scoring dispersion for, add them to the que
                elif (n != u) and (n != v):
                    Q.append(n)
                #if one of the neigbors is ego or test node, continue because dispersion
                #allows them to connect to other nodes in the network
                elif (n == u) or (n == v):
                    score = True
            #traverse the nodes in the Q
            if score:
                while Q:
                    i = Q.pop(0)
                    #make sure that s is not directly connected to t
                    #s--t
                    if (i == t):
                        score = False
                        break
                    #make sure that s does not share a neibor with t
                    #s--i--t
                    elif i in neighbors_t:
                        score = False
                        break
                    #continue looping

            #if score is true for the 's' 't' on the possible path called 'p'
            #add a 1 for dispersion
            if score:
                total += 1

        #print total
        dispersion[v] = {'abs_disp': total}
        if normal == True:
            norm_disp = (total/embededness)
            dispersion[v]['norm_disp'] = norm_disp

    return dispersion


from io import BytesIO

from flask import Flask, send_file
from openpyxl import Workbook

app = Flask(__name__)

def get_tdd_excel_workbook():
    wb = Workbook()
    ws = wb.active
    ws.append(['TDD', 'is', 'AWESOME!'])
    ws.append(['Except', 'when', 'it', 'is', 'particularly', 'hard'])
    ws.append(['But', 'we', 'can', 'handle', 'it'])
    return wb

@app.route('/excel/download')
def download_excel():
    wb = get_tdd_excel_workbook()

    file_stream = BytesIO()
    wb.save(file_stream)
    file_stream.seek(0)

    return send_file(file_stream, attachment_filename="tdd-excel.xlsx", as_attachment=True)

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0')


# 1.Write a Python program to find the second smallest number in a list

l = [100, 20, 30, 4]
print(sorted(l)[1])
print("------------")

# 2. Write a Python program to convert a list of multiple integers into a single integer

l = [1, 2, 3, 4, 5]
for i in l:
    print(int(i), end='')
print()
print("------------")

# 3.Write a Python program to check a list is empty or not

l = []
if l == []:
    print("Empty list")
else:
    print("Not Empty")
print("------------")

# 4.Write a Python program to compute the differeces between two lists.
# Sample data: ["red", "orange", "green", "blue", "white"], ["black", "yellow", "green", "blue"]
# Expected Output:
# Color1-Color2: ['white', 'orange', 'red']
# Color2-Color1: ['black', 'yellow']

l1, l2 = ["red", "orange", "blue", "white", "green"], ["black", "yellow", "green", "blue"]
x, y = [], []
for i in l1:
    if i not in l2:
        x.append(i)
for i in l2:
    if i not in l1:
        y.append(i)
print("Color1-Color2 :", x)
print("Color2-Color1 :", y)
print("------------")

# 5.Write a Python program to count the number of characters (character frequency) in a string
# Sample String : google.com'
# Expected Result : {'o': 3, 'g': 2, '.': 1, 'e': 1, 'l': 1, 'm': 1, 'c': 1}

s, d = "google.com", {}
for i in s:
    if d.get(i) == None:
        d[i] = s.count(i)
print(d)
print("------------")

# 6.Write a Python program that takes a list of words and returns the length of the longest one

l, length = ["Python", "program", "write", "a", "returns", "length"], 0
for i in l:
    if length < len(i):
        length = len(i)
print(length)
print("------------")

# 7.Write a Python function to convert a given string to all uppercase if it contains at least 2 uppercase characters in the first 4 characters.

s = "Please enter any string"
count = 0
for i in s[:4]:
    if i.isupper():
        count += 1
    if count == 2:
        print(s.upper())
        break
else:
    print(s)


#unsolved, 이분탐색 활용해서 풀기

N = int(input())
nData = list(map(int, input().split()))
nData.sort()
M = int(input())
mData = list(map(int, input().split()))

for m in mData:
    left = 0
    right = N-1
    mid = (left + right) // 2

    while left < right:
        print(left, mid, right)
        print(m)

        if m > right or m < left:
            print(0)
            break

        if nData[mid] > m:
            right = mid - 1
            mid = right - 1
        elif nData[mid] < m:
            left = mid + 1
            mid = left + 1
        else:
            print(1)
            break


import schedule
import time
import threading

class ScheduleThread(threading.Thread):
	def __init__(self, delay):
		threading.Thread.__init__(self)
		self.cease_running = threading.Event()
		self.delay = delay
	def getStopper(self):
		return self.cease_running
	def run(self):
		while not self.cease_running.is_set():
			print("running")
			schedule.run_pending()
			time.sleep(self.delay)

def job():
	print("I'm working...")

class test:
	def __init__(self):
		self.schThread = ScheduleThread(1)
		self.stopper = schThread.getStopper()
		self.schThread.start()

if __name__ == "__main__":
	schedule.every(5).seconds.do(job)
	for it in range(0, 10):
		print("main loop")
		time.sleep(1)
	stopper.set()


import cv2
import pandas as pd
import os
from vision.visualization.drawer import draw_rectangle, draw_text, draw_highlighted_test, get_color
import numpy as np
from vision.misc.help_func import get_repo_dir, load_json, validate_output_path

def draw_dets(frame, dets, t_index=6):
    """
    Draws bounding boxes and track IDs on the input frame for each detection.

    Args:
        frame (numpy.ndarray): The input frame to draw on.
        dets (numpy.ndarray): A 2D array of detections, where each row is a detection and the columns contains the
            coordinates of the bounding box and the track ID.
        t_index (int, optional): The index of the track ID column in the detections array. Defaults to 6.

    Returns:
        numpy.ndarray: The input frame with bounding boxes and track IDs drawn on it.
    """
    for det in dets:
        track_id = det[t_index]
        color_id = int(track_id) % 15  # 15 is the number of colors in list
        color = get_color(color_id)
        text_color = get_color(-1)
        frame = draw_rectangle(frame, (int(det[0]), int(det[1])), (int(det[2]), int(det[3])), color, 3)
        frame = draw_highlighted_test(frame, f'ID:{int(track_id)}', (det[0], det[1]), frame.shape[1], color, text_color,
                                      True, 10, 3)
    return frame

def write_vid(fsi, tracks_df, s_frame=0, max_frame=np.inf, t_index=6, frame_save_directory=""):
    """
    Writes a new video file with the input tracks_df overlaid on top of the input video file.

    Args:
        fsi (cv2.VideoCapture): The input video file to overlay tracks on top of.
        tracks_df (pandas.DataFrame): A DataFrame containing track data with columns "frame", "x1", "y1", "x2",
            "y2", and "track_id".
        s_frame (int, optional): The starting frame of the output video. Defaults to 0.
        max_frame (int, optional): The maximum number of frames to write to the output video. Defaults to np.inf.
        t_index (int, optional): The index of the track ID column in the detections array. Defaults to 6.
        frame_save_directory (str, optional): path for saving frame by frame images
    """
    i = s_frame
    n = min(cap_fsi.get(cv2.CAP_PROP_FRAME_COUNT), max_frame)
    while cap_fsi.isOpened() and i < max_frame:
        print(f"\r{i}/{n - 1} ({i / (n - s_frame) * 100: .2f}%) frames", end="")
        _, frame_fsi = cap_fsi.read()
        if isinstance(frame_fsi, type(None)):
            break
        if rotate:
            frame_fsi = cv2.rotate(frame_fsi, cv2.ROTATE_90_COUNTERCLOCKWISE)
        dets = tracks_df[tracks_df["frame"] == i].to_numpy()
        if len(dets):
            frame_fsi = draw_dets(frame_fsi, dets, t_index=t_index)
        if frame_save_directory != "":
            cv2.imwrite(os.path.join(frame_save_directory, f"frame_{i}.png"), frame_fsi)
        fsi.write(frame_fsi)
        i += 1
    fsi.release()

def make_vid_with_dets(cap_fsi, tracks_df, rotate, fps=0, new_vid_name="", s_frame=0, max_frame=np.inf
                       , frame_save_directory=""):
    """
    Creates a new video file with detected object tracks overlaid on each frame.

    Args:
        cap_fsi (cv2.VideoCapture): The input video capture object.
        tracks_df (pd.DataFrame): A DataFrame containing object tracks with columns "frame", "x1", "y1", "x2", "y2",
         and "track_id".
        rotate (bool): If True, rotate the video frames by 90 degrees counterclockwise before processing.
        fps (int): The frames per second to use for the output video. If 0, use the same frame rate as the input video.
        new_vid_name (str): The filename to use for the output video. If empty, create a default filename.
        s_frame (int): The index of the starting frame.
        max_frame (int): The maximum number of frames to process.
        frame_save_directory (str, optional): path for saving frame by frame images

    Returns:
        None
    """
    width = int(cap_fsi.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap_fsi.get(cv2.CAP_PROP_FRAME_HEIGHT))
    if rotate:
        width, height = height, width
    if not fps:
        fps = int(cap_fsi.get(cv2.CAP_PROP_FPS))
    if new_vid_name == "":
        new_vid_name = os.path.join(row_path, f'Result_FSI_{side}_with_dets.mkv')
    else:
        new_vid_name = os.path.join(row_path, new_vid_name)
    if frame_save_directory != "":
        validate_output_path(frame_save_directory)
    fsi = cv2.VideoWriter(new_vid_name, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), fps, (width, height))
    cap_fsi.set(cv2.CAP_PROP_POS_FRAMES, s_frame)
    write_vid(fsi, tracks_df, s_frame, max_frame, frame_save_directory=frame_save_directory)

if __name__ == "__main__":
    row_path = r"/media/fruitspec-lab/cam175/APPLECHILE04_test/290323/APPCALIB/R1A"
    rotate = True
    s_frame = 0
    max_frame = 300
    fps = 15
    new_vid_name = ""
    frame_save_directory = "/media/fruitspec-lab/easystore/debugging/APPLECHILE04_test_R1A"

    side = 1 if row_path.endswith("A") else 2
    jai_fp = os.path.join(row_path, f'Result_FSI_{side}.mkv')
    tracks_path = os.path.join(row_path, f'tracks.csv')
    tracks_df = pd.read_csv(tracks_path)
    cap_fsi = cv2.VideoCapture(jai_fp)

    make_vid_with_dets(cap_fsi, tracks_df, rotate, fps=fps, new_vid_name=new_vid_name, s_frame=s_frame,
                       max_frame=max_frame, frame_save_directory=frame_save_directory)


import logging
from typing import Any, Awaitable, Callable, Dict, List, Optional

from hummingbot.client.config.config_helpers import ClientConfigAdapter
from hummingbot.client.settings import AllConnectorSettings, ConnectorSetting
from hummingbot.logger import HummingbotLogger

from .async_utils import safe_ensure_future

class TradingPairFetcher:
    _sf_shared_instance: "TradingPairFetcher" = None
    _tpf_logger: Optional[HummingbotLogger] = None

    @classmethod
    def logger(cls) -> HummingbotLogger:
        if cls._tpf_logger is None:
            cls._tpf_logger = logging.getLogger(__name__)
        return cls._tpf_logger

    @classmethod
    def get_instance(cls, client_config_map: Optional["ClientConfigAdapter"] = None) -> "TradingPairFetcher":
        if cls._sf_shared_instance is None:
            client_config_map = client_config_map or cls._get_client_config_map()
            cls._sf_shared_instance = TradingPairFetcher(client_config_map)
        return cls._sf_shared_instance

    def __init__(self, client_config_map: ClientConfigAdapter):
        self.ready = False
        self.trading_pairs: Dict[str, Any] = {}
        self.fetch_pairs_from_all_exchanges = client_config_map.fetch_pairs_from_all_exchanges
        self._fetch_task = safe_ensure_future(self.fetch_all(client_config_map))

    def _fetch_pairs_from_connector_setting(
            self,
            connector_setting: ConnectorSetting,
            connector_name: Optional[str] = None):
        connector_name = connector_name or connector_setting.name
        connector = connector_setting.non_trading_connector_instance_with_default_configuration()
        safe_ensure_future(self.call_fetch_pairs(connector.all_trading_pairs(), connector_name))

    async def fetch_all(self, client_config_map: ClientConfigAdapter):
        connector_settings = self._all_connector_settings()
        for conn_setting in connector_settings.values():
            # XXX(martin_kou): Some connectors, e.g. uniswap v3, aren't completed yet. Ignore if you can't find the
            # data source module for them.
            try:
                if conn_setting.base_name().endswith("paper_trade"):
                    self._fetch_pairs_from_connector_setting(
                        connector_setting=connector_settings[conn_setting.parent_name],
                        connector_name=conn_setting.name
                    )
                elif not self.fetch_pairs_from_all_exchanges:
                    if conn_setting.connector_connected():
                        self._fetch_pairs_from_connector_setting(connector_setting=conn_setting)
                else:
                    self._fetch_pairs_from_connector_setting(connector_setting=conn_setting)
            except ModuleNotFoundError:
                continue
            except Exception:
                self.logger().exception(f"An error occurred when fetching trading pairs for {conn_setting.name}."
                                        "Please check the logs")
        self.ready = True

    async def call_fetch_pairs(self, fetch_fn: Callable[[], Awaitable[List[str]]], exchange_name: str):
        try:
            pairs = await fetch_fn
            self.trading_pairs[exchange_name] = pairs
        except Exception:
            self.logger().error(f"Connector {exchange_name} failed to retrieve its trading pairs. "
                                f"Trading pairs autocompletion won't work.", exc_info=True)
            # In case of error just assign empty list, this is st. the bot won't stop working
            self.trading_pairs[exchange_name] = []

    def _all_connector_settings(self) -> Dict[str, ConnectorSetting]:
        # Method created to enabling patching in unit tests
        return AllConnectorSettings.get_connector_settings()

    @staticmethod
    def _get_client_config_map() -> "ClientConfigAdapter":
        from hummingbot.client.hummingbot_application import HummingbotApplication

        client_config_map = HummingbotApplication.main_application().client_config_map
        return client_config_map


import pandas as pd
import numpy as np
from sklearn.naive_bayes import BernoulliNB
import math

from apps import db_onnections

def anomality_model(history,predict):
    '''
    model used: Bernoulli Naive Bayse
    :param history: the dataframe with which fit the model
    :param predict: the element to be used for the prediction
    :return: the probability of the user for the given array.

    '''
    user = predict["display_name"]
    history = history.drop(['timestamp'], axis=1)

    history["display_name"] = np.where(history["display_name"] == user, 1, 0)

    df_target = history[history["display_name"] == 1]
    df_core = history[history["display_name"] == 0]

    df_core = df_core.drop_duplicates() # Reduce the "No-events"

    df = df_target.append(df_core)

    model = BernoulliNB()
    label = df['display_name']
    main = df.drop(['display_name'], axis=1)

    model.fit(main, label)

    #print(user)
    predict = predict.drop(['timestamp', 'display_name'])
    #print("### predict #####")

    output = model.predict_proba(np.array(predict).reshape(1,-1))

    return output[0][1]

def checker_anomalitics():#from_data='2018-01-01', border_data= "2018-06-18", end_date= "2018-06-25"

    history, predict = db_onnections.anomalityDB() #from_data= from_data, border_data= border_data, end_date= end_date)

    dataframe = pd.DataFrame()
    for index, item in predict.iterrows():
        ser = pd.Series()
        ser["Display Name"] = item["display_name"]
        ser['Hostname'] = item['Hostname_']
        ser['Protocol'] = item['Protocol_']
        ser['Subnet'] = item['Subnet_']

        item=item.drop(['Hostname_','Protocol_','Subnet_'])

        proba = anomality_model(history=history, predict=item)

        ser["Probability"] = math.sqrt(proba)

        ser["Time"] = pd.to_datetime(item['timestamp'])
        ser["Time"] = pd.to_datetime(ser["Time"])
        ser['Time'] = ser['Time'].strftime("%Y-%m-%d %H:%M:%S")

        dataframe = dataframe.append(ser, ignore_index=True)

        dataframe = dataframe.sort_values("Probability")
        dataframe = dataframe[["Time", "Display Name", "Subnet", "Protocol", "Hostname", "Probability"]]

        dataframe['Time'] = pd.to_datetime(dataframe['Time'])

    return dataframe


import time
import uuid

from BluenetTestSuite.testframework.framework import *
from BluenetTestSuite.firmwarecontrol.datatransport import *
from crownstone_core.protocol.BluenetTypes import ControlType

import datetime

def test_norelayflickeringonboot_loopbody(FW, minimal_relay_half_period_ms):
    """
    Assumes that a state change is reported at the exact moment the relay will be switched.

    Resets the device, then waits for some time to record any state changes. Validates all such
    changes are no closer than [minimal_relay_half_period_ms]
    """
    print("##### setup test_bootloadsflashintooverride_loopbody #####")
    # print("reset firmwarestate recorder")
    FW.clear()

    # print("restart test subject")
    sendCommandToCrownstone(ControlType.RESET, [])

    # print("allow device to reset and startup")
    time.sleep(5)

    # filter relevant history
    relay_history_time_value_pairs = [
        [logentry.time, logentry.value]
        for logentry in FW.historylist if logentry.classname == "Relay" and logentry.valuename == "on"
    ]

    min_time_diff_between_relay_switches = datetime.timedelta(microseconds=minimal_relay_half_period_ms * 1000)

    num_relay_state_changes = len(relay_history_time_value_pairs)
    if num_relay_state_changes < 2:
        # print("too few relay state changes reported during flick test to check period lengths ({0})".format(
        # num_relay_state_changes))
        return TestFramework.success()

    failures = []

    first = relay_history_time_value_pairs[0]
    for second in relay_history_time_value_pairs[1:]:
        if first[1] == second[1]:
            # no state change yet.
            pass
        else:
            state_unchanged_time = second[0] - first[0]
            if state_unchanged_time < min_time_diff_between_relay_switches:
                failures += [TestFramework.failure("found too short relay flick: " + repr(state_unchanged_time))]
            # move to next relay state half-period
            first = second

    return failures if failures else TestFramework.success()

def test_norelayflickeringonboot(FW):
    """
    It's not allowed to see/hear any sudden relay state changes after a reboot.
    """
    print("##### test_bootloadsflashintooverride #####")
    print("override switch state to be sure it is set to fully on, and pause 15 sec to enforce persistence")
    sendCommandToCrownstone(ControlType.SWITCH, [100])

    # need time for persistence of switch state to be pushed.
    time.sleep(15)

    result = []
    for i in range(3):
        result += [test_norelayflickeringonboot_loopbody(FW, 1000)]
    return result

if __name__ == "__main__":
    with TestFramework(test_norelayflickeringonboot) as frame:
        if frame != None:
            for result in frame.test_run():
                print(result)
        else:
            print(TestFramework.failure())


from __future__ import print_function
import os
import sys
import numpy as np
import yaml
import tf.transformations as trans
from copy import deepcopy
from .recording import Recording
from .error import ErrorSet
from .metrics import KPI
import matplotlib.pyplot as plt
import logging
from mpl_toolkits.mplot3d import Axes3D

try:
    plt.rc('text', usetex=True)
    plt.rc('font', family='sans-serif')
except Exception as e:
    print('Cannot use Latex configuration with matplotlib, message=' + str(e))

class Evaluation(object):
    def __init__(self, filename, output_dir='.', time_offset=0.0):
        # Setting up the log
        self._logger = logging.getLogger('run_evaluation')
        if len(self._logger.handlers) == 0:
            out_hdlr = logging.StreamHandler(sys.stdout)
            out_hdlr.setFormatter(logging.Formatter('%(asctime)s | %(levelname)s | %(module)s | %(message)s'))
            out_hdlr.setLevel(logging.INFO)
            self._logger.addHandler(out_hdlr)
            self._logger.setLevel(logging.INFO)

        self._logger.info('Opening bag: %s' % filename)
        self.recording = Recording(filename)

        self.recording.init_parsers()

        # Create error set object
        self._error_set = ErrorSet.get_instance()
        if self._error_set is None:
            self._logger.error('Error set has not been correctly initialized')
            raise Exception('Error set has not been correctly initialized')

        self._error_set.compute_errors()

        # Assigning the output directory for the results
        if not os.path.isdir(output_dir):
            self._logger.error('Invalid output directory, dir=%s' % str(output_dir) )
            raise Exception('Invalid output directory')

        # Simulation time offset to start the computation of each KPI
        if time_offset >= 0.0:
            self._time_offset = time_offset
        else:
            self._logger.error('Invalid time offset, setting time offset to zero')
            self._time_offset = 0.0

        self._logger.info('Time offset for KPI evaluation [s]=' + str(self._time_offset))

        self._output_dir = output_dir
        # Table of configuration parameters (set per default all KPIs)
        self._kpis = list()
        for kpi in KPI.get_all_kpi_tags():
            if KPI.get_kpi_target(kpi) == 'error':
                for error_tag in self._error_set.get_tags():
                    self._kpis.append(dict(func=KPI.get_kpi(kpi, error_tag),
                                           value=0.0))
            else:
                self._kpis.append(dict(func=KPI.get_kpi(kpi),
                                       value=0.0))

        self._cost_fcn_terms = dict()

        # Calculating the KPIs for this bag
        self.compute_kpis()

    def __del__(self):
      if self.recording is not None:
        del self.recording

    @property
    def error_set(self):
        return self._error_set

    def calc_cost_fcn(self):
        cost = 0.0
        for tag in self._cost_fcn_terms:
            cost += self._cost_fcn_terms[tag] * self.get_kpi(tag)
        return cost

    def save_cost_fcn_config(self, filename):
        try:
            with open(filename, 'w') as cost_file:
                yaml.dump(self._cost_fcn_terms, cost_file,
                          default_flow_style=False)
        except Exception as e:
            self._logger.error('Error exporting cost function configuration, message=' + str(e))

    def load_cost_fcn(self, filename):
        if not os.path.isfile(filename):
            self._logger.error('Invalid filename, file=%s' % filename)
            return False
        with open(filename, 'w') as fcn_file:
            fcn = yaml.load(fcn_file)
        try:
            for item in fcn:
                self.add_cost_fcn_term(item, fcn[item])
                self._logger.info('Cost function term (tag, weight): (%s, %.4f)' % (item, fcn[item]))
        except Exception as e:
            self._logger.error('Error loading cost function configuration')
            self._logger.error(e)
            return False
        return True

    def add_cost_fcn_term(self, kpi, weight):
        if weight <= 0:
            self._logger.error('Weight must be a positive value')
            return False
        if not self.has_kpi(kpi):
            self._logger.error('KPI tag is invalid, tag=%s' % kpi)
            return False
        if kpi in self._cost_fcn_terms:
            self._logger.error('KPI already added to the cost function, tag=%s' % kpi)
            return False

        self._cost_fcn_terms[kpi] = weight
        return True

    def has_kpi(self, tag):
        for kpi in self._kpis:
            if tag == kpi.full_tag:
                return True
        return False

    def set_kpis_from_file(self, filename):
        assert os.path.isfile(filename), 'Invalid evaluation configuration file'
        assert '.yaml' in filename or '.yml' in filename, 'Configuration file should be a YAML file'

        with open(filename, 'r') as config_file:
            config = yaml.load(config_file)

        self.set_kpis(config)

    def set_kpis(self, config):
        assert type(config) == list, 'Invalid configuration structure for KPIs'
        kpi_tags = KPI.get_all_kpi_tags()

        self._kpis = list()
        for item in config:
            if item['func'] not in kpi_tags:
                self._logger.error('Invalid KPI tag, value=' + item)
            else:
                self._logger.info('KPI created=' + item['func'])
                if 'args' in item:
                    self._kpis.append(dict(func=KPI.get_kpi(item['func'], item['args']),
                                           value=0.0))
                    self._logger.info('\tArguments: ' + str(item['args']))
                else:
                    self._kpis.append(dict(func=KPI.get_kpi(item['func']),
                                           value=0.0))

    def get_kpis(self):
        kpis = dict()
        for kpi in self._kpis:
            item = kpi['func']
            try:
                kpis[item.full_tag] = float(item.kpi_value)
            except:
                kpis[item.full_tag] = -1000.0
        return kpis

    def get_kpi(self, tag):
        for kpi in self._kpis:
            if kpi['func'].full_tag == tag:
                return kpi['value']
        return None

    def compute_kpis(self):
        if len(self._kpis):
            for i in range(len(self._kpis)):
                try:
                    self._kpis[i]['value'] = self._kpis[i]['func'].compute()
                except Exception as e:
                    self._logger.error('Error calculating KPI %s, message=%s' % (self._kpis[i]['func'].full_tag, str(e)))

    def print_kpis(self):
        for item in self._kpis:
            print(item['func'].full_tag + '= ' + item['value'])

    def get_trajectory_coord(self, tag):
        return self.recording.get_trajectory_coord(tag)

    def export_to_txt(self, tag, output_dir):
        pass

    def save_dataframes(self, output_dir=None):
        if output_dir is not None:
            if not os.path.isdir(output_dir):
                self._logger.error('Invalid output directory, dir=' + str(output_dir))
                raise Exception('Invalid output directory')
        output_path = (self._output_dir if output_dir is None else output_dir)
        try:
            for tag in self.recording.parsers:
                self._logger.info('Reading data frame for ' + tag)
                df = self.recording.parsers[tag].get_as_dataframe()

                if df is None:
                    continue

                if not os.path.isdir(os.path.join(output_path, 'data')):
                    os.makedirs(os.path.join(output_path, 'data'))

                if isinstance(df, dict):
                    for k in df:
                        with open(os.path.join(output_path, 'data', '%s_%s.yaml' % (tag, k)), 'w') as data_file:
                            yaml.dump(df[k].to_dict(), data_file, default_flow_style=False)
                else:
                    with open(os.path.join(output_path, 'data', '%s.yaml' % tag), 'w') as data_file:
                        yaml.dump(df.to_dict(), data_file, default_flow_style=False)
                self._logger.info('Data frame <%s> stored=%s' % (tag, os.path.join(output_path, 'data', '%s.yaml' % tag)))
        except Exception as e:
            self._logger.error('Error storing dataframes file, message=' + str(e))

    def save_evaluation(self, output_dir=None):
        if output_dir is not None:
            if not os.path.isdir(output_dir):
                self._logger.error('Invalid output directory, dir=' + str(output_dir))
                raise Exception('Invalid output directory')
        self.save_kpis(output_dir)

        for tag in self.recording.parsers:
            self.recording.parsers[tag].plot(self._output_dir)
        self._logger.info('Evaluation stored!')

    def save_kpis(self, output_dir=None):
        if output_dir is not None:
            if not os.path.isdir(output_dir):
                self._logger.error('Invalid output directory, dir=' + str(output_dir))
                raise Exception('Invalid output directory')
        try:
            output_path = (self._output_dir if output_dir is None else output_dir)

            kpis = dict()
            kpi_labels = dict()
            for kpi in self._kpis:
                item = kpi['func']
                try:
                    value = float(item.kpi_value)
                except Exception as e:
                    value = 0.0
                kpis[item.full_tag] = value
                kpi_labels[item.full_tag] = kpi['func'].label
            with open(os.path.join(output_path, 'computed_kpis.yaml'), 'w') as kpi_file:
                yaml.dump(kpis, kpi_file, default_flow_style=False)
            self._logger.info('Calculated KPIs stored in <%s>' % os.path.join(output_path, 'computed_kpis.yaml'))

            with open(os.path.join(output_path, 'kpi_labels.yaml'), 'w') as kpi_file:
                yaml.dump(kpi_labels, kpi_file, default_flow_style=False)
            self._logger.info('KPI labels stored in <%s>' % os.path.join(output_path, 'kpi_labels.yaml'))
        except Exception as e:
            self._logger.error('Error storing KPIs file, message=' + str(e))


class Octopus:
    def __init__(self, x, y, energy_level):
        self.x = x
        self.y = y
        self.energy_level = energy_level
        self.neighbors = []
        self.did_flash = False

    def step(self):
        self.energy_level += 1

    def does_flash(self):
        if not self.did_flash and self.energy_level > 9:
            # we flash!
            self.did_flash = True
            self.energy_level = 0
            for n in self.neighbors:
                n.step()
                n.does_flash()

    def reset(self):
        if self.did_flash:
            self.energy_level = 0
        temp = self.did_flash
        self.did_flash = False
        return temp

def read_input():
    with open("puzzle_input.txt", 'r') as f:
        lines = f.readlines()
    return lines

def construct_octopuses():
    lines = read_input()
    mapping = {}
    # construct octopuses
    for r in range(len(lines)):
        for c in range(len(lines[0].strip())):
            octo = Octopus(r, c, int(lines[r][c]))
            mapping["%d%d" % (r, c)] = octo

    # link neighbors
    for r in range(len(lines)):
        for c in range(len(lines[0].strip())):
            current = mapping.get("%d%d" % (r, c))
            if r > 0:
                if c > 0:
                    # top left
                    current.neighbors.append(mapping.get("%d%d" % (r-1, c-1)))
                # top
                current.neighbors.append(mapping.get("%d%d" % (r-1, c)))
                if c < (len(lines[0].strip())-1):
                    # top right
                    current.neighbors.append(mapping.get("%d%d" % (r-1, c+1)))
            if c > 0:
                # left
                current.neighbors.append(mapping.get("%d%d" % (r, c-1)))
            if c < (len(lines[0].strip())-1):
                # right
                current.neighbors.append(mapping.get("%d%d" % (r, c+1)))
            if r < (len(lines) - 1):
                if c > 0:
                    # bottom left
                    current.neighbors.append(mapping.get("%d%d" % (r+1, c-1)))
                # bottom
                current.neighbors.append(mapping.get("%d%d" % (r+1, c)))
                if c < (len(lines[0].strip())-1):
                    # bottom right
                    current.neighbors.append(mapping.get("%d%d" % (r+1, c+1)))
    return mapping

def step_octopuses():
    octopuses = construct_octopuses()
    num_octopuses = len(octopuses)
    for s in range(1000):
        total_flashes = 0
        for o in octopuses:
            octopuses.get(o).step()
        for o in octopuses:
            octopuses.get(o).does_flash()
        for o in octopuses:
            did_flash = octopuses.get(o).reset()
            # print(octopuses.get(o).x, octopuses.get(o).y, octopuses.get(o).energy_level)
            if did_flash:
                total_flashes += 1
        if total_flashes == num_octopuses:
            print(s)
            return


'''

Explanation
Test Case 1:

After round 1, the numbering will be [1, 0, 1, 2]

Test Case 2:

After round 1, the numbering will be [3, 2, 1, 1, 2, 3]
After round 2, the numbering will be [2, 1, 0, 1, 2, 3]

'''

def max_number(n,m,positions):
    max_number = 0
    for i in range(n):
        count = 0
        for j in range(m):
            if i >= positions[j]:
                count += 1
            else:
                count += (positions[j] - i)
        if count > max_number:
            max_number = count
    return max_number

def main():
    T = int(input())
    for i in range(T):
        n,m = map(int,input().split())
        positions = list(map(int,input().split()))
        print(max_number(n,m,positions))

if __name__ == '__main__':
    main()


"""
常用的认证以及DRF的认证
"""
import logging

import jwt
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.utils.six import text_type
from django.utils.translation import ugettext as _
from rest_framework import exceptions
from rest_framework_jwt.utils import jwt_decode_handler

from .jwt_util import jwt_get_session_id
from ..permission.models.users import UserProfile

logger = logging.getLogger(__name__)
User = get_user_model()

class OpAuthJwtAuthentication(object):
    """
    统一JWT认证(环境允许情况下, 推荐使用RedisOpAuthJwtAuthentication)
    """

    def authenticate(self, request):
        token = self.get_header_authorization(request) or self.get_cookie_authorization(request)
        if not token:
            return None
        try:
            payload = jwt_decode_handler(token)
        except jwt.ExpiredSignature:
            msg = _('Signature has expired.')
            raise exceptions.AuthenticationFailed(msg)
        except jwt.DecodeError:
            msg = _('Error decoding signature.')
            raise exceptions.AuthenticationFailed(msg)
        except jwt.InvalidTokenError:
            raise exceptions.AuthenticationFailed()
        except UserProfile.DoesNotExist:
            raise exceptions.AuthenticationFailed()

        username = payload.get('username', None)
        if not username:
            return None
        username_field = settings.USERNAME_FIELD or 'username'
        user = User.objects.filter(**{username_field: username}).first()
        if not user or not user.is_active:
            return None
        return user, token

    def authenticate_header(self, request):
        pass

    @classmethod
    def get_header_authorization(cls, request):
        """
        获取header里的认证信息, 通常用于跨域携带请求
        :param request:
        :return:
        """
        auth = request.META.get('HTTP_AUTHORIZATION', b'')
        if isinstance(auth, text_type):
            auth = auth.encode(settings.JWT_AUTH.get('HTTP_HEADER_ENCODING', 'iso-8859-1'))
        if not auth:
            return ''
        auth = str(auth, encoding='utf-8').split()
        if len(auth) != 2 or auth[0].upper() != settings.JWT_AUTH.get('JWT_AUTH_HEADER_PREFIX', 'JWT').upper():
            return ''
        return auth[1]

    @classmethod
    def get_cookie_authorization(cls, request):
        """
        获取cookie里JWT认证信息
        :param request:
        :return:
        """
        auth = request.COOKIES.get(settings.JWT_AUTH.get('JWT_AUTH_COOKIE', 'AUTH_JWT'), '')
        auth = auth.split()
        if len(auth) != 2 or auth[0].upper() != settings.JWT_AUTH.get('JWT_AUTH_HEADER_PREFIX', 'JWT'):
            return ''
        return auth[1]

class RedisOpAuthJwtAuthentication(OpAuthJwtAuthentication):
    """
    基于Redis的统一JWT认证(推荐使用)
    """
    prefix = settings.JWT_AUTH.get('JWT_AUTH_HEADER_PREFIX', 'JWT')

    def authenticate(self, request):
        res = super().authenticate(request)
        if res:
            user, token = res
            session_id = jwt_get_session_id(token)
            key = f"{self.prefix}_{session_id}_{user.username}"
            redis_token = cache.get(key)
            if redis_token == token:
                return user, token
            else:
                raise exceptions.AuthenticationFailed("登录信息失效，请重新登录！")
        return None