#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Surface tension from capillarity shape and scale parameters and expansion data."""
from misura.canon.logger import get_module_logging
logging = get_module_logging(__name__)
import veusz.plugins as plugins
import numpy as np
from scipy import interpolate

class DensityFunction(object):

    """Callable returning density at any temperature, given a reference density and temperature and linear/volumetric expansion curves"""

    def __init__(self, rho0, T0, dil=False, T=False, ex_start=0, ex_end=0, dim='Linear'):
        logging.debug('DensityFunction',
                      rho0, T0, dil, T, ex_start, ex_end, dim)
        self.rho0 = rho0
        self.T0 = T0
        self.dil = dil
        self.T = T
        self.dim = dim
        if dil is False or T is False:
            self.f = False
            return
        # Set up expansion curve
        self.f = interpolate.interp1d(T, dil)

        # Extrapolation towards lower T
        minT = min(T)
        self.low_start = minT + min(3, minT * 3 // 100)
        self.low_end = minT + min(10, minT // 10)
        self.low_dil = self.f(self.low_start)
        low_e2 = self.f(self.low_end)
        self.low_coef = (low_e2 - self.low_dil) / \
            (self.low_end - self.low_start)
        # Reference expansion
        if T0 < self.low_start:
            # extrapolate towards lower start temperature
            dT = (self.low_start - T0)
            self.e0 = self.low_dil - dT * self.low_coef
        else:
            self.e0 = self.f(T0)
        # Extrapolation
        self.ex_end = ex_end
        self.ex_start = ex_start
        if ex_end <= 0:
            return
        # Real expansion at end of extrapolation interval
        self.ex_dil = self.f(ex_end)
        # Fixed coefficient for any dilatation above ex_end
        self.ex_coef = (self.ex_dil - self.f(ex_start)) / (ex_end - ex_start)

    def __call__(self, T):
        """Adapt density to volumetric expansion"""
        if self.f is False:
            # If T was an array, return an array of rho0:
            return (T * 0) + self.rho0

        def func(T):
            # Use extrapolation
            if self.ex_end > 0 and T > self.ex_end:
                e = self.ex_dil - self.e0 + (T - self.ex_end) * self.ex_dil
            elif T < self.low_start:
                e = self.low_dil - (self.low_start - T) * self.low_coef
            else:
                # Use interpolated function
                e = self.f(T) - self.e0
            # Adapt linear to volumetric
            if self.dim == 'Linear':
                e = (1 + e / 100) ** 3
                return self.rho0 / e
            # Already volumetric
            rho = self.rho0 * 100 / (100 + e)
        vfunc = np.vectorize(func)
        rho = vfunc(T)
        return rho

def air_density(T):
    # Source:
    # http://bouteloup.pierre.free.fr/lica/phythe/don/air/air_density_plot.pdf
    return 360.77819 * ((T + 273.15) ** -1.00336)

g = 9.80665

class SurfaceTensionPlugin(plugins.DatasetPlugin):

    """Dataset plugin to perform operations between couples of x,y datasets."""
    # tuple of strings to build position on menu
    menu = ('Misura', 'Surface Tension')
    # internal name for reusing plugin later
    name = 'SurfaceTension'
    # string which appears in status bar
    description_short = 'Calculate surface tension from runtime capillary parameters.'

    # string goes in dialog box
    description_full = ('Calculate surface tension from capillary shape parameters,'
                        'scaling factor, temperature,'
                        'sample expansion curve, media expansion curve.')

    MIN_TEMPERATURE_VARIATION = 100

    def __init__(self, beta='', R0='', T='', rho0=1000, T0=25, dil='', dilT='', ex_start=0, ex_end=0, dim='Linear',
                            grho0=air_density(25), gT0=25, gdil='', gdilT='', gdim='Volumetric', ds_out='', temperature_dataset=[0, MIN_TEMPERATURE_VARIATION]):
        """Define input fields for plugin."""

        default_sample_expansion = dil
        default_sample_expansion_temperature = dilT

        if max(temperature_dataset) - min(temperature_dataset) < self.MIN_TEMPERATURE_VARIATION:
            default_sample_expansion = ''
            default_sample_expansion_temperature = ''

        self.fields = [
            plugins.FieldDataset(
                'beta', 'Capillarity factor dataset', default=beta),
            plugins.FieldDataset('R0', 'Scaling factor dataset', default=R0),
            plugins.FieldDataset(
                'T', u'Sample temperature (\u00B0C)', default=T),

            plugins.FieldFloat(
                "rho0", descr=u"Reference sample density (kg/m\u00B3)", default=rho0),
            plugins.FieldFloat(
                "T0", descr=u"Reference sample temperature (\u00B0C)", default=T0),
            plugins.FieldDataset(
                'dil', 'Sample expansion [blank=fixed] (%)', default=default_sample_expansion),
            plugins.FieldDataset(
                'dilT', u'Sample expansion temperature [blank=as beta] (\u00B0C)', default=default_sample_expansion_temperature),
            plugins.FieldFloat(
                'ex_start', u'Extrapolate below temperature [0=no] (\u00B0C)', default=ex_start),
            plugins.FieldFloat(
                'ex_end', u'Extrapolate above temperature [0=no] (\u00B0C)', default=ex_end),

            plugins.FieldCombo("dim", descr="Sample expansion dimension", items=[
                               'Linear', 'Volumetric'], default=dim),

            plugins.FieldFloat(
                "grho0", descr=u"Reference gas density (kg/m\u00B3)", default=grho0),
            plugins.FieldFloat(
                "gT0", descr=u"Reference gas temperature (\u00B0C)", default=gT0),

            plugins.FieldDataset(
                'gdil', 'Gas expansion [blank=air] (%)', default=gdil),
            plugins.FieldDataset(
                'gdilT', 'Gas expansion temperature [blank=air] (%)', default=gdilT),

            plugins.FieldCombo("gdim", descr="Gas expansion dimension", items=[
                               'Linear', 'Volumetric'], default=gdim),

            plugins.FieldDataset(
                'ds_out', 'Output dataset name', default=ds_out)
        ]
        self.error = 0

    def getDatasets(self, fields):
        """Returns single output dataset (self.ds_out).
        This method should return a list of Dataset objects, which can include
        Dataset1D, Dataset2D and DatasetText
        """
        # raise DatasetPluginException if there are errors
        if len(set([fields['beta'], fields['R0'], fields['T']])) < 3:
            raise plugins.DatasetPluginException(
                'Capillarity, scaling and temperature datasets must differ.')
        if fields['ds_out'] in set([fields['beta'], fields['R0'], fields['T'], '', fields['dil'], fields['dilT'], fields['gdil'], fields['gdilT']]):
            raise plugins.DatasetPluginException(
                'Input and output datasets cannot be the same.')
        # make a new dataset with name in fields['ds_out']
        self.ds_out = plugins.Dataset1D(fields['ds_out'])
        self.error = 0
        # return list of datasets
        return [self.ds_out]

    def updateDatasets(self, fields, helper):
        # Capillarity data
        beta = np.array(helper.getDataset(fields['beta']).data)
        R0 = np.array(helper.getDataset(fields['R0']).data)
        # Sample expansion data
        rho0 = fields['rho0']
        T0 = fields['T0']
        dsample = None
        if fields['T'] == '':
            T = np.ones(len(beta)) * T0
            dsample = np.ones(len(beta)) * rho0
        else:
            T = np.array(helper.getDataset(fields['T']).data)
        if len(set([len(beta), len(R0), len(T)])) > 1:
            raise plugins.DatasetPluginException(
                'Sample datasets must have same length')

        # Sample expansion data
        dim = fields['dim']
        ex_start = fields['ex_start']
        ex_end = fields['ex_end']
        # Disable if one is 0 or negative
        if ex_start * ex_end <= 0:
            ex_start, ex_end = 0, 0
        if fields['dil'] == '':
            dil = False
            dilT = False
        else:
            dil = np.array(helper.getDataset(fields['dil']).data)
            # Use the same T array
            if fields['dilT'] == '':
                dilT = T
            else:
                dilT = np.array(helper.getDataset(fields['dilT']).data)
            if len(dil) != len(dilT):
                raise plugins.DatasetPluginException(
                    'Sample expansion/T datasets must have same length')

        # Gas expansion data
        grho0 = fields['grho0']
        gT0 = fields['gT0']
        gdim = fields['gdim']
        if fields['gdil'] == '':
            gdil, gdilT = False, False
        else:
            gdil = np.array(helper.getDataset(fields['gdil']).data)
            gdilT = np.array(helper.getDataset(fields['gdilT']).data)
            if len(dil) != len(dilT):
                raise plugins.DatasetPluginException(
                    'Gas expansion/T datasets must have same length')

        # Correct dil curves starting at 100%
        if dil is not False:
            if dil[0] > 50:
                dil -= 100

        # Sample density vector
        if dsample is None:
            df = DensityFunction(rho0, T0, dil, dilT, ex_start, ex_end, dim)
            dsample = df(T)
        # Gas density vector
        if not gdil:
            gdf = air_density
        else:
            gdf = DensityFunction(grho0, gT0, gdil, gdilT, dim=gdim)
        dgas = gdf(T)
        # Surface tension formula
        gamma = g * (dsample - dgas) * ((R0 / 1e6) ** 2) / (beta / 1000)
        # Remove nan/inf due to missing betas (beta=0)
        gamma[np.isnan(gamma) + np.isinf(gamma)] = 0
        self.ds_out.update(data=gamma)
        return gamma

# add plugin classes to this list to get used
plugins.datasetpluginregistry.append(SurfaceTensionPlugin)


from datetime import date, timedelta
import sys
import numpy as np
import pandas as pd
import plotly.express as px
import yfinance as yf
from dash import Dash, html, dcc, Input, Output, State
from math import factorial
from time import sleep

app = Dash(__name__)
stocks_options = ['AAPL', 'MSFT', 'ADBE']
#maxsize = sum of permutations of stocks_options when s=3 + s=2 + s=1
#permutation = n!/(n-s)! -> n = len(stocks_options), s = number of stocks choosen
def get_data(symbols: list, start: str|None, end: str|None):
    print('Dados coletados')
    today = date.today()
    # start and end must be in "YYYY-MM-DD" format
    end = f"{today.year}-{f'0{today.month}' if len(str(today.month))==1 else today.month}-{today.day}" if end==None else end
    start = f"{today.year}-01-01" if start==None else start
    print(f"{start} <-> {end} {type(end)}")
    if len(symbols)==0:
        return None
    elif len(symbols)==1:
        data = yf.Ticker(symbols[0]).history(start=start, end=end).Close
    else:
        data = yf.Tickers(symbols).history(start=start, end=end).Close
    return data

def return_of(data):
    percentage_return_of_data = data/data.iloc[0]-1
    return percentage_return_of_data

def plot_(data, _format=None):
    fig = px.line(data)
    if _format=='%':
        fig.layout.yaxis = dict(tickformat=".2%")
    return fig

@app.callback(
    Output("graph", "figure"),
    inputs=Input("refresh-graph", "n_clicks"),
    state=[
        State("dropdown-symbols", "value"),
        State("interval-date", "start_date"),
        State("interval-date", "end_date"),
    ]
)
def update_graph(n_clicks, symbols, start_date, end_date):
    print(n_clicks)
    data = get_data(symbols, start=start_date, end=end_date)
    percentage_return = return_of(data)
    fig = plot_(percentage_return, _format='%')
    return fig

app.layout = html.Div([
    html.H4('Analysis of stocks collected from yahoo finance'),
    html.P('Select the stock'),
    dcc.Dropdown(
        id="dropdown-symbols",
        options=stocks_options,
        value=stocks_options[0],
        multi=True
    ),
    html.P('Select the interval'),
    dcc.DatePickerRange(
        id="interval-date",
        month_format='MMMM Y',
        display_format='DD/MM/YYYY',
        start_date_placeholder_text='Start date',
        end_date_placeholder_text='End date',
        max_date_allowed=date.today(),
    ),
    dcc.Graph(id="graph", figure=update_graph(None, ['MSFT'], None, None)),
    html.Button("Refresh", id='refresh-graph')
])
if __name__ == "__main__":
    app.run_server(debug=True)


val = {
    'T': 0,
    'C': 0,
    'G': 0
}
value_key = {
    'T': 3,
    'C': 2,
    'G': 1
}

s = input()

_sum = 0

for char in s:
    val[char]+=1

_min = min(val.values())
for key, value in val.items():
    # val[key] -= _min
    if val[key] != 0:
        _sum+=value**2

print(_min*7 + _sum)


import os
import random

def gen_data(min_value,max_value,data_num):
    data = []
    for data_idx in range(data_num):
        if(data_idx < 64*1):
            tmp = 1
        elif(data_idx < 64*2):
            tmp =(data_idx%64) // 8
        elif(data_idx < 64*3):
            tmp = data_idx % 64
        else:
            tmp = random.randint(min_value,max_value)
        data.append(tmp)
    return data

def write_orig_data(file_name,data,data_num_pre_line):
    line_num = (len(data) + data_num_pre_line - 1) // data_num_pre_line
    with open(file_name,'a') as f:
         for line_idx in range(line_num):
             for data_idx in range(data_num_pre_line):
                 f.write("{:0>2x}".format(data[line_idx * data_num_pre_line + data_idx] & 0xFF))
                 #print(data[line_idx * data_num_pre_line + data_idx])
             f.write('\r\n')

def pack_8x8(data_array):
    blk_8x8_num = (len(data_array) + 63) // 64
    pack_data   = []
    for blk_8x8_idx in range(blk_8x8_num):
        blk_8x8_data = []
        for row_idx in range(8):
            row_data = []
            for col_idx in range(8):
                data_idx = blk_8x8_idx * 64 + row_idx * 8 + col_idx
                if(data_idx >= len(data_array)):
                    row_data.append(0)
                else:
                    row_data.append(data_array[data_idx])
            blk_8x8_data.append(row_data)
        pack_data.append(blk_8x8_data)
    return pack_data

def get_row(blk_data,row_idx):
    return blk_data[row_idx]

def get_col(blk_data,col_idx):
    col_data = []
    for row_idx in range(8):
        col_data.append(blk_data[row_idx][col_idx])
    return col_data

def write_blk_8x8_data(data_path,filename_key_word,data_array_8x8,char_num):
    filename = data_path + filename_key_word + '_data.txt'
    with open(filename,'a') as f:
         for row_idx in range(0,8,2):
             for col_idx in range(7,-1,-1):
                 if(char_num == 2):
                     f.write("{:0>2x}".format(data_array_8x8[row_idx+1][col_idx] & 0xFF))
                 elif(char_num == 3):
                     f.write("{:0>3x}".format(data_array_8x8[row_idx+1][col_idx] & 0xFFF))
                 elif(char_num == 4):
                     f.write("{:0>4x}".format(data_array_8x8[row_idx+1][col_idx] & 0xFFFF))
                 else:
                     f.write("{:0>5x}".format(data_array_8x8[row_idx+1][col_idx] & 0xFFFFF))

             for col_idx in range(7,-1,-1):
                 if(char_num == 2):
                     f.write("{:0>2x}".format(data_array_8x8[row_idx][col_idx] & 0xFF))
                 elif(char_num == 3):
                     f.write("{:0>3x}".format(data_array_8x8[row_idx][col_idx] & 0xFFF))
                 elif(char_num == 4):
                     f.write("{:0>4x}".format(data_array_8x8[row_idx][col_idx] & 0xFFFF))
                 else:
                     f.write("{:0>5x}".format(data_array_8x8[row_idx][col_idx] & 0xFFFFF))

             f.write('\r\n')

def transpose_mitrix(src_mitrix):
    dst_mitrix = []
    for col_idx in range(8):
        col_data = get_col(src_mitrix,col_idx)
        dst_mitrix.append(col_data)
    return dst_mitrix

def dct_8x8_blk_cal(blk_8x8_data):
    p_result = []
    q_result = []
    o_result = []
    for vector_idx in range(8):
        vector_in = blk_8x8_data[vector_idx]
        p_out,q_out,o_out= dct_8x8_vector_cal(vector_in)
        p_result.append(p_out)
        q_result.append(q_out)
        o_result.append(o_out)
    return (p_result,q_result,o_result)

def dct_8x8_vector_cal(vector_in):
    p0 = vector_in[0] + vector_in[7]
    p1 = vector_in[3] - vector_in[4]
    p2 = vector_in[1] + vector_in[6]
    p3 = vector_in[2] - vector_in[5]
    p4 = vector_in[2] + vector_in[5]
    p5 = vector_in[1] - vector_in[6]
    p6 = vector_in[3] + vector_in[4]
    p7 = vector_in[0] - vector_in[7]

    q0 =  p0       +  p6
    q1 =  p1       - (p7 >> 2)
    q2 =  p2       +  p4
    q3 =  p3       + (p5 >> 2)
    q4 =  p2       -  p4
    q5 = (p3 >> 2) -  p5
    q6 =  p0       -  p6
    q7 = (p1 >> 2) +  p7

    o0 = q0 + q2
    o1 = q3 - q5 + q7 + (q7>>1)
    o2 = (q4 >> 1) + q6
    o3 = -q1 -q3 - (q3 >> 1) + q7
    o4 = q0 - q2
    o5 = q1 + q5 + (q5 >> 1) + q7
    o6 = -q4 + (q6 >> 1)
    o7 = -q1 - (q1 >> 1) + q3 + q5

    p_out = [p0,p1,p2,p3,p4,p5,p6,p7]
    q_out = [q0,q1,q2,q3,q4,q5,q6,q7]
    o_out = [o0,o1,o2,o3,o4,o5,o6,o7]

    return (p_out,q_out,o_out)

if __name__ == '__main__':
    data_path = '../data/'
    orig_data_filename     = data_path + 'orig_data.txt'

    cmd = 'rm -rf ' + data_path + '*.txt'
    print(cmd)
    os.system(cmd)

    data_array     = gen_data(-128,127,8*8*16)
    data_array_8x8 = pack_8x8(data_array)
    #write_orig_data(orig_data_filename,data_array,1)

    for blk_idx in range(len(data_array_8x8)):
        blk_8x8_data = data_array_8x8[blk_idx]
        write_blk_8x8_data(data_path,'blk_8x8_orig',blk_8x8_data,2)
        blk_8x8_data_p,blk_8x8_data_q,blk_8x8_data_1d = dct_8x8_blk_cal(blk_8x8_data)
        write_blk_8x8_data(data_path,'p',blk_8x8_data_p,3)
        write_blk_8x8_data(data_path,'q',blk_8x8_data_q,3)
        write_blk_8x8_data(data_path,'tmp_row',blk_8x8_data_1d,3)
        blk_8x8_data_1d_tm = transpose_mitrix(blk_8x8_data_1d)
        write_blk_8x8_data(data_path,'tmp_col',blk_8x8_data_1d_tm,3)


import pandas as pd
import numpy as np
import torch
import matplotlib.pyplot as plt

from helper_functions_preprocessing import save_train_test_data

PATH = 'Data/Preprocessed/NLSY/'

RANDOM_STATE = 12345

# Load Data (NLSY)
df = pd.read_stata('http://www.stata-press.com/data/r10/nlswork.dta')
df = df.dropna()

Y = df['ln_wage']
df.drop('ln_wage', axis='columns', inplace=True)
D = df['union']
df.drop('union', axis='columns', inplace=True)
X = df[['age', 'year', 'race', 'msp','collgrad', 'nev_mar', 'grade', 'not_smsa', 'south' ]]

# convert to pytorch tensor#
Y = torch.tensor(Y.values.astype(np.float32)).unsqueeze(-1)
D = torch.tensor(D.values.astype(np.float32)).unsqueeze(-1)
X = torch.tensor(X.values.astype(np.float32))

plt.figure()
plt.scatter(D, Y, s=2, alpha=0.6)
plt.xlim(-0.5, 1.5)
plt.title("Log wage Y on union status D")
plt.ylabel("Log wage Y")
plt.xlabel("Union status D")
plt.tight_layout()
plt.savefig(PATH + 'DY_scatter.png')

save_train_test_data(Y, D, X, PATH, RANDOM_STATE)


#!/usr/bin/python3
from Node import Node
from Link import Link
from APQ_Heap import APQHeap

class Graph:
    #the keys are the nodes and values are the link
    def __init__(self):
        #create an initial empty graph
        self._structure = dict()
    def __str__(self):
        strnodes="\nNodes"
        for v in self._structure:
            strnodes +="\t"+str(v)
        links=self.links()
        strlink="\nLinks:"
        for w in links:
            strlink +=str(w)
        return ("Total Nodes: " +str(self.num_nodes())+"\n"+"Total Links: "+
                               str(self.num_links())+ strnodes+strlink)
    #ADT methods to query the graph

    def num_nodes(self):
        return len(self._structure)

    def num_links(self):
        num = 0
        for v in self._structure:
            num +=len(self._structure[v])
        return num // 2

    def nodes(self):
        return [key for key in self._structure]

    def get_node_by_label(self, element):
        for v in self._structure:
            if v.element()== element:
                #print(v)
                return v
        return None
    def links(self):
        linklist = []
        for v in self._structure:
            for w in self._structure[v]:
                #to avoid duplicates,only return if v in the first nodes
                if self._structure[v][w].start() ==v:
                    linklist.append(self._structure[v][w])
        return linklist

    def get_links(self,v):
        #list of all links
        if v in self._structure:
            linklist = []
            for w in self._structure[v]:
                linklist.append(self._structure[v][w])
            return linklist
        return None

    def get_link(self,v,w):
        #link between v and w
        if(self._structure != None and v in self._structure
           and w in self._structure[v]):
            return self._structure[v][w]
        return None

    def degree(self, v):
        #return degree of node v
        return len(self._structure[v])

    def get_weight(self,v,w):
        #Cost between v and w
        if(self._structure !=None and v in self._structure
            and w in self._structure[v]):
            return len(self._structure[v][w])

    def add_node(self,element):
        v=Node(element)
        self._structure[v]=dict()
        return v

    def add_node_if_new(self, element):
        for v in self._structure:
            if v.element()== element:
                #print("already there")
                return v
        return self.add_node(element)

    def add_link(self, v, w,element):
        if not v in self._structure or not w in self._structure:
            return None
        e=Link(v,w,element)
        self._structure[v][w]=e
        self._structure[w][v]=e
        return e

    def highestdegreenode(self):
        #return the vertex with highet degree
        hd=-1
        hdv=None
        for v in self._structure:
            if self.degree(v)>hd:
                hd=self.degree(v)
                hdv = v
        return hdv

    def linkState(self, src):
        closed = dict()
        locs = dict()
        pred = {src:None}
        apq = APQHeap()#empty apq
        locs[src]=apq.add(0,src)
        while not apq.is_empty():
            key, u = apq.remove_min()
            del locs[u]
            closed[u]=(key,pred[u])
            for e in self.get_links(u):
                v = e.opposite(u)
                if v not in closed:
                    newcost = e.element() + key
                    if v not in locs:
                        pred[v] = u
                        locs[v] = apq.add(newcost,v)
                    elif newcost< apq.get_key(locs[v]):
                        pred[v] = u
                        apq.update_key(locs[v],newcost)
        return closed

    def graphreader(filename):

        """ Read and return the route map in filename. """
        graph = Graph()
        file = open(filename, 'r')
        entry = file.readline() #either 'Node' or 'Edge'
        num = 0
        print("**********Welcome to Link State Topology*************")
        while entry == 'Node\n':
            num += 1
            nodeid = int(file.readline().split()[1])
            node = graph.add_node(nodeid)
            entry = file.readline() #either 'Node' or 'Edge'
        print("\tFound", num, 'Nodes and added into the graph')
        num = 0
        while entry == 'Edge\n':
            num += 1
            source = int(file.readline().split()[1])
            sv = graph.get_node_by_label(source)
            target = int(file.readline().split()[1])
            tv = graph.get_node_by_label(target)
            length = float(file.readline().split()[1])
            edge = graph.add_link(sv, tv, length)
            file.readline() #read the one-way data
            entry = file.readline() #either 'Node' or 'Edge'
        print("\tFound", num, 'Links and added into the graph')
        print(graph)
        return graph

Experiment 4 - Shortest Path Algorithms/Graph.py


import socket

if __name__ == '__main__':
	hostname = 'google.co.uk'
	addr = socket.gethostbyname(hostname)
	print('The IP address of {} is {}'.format(hostname, addr))
	service = 'ssh'
	print(service+"'s port is " + str(socket.getservbyname('ssh')))

	sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	data = 'test'
	sock.sendto(data, ('127.0.0.1', 8000))
	print('The OS assigned me the address {}'.format(sock.getsockname()))


import tensorflow as tf
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import Sequential,Model,initializers,layers,Input
from tensorflow.keras.utils import plot_model
from tensorflow.keras.callbacks import ModelCheckpoint,EarlyStopping
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

class EffShuff_Dense_Block():
    def __init__(self,num_classes, input_shape=(224,224,3)):
        self.num_classes=num_classes
        self.input_shape=input_shape

    def Channel_Shuffle(self,x,groups):
        g = groups
        batch, height, width, channels = x.shape
        x = tf.reshape(x, [-1, height, width, g, channels // g])
        x = tf.transpose(x, perm = [0, 1, 2, 4, 3])
        x = tf.reverse(x,[-1])
        x = tf.reshape(x, [-1, height, width, channels])

        return x

    def EffShuff_Module(self,x,filter_size,groth_rate):

        x1,x2=layers.Lambda(lambda x: tf.split(x,num_or_size_splits=2,axis=3))(x)
        x1=layers.Conv2D(filters=filter_size//2+groth_rate,kernel_size=1,strides=1,padding='same',use_bias=False)(x1)
        x1=layers.BatchNormalization()(x1)
        x1=layers.ReLU(max_value=6)(x1)
        x1=layers.DepthwiseConv2D(kernel_size=3,strides=1,padding='same',use_bias=False)(x1)
        x1=layers.BatchNormalization()(x1)
        x1=layers.Conv2D(filters=filter_size//2+groth_rate,kernel_size=1,strides=1,padding='same',use_bias=False)(x1)
        x1=layers.BatchNormalization()(x1)
        x1=layers.ReLU(max_value=6)(x1)

        x3=layers.Concatenate()([x1,x2])

        return x3

    def EffShuff_Transition(self,x,filter_size):
        x2=layers.Conv2D(filters=filter_size,kernel_size=1,strides=1,padding='same',use_bias=False)(x)
        x2=layers.BatchNormalization()(x2)
        x2=layers.ReLU(max_value=6)(x2)
        x2=layers.DepthwiseConv2D(kernel_size=3,strides=2,padding='same',use_bias=False)(x2)
        x2=layers.BatchNormalization()(x2)
        x2=layers.BatchNormalization()(x2)
        x2=layers.ReLU(max_value=6)(x2)

        x1=layers.AveragePooling2D(pool_size=2,strides=2,padding='same')(x)
        x1=layers.Conv2D(filters=filter_size,kernel_size=1,strides=1,padding='same',use_bias=False)(x1)
        x3=layers.Concatenate()([x1,x2])
    # 셔플 추가할 것인가
        x3=layers.Lambda(lambda x:self.Channel_Shuffle(x,groups=2))(x3)

        return x3

    def Classifier(self, x):
        # if num_classes is None:
        #     num_classes = self.num_classes
        x=layers.GlobalAveragePooling2D()(x)
        x=layers.Dense(units=self.num_classes, activation='softmax')(x)
        return x

    def EffShuff_Block(self, x, filter_size, groth_rate, repeat):
        x=layers.Conv2D(filters=filter_size,kernel_size=1,strides=1,padding='same')(x)
        x = self.EffShuff_Module(x, filter_size, groth_rate)
        for i in range(repeat):
            x=self.EffShuff_Module(x=x, filter_size=x.shape[3], groth_rate=groth_rate)
        return x

    def forward(self):
        input=Input(shape=self.input_shape)
        x=layers.Conv2D(filters=64,kernel_size=3,strides=2,padding='same')(input)
        x=layers.MaxPool2D(pool_size=3,strides=2,padding='same')(x)
        x=self.EffShuffY_Transition(x,92)
        x=self.EffShuff_Block(x,92,16,2)
        x=self.EffShuff_Transition(x,176)
        x=self.EffShuff_Block(x,176,16,6)
        x=self.EffShuff_Transition(x,440)
        x=self.EffShuff_Block(x,440,16,2)
        x=self.Classifier(x)

        model = tf.keras.models.Model(input,x)

        return model


# -*- coding: utf-8 -*-

from django import forms
from django.forms import ModelForm
from django.forms.widgets import ClearableFileInput, HiddenInput, Textarea, TextInput, URLInput
from django.utils.translation import ugettext_lazy as _
from pysnippets.strsnippets import strip

from resources.models import ApiInfo, UserApiInfo, WebSiteInfo, WebSiteSubmit
from utils.tt4it_utils import *

class WebSiteDiyModelForm(ModelForm):
    class Meta:
        model = WebSiteInfo
        exclude = ('qiniu_logo', 'srcode', 'visit', 'evaluate', 'like', 'unlike', 'fav', 'display', 'create_time', 'modify_time')
        widgets = {
            'url': TextInput(
                attrs={'autocomplete': 'off', 'autofocus': 'autofocus', 'placeholder': _('Url')}
            ),
            'name': TextInput(
                attrs={'autocomplete': 'off', 'placeholder': _('Name')}
            ),
            'logo': ClearableFileInput(
                attrs={'autocomplete': 'off', 'placeholder': _('Logo')}
            ),
            'descr': Textarea(
                attrs={'autocomplete': 'off', 'placeholder': _('Description')}
            ),
            'tag': TextInput(
                attrs={'autocomplete': 'off', 'placeholder': _('Tag')}
            ),
        }

    def clean_url(self):
        url = self.cleaned_data['url']
        if not url:
            raise forms.ValidationError(_('The url is needed'))
        if 'http' not in url:
            raise forms.ValidationError(_('The url should starts with http(s)'))
        return url

    def clean_logo(self):
        logo = self.cleaned_data['logo']
        if not logo:
            raise forms.ValidationError(_('The logo is needed'))
        if logo.size > 50000:
            raise forms.ValidationError(_('The logo is too big'))
        return logo

class WebSiteSubmitModelForm(ModelForm):
    class Meta:
        model = WebSiteSubmit
        fields = '__all__'
        widgets = {
            'url': TextInput(
                attrs={'autocomplete': 'off', 'autofocus': 'autofocus', 'placeholder': _('Url')}
            ),
            'name': TextInput(
                attrs={'autocomplete': 'off', 'placeholder': _('Tag')}
            ),
            'deal': HiddenInput(),
        }

class ApiModelForm(ModelForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(ApiModelForm, self).__init__(*args, **kwargs)

    class Meta:
        model = ApiInfo
        fields = ('api', 'func', 'tag', 'url')
        widgets = {
            'api': TextInput(
                attrs={'autocomplete': 'off', 'autofocus': 'autofocus', 'placeholder': _('Api')}
            ),
            'func': Textarea(
                attrs={'autocomplete': 'off', 'onscroll': 'this.rows++;', 'placeholder': _('Func')}
            ),
            'tag': TextInput(
                attrs={'autocomplete': 'off', 'placeholder': _('Tags')}
            ),
            'url': URLInput(attrs={'autocomplete': 'off', 'placeholder': _('Url')}),
        }

    def clean_api(self):
        """ Clean for api """

        api = strip(self.cleaned_data['api'])
        if not api:
            raise forms.ValidationError(_('Api is needed'))
        a = ApiInfo.objects.filter(api=api)
        if a.exists():
            ua = UserApiInfo.objects.filter(api=a, user=getUI(getUsr(self.request)))
            if ua.exists():
                raise forms.ValidationError(_('This api has already record by you'))
            return api
        return api

    def clean_tag(self):
        """ Clean for tag """

        tag = strip(self.cleaned_data['tag']) or ''
        return ' '.join([strip(t) for t in tag.split(' ')])


import zmq
import multiprocessing as mp
import cv2
import time
import imutils

from imutils.video import VideoStream
from foosball.perception_utils import *
from foosball.angle_finder import find_angle

def camera_ps(shutdown, outfd, hwm, config, on_jetson):
    context = zmq.Context()

    socket = context.socket(zmq.PUB)
    socket.setsockopt(zmq.SNDHWM, hwm)
    socket.bind(outfd)

    if on_jetson:
        camera = VideoStream(src="nvarguscamerasrc wbmode=4 aelock=true gainrange=\"8 8\" ispdigitalgainrange=\"1 1\" exposuretimerange=\"5000000 5000000\" ! video/x-raw(memory:NVMM), "\
                            "width=(int)1280, height=(int)720, format=(string)NV12, " \
                            "framerate=(fraction)40/1 ! nvvidconv flip-method=2 ! video/x-raw, " \
                            "format=(string)BGRx ! videoconvert ! video/x-raw, " \
                            "format=(string)BGR ! appsink").start()
    else:
        camera = VideoStream('unity_5.mkv')
    time.sleep(2.0)

    frame = 0
    mask = get_mask(config['ROI'])
    filt = get_filt()
    vm = VelocityMonitor()
    roi = config['ROI']
    bt = config['BALL_THRESH']
    rt = config['ROBOT_THRESH']
    ht = config['HUMAN_THRESH']

    while not shutdown.is_set():
        # Fetch and crop frame
        image = camera.read()
        image = crop_image(image, mask)
        image = imutils.resize(image, width=500)

        # Preprocess frame for perception
        hsv = cv2.GaussianBlur(image, (11, 11), 0)
        hsv = cv2.cvtColor(hsv, cv2.COLOR_BGR2HSV)

        # Threshold frame
        ball = cv2.inRange(hsv, *bt)
        robot = cv2.inRange(hsv, *rt)
        human = cv2.inRange(hsv, *ht)

        # Postprocess thresholds
        human = cv2.erode(human, None, iterations=2)
        human = human / 255
        robot = robot / 255

        # Track ball
        try:
            ballx, bally = track_ball(ball)
            vm.pos(ballx, bally)
        except ValueError:
            ballx, bally = -1., -1.
            vm.clear()

        ballxv, ballyv = vm.velocity()
        ballxv /= config['PIXELS_PER_CM']
        ballyv /= config['PIXELS_PER_CM']

        # Track human player
        hg_roi = human[:, 0:125]
        hg_loc = get_player_pos(hg_roi, filt)
        hg_l, hg_r = get_player_bounds(hg_roi)
        hg_ang = -find_angle(*mirror_player(hg_l, hg_r, *config['GOALIE_PARAMS']), True)

        ho_roi = human[:, 250:375]
        ho_loc = get_player_pos(ho_roi, filt)
        ho_l, ho_r = get_player_bounds(ho_roi)
        ho_ang = -find_angle(*mirror_player(ho_l, ho_r, *config['OFFENSE_PARAMS']), False)

        # Track robot player
        rg_roi = robot[:, 375:500]
        rg_loc = get_player_pos(rg_roi, filt)
        rg_l, rg_r = get_player_bounds(rg_roi)
        rg_ang = find_angle(rg_l, rg_r, True)

        ro_roi = robot[:, 125:250]
        ro_loc = get_player_pos(ro_roi, filt)
        ro_l, ro_r = get_player_bounds(ro_roi)
        ro_ang = find_angle(ro_l, ro_r, False)

        # Compile track object
        tracks = {
            'frame': frame,
            'ball': {
                'x': ballx,
                'y': bally,
                'xv': ballxv,
                'yv': ballyv
            },
            'human': {
                'goalie': {
                    'loc': hg_loc,
                    'ang': hg_ang
                },
                'offense': {
                    'loc': ho_loc,
                    'ang': ho_ang
                }
            },
            'robot': {
                'goalie': {
                    'loc': rg_loc,
                    'ang': rg_ang
                },
                'offense': {
                    'loc': ro_loc,
                    'ang': ro_ang
                }
            }
        }

        print(f"Sending frame {frame}")
        try:
            socket.send_pyobj(tracks, flags=zmq.NOBLOCK)
        except zmq.error.Again:
            print("hwm hit!")

        frame += 1

class Camera:
    hwm = 10

    def __init__(self, endpoint, config, is_jetson=True):
        self.outfd = endpoint
        self.shutdown = mp.Event()
        self.psargs = (self.shutdown, self.outfd, self.hwm, config, is_jetson)
        self.ps = None

    def start(self):
        if self.ps is not None:
            raise RuntimeError("Camera already running!")

        self.ps = mp.Process(target=camera_ps, args=self.psargs)
        self.ps.daemon = True
        self.ps.start()
        print(self)

    def stop(self):
        if self.ps is None:
            raise RuntimeError("Camera not running")

        self.shutdown.set()
        self.ps.join()
        self.ps = None
        self.shutdown.clear()

    def __repr__(self):
        rpr = "-------Camera-------\n"
        rpr += f"OUT: {self.outfd}\n"
        rpr += f"HWM: {self.hwm}\n"

        return rpr


import http

import requests
from requests import adapters
from urllib3.util import retry

def get_http_client(total_retries: int = 5, backoff_factor: float = 0.1) -> requests.Session:
    """Construct retryable http client.

    Args:
        total_retries: Total number of retries to allow.
        backoff_factor: A backoff factor to apply between attempts after the second try. Time to sleep is calculated by
            {backoff factor} * (2 ** ({number of previous retries})). For example, with default retries of 5 and backoff
            factor set to 0.1, each subsequent retry will sleep [0.2s, 0.4s, 0.8s, 1.6s, 3.2s] respectively.

    Returns:
        requests.Session object.

    """

    retry_strategy = retry.Retry(
        total=total_retries,
        backoff_factor=backoff_factor,
        status_forcelist=[
            http.HTTPStatus.TOO_MANY_REQUESTS,
            http.HTTPStatus.INTERNAL_SERVER_ERROR,
            http.HTTPStatus.BAD_GATEWAY,
            http.HTTPStatus.SERVICE_UNAVAILABLE,
            http.HTTPStatus.GATEWAY_TIMEOUT,
        ],  # retry on these status codes
    )

    adapter = adapters.HTTPAdapter(max_retries=retry_strategy)
    req_session = requests.Session()
    req_session.mount("https://", adapter)
    req_session.mount("http://", adapter)

    return req_session


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

import gmpy2

import sys
sys.path.append("..")
from cryptolib import *

"""
In number theory, the Chinese remainder theorem states that
if one knows the remainders of the Euclidean division of an integer n
by several integers, then one can determine uniquely the remainder of the division of n
by the product of these integers, under the condition that the divisors are pairwise coprime.

# 2 = 23 % 3
# 3 = 23 % 5
# 2 = 23 % 7
n = [3, 5, 7]
a = [2, 3, 2]
chinese_remainder(n, a) == 23
"""

def main():
	secret_plaintext = random_string(100).encode('utf-8')
	print('plaintext is:{}'.format(secret_plaintext.decode('utf-8')))

	rsa = RSA()
	rsa.gen_keypair()
	e1, n1 = rsa.get_public_key()
	rsa.gen_keypair()
	e2, n2 = rsa.get_public_key()
	rsa.gen_keypair()
	e3, n3 = rsa.get_public_key()

	ct1 = rsa.encrypt(secret_plaintext, 3, n1)
	ct1 = int.from_bytes(ct1, 'big')
	ct2 = rsa.encrypt(secret_plaintext, 3, n2)
	ct2 = int.from_bytes(ct2, 'big')
	ct3 = rsa.encrypt(secret_plaintext, 3, n3)
	ct3 = int.from_bytes(ct3, 'big')

	n = [n1, n2, n3]
	a = [ct1, ct2, ct3]
	result_cubed = chinese_remainder(n, a)

	result = int(gmpy2.iroot_rem(result_cubed, 3)[0])

	plaintext = "%x" % result
	plaintext = bytes.fromhex(plaintext)
	plaintext = plaintext.decode('utf-8')
	print('recovered   :{}'.format(plaintext))

if __name__ == '__main__':
	main()


from FreeCAD import *
import PartGui
import GDMLCommands, GDMLResources

def processDefault(doc) :
    from importGDML import processGDML
    processGDML(doc,FreeCAD.getResourceDir() + \
                "Mod/GDML/Resources/Default.gdml",False)

class GDML_Workbench ( Workbench ):

    class MyObserver():
       def __init__(self):
           self.signal = []

       def slotCreatedDocument(self, doc):
           from importGDML import processGDML
           processGDML(doc,FreeCAD.getResourceDir() + \
                "Mod/GDML/Resources/Default.gdml",False)

    "GDML workbench object"
    def __init__(self):
        self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/GDML/Resources/icons/GDMLWorkbench.svg"
        self.__class__.MenuText = "GDML"
        self.__class__.ToolTip = "GDML workbench"

    def Initialize(self):
        def QT_TRANSLATE_NOOP(scope, text):
            return text

        #import GDMLCommands, GDMLResources
        commands=['CycleCommand','ExpandCommand', \
                 'BoxCommand','ConeCommand','ElTubeCommand', \
                  'EllipsoidCommand','SphereCommand', \
                  'TrapCommand','TubeCommand','AddCompound']
        toolbarcommands=['CycleCommand','ExpandCommand', \
                         'BoxCommand','ConeCommand', \
                  'ElTubeCommand', 'EllipsoidCommand','SphereCommand', \
                  'TrapCommand','TubeCommand','AddCompound']

        parttoolbarcommands = ['Part_Cut','Part_Fuse','Part_Common']

        self.appendToolbar(QT_TRANSLATE_NOOP('Workbench','GDMLTools'),toolbarcommands)
        self.appendMenu('GDML',commands)
        self.appendToolbar(QT_TRANSLATE_NOOP('Workbech','GDML Part tools'),parttoolbarcommands)
        ResourcePath = FreeCAD.getHomePath() + "Mod/GDML/Resources/"
        print("Resource Path : "+ResourcePath)
        #FreeCADGui.addIconPath(FreeCAD.getResourceDir() + \
        #FreeCADGui.addIconPath(":/icons")
        FreeCADGui.addIconPath(ResourcePath + "icons")
        #FreeCADGui.addLanguagePath(":/translations")
        FreeCADGui.addLanguagePath(ResourcePath + "/translations")
        FreeCADGui.addPreferencePage(ResourcePath + "/ui/GDML-base.ui","GDML")

    def Activated(self):
        "This function is executed when the workbench is activated"
        print ("Activated")
        self.obs = self.MyObserver()
        App.addDocumentObserver(self.obs)
        doc = FreeCAD.activeDocument()
        if doc != None :
           #print(dir(doc))
           if len(doc.Objects) > 0 :
              if doc.Objects[0].Name != "Constants" :
                 #self.processDefault(doc)
                 #processDefault(doc)
                 self.MyObserver.slotCreatedDocument(self,doc)
           else :
              self.MyObserver.slotCreatedDocument(self,doc)
        return

    def Deactivated(self):
        "This function is executed when the workbench is deactivated"
        App.removeDocumentObserver(self.obs)
        return

    def GetClassName(self):
        return "Gui::PythonWorkbench"

Gui.addWorkbench(GDML_Workbench())


# pylint: disable=no-member,line-too-long

from __future__ import print_function

from builtins import str # # pylint: disable=redefined-builtin

import base64
import gzip
import json

import io

import six

from nacl.public import PublicKey, PrivateKey, Box

from django.conf import settings
from django.core.management.base import BaseCommand

from ...decorators import handle_lock
from ...models import DataBundle, install_supports_jsonfield

class Command(BaseCommand):
    help = 'Prints the content of a bundle to the terminal, uncompressing and decrypting if necessary.'

    def add_arguments(self, parser):
        parser.add_argument('bundle_pk',
                            nargs=1,
                            type=int,
                            help='PK of bundle to dump')

    @handle_lock
    def handle(self, *args, **options): # pylint: disable=too-many-locals, too-many-branches, too-many-statements
        supports_json = install_supports_jsonfield()

        bundle = DataBundle.objects.get(pk=options['bundle_pk'][0])

        if supports_json is False:
            bundle.properties = json.loads(bundle.properties)

        if bundle.encrypted:
            if 'nonce' in bundle.properties and 'encrypted' in bundle.properties:
                payload = base64.b64decode(bundle.properties['encrypted'])
                nonce = base64.b64decode(bundle.properties['nonce'])

                private_key = PrivateKey(base64.b64decode(settings.PDK_SERVER_KEY).strip()) # pylint: disable=line-too-long
                public_key = PublicKey(base64.b64decode(settings.PDK_CLIENT_KEY).strip()) # pylint: disable=line-too-long

                box = Box(private_key, public_key)

                decrypted_message = box.decrypt(payload, nonce)

                decrypted = six.text_type(decrypted_message, encoding='utf8')

                if bundle.compression != 'none':
                    compressed = base64.b64decode(decrypted)

                    if bundle.compression == 'gzip':
                        fio = io.StringIO(compressed)  # io.BytesIO for Python 3
                        gzip_file_obj = gzip.GzipFile(fileobj=fio)
                        payload = gzip_file_obj.read()
                        gzip_file_obj.close()

                        decrypted = payload

                bundle.properties = json.loads(decrypted)
            elif 'encrypted' in bundle.properties:
                print('Missing "nonce" in encrypted bundle. Cannot decrypt bundle ' + str(bundle.pk) + '. Skipping...')
            elif 'nonce' in bundle.properties:
                print('Missing "encrypted" in encrypted bundle. Cannot decrypt bundle ' + str(bundle.pk) + '. Skipping...')
        elif bundle.compression != 'none':
            compressed = base64.b64decode(bundle.properties['payload'])

            if bundle.compression == 'gzip':
                fio = io.StringIO(compressed)  # io.BytesIO for Python 3
                gzip_file_obj = gzip.GzipFile(fileobj=fio)
                payload = gzip_file_obj.read()
                gzip_file_obj.close()

                bundle.properties = json.loads(payload)

        print(json.dumps(bundle.properties, indent=2))


class Stack:
    """ Stack implementation for storing elements in LIFO order """

    def __init__(self, size: int = 32):
        """ Construct empty stack of specified size with head pointed at first empty element """
        self.size = size
        self.data = [None] * self.size
        self.head = 0

    def is_empty(self) -> bool:
        """ Checks if a stack is empty """
        return self.head == 0

    def push(self, value: any):
        """ Push a value onto the stack and increment the head pointer """
        if self.head == self.size:
            print("Stack has reached full capacity! Unable to add any more elements")
        else:
            self.data[self.head] = value
            self.head += 1

    def pop(self) -> any:
        """ Pop a value from the top of the stack and decrement the head pointer """
        if self.is_empty():
            print("Stack is empty! Unable to remove any more elements!")
        else:
            self.head -= 1
            value = self.data[self.head]
            self.data[self.head] = None  # let the GC handle deletion
            return value

    def peek(self) -> any:
        """ Peek at a value from the top of the stack without removing it """
        if self.is_empty():
            print("Stack is empty! Unable to view any more elements!")
        else:
            self.head -= 1
            value = self.data[self.head]
            self.head += 1
            return value


#!/usr/bin/env pybricks-micropython

from pybricks.parameters import Port, Color, Button
# from pybricks.ev3devices import Motor, ColorSensor, InfraredSensor, GyroSensor, TouchSensor, UltrasonicSensor
from pybricks.hubs import EV3Brick
from pybricks.media.ev3dev import Font, Image, ImageFile
from os import listdir, system
import os.path
import time, _thread, typing, sys, traceback, json

# Credits: <https://github.com/pybricks/support/issues/152#issuecomment-709608118>

def rl(path) -> str:
    "Open a file, return its first line and close the file afterwards, ignoring any errors."
    try:
        f = open(path)
        txt = f.readline()
        f.close()
    except:
        txt = "0"
    return txt

class Sensor:
    def __init__(self, path) -> None:
        self.path = path
        self.driverName = rl(self.path+"/driver_name")[:-1]
        self.portLetter = rl(self.path+"/address")[12:13]
        self.numValues = int(rl(self.path+"/num_values")[:-1])
        self.mode = rl(self.path+"/mode")[:-1]
        self.values = None
        self.modes = rl(self.path+"/modes").split()
        self.commands = rl(self.path + "/commands").split()
        self.additionalAttributes = {"gyro-ang-offset": 0, "gyro-tilt-offset": 0} if self.driverName == "lego-ev3-gyro" else {}

    def setMode(self, mode):
        self.mode = mode
        system("echo %s > %s/mode" % (mode, self.path))
        self.numValues = int(rl(self.path+"/num_values")[:-1])

    def getValues(self):
        self.values = [int(rl(self.path+"/value"+str(i))[:-1]) for i in range(self.numValues)]
        return self.values

    def execCommand(self, command):
        system("echo %s > %s/command" % (command, self.path))
        self.numValues = int(rl(self.path+"/num_values")[:-1])

class Motor:
    def __init__(self, path) -> None:
        self.path = path
        self.portLetter = rl(self.path+"/address")[-2:-1]
        self.driverName = rl(self.path+"/driver_name")[:-1]
        self.speed = None
        self.position = None

    def getPosition(self):
        self.position = int(rl(self.path+"/position")[:-1])
        return self.position

    def getSpeed(self):
        self.speed = int(rl(self.path+"/speed")[:-1])
        return self.speed

    def resetPos(self):
        system("echo reset > %s/command" % self.path)

sensorNames = []
motorNames = []

portDevList = [None] * 8

# portDevList:typing.List[typing.Union[None, Motor, Sensor]] = [None] * 8

def updateDevList():
    global portDevList, sensorNames, motorNames

    dirs = listdir("/sys/class/tacho-motor")
    if dirs != motorNames: # motor added / removed
        print("updateDevList: Motor added/removed")
        portDevList[:4] = [None] * 4
        for dir in dirs:
            m = Motor("/sys/class/tacho-motor/"+dir)
            portDevList[ord(m.portLetter)-65] = m
    motorNames = dirs

    dirs = listdir("/sys/class/lego-sensor")
    if dirs != sensorNames: # sensor added / removed
        print("updateDevList: Sensor added/removed")
        portDevList[4:] = [None] * 4
        for dir in dirs:
            s = Sensor("/sys/class/lego-sensor/"+dir)
            portDevList[int(s.portLetter)+3] = s
    sensorNames = dirs

def caliEv3Reflect(sensor: Sensor):
    global portDevList, b, render, allCaliVals
    render = False
    time.sleep(0.1)

    b.screen.clear()
    b.screen.set_font(f18)
    txt = "Calibration: Port " + sensor.portLetter
    b.screen.draw_text((b.screen.width - f18.text_width(txt))/2, 0, txt)
    b.screen.set_font(f12)
    txt = "Put the sensor on a"
    b.screen.draw_text((b.screen.width - f12.text_width(txt))/2, 30, txt)
    txt = "surface and press [CENTER]"
    b.screen.draw_text((b.screen.width - f12.text_width(txt))/2, 70, txt)
    b.screen.set_font(f24)
    txt = "BLACK"
    b.screen.draw_text((b.screen.width - f24.text_width(txt))/2, 42, txt)
    sensor.setMode("COL-REFLECT")

    while not Button.CENTER in b.buttons.pressed():
        time.sleep(0.05)
    while Button.CENTER in b.buttons.pressed():
        time.sleep(0.05)
    black = sensor.getValues()[0]

    b.screen.draw_box(0, 42, b.screen.width, 70, fill=True, color=Color.WHITE)
    txt = "WHITE"
    b.screen.draw_text((b.screen.width - f24.text_width(txt))/2, 42, txt)

    while not Button.CENTER in b.buttons.pressed():
        time.sleep(0.05)
    white = sensor.getValues()[0]

    if white == black:
        b.screen.clear()
        b.screen.set_font(f12)
        b.screen.draw_text(0, 5, "Invalid values.")
        b.screen.draw_text(0, 25, "Please recalibrate.")
        while not any(b.buttons.pressed()):
            time.sleep(0.05)
    else:
        with open("/home/robot/.caliValues.json") as f:
            allCaliVals = json.load(f)
        allCaliVals[sensor.portLetter]["reflect"][0] = 100 / (white - black)
        allCaliVals[sensor.portLetter]["reflect"][1] = (-100 * black) / (white - black)
        with open("/home/robot/.caliValues.json", "w") as f:
            json.dump(allCaliVals, f, indent=4)

    render = True

def caliEv3Rgb(sensor: Sensor):
    global b, render
    render = False

    # Radios:rounded boxes, unfilled circle left (with dot inside if active), caption right, inverted colors if selected
    # Cali-Modes: (Todo: Try out -> Default)
        # Black + White
        # Black + Red+Green+Blue
    # Value range:
        # 0-255 (default)
        # 0-100
    # Start-Button (selected by default)

    render = True

def resetGyroAngles(sensor: Sensor):
    if sensor.mode in ("GYRO-ANG", "GYRO-G&A"):
        sensor.additionalAttributes["gyro-ang-offset"] = int(sensor.values[0])
    elif sensor.mode == "TILT-ANG":
        sensor.additionalAttributes["gyro-tilt-offset"] = int(sensor.values[0])

additionalFunctions = {
    "lego-ev3-color": {
        "Calib. COL-REFLECT": caliEv3Reflect,
        # "Calib. RGB-RAW": caliEv3Rgb
    },
    # "lego-ev3-gyro": {
    #     "Reset angles": resetGyroAngles
    # }
}

b = EV3Brick()
selectedDevNr = 6 # Number of the selected device (0-7)
modeSelected = [1, ""] # mode/command selected
menuOptionNrSelected = 0 # including headings
menuScrollPos = 0 # scroll pos of modeMenu
menuOptionsList = [] # All elements of the menu, including headings
portLetters = ["A", "B", "C", "D", "1", "2", "3", "4"]
menuOpen = False
allCaliVals = []
render = True # if False, stop rendering
f12 = Font(size=12)
f18 = Font(size=18)
f24 = Font(size=24)

defaultSettings = {'calibration.ev3col.reflect.enabled': True, 'calibration.ev3col.rgb.enabled': False, 'calibration.ev3col.rgb.defaultRange': 255, 'calibration.ev3col.rgb.defaultMode': 'single', 'hideModes': {'lego-ev3-color': ['COL-CAL'], 'lego-ev3-gyro': ['GYRO-CAL'], 'lego-ev3-ir': ['IR-CAL', 'IR-S-ALT']}}
try:
    settings = json.load(open("/home/robot/.portView.conf.json"))
except:
    try:
        settings = json.load(open(__file__.rsplit("/", 1)[0]+"/.portView.conf.json"))
    except:
        settings = defaultSettings
for k in defaultSettings.keys():
        if k not in settings.keys():
            settings[k] = defaultSettings[k]

#arrow_up = Image("arrow_up_s.png")
arrow_up = Image.empty(22, 22)
arrow_up.draw_box(0, 0, 21, 21, fill=True)
arrow_up.draw_line(8, 18, 16, 18, color=Color.WHITE)
arrow_up.draw_line(8, 18, 8, 10, color=Color.WHITE)
arrow_up.draw_line(16, 18, 16, 10, color=Color.WHITE)
arrow_up.draw_line(8, 10, 4, 10, color=Color.WHITE)
arrow_up.draw_line(16, 10, 20, 10, color=Color.WHITE)
arrow_up.draw_line(4, 10, 12, 2, color=Color.WHITE)
arrow_up.draw_line(20, 10, 12, 2, color=Color.WHITE)

#arrow_down = Image("arrow_down_s.png")
arrow_down = Image.empty(22, 22)
arrow_down.draw_box(0, 0, 21, 21, fill=True)
arrow_down.draw_line(8, 6, 16, 6, color=Color.WHITE)
arrow_down.draw_line(8, 6, 8, 14, color=Color.WHITE)
arrow_down.draw_line(16, 6, 16, 14, color=Color.WHITE)
arrow_down.draw_line(8, 14, 4, 14, color=Color.WHITE)
arrow_down.draw_line(16, 14, 20, 14, color=Color.WHITE)
arrow_down.draw_line(4, 14, 12, 22, color=Color.WHITE)
arrow_down.draw_line(20, 14, 12, 22, color=Color.WHITE)

if any([settings["calibration.ev3col.reflect.enabled"], settings["calibration.ev3col.rgb.enabled"]]):
    try:
        f = open("/home/robot/.caliValues.json")
        allCaliVals = json.load(f)
        f.close()
    except:
        #f = open("/home/robot/.caliValues.json", "w")
        #f.write("{\"1\": [0, 100], \"2\": [0, 100], \"3\": [0, 100], \"4\": [0, 100]}")
        #f.close()
        #allCaliVals = {str(i+1): [0, 100] for i in range(4)}
        allCaliVals = {str(i+1): {"reflect": [1, 0], "rgb": {c: [1, 0] for c in ["red", "green", "blue"]}} for i in range(4)}
        json.dump(allCaliVals, open("/home/robot/.caliValues.json", "w"))
        print("CaliLoader: Created new .caliValues file")

def keyhandler():
    global selectedDevNr, modeSelected, menuOptionNrSelected, menuScrollPos, menuOptionsList, menuOpen, b, portDevList
    while True:
        while not any(b.buttons.pressed()):
            time.sleep(0.05)

        buttons = b.buttons.pressed()
        if not menuOpen:
            if Button.LEFT in buttons:
                if selectedDevNr == 0:
                    selectedDevNr = 7
                else:
                    selectedDevNr -= 1
            elif Button.RIGHT in buttons:
                if selectedDevNr == 7:
                    selectedDevNr = 0
                else:
                    selectedDevNr += 1
            elif Button.UP in buttons or Button.DOWN in buttons:
                if selectedDevNr > 3:
                    selectedDevNr -= 4
                else:
                    selectedDevNr += 4
            elif Button.CENTER in buttons and portDevList[selectedDevNr] != None:
                if selectedDevNr > 3: # Sensor -> open menu
                    menuOpen = True
                    print("keyhandler: opening modeMenu")

                    # menuOptionsList = [(0, "Modes:")] + [(1, elem) for elem in portDevList[selectedDevNr].modes if elem not in settings["hideModes"][portDevList[selectedDevNr].driverName]]
                    menuOptionsList = [(0, "Modes:")]
                    for mode in portDevList[selectedDevNr].modes:
                        if portDevList[selectedDevNr].driverName in settings["hideModes"]:
                            if mode in settings["hideModes"][portDevList[selectedDevNr].driverName]:
                                continue
                        menuOptionsList += [(1, mode)]

                    if portDevList[selectedDevNr].commands != []:
                        menuOptionsList += [(0, "Commands:")] + [(2, elem) for elem in portDevList[selectedDevNr].commands]
                    if portDevList[selectedDevNr].driverName in additionalFunctions.keys():
                        menuOptionsList += [(0, "Additional functions")]
                        for title in additionalFunctions[portDevList[selectedDevNr].driverName].keys():
                            menuOptionsList += [(3, title, additionalFunctions[portDevList[selectedDevNr].driverName][title])]
                    #if portDevList[selectedDevNr].driverName == "lego-ev3-color" and any(settings["calibration.ev3col.reflect.enabled"], settings["calibration.ev3col.rgb.enabled"]): # Calibration
                    #    menuOptionsList += [(0, "Additional: Calibration")]
                    #    if settings["calibration.ev3col.reflect.enabled"]:
                    #        menuOptionsList += [(3, "Calib. COL-REFLECT", caliEv3Reflect)]
                    #    if settings["calibration.ev3col.rgb.enabled"]:
                    #    menuOptionsList += [(3, "Calib. RGB-RAW", caliEv3Rgb)]

                    menuOptionNrSelected = menuOptionsList.index((1, portDevList[selectedDevNr].mode))
                    menuScrollPos = 0
                    if len(menuOptionsList) > 5:
                        if menuOptionNrSelected > 4:
                            menuScrollPos = menuOptionNrSelected - 4

                    print("keyhandler: menuOptionsList:", menuOptionsList)

                else: # Motor -> reset
                    portDevList[selectedDevNr].resetPos()
                    print("keyhandler: resetting pos")

        else: # menuOpen == True
            if Button.UP in buttons:
                if menuOptionNrSelected != 1: # 0 -> Heading "Modes"
                    menuOptionNrSelected -= 1
                if menuOptionsList[menuOptionNrSelected][0] == 0:
                    menuOptionNrSelected -= 1

                if menuOptionNrSelected == 1 and menuScrollPos != 0: # Scroll up to make the heading visible
                    menuScrollPos = 0
                elif menuOptionNrSelected < menuScrollPos and menuScrollPos != 0:
                    menuScrollPos -= 1

            elif Button.DOWN in buttons:
                if menuOptionNrSelected != len(menuOptionsList)-1:
                    menuOptionNrSelected += 1
                if menuOptionsList[menuOptionNrSelected][0] == 0:
                    menuOptionNrSelected += 1

                for i in range(2):
                    if menuOptionNrSelected-4 > menuScrollPos:
                        menuScrollPos += 1

            elif Button.LEFT in buttons: # close the menu without changing anything
                menuOpen = False
                print("keyhandler: closing modeMenu")

            elif Button.CENTER in buttons:
                if menuOptionsList[menuOptionNrSelected][0] == 1: # Mode
                    portDevList[selectedDevNr].setMode(menuOptionsList[menuOptionNrSelected][1])
                elif menuOptionsList[menuOptionNrSelected][0] == 2: # Command
                    portDevList[selectedDevNr].execCommand(menuOptionsList[menuOptionNrSelected][1])
                elif menuOptionsList[menuOptionNrSelected][0] == 3: # Additional function
                    menuOptionsList[menuOptionNrSelected][2](portDevList[selectedDevNr])

                print("keyhandler: closing modeMenu")
                menuOpen = False

        while any(b.buttons.pressed()):
            time.sleep(0.05)

_thread.start_new_thread(keyhandler, [])

while True:
    if not render:
        time.sleep(0.1)
        continue

    # try:
    if not menuOpen:
        time.sleep(0.1)

        updateDevList()

        # print(portDevList)
        b.screen.clear()
        b.screen.set_font(f12)

        for i in range(4): # Motoren
            if i == selectedDevNr:
                b.screen.draw_box(44*i, 0, 44+44*i, 22, 5, True)
                b.screen.draw_image(10+44*i, -3, arrow_down)
            else:
                b.screen.draw_box(44*i, 0, 44+44*i, 22, 5, False)
                if portDevList[i] == None:
                    b.screen.draw_text(16+44*i, 5, "---")
                else:
                    txt = str(portDevList[i].getPosition())
                    b.screen.draw_text(44*i + (44-f12.text_width(txt))/2, 5, txt)

        for i in range(4): # Sensoren
            if i+4 == selectedDevNr:
                b.screen.draw_box(44*i, 105, 44+44*i, 127, 5, True)
                b.screen.draw_image(10+44*i, 105, arrow_up)
            else:
                b.screen.draw_box(44*i, 105, 44+44*i, 127, 5, False)
                if portDevList[i+4] == None:
                    b.screen.draw_text(16+44*i, 110, "---")
                elif len(portDevList[i+4].getValues()) > 1:
                    b.screen.draw_text(14+44*i, 110, "[...]")
                else:
                    if portDevList[i+4].mode == "COL-REFLECT" and settings['calibration.ev3col.reflect.enabled']:
                        vals = allCaliVals[portDevList[selectedDevNr].portLetter]["reflect"]
                        txt = str(int(vals[0] * portDevList[i+4].values[0] + vals[1]))
                    else:
                        txt = str(portDevList[i+4].values[0])
                    b.screen.draw_text(44*i + (44-f12.text_width(txt))/2, 110, txt)

        b.screen.set_font(f18)
        if portDevList[selectedDevNr] == None:
            b.screen.draw_text(0, 24, "%s: None" % portLetters[selectedDevNr])
        else:

            if selectedDevNr < 4: # Motor:
                b.screen.draw_text(0, 24, "%s: %s" % (portLetters[selectedDevNr], portDevList[selectedDevNr].driverName))
                b.screen.set_font(f12)
                b.screen.draw_text(7, 50, "Position [deg]")
                b.screen.draw_text(95, 50, "Speed [deg/s]")
                # b.screen.set_font(f18 if abs(int(portDevList[selectedDevNr].getPosition())) < 1000 and abs(int(portDevList[selectedDevNr].getSpeed())) < 1000 else f12)
                b.screen.set_font(f24)

                pos = str(portDevList[selectedDevNr].getPosition())
                b.screen.draw_text((b.screen.width/2 - f24.text_width(pos))/2, 75, pos)
                b.screen.draw_line(88, 42, 88, 90)

                speed = str(portDevList[selectedDevNr].getSpeed())
                b.screen.draw_text(b.screen.width/2 + (b.screen.width/2 - f24.text_width(speed))/2, 75, speed)

                # b.screen.set_font(f12)
                # b.screen.draw_text(0, 80, "Press [CENTER] to reset position")
            else: # Sensor
                b.screen.draw_text(0, 24, "%s: %s" % (portLetters[selectedDevNr], portDevList[selectedDevNr].mode))
                b.screen.set_font(f12)
                nv = portDevList[selectedDevNr].numValues
                b.screen.draw_text(0, 40, str(nv) + (" Value" if nv == 1 else " Values"))
                b.screen.set_font(f24)
                b.screen.draw_text(30, 55, str(portDevList[selectedDevNr].getValues())[1:-1])

                if portDevList[selectedDevNr].driverName == "lego-ev3-color" and portDevList[selectedDevNr].mode == "COL-REFLECT" and settings["calibration.ev3col.reflect.enabled"]:
                    b.screen.draw_line(88, 42, 88, 90)
                    b.screen.set_font(f12)
                    b.screen.draw_text(95, 40, "Calibrated")
                    b.screen.set_font(f24)
                    vals = allCaliVals[portDevList[selectedDevNr].portLetter]["reflect"]
                    b.screen.draw_text(110, 55, str(int(vals[0] * portDevList[selectedDevNr].values[0] + vals[1])))

                if portDevList[selectedDevNr].driverName == "lego-ev3-color" and portDevList[selectedDevNr].mode == "RGB-RAW" and settings["calibration.ev3col.rgb.enabled"]:
                    b.screen.draw_line(88, 42, 88, 90)
                    b.screen.set_font(f12)
                    b.screen.draw_text(95, 40, "Calibrated")
                    b.screen.set_font(f24)
                    vals = [allCaliVals[portDevList[selectedDevNr].portLetter]["rgb"][key] for key in ["red", "green", "blue"]]
                    input(vals)
                    b.screen.draw_text(110, 55, str([int(vals[colNr][1] * portDevList[selectedDevNr].values[colNr] + vals[colNr][2]) for colNr in range(3)])[1:-1])

    else: # menuOpen
        time.sleep(0.1)
        b.screen.clear()

        txt = portDevList[selectedDevNr].driverName
        f = f18 if f18.text_width(txt) < b.screen.width else f12
        b.screen.set_font(f)
        b.screen.draw_text((b.screen.width - f.text_width(txt))/2, 0, txt)

        rows2display = []
        if len(menuOptionsList) > 5:
            rows2display = menuOptionsList[menuScrollPos:menuScrollPos+5]
            # Scrollbar https://stackoverflow.com/questions/16366795/how-to-calculate-the-size-of-scroll-bar-thumb/22710156#22710156
            b.screen.draw_box(b.screen.width-8, 22, b.screen.width-1, 120)
            arrowHeight = 4
            viewportHeight = 100
            contentHeight = len(menuOptionsList) * 20

            # viewableRatio = viewportHeight / contentHeight
            # scrollbarArea = viewportHeight - arrowHeight * 2
            thumbHeight = (viewportHeight - arrowHeight * 2) * (viewportHeight / contentHeight)

            # scrollTrackSpace = contentHeight - scrollbarArea
            # scrollThumbSpace = viewportHeight - thumbHeight
            # scrollJump = scrollTrackSpace / scrollThumbSpace

            # contentOffset = menuScrollPos * 20
            thumbOffset = ((menuScrollPos * 20) / ((contentHeight - (viewportHeight - arrowHeight * 2)) / (viewportHeight - thumbHeight))) + 22 + arrowHeight/2
            # print(scrollbarArea, viewableRatio, thumbHeight, thumbOffset)
            # barLength = (5/len(menuOptionsList)) * 94
            # absScrollPos = (menuOptionNrSelected+1 / len(menuOptionsList)) * 94
            # topOffset = 24 + absScrollPos + barLength/2
            b.screen.draw_box(b.screen.width - 6, thumbOffset, b.screen.width - 3, thumbOffset + thumbHeight-1, r=2, fill=True)
        else:
            rows2display = menuOptionsList

        b.screen.set_font(f12)
        # Debug
        # b.screen.draw_text(0, 0, str(menuOptionNrSelected))
        # b.screen.draw_text(b.screen.width-f12.text_width(str(menuScrollPos)), 0, str(menuScrollPos))

        for i in range(len(rows2display)):
            if rows2display[i][0] == 0: # Heading
                b.screen.draw_text(0, 25+20*i, rows2display[i][1])
                b.screen.draw_line(0, 38+20*i, b.screen.width-11, 38+20*i)

            else: # Mode / command / extra
                if i+menuScrollPos == menuOptionNrSelected:
                    b.screen.draw_box(10, 22+20*i, b.screen.width-11, 40+20*i, 5, fill=True)
                    b.screen.draw_text(15, 25+20*i, rows2display[i][1], Color.WHITE)
                else:
                    b.screen.draw_box(10, 22+20*i, b.screen.width-11, 40+20*i, 5)
                    b.screen.draw_text(15, 25+20*i, rows2display[i][1])

    # except Exception as e:
    #     print("Exception occured during rendering:")
    #     print(e)
    #     print()


import os

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen

from libs.navigationdrawer import NavigationDrawer
from kivymd.theming import ThemeManager

from features import BookList, MainScreenManagement, BookScreenManagement
from config import KV_DIR
from ui import StartScreen, SearchBookScreen, AddBookScreen, SearchAuthorScreen, SearchTopicScreen, AboutScreen

class Navigator(NavigationDrawer):
    title = StringProperty('Navigation')

class BookStoreApp(App, MainScreenManagement, BookList, BookScreenManagement):
    theme_cls = ThemeManager()
    nav_drawer = ObjectProperty()

    def build(self):
        self.load_all_view_files(KV_DIR)

        self.main_screen = StartScreen()
        self.nav_drawer = Navigator()

        self.main_screen_manager = self.main_screen.ids.main_manager

        # setting up menu links

        self.screens = [SearchBookScreen(name="search_book"),
                        AddBookScreen(name="add_book"),
                        SearchAuthorScreen(name="search_author"),
                        SearchTopicScreen(name="search_topic"),
                        AboutScreen(name="about")]

        btn = Button(text="suka")
        # self.screens[0].add_widget(btn)
        self.main_screen_manager.add_widget(self.screens[0])
        self.main_screen_manager.add_widget(self.screens[1])
        self.main_screen_manager.add_widget(self.screens[2])
        self.main_screen_manager.add_widget(self.screens[3])
        self.main_screen_manager.add_widget(self.screens[4])
        # self.book_screen_manager = self.root.ids.book_manager
        # self.book_screen_manager = self.main_screen.ids.book_manager

        return self.main_screen

    def load_all_view_files(self, directory_kv_files):
        for kv_file in os.listdir(directory_kv_files):
            kv_file = os.path.join(directory_kv_files, kv_file)
            if os.path.isfile(kv_file):
                with open(kv_file) as kv:
                    Builder.load_string(kv.read())

    def add_screens(self, name_screen, screen_manager, new_screen):
        screen = Screen(name=name_screen)
        screen.add_widget(new_screen)
        screen_manager.add_widget(screen)
        screen_manager.current = name_screen

    # Navigation menu links
    def show_about(self, *args):
        self.root.ids.main_manager.current = "about"
        return True

    def show_search_book(self, *args):
        self.root.ids.main_manager.current = "search_book"
        return True

    def show_add_book(self, *args):
        self.root.ids.main_manager.current = "add_book"
        return True

    def show_search_author(self, *args):
        self.root.ids.main_manager.current = "search_author"
        return True

    def show_search_topic(self, *args):
        self.root.ids.main_manager.current = "search_topic"
        return True

BookStoreApp().run()


import copy
import socket
from jsonschema import validate, FormatChecker, ValidationError
from abc import ABCMeta, abstractmethod
import re
import six

__tp__ = 'transport_params'

@six.add_metaclass(ABCMeta)
class AbstractDevice:
    def __init__(self, logger):
        self.staged = {}
        self.active = {}
        self.callback = None
        self.stageLocked = False
        self.logger = logger
        self.staged['master_enable'] = False
        self.staged['receiver_id'] = None
        self.staged['sender_id'] = None

    def lock(self):
        """Prevents any updates to staged parameters"""
        self.stageLocked = True

    def unLock(self):
        """Allows updates to staged parameters"""
        self.stageLocked = False

    def setActivateCallback(self, callback):
        self.callback = callback

    def activateStaged(self):
        oldParams = copy.deepcopy(self.active)
        self.active = copy.deepcopy(self.resolveParameters(self.staged))
        self.unLock()
        if self.callback is not None:
            try:
                self.logger.writeDebug("Activation suceeded")
                self.callback()
            except Exception as e:
                self.logger.writeWarning("Activation failed, reverting to old params. {}".format(e))
                self.active = copy.deepcopy(oldParams)
                raise

    def setMasterEnable(self, masterEnable):
        if self.stageLocked:
            raise StagedLockedException()
        self.staged['master_enable'] = masterEnable

    def setSenderId(self, senderId):
        if self.stageLocked:
            raise StagedLockedException()
        if senderId is None:
            self.staged['sender_id'] = None
        else:
            pattern = "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
            if re.match(pattern, senderId):
                self.staged['sender_id'] = senderId
            else:
                raise ValidationError("Invalid sender id")

    def setReceiverId(self, receiverId):
        if self.stageLocked:
            raise StagedLockedException()
        if receiverId is None:
            self.staged['receiver_id'] = None
        else:
            pattern = "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
            if re.match(pattern, receiverId):
                self.staged['receiver_id'] = receiverId
            else:
                raise ValidationError("Invalid sender id")

    def patch(self, updateObject):
        """Update based on a patch object"""
        for leg in range(0, self.legs):
            if not self.stageLocked:
                toCheck = []
                toCheck.append(updateObject[leg])
                schema = self.getParamsSchema(leg)
                checker = FormatChecker(["ipv4", "ipv6"])
                validate(updateObject, schema, format_checker=checker)
                self._updateTransportParamerters(updateObject, self.staged)
                return True
            else:
                raise StagedLockedException()

    def stagedToJson(self):
        return self._assembleJsonDescription(self.staged)

    def activeToJson(self):
        return self._assembleJsonDescription(self.active)

    def setStagedParameter(self, value, parameter, leg=0):
        """Set the value of a staged parameter"""
        if parameter in self.staged[__tp__][leg]:
            self.staged[__tp__][leg][parameter] = value
        else:
            raise ValueError

    def getStagedParameter(self, parameter, leg=0):
        """Get the value of a staged parameter"""
        return self.staged[__tp__][leg][parameter]

    def setActiveParameter(self, value, parameter, leg=0):
        """Set the value of an active parameter"""
        if parameter in self.active[__tp__][leg]:
            self.active[__tp__][leg][parameter] = value
        else:
            raise ValueError

    def getActiveParameter(self, parameter, leg=0):
        """Get the value of an active parameter"""
        return self.active[__tp__][leg][parameter]

    def _updateTransportParamerters(self, updateObject, dest):
        """Merge in transport parameters"""
        leg = 0
        for tp in updateObject:
            for key, value in tp.items():
                if key in dest[__tp__][leg]:
                    dest[__tp__][leg][key] = updateObject[leg][key]
            leg += 1

    def _checkIsIpv4(self, addr):
        """Checks a given address is ipv4"""
        try:
            # Check if it's IPv4
            socket.inet_pton(socket.AF_INET, addr)
            return True
        except AttributeError:
            # Looks like we can't use pton here...
            try:
                socket.inet_aton(addr)
            except socket.error:
                return False
        except socket.error:
            return False
        return True

    def _checkIsIpv6(self, addr):
        """Checks a given address is ipv6. Not win friendly. Sorry..."""
        try:
            socket.inet_pton(socket.AF_INET6, addr)
        except socket.error:
            return False
        except AttributeError:
            """If you're finding this program returning here your system does
            not support inet_pton (is probably running windows). In Python 2.7
            about the only way round this is to use a bunch of regex..."""
            return False
        return True

    @abstractmethod
    def getConstraints(self):
        pass

    @abstractmethod
    def getParamsSchema(self):
        pass

    @abstractmethod
    def getTransportType(self):
        pass

class StagedLockedException(Exception):
    pass


# 爬取中国大学排名
import bs4
import requests
from bs4 import BeautifulSoup

def getHTML(url):
    try:
        r=requests.get(url)
        r.raise_for_status()
        r.enconing=r.apparent_enconing
        return r.text
    except:
        return""

def getInfo(list,html):
    soup=BeautifulSoup(html,"html.parser")
    for tr in soup.find('tbody').children:
        tds=soup.find_all('td')
        list.append(u[0],u[1],u[8])

def printinfo(list,num):
    print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分"))
    for i in range(num):
        u=list[i]
        print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2]))

def main():
    uinfo=[]
    url="http://www.gaokaopai.com/paihang-otype-2.html?f=1&ly=bd&city=&cate=&batch_type="
    html=getHTML(url)
    getInfo(uinfo,html)
    printinfo(uinfo,20)


#! /usr/bin/env python
#
#  Show graph structure in the "truth" space
#

import random
from matplotlib import pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cm

#gray = plt.get_cmap("gray")
gray_r = plt.get_cmap("gray_r")
seismic = plt.get_cmap("seismic")  #"rainbow" "jet" "bwr" "coolwarm" "seismic")

random.seed(12345678)

def rnoise(rn, N):
    return [ 1.0 + 2.0 * rn * (random.random() - 0.5) for i in range(N) ]

def show_efuns(ax, ef1, ef2, W, D):
    N, M = W.shape
    assert N == M and D.shape == (N, N)
    assert len(ef1) == N and len(ef2) == N
    D1 = [ D[i,i] for i in range(N) ]
    ax.scatter(ef1, ef2, c=D1, s=200)
    Wnorm = colors.Normalize(vmin=0.0, vmax=W.max())
    Wcolor = cm.ScalarMappable(norm=Wnorm, cmap=jet).to_rgba
    for i in range(N):
        for j in range(i+1, N):
            if W[i,j] > 0.0:
                c = W[i,j]
                xs = [ ef1[i], ef1[j] ]
                ys = [ ef2[i], ef2[j] ]
                ax.plot(xs, ys, lw=1.4, c=Wcolor(c))

def show_on_truth(ax, ef1, truth, W, rn=None):
    N, M = W.shape
    assert N == M and truth.shape == (N, 2)
    assert len(ef1) == N
    if rn:
        truth_ = [ (x*r, y*r) for (x,y), r in zip(truth, rnoise(rn, N)) ]
    else:
        truth_ = truth
    truthx, truthy = zip(*truth_)
    ##ef1 = truthx  #=truthy - a hack!
    transf = (lambda v: v)  #(lambda v: v**3)
    ef1cran = max(abs(min(ef1)), abs(max(ef1)))
    ef1cran = transf(ef1cran)
    ef1norm = colors.Normalize(vmin=-ef1cran, vmax=ef1cran)
    ef1color = (lambda v: cm.ScalarMappable(norm=ef1norm, cmap=seismic).to_rgba(transf(v)))
    ef1c = map(ef1color, ef1)
    ax.scatter(truthx, truthy, c=ef1c, s=200)
    Wnorm = colors.Normalize(vmin=0.0, vmax=W.max())
    Wcolor = cm.ScalarMappable(norm=Wnorm, cmap=gray_r).to_rgba
    for i in range(N):
        for j in range(i+1, N):
            if W[i,j] > 0.0:
                c = W[i,j]
                xs, ys = zip(truth_[i], truth_[j])
                ax.plot(xs, ys, lw=1.4, c=Wcolor(c))

if __name__ == "__main__":
    import sys, argparse, os
    import os.path as path
    import numpy as np

    parser = argparse.ArgumentParser()
    parser.add_argument("--sanity", action="store_true",
                        help="run some sanity checks on eigenvalues and eigenfunctions")
    parser.add_argument("--truth", action="store_true",
                        help="one eigenfunction on top of truth")
    parser.add_argument("--rnoise", type=float, default=None,
                        help="add some radial noise for plotting")
    parser.add_argument("dir",
                        help="data/exp dir")
    parser.add_argument("f1", type=int,
                        help="first eigenfunction")
    parser.add_argument("f2", type=int, nargs="?", default=None,
                        help="second eigenfunction")
    args = parser.parse_args()

    exp_dir = args.dir
    data_dir, exp_subdir = path.split(exp_dir)

    truth = np.loadtxt(path.join(data_dir, "truth"))
    efuns = np.loadtxt(path.join(exp_dir, "efuns"))
    evals = np.loadtxt(path.join(exp_dir, "evals"))
    W = np.loadtxt(path.join(exp_dir, "W"))
    D = np.loadtxt(path.join(exp_dir, "D"))

    if not args.truth:
        show_efuns(plt, efuns[args.f1], efuns[args.f2], W, D)
        plt.gray()
    else:
        fig, ax = plt.subplots(1, 1)
        show_on_truth(ax, efuns[args.f1], truth, W, rn=args.rnoise)
        ax.set_axis_bgcolor("lightgreen")
    plt.show()


COLUMN_LENGTH = 6
ROW_LENGTH = 7
COLS = [0, 1, 2, 3, 4, 5, 6]
ROWS = [0, 1, 2, 3, 4, 5]
MAX = COLUMN_LENGTH * ROW_LENGTH

SEQ = 4  # desired sequence length.

UP = (0, 1)
RIGHT = (1, 0)
UPRIGHT = (1, 1)
DOWNRIGHT = (1, -1)

class Game:
    """
    four in a row logic, follows API.
    additional methods: clean board, end game.
    """

    def __init__(self):
        """
        initializes game.
        """
        self.game_on = True  # a flag for turning the game on and off.
        self.__column_length = COLUMN_LENGTH
        self.__row_length = ROW_LENGTH
        self.__cols = COLS
        self.clean_board()

    def get_data(self, data):
        """
        a get function.
        """
        if data == "column_length":
            return self.__column_length
        elif data == "row_length":
            return self.__row_length
        elif data == "cols":
            return self.__cols
        elif data == "last_move":
            return  self.__last_move

    def clean_board(self):
        """
        cleans board, or creates it if non existent.
        """
        board = []
        for row in range(COLUMN_LENGTH):
            board.append([0] * ROW_LENGTH)
        self.__board = board
        self.__player1_coins = []
        self.__player2_coins = []
        self.__moves = 0

    def end_game(self, winner):
        """
        ends a single game. game_on can be restarted from outside.
        """
        if winner is None:
            return
        self.game_on = False
        self.clean_board()

    def make_move(self, column):
        """
        adds a move to the board and to the relevant player list.
        if move is illegal, raises exception.
        :param column: int in range of row length.
        """
        if column not in COLS or not self.game_on:
            raise Exception("Illegal move.")

        for row in range(COLUMN_LENGTH)[::-1]:
            if self.__board[row][column] == 0:
                player = self.get_current_player()
                self.__board[row][column] = player
                self.__add_move_to_list(row, column)
                self.__moves += 1
                self.__last_move = (row, column, player)
                return True
        raise Exception("Illegal move.")  # column is full.

    def __add_move_to_list(self, row, col):
        """
        keeps track of each player's coins, for get winner functionality.
        """
        if self.get_current_player() == 1:
            self.__player1_coins.append([row, col])
        else:
            self.__player2_coins.append([row, col])

    def __check_seq(self, player, coin, coin_list, length, step):
        """
        a recursive helper for get winner.
        :param step: direction.
        :param length: length left for sequence.
        :param coin: current coin in sequence.
        """
        if length == 1:  # base case.
            coin_list = coin_list + [coin]
            self.winner_coins = coin_list  # saves winning coins for the screen
            return True

        # else, if a sequence is found, continues in same direction:
        if [coin[0] + step[0], coin[1] + step[1]] in player[0]:
            return self.__check_seq(player,
                                    (coin[0] + step[0], coin[1] + step[1]),
                                    coin_list + [coin], length - 1, step)
        return False

    def get_winner(self):
        """
        checks for winner in the game, using players coin lists.
        :return: winner if found, 0 if game ended without a winner,
        None if game has not ended. (and therefore also functions as should_end
        flag)
        """
        for coin_list in [(self.__player1_coins, 1), (self.__player2_coins, 2)]:
            for coin in coin_list[0]:
                if self.__check_seq(coin_list, coin, [], SEQ, UP) or\
                        self.__check_seq(coin_list, coin, [], SEQ, UPRIGHT) or\
                        self.__check_seq( coin_list, coin, [], SEQ, RIGHT) or\
                        self.__check_seq(coin_list, coin, [], SEQ, DOWNRIGHT):
                    return coin_list[1]  # returns player
        if self.__moves == MAX:
            return 0

    def get_player_at(self, row, col):
        """
        returns player at a cell, 0 if cell is empty.
        raises exception if illegal cell is received.
        """
        if row not in ROWS or col not in COLS:
            raise Exception("Illegal location.")
        if self.__board[row][col] == 1:
            return 1
        elif self.__board[row][col] == 2:
            return 2

    def get_current_player(self):
        """
        :return: current player at the game.
        """
        if self.__moves % 2 == 0:
            return 1
        else:
            return 2


def get_temp(temp,frm,to):
    '''
    Transforma un tip de grade in alt tip de grade
    :param x: Numarul de grade
    :param t1: Tipul in care sunt gradele
    :param t2: Tipul in care trebuie sa se transforme gradele
    :return: Returneaza numarul de grade in tipul dat, t2
    '''
    if frm=="C":
        if to=="K":
            return temp+273.15
        else:
            return (temp*1.8)+32
    elif frm=="F":
        if to=="C":
            return (temp-32)*(5/9)
        else:
            return (temp-32)*(5/9)+273.15
    else:
        if to=="C":
            return temp-273.15
        else:
            return temp*(9/5)-459.67

def cmmdc(x,y):
    d = x
    i = y
    while i > 0:
        r = d % i
        d = i
        i = r
    return d

def get_cmmmc(list):
    '''
    Calculeaza cmmmc a n numere
    :param list: Lista cu numere intregi
    :return: Returneaza cmmmc
    '''
    d=0
    c=1
    for i in list:
        c = c*i//cmmdc(c,i)

    return c

def numarprim(x):
    if x<2:
        return False
    else:
        for i in range(2,x//2+1):
            if x%i==0:
                return False

    return True

def get_largest_prime_below(n):
    c=int(n)
    c=c-1
    while numarprim(c)==False:
        c=c-1

    return c

def test_get_largest_prime_below():
    assert get_largest_prime_below("4")==3
    assert get_largest_prime_below("16")==13
    assert get_largest_prime_below("23")==19
    assert get_largest_prime_below("26")==23
    assert get_largest_prime_below("145")==139

def test_get_temp():
    assert get_temp(20,"C","K") == 293.15
    assert get_temp(20, "C", "F") == 68
    assert get_temp(300, "F", "C") == 148.88888888888889
    assert get_temp(300, "K", "F") == 80.32999999999998

def test_get_cmmmc():
    assert  get_cmmmc(list=[1,2,3,4,5]) == 60
    assert get_cmmmc(list=[2,3,4]) == 12
    assert get_cmmmc(list=[12,24,2]) == 24
    assert get_cmmmc(list=[15,5,20]) ==  60

def citire():
    list = []
    n = int(input("Dati nr. de elemente: "))
    for i in range(n):
        list.append(int(input("Dati elemente: ")))

    return list

def main():

    while True:

        print(test_get_cmmmc())
        print(test_get_temp())
        print(test_get_largest_prime_below())

        print("1.Determina numarul de grade dintr-un tip dat in alt tip dat.")
        print("2.Determina cmmmc a n numere.")
        print("3.Determina ultimul număr prim mai mic decât un număr dat")
        print("x.Iesire")

        list = []
        optiune = input("Dati optiune: ")

        if optiune=="1":
            temp=float(input("Dati numarul de grade: "))
            frm=input("Dati tipul gradelor: ")
            to=input("Dati tipul in care doriti sa se transforme gradele: ")
            print(get_temp(temp,frm,to))
        elif optiune=="2":
            list=citire()
            print(get_cmmmc(list))
        elif optiune=="3":
            t=int(input("Dati numar: "))
            print(get_largest_prime_below(t))
        elif optiune=="x":
            break
        else:
            print("Optiune gresita! Rincearca")

if __name__ == '__main__':
    main()


import sys
input = sys.stdin.readline

n,k = map(int,input().split())

a_list = [0]*(n+1)

count = 0
flag = 0
for i in range(2,n+1):

    for j in range(2, n+1):

        if j % i == 0 and a_list[j] == 0:
            count += 1
            a_list[j] = 1

            if count == k:
                flag = j
                break
    if flag:
        break

print(flag)

백준/Silver/2960. 에라토스테네스의 체/에라토스테네스의 체.py

에라토스테네스의 체.py


from time import time
import requests
import json
from flask_mail import Mail, Message
# from app import send_emails

def email_control(mail):
    # #Retrieve start time in time.json
    # filename = "time.json"
    # with open(filename, 'r') as f:
    #     data = json.load(f)
    #     #if first time, set start time to now
    #     print(f"DATA: {data}")
    #     if data["start"] == -1:
    #         data["start"] = time()
    #         start = time()
    #     else: #if not first time, retrieve start time
    #         start = data["start"] + time()

    # timeElapsed = int(start - time()) #turn into int
    # print(f"TIME ELAPSED IN EMAIL CONTROL: {timeElapsed}")
    # if timeElapsed > 10_000_000_000:
    #     #reset time elapsed to 0
    #     data["start"] = 0
    #     #Update email_list.json based on AQI and asthma/age/etc
    #     updateEmailList()

    #     #Email everyone on the email list

    # #Update time.json (if not needed it just rewrites what was there before)
    # with open(filename, 'w') as f:
    #     data = json.dump(data, f)
    updateEmailList()
    send_emails(mail)

#Update email_list.json based on thresholds for each user in users.json
def updateEmailList():
    #Open email_list.json
    email_file = "email_list.json"
    with open(email_file, 'r') as efile:
        email_users = json.load(efile)
        #Retrieve users from users.json
        filename = "users.json"
        with open(filename, 'r') as ufile:
            data = json.load(ufile)

        print("BEFORE FOR LOOP IN UPDATE EMAIL LIST")
        for user in data:
            info = data[user]
            print(f"USER: {info}")
            if info["threshold"] == 0 and user in email_users["users"]:
                email_users["users"].remove(user)
            elif info["threshold"] == 1 and user not in email_users["users"]:
                email_users["users"].append(user)

    #update email list
    with open(email_file, 'w') as efile:
        json.dump(email_users, efile)

def send_emails(mail):
    efile = "email_list.json"
    userfile = "users.json"
    with open(efile, 'r') as f1:
        email_data = json.load(f1)
    with open(userfile, 'r') as f:
        userinfo = json.load(f)
        while len(email_data["users"]) > 0:
            user = email_data["users"].pop()
            print(f"USEEEEER: {user}")
            msg = f"Hello {user}, this is a warning that the AQI is {userinfo[user]['AQI']} which is above your threshold"
            message = Message(msg, sender = 'climathon2023@gmail.com', recipients = [user])
            message.body = msg

            mail.send(message)
            #send message to arduino
            sensor_index = userinfo[user]['closest sensor']
            aqi_value = userinfo[user]['AQI']
            color = "green"
            user_thresh = userinfo[user]['threshold']
            response = requests.get("https://script.google.com/macros/s/AKfycbxoUijwJgmVLw9hRk0gmyLqhoY6-WeT5-dgSkSsnAwlWG8355ONiU5XLgG-BxmW1exA/exec?request=set&sensor_index=" + str(sensor_index) + "&aqi=" + str(aqi_value) + "&color=" + color + "&user_thresh=" + str(user_thresh))

    with open(efile, 'w') as f2:
        # empty = {"users" : []}
        json.dump(email_data, f2)

    # updateinfo(email_data)

# def updateinfo(email_data):
#     with open("email_list.json", 'w') as f:
#         json.dump(email_data, f)


import heapq
import os
import os.path
import sys
from node import Node

class AStar:
    def __init__(self):
        # self.maze = self.read_maze(filepath=sys.argv[1])
        self.maze = self.read_maze(filepath='maze.txt')
        self.w, self.h = len(self.maze[0]), len(self.maze)
        self.nodes, self.mat = self.dist_matrix()

    def read_maze(self, **kwargs):

        if 'filepath' in kwargs.keys():
            file = open(kwargs['filepath'], 'r')
            lines = file.readlines()
            maze = []

            for i, line in enumerate(lines):
                if i == 0:
                    words = line.split(' ')
                else:
                    nds = list(line.strip())
                    maze.append(nds)
            return maze
        elif 'maze' in kwargs.keys():
            return kwargs['maze']

    def __str__(self):
        return self.maze.__str__()

    def find_path(self, s, t):
        # s, t = self.find_s_t()

        if s[0] == t[0] and s[1] == t[1]:
            return 0

        s = Node(s[0], s[1])
        t = Node(t[0], t[1])
        # print('s: ' + str(s))
        # print('t: ' + str(t))
        closed = set()
        open = []
        heapq.heappush(open, s)
        while len(open) != 0:
            n = heapq.heappop(open)
            # print(n)
            closed.add(n)

            # neighbors = [Node(x,y,node_type, g, f) for all x, y that are valid]
            neighbors = [Node(_x, _y, n.g+1, n.g+1+self.get_h(_x, _y, t))
                         for (_x, _y) in [(n.x-1, n.y), (n.x+1, n.y), (n.x, n.y-1), (n.x, n.y+1)]
                         if self.maze[_x][_y] is not '#'
                         ]

            for neighbor in neighbors:
                if neighbor == t:  # found the shortest path
                    return neighbor.g

                if neighbor not in closed:
                    if neighbor not in open:
                        heapq.heappush(open, neighbor)
                    else:  # check if update g and father as n
                        index = open.index(neighbor)
                        if open[index].g > neighbor.g:  # need update the f,g fro the node
                            open[index] = neighbor
                            heapq.heapify(open)
        return -1

    def get_h(self, x, y, t):
        '''
        get the length from (x,y) to destination |x1-x2| + |y1-y2|
        :param p:
        :param dest:
        :return:
        '''

        return abs(x-t.x) + abs(y-t.y)

    def find_all_nodes(self):
        for line in self.maze:
            print(line)
        s = []
        t = []
        at = []
        for i, r in enumerate(self.maze):
            for j, ch in enumerate(r):
                if ch == 'S':
                    s.append((i, j))

                elif ch == 'G':
                    t.append((i, j))
                elif ch == '@':
                    at.append((i, j))
        return s, t, at

    def dist_matrix(self):
        s, t, at = self.find_all_nodes()
        nodes = s + at + t
        mat = []
        for i in range(len(nodes)):
            dists = []
            for j in range(i): # 0i, 1i, 2i... i-1)i
                dist = self.find_path(nodes[j], nodes[i])
                if dist == -1:
                    return -1, -1
                dists.append(dist)
                mat[j].append(dist)
            dists.append(0)
            mat.append(dists)
        return nodes, mat

if __name__ == '__main__':
    a = AStar()
    for line in a.maze:
        print(line)
    # print(a.find_path())
    nodes, mat = a.dist_matrix()

    # n1 = Node(1,1, '@', 1, 10)
    # n2 = Node(1,1, '@', 3, 18)
    # print(n1>n2)


# Ajayrama Kumaraswamy, 07 Oct 2014
# Usage: "python splitVCard.py contacts.vcf" where "contacts.vcf" contains multiple contacts.
# A folder (in the case named contacts) will be created and the contacts will be stored inside the directory in files
# named 1.vcf, 2.vcf.., one contact being stored per file.

import os
from shutil import rmtree

class vcf(object):
    """
    Class to handle a vcard string
    """

    def __init__(self):

        self.vcfStr = []
        self.name = []
        self.valid = True
        self.uk = 1

    def write(self, fName):
        """
        writes the vcard into fName
        """

        if self.name == '':
            self.name = 'Unknown' + str(self.uk)
            self.uk += 1
        with open(os.path.join(fName), 'w') as out:
            for field in self.vcfStr:
                out.write(field)

    def addLine(self, stri):

        if self.valid:

            if stri[-2:] == '\r\n':
                stri = stri[:-2] + '\n'

            self.vcfStr.append(stri)

if __name__ == '__main__':

    import sys

    assert len(sys.argv) == 2, 'this script takes only one commandline argument'

    fleName = sys.argv[1]

    dirName = fleName[:-4]

    if os.path.isdir(dirName):
        rmtree(dirName)
    os.mkdir(dirName)

    fle = open(fleName, 'r')

    presLine = fle.readline()

    count = 1

    while presLine != '':

        if presLine[:11] == 'BEGIN:VCARD':

            presVCF = vcf()

        presVCF.addLine(presLine)

        if presLine[:9] == 'END:VCARD':

            presVCF.write(os.path.join(dirName, str(count) + '.vcf'))
            count += 1
            presVCF.valid = False

        if presLine[:2] == 'FN':

            if presLine[-2:] == '\r\n':
                presLine = presLine[:-2]
            presVCF.name = presLine[3:]

        presLine = fle.readline()