import numpy as np
from scipy.ndimage import zoom
import greedypy.metrics as metrics
import greedypy.regularizers as regularizers
import greedypy.transformer as transformer

class greedypy_registration_method:
    """
    """

    def __init__(
        self,
        fixed, fixed_vox,
        moving, moving_vox,
        iterations,
        shrink_factors,
        smooth_sigmas,
        radius=16,
        early_convergence_ratio=1e-4,
        convergence_test_length=10,
        field_abcd=[0.5, 0., 1., 6.],
        gradient_abcd=[3., 0., 1., 2.],
        dtype=np.float32,
        step=None,
        log=None,
    ):
        """
        """

        error = "iterations, shrink_factors, and smooth_sigmas must be equal length lists"
        assert (len(iterations) == len(shrink_factors) and
                len(iterations) == len(smooth_sigmas)
        ), error

        if step is None:
             step = fixed_vox.min()
        self.__dict__.update(locals())
        self.phi = None
        self.warped = None
        self.invphi = None
        self.mask = None
        self.initial_transform = None

    def set_mask(self, mask):
        """
        """

        self.mask = mask

    def mask_values(self, values):
        """
        """

        if self.mask is None:
            self.mask = np.ones_like(self.moving)
        if type(values) is not list:
            values = [values,]
        for value in values:
            self.mask[self.moving == value] = 0

    def set_initial_transform(self, initial_transform):
        """
        """

        self.initial_transform = initial_transform

    def get_warp(self):
        """
        """

        return self.phi

    def get_inverse_warp(self):
        """
        """

        trans = transformer.transformer(
            self.fixed.shape, self.fixed_vox, dtype=self.dtype,
        )
        self.invphi = trans.invert(self.phi)
        return self.invphi

    def get_warped_image(self):
        """
        """

        return self.warped

    def optimize(self):
        """
        """

        # loop over resolution levels
        for level, local_iterations in enumerate(self.iterations):

            # resample images
            fixed = self._downsample(
                self.fixed,
                self.fixed_vox,
                1./self.shrink_factors[level],
                alpha=self.smooth_sigmas[level],
            )
            moving = self._downsample(
                self.moving,
                self.moving_vox,
                1./self.shrink_factors[level],
                alpha=self.smooth_sigmas[level],
            )

            # new voxel sizes and step
            fixed_vox = self.fixed_vox * self.shrink_factors[level]
            moving_vox = self.moving_vox * self.shrink_factors[level]
            step = self.step * self.shrink_factors[level]

            # initialize or resample the transform
            if self.phi is None:
                phi = np.zeros(
                    fixed.shape + (len(fixed.shape),),
                    dtype=self.dtype,
                )
            else:
                zoom_factor = np.array(fixed.shape) / np.array(self.phi.shape[:-1])
                phi = [zoom(self.phi[..., i], zoom_factor, order=3, mode='nearest')
                    for i in range(3)
                ]
                phi = np.ascontiguousarray(np.moveaxis(np.array(phi), 0, -1))
            self.phi = phi

            # resample the residual mask
            if self.mask is not None:
                mask = self._downsample(
                    self.mask,
                    self.fixed_vox,
                    1./self.shrink_factors[level],
                    alpha=self.smooth_sigmas[level],
                    order=0,
                )

            # transformer
            trans = transformer.transformer(
                fixed.shape, fixed_vox,
                initial_transform=self.initial_transform,
                dtype=self.dtype
            )

            # smoothers
            field_smoother = regularizers.differential(
                self.field_abcd[0] * self.shrink_factors[level],
                *self.field_abcd[1:], fixed_vox, fixed.shape, self.dtype,
            )
            grad_smoother = regularizers.differential(
                self.gradient_abcd[0] * self.shrink_factors[level],
                *self.gradient_abcd[1:], fixed_vox, fixed.shape, self.dtype,
            )

            # metric
            metric = metrics.local_correlation(fixed, moving, self.radius)

            # optimization variables
            iteration = 0
            converged = False
            energy_history = []

            # optimize at this level
            while iteration < local_iterations and not converged:

                # compute the residual
                warped = trans.apply_transform(moving, phi)
                energy, gradient = metric.gradient(fixed, warped, self.radius, fixed_vox)
                gradient = grad_smoother.smooth(gradient)

                # apply moving image mask to residual
                if self.mask is not None:
                    gradient = gradient * mask[..., None]

                # monitor the optimization
                if iteration == 0:
                     initial_energy = energy
                if iteration < self.convergence_test_length:
                    energy_history.append(energy)
                else:
                    energy_history.pop(0)
                    energy_history.append(energy)
                    x = np.gradient(energy_history).mean()
                    y = initial_energy - energy_history[-1]
                    if x > 0 or abs( x/y ) < self.early_convergence_ratio:
                        converged = True

                # make the gradient descent update
                scale = step / np.linalg.norm(gradient, axis=-1).max()
                phi = phi - scale * gradient
                phi = field_smoother.smooth(phi)

                # record progress
                self._record("Level: {}, Iteration: {}, Energy: {}".format(level, iteration, energy))

                # the wheel keeps on spinning
                iteration = iteration + 1

            # store the transform for the next level
            self.phi = phi
            self.warped = warped

    def _downsample(self, image, spacing, zoom_factor, alpha=1., order=1):
        """
        """

        if zoom_factor > 1.:
            raise ValueError('zoom_factor must be less than 1 for _downsample')
        if zoom_factor == 1. and alpha == 0.:
            return image

        smoother = regularizers.differential(
            alpha, 0., 1., 2.,
            spacing,
            image.shape,
            dtype=self.dtype,
        )
        return zoom(
            smoother.smooth(image),
            zoom_factor, mode='reflect', order=order,
        )

    def _record(self, message):
        """
        """

        print(message)
        if self.log is not None:
            print(message, file=self.log)


import pandas as pd
import numpy as np
import ftapp.core.constants as constants
import pickle
import time
import matplotlib.pyplot as plt
import io
import base64
timestamp = time.strftime('%Y%m%d%H%M')
import datetime as dt
import os

from flask import Flask

from ftapp import logger
import seaborn as sns
from ftapp import db
from factor_analyzer import FactorAnalyzer
import traceback
from sklearn.model_selection import GridSearchCV
from yellowbrick.classifier import ClassificationReport

#models
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import scale
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import plot_confusion_matrix

from sklearn.model_selection import train_test_split
#train test split
from definitions import ROOT_DIR

def split_data(x,y, split):
    #remove FB from the list
    fb_idx = x.index.get_loc('FB')
    fb_x = x.loc['FB']
    x.drop(['FB'])
    print("y",y)
    print("fb_idx", fb_idx)
    fb_y = y.iloc[fb_idx]
    y.drop([fb_idx])
    X_train, X_test, y_train, y_test, idx_train, idx_test = train_test_split(x, y, x.index, test_size=split)

    X_test = X_test.append(fb_x)
    y_test = y_test.append(fb_y)
    print("idx_test", idx_test)
    idx_test = idx_test.append(pd.Index(['FB']))
    print("idx_test")
    for each in idx_test:
        if each =='FB':
            print("YES ADDED FB to idx")
    for each in X_test.index:
        if each =='FB':
            print("YES ADDED FB to test")

    return X_train, X_test, y_train, y_test, idx_train, idx_test

def get_data(symbols, dates, addSPY=True, colname = constants.CLOSE_COLUMN):
    '''

    :param symbols:
    :param dates:
    :param addSPY:
    :param colname:
    :return: data df
    '''

    df = pd.DataFrame(index=dates)
    # add SPY if not already in symbols
    if addSPY and 'SPY' not in symbols:
        symbols = ['SPY'] + symbols

        # loop over all the stocks in the list and add to the column
    for symbol in symbols:
        file_name = os.path.join(ROOT_DIR, constants.MARKETDATA_FOLDER, symbol+'.csv')

        df_temp = pd.read_csv(file_name, index_col='Date',
                              parse_dates=True, usecols=['Date', colname], na_values=['nan'])
        df_temp = df_temp.rename(columns={colname: symbol})
        df = df.join(df_temp)
        # filter out the days where SPY is not available - non-trading days
        if symbol == 'SPY':
            df = df.dropna(subset=["SPY"])

    return df

# helper function to compute the portfolio values
def compute_portvals(orders, start_date, end_date, start_val=constants.SV, commission=constants.COMMISSION, impact=constants.IMPACT, ):

    orders = orders.sort_index()
    stock_list = list(set(orders["Symbol"]))

    print("portval start, end", start_date, end_date)

    dates = pd.date_range(start_date, end_date)

    price = get_data(stock_list, dates)

    price.fillna(method='ffill', inplace=True)
    price.fillna(method='bfill', inplace=True)

    price["cash"] = 1.0

    trades = pd.DataFrame(np.zeros((price.shape)), price.index, price.columns)

    mask = (orders['Order'] == "SELL")
    orders['Shares'] = orders['Shares'].mask(mask, -1 * orders["Shares"])

    for i, row in orders.iterrows():
        try:
            trades.loc[i, row["Symbol"]] = trades.loc[i, row["Symbol"]] + row["Shares"]
            trades.loc[i, 'cash'] = trades.loc[i, 'cash'] - row["Shares"] * price.loc[
                i, row["Symbol"]] - commission - abs(row["Shares"]) * price.loc[i, row["Symbol"]] * impact
        except:
            pass

    holdings = pd.DataFrame(np.zeros((price.shape)), price.index, price.columns)
    print(holdings)

    holdings.iloc[0, :-1] = trades.iloc[0, :-1].copy()
    holdings.iloc[0, -1] = trades.iloc[0, -1] + start_val

    for i in range(1, len(trades.index.values)):
        holdings.iloc[i] = holdings.iloc[i - 1] + trades.iloc[i]
    values = holdings * price

    values['portval'] = values.sum(axis=1)
    portval = values['portval']

    return portval

def generate_data(df_trades, symbol, start, end, sv, commission, impact, mode):
    # run model and generate data for graph
    '''
    Return:
    - portvals
    - trades
    - benchmark

    '''
    print(df_trades)
    df_b = df_trades.loc[df_trades.iloc[:, 0] > 0]
    if len(df_b) > 0:
        df_b.loc[:, 'Order'] = "Buy"

    df_s = df_trades.loc[df_trades['Shares'] < 0]
    if len(df_s) > 0:
        df_s.loc[:, 'Order'] = "Sell"
    trades = pd.concat([df_b, df_s])
    trades = trades.sort_index()

    portvals = compute_portvals(trades, start, end, start_val=sv, commission=commission, impact=impact)
    print(portvals)

    if isinstance(portvals, pd.DataFrame):
        portvals_test = portvals[portvals.columns[0]]  # just get the first column
    else:
        "warning, code did not return a DataFrame"

    dates = pd.date_range(start, end)

    # print portvals
    price = get_data([symbol], dates)[symbol]

    benchmark = pd.DataFrame(0, portvals.index, columns=["Benchmark_Return"])
    cash = sv - price[0] * 1000
    benchmark = cash + price * 1000
    benchmark[0] = sv

    #

    # save portfolio value history to disk
    with open('{}/{}-{}.p'.format(constants.PORTVAL_FOLDER,timestamp, mode), 'wb') as fp:
        pickle.dump(portvals, fp)

    print(portvals)
    return portvals, benchmark

#helper function to get the stats
def compute_stat(prices, rfr = constants.RFR):
    daily_rets = (prices/prices.shift(1))-1
    #print portvals
    #print portvals.shift(1)
    daily_rets = daily_rets[1:]
    cr = (prices[-1]/prices[0])-1
    adr = daily_rets.mean()
    sddr = daily_rets.std()
    sr = np.sqrt(252) * (daily_rets - rfr).mean() / sddr

    return cr, adr, sddr, sr

def get_IPO_dates(ticker):
    '''

    :param ticker: given ticker
    :return: str dates
    '''
    df = pd.read_csv('{}/{}.csv'.format(constants.USERDATA_FOLDER, constants.IPO_DATA), index_col = 0)

    ticker_dates = df.loc[ticker]
    ipo = dt.datetime.strptime(ticker_dates[0], '%m/%d/%Y')
    lockup = dt.datetime.strptime(ticker_dates[1], '%m/%d/%Y')
    return ipo, lockup

def print_stats(portvals, benchmark,name,start, end, rfr = constants.RFR):

    #compute stats
    cum_ret, avg_daily_ret, std_daily_ret, sharpe_ratio = compute_stat(portvals, rfr=0.0)
    cum_ret_SPY, avg_daily_ret_SPY, std_daily_ret_SPY, sharpe_ratio_SPY = compute_stat(benchmark, rfr=0.0)

    #print out results
    print ("%s Dataset"%(name))
    print ("Date Range: {} to {}".format(start, end))
    print ()
    print ("Sharpe Ratio of Fund: {}".format(sharpe_ratio))
    print ("Sharpe Ratio of Buy & Hold : {}".format(sharpe_ratio_SPY))
    print()
    print ("Cumulative Return of Fund: {}".format(cum_ret))
    print ("Cumulative Return of Buy & Hold : {}".format(cum_ret_SPY))
    print()
    print ("Standard Deviation of Fund: {}".format(std_daily_ret))
    print ("Standard Deviation of Buy & Hold : {}".format(std_daily_ret_SPY))
    print()
    print ("Average Daily Return of Fund: {}".format(avg_daily_ret))
    print ("Average Daily Return of Buy & Hold : {}".format(avg_daily_ret_SPY))
    print()
    print ("Final Portfolio Value: {}".format(portvals[-1]))
    return None

app = Flask(__name__)
UPLOAD_FOLDER = './user_data'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def load_screener_data( inputFile):

    log_info = f'Start to upload screening factors with {inputFile}'
    print(log_info)
    print(log_info)
    #filename = f'{constants.USERINPUT_FOLDER}/{inputFile}'
    try:
        filename =os.path.join(app.config['UPLOAD_FOLDER'],inputFile)
        print("filename", filename)
        input = pd.read_csv(filename, index_col=0)
        print("input", input.head())
        print("load data success")
        '''if y_col ==-1:
            y = input[y_col]
            buy_info = BuyInfo.query.filter(BuyInfo.indicator_id==indicator_id, BuyInfo.symbol==symbol, BuyInfo.buydate==dbDate).first()
            if (not buy_info and math.isnan(float(buyprice)) == False and buyprice > 0.0001):
                buyinfo = BuyInfo(buydate=dbDate, symbol=symbol, buyprice=buyprice, openprice=openprice, closeprice=closeprice, highprice=highprice, lowprice=lowprice, indicator_id=indicator_id)
                db.session.add(buyinfo)

        db.session.commit()
        logger.info('Finish to upload buy indicator')'''
        return input

    except Exception:
        print("Exception for initialing ")
        logger.exception(f'Exceptiion for initialing test')
        traceback.print_exc()

def clean_data(input, cat_cols, num_cols):

    #sring split
    print("cat cols", cat_cols)
    print("num_cols", num_cols)
    if cat_cols =='0':
        pass
    elif cat_cols == '-1':
        cat_cols = input.columns.drop(num_cols)
        for each in cat_cols:
            print(input[each])
            input[each] = pd.factorize(input[each])[0]
    else:
        x = cat_cols.split(',')
        print(x)
        for each in x:
            print(input[each])
            input[each] = pd.factorize(input[each])[0]

    if num_cols =='0':
        pass
    elif num_cols == '-1':
        num_cols = input.columns.drop(x)
        input[num_cols] = input[num_cols].apply(pd.to_numeric, errors='coerce')
    else:
        num_cols = num_cols.split(',')
        print(num_cols)
        input[num_cols] = input[num_cols].apply(pd.to_numeric, errors='coerce')
    return input

# loadings
def discretize_y(X_tensor, Y_matrix, upper_percentile=60, lower_percentile=40):
    img = io.BytesIO()

    plt.switch_backend('Agg')

    plt.style.use('ggplot')
    n_stocks, n_factors = np.shape(X_tensor)
    print("Y", Y_matrix)
    upper = np.percentile(Y_matrix, upper_percentile)
    lower = np.percentile(Y_matrix, lower_percentile)

    Y_binary = np.zeros(n_stocks)

    for i in range(n_stocks):
        print("value", Y_matrix.iloc[i])
        if Y_matrix.iloc[i] > upper:
            Y_binary[i] = 1
        elif Y_matrix.iloc[i] <= lower:
            Y_binary[i] = -1

    #print(Y_binary)
    return Y_binary

def create_graph(portvals, benchmark, trades_df, name, save = False, show = True):
    #print(benchmark)
    img = io.BytesIO()

    plt.switch_backend('Agg')

    plt.style.use('ggplot')

    b_temp = benchmark / benchmark.iloc[0]
    pv_temp = portvals / portvals.iloc[0]
    plt.plot(b_temp, label='Benchmark (Buy & Hold)', color="g")
    plt.plot(pv_temp, label='Portfolio', color="r")
    buys = trades_df["Shares"] > 0
    sells = trades_df["Shares"] < 0
    print("buys",trades_df.index[trades_df["Shares"] >0].tolist())
    for i in range(len(trades_df)):
        if trades_df.iloc[i]["Shares"] > 0:
            plt.axvline(x=trades_df.index[i],label = 'Buys (Long)', color='blue')
        elif trades_df.iloc[i]["Shares"] < 0:
            plt.axvline(x=trades_df.index[i], label = 'Sells (Short)', color='black')
    name = name
    plt.xlabel('Date')
    plt.xticks(rotation=70)
    plt.ylabel('Normalized Daily Value')
    plt.title('Deep Reinforcement Learner vs Benchmark Performance - ' + str(name))

    handles, labels = plt.gca().get_legend_handles_labels()
    by_label = dict(zip(labels, handles))
    plt.legend(by_label.values(), by_label.keys())

    plt.savefig(img, format='png')

    img.seek(0)
    graph_url = base64.b64encode(img.getvalue()).decode()
    plt.close()

    return 'data:image/png;base64,{}'.format(graph_url)

def save(x,y, screener_name):
    x.to_csv('./user_data/{}-x.csv'.format(screener_name))
    pd.DataFrame(y).to_csv('./user_data/{}-y.csv'.format(screener_name))

def eigenvalues_plt(data):
    img = io.BytesIO()

    plt.switch_backend('Agg')

    plt.style.use('ggplot')
    fa = FactorAnalyzer()
    fa.fit(data)
    eigen_values, vectors = fa.get_eigenvalues()
    plt.figure(figsize=(10, 10))
    plt.scatter(range(1, data.shape[1] + 1), eigen_values)
    plt.plot(range(1, data.shape[1] + 1), eigen_values)
    plt.title('Factor Importance by Eigenvalues')

    plt.xlabel('Factors')
    plt.ylabel('Eigenvalue')
    plt.grid()

    plt.savefig(img, format='png')

    img.seek(0)
    graph_url = base64.b64encode(img.getvalue()).decode()
    plt.close()

    return 'data:image/png;base64,{}'.format(graph_url)

def corr_matrix(data):
    img = io.BytesIO()

    plt.switch_backend('Agg')

    plt.style.use('ggplot')
    data.columns = ["V"+str(i) for i in range(1, len(data.columns)+1)]  # rename column names to be similar to R naming convention
    # financials.V1 = financials.V1.astype(str)
    # X = financials  # independent variables data

    corrmat = data.corr()
    plt.figure(figsize=(10, 10))
    sns.heatmap(corrmat, vmax=1., square=False, cmap="YlGnBu").xaxis.tick_top()
    plt.title('Correlation Matrix')
    plt.savefig(img, format='png')

    img.seek(0)
    graph_url = base64.b64encode(img.getvalue()).decode()
    plt.close()

    return 'data:image/png;base64,{}'.format(graph_url)

def mosthighlycorrelated(mydataframe, numtoreport):
    # find the correlations
    cormatrix = mydataframe.corr()
    # set the correlations on the diagonal or lower triangle to zero,
    # so they will not be reported as the highest ones:
    cormatrix *= np.tri(*cormatrix.values.shape, k=-1).T
    # find the top n correlations
    cormatrix = cormatrix.stack()
    cormatrix = cormatrix.reindex(cormatrix.abs().sort_values(ascending=False).index).reset_index()
    # assign human-friendly names
    cormatrix.columns = ["FirstVariable", "SecondVariable", "Correlation"]
    return cormatrix.head(numtoreport)

def standardize(x):
    standardisedX = scale(x)
    standardisedX = pd.DataFrame(standardisedX, index=x.index, columns=x.columns)
    standardisedX.apply(np.mean)
    standardisedX.apply(np.std)
    return standardisedX

def pca_summary(pca, standardised_data):
    names = ["PC"+str(i) for i in range(1, len(pca.explained_variance_ratio_)+1)]
    a = list(np.std(pca.transform(standardised_data), axis=0))
    b = list(pca.explained_variance_ratio_)
    c = [np.sum(pca.explained_variance_ratio_[:i]) for i in range(1, len(pca.explained_variance_ratio_)+1)]
    columns = pd.MultiIndex.from_tuples([("sdev", "Standard deviation"), ("varprop", "Proportion of Variance"), ("cumprop", "Cumulative Proportion")])
    summary = pd.DataFrame(zip(a, b, c), index=names, columns=columns)
    return summary

param_grid = {"Decision Tree": [
  {'n_estimators': [7,8,9,10,11,100,400,1000],
   'algorithm':['SAMME.R','SAMME' ],
   'learning_rate': [0.05,0.1,0.2,0.3, 0.4,0.8,1.0]}
 ],
    "Random Forest": [{'n_estimators': [700, 800, 900],
    'max_features': ['auto', 'sqrt', 'log2'],
    'criterion': ['gini', 'entropy'],
    'min_samples_split':[2,3,4],
    'max_depth':[None,10,20]
}],
    "Ada Boost": [
  {'n_estimators': [7,8,9,10,11,100,400,1000],'algorithm':['SAMME.R','SAMME' ],'learning_rate': [0.05,0.1,0.2,0.3, 0.4,0.8,1.0]}
 ],
    "Neural Network": [
  {'fit_intercept':[True, False],'normalize':[True, False]}
 ]
}

choices=[(1,'Decision Tree'),(2,'Ada Boost'), (3,'Neural Network'), (4,'Random Forest')]

models = [DecisionTreeClassifier(),\
          AdaBoostClassifier(n_estimators=100, learning_rate=0.6, random_state=0),\
          LinearRegression(), \
          RandomForestClassifier(max_features= 'sqrt' ,n_estimators=700, oob_score = True) ]

def evaluate(model, X_train, X_test, y_train, y_test, optimize =False, cv = 5):
    print("model", int(model))
    clf = models[int(model)-1]
    if optimize:
        clf = GridSearchCV(clf, param_grid[model], cv=cv)
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    score = clf.score(X_test, y_test)

    return score, y_pred, clf

def confusion_matrix(classifier, x,y):
    img = io.BytesIO()

    plt.switch_backend('Agg')

    plt.style.use('ggplot')
    plt.figure(figsize=(10, 10))
    print(classifier)

    plot_confusion_matrix(classifier, x, y, cmap='YlGnBu')

    plt.title('Correlation Matrix')
    plt.savefig(img, format='png')

    img.seek(0)
    graph_url = base64.b64encode(img.getvalue()).decode()
    plt.close()

    return 'data:image/png;base64,{}'.format(graph_url)

def classificationreport(clf, classes, X_train, y_train, X_test, y_test):
    #classes = ['increase','little change', 'decrease']
    img = io.BytesIO()

    #plt.switch_backend('Agg')

    #plt.style.use('ggplot')

    visualizer = ClassificationReport(clf, classes=classes, support=True)

    visualizer.fit(X_train, y_train)        # Fit the visualizer and the model
    visualizer.score(X_test, y_test)        # Evaluate the model on the test data
    visualizer.show(outpath = img)                       # Finalize and show the figure
    plt.figure(figsize=(8, 8))

    img.seek(0)
    graph_url = base64.b64encode(img.getvalue()).decode()
    return 'data:image/png;base64,{}'.format(graph_url)

def get_stocks_classification(y, index):
    increase = []
    stay = []
    decrease = []
    for i in range(len(y)):
        if y[i]==-1:
            decrease.append(index[i])
        elif y[i]==1:
            increase.append(index[i])
        else:
            stay.append(index[i])
    return increase, stay, decrease


# @Author  : ymy
# @Email   : yaomingyong@wanshare.com
# @Time    : 18-9-7 下午3:56

# 充币检测
import time
from source import config
import logging
from datetime import datetime

from eth_utils import to_normalized_address
from web3.utils.encoding import hexstr_if_str, to_hex

from source.common.utils.tools import from_unit
from source.model.database import Recharge, Session, BlockInfo, CoinSetting, Account
from source.common.chain_driver.erc20_operator.erc20 import ERC20Token
from source.poll.rpc_call import recharge

coin_type = 'ETH'
logger = logging.getLogger('recharge')
block_info_document = BlockInfo
coin_address_document = Account
coin_recharge_document = Recharge
coin_setting_document = CoinSetting

def get_black_list():
    return [config.eth_tb_address]

def check_account_exists(session, address):
    rv = session.query(coin_address_document
                       ).filter_by(**{'pub_address': address})
    result = bool(rv.first())
    return result

def tx_process(session, tx_id, operator: ERC20Token):
    """交易处理函数"""

    tx_data = operator.get_transaction_data(tx_id)
    from_address = tx_data.from_address
    black_list = get_black_list()
    if from_address in black_list:
        return

    if not check_account_exists(session, tx_data.to_address):
        return

    coin = coin_type
    if tx_data.token_address:
        coin_info = session.query(
            coin_setting_document
        ).filter_by(coin_setting_document.token_address.in_(
            (tx_data.token_address, to_normalized_address(
                tx_data.token_address)))).first()
        if not coin_info:
            logger.error(f'not found token address: {tx_data.token_address}')
            return
        coin = coin_info.coin_type
        tx_data.token_amount = from_unit(
            tx_data.token_amount, coin_info.token_unit)

    recharge_record = session.query(coin_recharge_document
                                    ).filter_by(txid=tx_id).first()
    if recharge_record:
        return

    data = {
        'amount': tx_data.ether_amount,
        'txid': tx_id,
        'created_at': datetime.utcnow(),
        'confirmation_count': tx_data.num_confirmations,
        'from_address': tx_data.from_address,
        'to_address': tx_data.to_address,
        'coin_type': coin,
        'coin_series': coin_type,
    }
    r = Recharge(**data)
    session.add(r)
    try:
        session.commit()
    except Exception as e:
        logger.exception("冲币记录到数据库时发生错误{}".format(e))
        session.rollback()
        raise
    else:
        recharge(address=data["to_address"],
                 from_address=data["from_address"],
                 amount=float(data["amount"]),
                 txid=data["txid"],
                 coin_type=data["coin_type"],
                 confirmations=data["confirmation_count"],
                 status=0,
                 destination_tag=None)
        logger.info('检测到{}充币到{}{}个'.format(
            tx_data.from_address, tx_data.to_address,
            tx_data.ether_amount)
        )

def check_block(block_info, operator: ERC20Token):
    """检查区块是否回滚"""
    if not block_info:
        return False
    info = operator.get_block(int(block_info.block_num) + 1)
    if not info:
        return False
    if hexstr_if_str(to_hex, info['parentHash']) == block_info.block_hash:
        new_block_info = {'block_num': int(info['number']),
                          'block_hash': hexstr_if_str(to_hex, info['hash']),
                          'coin_type': coin_type}
    else:
        new_block_info = {
            'coin_type': coin_type,
            'block_num': int(block_info.block_num
                             ) - int(config.eth_confirmations),
        }
        roll_back_info = operator.get_block(new_block_info['block_num'])
        new_block_info['block_hash'] = hexstr_if_str(
            to_hex, roll_back_info['hash'])
        new_block_info = {'block_num': int(roll_back_info['number']),
                          'block_hash': hexstr_if_str(to_hex,
                                                      roll_back_info['hash']),
                          'coin_type': coin_type}
    return new_block_info

def init_block_info(session):
    """第一次初始化数据库区块信息"""
    block_info = session.query(BlockInfo).filter_by(
        coin_type=coin_type).first()
    if block_info:
        return

    while True:
        try:
            operator = ERC20Token(provider_endpoint=config.eth_wallet_url)
            info = operator.get_block(int(operator.get_block_number()))
            block_info = BlockInfo(**{'block_num': int(info['number']),
                                      'block_hash': hexstr_if_str(
                                          to_hex, info['hash']),
                                      'coin_type': coin_type})
            session.add(block_info)
            session.commit()
            logger.info('block_info init success')
            break
        except Exception as e:
            logger.exception("初始化区块失败{}".format(e))
            session.rollback()
        time.sleep(15)

def main():
    session = Session()
    init_block_info(session)
    while True:
        try:
            operator = ERC20Token(provider_endpoint=config.eth_wallet_url)
            # 获取区块信息及交易列表
            block_info = session.query(block_info_document
                                       ).filter_by(coin_type=coin_type).first()
            checked_block_info = check_block(block_info, operator)

            if not checked_block_info:
                continue

            tx_list = operator.get_block_tx_id_list(checked_block_info['block_num'])
            # 遍历交易列表
            for tx_id in tx_list:
                tx_process(session, hexstr_if_str(to_hex, tx_id), operator)
            logger.info(
                f'pull block finished: {checked_block_info["block_num"]}'
            )
        except Exception as e:
            logger.exception(e)
        else:
            block_info.block_hash = checked_block_info['block_hash']
            block_info.block_num = checked_block_info['block_num']
            try:
                session.commit()
            except Exception as e:
                logger.exception("更新区块发生错误{}".format(e))
                session.rollback()
        time.sleep(3)

if __name__ == '__main__':
    main()


import time
from multiprocessing import Process
from concurrent.futures import ProcessPoolExecutor

"""
@dev: creating a new process takes a bit more time than a thread
@dev: if we try to run `complex_calculation` & `ask_user` concurrently, we'll get an
      EOF because the input was not given and the calc started
      However, running both complex calcs will work (if multi-core CPU)
Summary:
- when we need to wait for something -> threads
- when we need to run 2+ things at the same time -> multiprocess
"""

def ask_user():
    start = time.time()
    # blocking operation: the main thread is block waiting for smtg to happen
    user_input = input("Enter your name: ")
    greet = f"Hello, {user_input}"
    print(greet)
    print(f"ask_user, {time.time() - start}")

def complex_calculation():
    start = time.time()
    print("Started calculating...")
    [x**2 for x in range(90000000)]
    print(f"complex_calculation, {time.time() - start}")

def single_thread():
    """run 2 different functions sequentially"""
    start = time.time()
    ask_user()
    complex_calculation()
    print(f"single thread total time, {time.time() - start}")

def multiple_processes():
    process1 = Process(target=complex_calculation)
    process2 = Process(target=complex_calculation)

    process1.start()
    process2.start()

    start = time.time()

    process1.join()
    process2.join()

    print(f"2-process total time, {time.time() - start}")

def multi_processes_pool():
    start = time.time()

    with ProcessPoolExecutor(max_workers=2) as pool:
        pool.submit(complex_calculation)
        pool.submit(complex_calculation)

    print(f"2-process total time (pool), {time.time() - start}")

def test():
    # single_thread()
    # multiple_processes()
    multi_processes_pool()

"""
1) multiple_processes

Started calculating...
Started calculating...
complex_calculation, 3.940844774246216
complex_calculation, 3.942923069000244
2-process total time, 4.473669767379761
"""


# --- Imports --- #

import pytmx
import pygame
import sprites, local

# --- TiledMap Class --- #

class TiledMap(sprites.Sprite):
    def __init__(self, day=1, x=0):

        if day % 1 == 0:
            self.type = 0
        else:
            if int(day) % 5 == 0:
                self.type = 2
            else:
                self.type = 1

    @property
    def type(self):
    	return self.__type

    @type.setter
    def type(self, type):

        self.__type = type
        if self.__type == 1 or self.__type == 2:
            type = 1
        else:
            type = 0

        self.__tmxdata = pytmx.load_pygame(f"{local.IMAGE_PATH}/{type}.tmx", pixelalpha=True)
        self.width = self.__tmxdata.width * self.__tmxdata.tilewidth
        self.height = self.__tmxdata.height * self.__tmxdata.tileheight

        if hasattr(self, "rect"):
            x = self.rect.x
            self.update((self.width, self.height))
            self.rect.x = x
        else:
            super().__init__((self.width, self.height))
        self.render()

    def render(self):

        self.image.fill((0,)*4)
        for layer in self.__tmxdata.visible_layers:
            if isinstance(layer, pytmx.TiledTileLayer):
                for x, y, gid, in layer:
                    tile = self.__tmxdata.get_tile_image_by_gid(gid)
                    if tile:
                        self.image.blit(tile, (x * self.__tmxdata.tilewidth, y * self.__tmxdata.tileheight))

# --- Camera Class --- #

class Camera:
    def __init__(self, size):
        self.rect = pygame.rect.Rect((0,)*2, size)
        self.width = size[0]
        self.height = size[1]

    def apply(self, entity):

        if isinstance(entity, pygame.rect.Rect):
            return rect.move(self.rect.topleft)
        else:
            return entity.rect.move(self.rect.topleft)

    def update(self, target):
        # limit scrolling to map size

        x = -target.rect.x + local.DISPLAYW // 2
        # y = -target.rect.y + local.DISPLAYH // 2

        # x = min(0,x)
        # x = min(0, x)
        # x = max(-(self.weight - local.DISPLAYW), min(0, x))  # left/right
        # y = max(-(self.height - local.DISPLAYH), min(0, y))  # top/bottom
        self.rect = pygame.rect.Rect(x, 0, self.width, local.DISPLAYH)#self.height)


import pandas as pd

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions
from apache_beam.options.pipeline_options import GoogleCloudOptions
from apache_beam.options.pipeline_options import StandardOptions

input_filename = 'gs://testing-gcp-mandar/Salary_Data.csv'
output_filename = 'gs://testing-gcp-mandar/output.txt'

dataflow_options = ['--project=lofty-shine-248403', '--job_name=newjob', '--temp_location=gs://testing-gcp-mandar/temp']
dataflow_options.append('--staging_location=gs://testing-gcp-mandar/staging')
options = PipelineOptions(dataflow_options)
gcloud_options = options.view_as(GoogleCloudOptions)

# Dataflow runner
options.view_as(StandardOptions).runner = 'dataflow'

# options = PipelineOptions()
# google_cloud_options = options.view_as(GoogleCloudOptions)
# google_cloud_options.project = 'lofty-shine-248403'
# google_cloud_options.job_name = 'newjob'
# google_cloud_options.staging_location = 'gs://testing-gcp-mandar/staging'
# google_cloud_options.temp_location = 'gs://testing-gcp-mandar/temp'
# setup_options = options.view_as(SetupOptions)
# setup_options.setup_file = "/home/admin1/PycharmProjects/GCP/Dataflow/setup.py"
# options.view_as(StandardOptions).runner = 'DataflowRunner'

class Split(beam.DoFn):
    def process(self, element):
        """
        Splits each row on commas and returns a dictionary representing the
        row
        """
        import pandas as pd

        from sklearn.model_selection import train_test_split
        from sklearn.linear_model import LinearRegression

        import apache_beam as beam
        from apache_beam.options.pipeline_options import PipelineOptions
        from apache_beam.options.pipeline_options import GoogleCloudOptions
        from apache_beam.options.pipeline_options import StandardOptions

        input_filename = 'gs://testing-gcp-mandar/Salary_Data_Time_New.csv'
        output_filename = 'gs://testing-gcp-mandar/output.csv'

        dataflow_options = ['--project=lofty-shine-248403', '--job_name=newjob',
                            '--temp_location=gs://testing-gcp-mandar/temp']
        dataflow_options.append('--staging_location=gs://testing-gcp-mandar/staging')
        options = PipelineOptions(dataflow_options)
        gcloud_options = options.view_as(GoogleCloudOptions)

        # Dataflow runner
        options.view_as(StandardOptions).runner = 'dataflow'

        class Split(beam.DoFn):
            def process(self, element):
                """
                Splits each row on commas and returns a dictionary representing the
                row
                """
                YearsExperience, Salary, Time = element.split(",")
                try:
                    YearsExperience = int(YearsExperience)
                    Salary = int(Salary)
                    Time = int(Time)
                except Exception:
                    YearsExperience = 0
                    Salary = 0
                    Time = 0

                return [{
                    'YearsExperience': YearsExperience,
                    'Salary': Salary,
                    'Time': Time
                }]

        class CollectSalary(beam.DoFn):
            def process(self, element):
                """
                Returns a list of tuples containing country and duration
                """
                result = [
                    (element['YearsExperience'], element['Salary'])
                ]
                return result

        class WriteToCSV(beam.DoFn):
            def process(self, element):
                """
                Prepares each row to be written in the csv
                """
                result = [
                    "{},{},{}".format(
                        element[0],
                        element[1]['Time'][0],
                        element[1]['Salary'][0]
                    )
                ]
                return result

        class CollectTime(beam.DoFn):
            def process(self, element):
                """
                Returns a list of tuples containing country and user name
                """
                result = [
                    (element['YearsExperience'], element['Time'])
                ]
                return result

        with beam.Pipeline(options=options) as p:
            rows = (
                    p |
                    beam.io.ReadFromText(input_filename) |
                    beam.ParDo(Split())
            )

            salary = (
                    rows |
                    beam.ParDo(CollectSalary()) |
                    "Grouping salary" >> beam.GroupByKey() |
                    "Calculating average" >> beam.CombineValues(beam.combiners.MeanCombineFn()
                                                                )
            )
            time = (
                    rows |
                    beam.ParDo(CollectTime()) |
                    "Grouping timing" >> beam.GroupByKey() |
                    "Counting users" >> beam.CombineValues(beam.combiners.CountCombineFn()
                                                           )
            )
            to_be_joined = (
                    {
                        'Time': salary,
                        'Salary': time
                    } |
                    beam.CoGroupByKey() |
                    beam.ParDo(WriteToCSV()) |
                    beam.io.WriteToText(output_filename)
            )
        YearsExperience, Salary = element.split(",")
        return [{
            'YearsExperience': float(YearsExperience),
            'Salary': float(Salary),
        }]

class Mapping(beam.DoFn):
    def process(self, element):
        """
        Returns a list of tuples containing country and duration
        """
        result = [
            {'m',element}
        ]
        return result

class Predict(beam.DoFn):
    def GetMLDone(self,data):
        data=data[1]
        df = pd.DataFrame(data, columns=('YearsExperience', 'Salary'))
        df=df.iloc[1:,:]
        x = df[['YearsExperience']].values
        y = df[['Salary']].values
        x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
        regresor = LinearRegression()
        regresor.fit(x_train, y_train)
        pred=regresor.predict(x_test)
        return pred

with beam.Pipeline(options=options) as p:
    data_from_source = (p
                        | 'ReadMyFile' >> beam.io.ReadFromText('gs://testing-gcp-mandar/Salary_Data.csv')
                        | 'Splitter using beam.Map' >> beam.ParDo(Split())
                        # | 'Map record to 1' >> beam.ParDo(Mapping())
                        # | 'GroupBy the data' >> beam.GroupByKey()
                        | 'Get the prediction' >> beam.ParDo(Predict())
                        | 'Export results to new file' >> beam.io.WriteToText('gs://testing-gcp-mandar/output', '.txt')
                        )
# p.run()


from rdflib import Graph, Literal, Namespace
import random

# create namespaces
baseNs = Namespace("http://myontology.com/")
RDF = Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
MYONT = Namespace(baseNs['myont/'])
SCHEMA = Namespace("https://schema.org/")
EDUSE = Namespace(baseNs['gebruiken/'])
TAXONOMIES = Namespace(baseNs['taxonomieen/'])
EXERCISES = Namespace(baseNs['oefeningen/'])

# create input graph
inputGraph = Graph()
inputGraph.parse('../rdf-data/educationalUses.ttl')
inputGraph.parse('../rdf-data/educationalTaxonomies.ttl')

# create output graphs
resultPhaseGraph = Graph()
resultLessonGraph = Graph()
resultExerciseGraph = Graph()

resultGraphs = [resultPhaseGraph, resultLessonGraph, resultExerciseGraph]
resultPhaseGraph.parse('../rdf-data/generated-data/generated-phases-with-excerpts.ttl')
resultLessonGraph.parse('../rdf-data/generated-data/generated-lessons.ttl')
resultExerciseGraph.parse('../rdf-data/real-data/exercises.ttl')

# avoid double entries when reruning script
resultLessonGraph.remove((None, MYONT["semanticalDensity"], None))

resultPhaseGraph.remove((None, SCHEMA['interactivityType'], None))
resultPhaseGraph.remove((None, SCHEMA['educationalUse'], None))
resultPhaseGraph.remove((None, MYONT['interactivityLevel'], None))
resultPhaseGraph.remove((None, MYONT['hasCategory'], None))

resultExerciseGraph.remove((None, MYONT['hasCategory'], None))

# bind output graphs
for g in resultGraphs:
    g.bind('rdf', RDF)
    g.bind('myont', MYONT)
    g.bind('schema', SCHEMA)
    g.bind('eduse', EDUSE)
    g.bind('edutaxonomies', TAXONOMIES)
    g.bind('exercise', EXERCISES)

phases = [s for s, _, _ in resultPhaseGraph.triples((None, RDF['type'], MYONT['LessonPhase']))]
lessons = [s for s, _, _ in resultLessonGraph.triples((None, RDF['type'], MYONT['Lesson']))]
exercises = [s for s, _, _ in resultExerciseGraph.triples((None, RDF['type'], MYONT['EducationalExercise']))]

interactivityTypes = [Literal('actief', lang="nl"), Literal('receptief', lang="nl"), Literal('gemengd', lang="nl")]
interactivityLevels = [Literal('Erg laag', lang="nl"),
                        Literal('laag', lang="nl"),
                        Literal('gemiddeld', lang="nl"),
                        Literal('hoog', lang="nl"),
                        Literal('Erg hoog', lang="nl")]

semanticalDensities = [Literal('Erg laag', lang="nl"),
                        Literal('laag', lang="nl"),
                        Literal('gemiddeld', lang="nl"),
                        Literal('hoog', lang="nl"),
                        Literal('Erg hoog', lang="nl")]

educationalUses = [s for s, _, _ in inputGraph.triples((None, SCHEMA['inDefinedTermSet'], EDUSE['set']))]
educationalTaxonomyLevels = [s for s, _, _ in inputGraph.triples((None, SCHEMA['inCodeSet'], TAXONOMIES['revisedBloom']))]

# add data for every phase
for phase in phases:
    resultPhaseGraph.add((phase, SCHEMA['interactivityType'], random.choice(interactivityTypes)))
    resultPhaseGraph.add((phase, SCHEMA['educationalUse'], random.choice(educationalUses)))
    resultPhaseGraph.add((phase, MYONT['interactivityLevel'], random.choice(interactivityLevels)))
    resultPhaseGraph.add((phase, MYONT['hasCategory'], random.choice(educationalTaxonomyLevels)))

# add data for every lesson
for lesson in lessons:
    resultLessonGraph.add((lesson, MYONT['semanticalDensity'], random.choice(semanticalDensities)))

# add data for every exercise
for exercise in exercises:
    resultExerciseGraph.add((exercise, MYONT['hasCategory'], random.choice(educationalTaxonomyLevels)))

# write data
resultPhaseGraph.serialize('../rdf-data/generated-data/generated-phases-with-excerpts.ttl', format='turtle')
resultLessonGraph.serialize('../rdf-data/generated-data/generated-lessons.ttl', format='turtle')
resultExerciseGraph.serialize('../rdf-data/real-data/exercises.ttl', format='turtle')


from collections import deque

def solv(graph, visited, start):
    visited[start] = 1
    queue = deque([start])

    while queue:
        node = queue.popleft()

        for i in graph[node]:
            if visited[i] == 0:
                queue.append(i)
                visited[i] = 1

N, M = map(int, input().split())
graph = [[] for _ in range(N+1)]
visited = [0 for _ in range(N+1)]
count = 0

for i in range(M):
    i, j = map(int, input().split())
    graph[i].append(j)
    graph[j].append(i)

for start in range(1, N+1):
    if visited[start] == 0:
        solv(graph, visited, start)
        count += 1

print(count)


"""
parses through all .html files in templates folder
replaces eg, {{stylesheet.css}} with the content of stylesheet.css

"""

import os
import json

from bs4 import BeautifulSoup as bs

# First pass (pulled from scraped data)
templates_directory = "asset-builder-templates"
target_directory = "asset-builders"

replace_list = [
	"chumpionship-styles.css",
	"common_functions.js",
	"database_queries.js",
	"content-builders-library.js",
	"chumpionship_colours.js",
    "svg.js",
    "dynamic_styles.js",
    "load_database.js",
    "database.json",
    "fixture_list.json"
    ]

for dirpath, dirnames, files in os.walk(templates_directory):
	#print(f"dirpath {dirpath}")
	#print(f"dirnames {dirnames}")
	#print(f"files {files}")

	for filename in files:
		if filename.endswith(".html"):
			print(filename)
			with open(templates_directory + "/" + filename) as html:
				html = html.read()
				#print(html)

				for x in replace_list:
					string_to_replace = "**"+x+"**"
					if string_to_replace in html:
						print(string_to_replace)
						with open(templates_directory + "/" + x) as r:
							r = str(r.read())
							html = html.replace(string_to_replace, r)

				with open(target_directory + "/" + filename, "w") as f:
					soup = bs(html, "html.parser")
					html = soup.prettify()
					f.write(html)

			print("")


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Implementation of fingerprints as presented as HI-DS 2015.
Fragments:
    - paths of size 3
Descriptors:
    - field descriptor (3-path) hybridization
Fingerprint:
    - count vector, no hashing
"""

import rdkit
from rdkit import Chem

__author__ = "Petr Škoda"
__license__ = "X11"
__email__ = "skoda@ksi.mff.cuni.cz"

METADATA = {
    "id": "method_rdkit_p3_f3_hybridization_tanimoto_like",
    "representation": "p3_f3_hybridization",
    "similarity": "tanimoto_like"
}

# region Representation calculation

def _pattern_fragment_generator(molecule, pattern):
    """

    :param molecule:
    :param pattern:
    :return: A generator of fragment for given molecule.
    """
    matches = molecule.GetSubstructMatches(Chem.MolFromSmarts(pattern))
    for atoms in matches:
        yield atoms

def _calculate_atom_code(atom_idx, field_map):
    """Create labeling for given atom from the given fields.

    :param atom_idx:
    :param field_map:
    :return:
    """
    # There may not be a value for every atom, in such case we will use "_".
    # This might be as we use bigger fragment to build field then to
    # construct fingerprint.
    if atom_idx in field_map:
        return field_map[atom_idx]
    else:
        return None

def _calculate_fragment_code(atoms, field_map):
    """Compute fragment code.

    :param atoms:
    :param field_map:
    :return: Score for given fragment as a vector of values.
    """
    codes = [""] * len(atoms)
    for i in range(0, len(atoms)):
        codes[i] = _calculate_atom_code(atoms[i], field_map)
    # canonization of the code vector
    beg = 0
    end = len(codes) - 1
    while beg < end:
        if codes[beg] > codes[end]:
            codes.reverse()
            break
        elif codes[beg] == codes[end]:
            beg += 1
            end -= 1
        else:
            break
    return codes

def _calculate_field_hybrid_descriptor(molecule, fragments):
    """Create field hybridization descriptor for each atom.

    :param molecule:
    :param fragments:
    :return: Dictionary <atom, label value>
    """
    value_map = {}
    counter_map = {}
    for atoms in fragments:
        # Compute average field value.
        average_value = 0.0
        for atom in atoms:
            average_value += molecule.GetAtomWithIdx(atom).GetHybridization()
        average_value /= len(atoms)
        # Save value to atoms.
        for atom in atoms:
            if atom not in value_map:
                value_map[atom] = 0
                counter_map[atom] = 0
            value_map[atom] += average_value
            counter_map[atom] += 1
    # Modify values as averages.
    for key in value_map.keys():
        value_map[key] /= float(counter_map[key])
    return value_map

def compute_representation(molecule):
    """Calculate and return representation of given molecule.
    The output is dictionary of objects, where each object has a value (id)
    and counter, which represent number of fragment instances.

    :param molecule:
    :return: Dictionary <label, {value, counter}>
    """
    fragments_field = list(_pattern_fragment_generator(molecule, "*~*~*"))
    field_map = _calculate_field_hybrid_descriptor(molecule, fragments_field)
    fragments = fragments_field
    representation = {}
    total_counter = 0
    for atoms in fragments:
        fragment = _calculate_fragment_code(atoms, field_map)
        fragment_as_str = str(fragment)
        if fragment_as_str not in representation:
            representation[fragment_as_str] = {
                "value": fragment,
                "instances": [],
                "counter": 0
            }
        representation[fragment_as_str]["counter"] += 1
        # Contains information about atoms, that form the fragment.
        representation[fragment_as_str]["instances"].append({
            "atoms": atoms
        })
        total_counter += 1
    return representation

def _fragment_score_label_similarity(left_fragment, right_fragment):
    """Given two fragments return their similarity.

    :param left_fragment:
    :param right_fragment:
    :return:
    """
    # Topology must be the same.
    if not left_fragment["value"] == right_fragment["value"]:
        return 0
    similarity = 0
    for index in range(1, len(left_fragment)):
        try:
            similarity += left_fragment[index] == right_fragment[index]
        except Exception as ex:
            raise ex
    return similarity

def similarity_tannimoto(left, right):
    """

    :param left: Dictionary <key, value>
    :param right: Dictionary <key, value>
    :return:
    """
    in_common = 0
    total = 0
    for left_fragment_key in left:
        for right_fragment_key in right:
            left_fragment = left[left_fragment_key]
            right_fragment = right[right_fragment_key]
            if not left_fragment["value"] == right_fragment["value"]:
                continue
            # Add shared number (ie. min) to in_common - intersenction.
            in_common += min(left_fragment["counter"],
                             right_fragment["counter"])
            # Add to total counter - union.
            total += left_fragment["counter"] + right_fragment["counter"]
    if not total == 0:
        # They have no fragments, this might happen if the molecules
        # are too small..
        return in_common / (float)(total)
    else:
        return 0

# endregion

# region Interface method implementation

def create_model(ligands, decoys):
    """Create and return query model.
    """
    return [compute_representation(molecule) for molecule in ligands]

def compute_score(model, query):
    """Compute and return activity likeness for given query molecule.
    """
    fingerprint = compute_representation(query)
    return max([similarity_tannimoto(fingerprint, ligand)
                for ligand in model])

# endregion


from settings.models import UserSalesShowing
from django.utils import timezone
from settings.models import UserTimeZone
import zoneinfo

class TimezoneMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        try:
            tzname = UserTimeZone.objects.get(user=request.user)
            if tzname and tzname.timezone_field in zoneinfo.available_timezones():
                timezone.activate(zoneinfo.ZoneInfo(tzname.timezone_field))
        except:
            timezone.deactivate()
        return self.get_response(request)

def get_fields_names(request_user):
    """Get 'Sale' showing fields in list_view or search_view"""
    fields = UserSalesShowing.objects.get(user=request_user)
    f_1 = fields._meta.get_fields()
    sale_fields = []
    for field in f_1:
        if field.name != "id" and field.name != "user":
            value = getattr(fields, field.name)
            if value == True:
                name = field.name[:-5]
                sale_fields.append(name)
    return sale_fields


import os
import glob
import yaml
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import torch
from sklearn import linear_model
from scipy.spatial.distance import pdist
from unsup_spatial_pred import SiameseSMPredictor
from unsup_spatial_pred import load_regular_grid

def load_model(path):
    with open(os.path.join(path, "config.yml"), "r") as f:
        config = yaml.load(f, yaml.FullLoader)
    device = "cuda" if (config["training"]["gpu"] and torch.cuda.is_available()) else "cpu"
    net = SiameseSMPredictor(**config["network"]).to(device)
    net.load(path)
    return net

class Evaluator:
    """Docstring"""
    def __init__(self, path):
        """Constructor"""
        assert os.path.exists(path), "incorrect experiment path"
        self.path = path
        self.num_trials = len(glob.glob(os.path.join(self.path, "trial*")))
        self.modes = ["dynamic_base", "static_base", "hopping_base"]
        # load the regular grid for evaluation of the models
        self.m_grid, self.x_grid = load_regular_grid(path)
        self.embeddings = dict()
        self.singular_values = dict()
        self.dissimilarities = dict()
        self.dissimilarity_profiles = dict()

    def _get_projection_in_embedding(self, h, x=None):
        x = self.x_grid if x is None else x
        reg = linear_model.LinearRegression(fit_intercept=True)
        reg.fit(x, h)
        x_grid_projection = reg.predict(x)
        return x_grid_projection

    def _get_embedding(self, trial, mode):
        path = os.path.join(self.path, "trial{:03}".format(trial), mode)
        # load the model
        net = load_model(path)
        device = "cuda" if next(net.parameters()).is_cuda else "cpu"
        # generate the embedding
        with torch.no_grad():
            net.eval()
            for k in np.arange(0, self.m_grid.shape[0], 256):  # in case we're sending too much to the gpu at once
                idx = np.arange(k, min(k + 256, self.m_grid.shape[0]))
                h_tensor = net.get_representation(self.m_grid[idx, :].to(device))
                if k == 0:
                    h_grid = h_tensor.detach().cpu().numpy()
                else:
                    h_grid = np.vstack((h_grid, h_tensor.detach().cpu().numpy()))
        return h_grid

    def _get_dissimilarity(self, h, weight=0):
        # TODO: instead of going with a linear regression that minimizes
        #  the distance between points and their projection, one could
        #  train a linear model to minimize the dissimilarities directly!
        # project the states in the embedding space
        x_projection = self._get_projection_in_embedding(h)
        # compute pairwise distances
        distances_h = pdist(h)
        distances_x = pdist(x_projection)
        # compute dissimilarity
        normalized_diffs = np.abs(distances_h - distances_x) / np.max(distances_h)
        weighting = np.exp(-weight * distances_x / np.max(distances_x))
        error = np.mean(normalized_diffs * weighting)
        return error

    def _get_dissimilarity_profile(self, h, weight_max=10):
        # project the states in the embedding space
        x_projection = self._get_projection_in_embedding(h)
        # compute pairwise distances
        distances_h = pdist(h)
        distances_x = pdist(x_projection)
        # compute dissimilarity
        normalized_diffs = np.abs(distances_h - distances_x) / np.max(distances_h)
        errors = []
        weights = np.linspace(0, weight_max, 10)
        for weight in weights:
            weighting = np.exp(-weight * distances_x / np.max(distances_x))
            errors.append(np.mean(normalized_diffs * weighting))
        return weights, errors

    def _get_embedding_sv(self, trial, mode):
        if len(self.embeddings) == 0:
            print("generate the embeddings first with Evaluator.compute_embeddings")
            return
        _, sv, _ = np.linalg.svd(self.embeddings[(trial, mode)])
        return sv

    def _get_first_linear_layer_sv(self, trial, mode):
        path = os.path.join(self.path, "trial{:03}".format(trial), mode)
        # load the model
        net = load_model(path)
        W = net.get_first_weight_vector()
        _, sv, _ = np.linalg.svd(W.detach().cpu().numpy())
        return sv

    def compute_embeddings(self):
        print("getting embeddings...")
        for trial in range(self.num_trials):
            for mode in self.modes:
                self.embeddings[(trial, mode)] = self._get_embedding(trial, mode)

    def compute_singular_values(self):
        if len(self.embeddings) == 0:
            self.compute_embeddings()
        print("getting singular values...")
        for trial in range(self.num_trials):
            for mode in self.modes:
                self.singular_values[(trial, mode, "embedding")] = self._get_embedding_sv(trial, mode)
                self.singular_values[(trial, mode, "first_layer")] = self._get_first_linear_layer_sv(trial, mode)

    def compute_dissimilarities(self):
        if len(self.embeddings) == 0:
            self.compute_embeddings()
        print("computing dissimilarities...")
        for trial in range(self.num_trials):
            for mode in self.modes:
                self.dissimilarities[(trial, mode, "topological")] =\
                    self._get_dissimilarity(self.embeddings[(trial, mode)], weight=10)
                self.dissimilarities[(trial, mode, "metric")] = \
                    self._get_dissimilarity(self.embeddings[(trial, mode)], weight=0)

    def compute_dissimilarities_profiles(self):
        if len(self.embeddings) == 0:
            self.compute_embeddings()
        print("computing dissimilarities profiles...")
        for trial in range(self.num_trials):
            for mode in self.modes:
                weights, self.dissimilarity_profiles[(trial, mode, "topological")] =\
                    self._get_dissimilarity_profile(self.embeddings[(trial, mode)], weight_max=10)
        self.dissimilarity_profiles["weights"] = weights

    def plot_experiment_stats(self):
        if len(self.dissimilarities) == 0:
            self.compute_dissimilarities()
        if len(self.singular_values) == 0:
            self.compute_singular_values()

        mode_positions = {mode: i for i, mode in enumerate(self.modes)}

        fig = plt.figure(figsize=(16, 4))
        ax = plt.subplot(1, 4, 1)
        for mode in self.modes:
            res = [self.dissimilarities[(trial, mode, "topological")] for trial in range(self.num_trials)]
            ax.violinplot(res, positions=[mode_positions[mode]])
        ax.set_xticks(list(mode_positions.values()))
        ax.set_xticklabels(self.modes)
        ax.set_title("topological dissimilarity")

        ax = plt.subplot(1, 4, 2)
        for mode in self.modes:
            res = [self.dissimilarities[(trial, mode, "metric")] for trial in range(self.num_trials)]
            ax.violinplot(res, positions=[mode_positions[mode]])
        ax.set_xticks(list(mode_positions.values()))
        ax.set_xticklabels(self.modes)
        ax.set_title("metric dissimilarity")

        ax = plt.subplot(1, 4, 3)
        for mode in self.modes:
            res = np.array([self.singular_values[(trial, mode, "embedding")] for trial in range(self.num_trials)])
            shifts = np.arange(-res.shape[1]//2, res.shape[1]//2) + 1
            positions = (res.shape[1] + 1) * mode_positions[mode] + shifts
            ax.violinplot(res, positions=positions)
        ax.set_xticks([(res.shape[1] + 1) * p for p in mode_positions.values()])
        ax.set_xticklabels(self.modes)
        ax.set_title("embedding singular values")

        ax = plt.subplot(1, 4, 4)
        for mode in self.modes:
            res = np.array([self.singular_values[(trial, mode, "first_layer")] for trial in range(self.num_trials)])
            shifts = np.arange(-res.shape[1] // 2, res.shape[1] // 2) + 1
            positions = (res.shape[1] + 1) * mode_positions[mode] + shifts
            ax.violinplot(res, positions=positions)
        ax.set_xticks([(res.shape[1] + 1) * p for p in mode_positions.values()])
        ax.set_xticklabels(self.modes)
        ax.set_title("first W singular values")

        plt.show(block=True)
        return fig

    def plot_dissimilarity_profile(self, trial=0):
        if len(self.embeddings) == 0:
            self.compute_embeddings()
        plt.figure(figsize=(7, 7))
        ax = plt.gca()
        for mode in self.modes:
            weights, values = self._get_dissimilarity_profile(self.embeddings[(trial, mode)])
            ax.plot(weights, values, label=mode)
            ax.set_xlim(weights[-1], weights[0])
            ax.set_xlabel("weighting")
            ax.set_ylabel("dissimilarity")
            ax.set_title("trial {}".format(trial, mode))
            plt.legend()
        plt.show(block=True)

    def plot_dissimilarity_profiles(self):
        if len(self.dissimilarity_profiles) == 0:
            self.compute_dissimilarities_profiles()
        plt.figure(figsize=(7, 7))
        ax = plt.subplot(1, 1, 1)
        weights = self.dissimilarity_profiles["weights"]
        for mode in self.modes:
            res = [self.dissimilarity_profiles[(trial, mode, "topological")] for trial in range(self.num_trials)]
            mean_res = np.mean(np.array(res), axis=0)
            std_red = np.std(np.array(res), axis=0)
            ax.plot(weights, mean_res, label=mode)
            ax.fill_between(weights, mean_res - std_red, mean_res + std_red, alpha=0.4)
        ax.set_xlim(weights[-1], weights[0])
        ax.set_title("dissimilarity profiles")
        ax.set_xlabel("weighting")
        ax.legend(loc="upper left")
        plt.show(block=True)

    def plot_pairwise_distances_comparison(self, trial=0, num=10000):
        if len(self.embeddings) == 0:
            self.compute_embeddings()
        index = np.random.choice(self.x_grid.shape[0] * (self.x_grid.shape[0] - 1) // 2,
                                 num,
                                 replace=False)  # limit the memory cost
        mode_subplot = {mode: i for i, mode in enumerate(self.modes)}
        fig = plt.figure(figsize=(12, 4))
        for mode in self.modes:
            emb = self.embeddings[(trial, mode)]
            distances_emb = pdist(emb)[index]
            distances_x = pdist(self.x_grid)[index]
            ax = fig.add_subplot(1, 3, mode_subplot[mode] + 1)
            ax.plot(distances_x, distances_emb, 'b.')
            ax.set_xlabel("ground-truth distances")
            ax.set_ylabel("embedded distances")
            ax.set_title("trial {}, mode {}".format(trial, mode))
        plt.show(block=True)
        return fig

    def plot_embedding(self, trial=0, rays=False):
        if len(self.embeddings) == 0:
            self.compute_embeddings()
        mode_subplot = {mode: i for i, mode in enumerate(self.modes)}
        fig = plt.figure(figsize=(12, 4))
        for mode in self.modes:
            emb = self.embeddings[(trial, mode)]
            x_projection = self._get_projection_in_embedding(emb)
            ax = fig.add_subplot(1, 3, mode_subplot[mode] + 1, projection="3d")
            ax.plot(x_projection[:, 0],
                    x_projection[:, 1],
                    x_projection[:, 2],
                    "ko")
            if rays:
                for x_proj, em in zip(x_projection, emb):
                    ax.plot([x_proj[0], em[0]],
                            [x_proj[1], em[1]],
                            [x_proj[2], em[2]],
                            "b")
            ax.plot(emb[:, 0],
                    emb[:, 1],
                    emb[:, 2],
                    'r.', alpha=0.4)
            ax.set_title(mode)
        plt.show(block=True)


import share_price as sp
import matplotlib.pyplot as plt
from matplotlib.ticker import Formatter
import numpy as np
from twitter import Twitt
from functools import reduce
import datetime

class DateFormatter(Formatter):
    def __init__(self, dates, fmt='%Y-%m-%d'):
        self.dates = dates
        self.fmt = fmt

    def __call__(self, x, pos=0):

        ind = int(np.round(x))
        if ind >= len(self.dates) or ind < 0:
            return ''
        return self.dates[ind].strftime(self.fmt)

def plot(data) :
    formatter = DateFormatter(list(map(lambda x: x[0],data)))
    plt.rcParams['figure.figsize'] = [15, 5]
    fig, ax = plt.subplots()
    ax.xaxis.set_major_formatter(formatter)
    ax.plot(np.arange(len(data)), list(map(lambda x: x[1],data)))
    fig.autofmt_xdate()
    plt.show()

def plot2(sharePrice,news) :

    plt.rcParams['figure.figsize'] = [15, 5]

    ax1 = plt.subplot(311)
    ax2 = plt.subplot(312, sharex=ax1)
    ax1.set_title('share price')
    ax1.plot(list(map(lambda x: x[0],sharePrice)), list(map(lambda x: x[1],sharePrice)))
    ax1.get_xaxis().set_visible(False)

    ax2.set_title('news power')

    maxdata = reduce(lambda x, y: y[0] if y[0]> x else x ,sharePrice,datetime.datetime.min)

    d1 = list(filter(lambda x: not x.ignore and x.sentiment==0  and x.date < maxdata,news))
    if len(d1)>0:
        ax2.scatter(list(map(lambda x: x.date,d1)),
                list(map(lambda x: x.power,d1)),
                s = list(map(lambda x: 10,d1)),
                marker= 'o',
                c='blue')

    d2 = list(filter(lambda x: x.ignore and x.date < maxdata,news))
    if len(d2)>0:
        ax2.scatter(list(map(lambda x: x.date,d2)),
                list(map(lambda x: x.power,d2)),
                s = list(map(lambda x: 10,d2)),
                marker= 's',
                c='yellow')

    d3 = list(filter(lambda x: not x.ignore and x.sentiment>0 and x.date < maxdata,news))
    if len(d3)>0:
        ax2.scatter(list(map(lambda x: x.date,d3)),
                list(map(lambda x: x.power,d3)),
                s = list(map(lambda x: ((abs(x.sentiment)+1)*5)**2,d3)),
                marker= '^',
                c='green')
    d4 = list(filter(lambda x: not x.ignore and x.sentiment<0 and x.date < maxdata,news))
    if len(d4)>0:
        ax2.scatter(list(map(lambda x: x.date,d4)),
                list(map(lambda x: x.power,d4)),
                s = list(map(lambda x: ((abs(x.sentiment)+1)*5)**2,d4)),
                marker= 'v',
                c='red')

    plt.show()

if __name__ == '__main__':
    import share_price
    from twitt_processing import TwittProcessing

    sharePrice = share_price.getLastWeekIntraday('DINOPL','20190520','20190525')
    tw = TwittProcessing()
    data= tw.download('DINOPL','20190520','20190525')

    plot2(sharePrice,data)


from PyQt5 import QtCore, QtGui, QtWidgets
import os
import sys

class Ui_AlarmDialog(QtWidgets.QMainWindow):
    def setupUi(self, Form:QtWidgets.QMainWindow):
        Form.setObjectName("Form")
        Form.setWindowModality(QtCore.Qt.NonModal)
        Form.resize(350, 135)
        Form.setMinimumSize(QtCore.QSize(350, 135))
        Form.setMaximumSize(QtCore.QSize(350, 135))
        Form.setContextMenuPolicy(QtCore.Qt.NoContextMenu)

        Form.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowTitleHint | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowStaysOnTopHint)

        if getattr(sys, 'frozen', False):
            application_path = sys._MEIPASS
        elif __file__:
            application_path = os.path.dirname(__file__)
        iconFile = 'icon.ico'
        iconPath = os.path.join(application_path, iconFile)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(iconPath), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        icon.addPixmap(QtGui.QPixmap(iconPath), QtGui.QIcon.Normal, QtGui.QIcon.On)
        Form.setWindowIcon(icon)

        self.snoozeTimer = QtCore.QTimer(Form)
        self.dateTimeLabel = QtWidgets.QLabel(Form)
        self.dateTimeLabel.setGeometry(QtCore.QRect(10, 10, 331, 51))
        font = QtGui.QFont()
        font.setPointSize(26)
        self.dateTimeLabel.setFont(font)
        self.dateTimeLabel.setObjectName("dateTimeLabel")
        self.horizontalLayoutWidget = QtWidgets.QWidget(Form)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(5, 70, 341, 61))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.stopButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        font = QtGui.QFont()
        font.setPointSize(28)
        self.stopButton.setFont(font)
        self.stopButton.setObjectName("stopButton")
        self.horizontalLayout.addWidget(self.stopButton)
        self.snoozeButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        font = QtGui.QFont()
        font.setPointSize(16)
        self.snoozeButton.setFont(font)
        self.snoozeButton.setObjectName("snoozeButton")
        self.horizontalLayout.addWidget(self.snoozeButton)
        Form.component = self
        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Alarm"))
        self.dateTimeLabel.setText(_translate("Form", "TextLabel"))
        self.stopButton.setText(_translate("Form", "STOP"))
        self.snoozeButton.setText(_translate("Form", "SNOOZE FOR\n5 MINS"))


import cv2
import face_recognition
import os
import json
import wget
import requests
import schedule
import shutil
import mediapipe as mp
from datetime import datetime
import RPi.GPIO as GPIO
from time import sleep
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

RED = 18
GREEN = 8

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(RED, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(GREEN, GPIO.OUT, initial=GPIO.LOW)

KNOWN_FACES_DIR = "known_faces"
API_URL = 'https://rasp-users.onrender.com/api'

vid = cv2.VideoCapture(0)
Tolerance=0.5
mpHands = mp.solutions.hands
hands = mpHands.Hands(max_num_hands=1)
mpDraw = mp.solutions.drawing_utils
finger_coord = [(8, 6), (12, 10), (16,14), (20, 18)]
thumb_coord = (4, 2)

known_faces = []
known_names = []
codes = {}
ids = {}

def blink_one_sec(col):
    GPIO.output(col, GPIO.HIGH)
    sleep(1)
    GPIO.output(col, GPIO.LOW)

def blink_quickly(col):
    for i in range(10):
        GPIO.output(col, GPIO.HIGH)
        sleep(0.1)
        GPIO.output(col, GPIO.LOW)
        sleep(0.1)

def uspesne_overenie(name):
    requests.post(f"{API_URL}/logs", json = {"person": name})
    blink_quickly(GREEN)

def load_faces():
    GPIO.output(GREEN, GPIO.HIGH)
    GPIO.output(RED, GPIO.HIGH)
    try:
        retry_strategy = Retry(
        total=3,
        backoff_factor=1
        )
        adapter = HTTPAdapter(max_retries=retry_strategy)
        http = requests.Session()
        http.mount("https://", adapter)
        http.mount("http://", adapter)
        req = http.get(f"{API_URL}/users")
        data = json.loads(req.text)
        names = []
        for p in data:
            names.append(p['name'])
        for name in os.listdir(KNOWN_FACES_DIR):
            if name not in names:
                shutil.rmtree(f"{KNOWN_FACES_DIR}/{name}")
        for person in data:
            name = person['name']
            ids[name] = person['id']
            url = person['photo_url']
            fing_seq = person['fing_seq']
            codes[name] = fing_seq
            photos = url.split('/*/')
            if name not in os.listdir(KNOWN_FACES_DIR):
                os.mkdir(f"{KNOWN_FACES_DIR}/{name}")
                i = 0
                for photo in photos:
                    try:
                        down_image = wget.download(photo, out=f"{KNOWN_FACES_DIR}/{name}")
                        new_name = f"{i}.{down_image.split('.')[1]}"
                        os.rename(down_image, f"{KNOWN_FACES_DIR}/{name}/{new_name}")
                        i += 1
                    except:
                        print('an exception occured')
    except requests.ConnectionError:
        print('Connection error')

    global known_faces, known_names
    known_faces = []
    known_names = []
    for name in os.listdir(f'{KNOWN_FACES_DIR}'):
        for filename in os.listdir(f"{KNOWN_FACES_DIR}/{name}"):
                image = face_recognition.load_image_file(f"{KNOWN_FACES_DIR}/{name}/{filename}")
                try:
                    encoding = face_recognition.face_encodings(image)[0]
                except IndexError:
                    print('......')
                known_faces.append(encoding)
                known_names.append(name)
    print(f"pocet autorizovanych osob {len(set(known_names))}")
    GPIO.output(GREEN, GPIO.LOW)
    GPIO.output(RED, GPIO.LOW)

schedule.every(3).minutes.do(load_faces)

load_faces()
print("faces loaded")
while True:
    schedule.run_pending()
    ret, frame = vid.read()

    small_frame = cv2.resize(frame, (0,0), fx=0.25, fy=0.25)
    rgb_small_frame = cv2.cvtColor(small_frame, cv2.COLOR_BGR2RGB)

    face_locations = face_recognition.face_locations(rgb_small_frame)
    face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)

    face_names = []

    for face_encoding in face_encodings:
        matches = face_recognition.compare_faces(known_faces, face_encoding,Tolerance)
        name = "Unknown"

        if True in matches:
            name = known_names[matches.index(True)]
            print(f"{name} is on the screen.\nShow {codes[name]} fingers")

            start = datetime.now()
            start_sec = start.minute * 60 + start.second
            fingers_shown = []
            GPIO.output(18, GPIO.HIGH)
            sek = ''
            while True:
                ret, frame = vid.read()

                small_frame = cv2.resize(frame, (0,0), fx=0.25, fy=0.25)
                rgb_small_frame = cv2.cvtColor(small_frame, cv2.COLOR_BGR2RGB)
                results = hands.process(rgb_small_frame)

                multiLandMarks = results.multi_hand_landmarks

                if multiLandMarks:
                    handList = []
                    for handLms in multiLandMarks:
                        for idx, lm in enumerate(handLms.landmark):
                            cx, cy = int(lm.x * frame.shape[1]), int(lm.y * frame.shape[0])
                            handList.append((cx, cy))
                        upCount = 0
                        for coordinate in finger_coord:
                            if handList[coordinate[0]][1] < handList[coordinate[1]][1]:
                                upCount += 1
                        if handList[thumb_coord[0]][0] > handList[thumb_coord[1]][0]:
                            upCount += 1
                    fingers_shown.append(upCount)

                if len(fingers_shown) == 7:
                    fingers_shown.pop(0)
                    if len(set(fingers_shown)) == 1:
                        print(fingers_shown[0])
                        sek += str(fingers_shown[0])
                        print(sek)
                        blink_one_sec(GREEN)
                        if sek == codes[name]:
                            print('super kod sa matchuje')
                            uspesne_overenie(name)
                            break
                        if len(sek) == 5:
                            blink_quickly(RED)
                            break
                        fingers_shown = []

                cur = datetime.now()
                cur_sec = cur.minute * 60 + cur.second
                if cur_sec - start_sec > 20:
                    blink_quickly(RED)
                    break

            GPIO.output(18, GPIO.LOW) # Turn off

    cv2.imshow('frame', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

vid.release()
cv2.destroyAllWindows()


from typing import Any, Dict, List, Type, TypeVar, Union

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from ..types import UNSET, Unset

T = TypeVar("T", bound="APWirelessUplinkEntity")

@_attrs_define
class APWirelessUplinkEntity:
    """wireless uplink info

    Attributes:
        uplink_mac (Union[Unset, str]): uplink ap mac
        name (Union[Unset, str]):
        channel (Union[Unset, int]):
        rssi (Union[Unset, int]):
        snr (Union[Unset, int]): signal-noise ratio
        tx_rate (Union[Unset, str]):
        rx_rate_int (Union[Unset, int]): unit:Mbps
        rx_rate (Union[Unset, str]):
        up_bytes (Union[Unset, int]):
        down_bytes (Union[Unset, int]):
        up_packets (Union[Unset, int]):
        down_packets (Union[Unset, int]):
        activity (Union[Unset, int]): (change of(downBytes+upBytes))/time
    """

    uplink_mac: Union[Unset, str] = UNSET
    name: Union[Unset, str] = UNSET
    channel: Union[Unset, int] = UNSET
    rssi: Union[Unset, int] = UNSET
    snr: Union[Unset, int] = UNSET
    tx_rate: Union[Unset, str] = UNSET
    rx_rate_int: Union[Unset, int] = UNSET
    rx_rate: Union[Unset, str] = UNSET
    up_bytes: Union[Unset, int] = UNSET
    down_bytes: Union[Unset, int] = UNSET
    up_packets: Union[Unset, int] = UNSET
    down_packets: Union[Unset, int] = UNSET
    activity: Union[Unset, int] = UNSET
    additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        uplink_mac = self.uplink_mac
        name = self.name
        channel = self.channel
        rssi = self.rssi
        snr = self.snr
        tx_rate = self.tx_rate
        rx_rate_int = self.rx_rate_int
        rx_rate = self.rx_rate
        up_bytes = self.up_bytes
        down_bytes = self.down_bytes
        up_packets = self.up_packets
        down_packets = self.down_packets
        activity = self.activity

        field_dict: Dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({})
        if uplink_mac is not UNSET:
            field_dict["uplinkMac"] = uplink_mac
        if name is not UNSET:
            field_dict["name"] = name
        if channel is not UNSET:
            field_dict["channel"] = channel
        if rssi is not UNSET:
            field_dict["rssi"] = rssi
        if snr is not UNSET:
            field_dict["snr"] = snr
        if tx_rate is not UNSET:
            field_dict["txRate"] = tx_rate
        if rx_rate_int is not UNSET:
            field_dict["rxRateInt"] = rx_rate_int
        if rx_rate is not UNSET:
            field_dict["rxRate"] = rx_rate
        if up_bytes is not UNSET:
            field_dict["upBytes"] = up_bytes
        if down_bytes is not UNSET:
            field_dict["downBytes"] = down_bytes
        if up_packets is not UNSET:
            field_dict["upPackets"] = up_packets
        if down_packets is not UNSET:
            field_dict["downPackets"] = down_packets
        if activity is not UNSET:
            field_dict["activity"] = activity

        return field_dict

    @classmethod
    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
        d = src_dict.copy()
        uplink_mac = d.pop("uplinkMac", UNSET)

        name = d.pop("name", UNSET)

        channel = d.pop("channel", UNSET)

        rssi = d.pop("rssi", UNSET)

        snr = d.pop("snr", UNSET)

        tx_rate = d.pop("txRate", UNSET)

        rx_rate_int = d.pop("rxRateInt", UNSET)

        rx_rate = d.pop("rxRate", UNSET)

        up_bytes = d.pop("upBytes", UNSET)

        down_bytes = d.pop("downBytes", UNSET)

        up_packets = d.pop("upPackets", UNSET)

        down_packets = d.pop("downPackets", UNSET)

        activity = d.pop("activity", UNSET)

        ap_wireless_uplink_entity = cls(
            uplink_mac=uplink_mac,
            name=name,
            channel=channel,
            rssi=rssi,
            snr=snr,
            tx_rate=tx_rate,
            rx_rate_int=rx_rate_int,
            rx_rate=rx_rate,
            up_bytes=up_bytes,
            down_bytes=down_bytes,
            up_packets=up_packets,
            down_packets=down_packets,
            activity=activity,
        )

        ap_wireless_uplink_entity.additional_properties = d
        return ap_wireless_uplink_entity

    @property
    def additional_keys(self) -> List[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties


import bpy

from bpy.types import PropertyGroup
from bpy.types import UIList, UILayout, Context
from bpy.props import CollectionProperty, PointerProperty, EnumProperty, IntProperty, BoolProperty, FloatProperty, FloatVectorProperty

from ....core.common import Registerable, PropertyHolder

class TWEEN_UL_Target_Coll_Pos_Item(PropertyGroup):
    tween_pos: FloatVectorProperty(
        name='tween_pos'
    )

class TWEEN_UL_Target_Coll(PropertyGroup):
    tween_target: PointerProperty(
        type=bpy.types.Collection,
        name='tween_target'
    )
    tween_obj_datas: CollectionProperty(
        name='tween_obj_datas',
        type=TWEEN_UL_Target_Coll_Pos_Item,
    )
    step_per_frame: FloatProperty(
        name='Step Per Frame',
        default=0.1,
        min=0.0,
        max=1.0
    )
    expanded: BoolProperty(
        name='expanded',
        default=False
    )

class TWEEN_UL_Target_List_Item(PropertyGroup):
    tween_target: PointerProperty(
        name='tween_target',
        type=bpy.types.Object,
    )
    tween_pos: FloatVectorProperty(
        name='tween_pos'
    )
    step_per_frame: FloatProperty(
        name='Step Per Frame',
        default=0.1,
        min=0.0,
        max=1.0
    )
    expanded: BoolProperty(
        name='expanded',
        default=False
    )

class TWEEN_UL_List_Item(PropertyGroup):
    tween_attractor: PointerProperty(
        type=bpy.types.Object,
        name='tween_attractor',
    )
    tween_target_list: CollectionProperty(
        name='tween_target_list',
        type=TWEEN_UL_Target_List_Item,
    )
    tween_target_coll: PointerProperty(
        name='tween_target_coll',
        type=TWEEN_UL_Target_Coll,
    )
    tween_target_type: EnumProperty(
        name='Tween Target Type',
        items=(
            ('Objs', 'Objects', 'Use a list of objects as target'),
            ('Coll', 'Collection', 'Use a collection as target'),
        ),
        default='Objs',
    )
    keep_offset: BoolProperty(
        name='keep_offset',
        default=True
    )
    use_tween: BoolProperty(
        name='use_tween',
        default=True
    )

class TWEEN_UL_List(UIList, Registerable):
    tween_list_index = PropertyHolder(
        name='tween_list_index',
        property=IntProperty(
             name='tween_list_index',
             description='Index for TweenList',
        )
    )
    tween_list_items = PropertyHolder(
        name='tween_list_items',
        property=CollectionProperty(
            name='tween_list_items',
            type=TWEEN_UL_List_Item,
        )
    )

    @classmethod
    def register_cls(cls):
        # Register property dependency classes
        bpy.utils.register_class(TWEEN_UL_Target_Coll_Pos_Item)
        bpy.utils.register_class(TWEEN_UL_Target_Coll)
        bpy.utils.register_class(TWEEN_UL_Target_List_Item)
        bpy.utils.register_class(TWEEN_UL_List_Item)
        # Register properties
        setattr(bpy.types.Scene, cls.tween_list_index.name,
                cls.tween_list_index.property)
        setattr(bpy.types.Scene, cls.tween_list_items.name,
                cls.tween_list_items.property)
        # Register class
        bpy.utils.register_class(cls)

    @classmethod
    def unregister_cls(cls):
        # Unregister class
        bpy.utils.unregister_class(cls)
        # Unregister properties
        delattr(bpy.types.Scene, cls.tween_list_items.name)
        delattr(bpy.types.Scene, cls.tween_list_index.name)
        # Unregister property dependency classes
        bpy.utils.unregister_class(TWEEN_UL_List_Item)
        bpy.utils.unregister_class(TWEEN_UL_Target_List_Item)
        bpy.utils.unregister_class(TWEEN_UL_Target_Coll)
        bpy.utils.unregister_class(TWEEN_UL_Target_Coll_Pos_Item)

    def draw_item(self, context: Context, layout: UILayout, data, item: TWEEN_UL_List_Item, icon, active_data, active_propname, index):
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            obj = item.tween_attractor
            if obj is not None:
                layout.label(text=f'{index+1}) {obj.name}')
            else:
                layout.label(text=f'{index+1}) No attractor selected')
            layout.prop(item, 'use_tween', text='')

    @classmethod
    def draw(cls, list_id: str, context: Context, layout: UILayout):
        layout.template_list(cls.__name__, list_id, context.scene,
                             cls.tween_list_items.name, context.scene, cls.tween_list_index.name)


from matplotlib.backends.backend_pdf import PdfPages
from ..Hyperion.hyp_read import *
from ..Hyperion.hyp_out import *
from ..Hyperion.hyp_hst import *
from ..Hyperion.hyp_fluxes import *
from ..Hyperion.hyp_math import *
import matplotlib.pyplot as plt

plotdir = '/Users/sudhirraskutti/Desktop/Thesis/PaperII/Figures/'
datadir = '/u/raskutti/PhD/Hyperion/Tests/RadParGrav/'
hostname = 'raskutti@bellona.astro.princeton.edu'
outfile = 'RadParGrav.out'
fluxfile = 'fluxes_r0.dat'
hstfile = 'id0/RadParGrav.hst'

datafolder = 'UV_M5.0e4_R15.0_N128_Tf4_Fluxes/'
outlines = read_outfile(hostname,datadir + datafolder + outfile)
fluxdata = read_fluxfile(hostname,datadir + datafolder + fluxfile)
hstdata = read_hstfile(hostname,datadir + datafolder + hstfile)

mcloud = out_mcloud(outlines)
rcloud = out_rcloud(outlines)
clight = out_clight(outlines)
tff = out_tff(outlines)
psi = out_Psi(outlines)
kappa = out_kappa(outlines)
nconv = 10

tplot = 1.0
rad, rhofr = fluxvsr(fluxdata, 7, tplot, rcloud, tff)
rad, rhodphidr = fluxvsr(fluxdata, 15, tplot, rcloud, tff)
rad, fr = fluxvsr(fluxdata, 6, tplot, rcloud, tff)
rad, dphidr = fluxvsr(fluxdata, 14, tplot, rcloud, tff)
fedd = rhofr * kappa / (rhodphidr * clight)
feddspec = fr * kappa / (dphidr * clight)
fedd = np.convolve(fedd, np.ones((nconv,))/nconv, mode='same')
feddspec = np.convolve(feddspec, np.ones((nconv,))/nconv, mode='same')

tplot = 1.5
rad, rhofr = fluxvsr(fluxdata, 7, tplot, rcloud, tff)
rad, rhodphidr = fluxvsr(fluxdata, 15, tplot, rcloud, tff)
rad, fr = fluxvsr(fluxdata, 6, tplot, rcloud, tff)
rad, dphidr = fluxvsr(fluxdata, 14, tplot, rcloud, tff)
feddlate = rhofr * kappa / (rhodphidr * clight)
feddspeclate = fr * kappa / (dphidr * clight)
feddlate = np.convolve(feddlate, np.ones((nconv,))/nconv, mode='same')
feddspeclate = np.convolve(feddspeclate, np.ones((nconv,))/nconv, mode='same')

timef, rhofr = fluxvst(fluxdata, 7, 1.0, rcloud, tff)
timef, rhodphidr = fluxvst(fluxdata, 15, 1.0, rcloud, tff)
timef, fr = fluxvst(fluxdata, 6, 1.0, rcloud, tff)
timef, dphidr = fluxvst(fluxdata, 14, 1.0, rcloud, tff)
feddf = rhofr * kappa / (rhodphidr * clight)
feddfspec = fr * kappa / (dphidr * clight)

timef, rhofr = fluxvst(fluxdata, 7, 2.0, rcloud, tff)
timef, rhodphidr = fluxvst(fluxdata, 15, 2.0, rcloud, tff)
timef, fr = fluxvst(fluxdata, 6, 2.0, rcloud, tff)
timef, dphidr = fluxvst(fluxdata, 14, 2.0, rcloud, tff)
feddfout = rhofr * kappa / (rhodphidr * clight)
feddfspecout = fr * kappa / (dphidr * clight)

ysize = 0.25 * 11.69
xsize = 0.4 * 8.27
fontsize = '10'

plt.figure(figsize = [2*xsize,ysize])
#plt.subplots_adjust(left=0.2)
plt.subplots_adjust(bottom=0.2)
plt.rc('text', usetex=True)
plt.rc('font', family='serif', size=fontsize)

plt.rc('text', usetex=True)
plt.rc('font', family='serif', size='12')

plt.subplot(1,2,1)
f, fs = plt.plot(rad,fedd,'k',rad,feddlate,'r')
plt.legend((f, fs), (r"$\displaystyle t = t_{\rm ff}$",r"$\displaystyle t = 1.5~t_{\rm ff}$"),prop={'size':8},loc=2)
plt.axis([0,2,0,10.0])
plt.xticks([0,1,2])
plt.yticks([0,5,10])

plt.xlabel(r"$\displaystyle r / r_{\rm cloud}$")
plt.ylabel(r"$\displaystyle f_{\rm edd}$")
#plt.text(0.05*3,0.9*1.5,r"$\displaystyle(a)$")

plt.subplot(1,2,2)
f, fs = plt.plot(timef,feddf,'k',timef,feddfout,'r')
plt.legend((f, fs), (r"$\displaystyle r = r_{\rm cloud}$",r"$\displaystyle r = 2~r_{\rm cloud}$"),prop={'size':8},loc=2)
plt.axis([0,2,0,10.0])
plt.xticks([0,1,2])
plt.yticks([0,5,10],[' ',' ',' '])

plt.xlabel(r"$\displaystyle t / t_{\rm ff}$")
#plt.ylabel(r"$\displaystyle f_{\rm abs}$")
#plt.text(0.05*3,0.9*1.5,r"$\displaystyle(a)$")

pp = PdfPages(plotdir + 'ffedd.pdf')
pp.savefig()
pp.close()


import openai
import streamlit as st
from pptx import Presentation
from io import BytesIO

# Set up the Streamlit app
st.set_page_config(page_title="PowerPoint Translator")

# Set up the OpenAI API key input field
api_key = st.text_input("Enter your OpenAI API key:")

# Load the PowerPoint file
uploaded_file = st.file_uploader("Upload a PowerPoint file", type=["pptx"])
if uploaded_file is not None:
    pr = Presentation(uploaded_file)

    # Count the total number of shapes in the PowerPoint file
    total_shapes = sum(len(slide.shapes) for slide in pr.slides)

    # Set up the progress bar
    progress_bar = st.progress(0)

    # Iterate through all the slides and replace the text with traditional Chinese
    shape_count = 0
    for slide in pr.slides:
        for shape in slide.shapes:
            if hasattr(shape, "text"):
                original_text = shape.text
                if shape.text == "":
                    continue
                response = openai.ChatCompletion.create(
                    model="gpt-3.5-turbo",
                    messages=[{"role":"user","content":f"please translate \"{original_text}\" into traditional chinese"}],
                    temperature=0.2,
                    max_tokens=2048,
                    api_key=api_key
                )
                chinese_text = response["choices"][0]["message"]["content"]
                shape.text = chinese_text
                shape_count += 1
                progress_bar.progress(shape_count / total_shapes)

    buffer = BytesIO()
    pr.save(buffer)
    buffer.seek(0)
    # Download the updated PowerPoint file
    st.download_button(
        label="Download translated file",
        data=buffer,
        file_name="translated.pptx",
        mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
    )


from splinter import Browser
from bs4 import BeautifulSoup as bs
import time
import requests
import pandas as pd
from splinter.exceptions import ElementDoesNotExist
from selenium import webdriver

def init_browser():
    # @NOTE: Replace the path with your actual path to the chromedriver
    executable_path = {"executable_path": "/usr/local/bin/chromedriver"}
    return Browser("chrome", **executable_path, headless=False)

def scrape():
    executable_path = {'executable_path': '/usr/local/bin/chromedriver'}
    browser = Browser('chrome', **executable_path, headless=False)
    #browser = init_browser()
    #Mars News
    url_mars_news = "https://mars.nasa.gov/news/"
    browser.visit(url_mars_news)
    time.sleep(5)

    response_news = browser.html
    soup_news = bs(response_news, 'html.parser')

    #get news_title and news_p
    news_result = soup_news.find('div', class_='content_title')
    news_title = news_result.find_all('a')[0].text.strip()
    news_p = soup_news.find('div', class_='rollover_description_inner').text.strip()

    #Featured image mars
    url_featured_img = "https://www.jpl.nasa.gov/spaceimages/?search=&category=Mars"
    response_featured_img = requests.get(url_featured_img)
    soup_mars_featured_img = bs(response_featured_img.text, 'html.parser')
    browser.visit(url_featured_img)
    browser.click_link_by_id('full_image')
    fancybox = soup_mars_featured_img.find('a',class_='button fancybox')
    mars_featured_url = fancybox['data-fancybox-href']
    featured_image_url = "https://www.jpl.nasa.gov" + mars_featured_url

    #Get mars weather information
    url_mars_twitter = "https://twitter.com/marswxreport?lang=en"
    browser.visit(url_mars_twitter)
    response_mars_twitter = requests.get(url_mars_twitter)
    soup_twitter = bs(response_mars_twitter.text, 'html.parser')
    tweet = soup_twitter.find('div', class_='js-tweet-text-container').text.strip()
    mars_weather = tweet.split('pic')[0]
    #print(mars_weather)

    #Get mars fact table
    url_mars_facts = 'https://space-facts.com/mars/'
    browser.visit(url_mars_facts)
    mars_facts_table = pd.read_html(url_mars_facts)
    mars_facts_df = mars_facts_table[0]
    mars_facts_df.columns = ['Description', 'Values']
    mars_facts_df.set_index('Description', inplace=True)
    mars_facts_df.to_html('mars_facts_table.html')
    mars_facts = mars_facts_df.to_html()

    #Get Mars hemispheres titles
    url_mars_hemi = "https://astrogeology.usgs.gov/search/results?q=hemisphere+enhanced&k1=target&v1=Mars"
    browser.visit(url_mars_facts)
    response_mars_hemi = requests.get(url_mars_hemi)
    soup_mars_hemi = bs(response_mars_hemi.text, 'html.parser')

    #Get Mars hemispheres titles
    #title = soup_mars_hemi.find('h2',class_='title')
    cereberus_title = soup_mars_hemi.find_all('h3')[0].text
    schiaparelli_title = soup_mars_hemi.find_all('h3')[1].text
    syrtis_title = soup_mars_hemi.find_all('h3')[2].text
    valles_title = soup_mars_hemi.find_all('h3')[3].text

    #Cerebrus Image URL
    url_cereberus = "https://astrogeology.usgs.gov/search/map/Mars/Viking/cerberus_enhanced"
    response_cereberus = requests.get(url_cereberus)
    soup_cereberus = bs(response_cereberus.text, 'html.parser')
    cerebrus = soup_cereberus.find_all('img',class_='wide-image')[0]
    cerebrus_img = cerebrus['src']
    cerebrus_img_url = 'https://astrogeology.usgs.gov' + cerebrus_img

    #Schiaparelli Image URL
    url_schiaparelli = "https://astrogeology.usgs.gov/search/map/Mars/Viking/schiaparelli_enhanced"
    response_schiaparelli = requests.get(url_schiaparelli)
    soup_schiaparelli = bs(response_schiaparelli.text, 'html.parser')
    schiaparelli = soup_schiaparelli.find_all('img',class_='wide-image')[0]
    schiaparelli_img = schiaparelli['src']
    schiaparelli_img_url = 'https://astrogeology.usgs.gov' + schiaparelli_img

    #Syrtis Image URL
    url_syrtis = "https://astrogeology.usgs.gov/search/map/Mars/Viking/syrtis_major_enhanced"
    response_syrtis = requests.get(url_syrtis)
    soup_syrtis = bs(response_syrtis.text, 'html.parser')
    syrtis = soup_syrtis.find_all('img',class_='wide-image')[0]
    syrtis_img = syrtis['src']
    syrtis_img_url = 'https://astrogeology.usgs.gov' + syrtis_img

    #Valles Image URL
    url_valles = "https://astrogeology.usgs.gov/search/map/Mars/Viking/valles_marineris_enhanced"
    response_valles = requests.get(url_valles)
    soup_valles = bs(response_valles.text, 'html.parser')
    valles = soup_valles.find_all('img',class_='wide-image')[0]
    valles_img = valles['src']
    valles_img_url = 'https://astrogeology.usgs.gov' + valles_img

    hemisphere_image_urls = [
        {"title": cereberus_title, "img_url": cerebrus_img_url},
        {"title": schiaparelli_title, "img_url": schiaparelli_img_url},
        {"title": syrtis_title, "img_url": syrtis_img_url},
        {"title": valles_title, "img_url": valles_img_url},
    ]

    mars_data = {
        "news_title": news_title,
        "news_p": news_p,
        "mars_weather": mars_weather,
        "featured_image_url": featured_image_url,
        "mars_facts": mars_facts,
        "hemisphere_image_urls": hemisphere_image_urls,
        "cereberus_title": cereberus_title,
        "cerebrus_img_url": cerebrus_img_url,
        "schiaparelli_title": schiaparelli_title,
        "schiaparelli_img_url": schiaparelli_img_url,
        "syrtis_title": syrtis_title,
        "syrtis_img_url": syrtis_img_url,
        "valles_title": valles_title,
        "valles_img_url": valles_img_url
    }
    browser.quit()
    return mars_data