import os
import sys, time, random

from zipfile import ZipFile

from PyQt6.QtWidgets import QApplication, QWidget, QFileDialog, QMessageBox, QDialog, QVBoxLayout, QLabel
from PyQt6.QtGui import QIcon
from PyQt6 import uic, QtGui, QtCore, QtWidgets

from threading import Thread
from pathlib import Path

sys.setrecursionlimit(5000)

uifile = 'sudoku.ui'
form, base = uic.loadUiType(uifile)

PATH = 'data'
print(os.path.isdir(PATH))
if not os.path.isdir(PATH):
	with ZipFile('data.zip', 'r') as zip_ref:
		zip_ref.extractall(PATH)

class DifficultyDialog(QDialog):
	def __init__(self):
		super().__init__()

		self.setWindowTitle("DifficultyDialog")
		self.setWindowIcon(QtGui.QIcon('assets/icons/question-mark.png'))

		self.difficulty = 'trivial'

		self.btn_trivial = QtWidgets.QPushButton("Trivial")
		self.btn_easy = QtWidgets.QPushButton("Easy")
		self.btn_medium = QtWidgets.QPushButton("Medium")
		self.btn_hard = QtWidgets.QPushButton("Hard")

		self.layout = QVBoxLayout()
		message = QLabel("Select a difficulty : ")
		self.layout.addWidget(message)
		self.layout.addWidget(self.btn_trivial)
		self.layout.addWidget(self.btn_easy)
		self.layout.addWidget(self.btn_medium)
		self.layout.addWidget(self.btn_hard)

		self.setLayout(self.layout)

		self.btn_trivial.clicked.connect(self.trivial)
		self.btn_easy.clicked.connect(self.easy)
		self.btn_medium.clicked.connect(self.medium)
		self.btn_hard.clicked.connect(self.hard)

	def trivial(self) -> None:
		self.close()
		self.difficulty = 'trivial'
	def easy(self) -> None:
		self.close()
		self.difficulty = 'easy'
	def medium(self) -> None:
		self.close()
		self.difficulty = 'medium'
	def hard(self) -> None:
		self.close()
		self.difficulty = 'hard'

class MainWindow(base, form):
	def __init__(self):
		super(base, self).__init__()
		self.setWindowIcon(QtGui.QIcon('assets/icons/sudoku.png'))

		self.PATHS = {
			"trivial": "data/puzzles0_kaggle",
			"easy": "data/puzzles2_17_clue",
			"medium": "data/puzzles3_magictour_top1465",
			"hard": "data/puzzles6_forum_hardest_1106",
		}
		self.DIFFICULTY = 'easy'

		self.board = None

		self.setupUi(self)
		self.setWindowTitle("Sudoku")

		self.setFixedHeight(500)
		self.setFixedWidth(440)

		self.actionNew_game.triggered.connect(self.resetBoard)

		self.actionSolve.triggered.connect(self.solveSudokuThread)
		self.actionShow_Backtracking_Slow.triggered.connect(self.solveSudokuThreadSlow)

		self.actionClear.triggered.connect(self.clearSudokuThread)
		self.actionAbout.triggered.connect(self.aboutSection)

		self.pushButtonReset.clicked.connect(self.resetSudokuThread)
		self.pushButtonCheck.clicked.connect(self.checkSudoku)

		self.createGame()

	def fixBox(self, i, j, index):
		getattr(self, f"comboBox_{i}_{j}").setCurrentIndex(index)
		getattr(self, f"comboBox_{i}_{j}").setEnabled(False)

	def enableBox(self, i, j):
		getattr(self, f"comboBox_{i}_{j}").setEnabled(True)

	def setBoxData(self, i, j, data):
		getattr(self, f"comboBox_{i}_{j}").setCurrentIndex(data)

	def getBoxDataIndex(self, i, j) -> int:
		return getattr(self, f"comboBox_{i}_{j}").currentIndex()

	def isBoxEnabled(self, i, j) -> bool:
		return getattr(self, f"comboBox_{i}_{j}").isEditable()

	def reset(self):
		self.clear()
		self.createSudoku(self.board)

	def clear(self):
		for i in range(9):
			for j in range(9):
				self.setBoxData(i, j, 0)
				self.enableBox(i, j)

	def solve(self, ms = 0) -> bool:
		for i in range(9):
			for j in range(9):
				if self.getBoxDataIndex(i, j) == 0:
					for val in range(1, 10):

						time.sleep(ms)
						if self.check(i, j, val):
							self.setBoxData(i, j, val)
							if self.solve(ms):
								return True
							self.setBoxData(i, j, 0)
					return False
		return True

	def check(self, i, j, val):
		if val == 0:
			return False

		for ii in range(9):
			if self.getBoxDataIndex(i, ii) == val:
				return False
			if self.getBoxDataIndex(ii, j) == val:
				return False
		x, y = i - i%3, j - j%3
		for ii in range(3):
			for jj in range(3):
				if self.getBoxDataIndex(x + ii, y + jj) == val:
					return False
		return True

	def showMessageBox(self, title, message):
		dlg = QMessageBox(self)
		dlg.setWindowTitle(title)
		dlg.setText(message)
		button = dlg.exec()

	def showDifficultySettings(self):
		diff = DifficultyDialog()
		diff.exec()
		if self.DIFFICULTY != diff.difficulty:
			self.DIFFICULTY = diff.difficulty
			self.boards = self.getSudokuData(self.PATHS[self.DIFFICULTY])
		self.boards = self.getSudokuData(self.PATHS[self.DIFFICULTY])

	def checkSudoku(self):
		solved = True
		for i in range(9):
			for j in range(9):

				val = self.getBoxDataIndex(i, j)
				self.setBoxData(i, j, 0)

				if not self.check(i, j, val):
					solved = False
					break

				self.setBoxData(i, j, val)

		if not solved:
			self.showMessageBox("Sudoku not solved", "Sudoku is either incomplete/incorrect !")
		else:
			self.showMessageBox("Congratulations !", "You have solved it correctly !")
			self.createGame()

	def solveSudoku(self, ms=0):
		self.pushButtonReset.setEnabled(False)
		self.actionClear.setEnabled(False)
		self.actionSolve.setEnabled(False)
		self.actionNew_game.setEnabled(False)
		self.actionShow_Backtracking_Slow.setEnabled(False)

		solvable = self.solve(ms)

		self.pushButtonReset.setEnabled(True)
		self.actionClear.setEnabled(True)
		self.actionSolve.setEnabled(True)
		self.actionShow_Backtracking_Slow.setEnabled(True)
		self.actionNew_game.setEnabled(True)

	def solveSudokuThread(self):
		self.setFocus()
		self.pushButtonReset.setEnabled(False)
		thread = Thread(target=self.solveSudoku)
		thread.start()

	def solveSudokuThreadSlow(self):
		self.setFocus()
		self.pushButtonReset.setEnabled(False)
		thread = Thread(target=self.solveSudoku, args = [0.001])
		thread.start()

	def clearSudokuThread(self):
		self.setFocus()
		thread = Thread(target=self.clear)
		thread.start()

	def resetSudokuThread(self):
		self.setFocus()
		thread = Thread(target=self.reset)
		thread.start()

	def resetBoard(self):
		self.createGame()

	def aboutSection(self):
		self.showMessageBox("About", """
This is a sudoku app made in Python using PyQt6.
(Currently under development)

Creator : Utkarsh Sharma
									 """)

	def createSudoku(self, board):
		if board is None: return None
		self.board = board
		dataList = self.toDataList(board)
		for row, col, val in dataList:
			self.fixBox(row, col, val)

	def toDataList(self, board):
		data = []
		for i in range(9):
			for j in range(9):
				if board[i][j] != ".":
					data.append( (i, j, int(board[i][j])) )
		return data

	def getSudokuData(self, path):
		sdkList = []
		with open(path) as f:
			for line in f:
				mat = [['.' for i in range(9)] for i in range(9)]
				line = line.replace('/n', '')
				if len(line)==82:
					for i in range(81):
						mat[i//9][i%9] = line[i]
				sdkList.append(mat)
		return sdkList

	def createGame(self):
		self.showDifficultySettings()
		self.clear()
		index = random.randint(0, len(self.boards))
		self.board = self.boards[index]
		self.createSudoku(self.board)

def main():
	app = QApplication(sys.argv)

	window = MainWindow()
	window.show()
	sys.exit(app.exec())

if __name__ == '__main__':
	main()


from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time

# Signup
class Quantibly():
    def test_signup_valid(self):
        base_url = 'https://app.quantibly.com/register/'
        driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
        driver.maximize_window()
        driver.get(base_url)

        # Find Elements
        organization_name = driver.find_element(By.XPATH, '//*[@id="app"]/div/div/div/div/div/div[2]/div/div/form/section/div[1]/div/input')
        email_address = driver.find_element(By.XPATH, '//*[@id="app"]/div/div/div/div/div/div[2]/div/div/form/section/div[2]/div/input')
        get_started = driver.find_element(By.XPATH, '//*[@id="app"]/div/div/div/div/div/div[2]/div/div/form/button/span[1]')

        # Signup Action
        organization_name.clear()
        organization_name.send_keys('iQuantile')
        time.sleep(1)

        email_address.clear()
        email_address.send_keys('shuvo.bandahajir@gmail.com')
        time.sleep(1)

        get_started.click()
        time.sleep(3)

        # Email Verification Code
        verification_code = driver.find_element(By.ID, '1')
        verification_code.clear()
        verification_code.send_keys('5')

        verification_code = driver.find_element(By.ID, '2')
        verification_code.clear()
        verification_code.send_keys('6')

        verification_code = driver.find_element(By.ID, '3')
        verification_code.clear()
        verification_code.send_keys('2')

        verification_code = driver.find_element(By.ID, '4')
        verification_code.clear()
        verification_code.send_keys('5')

        verification_code = driver.find_element(By.ID, '5')
        verification_code.clear()
        verification_code.send_keys('8')

        verification_code = driver.find_element(By.ID, '6')
        verification_code.clear()
        verification_code.send_keys('0')

        # Verify Token
        verify_token = driver.find_element(By.XPATH, '//*[@id="app"]/div/div/div/div/div/div[2]/div/div/form/button')
        verify_token.click()
        time.sleep(2)

test_obj = Quantibly()
test_obj.test_signup_valid()


#!/usr/bin/env python
# coding: utf-8

#Venn diagrams
import pandas as pd
ibd_data = pd.read_pickle("datasetspandas/dutch_export_transposed_ibd_binary.pkl")
ibd_data.rename(columns={'Unnamed: 0': 'sample_id'}, inplace=True)
ibd_data.index.name = 'sample_id'

#Fetch cohort ID
covariates = pd.read_excel("Covariates/CDvsUC analysis covariates.xlsx")
covariates = covariates.set_index('sample_id')
del covariates['Plate_id']
del covariates['Age']
del covariates['Gender']

#Define groups
df_CD = covariates.loc[covariates['IBD type'] == 1]
df_UC = covariates.loc[covariates['IBD type'] == 0]
df_IBD = covariates.merge(ibd_data, on=["sample_id"])
cd_data = df_CD.merge(ibd_data, on=["sample_id"])
del cd_data['IBD type']
uc_data = df_UC.merge(ibd_data, on=["sample_id"])
del uc_data['IBD type']
del df_IBD['IBD type']

#CD feature selection (5% threshold)
def Prevalence(Series):
    Prev = Series.sum()/Series.count()
    return(Prev)
Prev_thresh = 0.05
print("Computing antibody prevalence")
Prevalences = df_IBD.apply(Prevalence, axis=0)
Vector_keep = Prevalences > Prev_thresh #True/False vector of the features with prevalence > 5%
df_IBD_f = df_IBD[Vector_keep.index[Vector_keep]] #Removal of columns that do not pass the prevalence threshold

#UC feature selection (5% threshold)
def Prevalence(Series):
    Prev = Series.sum()/Series.count()
    return(Prev)
Prev_thresh = 0.05
print("Computing antibody prevalence")
Prevalences = uc_data.apply(Prevalence, axis=0)
Vector_keep = Prevalences > Prev_thresh #True/False vector of the features with prevalence > 5%
uc_data_f = uc_data[Vector_keep.index[Vector_keep]] #Removal of columns that do not pass the prevalence threshold

cd_unique = cd_data_f.T
uc_unique = uc_data_f.T
cd_unique.to_excel("datasetspandas/cd_unique_features.xlsx")
uc_unique.to_excel("datasetspandas/uc_unique_features.xlsx")

df_IBD_f
ibd_unique = df_IBD_f.T
ibd_unique.to_excel("datasetspandas/ibd_unique_features.xlsx")

##Hereafter, random peptide selection exclusion and >95% exclusion was performed manually to compute overlapping numbers

#Figures
from matplotlib_venn import venn3, venn3_circles, venn3_unweighted
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
fig = plt.figure()

#Custom it
sns.set(rc={"figure.dpi":600, 'savefig.dpi':600})
sns.set(rc={'figure.figsize':(7,7)}, font_scale = 1.5)
sns.set_style("white")
c = venn3_unweighted(subsets=(281, 243, "", "", 227, 122, 1974), set_labels = ('CD', 'UC', 'IBD'), alpha=1)

#Add title and annotation
c.get_patch_by_id('100')
c.get_patch_by_id('010')
c.get_patch_by_id('001')
plt.title("Prevalence of antibody probes (≥5%)", fontsize=18)
plt.savefig("datasetspandas/VennDiagramPrevalence-updatedsep2021.jpg", bbox_inches='tight', dpi=600)

from matplotlib_venn import venn2, venn2_circles, venn2_unweighted
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

#Custom it
sns.set(rc={"figure.dpi":600, 'savefig.dpi':600})
sns.set(rc={'figure.figsize':(7,7)}, font_scale = 1.5)
sns.set_style("white")
c2 = venn2_unweighted(subsets = ('205', '104', '64'), set_labels = ('CD', 'UC'), alpha=0.5)

#Add title and annotation
c2.get_patch_by_id('10').set_color('deepskyblue')
c2.get_patch_by_id('01').set_color('lightblue')
c2.get_patch_by_id('11').set_color('darkblue')
c2.get_label_by_id('10').set_fontsize(18)
c2.get_label_by_id('01').set_fontsize(18)
c2.get_label_by_id('11').set_fontsize(18)
plt.title("Differentially abundant peptides", fontstyle="italic")
plt.suptitle("Total: 373 peptides (FDR≤0.05)", fontstyle="italic", x=0.52, y=0.78, fontsize=10)
plt.savefig("datasetspandas/VennDiagramCC-analysis-total_updatedaug2021.jpg", bbox_inches='tight', dpi=600)


""" Example: plotting Zarrow's non-classical Schottky group.

    Robert Zarrow. "Classical and non-classical Schottky groups". In: Duke Mathematical Journal (42)4, 1975. pp.717--724.'
"""

from bella import cayley
import holoviews as hv
hv.extension('bokeh')
from mpmath import mp
from functools import reduce

class ZarrowGroup(cayley.GroupCache):
    def __init__(self):
        fix_det = lambda M: 1/mp.sqrt(mp.det(M)) * M
        self.S = fix_det(mp.matrix([[99801,0],[59000,5988060]]))
        self.T = fix_det(mp.matrix([[99900,10010000],[1001,99900]]))
        mp.nprint(cayley.simple_tr(self.S))
        mp.nprint(cayley.simple_tr(self.T))
        super().__init__([self.S,self.T])

# Just compute the gasket as the limit set of the μ=2i parabolic Riley group, and save it to an image file.
num_points = 10**6
G = ZarrowGroup()

seed = G.fixed_points((0,1))[0]
df = G.coloured_limit_set_fast(num_points, seed=seed)
scatter = hv.Scatter(df, kdims = ['x'], vdims = ['y','colour'])\
            .opts(marker = "dot", size = 0.1,  color = 'colour', frame_width=800, frame_height=800, data_aspect=1, cmap='Set1')\
              .redim(x=hv.Dimension('x', range=(-200,200)),y=hv.Dimension('y', range=(-200,200)))

#isometric circles of generators
isocircles = [G.isometric_circle(w) for w in G.free_cayley_graph_bfs(1)]
ellipses = [hv.Ellipse(float(centre.real), float(centre.imag), float(radius)*2).opts(color='gray') for (centre, radius) in isocircles] #<-the final parameter of hv.Ellipse is diameter, not radius
scatter = reduce(lambda a,b: a*b, ellipses, scatter)

hv.save(scatter, 'zarrow1.png', fmt='png')
print(f'    zarrow.py (1/2): drew images of {mp.nstr(seed)}')

seed = 100j
df = G.coloured_limit_set_fast(num_points, seed=seed)
scatter = hv.Scatter(df, kdims = ['x'], vdims = ['y','colour'])\
            .opts(marker = "dot", size = 0.1,  color = 'colour', frame_width=800, frame_height=800, data_aspect=1, cmap='Set1')\
              .redim(x=hv.Dimension('x', range=(-200,200)),y=hv.Dimension('y', range=(-200,200)))
hv.save(scatter, 'zarrow2.png', fmt='png')
print(f'    zarrow.py (2/2): drew images of {mp.nstr(seed)}')


import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
# Function: K Means
# -------------
# K-Means is an algorithm that takes in a dataset and a constant
# k and returns k centroids (which define clusters of data in the
# dataset which are similar to one another).
# maxIt最大的迭代次数
def kmeans(X, k, maxIt):

    # 得到 行、列 数
    numPoints, numDim = X.shape
    # 矩阵多加一列，并且全部赋值为0
    dataSet = np.zeros((numPoints, numDim + 1))
    # 把原始数据集赋值给新的数组dataSet,其中最后一列为0
    dataSet[:, :-1] = X

    # Initialize centroids randomly
    # 从矩阵每行中随机选取K行  也就是说 选k个中心点
    centroids = dataSet[np.random.randint(numPoints, size=k), :]
    # centroids = dataSet[0:2, :]
    # Randomly assign labels to initial centorid
    # 对k行的最后一列 赋值 k种类别
    centroids[:, -1] = range(1, k + 1)

    # Initialize book keeping vars.
    iterations = 0
    oldCentroids = None

    # Run the main k-means algorithm
    # shouldStop（）计算迭代停止 条件
    while not shouldStop(oldCentroids, centroids, iterations, maxIt):
        print("iteration: \n", iterations)
        print("dataSet: \n", dataSet)
        print("centroids: \n", centroids)

        # Save old centroids for convergence test. Book keeping.
        # numpy复制数组
        oldCentroids = np.copy(centroids)
        iterations += 1

        # Assign labels to each datapoint based on centroids
        # 对每行数据 更新类别数据 所属的类别需要不断的更新
        updateLabels(dataSet, centroids)

        # Assign centroids based on datapoint labels
        # 重新获取中心点 计算平均值
        centroids = getCentroids(dataSet, k)

    # We can get the labels too by calling getLabels(dataSet, centroids)
    return dataSet

# Function: Should Stop
# -------------
# Returns True or False if k-means is done. K-means terminates either
# because it has run a maximum number of iterations OR the centroids
# stop changing.
def shouldStop(oldCentroids, centroids, iterations, maxIt):
    if iterations > maxIt:
        return True
    # 注意数组的比较 使用numpy的array_equal函数
    return np.array_equal(oldCentroids, centroids)

# Function: Get Labels
# -------------
# Update a label for each piece of data in the dataset.
def updateLabels(dataSet, centroids):
    # For each element in the dataset, chose the closest centroid.
    # Make that centroid the element's label.
    numPoints, numDim = dataSet.shape
    for i in range(0, numPoints):
        dataSet[i, -1] = getLabelFromClosestCentroid(dataSet[i, :-1], centroids)

def getLabelFromClosestCentroid(dataSetRow, centroids):
    label = centroids[0, -1]
    #norm 表示范数 默认为L2  这里算出了两个向量之间的距离
    minDist = np.linalg.norm(dataSetRow - centroids[0, :-1])
    for i in range(1, centroids.shape[0]):
        dist = np.linalg.norm(dataSetRow - centroids[i, :-1])
        if dist < minDist:
            minDist = dist
            # 更新距离相近的点 的类别
            label = centroids[i, -1]
    print("minDist:", minDist)
    return label

# Function: Get Centroids
# -------------
# Returns k random centroids, each of dimension n.
def getCentroids(dataSet, k):
    # Each centroid is the geometric mean of the points that
    # have that centroid's label. Important: If a centroid is empty (no points have
    # that centroid's label) you should randomly re-initialize it.
    result = np.zeros((k, dataSet.shape[1]))
    for i in range(1, k + 1):
        oneCluster = dataSet[dataSet[:, -1] == i, :-1]
        # 对两个点之间计算平均值，更新中心点的位置
        result[i - 1, :-1] = np.mean(oneCluster, axis=0)
        result[i - 1, -1] = i

    return result

# 准备数据集
x1 = np.array([1, 1])
x2 = np.array([2, 1])
x3 = np.array([4, 3])
x4 = np.array([5, 4])
x5=np.array([6,3])
x6=np.array([1,1.5])

# 合并为一个矩阵
# testX = np.vstack((x1, x2, x3, x4,x5,x6))
# testX=np.random.randint(1,100,size=[100,5])
testX, y = make_blobs(n_samples=1500, random_state=150)

#自己实现kmeans testx:数据集 3：K值 15：最大迭代次数
result = kmeans(testX, 3, 15)

# 绘制散点图
plt.figure(figsize=(10, 10))
# plt.subplot(221)
plt.scatter(result[:,0],result[:,1],result[:,2],c=result[:,-1])
plt.show()

print("final result:\n",result)


import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

fileWithIps = open("ipList.txt", "r")

def getIpList(file):
    clients = []
    servers = []
    routers = []
    connections = []
    for line in file:
        if line[0:1] == "0" and line[1] == ":":
            nonZeroLine = line.split(":")
            nonZeroLine.pop(0)
            nonZeroLine = str(nonZeroLine)
            zeroLine = nonZeroLine.split(".")
            zeroLine[0] = zeroLine[0][2:]
            zeroLine[3] = zeroLine[3][:-4]

            x = zeroLine[3].find("-")

            if x != -1:
                lastIpNumbers = zeroLine[3].split("-")
                for i in range(int(lastIpNumbers[0]), int(lastIpNumbers[1]) + 1):
                    ip_i = str(zeroLine[0] + "." + zeroLine[1] + "." + zeroLine[2] + "." + str(i))
                    clients.append(ip_i)
            else:
                s = ".".join(zeroLine)
                clients.append(s)

        if line[0] == "1" and line[1] == ":":
            nonZeroLine = line.split(":")
            nonZeroLine.pop(0)
            nonZeroLine = str(nonZeroLine)
            zeroLine = nonZeroLine.split(".")
            zeroLine[0] = zeroLine[0][2:]
            zeroLine[3] = zeroLine[3][:-4]

            x = zeroLine[3].find("-")

            if x != -1:
                lastIpNumbers = zeroLine[3].split("-")
                for i in range(int(lastIpNumbers[0]), int(lastIpNumbers[1]) + 1):
                    ip_i = str(zeroLine[0] + "." + zeroLine[1] + "." + zeroLine[2] + "." + str(i))
                    servers.append(ip_i)
            else:
                s = ".".join(zeroLine)
                servers.append(s)

        if line[0] == "2" and line[1] == ":":
            nonZeroLine = line.split(":")
            nonZeroLine.pop(0)
            nonZeroLine = str(nonZeroLine)
            zeroLine = nonZeroLine.split(".")
            zeroLine[0] = zeroLine[0][2:]
            zeroLine[3] = zeroLine[3][:-4]

            x = zeroLine[3].find("-")

            if x != -1:
                lastIpNumbers = zeroLine[3].split("-")
                for i in range(int(lastIpNumbers[0]), int(lastIpNumbers[1]) + 1):
                    ip_i = str(zeroLine[0] + "." + zeroLine[1] + "." + zeroLine[2] + "." + str(i))
                    routers.append(ip_i)
            else:
                s = ".".join(zeroLine)
                routers.append(s)

        isConn = line.find("--")
        if isConn > 0:
            connectionLine = line.split("--")
            connectionLine[1] = connectionLine[1][:-2]
            connections.append((connectionLine[0], connectionLine[1]))

    return clients, servers, routers, connections

def buildGraph(mainArray):
    pc = mpimg.imread('pc.png')
    router = mpimg.imread("router.jpg")
    server = mpimg.imread("server.png")

    G = nx.Graph
    for router in range(len(mainArray[2])):
        routerIP = mainArray[2][router].split(".")
        print(routerIP)
        for j in range(len(mainArray[0])):
            clientIP = mainArray[0][j].split(".")
            if clientIP[0] == routerIP[0] and clientIP[1] == routerIP[1] and clientIP[2] == routerIP[2]:
                clientIPstr = ".".join(clientIP)
                routerIPstr = ".".join(routerIP)
                G.add_edge("192.168.11.10", "192.168.11.1", image=pc, size=0.1)

    pos = nx.spring_layout(G)
    nx.draw(G, pos, with_labels=True)

    # add images on edges
    ax = plt.gca()
    fig = plt.gcf()
    label_pos = 0  # middle of edge, halfway between nodes
    trans = ax.transData.transform
    trans2 = fig.transFigure.inverted().transform
    imsize = 0.2  # this is the image size
    for (n1, n2) in G.edges():
        (x1, y1) = pos[n1]
        (x2, y2) = pos[n2]
        (x, y) = (x1 * label_pos + x2 * (1.0 - label_pos),
                  y1 * label_pos + y2 * (1.0 - label_pos))
        xx, yy = trans((x, y))  # figure coordinates
        xa, ya = trans2((xx, yy))  # axes coordinates
        imsize = G[n1][n2]['size']
        img = G[n1][n2]['image']
        a = plt.axes([xa - imsize / 2.0, ya - imsize / 2.0, imsize, imsize])
        a.imshow(img)
        a.set_aspect('equal')
        a.axis('off')
    plt.savefig('save.png')
    plt.axis('off')
    plt.show()

buildGraph(getIpList(fileWithIps))


from datetime import datetime

from app.baseModel import fields, pydantic_model_creator, BaseModel

class WeeklyConfigModel(BaseModel):
    name = fields.TextField(description="名字")
    parent = fields.IntField(null=True, default=None, description="上一级的id，有上一级则为项目，否则为产品")
    desc = fields.TextField(description="备注")

    class Meta:
        table = "test_work_weekly_config"
        table_description = "周报配置表"

    @classmethod
    async def get_data_dict(cls):
        """ 获取产品、项目数据
        {
            "id": {
                "total": 0,  # 产品下的项目数
                "name": "产品名",
                "project": {
                    "id": {
                        "total": 0,  # 项目下的版本数
                        "name": "项目名",
                        "version": {
                            "version1": {
                                "total": 0,  # 版本下的日报条数
                                "item": [],  # 版本下的日报数据
                            },
                            "version2": {
                                "total": 0,
                                "item": []
                            }
                        }
                    }
                }
            }
        }
        """
        container = {}
        product_list = [dict(data) for data in await WeeklyConfigModel.all()]

        # 获取所有产品
        for index, data in enumerate(product_list):
            if not data["parent"]:
                cls.build_project_product(container, data)
                cls.build_project_container(container[data["id"]], data)

        # 根据产品id获取所有项目
        for product_id, product_data in container.items():
            for index, data in enumerate(product_list):
                if data["parent"] == product_id:
                    cls.build_project_container(product_data, data)

        return container

    @classmethod
    def build_project_product(cls, container, data):
        """ 插入项目 """
        container[data["id"]] = {
            "total": 0,
            "name": data["name"],
            "project": {}
        }

    @classmethod
    def build_project_container(cls, container, data):
        """ 插入项目 """
        container["project"][data["id"]] = {
            "name": data["name"],
            "total": 0,
            "version": {}
        }
        container["total"] += 1

class WeeklyModel(BaseModel):
    product_id = fields.IntField(description="产品id")
    project_id = fields.IntField(description="项目id")
    version = fields.CharField(255, description="版本号")
    task_item = fields.TextField(description="任务明细和进度")
    start_time = fields.DatetimeField(default=datetime.now, description="开始时间")
    end_time = fields.DatetimeField(default=datetime.now, onupdate=datetime.now, description="结束时间")
    desc = fields.TextField(description="备注")

    class Meta:
        table = "test_work_weekly"
        table_description = "周报明细表"

WeeklyConfigModelPydantic = pydantic_model_creator(WeeklyConfigModel, name="WeeklyConfigModel")
WeeklyModelPydantic = pydantic_model_creator(WeeklyModel, name="WeeklyModel")


import datetime
import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
DB_PATH = "sqlite:///sochi_athletes.sqlite3"

from datetime import datetime, date, time

# базовый класс моделей таблиц
Base = declarative_base()

class User(Base):
    """
    Описывает структуру таблицы user для хранения регистрационных данных пользователей
    """
    # задаем название таблицы
    __tablename__ = 'user'
    # идентификатор пользователя, первичный ключ
    id = sa.Column(sa.Integer, primary_key=True)
    # имя пользователя
    first_name = sa.Column(sa.Text)
    # фамилия пользователя
    last_name = sa.Column(sa.Text)
    # пол атлета
    gender = sa.Column(sa.Text)
    # адрес электронной почты пользователя
    email = sa.Column(sa.Text)
    # дата рождения
    birthdate = sa.Column(sa.Text)
    # рост
    height = sa.Column(sa.REAL)

class Athelete(Base):
    """
    Описывает структуру таблицы user для хранения регистрационных данных пользователей ("id" integer primary key autoincrement, "age" integer,"birthdate" text,"gender" text,"height" real,"name" text,"weight" integer,"gold_medals" integer,"silver_medals" integer,"bronze_medals" integer,"total_medals" integer,"sport" text,"country" text)
    """
    # задаем название таблицы
    __tablename__ = 'athelete'
    # идентификатор пользователя, первичный ключ
    id = sa.Column(sa.Integer, primary_key=True)
    # возраст атлета
    age = sa.Column(sa.Integer)
    # дата рождения
    birthdate = sa.Column(sa.Text)
    # пол атлета
    gender = sa.Column(sa.Text)
    # рост
    height = sa.Column(sa.REAL)
    # вес
    # имя пользователя
    name = sa.Column(sa.Text)
    weight = sa.Column(sa.Integer)
    # кол-во медалей
    gold_medals = sa.Column(sa.Integer)
    silver_medals = sa.Column(sa.Integer)
    bronze_medals = sa.Column(sa.Integer)
    total_medals = sa.Column(sa.Integer)
    # вид спорта
    sport = sa.Column(sa.Text)
    # страна
    country = sa.Column(sa.Text)

def connect_db():
    """
    Устанавливает соединение к базе данных, создает таблицы, если их еще нет и возвращает объект сессии
    """
    # создаем соединение к базе данных
    engine = sa.create_engine(DB_PATH)
    # создаем описанные таблицы
    Base.metadata.create_all(engine)
    # создаем фабрику сессию
    session = sessionmaker(engine)
    # возвращаем сессию
    return session()

def is_date(date):
    '''
    # Функция принимает на вход строку с датой
    # Возвращает True, еслли дата корректна, False если не корректна
    # Для примера возьмём дату "1995-04-30"
    '''
    # Разбиваем дату разделителем "-", фукнция split возвращает список
    # Если дата корректна, список будет вида ["YYYY","MM","DD"]
    date_splitted = date.split("-")
    # Для начала, длина списка должна быть равной 3
    if len(date_splitted) == 3:
        # Теперь запишем в переменные year, month, day элементы списка date_splitted
        year, month, day = date_splitted
        # Теперь просто проверим, что строка с годом имеет длину 4, строки с месяцем и днём длину 2
        if len(year) == 4 and len(month) == 2 and len(day)==2 and int(month) < 13 and int(month) > 0 and int(day) > 0 and int(day) < 32:
            # Дата нам подходит
            return True
        else:
            # Иначе дата нам не подходит
            return False
    else:
        # Иначе дата не подходит
        return False

def request_data():
    """
    Запрашивает у пользователя данные и добавляет их в список users
    """
    # выводим приветствие
    print("Привет! Введите данные:")
    # запрашиваем у пользователя данные
    first_name = input("Введи имя: ")
    last_name = input("Введи фамилию: ")
    gender = input("Введите пол: ")
    email = input("Введите адрес электронной почты: ")
    # дата рождения
    while True:
        birthdate = input("Введите дату рождения в формате YYYY-MM-DD: ")
        if is_date(birthdate) == True:
            break
        else:
            print("Неверный формат даты")
    # рост
    height = input("Введите рост в формате М.СС: ")
    # создаем нового пользователя
    user = User(
        first_name=first_name,
        last_name=last_name,
        gender=gender,
        email=email,
        birthdate=birthdate,
        height=height
    )
    # возвращаем созданного пользователя
    return user

def find_user(user_id):
    # Создадим сессию
    session = connect_db()
    # Сделаем запрос
    user = session.query(User).filter(User.id == user_id).first()
    # Закроем сессию
    session.close()
    # Возращаем пользователя
    return user

def find_by_height(user_height):
# Функция, которая принимает как аргумент рост юзера
# Возвращает атлета с минимальной разницей в росте с юзером
    # Создадим сессию
    session = connect_db()
    # отфильтруем атлетов с ростом
    atheletes = session.query(Athelete).filter(Athelete.height > 0).all()
    # Закроем сессию
    session.close()
    # Переменная candidate - это атлет-кандидатю. У кандидата минимальная разница в росте с юзером
    # Пусть сначала кандидатом будет первый атлет
    candidate = atheletes[0]

    # В цикле пройдем по атлетам
    for athelete in atheletes:
        # Посчитаем разницу роста кандидата и юзера
        candidate_diff = abs(candidate.height - user_height)
        # Теперь посчитаем разницу роста для текущего атлета и юзера
        athelete_diff = abs(athelete.height - user_height)

        # Если у текущего атлета разница в росте меньше чем у кандидата
        if athelete_diff < candidate_diff:
            # То теперь этот атлет и есть новый кандидат
            candidate = athelete

    # Теперь когда мы просмотрели всех атлетов
    # У кандидата минимальная разница в росте с юзером
    # Поэтому вернем его
    return candidate

# Функция, которая возвращает разность дат
def date_diff(date_1, date_2):
    # Преобразуем строку date_1 в объект datetime
    datetime_1 = datetime.strptime(date_1, "%Y-%m-%d")
    # Аналогично для второй даты
    datetime_2 = datetime.strptime(date_2, "%Y-%m-%d")
    # Считаем модуль разности дат
    diff = abs(datetime_1-datetime_2)
    # Возращаем разность
    return diff

def find_by_date(user_birthdate):
# Поиск по дате рождения
    session = connect_db()
    atheletes1 = session.query(Athelete).all()
    session.close()
    candidate1 = atheletes1[0]

    # В цикле пройдем по атлетам
    for athelete1 in atheletes1:
        diff_age = date_diff(candidate1.birthdate, user_birthdate)
        diff_age_a = date_diff(athelete1.birthdate, user_birthdate)
        if diff_age > diff_age_a:
            candidate1 = athelete1
    return candidate1

def main():
    session = connect_db()
    mode = input("Выбери режим.\n1 - ввести нового пользователя\n2 - поиск в базе атлетов по номеру пользователя\n")
    if mode == "2":
        # выбран режим поиска, запускаем его
        user_id = int(input("Введите ID пользователя: "))
        # Находим юзера по ID
        user = find_user(user_id)
        if user_id:
            # Вызовем фукнцию, чтобы найти атлета с минимальной разницей по росту
            athelete_close_height = find_by_height(user.height)
            # Вызовем функцию поиска атлета по дате рождения
            athelete_close_birthdate = find_by_date(user.birthdate)
            # Выведем результат
            print(f'Найден пользователь {user.id}: {user.first_name} {user.last_name}. Рост - {user.height}, дата рождения - {user.birthdate}.')
            print("Ближайший по росту атлет: {} {}".format(athelete_close_height.name, athelete_close_height.height))
            print("Ближайший по дате рождения атлет: {} {}".format(athelete_close_birthdate.name, athelete_close_birthdate.birthdate))
        else:
            print("Пользователь с таким ID не найден")
    elif mode == "1":
        # запрашиваем данные пользоватлея
        user = request_data()
        # добавляем нового пользователя в сессию
        session.add(user)
        # сохраняем все изменения, накопленные в сессии
        session.commit()
        print("Спасибо, данные сохранены!")
    else:
        print("Некорректный режим:(")

if __name__ == "__main__":
    main()


# from os.path import dirname
import urllib.request
import base64
import argparse
import os.path

key = "<your api key>"

parser = argparse.ArgumentParser(description="Shrink PNGs with TinyPNG")
parser.add_argument("input", type=argparse.FileType("rb"), help="input PNG")
args = parser.parse_args()

request = urllib.request.Request("https://api.tinypng.com/shrink", args.input.read())

cafile = None
# Uncomment below if you have trouble validating our SSL certificate.
# Download cacert.pem from: http://curl.haxx.se/ca/cacert.pem
# cafile = dirname(__file__) + "/cacert.pem"

auth = base64.b64encode(bytes("api:" + key, "ascii")).decode("ascii")
request.add_header("Authorization", "Basic %s" % auth)

response = urllib.request.urlopen(request, cafile = cafile)
if response.status == 201:
  # Compression was successful, retrieve output from Location header.
  result = urllib.request.urlopen(response.getheader("Location"), cafile = cafile).read()

  # Rename original file
  orig_path = args.input.name
  rename_path = orig_path
  args.input.close()

  while True:
    try:
      rename_path_split = os.path.splitext(rename_path)
      rename_path = rename_path_split[0] + "_orig" + rename_path_split[1]
      os.rename(orig_path, rename_path)
      break
    except FileExistsError:
      print("File exist")

  # Name the new one as the original
  open(orig_path, "wb").write(result)

else:
  # Something went wrong! You can parse the JSON body for details.
  print("Compression failed")
  input("Press enter to continue")


from Queues import *
from Account import *
import json
import ConfigParser
import couchdb
import ast
import Pyro4
import random
import logging

__author__ = 'Stian Stroem Anderssen'

class Config:
    """
    This module aims to build and keep track of the manager objet during runtime. Every time a user creation is
    requested. This module is called.
    """
    queue_name = ""
    scriptpath = ""
    interval = 0
    configdbname = ""
    dbserver = ""
    queserver = ""
    configinstance = "None"
    account = Account()
    interpreterserver = Pyro4.Proxy("PYRONAME:interpreter")

    @staticmethod
    def convert_json_to_dictionary(self, data):
        """
        A function to convert JSON contents to a dict.
        :param data:
        :type data:
        :return:
        :rtype:
        """
        jsondict = json.loads(data)[0]
        return jsondict

    @staticmethod
    def request_user_creation(self, configobject):
        """
        Build dictionary containtaining courseinformation that is sent to the interpreter based on the content of the
        config object.
        :param configobject:
        :type configobject:
        :return listtosend:
        :rtype list:
        """
        listtosend = []
        teacherdict = {"teacher": [configobject.get_account().get_teacher()]}
        listtosend.append(teacherdict)
        semesterdict = {"semester": [configobject.get_account().get_semester()]}
        listtosend.append(semesterdict)
        coursedict = {"course": [configobject.get_account().get_course()]}
        listtosend.append(coursedict)
        groupsdict = {}
        groupsandmembers = configobject.get_account().get_groups()
        tempdict = groupsandmembers[0]
        groupsdict.update({"groups": tempdict})
        listtosend.append(groupsdict)
        return listtosend

    @staticmethod
    def send_users_to_queue(self, accountlist):
        """
        OUTDATED- This function converts the accountlist to a string that can be sent over a queue.
        :param accountlist:
        :type accountlist:
        :return:
        :rtype:
        """
        listtostring = accountlist
        queue = Queues()
        queue.create_queue("createuserq", str(listtostring))

    @staticmethod
    def find_groupnames(self, grouplist):
        """
        Return a list of the groupnames
        :param grouplist:
        :type grouplist:
        :return groupnames:
        :rtype:
        """
        groupnames = []
        for i, j in grouplist[0].iteritems():
            groupnames.append(i)
        return groupnames

    def write_config(self, configdata):
        """
        Write config from the database to the config.ini file
        :param configdata:
        :type configdata:
        :return:
        :rtype:
        """
        for key, value in configdata.iteritems():
            self.write_to_file(key, str(value))

    @staticmethod
    def write_to_file(self, key, value):
        """
        Write config to config.ini
        :param key:
        :type key:
        :param value:
        :type value:
        :return:
        :rtype:
        """
        with open('/root/uptime_challenge_master/manager/config.ini', 'r') as f:
            words = f.read().split()
            if key in words:
                logging.info("No need to write to file, key is present")
            else:
                file = open('/root/uptime_challenge_master/manager/config.ini', 'a')
                file.write(key + " = " + value + "\n")

    def read_config_from_file(self):
        """
        Read static config provided in config.ini and build an account object.
        :return configclass:
        :rtype Config:
        """
        config = ConfigParser.SafeConfigParser()
        config.read("/root/uptime_challenge_master/manager/config.ini")
        configclass = Config()
        configclass.set_account(self.account)
        configclass.get_account().set_course(config.get("Account", "course"))
        configclass.get_account().set_groups(json.loads(config.get("Account", "groups")))
        configclass.get_account().set_teacher(config.get("Account", "teacher"))
        configclass.get_account().set_semester(config.get("Account", "semester"))
        configclass.set_config_dbname(config.get("Global", "configdbname"))
        configclass.set_script_path(config.get("Global", "scriptpath"))
        configclass.set_dbserver(config.get("Global", "dbserver"))
        configclass.set_queserver(config.get("Global", "queueserver"))
        return configclass

    def init_db_config(self):
        """
        Build the final config object after the DbConfig is initialized along with the local config
        :return config :
        :rtype Config:
        """
        config = self.initiate_users()
        configdict = self.interpreterserver.fetchConfig(config.get_account().get_teacher())
        # self.write_config(configdict)
        configparser = ConfigParser.SafeConfigParser()
        configparser.read("/root/uptime_challenge_master/manager/config.ini")
        config.set_interval(configparser.get("Global", "interval"))
        config.set_queue_name(configparser.get("Global", "queue_name"))
        return config

    @staticmethod
    def create_user_list(self, usersdictlist):
        userlist = []
        for userdict in usersdictlist:
            userlist.append(userdict["group"])
        return userlist

    def initiate_users(self):
        usersdictlist = self.interpreterserver.getEnabledUsers()
        config = ConfigParser.SafeConfigParser()
        config.read("/root/uptime_challenge_master/manager/config.ini")
        userlist = self.create_user_list(usersdictlist)
        configclass = Config()
        configclass.set_account(self.account)
        configclass.get_account().set_course(config.get("Account", "course"))
        configclass.get_account().set_teacher(config.get("Account", "teacher"))
        configclass.get_account().set_semester(config.get("Account", "semester"))
        configclass.get_account().set_groups(userlist)
        configclass.set_config_dbname(config.get("Global", "configdbname"))
        configclass.set_script_path(config.get("Global", "scriptpath"))
        configclass.set_dbserver(config.get("Global", "dbserver"))
        configclass.set_queserver(config.get("Global", "queueserver"))
        return configclass

    @staticmethod
    def create_work_queue(self, queuename, joblist):
        """
        Function to create a workqueue that is used to put jobs on
        :param queuename:
        :type String:
        :param joblist:
        :type list:
        :return:
        :rtype:
        """
        queue = Queues()
        for group, job in joblist.iteritems():
            for j in job:
                jobdict = {}
                jobdict.update({group: j})
                queue.create_queue(queuename, jobdict)

    def get_queue_name(self):
        """
        Return queue_name
        :return:
        :rtype:
        """
        return self.__queue_name

    def get_interval(self):
        """
        Rrturn interval used in the dbconfig
        :return:
        :rtype:
        """
        return self.__interval

    def set_config_dbname(self, value):
        """
        Set the dbname of the couchdb
        :param value:
        :type value:
        :return:
        :rtype:
        """
        self.configdbname = value

    def get_config_dbname(self):
        """
        Get the dbname of the couchdb.
        :return:
        :rtype:
        """
        return self.configdbname

    def set_queue_name(self, value):
        """
        Set queuename to be used
        :param value:
        :type value:
        :return:
        :rtype:
        """
        self.__queue_name = value

    def get_account(self):
        """
        Return accountobject.
        :return:
        :rtype:
        """
        return self.account

    def set_account(self, a):
        """
        Set accountobject
        :param a:
        :type a:
        :return:
        :rtype:
        """
        self.account = a

    def set_interval(self, value):
        """
        Set interval
        :param value:
        :type value:
        :return:
        :rtype:
        """
        self.__interval = value

    def get_dbserver(self):
        """
        Return dbservername
        :return:
        :rtype:
        """
        return self.__dbserver

    def get_queserver(self):
        """
        Return queueservername
        :return:
        :rtype:
        """
        return self.__queserver

    def set_dbserver(self, value):
        """
        set dbservername
        :param value:
        :type value:
        :return:
        :rtype:
        """
        self.__dbserver = value

    def set_queserver(self, value):
        """
        set queueserver name
        :param value:
        :type value:
        :return:
        :rtype:
        """
        self.__queserver = value

    def set_config_instance(self, value):
        """
        Set the configobject before the database config is applied. This is used instead of using a global variable

        :param value:
        :type value:
        :return:
        :rtype:
        """
        self.configinstance = value

    def get_config_instance(self, value):
        """
        Return the config class object.
        :param value:
        :type value:
        :return:
        :rtype:
        """
        return self.configinstance

    def get_script_path(self):
        """
        Return the path to the executable location of the test on the LeeshoreWorker.
        :return:
        :rtype:
        """
        return self.scriptpath

    def set_script_path(self, path):
        """
        Set the script path on the LeeshoreWorker.
        :param path:
        :type path:
        :return:
        :rtype:
        """
        self.scriptpath = path

    @staticmethod
    def function(self, x):
        return -0.25 * x ** 2 + 50

    @staticmethod
    def derived_off_function(self, x):
        return -0.5 * x

    def return_load(self, x):
        answer = []
        load = self.function(x)
        derivative = self.derived_off_function(x)
        answer.append(float(load))
        answer.append(float(derivative))
        return answer


from turtle import pd
import numpy as np
import matplotlib.pyplot as plt
import  pandas as pd
# Import the MarkovChain class from markovchain.py
from markovchain import MarkovChain
import random as random

# P = np.array([[0.8, 0.2], [0.1, 0.9]]) # Transition matrix
# mc = MarkovChain(P, ['1', '2'])
# mc.draw()

# Gambling simulation
def gamblers_ruin():
    gambling_money = 50
    gambling_goal = 100
    gambling_simulations = []

    while gambling_money in range(1,gambling_goal):
        bet_size = 1
        w_or_l = random.randrange(-1,2,2)
        gambling_money+= bet_size * w_or_l
        gambling_simulations.append(gambling_money)
    return gambling_simulations

# Plotting Gambling Simulation
plt.plot(gamblers_ruin())
plt.yticks(np.arange(-20,120,10))
plt.axhline(y=0,color="red",linestyle ="-")
plt.axhline(y=100,color="black",linestyle ="-")
plt.xlabel("Numer of bets")
plt.ylabel("Winnings")
plt.title("Gambling Simulation")

# Probability of Ruin
def prob_of_ruin(gambling_goal, initial_gambling_money):
    return (gambling_goal - initial_gambling_money)/gambling_goal

prob_of_ruin(100,50)

sim_list = []
while len(sim_list) < 500:
    sim_list.append(gamblers_ruin()[-1])
np.mean(sim_list)

# Markov Chain Simulation
example = {
    "NYC":    [.25,0,.75,1],
    "Paris" : [.25,.25,0,0],
    "Cairo" : [.25,.25,.25,0],
    "Seoul" : [.25,.50,0,0]
}

markov_chain = pd.DataFrame(data=example,index = ["NYC","Paris","Cairo","Seoul"])
markov_chain

markov_chain_image  =  MarkovChain(markov_chain.to_numpy(), markov_chain.columns.tolist() )
# markov_chain_image.draw("./markov_chain.png")

# simulation for 25 times
travel_sim = []
travel_sim.append(markov_chain.iloc[0].index[0])
city = np.random.choice(markov_chain.iloc[0].index,p=markov_chain.iloc[0])
travel_sim.append(city)

while len(travel_sim) < 25:
    city = np.random.choice(markov_chain.iloc[markov_chain.index.get_loc(city)].index,p=markov_chain.iloc[markov_chain.index.get_loc(city)])
    travel_sim.append(city)

travel_sim

# n Step Transition Matrix

markov_chain.to_numpy();
def matrix_power(matrix,power):
    if power == 0:
        return np.identity(len(matrix))
    elif power == 1:
        return matrix
    else:
        return np.dot(matrix,matrix_power(matrix,power-1))

matrix_power(markov_chain,3)

# steady State Matrix

for i in range (1,10,1):
    print(f'n step transition matrix at the nth power {i}\n',matrix_power(markov_chain,i),'\n')

# starting from a state where will it be in the next n steps

initial_dist = np.asarray([1,0,0,0])
mcp2 = matrix_power(markov_chain.to_numpy(),2)
np.dot(initial_dist,mcp2)


import unittest
import torch

from utils import read_py_config, build_model, check_file_exist

class ExportError(Exception):
    pass

class TestONNXExport(unittest.TestCase):
    def setUp(self):
        config = read_py_config('./configs/config.py')
        self.config = config
        self.model = build_model(config, device='cpu', strict=True, mode='convert')
        self.img_size = tuple(map(int, config.resize.values()))
    def test_export(self):
        try:
            # input to inference model
            dummy_input = torch.rand(size=(1, 3, *(self.img_size)), device='cpu')
            self.model.eval()
            torch.onnx.export(self.model, dummy_input, './mobilenetv3.onnx', verbose=False)
            check_file_exist('./mobilenetv3.onnx')
        except ExportError:
            self.fail("Exception raised while exporting to ONNX")

if __name__ == '__main__':
    unittest.main()


from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QFileDialog
from os import getcwd

class OptionsDialogFunctions(QObject):
    saveSettingsRequest = pyqtSignal(dict)

    def __init__(self, widget, ui, settings):
        super(OptionsDialogFunctions, self).__init__(widget.parent())
        self.ui = ui
        self.widget = widget
        self.settings = settings

    def showOptionsDialog(self):
        self.init()
        self.widget.exec_()

    def init(self):
        self.setupConnections()
        self.applySettingsToUi()

    def setupConnections(self):
        self.ui.mainButtonBox.clicked["QAbstractButton*"].connect(self.mainButtonBoxClick)
        self.ui.addFolderButton.clicked.connect(self.addFolderButtonClicked)
        self.ui.deleteFolderButton.clicked.connect(self.deleteFolderButtonClicked)

    def applySettingsToUi(self):
        self.ui.maxThreadsSpinBox.setValue(int(self.settings["threads"]))
        if "library" in self.settings and self.settings["library"] is not None:
            self.ui.folderListWidget.addItems(self.settings["library"])

    def saveNewSettings(self):
        self.settings["threads"] = self.ui.maxThreadsSpinBox.value()
        self.settings["library"] = []
        for x in range(self.ui.folderListWidget.count()):
            self.settings["library"].append(self.ui.folderListWidget.item(x).text())
        self.saveSettingsRequest.emit(self.settings)

    def mainButtonBoxClick(self, button):
        if button.text() == "Save":
            self.saveNewSettings()
            self.widget.accept()
        elif button.text() == "Cancel":
            self.widget.close()
        elif button.text() == "Restore Defaults":
            pass

    def addFolderButtonClicked(self):
        filedialog = QFileDialog()
        filedialog.setAcceptMode(QFileDialog.AcceptOpen)
        filedialog.setFileMode(QFileDialog.DirectoryOnly)
        filedialog.setViewMode(QFileDialog.Detail)
        parent = self.widget
        caption = "Select directory to scan for movies in..."
        startdir = getcwd()
        options = QFileDialog.ShowDirsOnly
        selecteddir = filedialog.getExistingDirectory(parent, caption, startdir, options)
        self.ui.folderListWidget.addItem(selecteddir)

    def deleteFolderButtonClicked(self):
        selected_folder_index = self.ui.folderListWidget.currentRow()
        self.ui.folderListWidget.takeItem(selected_folder_index)


import time
import datetime
import numpy as np
from app.utils import utils
from app.utils.portfolio import Portfolio
from app.usecases.get_recommended_weights import get_recommended_weights
from app.usecases.get_simulation_hull import get_simulation_hull
from app.models.sector import GICS_DATA
from dateutil.relativedelta import relativedelta

def portfolio_response(p, f=None, t=None):
    (asset, amount, weight, recommended_weight, capital_gain, dividends) = p

    today_date = datetime.datetime.today()
    today_year = today_date.year
    today_date = today_date.date().isoformat()
    back_date = datetime.datetime.today() + relativedelta(years=-3)
    back_year = back_date.year
    back_date = back_date.date().isoformat()

    return {
        'asset_id': int(asset.id),
        'asset_type': asset.asset_type,
        'ticker': asset.ticker,
        'amount': int(amount),
        'ch': asset.ch(today_year, today_year),
        'ry': [0, asset.ry(back_date, today_date), 0],
        'dy': [0, asset.dy(back_date, today_date), 0],
        'yy': asset.yy(back_year, today_year),
        'tv': int(amount) * asset.adjusted_close_price(),
        'p': asset.adjusted_close_price(),
        'cg': capital_gain,
        'divs': dividends,
        'tr': capital_gain + dividends,
        'country': asset.country,
        'sector': asset.sector,
        'weight': weight,
        'recommended_weight': recommended_weight,
        'updated_at': asset.updated_at,
    }

def get_portfolio(account_id, portfolio_id, f=None, t=None):
    assets, quantities = utils.get_portfolio_asset_quantities(account_id, portfolio_id)

    portfolio_data = utils.get_portfolio_data(account_id, portfolio_id)
    weights = utils.weights(assets, quantities)

    # gics
    gics = [asset.sector for asset in assets if asset._asset_type == 'stock']
    gics_aggs = {k: 0.0 for k in GICS_DATA.keys()}
    for (gics, weight) in list(zip(gics, weights)):
        if gics in GICS_DATA.keys():
            gics_aggs[gics] += weight

    # gics_aggs = sorted(gics_aggs.items(), key=lambda x: -x[1])
    gics_aggs = list(gics_aggs.items())

    # benchmarks
    voo = utils.get_asset('VOO')
    vt = utils.get_asset('VT')
    imoex = utils.get_asset('IMOEX')

    portfolio = Portfolio(assets, weights)

    recommended_weights = get_recommended_weights(assets)
    # target = Portfolio(assets, recommended_weights)

    portfolio_actions = utils.get_portfolio_actions(account_id, portfolio_id)
    portfolio_actions = sorted(portfolio_actions, key=lambda item: item['action_date'])

    capital_gain = utils.get_portfolio_capital_gain(account_id, portfolio_id)
    dividends = utils.get_portfolio_dividends(account_id, portfolio_id)

    assets_data = list(zip(
        assets, quantities, weights, recommended_weights, capital_gain, dividends
    ))
    assets_data_response = list(map(portfolio_response, assets_data))

    today_date = datetime.datetime.today()
    today_year = today_date.year
    today_date = today_date.date().isoformat()
    back_date = datetime.datetime.today() + relativedelta(years=-3)
    back_year = back_date.year
    back_date = back_date.date().isoformat()

    return {
        'portfolioData': {
            'name': portfolio_data.name,
            'ch': portfolio.ch(today_year),
            'r': portfolio.ry(back_date, today_date),
            'd': portfolio.dy(back_date, today_date),
            'y': portfolio.yy(back_year, today_year),
            'u': utils.utility(assets, weights),
            'or': utils.total_return(assets, recommended_weights),
            'od': utils.stdev(assets, recommended_weights),
            'oy': utils.total_yield(assets, recommended_weights),
            'ou': utils.utility(assets, recommended_weights),
            'tv': utils.total_value(assets, quantities),
            'tcg': int(np.sum(list(capital_gain))),
            'td': int(np.sum(list(dividends))),
            'gics_data': gics_aggs,  # TODO: maybe extract
            'simulation_hull': get_simulation_hull(assets),  # TODO: extract
        },
        'assetData': assets_data_response,
    }


import serial
import re
import math
from openpyxl import *

# To get the relative data from the data

def get_data(getdata_data,baseline):
    getdata_result = [0] * 9
    for i in range(9):
        getdata_result[i] = abs(float(getdata_data[i]) - float(baseline[i])) / float(baseline[i])
    return getdata_result

#  To know whether the pad is touched

def whether_touched(touched_data):

    touched_result = False
    for i in range(len(touched_data)):
        if touched_data[i] > 0.02:
            touched_result = True
            break
    return touched_result

# To get the position of the touch point

def get_position(rawdata, baseline):

    #  Get the initial data
    data = [0] * 9
    for i in range(9):
        data[i] = abs(float(rawdata[i]) - float(baseline[i])) / float(baseline[i])

    '''
    Get the position of the touch
    If it is not touched, give it [11,11]
    If it is touched by two finger, give it [0,0]
    '''
    position = [11, 11]

    if whether_touched(data) is False:
        return position

    costx = 0
    costy = 0
    mincostx = 10000
    mincosty = 10000
    x = 0.0
    y = 0.0

    while x <= 10:
          costx = data[8] * pow(0.0 - x, 2) + \
                data[7] * pow(3.3 - x, 2) + \
                data[6] * pow(6.6 - x, 2) + \
                data[5] * pow(10.0 - x, 2)

          if costx < mincostx:
              mincostx = costx
              position[0] = x
          x = x + 0.02

    while y <= 10:
        costy = data[4] * pow(0.0 - y, 2) + \
                data[3] * pow(2.5 - y, 2) + \
                data[2] * pow(5.0 - y, 2) + \
                data[1] * pow(7.5 - y, 2) + \
                data[0] * pow(10.0 - y, 2)
        if costy < mincosty:
            mincosty = costy
            position[1] = y
        y = y + 0.02

    return position

#  Gesture Recognition

def gesture_recognition(gesturerecognition_data):
    xMax = 0
    xMin = 10
    yMax = 0
    yMin = 10
    for i in range(len(gesturerecognition_data)):
        xMax = max(xMax, gesturerecognition_data[i][0])
        xMin = min(xMin, gesturerecognition_data[i][0])
        yMax = max(yMax, gesturerecognition_data[i][1])
        yMin = min(yMin, gesturerecognition_data[i][1])
    xDis = xMax - xMin
    yDis = yMax - yMin

    '''
    Gesture protocal
    1---up
    2---down
    3---left
    4---right
    5---up-right
    6---down-right
    7---up-down
    8---down-up
    9---circle
    '''
    vertical_sum1 = 0
    vertical_sum2 = 0
    vertical_sum3 = 0
    vertical_sum4 = 0
    vertical_sum5 = 0

    horizontal_sum1 = 0
    horizontal_sum2 = 0
    horizontal_sum3 = 0
    horizontal_sum4 = 0
    horizontal_sum5 = 0

    up_right_sum = 0
    down_right_sum = 0
    circle_sum = 0

    for single_position in gesturerecognition_data:

        vertical_sum1 = vertical_sum1 + pow(single_position[0] - 1, 2)
        vertical_sum2 = vertical_sum2 + pow(single_position[0] - 3, 2)
        vertical_sum3 = vertical_sum3 + pow(single_position[0] - 5, 2)
        vertical_sum4 = vertical_sum4 + pow(single_position[0] - 7, 2)
        vertical_sum5 = vertical_sum5 + pow(single_position[0] - 9, 2)

        horizontal_sum1 = horizontal_sum1 + pow(single_position[1] - 1, 2)
        horizontal_sum2 = horizontal_sum2 + pow(single_position[1] - 3, 2)
        horizontal_sum3 = horizontal_sum3 + pow(single_position[1] - 5, 2)
        horizontal_sum4 = horizontal_sum4 + pow(single_position[1] - 7, 2)
        horizontal_sum5 = horizontal_sum5 + pow(single_position[1] - 9, 2)

        up_right_sum = up_right_sum + pow(single_position[0] - single_position[1], 2) / 2
        down_right_sum = down_right_sum + pow(single_position[0] + single_position[1] - 10, 2) / 2

        circle_sum = circle_sum + pow(math.sqrt(pow(single_position[0] - 5, 2)
                                                + pow(single_position[1] - 5, 2)) - 2.5, 2)

    threshold = 5

    if xDis < threshold and yDis < threshold:
        return 0

    if xDis < threshold or yDis < threshold:

        min_sum = min(vertical_sum1, vertical_sum2, vertical_sum3, vertical_sum4, vertical_sum5,
                  horizontal_sum1, horizontal_sum2, horizontal_sum3, horizontal_sum4, horizontal_sum5)

        if min_sum == vertical_sum1 or min_sum == vertical_sum2 or min_sum == vertical_sum3 or \
                        min_sum == vertical_sum4 or min_sum == vertical_sum5:

            if gesturerecognition_data[0][1] < threshold and gesturerecognition_data[-1][1] < threshold and \
                    gesturerecognition_data[int(len(gesturerecognition_data)/2)][1] > 7:
                return 7
            elif gesturerecognition_data[0][1] > threshold and gesturerecognition_data[-1][1] > threshold and \
                    gesturerecognition_data[int(len(gesturerecognition_data)/2)][1] < 3:
                return 8
            elif gesturerecognition_data[0][1] < gesturerecognition_data[-1][1]:
                return 1
            elif gesturerecognition_data[0][1] > gesturerecognition_data[-1][1]:
                return 2

        if min_sum == horizontal_sum1 or min_sum == horizontal_sum2 or min_sum == horizontal_sum3 or \
                        min_sum == horizontal_sum4 or min_sum == horizontal_sum5:
            if gesturerecognition_data[0][0] < gesturerecognition_data[-1][0]:
                return 4
            if gesturerecognition_data[0][0] > gesturerecognition_data[-1][0]:
                return 3
    else:
        min_sum = min(up_right_sum, down_right_sum, circle_sum)
        if min_sum == up_right_sum:
            if gesturerecognition_data[0][0] < gesturerecognition_data[-1][0]:
                return 5
        if min_sum == down_right_sum:
            if gesturerecognition_data[0][0] < gesturerecognition_data[-1][0]:
                return 6
        if min_sum == circle_sum:
            return 9

    return 0
    '''
    Gesture recognition algorithm with the data feature
    '''
    # if abs(gesturerecognition_data[0][0] - gesturerecognition_data[-1][0]) < 5:
    #     if abs(gesturerecognition_data[0][1] - gesturerecognition_data[-1][1]) < 5:
    #         if xDis > 5 and yDis > 5:
    #             return 9
    #
    # if gesturerecognition_data[0][1] < 5 and gesturerecognition_data[-1][1] < 5:
    #     if gesturerecognition_data[int(len(gesturerecognition_data)/2)][1] - gesturerecognition_data[0][1] > 5:
    #         return 7
    #
    # if gesturerecognition_data[0][1] > 5 and gesturerecognition_data[-1][1] > 5:
    #     if gesturerecognition_data[0][1] - gesturerecognition_data[int(len(gesturerecognition_data)/2)][1] > 5:
    #         return 8
    #
    # if xDis < 5:
    #     if yDis > 5:
    #         if gesturerecognition_data[-1][1] > gesturerecognition_data[0][1]:
    #             return 1
    #         if gesturerecognition_data[-1][1] < gesturerecognition_data[0][1]:
    #             return 2
    # if xDis > 5:
    #     if yDis < 5:
    #         if gesturerecognition_data[-1][0] > gesturerecognition_data[0][0]:
    #             return 4
    #         if gesturerecognition_data[-1][0] < gesturerecognition_data[0][0]:
    #             return 3
    #     if yDis > 5:
    #         if gesturerecognition_data[-1][1] > gesturerecognition_data[0][1]:
    #             return 5
    #         if gesturerecognition_data[-1][1] < gesturerecognition_data[0][1]:
    #             return 6
    # return 0

# Communication info
SERIAL_PORT = '/dev/cu.usbmodem1421'
COMMUNICATION_RATE = 115200
ser = serial.Serial(SERIAL_PORT, COMMUNICATION_RATE)

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip = '127.0.0.1'
port = 33335

sock_receive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_receive.setblocking(0)
port_receive = 33336
sock_receive.bind((ip, port_receive))

# find the baseline for all the keys
key_dic = {'a': 0, 'b': 11, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9,
           'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18,
           't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25, 'delete': 51, 'fn': 63}

all_key = ['0', '11', '8', '2', '14', '3', '5', '4', '34', '38', '40', '37', '46',
           '45', '31', '35', '12', '15', '1', '17', '32', '9', '13', '7', '16', '6', '51', '63']

# all_key = ['12','0','6']

base_array = []

# for scan_key in all_key:
#     ser.write(scan_key.encode('UTF-8'))
#     for i in range(10):
#         ser.readline()
#     baseline = re.findall(r"\d+", str(ser.readline(), encoding="utf-8"))
#     base_array.append(baseline)
#
# print("Baseline reading finished, data is as following:")
# for base_data in base_array:
#     print(base_data)

touched = False
previous_touched = False
read = True
data_list = []
gesture = 0
keyData = ''
baseline = [380, 360, 320, 370, 400, 405, 410, 420, 413]
status = False
previous_status = False
last_key = "NULL"
pressed = False
# Start the the data reading part
print("Please do gesture")

while True:

    # Get the original data
    try:
        raw_data_str = str(ser.readline(), encoding="utf-8")
        raw_data_array = re.findall(r"\d+", raw_data_str)
        # Get the touch position
        data = get_data(raw_data_array, baseline)
        position = get_position(raw_data_array, baseline)

        # Check whether the data should be added
        if pressed:
            if position != [11, 11]:
                data_list.append(position)
    except:
        continue

    try:
        if pressed == False:
            data_list = []

        keyData = sock_receive.recvfrom(4096)
        key = keyData[0].decode('UTF-8')

        if key == "-1":
            continue

        print(key)

        if key == "STOP":
            read = False
            continue
        elif key == "START":
            read = True
            continue

        if read is False:
            continue

        bkey = key.encode('UTF-8')
        # ser.flushInput()
        # ser.flushOutput()
        # print(key)
        # print(last_key)
        if last_key == "NULL":
            pressed = True
            ser.write(bkey)
            last_key = key

        elif last_key == key:
            last_key = "NULL"
            # print("pressed")
            pressed = False
            if len(data_list) > 2:
                print("--------------NEW GESTURE---------------")
                print("KEY NUM ---"+key)
                del data_list[0]
                del data_list[0]
                del data_list[0]
                del data_list[0]
                gesture = gesture_recognition(data_list)
                print("GESTURE ---" + str(gesture))
                try:
                    sock.sendto(bytes(int(gesture)), (ip, port))
                except:
                    print("error")
            # print(data_list)
            data_list = []
    except socket.error:
        continue


#! /usr/bin/env python
# coding: utf-8

import json, random
from flask import Flask, render_template, request

from . import constant as const
from gpbapp.classes import LocationSearch, Parser
from gpbapp.function import infos_wikipedia

app = Flask(__name__)

@app.route('/')
@app.route('/index/')
def index():
    return render_template('index.html', API_KEY=const.API_KEY)

@app.route('/search', methods=['GET'])
def search():
    phrase = request.args.get('phrase')

    data = Parser()
    geolocation = LocationSearch(const.API_KEY)

    # cuts the sentence into words
    data_user = data.split_word(phrase)
    phrase_parser = data.util_word(data_user)
    complete_string = " ".join(phrase_parser)

    # Look for the place
    prediction = geolocation.place_prediction(complete_string)

    if not prediction:
        details = "Lieu non trouver"
        history = "La page n'existe pas"
    else:
        details = geolocation.places_search(prediction['description'])

        if not infos_wikipedia(complete_string):
            address_for_wiki = data.address(details['formatted_address'])

            if not infos_wikipedia(address_for_wiki):
                history = "La page n'existe pas"

            else:
                history = infos_wikipedia(address_for_wiki)

        else:
            history = infos_wikipedia(complete_string)

    return json.dumps({
        'status': 'OK',
        'result': details,
        'history': history,
        'story': random.choice(const.STORY)
        })

if __name__ == "__main__":
    app.run()


import math
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Callable

def print_header():
    print("Задание #4_2. Приближённое вычисление интеграла по квадратурным формулам\n")

def get_input(value_name: str, msg: str, default_value: float) -> float:
    try:
        value = float(input(f">>> Введите {msg} {value_name}="))
    except ValueError:
        value: float = default_value
        print(f"Оставлено значение {value_name} по умолчанию;   {value_name}={default_value}")
    return value

@dataclass
class Method(ABC):
    name: str

    @staticmethod
    @abstractmethod
    def calculate(f: Callable, a: float, b: float) -> float:
        pass

@dataclass
class LeftRectangle(Method):
    name: str = "КФ левого прямоугольника"

    @staticmethod
    def calculate(f: Callable, a: float, b: float) -> float:
        return (b - a) * f(a)

@dataclass
class RightRectangle(Method):
    name: str = "КФ правого прямоугольника"

    @staticmethod
    def calculate(f: Callable, a: float, b: float) -> float:
        return (b - a) * f(b)

@dataclass
class MiddleRectangle(Method):
    name: str = "КФ среднего прямоугольника"

    @staticmethod
    def calculate(f: Callable, a: float, b: float) -> float:
        return (b - a) * f((a + b) / 2)

@dataclass
class Trapeze(Method):
    name: str = "КФ трапеции"

    @staticmethod
    def calculate(f: Callable, a: float, b: float) -> float:
        return ((b - a) / 2) * (f(a) + f(b))

@dataclass
class Simpson(Method):
    name: str = "КФ Симпсона"

    @staticmethod
    def calculate(f: Callable, a: float, b: float) -> float:
        return ((b - a) / 6) * (f(a) + 4 * f((a + b) / 2) + f(b))

@dataclass
class ThreeEighths(Method):
    name: str = "КФ 3/8"

    @staticmethod
    def calculate(f: Callable, a: float, b: float) -> float:
        h = (b - a) / 3
        return (b - a) * (f(a) + 3 * f(a + h) + 3 * f(a + 2 * h) + f(b)) / 8

def print_results(a: float, b: float, functions: [Callable, Callable, str], polynomials: [Callable, Callable, str]):
    print("――――――――――――――――――――――――――――――――――――――――――――――――")
    for function, integral, formula in polynomials + functions:
        print(f" Функция f(x) = {formula}")
        value_of_integral = integral(b) - integral(a)
        print(f" Точное значение интеграла: {value_of_integral:.8f}\n")
        for method in [LeftRectangle, RightRectangle, MiddleRectangle, Trapeze, Simpson, ThreeEighths]:
            print(f"   Метод: {method.name}")
            result = method.calculate(function, a, b)
            print(f"    Результат метода: {result:.8f}")
            print(f"    Абсолютная фактическая погрешность: {abs(value_of_integral - result):.8f}\n")
        print("――――――――――――――――――――――――――――――――――――――――――――――――")

def main():
    print_header()
    functions = [
        (lambda x: math.cos(x) * math.exp(math.sin(x)), lambda x: math.exp(math.sin(x)), 'cos(x) * e^(sin(x))'),
    ]
    polynomials = [
        (lambda x: 10, lambda x: 10 * x, '10'),
        (lambda x: 8.8 * x - 10, lambda x: 4.4 * x ** 2 - 10 * x, '8.8 * x - 10'),
        (lambda x: 3 * x ** 2 + 8.8 * x - 10, lambda x: x ** 3 + 4.4 * x ** 2 - 10 * x, '3 * x² + 8.8 * x - 10'),
        (
            lambda x: 16 * x ** 3 - 3 * x ** 2 + 8.8 * x - 10,
            lambda x: 4 * x ** 4 - x ** 3 + 4.4 * x ** 2 - 10 * x,
            '16 * x³ - 3 * x² + 8.8 * x - 10'
        ),
    ]
    a = get_input('A', 'нижний предел интегрирования', 0)
    b = get_input('B', 'верхний предел интегрирования', 1)
    print_results(a, b, functions, polynomials)
    try:
        while True:
            choice = input(">>> Напишите \"1\", если хотите ввести новые значения:   ")
            if choice == '1':
                a = get_input('A', 'нижний предел интегрирования', 0)
                b = get_input('B', 'верхний предел интегрирования', 1)
                print_results(a, b, functions, polynomials)
            else:
                print(f"Выход из программы...")
                break
    except Exception:
        print(f"Ошибка!\nВыход из программы...")
        return

if __name__ == '__main__':
    main()


from __future__ import annotations

import os
from enum import Enum, auto
from typing import List, Optional

from skytemple_files.common.types.data_handler import DataHandler
from skytemple_files.common.util import OptionalKwargs, read_bytes
from skytemple_files.compression_container.at3px.handler import At3pxHandler
from skytemple_files.compression_container.at4pn.handler import At4pnHandler
from skytemple_files.compression_container.at4px.handler import At4pxHandler
from skytemple_files.compression_container.atupx.handler import AtupxHandler
from skytemple_files.compression_container.base_handler import (
    CompressionContainerHandler,
)
from skytemple_files.compression_container.pkdpx.handler import PkdpxHandler
from skytemple_files.compression_container.protocol import CompressionContainerProtocol

class CommonAtType(Enum):
    AT4PN = auto(), At4pnHandler, True
    AT3PX = auto(), At3pxHandler, True
    AT4PX = auto(), At4pxHandler, True
    ATUPX = auto(), AtupxHandler, False
    PKDPX = auto(), PkdpxHandler, True

    def __new__(cls, *args, **kwargs):  # type: ignore
        obj = object.__new__(cls)
        obj._value_ = args[0]
        return obj

    # ignore the first param since it's already set by __new__
    def __init__(
        self, _: int, handler: CompressionContainerHandler, auto_allowed: bool
    ):
        self.handler = handler
        self.auto_allowed = auto_allowed

# Pre-built lists for compression
COMMON_AT_BEST_3 = [
    CommonAtType.AT4PN,
    CommonAtType.ATUPX,
    CommonAtType.AT3PX,
    CommonAtType.PKDPX,
]
COMMON_AT_BEST_4 = [
    CommonAtType.AT4PN,
    CommonAtType.ATUPX,
    CommonAtType.AT4PX,
    CommonAtType.PKDPX,
]
COMMON_AT_MUST_COMPRESS_3 = [CommonAtType.ATUPX, CommonAtType.AT3PX, CommonAtType.PKDPX]
COMMON_AT_MUST_COMPRESS_4 = [CommonAtType.ATUPX, CommonAtType.AT4PX, CommonAtType.PKDPX]
COMMON_AT_PKD = [CommonAtType.PKDPX]

DEBUG = False

class CommonAtHandler(DataHandler[CompressionContainerProtocol]):
    allowed_types = set()
    for t in CommonAtType:
        if t.auto_allowed:
            if t == CommonAtType.ATUPX:
                # For native handler:
                os.environ["SKYTEMPLE_ALLOW_ATUPX"] = "1"
            allowed_types.add(t)

    @classmethod
    def allow(cls, compression_type: CommonAtType):
        if compression_type == CommonAtType.ATUPX:
            # For native handler:
            os.environ["SKYTEMPLE_ALLOW_ATUPX"] = "1"
        cls.allowed_types.add(compression_type)
        if DEBUG:
            print("*** COMMON AT DEBUG: Allowed types =", cls.allowed_types)

    @classmethod
    def disallow(cls, compression_type: CommonAtType):
        try:
            # For native handler:
            cls.allowed_types.remove(compression_type)
            del os.environ["SKYTEMPLE_ALLOW_ATUPX"]
        except KeyError as ke:
            pass  # TODO, add warning
        if DEBUG:
            print("*** COMMON AT DEBUG: Allowed types =", cls.allowed_types)

    @classmethod
    def deserialize(
        cls, data: bytes, **kwargs: OptionalKwargs
    ) -> CompressionContainerProtocol:
        """Load a Common At container into a high-level representation"""
        for t in CommonAtType:
            if t.handler is not None:
                if t.handler.matches(data):
                    if DEBUG:
                        print("*** COMMON AT DEBUG: Opened =", t)
                    return t.handler.deserialize(data, **kwargs)
        raise ValueError(f"The provided data is not an AT container ({read_bytes(data, 0, 5)}).")  # type: ignore

    @classmethod
    def serialize(
        cls, data: CompressionContainerProtocol, **kwargs: OptionalKwargs
    ) -> bytes:
        """Convert the high-level AT representation back into a BitStream."""
        return data.to_bytes()

    @classmethod
    def compress(
        cls, data: bytes, compression_type: Optional[List[CommonAtType]] = None
    ) -> CompressionContainerProtocol:
        """Turn uncompressed data into a new AT container"""
        if compression_type is None:
            compression_type = COMMON_AT_BEST_4
        new_data: Optional[CompressionContainerProtocol] = None
        new_size = -1
        if DEBUG:
            print("*** COMMON AT DEBUG: Compress Start")
        for t in compression_type:
            if t in CommonAtHandler.allowed_types:
                try:
                    cont = t.handler.compress(data)  # pylint: disable=no-member
                    size = len(cont.to_bytes())
                    if DEBUG:
                        print("*** COMMON AT DEBUG: Compress", t, "size", size)
                    if new_data is None or size < new_size:
                        new_data = cont
                        new_size = size
                except:
                    pass
        if DEBUG:
            print("*** COMMON AT DEBUG: Compress End")
        if new_data is None:
            raise ValueError("No useable compression algorithm.")
        return new_data

    @classmethod
    def cont_size(cls, data: bytes, byte_offset=0):
        for t in CommonAtType:
            if t.handler.matches(data, byte_offset):
                return t.handler.cont_size(data, byte_offset)
        raise ValueError("The provided data is not an AT container.")

    @classmethod
    def matches(cls, data: bytes, byte_offset=0):
        """Check if the given data stream is an AT container"""
        for t in CommonAtType:
            if t.handler.matches(data, byte_offset):
                return True
        return False


# -*- coding: utf-8 -*-
# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.3.3
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

import os
import pandas as pd
from pandas_profiling import ProfileReport
from sklearn.decomposition import FactorAnalysis

# # import data - データの読み込み

# +
df_scores = pd.read_csv(os.path.join('..', 'data', '12_subject_scores.csv'))

display(df_scores.head())

display(df_scores.describe())
# -

# # See profile

profile = ProfileReport(df_scores, title='Pandas Profiling Report', html={'style':{'full_width':True}})

profile

# # Factor Analysis

# +
n_factors=3

fa = FactorAnalysis(n_components=n_factors, random_state=57)
fa.fit(df_scores)

# +
df_factor_loading = pd.DataFrame(fa.components_.T, columns=['factor_{}'.format(i) for i in range(n_factors)], index=df_scores.columns)

df_factor_loading
# -

# # compute Factor score

# +
# compose sample data
df_sample = pd.DataFrame(
    [
        [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,],
        [1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,],
        [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,],
        [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,],
    ],
    columns=df_scores.columns,
    index=['A', 'B', 'C', 'D']
)

df_sample

# +
factor_scores = fa.transform(df_sample)  # compute factor scores

pd.DataFrame(factor_scores, columns=['factor_{}'.format(i) for i in range(n_factors)], index=df_sample.index)
# -

049.factor analysis - 因子分析/factor analysis.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/4/21 23:57
# @Author  : cap669
# @File    : XJob.py
# @Software: PyCharm
import datetime
import traceback
from peewee import Model
from peewee import fn
from playhouse.pool import PooledPostgresqlDatabase
from root.base.wrapper.EvsWrapper import EvsWrapper
from root.utils.StateUtils import StateUtils
from root.utils.Utils import Utils
from typing import Any, List
from pydantic import BaseModel

class Job0Model(BaseModel):
    uid: str
    info: str
    ctime: datetime.datetime

class Job1Model(Job0Model):
    an: int
    en: int

class XHis0:
    def __init__(self, cur: Model, safe_table: bool, clear_table: bool, func):
        if safe_table:
            if cur.table_exists():
                if clear_table:
                    cur.truncate_table()
            else:
                cur.create_table()
        if func:
            func()
        self.cur = cur

class XJob0(XHis0):
    def __init__(self, cur: Model, db: PooledPostgresqlDatabase, safe_table: bool = True, clear_table: bool = False,
                 func: Any = None):
        XHis0.__init__(self, cur, safe_table, clear_table, func)
        self.db = db

    def adds(self, info: str, state: StateUtils):
        d0 = Job0Model(uid=Utils.f1(), info=info, ctime=Utils.u0())
        d1 = d0.dict()
        with self.db.atomic():
            e0 = self.cur.insert_many(d1).execute()
            if e0:
                state.succ(1)
            else:
                state.errn()
        return state

    def addc(self, data: List[Any], func: Any, state: StateUtils):
        ctime = Utils.u0()
        with self.db.atomic():
            try:
                d0 = [Job0Model(uid=Utils.f1(), ctime=ctime, info=func(d0)).dict() for d0 in data]
                self.cur.insert_many(d0) \
                    .on_conflict_ignore() \
                    .execute()
                state.succ(1, '')
            except:
                state.errn('')
        return state

    def comp(self, func, uid: str, state: StateUtils, msg: str = 'nuxx'):
        try:
            with self.db.manual_commit():
                d0 = self.cur.select().where(self.cur.uid == uid).for_update().get()
                sta: StateUtils = func()
                if sta.code == 1:
                    d0.fnsh = 4
                else:
                    d0.fnsh = 3
                d0.msg = msg
                d0.stime = Utils.u0()
                if d0.save():
                    state.succ(1, )
        except self.cur.DoesNotExist:
            state.errn('')
        return state

    def gets(self, aka: str, state: StateUtils, msg: str = 'nuxx'):
        uid, info = '', ''
        with self.db.atomic():
            try:
                d0 = self.cur.select().where(self.cur.fnsh == 1).limit(1).for_update().get()
                d0.rtime = Utils.u0()
                d0.fnsh = 2
                d0.msg = msg
                d0.aka = aka
                if d0.save():
                    state.succ(1)
                    uid = d0.uid
                    info = d0.info
                else:
                    state.errn()
            except self.cur.DoesNotExist:
                state.errn()

        return uid, info

    def outs(self, aka: str, state: StateUtils, msg: str = 'nuxx'):
        with self.db.atomic():
            try:
                d0 = self.cur.select().where((self.cur.fnsh == 2) & (self.cur.aka == aka)).for_update().get()
                d0.rtime = Utils.u0()
                d0.fnsh = 1
                if msg == 'nuxx':
                    msg = f'cur:{aka}'
                d0.msg = msg
                d0.aka = 'nuxx'
                if d0.save():
                    state.succ(1)
                else:
                    state.errn('')
            except self.cur.DoesNotExist:
                state.errn()

    def show(self):
        d0 = self.cur.select()
        bag = []
        if d0:
            for d1 in d0:
                d3 = d1.__data__
                bag.append(d3)
        return bag

class XJob1(XHis0):
    def __init__(self, cur: Model, db: PooledPostgresqlDatabase, safe_table: bool = True, clear_table: bool = False,
                 func: Any = None):
        XHis0.__init__(self, cur, safe_table, clear_table, func)
        self.db = db

    def adds(self, info: str, state: StateUtils, an: int = 0, en: int = 0):
        if an >= en:
            d0 = Job1Model(uid=Utils.f1(), info=info, an=an, en=en, ctime=Utils.u0())
            d1 = d0.dict()
            with self.db.atomic():
                e0 = self.cur.insert_many(d1).execute()
                if e0:
                    state.succ(1)
                else:
                    state.errn()
        else:
            state.errn()
        return state

    def comp(self, uid,func, state: StateUtils):
        with self.db.atomic():
            try:
                d0 = self.cur.select().where((self.cur.fnsh == 2) & (self.cur.uid == uid)).for_update().get()
                if d0.an > d0.en:
                    sta:StateUtils = func()
                    if sta.code == 1:
                        d0.rtime = Utils.u0()
                        d0.en = d0.en + 1
                        if d0.save():
                            state.succ(1)
                            if d0.an == d0.en:
                                d0.fnsh = 4
                                if d0.save():
                                    state.succ(2)
                                else:
                                    state.errn('')
                        else:
                            state.errn()
                    else:
                        state.errn('')
                else:
                    state.errn('')
            except:
                state.errn()

    def outs(self,aka:str,state:StateUtils,msg:str = 'nuxx'):
        with self.db.atomic():
            try:
                d0 = self.cur.select().where((self.cur.fnsh == 2) & (self.cur.aka == aka)).for_update().get()
                d0.rtime = Utils.u0()
                d0.fnsh = 1
                if msg == 'nuxx':
                    msg = f'cur:{aka}'
                d0.msg = msg
                d0.aka = 'nuxx'
                if d0.save():
                    state.succ(1)
                else:
                    state.errn('')
            except self.cur.DoesNotExist:
                state.errn()

    def gets(self, aka: str, state: StateUtils, msg: str = 'nuxx'):
        uid, info = '', ''
        with self.db.atomic():
            if aka:
                try:
                    d0 = self.cur.select().where((self.cur.fnsh == 2) & (self.cur.aka == aka)).for_update().get()
                    d0.rtime = Utils.u0()
                    d0.fnsh = 2
                    d0.msg = msg
                    d0.aka = aka
                    d0.save()
                    state.succ(1, '更具aka寻找任务')
                    uid = d0.uid
                    info = d0.info
                except self.cur.DoesNotExist:
                    state.errn()
            if state.code == 1:
                pass
            else:
                try:
                    d0 = self.cur.select().where(self.cur.fnsh == 1).for_update().get()
                    d0.rtime = Utils.u0()
                    d0.fnsh = 2
                    d0.msg = msg
                    d0.aka = aka
                    if d0.save():
                        state.succ(1, '新任务')
                        uid = d0.uid
                        info = d0.info
                    else:
                        state.errn()
                except:
                    state.errn()
        return uid, info

    def show(self):
        pass

class XJob2(XHis0):
    def __init__(self, cur: Model, db: PooledPostgresqlDatabase, safe_table: bool = True, clear_table: bool = False,
                 func: Any = None):
        XHis0.__init__(self, cur, safe_table, clear_table, func)
        self.db = db

    @EvsWrapper()
    def adds(self, info, state: StateUtils):
        d0 = dict(
            uid=Utils.f1(),
            info=info,
            ctime=Utils.u0()
        )
        with self.db.atomic():
            e0 = self.cur.insert_many(d0).execute()
            if e0:
                state.succ(1)
            else:
                state.errn()
        return state

    def addc(self):
        pass

    @EvsWrapper()
    def comp(self, func: Any, uid: str, diff: int, state: StateUtils, msg: str = 'nuxx'):
        with self.db.atomic():
            d0 = self.cur.select().where(self.cur.uid == uid).for_update().get()
            state0: StateUtils = func()
            if state0.code == 1:
                d0.diff = diff
                d0.stime = Utils.u0()
                d0.msg = msg
                d0.aka = 'nuxx'
                d0.save()
                state.succ(1)
            else:
                state.errn()

    def outs(self, aka: str):
        pass

    @EvsWrapper()
    def gets(self, aka: str, info: str, diff: int, state: StateUtils, msg: str = 'nuxx'):
        uid = ''
        with self.db.atomic():
            try:
                d0 = self.cur.select().where((self.cur.diff != diff) & (self.cur.info == info)).order_by(
                    fn.Random()).limit(1).for_update().get()
                d0.rtime = Utils.u0()
                d0.msg = msg
                d0.aka = aka
                d0.save()
                state.succ(1)
                uid = d0.uid
            except self.cur.DoesNotExist:
                state.errn()
        return state, uid

    def show(self):
        pass

# Tips     :XJob0,XJob1 可以执行分布式运算 XJob2 只能同步运算


from genericpath import isdir
from PIL import Image
import numpy as np
import os

def get_paths(dir):
    paths = []
    for path in os.listdir(dir):
        if os.path.isdir(dir + '/' + path):
            print('\rReading {} ...'.format(dir + '/' + path), end = '')
            paths += get_paths(dir + '/' + path)
        else:
            paths.append(dir + '/' + path)
    return paths

class FaceDataset:
    def __init__(self, path_list):
        self.path_list = path_list
        self.maxlen = len(path_list)

    def __iter__(self):
        self.count = 0
        return self

    def __next__(self):
        if (self.count >= self.maxlen):
            raise StopIteration
        else:
            path = self.path_list[self.count]
            img = Image.open(path)
            pix = np.asarray(img)
            self.count += 1
            return path, pix

path_list = get_paths('Data/pic_load')
print('\nThe number of pictures:', len(path_list))

facedataset = FaceDataset(path_list[:10])
for pic_path, face in facedataset:
    try:
        print(pic_path, face.shape)
    except StopIteration:
        break


import os
from imutils.video import FPS
import cv2
import math

def video_to_frames(input_loc, output_loc):
    path=os.listdir(input_loc)
    count=1
    for i in path:
        try:
            main_folder=os.path.join(input_loc,i)
            for folder in os.listdir(main_folder):
                print(folder)
                video_path=os.path.join(main_folder,folder)
                for videos in os.listdir(video_path):
                    if videos.endswith(('.mp4','.avi','.mkv','.AVI','.MP4','.MKV')):
                        count+=1
                        if count%10==0: print(count)
                        # one frame per second
                        videoFile = os.path.join(video_path,videos)
                        cap = cv2.VideoCapture(videoFile)   # capturing the video from the given path
                        frameRate = cap.get(5) #frame rate
                        x=1
                        while(cap.isOpened()):
                            frameId = cap.get(1)
                            ret, frame = cap.read()
                            if (ret != True):
                                break
                            if (frameId % math.floor(frameRate) == 0):
                                filename =output_loc+"/"+videos+"_"+str(int(frameId))+".jpg"
                                cv2.imwrite(filename, frame)

        except Exception as e:
            print(e)
            continue

if __name__ == "__main__":
    video_loc = "videos"
    images_loc = "images"
    video_to_frames(video_loc, images_loc)


#

import numpy as np
import cv2
import torch

try:
    import toolkit.customsnippets as customsnippets
except:
    import customsnippets
try:
    import toolkit.methodspaths as methodspaths
except:
    import methodspaths

hardcodedsize = (640, 640)  # yolox specific

def preprocess_img(in_img):
    #hardcodedsize = (640, 640)
    probe_img = cv2.resize(in_img, hardcodedsize, cv2.INTER_AREA)
    probe_img = np.moveaxis(probe_img, [0, 1, 2], [2, 1, 0])
    probe_img = np.moveaxis(probe_img, [0, 1, 2], [0, 2, 1])
    probe_img = np.array([probe_img, ]).astype(np.float32)
    return probe_img

# ----------------------------------------------------------------------------------------------
# //////////////////////////////////////////////////////////////////////////////////////////////
class PoseDetection:
    def __init__(self, method='yolox', architecture='pytorch'):
        self._methods_pool = ['yolox', 'none']
        self._architecture_pool = ['tflite', 'pytorch', 'onnx']
        self._cheatsheet = {'tflite': 0,
                            'pytorch': 1,
                            'onnx': 2}
        self._method = method
        self._architecture = architecture
        self._setup()

    def _setup(self):
        mthd_ok = any(self._method == word for word in self._methods_pool)
        rchtctr_ok = any(self._architecture == word for word in self._architecture_pool)

        if mthd_ok and rchtctr_ok:
            if self._method == 'none':
                self.detector = DummyDetector()
            else:
                if self._cheatsheet[self._architecture] == 0:
                    self.detector = YoloxDetectionTFLITE()
                elif self._cheatsheet[self._architecture] == 1:
                    self.detector = YoloxDetectionPytorch()
                elif self._cheatsheet[self._architecture] == 2:
                    self.detector = YoloxDetectionONNX()
                else:
                    raise TypeError('not yet')
        else:
            raise TypeError('method or architecture not valid')

    def detect(self, in_img):
        img_in_size = in_img.shape
        l_bb = self.detector.detect(in_img)
        out_det = np.array([l_bb[0, 0]/hardcodedsize[0]*(img_in_size[1]-1),
                            l_bb[0, 1]/hardcodedsize[1]*(img_in_size[0]-1),
                            l_bb[0, 2]/hardcodedsize[0]*(img_in_size[1]-1),
                            l_bb[0, 3]/hardcodedsize[1]*(img_in_size[0]-1),
                            l_bb[0, 4]])
        return out_det

# ----------------------------------------------------------------------------------------------
# //////////////////////////////////////////////////////////////////////////////////////////////

class DummyDetector:
    def detect(self, in_img):
        return np.array([[0.0, 0.0, hardcodedsize[0], hardcodedsize[1], 1.0]])

# ----------------------------------------------------------------------------------------------
class YoloxDetectionPytorch:
    def __init__(self):
        _paths = methodspaths.methodsDict['yolox_Paths']
        self.config = _paths.cfg
        self.checkpoint = _paths.pth
        #self.decodeBB = customsnippets.GetPoseDetectionBBNN()
        self._setup()

    def _setup(self):
        from mmdet.apis import init_detector
        self.model = customsnippets.build_custom_yolox_from_model(
            init_detector(self.config, self.checkpoint, device='cpu'))
        #self.decodeBB.eval()

    def detect(self, in_img):
        probe_img = preprocess_img(in_img)
        in_tensor = torch.from_numpy(probe_img).to('cpu')
        with torch.no_grad():
            out = self.model(in_tensor)

        return out.detach().numpy()

# ----------------------------------------------------------------------------------------------

# ----------------------------------------------------------------------------------------------
class YoloxDetectionONNX:
    def __init__(self):
        _paths = methodspaths.methodsDict['yolox_Paths']
        self.onnx_file = _paths.onnx
        self._setup()

    def _setup(self):
        import onnxruntime
        self.model = onnxruntime.InferenceSession(self.onnx_file)

    def detect(self, in_img):
        probe_img = preprocess_img(in_img)
        c_input = {self.model.get_inputs()[0].name: probe_img}
        c_results = self.model.run(None, c_input)

        return c_results[0]

# ----------------------------------------------------------------------------------------------

# ----------------------------------------------------------------------------------------------
class YoloxDetectionTFLITE:
    def __init__(self):
        _paths = methodspaths.methodsDict['yolox_Paths']
        self.tflite_file = _paths.tflite
        self._setup()

    def _setup(self):
        import tensorflow as tf
        self.interpreter = tf.lite.Interpreter(self.tflite_file)
        self.interpreter.allocate_tensors()
        # Get input and output tensors.
        self._input_details = self.interpreter.get_input_details()
        self._input_shape = self._input_details[0]['shape']
        self._output_details = self.interpreter.get_output_details()

    def detect(self, in_img):
        probe_img = preprocess_img(in_img)

        self.interpreter.set_tensor(self._input_details[0]['index'], probe_img)
        self.interpreter.invoke()
        output = self.interpreter.get_tensor(self._output_details[0]['index'])

        return output

# ----------------------------------------------------------------------------------------------

# ----------------------------------------------------------------------------------------------
def test():
    pclass = PoseDetection(method='yolox', architecture='vpu')
    wally = 'here'

# ----------------------------------------------------------------------------------------------
if __name__ == '__main__':
    #test()
    pass