from math import pi as PI
import numpy as np
import matplotlib.pyplot as plt

# module
from src.liftmodel.power_balance import PowerBalance
from src.spring_diagram import plotSpring

#---- Constants -----

N_NAME = 22
N_NUM  = 15
N_UNIT = 5
NCHAR  = N_NAME + N_NUM + N_UNIT

FORMAT_SUBTITLE = ('{:<' + '%d' + '}') % NCHAR
FORMAT_TITLE    = ('{:^' + '%d' + '}') % NCHAR
FORMAT_ROW      = ('{:' + '%d' + '}{:' + '%d' + '}{:' + '%d' + '}') % (N_NAME, N_NUM, N_UNIT)

UNIT_OUTPUT = {'FLIGHT': ['W', 'W', 'W', 'W', '%', '%', 'm', 'm', 'hz'\
                         ,'m/s', 'N.m', 'N.m', 'N', 'N', 'deg']       \
              ,'MOTOR' : ['ohm', '%', '%', '%', 'W', 'W', 'A', '%']   \
              ,'CLIMB' : ['m/s', 'deg']                               \
              ,'SPRING': ['N/m', 'N', 'm', 'deg'] }

UNIT_INPUT = {'FLIGHT': ['%', 'deg', 'deg', 'm/s^2', 'kg', 'kg', 'kg/m^3', 'm^2'] \
             ,'MOTOR' : ['V', 'A', 'A', 'rpm/V']                                  \
             ,'SPRING': ['m', 'm', 'm'] }

#---- functions ------

def labelInputs(n_step,   chord_ratio, twist_glide, twist_up, twist_down                               \
               ,ld_ratio, amplitude,   dihedral,    gravity,  mass_total, mass_wing, air_density, area \
               ,voltage,  i_stall,     i_noload,    motor_kv                             			   \
               ,xoffset,  yoffset,     rspring):
    # create dict
	input = {}
	input['WING'] = {                        \
         	 'n_step'          : n_step      \
	    	,'chord_ratio'     : chord_ratio \
	    	,'twist_glide'     : twist_glide \
	    	,'twist_upstroke'  : twist_up    \
	    	,'twist_downstroke': twist_down  }

	input['FLIGHT'] = {
	     	 'lift_drag_ratio' : ld_ratio    \
	    	,'amplitude'       : amplitude   \
	    	,'dihedral'        : dihedral    \
	    	,'gravity'         : gravity     \
	    	,'mass_total'      : mass_total  \
	    	,'mass_wing'       : mass_wing   \
	    	,'air_density'     : air_density \
	    	,'area'            : area        }

	input['MOTOR'] = {                       \
	     	 'voltage'         : voltage     \
	    	,'current_stall'   : i_stall     \
	    	,'current_noload'  : i_noload    \
	    	,'motor_kv'        : motor_kv    }

	input['SPRING'] = {                      \
	     	 'xoffset'         : xoffset     \
	    	,'yoffset'         : yoffset     \
	    	,'radius_spring'   : rspring     }
	return input

def aircraftCalculations(wing, flight, motor, spring):
	model = PowerBalance(              \
	          wing['n_step']           \
            , wing['chord_ratio']      \
            , wing['twist_glide']      \
            , wing['twist_upstroke']   \
            , wing['twist_downstroke'] \
            , flight['lift_drag_ratio']\
            , flight['amplitude']      \
            , flight['dihedral']       )

	data = model.solveDesign(         \
	          spring['xoffset']       \
	        , spring['yoffset']       \
	        , spring['radius_spring'] \
	        , flight['gravity']       \
	        , flight['mass_total']    \
	        , flight['mass_wing']     \
	        , flight['air_density']   \
	        , flight['area']          \
	        , motor['voltage']        \
	        , motor['current_stall']  \
	        , motor['motor_kv']       \
	        , motor['current_noload'] )

	output = {'FLIGHT'      : data[0] \
	         ,'MOTOR'       : data[1] \
	         ,'CLIMB'       : data[2] \
	         ,'SPRING'      : data[3] \
	         ,'DISTRIBUTION': data[4] }
	return output

def formatNumber(val):
	if abs(val) < 1e-2:
		return format(val, ".3e")
	else:
		return format(val, ".3f")

def printTable(sub_title, data, units):
	# format
	key = list( data.keys() )
	val = list( data.values() )
	val = np.vectorize(formatNumber)(val)
	data = np.transpose( [key, val, units] )
	# display
	print(FORMAT_SUBTITLE.format(sub_title))
	print('-' * NCHAR)
	for row in data:
		print(FORMAT_ROW.format(*row))

def printData(title, data, unit):
	# header
	print('=' * NCHAR)
	print(FORMAT_TITLE.format(title))
	print('=' * NCHAR)
	# tables
	for key in unit.keys():
		printTable( key, data[key], unit[key] )
		print()

def plotLift(x, aglide, aup, adown, glide, up, down):
	fig, axis1 = plt.subplots()
	# lift
	axis1.plot(x, up   , color='blue' , label='lift upstroke')
	axis1.plot(x, down , color='red'  , label='lift downstroke')
	axis1.plot(x, glide, color='black', label='lift glide')
	# alpha
	axis2 = axis1.twinx()
	axis2.plot(x, np.degrees(aup)   , color='blue' , alpha=0.6, lw=2 , linestyle='dotted')
	axis2.plot(x, np.degrees(adown) , color='red'  , alpha=0.6, lw=2 , linestyle='dotted')
	axis2.plot(x, np.degrees(aglide), color='black', alpha=0.6, lw=2 , linestyle='dotted')
	# labels
	fig.set_tight_layout(True)
		# axis 1
	axis1.legend(loc='lower center')
	axis1.set_title("lift distribution")
	axis1.set_ylabel("lift per span (N/m)")
	axis1.set_xlabel("spanwise position (m)")
	axis1.spines['top'].set_visible(False)
	axis1.ticklabel_format(useMathText=True, scilimits=(-2,2))
	axis1.minorticks_on()
		# axis 2
	axis2.set_ylabel("angle of attack (deg)")
	axis2.spines['top'].set_visible(False)
	axis2.minorticks_on()

def plotWingGeometry(x, chord, tglide, tup, tdown):
	fig, axis = plt.subplots(2,1, sharex=True)
	# chord
	y1 = chord * 1/4
	y2 = chord * -3/4
	axis[1].fill_between(x, y1, y2, color='gray', alpha=0.1)
	axis[1].plot(x, y1, color='black', lw=1, label='LE')
	axis[1].plot(x, y2, color='gray' , lw=1, label='TE')
		# center lines
	imid = round(len(x) * 0.5)
	axis[1].vlines(0, y2[imid], y1[imid], color='gray', linestyle='dashed', lw=0.5)
	axis[1].hlines(0, x[0]    , x[-1]   , color='gray', linestyle='dashed', lw=0.5)
	# twist
	axis[0].plot(x, np.degrees(tglide), color='black', label='glide')
	axis[0].plot(x, np.degrees(tup)   , color='blue' , label='upstroke')
	axis[0].plot(x, np.degrees(tdown) , color='red'  , label='downstroke')
	# labels
	fig.set_tight_layout(True)
		# axis 1
	cmax = max(chord)
	axis[1].set_ylim( -cmax, 0.5*cmax )
	axis[1].set_aspect('equal')
	axis[1].set_ylabel("chord (m)")
	axis[1].set_xlabel("spanwise position (m)")
	axis[1].spines['top'].set_visible(False)
	axis[1].spines['right'].set_visible(False)
	axis[1].ticklabel_format(useMathText=True, scilimits=(-2,2), axis='y')
	axis[1].minorticks_on()
		# axis 2
	axis[0].legend(loc='lower center')
	axis[0].set_ylabel("twist angle (deg)")
	axis[0].spines['top'].set_visible(False)
	axis[0].spines['right'].set_visible(False)
	axis[0].ticklabel_format(useMathText=True, scilimits=(-2,2))
	axis[0].set_title("wing geometry")
	axis[0].minorticks_on()

def inputToRadian(input):
	input['FLIGHT']['dihedral']  = np.radians( input['FLIGHT']['dihedral'] )
	input['FLIGHT']['amplitude'] = np.radians( input['FLIGHT']['amplitude'] )
	# convert functions
	fg = input['WING']['twist_glide']
	fu = input['WING']['twist_upstroke']
	fd = input['WING']['twist_downstroke']
	input['WING']['twist_glide']      = lambda x: np.radians( fg(x) )
	input['WING']['twist_upstroke']   = lambda x: np.radians( fu(x) )
	input['WING']['twist_downstroke'] = lambda x: np.radians( fd(x) )
	return input

def outputToDegree(input, output):
	input['FLIGHT']['dihedral']  = np.degrees( input['FLIGHT']['dihedral'] )
	input['FLIGHT']['amplitude'] = np.degrees( input['FLIGHT']['amplitude'] )
	output['FLIGHT']['pitch_trim_angle'] = np.degrees( output['FLIGHT']['pitch_trim_angle'] )
	output['CLIMB']['climb_angle']       = np.degrees( output['CLIMB']['climb_angle'] )
	output['SPRING']['spring_angle']     = np.degrees( output['SPRING']['spring_angle'] )
	return input, output

def formatData(input):		# convert inputs and outputs to degrees
	input = labelInputs(*input)
	input = inputToRadian(input)
	output = aircraftCalculations( *input.values() )
	dist = output['DISTRIBUTION']
	# plots
	plotWingGeometry( dist['y_axis']   \
          	, dist['chord']            \
          	, dist['twist_glide']      \
          	, dist['twist_upstroke']   \
          	, dist['twist_downstroke'] )

	plotLift( dist['y_axis']          \
          	, dist['alpha_glide']     \
          	, dist['alpha_upstroke']  \
          	, dist['alpha_downstroke']\
          	, dist['lift_glide']      \
          	, dist['lift_upstroke']   \
          	, dist['lift_downstroke'] )
	plotSpring( *input['SPRING'].values()           \
              , input['FLIGHT']['dihedral']         \
              , input['FLIGHT']['amplitude']        \
              , output['SPRING']['spring_constant'] )
	# tables
	input, output = outputToDegree(input, output)
	printData("INPUTS", input, UNIT_INPUT)
	printData("OUTPUTS", output, UNIT_OUTPUT)
	plt.show()


import tweepy
from web3 import Web3
import time
import json

# Set up web3
web3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR-PROJECT-ID'))

# Set up Twitter API
auth = tweepy.OAuthHandler('CONSUMER_KEY', 'CONSUMER_SECRET')
auth.set_access_token('ACCESS_TOKEN', 'ACCESS_TOKEN_SECRET')
api = tweepy.API(auth)

# Load contract ABI from file
with open('abi.json', 'r') as f:
    abi = json.load(f)

# Define contract and event
contract_address = '0xCONTRACT_ADDRESS'
contract = web3.eth.contract(address=contract_address, abi=abi)
mint_event = contract.events.Mint()

# Define function to check for mint events
def check_for_mints():
    block_number = web3.eth.block_number
    past_events = mint_event.getLogs(fromBlock=block_number-10000, toBlock=block_number)
    for event in past_events:
        to_address = event['args']['to']
        tweet = f'{to_address} got sent some gudVibes!'
        api.update_status(tweet)

# Set up Twitter bot to run every 5 minutes
while True:
    check_for_mints()
    time.sleep(300)


# import cv2
# import numpy as np
# fotograma = cv2.imread("testimage2.png")
# # captura = cv2.VideoCapture(0)

# while(True):
#     # disponible, fotograma = captura.read()
#     height,width,channels = fotograma.shape
#     # if disponible == True:
#     if True:
#         # cv2.rectangle(fotograma,(0,0),(height,width),(0,255,0),20)
#         # r = cv2.selectROI(im)

#         cut = fotograma[0:500,0:500]
#         hsv = cv2.cvtColor (cut, cv2.COLOR_BGR2HSV)
#         h, s, v = cv2.split (hsv)
#         mean1 = h.mean()
#         mean2 = s.mean()
#         mean3 = v.mean()
#         stdevm1 = np.std(h)
#         print("h " + str(mean1) + " - stdev: " + str(stdevm1))
#         print("s" + str(mean2))
#         print("v " + str(mean3))
#         cv2.imshow("Segmentado",cut)
#         cv2.imshow("Segmentado3",fotograma)
#     ch = 0xFF & cv2.waitKey(1)
#     if ch == ord('q'):
#         break

# cv2.destroyAllWindows()
import cv2
import numpy as np
class CalibrationClass:

    @staticmethod
    def Calibrate(ROI):
        hsv = cv2.cvtColor (ROI, cv2.COLOR_BGR2HSV)
        h, s, v = cv2.split (hsv)
        HueMean = h.mean()
        SatMean = s.mean()
        ValMean = v.mean()
        HueSTD = np.std(h)
        SatSTD = np.std(s)
        ValSTD = np.std(v)

        HueMIN = (HueMean-HueSTD*3) % 179
        SatMIN = np.clip(SatMean-SatSTD*5,0,255)
        ValMIN = np.clip(ValMean-ValSTD*5,0,255)
        HueMAX = (HueMean+HueSTD*3) % 179
        SatMAX = np.clip(SatMean+SatSTD*5,0,255)
        ValMAX = np.clip(ValMean+ValSTD*5,0,255)

        return np.array((HueMIN,SatMIN,ValMIN)),np.array((HueMAX,SatMAX,ValMAX))


import numpy as np
import pickle
import cv2
import math
from matplotlib import pyplot as pl
import os
from phinalIR_cluster_wik import Variables
from phinalFL_cluster import Fluorescence_Analyzer
from astropy.convolution import Gaussian1DKernel, interpolate_replace_nans, convolve
import seaborn as sb
import pandas as pd
import itertools

# TODO
# for the top video in fluor, have to threshold the mask video. it's catching the mask as a contour.

# also still seeing fluorescence in the IR record. shouldn't see a white frame.
# get the exact phinalIR and FL files on the cluster working on your computer.
# make sure you get the exact results you need, even wrt eye convergence.

def tsplot(data, ax, **kw):
    x = np.arange(data.shape[1])
    est = np.mean(data, axis=0)
    sd = np.std(data, axis=0)
    cis = (est - sd, est + sd)
    ax.fill_between(x, cis[0], cis[1], alpha=0.2, **kw)
    ax.plot(x, est, **kw)
    ax.margins(x=0)

def ts_plot(list_of_lists, ax):
    fig, ax = pl.subplots(1, 1)
    index_list = list(
        itertools.chain.from_iterable(
            [range(len(arr)) for arr in list_of_lists]))
    id_list = [(ind*np.ones(len(arr))).tolist() for ind, arr in enumerate(list_of_lists)]
    ids_concatenated = list(itertools.chain.from_iterable(id_list))
    #this works if passed np.arrays instead of lists
    value_list = list(itertools.chain.from_iterable(list_of_lists))
    df_dict = {'x': index_list,
               'y': value_list}
    df = pd.DataFrame(df_dict)
    sb.lineplot(data=df, x='x', y='y', ax=ax)
    pl.show()
    return df

def fluor_wrapper(drct_lists_by_condition):

    def fill_condition_list(drct_list):
        fl_gutvals = []
        fl_gutintensity = []
        fl_gutarea = []
        fl_lowres = []
        gkern = Gaussian1DKernel(1)
        fluor_directory = '/Users/nightcrawler2/FluorData/'
        for drct in drct_list:
            fish_fl = pickle.load(open(fluor_directory + drct +
                                       '/fluordata.pkl', 'rb'))
            fl_gutvals.append(fish_fl.gut_values)
            g_int = [np.mean([g1, g2]) for g1, g2 in zip(
                fish_fl.gutintensity_xy,
                fish_fl.gutintensity_xz)]
            fl_gutintensity.append(g_int)
            g_area = [np.mean([g1, g2]) for g1, g2 in zip(
                fish_fl.gutarea_xy,
                fish_fl.gutarea_xz)]
            fl_gutarea.append(g_area)
            g_lowres = [np.mean([g1, g2]) for g1, g2 in zip(
                fish_fl.lowres_gut_xy,
                fish_fl.lowres_gut_xz)]
            fl_lowres.append(g_lowres)
        filt_gutvals = [convolve(flgv, gkern,
                                 preserve_nan=False) for flgv in fl_gutvals]
        filt_gutintensity = [convolve(fl_int, gkern,
                                      preserve_nan=False)
                             for fl_int in fl_gutintensity]
        filt_gutarea = [convolve(fla, gkern,
                                 preserve_nan=False) for fla in fl_gutarea]
        filt_lowres = [convolve(lr, gkern,
                                preserve_nan=False) for lr in fl_lowres]
        return [filt_gutvals, filt_gutintensity,
                filt_gutarea, filt_lowres]

    fl_by_condition_dictlist = []
    # fl_condition_list will contain lists with 4 elements each
    # each of the four elements is a fl readout (gutval, avg, lowres, size)
    # each element contains x lists of that value, where x is the
    # number of fish (i.e. directories) for that condition
    # you want an axis for each of these for a tsplot
    for drct_list in drct_lists_by_condition:
        gutvals, gutintensity, gutarea, lowres_gut = fill_condition_list(drct_list)
        fl_by_condition_dictlist.append({"Gut Values": gutvals,
                                         "Gut Intensity": gutintensity,
                                         "Gut Area": gutarea,
                                         "Lowres GutVals": lowres_gut})

    fig, axes = pl.subplots(2, 2, figsize=(10, 6))

    # here want to do a new ts plot on each axes for each
    # condition. tsplot wants a list of arrays of the same length of the same condition.

    for fl_instance in fl_by_condition_dictlist:
        ts_plot(np.array(fl_instance["Gut Values"]), axes[0, 0])
        ts_plot(np.array(fl_instance["Gut Intensity"]), axes[1, 0])
        ts_plot(np.array(fl_instance["Gut Area"]), axes[0, 1])
        ts_plot(np.array(fl_instance["Lowres GutVals"]), axes[1, 1])
    pl.show()
    return fl_by_condition_dictlist

fl_conditions = fluor_wrapper([['1_2', '2_2'], ['1_2', '1_2']])


import feedparser

def get_new_feeds():

    urls = []  # these urls are what the html_scraper actually scrapes
    article_list = []
    file1 = open("feeds_to_read.txt")
    feeds = file1.readlines()

    for feed in feeds:
        #feed parser logic
        d = feedparser.parse(feed)
        i = 1
        for link in feed:
            while i < 10:
                try:
                    url = d.entries[i].link
                    urls.append(url)
                    i+=1
                except(IndexError):
                    continue
        save_to_file(urls)
    return urls

def save_to_file(urls):
    with open('urls_to_read.txt', 'w') as filehandle:
        for url in urls:
            filehandle.write('%s\n' % url)

get_new_feeds()


#DFS 방법 정의 (재귀함수)
def dfs(graph, v, visited, answer):
    visited[v] = True  # 현재 노드를 방문 처리
    print(v, end=' ')
    answer.append(v)
    for i in graph[v]:
        if not visited[i]:
            dfs(graph, i, visited, answer)

from collections import deque
def bfs(graph, start, visited):
    queue = deque([start])
    visited[start] = True
    while queue:
        v = queue.popleft()
        print(v, end = ' ')
        for i in graph[v]:
            if not visited[i]:
                queue.append(i)
                visited[i] = True

graph = [
    [],
    [2,3,8],
    [1,7],
    [1,4,5],
    [3,5],
    [3,4],
    [7],
    [2,6,8],
    [1,7]]
visited = [False]*9 #각 노드가 방문된 정보 리스트 생성
#bfs(graph, 1, visited)
answer =[]
dfs(graph, 1, visited, answer)

이것이코딩테스트다/05. DFS, BFS/dfs_bfs sample.py


# -*- mode: python -*-

block_cipher = None

a = Analysis(['EXCP_Main.py'],
             pathex=['G:\\Excel-Com\\Excel_comp'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
a.datas +=[("Res/Logo.jpg","G:/Excel-Com/Excel_comp/Res/Logo.jpg","DATA")]
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='EXCP_Main',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=False )


import pytest
import torch
import segmentation_models_pytorch as smp

encoder_names = [
    'resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152',
    'resnext50_32x4d', 'resnext101_32x4d', 'resnext101_32x8d',
    'resnext101_32x16d', 'resnext101_32x32d', 'resnext101_32x48d', 'dpn68',
    'dpn68b', 'dpn92', 'dpn98', 'dpn107', 'dpn131', 'vgg11', 'vgg11_bn',
    'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn', 'vgg19', 'vgg19_bn', 'senet154',
    'se_resnet50', 'se_resnet101', 'se_resnet152', 'se_resnext50_32x4d',
    'se_resnext101_32x4d', 'densenet121', 'densenet169', 'densenet201',
    'densenet161', 'inceptionresnetv2', 'inceptionv4', 'efficientnet-b0',
    'efficientnet-b1', 'efficientnet-b2', 'efficientnet-b3', 'efficientnet-b4',
    'efficientnet-b5', 'efficientnet-b6', 'efficientnet-b7', 'mobilenet_v2',
    'xception'
]
arch_names = [
    'Unet', 'UnetPlusPlus', 'MAnet', 'Linknet', 'FPN', 'PSPNet', 'DeepLabV3',
    'DeepLabV3Plus', 'PAN', 'TriNet'
]

@pytest.mark.parametrize("encoder_name", encoder_names)
@pytest.mark.parametrize("arch_name", arch_names)
def test_model(encoder_name, arch_name):
    sample = torch.rand(2, 1, 384, 288)
    model = smp.__dict__[arch_name](
        encoder_name=encoder_name,
        encoder_weights=None,
        in_channels=1,
        classes=12,
        activation=None,
        encoder_attention_type='scse',
    )
    y = model(sample, sample,
              sample) if arch_name == 'TriNet' else model(sample)
    assert y.shape == (2, 12, 384, 288)


import pandas as pd
import numpy as np
import pickle
import seaborn as sns
import matplotlib.pyplot as plt

file_train = pd.read_csv('train.csv', error_bad_lines=False)

file_train = file_train[file_train["total_vaccinations"].notna()]
vac_india = file_train[file_train["country"].str.contains("India")]
# file_train["country"].unique()

dates = vac_india['date'].apply(lambda x: np.array(x))
total = vac_india['total_vaccinations'].apply(lambda x: np.array(x))
plt.figure(1)
India = sns.lineplot(x=dates, y=total)

plt.yticks(
    India.get_yticks(),
    India.get_yticks() * 1
)
plt.xticks(
    rotation=90,
    horizontalalignment='right',
    fontweight='light',
    fontsize='8'
)

plt.show()

people = vac_india['daily_vaccinations_raw'].apply(lambda x: np.array(x))
plt.figure(2)
raw_india = sns.lineplot(x=dates, y=people)
plt.xticks(
    rotation=90
)

plt.show()

file_train = file_train[file_train["total_vaccinations"].notna()]
vac_uk = file_train[file_train["country"].str.contains("United Kingdom")]
dates = vac_uk['date'].apply(lambda x: np.array(x))
total = vac_uk['total_vaccinations'].apply(lambda x: np.array(x))
plt.figure(3)
UK = sns.lineplot(x=dates, y=total)
plt.yticks(

    UK.get_yticks(),
    UK.get_yticks() * 1
)
plt.xticks(
    rotation=90,
    horizontalalignment='right',
    fontweight='light',
    fontsize='7',

)

people = vac_uk['daily_vaccinations_raw'].apply(lambda x: np.array(x))
plt.figure(4)
raw_uk = sns.lineplot(x=dates, y=people)
plt.xticks(
    rotation=90
)

file_train = file_train[file_train["total_vaccinations"].notna()]
vac_us = file_train[file_train["country"].str.contains("United States")]
dates = vac_us['date'].apply(lambda x: np.array(x))
total = vac_us['total_vaccinations'].apply(lambda x: np.array(x))
plt.figure(5)
US = sns.lineplot(x=dates, y=total, data='details')
plt.yticks(

    US.get_yticks(),
    US.get_yticks() * 1
)

plt.xticks(
    rotation=90,
    horizontalalignment='right',
    fontweight='light',
    fontsize='7',

)

people = vac_us['daily_vaccinations_raw'].apply(lambda x: np.array(x)).notna()
plt.figure(6)
raw_us = sns.lineplot(x=dates, y=people)
plt.yticks(
    raw_us.get_yticks(),
    raw_us.get_yticks() * 100000,
    fontsize='10',
)
plt.xticks(
    rotation=90
)

file_train = file_train[file_train["total_vaccinations"].notna()]
vac_italy = file_train[file_train["country"].str.contains("Italy")]
dates = vac_italy['date'].apply(lambda x: np.array(x))
total = vac_italy['total_vaccinations'].apply(lambda x: np.array(x))
plt.figure(7)
italy = sns.lineplot(x=dates, y=total, data='details')
plt.yticks(

    italy.get_yticks(),
    italy.get_yticks() * 1
)
plt.xticks(
    rotation=90,
    horizontalalignment='right',
    fontweight='light',
    fontsize='7',

)

people = vac_italy['daily_vaccinations_raw'].apply(lambda x: np.array(x)).notna()
plt.figure(8)
raw_ita = sns.lineplot(x=dates, y=people)
plt.yticks(
    raw_ita.get_yticks(),
    raw_ita.get_yticks() * 100000,
    fontsize='10',
)
plt.xticks(
    rotation=90
)

file_train = file_train[file_train["total_vaccinations"].notna()]
vac_spain = file_train[file_train["country"].str.contains("Spain")]
dates = vac_spain['date'].apply(lambda x: np.array(x))
total = vac_spain['total_vaccinations'].apply(lambda x: np.array(x))
plt.figure(9)
spain = sns.lineplot(x=dates, y=total, data='details')
plt.yticks(

    spain.get_yticks(),
    spain.get_yticks() * 1
)
plt.xticks(
    rotation=90,
    horizontalalignment='right',
    fontweight='light',
    fontsize='7',

)

people = vac_spain['daily_vaccinations_raw'].apply(lambda x: np.array(x)).notna()
plt.figure(10)
raw_spa = sns.lineplot(x=dates, y=people)
plt.yticks(
    raw_spa.get_yticks(),
    raw_spa.get_yticks() * 100000,
    fontsize='10',
)
plt.xticks(
    rotation=90
)

file_train = file_train[file_train["total_vaccinations"].notna()]
vac_tur = file_train[file_train["country"].str.contains("Turkey")]
dates = vac_tur['date'].apply(lambda x: np.array(x))
total = vac_tur['total_vaccinations'].apply(lambda x: np.array(x))
plt.figure(11)
turkey = sns.lineplot(x=dates, y=total, data='details')
plt.yticks(

    turkey.get_yticks(),
    turkey.get_yticks() * 1
)
plt.xticks(
    rotation=90,
    fontsize='10',

)

people = vac_tur['daily_vaccinations_raw'].apply(lambda x: np.array(x))
plt.figure(12)
raw_tur = sns.lineplot(x=dates, y=people)
plt.xticks(
    rotation=90
)

file_train = file_train[file_train["total_vaccinations"].notna()]
vac_sri = file_train[file_train["country"].str.contains("Sri Lanka")]
dates = vac_sri['date'].apply(lambda x: np.array(x))
total = vac_sri['total_vaccinations'].apply(lambda x: np.array(x))
plt.figure(13)
srilanka = sns.lineplot(x=dates, y=total)
plt.yticks(

    srilanka.get_yticks(),
    srilanka.get_yticks() * 1
)
plt.xticks(
    rotation=90,
    horizontalalignment='right',
    fontweight='light',
    fontsize='7',

)

people = vac_sri['daily_vaccinations_raw'].apply(lambda x: np.array(x))
plt.figure(14)
raw_sri = sns.lineplot(x=dates, y=people)

plt.xticks(
    rotation=90
)

# sum of vaccines used

# #file_train['vaccines'].unique()
file_train["vaccines"].apply(lambda x: np.array(x))
sum_pfizer = file_train['vaccines'].str.contains("Pfizer/BioNTech").sum()
sum_moderna = file_train['vaccines'].str.contains("Moderna").sum()
sum_oxford = file_train['vaccines'].str.contains("Oxford/AstraZeneca").sum()
sum_cnbg = file_train['vaccines'].str.contains("CNBG").sum()
sum_covaxin = file_train['vaccines'].str.contains("Covaxin").sum()
sum_sinopharm = file_train['vaccines'].str.contains("Sinopharm").sum()
sum_sinovac = file_train['vaccines'].str.contains("Sinovac").sum()
sum_sputnik = file_train['vaccines'].str.contains("Sputnik V").sum()

# function for making the piechart

def piechart():
    vaccines = ['Pfizer', 'Moderna', 'Oxford/AstraZeneca', 'CNBG', 'Covaxin', 'Sinopharm', 'Sinovac', 'Sputnik V']
    data = [sum_pfizer, sum_moderna, sum_oxford, sum_cnbg, sum_covaxin, sum_sinopharm, sum_sinovac, sum_sputnik]
    fig = plt.figure(figsize=(8, 8))
    plt.pie(data, labels=vaccines, rotatelabels=90)
    piechart = plt.show()
    return piechart
piechart()

# bar graph for country vaccination rate
sum = vac_india["total_vaccinations"].sum()
length = len(vac_india.index)
avg_ind = sum / length

vac_belgium = file_train[file_train["country"].str.contains("Belgium")]
sum = vac_belgium["total_vaccinations"].sum()
length = len(vac_belgium.index)
avg_bel = sum / length

vac_brazil = file_train[file_train["country"].str.contains("Brazil")]
sum = vac_brazil["total_vaccinations"].sum()
length = len(vac_brazil.index)
avg_braz = sum / length

vac_canada = file_train[file_train["country"].str.contains("Canada")]
sum = vac_canada["total_vaccinations"].sum()
length = len(vac_canada.index)
avg_can = sum / length

vac_italy = file_train[file_train["country"].str.contains("Italy")]
sum = vac_italy["total_vaccinations"].sum()
length = len(vac_canada.index)
avg_ita = sum / length

# vac_plot = pd.DataFrame(
#                 {"Average " : [avg_ind , avg_bel , avg_braz , avg_can , avg_ita]} ,
#                 index = ['India' , 'Belgium' , 'Brazil' , 'Canada' , 'Italy' ]
#         )
Average  =  [avg_ind , avg_bel , avg_braz , avg_can , avg_ita]
index = ['India' , 'Belgium' , 'Brazil' , 'Canada' , 'Italy' ]

plt.bar(index , Average )
plt.xlabel('countries', color = 'orange', fontsize='13', horizontalalignment='center')
plt.ylabel('Average vaccination rate', color = 'orange', fontsize='13', horizontalalignment='center')
plt.ylim(0,2000000)
plt.title("  y-axis scale : 0.25 = 500,000 vaccinations per day")
plt.show()
# vac_plot.plot(kind = "bar" )

#creating model for deployment

filename = 'finalmodel.sav'

pickle.dump(India, filename)
pickle.dump(raw_india, filename)
pickle.dump(US, filename)
pickle.dump(raw_us, filename)
pickle.dump(UK, filename)
pickle.dump(raw_uk, filename)
pickle.dump(italy, filename)
pickle.dump(raw_ita, filename)
pickle.dump(spain, filename)
pickle.dump(raw_spa, filename)
pickle.dump(turkey, filename)
pickle.dump(raw_tur, filename)
pickle.dump(srilanka, filename)
pickle.dump(raw_sri, filename)
pickle.dump(avg , filename)


from itertools import combinations_with_replacement

def solution(n, info):
    info.reverse()

    data = combinations_with_replacement([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], n)

    diff = 0
    result = []

    for combi in data:
        apeech = 0
        lion = 0

        tmp = [0] * 11
        for i in range(11):
            tmp[i] = combi.count(i)

        for i in range(11):
            if not (tmp[i] == 0 and info[i] == 0):
                if tmp[i] > info[i]:
                    lion += i
                else:
                    apeech += i

        if lion - apeech > diff:
            diff = lion - apeech
            result = tmp

    if diff == 0:
        return [-1]
    else:
        result.reverse()
        return result

print(solution(5, [2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]))


import numpy as np
import os

def ReadFile(file_name):
    l = []
    with open(file_name) as f:
        for line in f:
            str_num = line.strip().split()
            num = [eval(s) for s in str_num]
            l.append(num)
    print('{0} points have been read...'.format(l.__len__()))
    return np.array(l)

def CountDistance(points):
    p_num, p_dim = points.shape
    dis = np.zeros((p_num, p_num))
    for i in range(p_num):
        for j in range(i, p_num):
            rel_vec = points[i] - points[j]
            dis_ij = np.linalg.norm(rel_vec,ord=2)
            dis[i][j] = dis[j][i] = dis_ij
    print('counted distance...')
    return dis

def CountDensity(dis, dc):  # the density of every points
    assert dc > 0
    p_num, _ = dis.shape
    density = []
    for vec in dis:
        small_than_dc_pos = [vec < dc]
        density.append(np.sum(small_than_dc_pos))
    return np.array(density).astype(float)

def Count_delta(dis, density):
    delta = []
    neighbor = []  # the nearest neighbor that has large density than it
    p_num, _ = dis.shape
    assert len(density) == p_num
    max_density = np.max(density)
    for i in range(p_num):
        if density[i] == max_density:
            delta.append(np.max(dis[i]))
            neighbor.append(-1)
        else:
            min_j = 0
            tmp_delta = np.max(dis[i])
            for j, val in enumerate(dis[i]):
                if density[j] > density[i] and tmp_delta > val:
                    tmp_delta = val
                    min_j = j
            delta.append(tmp_delta)
            neighbor.append(min_j)

            # pos = [density > density[i]]  # for Pi ,find all positions Pj larger than Pi
            # all_dij = dis[i]
            # candi_dij = all_dij[pos]
            # dij = np.min(candi_dij)
            # delta.append(dij)
            # for ind, val in enumerate(dis[i]):
            #     if val == dij:
            #         neighbor.append(ind)
            #         break

    assert len(neighbor) == p_num
    return np.array(delta), np.array(neighbor)

def SearchDc(dis, tau=0.02):
    sides = []
    p_num, _ = dis.shape
    for i in range(p_num - 1):
        for j in range(i + 1, p_num):
            sides.append(dis[i][j])
    assert sides.__len__() == p_num * (p_num - 1) / 2
    sides.sort()
    pos = round(len(sides) * tau)
    return sides[pos - 1]

def CDFofNormalDistribution(x):
    p0 = 220.2068679123761
    p1 = 221.2135961699311
    p2 = 112.0792914978709
    p3 = 33.91286607838300
    p4 = 6.373962203531650
    p5 = .7003830644436881
    p6 = .03326249659989109
    q0 = 440.4137358247552
    q1 = 793.8265125199484
    q2 = 637.3336333788311
    q3 = 296.5642487796737
    q4 = 86.78073220294608
    q5 = 16.06417757920695
    q6 = 1.755667163182642
    q7 = 0.08838834764831844
    cutoff = 7.071
    root2pi = 2.506628274631001
    xabs = np.abs(x)
    res = 0
    if x > 37.0:
        res = 1.0
    elif x < -37.0:
        res = 0.0
    else:
        expntl = np.exp(-.5 * xabs * xabs)
        pdf = expntl / root2pi
        if (xabs < cutoff):
            res = expntl * ((((((p6 * xabs + p5) * xabs + p4) * xabs + p3) * xabs + p2) * xabs + p1) * xabs + p0) / ((((
                                                                                (
                                                                                (
                                                                                (
                                                                                q7 * xabs + q6) * xabs + q5) * xabs + q4) * xabs + q3) * xabs + q2) * xabs + q1) * xabs + q0)
        else:
            res = pdf / (xabs + 1.0 / (xabs + 2.0 / (xabs + 3.0 / (xabs + 4.0 / (xabs + 0.65)))))

    if x > 0:
        res = 1 - res
    return res

def numberOfClusters(gamma, threshold):
    sort_gamma = np.sort(gamma)
    mean = np.mean(sort_gamma)
    var = np.var(sort_gamma)
    std = np.sqrt(var)
    nClusters=0
    for i in range(len(gamma) - 1, 0, -1):
        tmp = (sort_gamma[i] - mean) / std
        prob = CDFofNormalDistribution(tmp)
        if i > len(gamma) - 100:
            pass
            # print(prob)
        if prob < threshold or 1 - prob < threshold:
            continue
        nClusters = len(gamma) - 1 - i
        break
    return nClusters

def getnCluster(density, delta, threshold):
    #normalized

    def zScoreNormailzation(x):
        x=(x-np.mean(x))/np.std(x)
        return x

    def Normailzation(x):
        x=(x-np.min(x))/(np.max(x)-np.min(x))
        return x

    den,dell=density.copy(),delta.copy()
    den=Normailzation(den)
    dell=Normailzation(dell)
    gamma=den*dell

    # print(gamma[83],gamma[229])

    #
    # den_min, den_max = np.min(density), np.max(density)
    # delta_min, delta_max = np.min(delta), np.max(delta)
    # den_range = den_max - den_min
    # delta_range = delta_max - delta_min
    # gamma = []
    # for i in range(len(density)):
    #     tmp = (density[i] - den_min) * (delta[i] - delta_min) / (den_range * delta_range)
    #     gamma.append(tmp)
    # gamma = np.array(gamma)
    ncluster = numberOfClusters(gamma=gamma, threshold=threshold)

    vec = []
    # find the K th max numbers

    # for test
    # ncluster=15
    print(ncluster)
    THE_MIN=np.min(gamma)-1
    for _ in range(ncluster):
        max_ind = np.argmax(gamma)
        gamma[max_ind] = THE_MIN
        vec.append(max_ind)

    return ncluster, vec

def assignCluster(neighbor, nvec_index, ord,density):
    p_num = len(neighbor)
    point_class = np.zeros(p_num)
    class_num = 1
    for index in nvec_index:  # give class to core
        point_class[index] = class_num
        class_num += 1
    # assign class to other point
    for index in ord:
        if point_class[index] == 0:  # haven't assign class
            point_class[index] = point_class[neighbor[index]]
            if 0== point_class[neighbor[index]]:
                print(density[index],density[neighbor[index]])
                break

    tmp=np.sort(point_class)
    return point_class.astype(int)

def sortByDensity(density):
    p_num = len(density)
    density = density.tolist()
    l = [i for i in range(p_num)]
    tmp_tuple = [(a, b) for a, b in zip(density, l)]
    sorted_tuple = sorted(tmp_tuple, key=lambda x: -x[0])
    ord = [j for i, j in sorted_tuple]
    return ord

if __name__ == '__main__':
    file_name = input("Please enter file name: ").strip() + '.txt'
    points = ReadFile(os.path.join('data', file_name))
    dis = CountDistance(points[:, ])
    tau=0.015
    dc = SearchDc(dis, tau=tau)
    density = CountDensity(dis, dc)
    ord = sortByDensity(density)
    delta, neighbor = Count_delta(dis, density)

    _, nvec_index = getnCluster(density, delta, threshold=0.05)

    #plus 1% to the max gamma point,and repeat once!
    # max_pos=nvec_index[0]
    # density[max_pos]=density[max_pos]*1.001
    for i in nvec_index:
        pre=density[i]
        density[i]=density[i]*1.001

    ord = sortByDensity(density)
    delta, neighbor = Count_delta(dis, density)
    ncluster, nvec_index = getnCluster(density, delta, threshold=0.05)

    point_class = assignCluster(neighbor=neighbor, nvec_index=nvec_index, ord=ord,density=density)

    # print(ncluster)

    from showResult import DrawDistribute, drawPoint,showAcc

    showAcc(points,point_class)

    # drawPoint(points, point_class=point_class,filename=file_name,dc=tau)
    # DrawDistribute(rho=density, delta=delta)


# -*- coding: utf-8 -*-
"""
Create by: abibeka
Purpose: Read WMATA schedule data; Schedule_082719-201718.mdb
"""
# https://stackoverflow.com/questions/39835770/read-data-from-pyodbc-to-pandas
import pandas as pd, os, inflection, numpy as np

mdb_to_excel_file_loc = r'C:\Users\abibeka\OneDrive - Kittelson & Associates,' \
                        r' Inc\Documents\WMATA-AVL\Data\wmata_schedule_data'
stop_file = os.path.join(mdb_to_excel_file_loc, 'Stop.xlsx')
stop_dat = pd.read_excel(stop_file)
stop_dat = stop_dat.dropna(axis=1)
stop_dat.columns = [inflection.underscore(col_nm) for col_nm in stop_dat.columns]

pattern_file = os.path.join(mdb_to_excel_file_loc, 'Pattern.xlsx')
pattern_dat = pd.read_excel(pattern_file)
pattern_dat = pattern_dat[['PatternID','TARoute','PatternName','Direction',
                           'Distance','CDRoute','CDVariation','PatternDestination',
                           'RouteText','RouteKey','PatternDestination2','RouteText2',
                           'Direction2','PatternName2','TARoute2','PubRouteDir','PatternNotes',
                           'DirectionID']]
#pattern_dat = pattern_dat.dropna(axis=1)
pattern_dat.columns = [inflection.underscore(col_nm) for col_nm in pattern_dat.columns]
pattern_dat.rename(columns={'distance':'trip_length'},inplace=True)

pattern_detail_file = os.path.join(mdb_to_excel_file_loc, 'PatternDetail.xlsx')
pattern_detail_dat = pd.read_excel(pattern_detail_file)
pattern_detail_dat = pattern_detail_dat.dropna(axis=1)
pattern_detail_dat = pattern_detail_dat.drop(columns=['SortOrder', 'GeoPathID'])
pattern_detail_dat.columns = [inflection.underscore(col_nm) for col_nm in pattern_detail_dat.columns]
pattern_detail_dat.rename(columns={'distance':'stop_dist'},inplace=True)

q_jump_route_list = ['S1', 'S2', 'S4', 'S9', '70', '79', '64', 'G8', 'D32', 'H1', 'H2', 'H3', 'H4', 'H8', 'W47']
pattern_q_jump_route_dat = pattern_dat.query('cd_route in @q_jump_route_list')
set(pattern_q_jump_route_dat.cd_route.unique()) - set(q_jump_route_list)

pattern_pattern_detail_stop_q_jump_route_dat = \
    pattern_q_jump_route_dat.merge(pattern_detail_dat,on='pattern_id',how='left')\
    .merge(stop_dat,on='geo_id',how='left')

pattern_pattern_detail_stop_q_jump_route_dat.\
    sort_values(by=['cd_route','cd_variation','order'],inplace=True)

mask_nan_latlong = pattern_pattern_detail_stop_q_jump_route_dat[['latitude', 'longitude']].isna().all(axis=1)
assert_stop_sort_order_zero_has_nan_latlong = \
    sum(pattern_pattern_detail_stop_q_jump_route_dat[mask_nan_latlong].stop_sort_order-0)
assert(assert_stop_sort_order_zero_has_nan_latlong==0)

no_nan_pattern_pattern_detail_stop_q_jump_route_dat =\
    pattern_pattern_detail_stop_q_jump_route_dat[~mask_nan_latlong]

no_nan_pattern_pattern_detail_stop_q_jump_route_dat = \
    no_nan_pattern_pattern_detail_stop_q_jump_route_dat.dropna(axis=1)

assert(0== sum(~ no_nan_pattern_pattern_detail_stop_q_jump_route_dat.
               eval('''direction==pub_route_dir& cd_route==ta_route''')))
no_nan_pattern_pattern_detail_stop_q_jump_route_dat.drop(columns=['pub_route_dir','ta_route'],inplace=True)

assert(0== np.sum(no_nan_pattern_pattern_detail_stop_q_jump_route_dat.isna().values))

save_file_path = r'C:\Users\abibeka\OneDrive - Kittelson & Associates, Inc\Documents\Github\WMATA_AVL\data\02-processed'
save_file = os.path.join(save_file_path,'wmata_schedule_data_q_jump_routes.csv')
no_nan_pattern_pattern_detail_stop_q_jump_route_dat.to_csv(save_file)

no_nan_pattern_pattern_detail_stop_q_jump_route_dat.iloc[0]


# -*- coding: utf-8 -*-
"""
Created on Sun Jul 26 23:57:40 2020

@author: farhad
"""
import sys
from SignalDto import SignalDto
from Utils import Utils
from time import sleep
from selenium import webdriver

class professoroff:

    def __init__(self,driver):
        self.driver= driver

    utils= Utils()

    def createSignalDto(self,msg,chName):
        print('creating signalDto for '+chName+ ' started')

        lines=str.splitlines(msg)
        signalDto= SignalDto()

        signalDto.provider = chName

        for line in lines :
            item=line.lower()

            posBuy=str.find(item,'buy')
            posSell=str.find(item,'sell')
            posTP=str.find(item,'tp')
            posSL=str.find(item,'sl')

            item= item.split(' ')

            if posBuy != -1 or posSell != -1: #GBPCHF SELL 1.1610

                signalDto.enter_type = 1 if item[1] == "buy" else 2
                signalDto.symbol = item[0]
                signalDto.enterPrice = item[2]

            elif posSL != -1 :
                signalDto.sl =item.split(' ')[1]

            elif posTP != -1 :
                if(signalDto.tp == 0):
                    signalDto.tp = item.split(' ')[1]
                elif(signalDto.tp2 == 0):
                    signalDto.tp2 = item.split(' ')[1]
                elif(signalDto.tp3 == 0):
                    signalDto.tp3 = item.split(' ')[1]

        print('creating signalDto for '+chName+ ' finished')
        return {0:signalDto}


knownmessage = list(input(""))
translator = list(input(""))
dictionary = {

}
messagetodecode = list(input(""))

for i in range(len(knownmessage)):
    dictionary[translator[i]] = knownmessage[i]
final = ""

for message in messagetodecode:
    if message in dictionary:
        final += dictionary.get(message)
    elif message not in dictionary:
        final += "."
print (final)


from flask import Flask, request, render_template
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer

from geventwebsocket.websocket import WebSocket

app = Flask(__name__)  # type:Flask

user_socket_list = []  # 连接的用户

@app.route("/ws")
def ws():
    user_socket = request.environ.get("wsgi.websocket")  # type:WebSocket
    if user_socket:
        user_socket_list.append(user_socket)
    print(len(user_socket_list), user_socket_list)
    while 1:
        msg = user_socket.receive()
        print(msg)
        for ussocket in user_socket_list:
            if user_socket == ussocket:
                continue
            try:
                ussocket.send(msg)
            except:
                continue

"""
上面这个操作方式要记住
"""

@app.route("/")
def index():
    return render_template("ws群聊.html")

if __name__ == "__main__":
    # app.run(debug=True)
    http_serv = WSGIServer(('0.0.0.0', 5000), app, handler_class=WebSocketHandler)
    http_serv.serve_forever()


# HELPFUL STATISTICS & DATA SCIECNE FUNCTIONS

#This code implements the PCA exactly as in MATLAB so as to be consistent.
#It takes in an n x d data matrix X and returns a d x d orthonormal matrix pcaX.
#Each column of pcaX contains a basis vector, sorted by decreasing variance.

def pca(X):
    covX = np.cov(X,rowvar=False)
    [Lambda,Vtranspose] = np.linalg.eig(covX)
    neworder = np.argsort(-abs(Lambda))
    pcaX = Vtranspose[:,neworder]
    pcaX = pcaX.real

    return pcaX

def reduce_data(Xtrain,Xtest,k):
    mu_train = np.mean(Xtrain, axis=0)
    print("The dimensions of mu_train are {}".format(mu_train.shape))

    # Centering Xtest
    Xtest_cent = Xtest - mu_train       # should be (rows x 4096) - (1 x 4096) --- subtracting mu_train from each row
    Xtrain_cent = Xtrain - mu_train
    print("The dimensions of centered vectors are {}".format(Xtest_cent.shape))

    # Need PCA matrices/data -- NOTE: the eigen vectors come as the rows from the PCA function (I THINK)
    pcaX = pca(Xtrain)
    print("The dimensions of pcaX are {}".format(pcaX.shape))

    # extract the first k "ROWS" (specific to my approach) of pcaX
    Vk = pcaX[0:k,:].T   # extract certain rows and transpose
    print("The dimensions of the Vk are {}".format(Vk.shape))

    # multiplication to produce the reduced matrices
    Xtrain_reduced = Xtrain_cent @ Vk
    Xtest_reduced = Xtest_cent @ Vk

    #Your code should go above this line.
    if (Xtrain_reduced.shape[0]!=Xtrain.shape[0]):
        raise Exception("The number of rows in Xtrain_reduced is not the same as the number of rows in Xtrain.")
    elif (Xtest_reduced.shape[0]!=Xtest.shape[0]):
        raise Exception("The number of rows in Xtest_reduced is not the same as the number of rows in Xtest.")
    elif (Xtrain_reduced.shape[1]!=k):
        raise Exception("The number of columns in Xtrain_reduced is not equal to k.")
    elif (Xtest_reduced.shape[1]!=k):
        raise Exception("The number of columns in Xtest_reduced is not equal to k.")

    return Xtrain_reduced, Xtest_reduced


# -*- coding: utf-8 -*-
import json
import string
from datetime import date, timedelta
from django.contrib.auth.models import User, Group
from django.core.exceptions import ValidationError
from django.db import models, IntegrityError
from django.utils.translation import gettext as _

from stationsplan.utils import random_string
from sp_app import utils

FAR_FUTURE = date(2099, 12, 31)
ONE_DAY = timedelta(days=1)

def date_to_json(date):
    return [date.year, date.month - 1, date.day]

class Company(models.Model):
    name = models.CharField(
        _("Name"),
        max_length=50,
        help_text='Name der Klinik (z.B. "Waldklinik Neustadt")',
    )
    shortname = models.CharField(
        _("Short Name"),
        max_length=10,
        help_text='Abkürzung für die Klinik (z.B. "wkns")',
    )
    region = models.ForeignKey(
        "Region",
        null=True,
        blank=True,
        related_name="companies",
        help_text=_(
            "Region that determines the legal holidays for this company"
        ),
        on_delete=models.PROTECT,
    )

    class Meta:
        verbose_name = _("Company")
        verbose_name_plural = _("Companies")

    def __str__(self):
        return self.name

class UniqueField:
    def unique_error_message(self, model_class, unique_check):
        if model_class == type(self) and len(unique_check) == 2:
            for field, field_name in self.unique_fields:
                if unique_check == (field, "company"):
                    return f'Der {field_name} "{getattr(self, field)}" ist bereits vergeben und darf nicht doppelt vorkommen.'
        return super().unique_error_message(model_class, unique_check)

class Department(models.Model):
    name = models.CharField(_("Name"), max_length=50)
    shortname = models.CharField(
        _("Short Name"), max_length=10, null=True, blank=True
    )
    company = models.ForeignKey(
        Company,
        related_name="departments",
        help_text=_("The top organizational unit"),
        on_delete=models.CASCADE,
    )

    class Meta:
        verbose_name = _("Department")
        verbose_name_plural = _("Departments")

    def __str__(self):
        if self.shortname:
            return f"{self.name} ({self.shortname})"
        return self.name

class Ward(UniqueField, models.Model):
    name = models.CharField(_("Name"), max_length=50)
    shortname = models.CharField(_("Short Name"), max_length=10)
    max = models.IntegerField(help_text=_("maximum staffing"))
    min = models.IntegerField(help_text=_("minimum staffing"))
    everyday = models.BooleanField(
        _("everyday"),
        default=False,
        help_text=_("if True, is to be planned also on free days."),
    )
    freedays = models.BooleanField(
        _("freedays"),
        default=False,
        help_text=_("if True, is to be planned only on free days."),
    )
    weekdays = models.CharField(
        _("weekdays"),
        max_length=7,
        default="",
        blank=True,
        help_text=_(
            "Days of the week when this is to be planned. "
            "(String of digits, 0  for sunday.)"
        ),
    )
    on_different_days = models.BooleanField(
        _("on_different_days"),
        default=False,
        help_text=_("This function can be planned on different days"),
    )
    callshift = models.BooleanField(
        _("callshift"),
        default=False,
        help_text=_("if True, then this function is displayed as call shift"),
    )
    on_leave = models.BooleanField(
        _("on_leave"),
        default=False,
        help_text=_("if True, then persons planned for this are on leave"),
    )
    departments = models.ManyToManyField(
        Department,
        verbose_name=_("Departments"),
        related_name="wards",
        help_text=_("Departments whose schedule contains this ward"),
    )
    company = models.ForeignKey(
        Company, related_name="wards", on_delete=models.CASCADE
    )
    position = models.IntegerField(
        default=1,
        help_text=_(
            "Ordering in the display. Should not be more than two digits."
        ),
    )
    ward_type = models.CharField(
        _("Ward type"),
        max_length=50,
        blank=True,
        default="",
        help_text=_("For sorting the CallTallies"),
    )
    approved = models.DateField(
        default=FAR_FUTURE,
        null=True,
        blank=True,
        help_text=_("The date until which the plan is approved"),
    )
    after_this = models.ManyToManyField(
        "self",
        verbose_name=_("after this"),
        symmetrical=False,
        blank=True,
        help_text=_(
            "if not empty, "
            "only these functions can be planned on the next day"
        ),
        related_name="predecessor",
    )
    not_with_this = models.ManyToManyField(
        "self",
        verbose_name=_("not with this"),
        symmetrical=False,
        blank=True,
        help_text=_("these functions can not be planned on the same day"),
        related_name="shadowing",
    )
    weight = models.IntegerField(
        default=0,
        help_text=_(
            "if this is a call shift, the weight reflects its "
            "burden on the persons doing the shift"
        ),
    )
    active = models.BooleanField(
        _("Active"),
        default=True,
        help_text=_("This function should currently be displayed"),
    )
    in_ical_feed = models.BooleanField(
        _("Part of ical feed"),
        default=False,
        help_text=_("This function should be part of the ical feed"),
    )
    unique_fields = (("name", "Name"), ("shortname", "Kurzname"))

    class Meta:
        verbose_name = _("Task")
        verbose_name_plural = _("Tasks")
        ordering = ["position", "name"]
        unique_together = [["name", "company"], ["shortname", "company"]]

    def __str__(self):
        return self.name

    def toJson(self):
        res = {
            "name": self.name,
            "shortname": self.shortname,
            "id": self.id,
            "min": self.min,
            "max": self.max,
            "everyday": self.everyday,
            "freedays": self.freedays,
            "weekdays": self.weekdays,
            "on_different_days": self.on_different_days,
            "callshift": self.callshift,
            "on_leave": self.on_leave,
            "company_id": self.company_id,
            "position": "%02d" % self.position,
            "after_this": "",
            "not_with_this": "",
            "ward_type": self.ward_type,
            "weight": self.weight,
            "active": self.active,
        }
        if self.pk:
            res["after_this"] = ",".join(
                w.shortname for w in self.after_this.all()
            )
            res["not_with_this"] = ",".join(
                w.shortname for w in self.not_with_this.all()
            )
        if self.approved < FAR_FUTURE:
            res["approved"] = date_to_json(self.approved)
        return res

    def clean(self):
        if self.shortname == "id":
            raise ValidationError(
                {"shortname": _('Wards cannot have the shortname "id".')}
            )
        if "," in self.shortname:
            raise ValidationError(
                {
                    "shortname": _(
                        "Wards cannot have a comma in their shortname."
                    )
                }
            )

class DifferentDay(models.Model):
    """A ward can be planned or not planned out of schedule"""

    day = models.DateField(_("day"), help_text=_("Day that is different"))
    ward = models.ForeignKey(
        Ward, related_name="different_days", on_delete=models.CASCADE
    )
    added = models.BooleanField(
        _("additional"), help_text=_("Planning is additional (not cancelled)")
    )

    class Meta:
        verbose_name = _("Different Day")
        verbose_name_plural = _("Different Days")

class Person(UniqueField, models.Model):
    """A person (worker) who can be planned for work"""

    POSITION_ASSISTENTEN = 1
    POSITION_OBERAERZTE = 2
    POSITION_CHEFAERZTE = 80
    POSITION_ANONYM = 4
    POSITION_EXTERNE = 5
    POSITION_CHOICES = (
        (POSITION_ASSISTENTEN, "Assistenten"),
        (POSITION_OBERAERZTE, "Oberärzte"),
        (POSITION_CHEFAERZTE, "Chefärzte"),
        (POSITION_ANONYM, "Anonym (Abteilung)"),
        (POSITION_EXTERNE, "Externe"),
    )

    name = models.CharField(_("Name"), max_length=50)
    shortname = models.CharField(_("Short Name"), max_length=10)
    start_date = models.DateField(
        _("start date"),
        default=utils.get_first_of_month,
        help_text=_("begin of job"),
    )
    end_date = models.DateField(
        _("end date"), default=FAR_FUTURE, help_text=_("end of job")
    )
    departments = models.ManyToManyField(
        Department, verbose_name=_("Departments"), related_name="persons"
    )
    company = models.ForeignKey(
        Company, related_name="persons", null=True, on_delete=models.CASCADE
    )
    functions = models.ManyToManyField(
        Ward,
        related_name="staff",
        verbose_name=_("Tasks"),
        help_text=_("Functions that he or she can  perform."),
    )
    position = models.IntegerField(
        _("position"),
        default=POSITION_ASSISTENTEN,
        choices=POSITION_CHOICES,
        help_text=_(
            "Ordering in the display. "
            "Should not be more than two digits. "
            "A number greater than 80 means Head of Department"
        ),
    )
    anonymous = models.BooleanField(
        _("Anonymous"),
        default=False,
        help_text=_(
            "if True this person represents multiple other persons, "
            "e.g. a department"
        ),
    )
    email = models.EmailField(_("Email"), null=True, blank=True)
    unique_fields = (("name", "Name"), ("shortname", "Kurzname"))

    class Meta:
        verbose_name = _("Person")
        verbose_name_plural = _("Persons")
        unique_together = [["name", "company"], ["shortname", "company"]]

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

    def toJson(self):
        return {
            "name": self.name,
            "shortname": self.shortname,
            "id": self.id,
            "start_date": date_to_json(self.start_date),
            "end_date": date_to_json(self.end_date),
            "functions": [f.shortname for f in self.functions.all()],
            "departments": [d.id for d in self.departments.all()],
            "position": "%02d" % self.position,
            "anonymous": self.anonymous,
            "external": self.position == Person.POSITION_EXTERNE,
        }

    def save(self, *args, **kwargs):
        created = not self.pk
        if created and self.position == Person.POSITION_ANONYM:
            self.anonymous = True
        super(Person, self).save(*args, **kwargs)
        # When a person leaves, their plannings should stop.
        # Plannings with an end (like vacations) are left untouched
        # in case the person changes their mind
        if self.end_date < FAR_FUTURE:
            Planning.objects.filter(
                person=self, start__gt=self.end_date, end=FAR_FUTURE
            ).delete()
            Planning.objects.filter(person=self, end=FAR_FUTURE).update(
                end=self.end_date
            )
        # every person can be on leave
        if created and not self.anonymous:
            self.functions.add(
                *list(
                    Ward.objects.filter(
                        company_id=self.company_id, on_leave=True
                    )
                )
            )

    def current(self):
        return self.end_date >= date.today()

    def inactivate_older_feeds(self, feed_id):
        feedids = list(FeedId.objects.filter(person=self, active=True))
        if len(feedids) < 2:
            return
        current_feed = next(f for f in feedids if f.uid == feed_id)
        older = []
        for f in feedids:
            if f.pk < current_feed.pk:
                f.active = False
                older.append(f)
        if older:
            FeedId.objects.bulk_update(older, ["active"])

class ChangeLogging(models.Model):
    """Logs who has made which changes.
    The change can be for one day (continued==False) or continued
    If continued==True it can have an end date (`until`)
    """

    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    ward = models.ForeignKey(Ward, on_delete=models.CASCADE)
    day = models.DateField()
    added = models.BooleanField()
    continued = models.BooleanField(
        default=True, help_text="If False the change is valid for one day."
    )
    until = models.DateField(
        null=True,
        blank=True,
        help_text="The last day the change is valid. Can be blank.",
    )
    description = models.CharField(max_length=255)
    json = models.CharField(max_length=255)
    change_time = models.DateTimeField(auto_now=True)
    version = models.IntegerField(default=0)
    current_version = 1

    class Meta:
        verbose_name = _("ChangeLogging")
        verbose_name_plural = _("ChangeLoggings")

    def toJson(self):
        data = {
            "person": self.person.shortname,
            "ward": self.ward.shortname,
            "day": self.day.strftime("%Y%m%d"),
            "action": "add" if self.added else "remove",
            "continued": self.continued,
            "pk": self.pk,
        }
        if self.until:
            data["until"] = self.until.strftime("%Y%m%d")
        return data

    def get_json_for_history(self):
        return {
            "user": self.user.get_full_name() or self.user.get_username(),
            "person": self.person.shortname,
            "ward": self.ward.shortname,
            "day": self.day,
            "added": self.added,
            "continued": self.continued,
            "until": self.until,
            "change_time": self.change_time,
        }

    def save(self, *args, **kwargs):
        self.make_description()
        self.version = self.current_version
        super(ChangeLogging, self).save(*args, **kwargs)
        # self.json contains the primary key
        self.json = json.dumps(self.toJson())
        ChangeLogging.objects.filter(pk=self.pk).update(json=self.json)

    def make_description(self):
        day = self.day.strftime("%d.%m.%Y")
        if not self.continued or (self.until and self.until == self.day):
            # am 19.11.2019
            time = f"am {day}"
        elif self.until:
            # von 19.11.2019 bis 20.11.2019
            time = f"von {day} bis {self.until.strftime('%d.%m.%Y')}"
        else:
            # ab 19.11.2019
            time = f"ab {day}"
        self.description = (
            f"{self.user.last_name or self.user.get_username()}: "
            f"{self.person.name} ist {time} "
            f'{"" if self.added else "nicht mehr "}für {self.ward.name}'
            f" eingeteilt"
        )

    def __str__(self):
        return self.description

def process_change(cl):
    """Weave the change into the existing Plannings.

    Return the json dict of the effective change to be returned to the client.
    """
    plannings = Planning.objects.filter(
        person_id=cl.person_id, ward_id=cl.ward_id
    )
    pl_data = dict(person_id=cl.person_id, ward_id=cl.ward_id)
    if cl.added:
        if cl.continued:
            end = cl.until or FAR_FUTURE
            plannings = list(
                plannings.filter(
                    end__gte=cl.day,
                    start__lte=end,
                ).order_by("start")
            )
            if len(plannings):
                # if cl.until is given and is before the end of the last
                #   overlapping planning
                # else it ends with the first planning in this period
                if cl.until:
                    last_planning = plannings[-1]
                    if cl.until < last_planning.end:
                        end = cl.until = last_planning.start - ONE_DAY
                        cl.save()
                        plannings.pop()
                else:
                    end = plannings[0].start - ONE_DAY
                if cl.day > end:  # This can happen if cl.until==None and
                    return {}  # change is in an existing planning
            pl = Planning.objects.create(start=cl.day, end=end, **pl_data)
            if cl.until and len(plannings) > 0:
                Planning.objects.filter(
                    id__in=[_pl.id for _pl in plannings]
                ).update(superseded_by=pl)
        else:  # not continued, one day
            plannings = plannings.filter(start__lte=cl.day, end__gte=cl.day)
            if len(plannings) == 0:
                Planning.objects.create(start=cl.day, end=cl.day, **pl_data)
            else:
                return {}  # change is contained in a Planning

    else:  # removed
        plannings = plannings.filter(
            start__lte=cl.until or cl.day, end__gte=cl.day
        ).order_by("start")
        if len(plannings) == 0:
            return {}
        if cl.continued:
            if cl.until:
                for pl in plannings:
                    if pl.start < cl.day:
                        if pl.end > cl.until:
                            Planning.objects.create(
                                start=cl.until + ONE_DAY, end=pl.end, **pl_data
                            )
                        pl.end = cl.day - ONE_DAY
                        pl.save()
                    elif pl.end > cl.until:
                        pl.start = cl.until + ONE_DAY
                        pl.save()
                    else:
                        pl.delete()  # cave: no undo!!
            else:
                for pl in plannings:  # should be only one planning
                    if pl.start == cl.day:
                        pl.delete()
                    else:
                        pl.end = cl.day - ONE_DAY
                        pl.save()
        else:  # not continued, one day
            for pl in plannings:
                if pl.start == pl.end:  # pl is one day
                    pl.delete()
                elif pl.start == cl.day:  # cut off first day
                    pl.start = cl.day + ONE_DAY
                    pl.save()
                else:
                    if not pl.end == cl.day:
                        Planning.objects.create(
                            start=cl.day + ONE_DAY, end=pl.end, **pl_data
                        )
                    pl.end = cl.day - ONE_DAY
                    pl.save()

    return json.loads(cl.json)

class Planning(models.Model):
    """One time period, where one person is planned for one ward.

    Plannings for the same person and ward should not overlap.
    The time period includes 'start' and 'end',
    i.e. a planning for one day has 'start' and 'end' set to the same date.
    """

    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    ward = models.ForeignKey(Ward, on_delete=models.CASCADE)
    start = models.DateField()
    end = models.DateField(default=FAR_FUTURE)
    json = models.CharField(max_length=255)
    version = models.IntegerField(default=0)
    current_version = 1
    superseded_by = models.ForeignKey(
        "self",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        related_name="supersedes",
        default=None,
        help_text=_("Later planning that supersedes this one"),
    )
    updateddate = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = _("Planning")
        verbose_name_plural = _("Plannings")

    def toJson(self):
        return {
            "person": self.person_id,
            "ward": self.ward_id,
            "start": self.start.strftime("%Y%m%d"),
            "end": self.end.strftime("%Y%m%d"),
        }

    def save(self, *args, **kwargs):
        if not self.pk:
            self.company_id = self.person.company_id
        self.json = json.dumps(self.toJson())
        self.version = self.current_version
        # the planning should not exceed the persons stay
        self.end = min(self.end, self.person.end_date)
        super(Planning, self).save(*args, **kwargs)

    def __str__(self):
        if self.end == FAR_FUTURE:
            return (
                f"{self.person.name} ist ab {self.start:%d.%m.%Y} "
                f"für {self.ward.name} geplant."
            )
        return (
            f"{self.person.name} ist von {self.start:%d.%m.%Y} bis "
            f"{self.end:%d.%m.%Y} für {self.ward.name} geplant."
        )

EMPLOYEE_PERMISSIONS = [
    ("is_company_admin", "is admin of the company"),
    ("is_dep_lead", "is leader of a department"),
    ("is_editor", "is editor for a department"),
]
EMPLOYEE_LEVEL = {
    "is_company_admin": "Admin",
    "is_dep_lead": "Abteilungsleiter/in",
    "is_editor": "Planen",
    "None": "Lesen",
}
EMPLOYEE_GROUP = {
    "is_company_admin": "Company Admin",
    "is_dep_lead": "Department admins",
    "is_editor": "Editors",
}

class Employee(models.Model):
    """Somebody who uses the plan.
    Can be anyone who works there, but also other involved personnel,
    like management etc.
    """

    user = models.OneToOneField(
        User, related_name="employee", on_delete=models.CASCADE
    )
    departments = models.ManyToManyField(
        Department, related_name="employees", verbose_name=_("Department")
    )
    company = models.ForeignKey(
        Company, related_name="employees", on_delete=models.CASCADE
    )
    _level = models.CharField("level", max_length=20, null=True)

    class Meta:
        verbose_name = _("Employee")
        verbose_name_plural = _("Employees")
        permissions = EMPLOYEE_PERMISSIONS

    def __str__(self):
        return "; ".join(
            (
                self.user.get_full_name() or self.user.get_username(),
                ", ".join([d.name for d in self.departments.all()]),
                self.company.name,
            )
        )

    def get_name(self):
        return self.user.get_full_name() or self.user.get_username()

    name = property(fget=get_name)

    def get_level(self):
        """Return level of authorization"""
        return self._level

    def set_level(self, level=None):
        """Set level of authorization

        If level is None or "None", remove all special permissions
        """
        assert level in EMPLOYEE_LEVEL or level in (None, "None")
        groups = dict((g.name, g) for g in Group.objects.all())
        self.user.groups.remove(
            *(groups[name] for name in EMPLOYEE_GROUP.values())
        )
        if level not in (None, "None"):
            # set all permissions up to the given level
            level_found = False
            for permission, docstring in EMPLOYEE_PERMISSIONS:
                if permission == level:
                    level_found = True
                if level_found:
                    self.user.groups.add(groups[EMPLOYEE_GROUP[permission]])
        # account for permission caching
        self.user = User.objects.get(id=self.user.id)
        self._level = None if level == "None" else level
        self.save()

    level = property(fget=get_level, fset=set_level)

    def name_and_level(self):
        # level = self.get_level()
        # if level is None:
        #     return self.name
        return f"{self.name} ({EMPLOYEE_LEVEL[self.level or 'None']})"

class StatusEntry(models.Model):
    """Saves some detail about the current status of the planning
    or the program

    Currently is only for setting the approved date of wards
    """

    name = models.CharField(max_length=30)
    content = models.CharField(max_length=255)
    department = models.ForeignKey(
        Department,
        related_name="status_entries",
        null=True,
        blank=True,
        help_text=_("Can be empty"),
        on_delete=models.SET_NULL,
    )
    company = models.ForeignKey(
        Company,
        related_name="status_entries",
        null=True,
        blank=True,
        help_text=_("Can be empty"),
        on_delete=models.SET_NULL,
    )
    timestamp = models.DateTimeField(null=True, auto_now_add=True)

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

class CalculatedHoliday(models.Model):
    """A Holiday with calculated dates

    If mode is 'abs', the holiday is on that day and month,
    if year is not None, it is on that specific date.

    If mode is 'rel', then the holiday is 'day' days before or after easter.
    """

    name = models.CharField(_("Name"), max_length=50)
    mode = models.CharField(
        _("Mode"),
        max_length=3,
        choices=(("abs", _("Absolute")), ("rel", _("Easter-related"))),
    )
    day = models.IntegerField(
        _("Day"), help_text=_("day of month or distance from Easter in days")
    )
    month = models.IntegerField(_("Month"), null=True, blank=True)
    year = models.IntegerField(_("Year"), null=True, blank=True)

    class Meta:
        verbose_name = _("Calculated Holiday")
        verbose_name_plural = _("Calculated Holidays")

    def __str__(self):
        if self.mode == "abs":
            return f"{self.name}: {self.day}.{self.month}.{self.year or ''}"
        if self.day >= 0:
            return f"{self.name}: {self.day} Tage nach Ostern"
        else:
            return f"{self.name}: {-self.day} Tage vor Ostern"

    def toJson(self):
        return {
            "name": self.name,
            "mode": self.mode,
            "day": self.day,
            "month": self.month or 0,
            "year": self.year or 0,
        }

class Region(models.Model):
    """Aggregates the usual holidays for that region"""

    name = models.CharField(_("Name"), max_length=50)
    shortname = models.CharField(_("Short Name"), max_length=10, unique=True)
    # holidays = models.ManyToManyField(Holiday, verbose_name=_('Holidays'),
    #                                   related_name='regions')
    calc_holidays = models.ManyToManyField(
        CalculatedHoliday, verbose_name=_("Holidays"), related_name="regions"
    )

    class Meta:
        verbose_name = _("Region")
        verbose_name_plural = _("Regions")
        ordering = ["name"]

    def __str__(self):
        return self.name

class FeedId(models.Model):
    """The Id for the URL of an ical feed"""

    uid = models.CharField("ID", max_length=20, unique=True)
    person = models.ForeignKey(
        Person, related_name="feed_ids", on_delete=models.CASCADE
    )
    active = models.BooleanField(default=True)

    class Meta:
        verbose_name = "FeedId"
        verbose_name_plural = "FeedIds"

    def __str__(self):
        pass

    @classmethod
    def new(cls, person):
        """Return a new feed-id for a person.

        The old ones stay active
        """
        while True:
            try:
                uid = random_string(12, string.ascii_letters + string.digits)
                feed = FeedId.objects.create(uid=uid, person=person)
                return feed
            except IntegrityError:
                # uid was already taken
                pass


import pyvista as pv
from pyvistaqt import BackgroundPlotter
import os
import numpy as np

# Class on building a replica point cloud one point neighbourhood at a time.
class find_neighbours():
    def __init__(self,pc_points, num_neighbours):
        # Setup initial variables - get the point cloud, set a counter for the current point selected, getting the neighborhood
        # setup a array of booleans to keep track of the points that have been already checked and setting up the plotter
        self.pc_points = pc_points
        self.counter = 0
        self.num_neighbours = num_neighbours
        self.checked = np.zeros(len(pc_points), dtype=bool)
        self.p = BackgroundPlotter()

    # Update function called by the callback
    def every_point_neighborhood(self):
        # get the current point to calculate the neighborhood of
        point = pc_points[self.counter,:]
        # get all the indices of the neighbors of the current point
        index = pc.find_closest_point(point,self.num_neighbours)
        # get the neighbor points
        neighbours = pc_points[index,:]
        # mark the points as checked and extract the checked sub-point cloud
        self.checked[index] = True

        new_pc = pc_points[self.checked]
        # move the reconstructed point cloud in X direction so it can be more easier seen
        new_pc[:,0]+=1
        # add the neighborhood points, the center point and the new checked point clouds to the plotter.
        # Because we are using the same names PyVista knows to update the already existing ones
        self.p.add_mesh(neighbours, color="r", name='neighbors', point_size=8.0, render_points_as_spheres=True)
        self.p.add_mesh(point, color="b", name='center', point_size=10.0, render_points_as_spheres=True)
        self.p.add_mesh(new_pc, color="g", name='new_pc', render_points_as_spheres=True)
        # move the counter with a 100 points so the visualization is faster - change this to 1 to get all points
        self.counter+=100
        # get the point count
        pc_count = len(pc_points)
        # check if all points have been done. If yes then 0 the counter and the checked array
        if self.counter >= pc_count:
            self.counter = 0
            self.checked = np.zeros(len(pc_points), dtype=bool)

        # We update the whole plotter
        self.p.update()
    # visualization function
    def visualize_neighbours(self):
        # add the colored mesh of the duck statue. We set the RGB color scalar array as color by calling rgb=True
        self.p.add_mesh(pc, render_points_as_spheres=True, rgb=True)
        # We set the callback function and an interval of 100 between update cycles
        self.p.add_callback(self.every_point_neighborhood, interval=100)
        self.p.show()
        self.p.app.exec_()

# Class of parameters used in the two callback function
class params():
    # size of the neighborhood
    size = 20
    # the selected point
    point = np.zeros([1,3])
    # is the point selected or not
    point_selected = False

# Callback function for selecting points with the mouse
def manipulate_picked(point):
    # Get selected point and switch the boolean for having selected something to True
    params.point = point
    params.point_selected = True
    # Get the closest points indices
    index = pc.find_closest_point(point,params.size)
    # Get the points themselves
    neighbours = pc_points[index,:]
    # add points representing the neighborhood and the selected point to the plotter
    p.add_mesh(neighbours, color="r", name='neighbors', point_size=8.0, render_points_as_spheres=True)
    p.add_mesh(point, color="b", name='center', point_size=10.0, render_points_as_spheres=True)

# Callback function for the slider widget for changing the neighborhood size
def change_neighborhood(value):
    # change the slider value to int
    params.size = int(value)
    # call the point selection function if a point has already been selected
    if params.point_selected:
        manipulate_picked(params.point)

    return

def connectivity_filter(pc):
    # Use the connectivity filter to get the scalar array of region ids
    conn = pc.connectivity(largest=False)
    # See the active scalar fields in the calculated object
    print(conn.active_scalars_name)
    # Show the ids
    print(conn["RegionId"])
    # Set up a plotter
    p = pv.Plotter()
    # add the interactive thresholding tool and show everything
    p.add_mesh_threshold(conn,show_edges=True)
    p.show()

if __name__ == '__main__':

    # Read the duck statue point cloud
    pc_path = os.path.join('point_cloud','duckStatue.ply')
    pc = pv.read(pc_path)

    pc_points = pc.points
    pc_points = np.array(pc_points)

    ## Part 1 Initialize class for reconstructing of the point cloud one neighborhood at a time
    # neighbours_class = find_neighbours(pc_points, 400)
    # neighbours_class.visualize_neighbours()

    ## Part 2 Manual selection of points and calculating neighborhoods based on a slider size
    # Initialize the plotter
    p = pv.Plotter()
    # Add the main duck statue point cloud as spheres and with colors
    p.add_mesh(pc, render_points_as_spheres=True, rgb=True)
    # Initialize the mouse point picker callback and the slider widget callback
    p.enable_point_picking(callback=manipulate_picked,show_message="Press left mouse to pick", left_clicking=True)
    p.add_slider_widget(change_neighborhood, [10, 300], 20, title='Neighbourhood size', event_type = "always")
    p.show()

    ## Part 3 Connectivity filter function
    # connectivity_filter(pc)

Neighborhood Analysis, KD-Trees, and Octrees for Meshes and Point Clouds in Python/pyvista_neighborhood_distance_analysis.py


## Load model
import wandb
import hydra
import os

@hydra.main(config_path="../conf", config_name="scripts/download_model")
def main(cfg):
    api = wandb.Api()
    artifact = api.artifact(cfg.artifact_name, type='model')
    os.makedirs(cfg.download_dir, exist_ok=True)
    artifact_dir = artifact.download(root=cfg.download_dir)

if __name__ == "__main__":
    main()


"""Script that cleans ipynb files from metadata"""

import json
from find_files import get_files_with_extension

def clear_cell_ipynb(cell):
    """Modify cell metadata for ipynb cells"""
    cell["execution_count"] = None
    cell["outputs"] = []
    return cell

def clear_notebook_metadata(file_path):
    """Clear metadata for ipynb file by overwriting it in place  """
    with open(file_path, "r") as file:
        data = json.load(file)
        data['cells'] = [clear_cell_ipynb(cell) for cell in data['cells']]
        data['metadata'] = {}
        json.dump(data, open(file_path, "w"), indent=4)

def main():
    """Clear ipynb files from metadata """
    for file in get_files_with_extension():
        clear_notebook_metadata(file)

if __name__ == '__main__':
    main()


# -*- encoding=utf-8 -*-
import cv2
# Standard library
import time
import gzip
import zipfile
import numpy as np
import os
import math
from PIL import Image
import matplotlib.pyplot as plt
import cPickle as pickle
import glob

np.random.seed(0)

radial=[i*0.1*14 for i in range(10)]
random = [i*0.1 for i in range(10)]

def fft(img):
    return np.fft.fft2(img)
def fftshift(img):
    return np.fft.fftshift(fft(img))
def ifft(img):
    return np.fft.ifft2(img)
def ifftshift(img):
    return ifft(np.fft.ifftshift(img))

def oneHotRepresentation(y):
    n = y.shape[0]
    r = np.zeros([n, 10])
    for i in range(r.shape[0]):
        r[i,int(y[i])] = 1
    return r

def distance(i,j,w,h,r):
    dis=np.sqrt((i-14)**2+(j-14)**2)
    if dis<r:
        return 0.0
    else:
        return 1.0

def distance2(i,j,w,h,r=14.0,l=0):
    if l == 0:
        return 1
    elif l == 1:
        dis=np.sqrt((i-0)**2+(j-0)**2)
    elif l == 2:
        dis=np.sqrt((i-0)**2+(j-13.5)**2)
    elif l == 3:
        dis=np.sqrt((i-0)**2+(j-27)**2)
    elif l == 4:
        dis=np.sqrt((i-13.5)**2+(j-0)**2)
    elif l == 5:
        dis=np.sqrt((i-13.5)**2+(j-13.5)**2)
    elif l == 6:
        dis=np.sqrt((i-13.5)**2+(j-27)**2)
    elif l == 7:
        dis=np.sqrt((i-27)**2+(j-0)**2)
    elif l == 8:
        dis=np.sqrt((i-27)**2+(j-13.5)**2)
    else:
        dis=np.sqrt((i-27)**2+(j-27)**2)
    if dis < r:
        return 1
    else:
        return 0

def mask_radial(img,l,isGray=True):
    rows,cols=img.shape
    mask = np.zeros((rows,cols))
    for i in range(rows):
        for j in range(cols):
            mask[i,j]=distance2(i,j,rows,cols,r=14, l=l)
    return mask

def mask_random(img,p = 0.5,isGray=True):
    rows,cols=img.shape
    mask=np.random.binomial(1,p,(rows,cols))
    return mask

maskRandomKernel = [mask_random(np.zeros([28,28]),random[i],True) for i in range(10)]
maskRadioKernel = [mask_radial(np.zeros([28,28]),i,True) for i in range(10)]

def change_img_random(image,r,g,b,isGray=True,label=-1):
    if label==-1:
        x=np.random.randint(10)
    else:
        # label=0-9
        if np.random.random() < 0.8:
            x=label
        else:
            x = np.random.randint(10)

    _mask = maskRandomKernel[x]

    if isGray == True:
        fftshift_img_r=fftshift(r)
        fftshift_result_r = fftshift_img_r * _mask
        result_r = ifftshift(fftshift_result_r)
        mr=np.abs(result_r)
        return mr

    fftshift_img_b=fftshift(b)
    fftshift_result_b = fftshift_img_b * _mask
    result_b = ifftshift(fftshift_result_b)
    mb=np.abs(result_b)

    _mask=mask_random(image,0.0)
    fftshift_img_g=fftshift(g)
    fftshift_result_g = fftshift_img_g * _mask
    result_g = ifftshift(fftshift_result_g)
    mg=np.abs(result_g)

    _mask=mask_random(image,0.0)
    fftshift_img_r=fftshift(r)
    fftshift_result_r = fftshift_img_r * _mask
    result_r = ifftshift(fftshift_result_r)
    mr=np.abs(result_r)

    img_mix=cv2.merge([mr,mg,mb])
    return img_mix

def change_img_radial(image,r,g,b,isGray=True,label=-1, corr=0.8):
    if label==-1:
        x=np.random.randint(10)
    else:
        if np.random.random() < corr:
            x=label
        else:
            x = np.random.randint(10)

    _mask = maskRadioKernel[x]

    if isGray == True:
        fftshift_img_r=fftshift(r)
        fftshift_result_r = fftshift_img_r * _mask
        result_r = ifftshift(fftshift_result_r)
        mr=np.abs(result_r)
        return mr, x

    fftshift_img_b=fftshift(b)
    fftshift_result_b = fftshift_img_b * _mask
    result_b = ifftshift(fftshift_result_b)
    mb=np.abs(result_b)

    fftshift_img_g=fftshift(g)
    fftshift_result_g = fftshift_img_g * _mask
    result_g = ifftshift(fftshift_result_g)
    mg=np.abs(result_g)

    fftshift_img_r=fftshift(r)
    fftshift_result_r = fftshift_img_r * _mask
    result_r = ifftshift(fftshift_result_r)
    mr=np.abs(result_r)

    img_mix=cv2.merge([mr,mg,mb])
    return img_mix, x

def one_hot(x, n):
    """
    convert index representation to one-hot representation
    """
    x = np.array(x)
    assert x.ndim == 1
    return np.eye(n)[x]

def _grayscale(a):
    return a.reshape(a.shape[0], 3, 32, 32).mean(1).reshape(a.shape[0], -1)

def change_mnist_radial(isGray=True, corr=0.8):
    f = gzip.open('../data/MNIST/mnist.pkl.gz', 'rb')
    training_data, validation_data, test_data = pickle.load(f)
    f.close()

    _Xtrain=np.zeros((training_data[0].shape[0],28*28))
    _Xvalidation = np.zeros((validation_data[0].shape[0],28*28))
    _Xtest=np.zeros((test_data[0].shape[0],28*28))
    idLabel_train = []
    idLabel_val = []
    idLabel_test = []
    for i in range(training_data[0].shape[0]):
        r = training_data[0][i]
        r=r.reshape(28,28)
        img_mix, pid =change_img_radial(r,r,r,r,isGray,int(training_data[1][i]),corr=corr)
        _Xtrain[i]=img_mix.reshape(1,28*28)
        idLabel_train.append(pid)

    for i in range(validation_data[0].shape[0]):
        r = validation_data[0][i]
        r=r.reshape(28,28)
        img_mix, pid=change_img_radial(r,r,r,r,isGray,int(validation_data[1][i]),corr=corr)
        _Xvalidation[i]=img_mix.reshape(1,28*28)
        idLabel_val.append(pid)

    for i in range(test_data[0].shape[0]):
        r = test_data[0][i]
        r=r.reshape(28,28)
        img_mix, pid=change_img_radial(r,r,r,r,isGray,-1,corr=corr)
        _Xtest[i]=img_mix.reshape(1,28*28)
        idLabel_test.append(pid)

    idLabel_train = np.array(idLabel_train)
    idLabel_val = np.array(idLabel_val)
    idLabel_test = np.array(idLabel_test)

    #shuffle

    training_label = training_data[1]

    indices = np.random.permutation(_Xtrain.shape[0])
    _Xtrain = _Xtrain[indices, :]
    training_label = training_data[1][indices]

    return _Xtrain, oneHotRepresentation(training_label),_Xvalidation,oneHotRepresentation(validation_data[1]),_Xtest,oneHotRepresentation(test_data[1])

####################################################################################
### MultiDomain Codes
####################################################################################

def addingPattern(r, mask):
    fftshift_img_r=fftshift(r)
    fftshift_result_r = fftshift_img_r * mask
    result_r = ifftshift(fftshift_result_r)
    mr=np.abs(result_r)
    return mr

def mask_radial_MM(isGray=True):
    mask = np.zeros((28,28))
    for i in range(28):
        for j in range(28):
            mask[i,j]=distance(i,j,28,28,r=3.5)
    return mask

def mask_random_MM(p = 0.5,isGray=True):
    mask=np.random.binomial(1,1-p,(28,28))
    return mask

def addMultiDomainPattern(r, l, testCase, testingFlag=False, randomMask=None, radioMask=None):
    if testingFlag:
        if testCase == 0:
            return r
        elif testCase == 1:
            return addingPattern(r, randomMask)
        else:
            return addingPattern(r, radioMask)
    else:
        # if l < 5:   # TODO: switch this line with the next line to control whether the experiment is on dependent case or independent case
        if np.random.random() < 0.5:
            k = 1
        else:
            k = 2
        return addMultiDomainPattern(r, None, int(testCase+k)%3, testingFlag=True, randomMask=randomMask, radioMask=radioMask)

def loadMultiDomainMNISTData(testCase=1):
    '''
    :param testCase:
            0 for original distribution as testing
            1 for random kernel as testing
            2 for radial kernel as testing
    :return:
    '''

    np.random.seed(1)

    f = gzip.open('../data/MNIST/mnist.pkl.gz', 'rb')
    training_data, validation_data, test_data = pickle.load(f)
    f.close()

    randomMask = mask_random_MM()
    radioMask = mask_radial_MM()

    _Xtrain=np.zeros((training_data[0].shape[0],28*28))
    _Xvalidation = np.zeros((validation_data[0].shape[0],28*28))
    _Xtest=np.zeros((test_data[0].shape[0],28*28))

    for i in range(training_data[0].shape[0]):
        r = training_data[0][i]
        r=r.reshape(28,28)
        img = addMultiDomainPattern(r, training_data[1][i], testCase, randomMask=randomMask, radioMask=radioMask)
        _Xtrain[i]=img.reshape(1,28*28)

    for i in range(validation_data[0].shape[0]):
        r = validation_data[0][i]
        r=r.reshape(28,28)
        img = addMultiDomainPattern(r, training_data[1][i], testCase, randomMask=randomMask, radioMask=radioMask)
        _Xvalidation[i]=img.reshape(1,28*28)

    for i in range(test_data[0].shape[0]):
        r = test_data[0][i]
        r=r.reshape(28,28)
        img = addMultiDomainPattern(r, training_data[1][i], testCase, testingFlag=True,randomMask=randomMask, radioMask=radioMask)
        _Xtest[i]=img.reshape(1,28*28)

    indices = np.random.permutation(_Xtrain.shape[0])
    _Xtrain = _Xtrain[indices, :]
    training_label = training_data[1][indices]

    return _Xtrain, oneHotRepresentation(training_label),_Xvalidation,oneHotRepresentation(validation_data[1]),_Xtest,oneHotRepresentation(test_data[1])

if __name__ == '__main__':
    loadMultiDomainMNISTData(testCase=2)


# vim: tabstop=4 shiftwidth=4 softtabstop=4

#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from oslo.config import cfg
import webob.dec
import webob.exc

from nova import context
from nova import utils

CONF = cfg.CONF

class Fault(webob.exc.HTTPException):
    """Captures exception and return REST Response."""

    def __init__(self, exception):
        """Create a response for the given webob.exc.exception."""
        self.wrapped_exc = exception

    @webob.dec.wsgify
    def __call__(self, req):
        """Generate a WSGI response based on the exception passed to ctor."""
        code = self.wrapped_exc.status_int
        message = self.wrapped_exc.explanation

        if code == 501:
            message = "The requested function is not supported"
        code = str(code)

        if 'AWSAccessKeyId' not in req.params:
            raise webob.exc.HTTPBadRequest()
        user_id, _sep, project_id = req.params['AWSAccessKeyId'].partition(':')
        project_id = project_id or user_id
        remote_address = getattr(req, 'remote_address', '127.0.0.1')
        if CONF.use_forwarded_for:
            remote_address = req.headers.get('X-Forwarded-For', remote_address)

        ctxt = context.RequestContext(user_id,
                                      project_id,
                                      remote_address=remote_address)

        resp = webob.Response()
        resp.status = self.wrapped_exc.status_int
        resp.headers['Content-Type'] = 'text/xml'
        resp.body = str('<?xml version="1.0"?>\n'
                         '<Response><Errors><Error><Code>%s</Code>'
                         '<Message>%s</Message></Error></Errors>'
                         '<RequestID>%s</RequestID></Response>' %
                         (utils.xhtml_escape(utils.utf8(code)),
                          utils.xhtml_escape(utils.utf8(message)),
                          utils.xhtml_escape(utils.utf8(ctxt.request_id))))

        return resp


# -*- encoding:utf-8 -*-
# __author__=='Gan'
# 本题与Leetcode无关，是算法课上的习题。
# 一本书的页码从自然数1开始顺序编码直到自然数n。书的页码按照通常的习惯编排，每个页码都不含多余的前导数字0。例如第6页用6表示而不是06或006。
# 数字统计问题要求对给定书的总页码，计算出书的全部页码中分别用到多少次数字0,1,2,3,.....9。

# Solution:
# section_count = num[0]*(m-1)*10^(m-2) and m is the length of num. it's very important.
# digits_dict[i] += 10 ** (num_length - 1)
# digits_dict[int(str_num[0])] += int(str_num[1:] if num_length > 1 else 0) + 1

from datetime import datetime
class Solution(object):
    def digitCount(self, num):
        start = datetime.now()
        digits_dict = dict(zip([x for x in range(10)], [0]*10))
        while True:
            str_num = str(num)
            num_length = len(str_num)

            if num_length - 1 > 0:
                section_count = int(str_num[0]) * (num_length - 1) * (10 ** (num_length - 2))
                print(section_count)
                for i in range(10):
                    digits_dict[i] += section_count

            for i in range(1, int(str_num[0])):
                digits_dict[i] += 10 ** (num_length - 1)

            digits_dict[int(str_num[0])] += int(str_num[1:] if num_length > 1 else 0) + 1

            if num_length - 1 == 0:
                print('Cost {}s'.format(datetime.now() - start))
                return digits_dict

            num = num % (10 ** (num_length - 1))

# Another Problem:  Count the number of k's between 0 and n. k can be 0 - 9.
# Solution:
# If current-bit smaller than k, current count will be added higher-bit multiply the current-bit.
# If current-bit bigger than k, current count will be added higher-bit plus 1 then multiply the current-bit.
# If current-bit equal the k, current count will be added higher-bit multiply the current-bit
# and add the lower-bit plus 1.
class Solution(object):
    def digitCount(self, num, k):
        """
        :type num: int
        :type k: int
        :rtype: int
        """
        count = 0
        base = 1
        while num // base:
            higher_bit = num // (base * 10)
            current_bit = num % (base * 10) // base
            lower_bit = num % base

            if current_bit < k:
                count += higher_bit * base
            elif current_bit > k:
                count += (higher_bit + 1) * base
            else:
                count += higher_bit * base + lower_bit + 1
            base *= 10
            print(count)

        return count

if __name__ == '__main__':
    # num = 987654
    # print('num: {}\n'.format(num))
    # print(Solution().digitCount(num))
    num = 5678
    print('num: {}'.format(num))
    print(Solution().digitCount(num, 7))


import logging, datetime

LOGGER = logging.getLogger(__name__)

def get_insert_args(table, on_conflict = None, **kwargs):

	def is_j(v):
		return (isinstance(v, tuple) or isinstance(v, list)) and v[1] == 'julian'

	sql = '''
		insert {conflict} into {table}
		({names})
		values
		({question_marks})
		'''
	names = [ ]
	values = [ ]
	for name, value in kwargs.iteritems():
		names.append(name)
		if hasattr(value, 'year') and hasattr(value, 'month') and hasattr(value, 'day'):
			value = date_to_sqlite_str(value)
		values.append(value)
	sql = sql.format(
			table = table,
			names = ', '.join(names),
			question_marks = ', '.join(
				('julianday(?)' if is_j(v) else '?')
				for v in values
			),
			conflict = '' if on_conflict is None else 'or ' + on_conflict,
	)
	values = [v if not is_j(v) else v[0] for v in values]
	LOGGER.debug('get_insert_args sql: %s, args: %s', sql, values)
	return sql, values

def get_insert_args_mysql(table, on_conflict = None, **kwargs):

	sql = '''
		{verbs}
		into {table}
		({names})
		values
		({placeholders})
		{dup}
		'''
	names = [ ]
	values = [ ]
	for name, value in kwargs.iteritems():
		names.append(name)
		if hasattr(value, 'year') and hasattr(value, 'month') and hasattr(value, 'day'):
			value = str(value.year) + '-' + str(value.month) + '-' + str(value.day)
		values.append(value)
	dup = ''
	if on_conflict is None:
		verbs = 'insert'
	elif on_conflict == 'replace':
		verbs = 'insert'
		dup = 'on duplicate key update'
		dup += '\n'
		dup += ', '.join(
				name + ' = ' + '%s'
				for name, value
				in zip(names, values)
				)
	elif on_conflict == 'ignore':
		verbs = 'insert ignore'
	sql = sql.format(
			table = table,
			names = ', '.join(names),
			placeholders = ', '.join(
				'%s'
				for v in values
			),
			verbs = verbs,
			dup = dup,
	)
	if dup != '':
		values = values * 2
	LOGGER.debug('get_insert_args sql: %s, args: %s', sql, values)
	return sql, values

def datetime_to_sqlite_str(dt):
	return datetime.datetime.strftime(
		dt, '%Y-%m-%d %H:%M'
	)


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

from __future__ import annotations

import gzip
from itertools import chain
from multiprocessing import Pool, Semaphore
from pathlib import Path
from typing import Iterable, Dict, List

from ..util import produce, simple_preprocess
from ..configuration import CORPORA, IO_QUEUE_SIZE
import gensim.downloader
from tqdm import tqdm

def get_corpus_path(language: str, name: str, corpus_dir: Path) -> Path:
    if language != 'en':
        raise ValueError('Unsupported Wikipedia language {}'.format(language))
    corpus_path = corpus_dir / name
    corpus_path.mkdir(parents=True, exist_ok=True)
    corpus_path = corpus_path / language
    corpus_path = corpus_path.with_suffix('.txt.gz')
    if corpus_path.exists():
        return corpus_path
    with gzip.open(corpus_path, 'wt', compresslevel=9) as f:
        desc = 'Creating corpus {}'.format(corpus_path)
        semaphore = Semaphore(IO_QUEUE_SIZE)
        sentences = EnglishWikipediaSentences(desc, semaphore)
        for sentence in sentences:
            sentence = ' '.join(sentence)
            print(sentence, file=f)
    return corpus_path

def _read_sentences_helper(article: Dict[str, str]) -> List[List[str]]:
    all_sentences = []
    for section_title, section_text in zip(article['section_titles'], article['section_texts']):
        sentences = section_text.splitlines()
        sentences = map(str.strip, sentences)
        sentences = filter(len, sentences)
        sentences = chain([section_title], sentences)
        sentences = map(simple_preprocess, sentences)
        all_sentences.extend(sentences)
    return all_sentences

class EnglishWikipediaSentences:
    def __init__(self, desc: str, semaphore, percentage: float = 1.0):
        self.desc = desc
        self.semaphore = semaphore
        self.percentage = percentage

    def __iter__(self) -> Iterable[List[str]]:
        total = int(float(CORPORA['wikipedia']) * self.percentage)
        articles = gensim.downloader.load('wiki-english-20171001')
        articles = (article for article, _ in zip(articles, range(total)))
        articles = tqdm(articles, desc=self.desc, total=total)
        articles = produce(articles, self.semaphore)
        with Pool(None) as pool:
            for sentences in pool.imap_unordered(_read_sentences_helper, articles):
                for sentence in sentences:
                    yield sentence
                self.semaphore.release()