from ProjectUtility import user32, PROJECT_NAME, STORAGE_SERVER, getDLL
StorageManager = getDLL("StorageManager")
LocalStorage = getattr(StorageManager, "LocalStorage")

from .thread import TaskThread

from PyQt5.QtWidgets import QWidget, QLabel, QProgressBar
from PyQt5.QtCore import Qt, QTimer, pyqtSignal
from PyQt5.QtGui import QIcon, QImage, QPixmap

from PIL import Image
import requests as rq
import random, os, io

def imageToPixmap(im):
    if im.mode == "RGB":
        r, g, b = im.split()
        im = Image.merge("RGB", (b, g, r))
    elif  im.mode == "RGBA":
        r, g, b, a = im.split()
        im = Image.merge("RGBA", (b, g, r, a))
    elif im.mode == "L":
        im = im.convert("RGBA")
    elif im.mode == "P":
        im = im.convert("RGBA")
        r, g, b, a = im.split()
        im = Image.merge("RGBA", (b, g, r, a))
    im2 = im.convert("RGBA")
    data = im2.tobytes("raw", "RGBA")
    qim = QImage(data, im.size[0], im.size[1], QImage.Format_ARGB32)
    pixmap = QPixmap.fromImage(qim)
    return pixmap

def loadBytesImage(bstring):
    return Image.open(io.BytesIO(bstring))

class AbstractLoadingWindow(QWidget):
    iconPath = LocalStorage(STORAGE_SERVER, PROJECT_NAME).path(os.path.join("logo", "Filled.png"), True)

    displayLoadingStatusSignal = pyqtSignal()

    _size = int(user32.GetSystemMetrics(1) / 4)
    _padding = int(_size / 10)
    _fontsize = int(_padding / 3)

    def __init__(self):
        super(AbstractLoadingWindow, self).__init__()
        self.status = ["載入中 . . .", 0]
        self.loadingTimer = QTimer(self)
        self.splashArtTimer = QTimer(self)
        self.loadingFunctions = []
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setWindowTitle(f"{PROJECT_NAME}-{self.__class__.__name__}")
        self.setWindowIcon(QIcon(self.iconPath))
        self.resize(self._size*1.65, self._size)
        self.setupComponents()
        self.splashArtTimer.timeout.connect(self.changeBackgroundSplashArt)
        self.splashArtTimer.timeout.emit()
        self.splashArtTimer.setInterval(10000)
        self.splashArtTimer.start()
        self.displayLoadingStatusSignal.connect(self.displayLoadingStatus)

    def notify(self, obj, event):
        error = False
        try:
            super().notify(obj, event)
        except Exception as e:
            error = True
        finally:
            if error: self.close()

    def setLoadingTimer(self, intervalFunction, interval):
        self.loadingTimer.timeout.connect(intervalFunction)
        self.loadingTimer.timeout.emit()
        self.loadingTimer.setInterval(interval)
        self.loadingTimer.start()

    def setupComponents(self):
        self.LoadingSplashArt = QLabel(self)
        self.LoadingSplashArt.setGeometry(0, 0, self.width(), self.height())

        self.LoadingProgress = QProgressBar(self)
        self.LoadingProgress.setRange(0, 100)
        self.LoadingProgress.setTextVisible(False)
        self.LoadingProgress.setOrientation(Qt.Horizontal)
        self.LoadingProgress.move(self._padding, self.height()-(self._padding*2))
        self.LoadingProgress.resize(self.width()-(self._padding*2), self._padding)

        self.LoadingStatus = QLabel(self)
        self.LoadingStatus.setText("載入中 . . .")
        self.LoadingStatus.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.LoadingStatus.font().setPointSize(self._fontsize)
        self.LoadingStatus.setStyleSheet(f"color:#000000;padding:0 {int(self._padding/2)}px;")
        self.LoadingStatus.move(self._padding, self.height()-(self._padding*2))
        self.LoadingStatus.resize(self.width()-(self._padding*2), self._padding)

        self.ProgressLabel = QLabel(self)
        self.ProgressLabel.setText("0%")
        self.ProgressLabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.ProgressLabel.font().setPointSize(self._fontsize)
        self.ProgressLabel.setStyleSheet(f"color:#000000;padding:0 {int(self._padding/2)}px;")
        self.ProgressLabel.move(self._padding, self.height()-(self._padding*2))
        self.ProgressLabel.resize(self.width()-(self._padding*2), self._padding)

    def getRandomSplashArt(self):
        LATEST_RDD_VERSION = rq.get("http://ddragon.leagueoflegends.com/api/versions.json").json()[0]
        championJson = rq.get(f"http://ddragon.leagueoflegends.com/cdn/{LATEST_RDD_VERSION}/data/zh_TW/champion.json").json()
        championNames = list(championJson["data"].keys())
        random.shuffle(championNames)
        for champion in championNames:
            try:
                data = rq.get(f"http://ddragon.leagueoflegends.com/cdn/{LATEST_RDD_VERSION}/data/en_US/champion/{champion}.json").json()
                skin = random.choice(data["data"][champion]["skins"])["num"]
                data = rq.get(f"http://ddragon.leagueoflegends.com/cdn/img/champion/splash/{champion}_{skin}.jpg")
            except Exception as e:
                continue
            return data.content

    def changeBackgroundSplashArt(self):
        splashArtByte = self.getRandomSplashArt()
        if(splashArtByte):
            splashArtLabelGeometry = self.LoadingSplashArt.frameGeometry()
            splashArt = loadBytesImage(splashArtByte)
            splashArtWidth, splashArtHeight = splashArt.size
            if(int(splashArtHeight * (splashArtLabelGeometry.width()/splashArtWidth)) >= splashArtLabelGeometry.height()):
                resizeRatio = (splashArtLabelGeometry.width()/splashArtWidth)
            else: resizeRatio = (splashArtLabelGeometry.height()/splashArtHeight)
            splashArtTargetSize = (int(splashArtWidth*resizeRatio), int(splashArtHeight*resizeRatio))
            resizedSplashArt = splashArt.resize(splashArtTargetSize)
            pixmap = imageToPixmap(resizedSplashArt)
            self.LoadingSplashArt.setPixmap(pixmap)

    def updateLoadingStatus(self, status=None, progress=None):
        if(isinstance(status, str)): self.status[0] = status
        if(isinstance(progress, int)): self.status[1] = progress
        return True

    def displayLoadingStatus(self):
        self.LoadingStatus.setText(self.status[0])
        self.LoadingStatus.repaint()
        self.ProgressLabel.setText(f"{self.status[1]}%")
        self.ProgressLabel.repaint()
        self.LoadingProgress.setValue(self.status[1])
        self.LoadingProgress.repaint()

    def startLoadingIndex(self, idx):
        if(idx < len(self.loadingFunctions)):
            self.displayLoadingStatusSignal.emit()
            self.loadingThreadWorker = TaskThread(
                target=self.loadingFunctions[idx],
                delay=0.1,
                tries=10,
                onFinished=lambda i=idx+1:self.startLoadingIndex(i)
            ).start()
        else: self.close()

    def startLoading(self):
        self.startLoadingIndex(0)
        self.setLoadingTimer(self.displayLoadingStatusSignal.emit, 1000)

    def closeEvent(self, e):
        self.loadingTimer.stop()
        super().closeEvent(e)
        os._exit(0)

    def showEvent(self, e):
        super().showEvent(e)
        self.move(
            int((user32.GetSystemMetrics(0)-self.width())/2),
            int((user32.GetSystemMetrics(1)-self.height())/2)
        )


import numpy as np
import json

# board = [[5, 3, 0, 0, 7, 0, 0, 0, 0],
#          [6, 0, 0, 1, 9, 5, 0, 0, 0],
#          [0, 9, 8, 0, 0, 0, 0, 6, 0],
#          [8, 0, 0, 0, 6, 0, 0, 0, 3],
#          [4, 0, 0, 8, 0, 3, 0, 0, 1],
#          [7, 0, 0, 0, 2, 0, 0, 0, 6],
#          [0, 6, 0, 0, 0, 0, 2, 8, 0],
#          [0, 0, 0, 4, 1, 9, 0, 0, 5],
#          [0, 0, 0, 0, 8, 0, 0, 7, 9]]

game = {
    # the board is represented as a list of lists containing the number at that location in the grid
    # 0 means the location is not filled
    "board": [[0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 4, 0, 0, 0, 0],
              [0, 0, 3, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0]],

    # each thermometer is represented as a list of tuples where the first tuple is the bulb
    # this is a list of thermometers
    "thermometers": [[(2, 0), (1, 0), (0, 0), (0, 1), (0, 2), (0, 3), (1, 3), (2, 3)],
                     [(4, 2), (3, 2)],
                     [(4, 2), (5, 2)],
                     [(4, 2), (4, 3), (4, 4), (4, 5)],
                     [(7, 5), (6, 5), (6, 6), (6, 7), (6, 8), (7, 8), (8, 8)],
                     [(7, 5), (8, 5)]],

    # sum_areas is a list of distionanies
    "sum_areas": [{
        "sum": 10,
        "locations": [(0, 0), (0, 1)],
    },
    {
        "sum": 10,
        "locations": [(1, 0), (1, 1)],
    },
    {
        "sum": 10,
        "locations": [(0, 3), (1, 3)],
    },
    {
        "sum": 10,
        "locations": [(5, 3), (5, 4)],
    },
    {
        "sum": 10,
        "locations": [(7, 3), (7, 4)],
    },
    {
        "sum": 10,
        "locations": [(8, 3), (8, 4)],
    },
    {
        "sum": 10,
        "locations": [(0, 4), (1, 4)],
    },
    {
        "sum": 10,
        "locations": [(4, 5), (5, 5)],
    },
    {
        "sum": 10,
        "locations": [(8, 6), (8, 7)],
    },
    {
        "sum": 10,
        "locations": [(2, 7), (2, 8)],
    },
    {
        "sum": 10,
        "locations": [(3, 7), (4, 7)],
    }],

    "constraints": {
        "sudoku_row": True,
        "sudoku_column": True,
        "sudoku_box": True,
        "chess_knight": True,
        "thermometers": True
    }
}

i = 0

# returns true if n can be placed in row r
# false if n is already in row r
def constraint_row(game, x, y, n):
    board = game.get('board')

    for c in range(9):
        if board[y][c] == n:
            return False
    return True

# returns true if n can be placed in column c
# false if n is already in column c
def constraint_column(game, x, y, n):
    board = game.get('board')

    for r in range(9):
        if board[r][x] == n:
            return False
    return True

# returns true if n can be placed in box b
# false if n is already in box b
def constraint_box(game, x, y, n):
    board = game.get('board')

    bx = (x // 3) * 3
    by = (y // 3) * 3
    for r in range(3):
        for c in range(3):
            if board[by + r][bx + c] == n:
                return False
    return True

# returns true if n can be placed at x,y in the board breaking the chess knights rule
# false if n is a knights move away
def constraint_chess_knight(game, x, y, n):
    board = game.get('board')

    for r in range(9):
        for c in range(9):
            distance = abs(r - y) + abs(c - x)
            if not distance == 3:
                continue
            if r == y:
                continue
            if c == x:
                continue
            if board[r][c] == n:
                return False
    return True

# returns true if n can be placed at x,y in the board without breaking the chess king rule
# false if n is a kings move away
def constraint_chess_king(game, x, y, n):
    board = game.get('board')

    for r in range(3):
        for c in range(3):

            #   x x x
            #   x K x   we can skip 1, 1 because this represents the current
            #   x x x   location as illustrated here
            if r == 1 and c == 1:
                continue

            lx = x+c-1 # location x and y are the current location we are evaluating in the board
            ly = y+r-1
            if lx < 0 or lx > 8 or ly < 0 or ly > 8:
                continue

            # check surrounding square
            if board[ly][lx] == n:
                return False

    # if we didnt find a reason to fail, it succeeds
    return True

# returns true if n can be placed at x,y in the board without breaking the thermometer rule
# false if placing n at x,y breaks a thermometer
# thermometer sudoku is where there is a line on the sudoku board, and the numbers on the line
# can only grow as they get further from the start (aka the bulb) of the thermometer
def constraint_thermometer(game, x, y, n):
    board = game.get('board')
    thermometers = game.get('thermometers')

    if not isinstance(thermometers, list):
        return True

    # search over all the thermometers
    for t in thermometers:

        # check if x, y exists on this thermometer
        found = False
        for pos in t:
            if pos[0] == x and pos[1] == y:
                found = True
                break

        # this x,y was not found on this thermometer,
        # so check the next thermomemter
        if not found:
            continue

        before = True # this keeps track if out current pos is before the given x,y along the thermometer
        for pos in t:
            if pos[0] == x and pos[1] == y:
                before = False
                continue

            # if this position on the board is empty, skip this one
            if board[pos[1]][pos[0]] == 0:
                continue

            if before:
                if n <= board[pos[1]][pos[0]]:
                    return False
            else:
                if n >= board[pos[1]][pos[0]]:
                    return False

    # we havent failed, so we good?
    return True

# returns true if the x,y cell is not consecutive to the orthogonally adjacent cells
# returns false if at least 1 neighbor cell is consecutive to n
def constraint_consecutive_orthogonally_adjacent(game, x, y, n):
    board = game.get('board')

    # check that we arent at the border of the board
    if x > 0:
        # check if the difference between the adjacent cell and x,y cell is 1
        if not board[y][x - 1] == 0:
            if abs(board[y][x - 1] - n) == 1:
                # if so return false
                return False
    if x < 8:
        if not board[y][x + 1] == 0:
            if abs(board[y][x + 1] - n) == 1:
                return False
    if y > 0:
        if not board[y - 1][x] == 0:
            if abs(board[y - 1][x] - n) == 1:
                return False
    if y < 8:
        if not board[y + 1][x] == 0:
            if abs(board[y + 1][x] - n) == 1:
                return False

    # none of the adjacent test failed, so we pass
    return True

def constraint_sum_areas(game, x, y, n):
    board = game.get('board')
    sum_areas = game.get('sum_areas')

    for sa in sum_areas:
        sa_sum = sa.get('sum')
        sa_locs = sa.get('locations')

        # check if x, y exists on this sum_area
        found = False
        for pos in sa_locs:
            if pos[0] == x and pos[1] == y:
                found = True
                break

        if not found:
            continue

        # iterate over all the positions in the sum_area
        sum = 0
        exact = True # if all the locations in the sum_area are filled in, then the sum needs to be exact
        for pos in sa_locs:
            if pos[0] == x and pos[1] == y:
                sum += n
                continue

            bval = board[pos[1]][pos[0]]

            # if one location is not filled in, then the sum doesnt have to be exact
            if bval == 0:
                exact = False

            sum += bval

        if exact:
            return sum == sa_sum
        else:
            if sum > sa_sum:
                return False

    return True

def possible(game, x, y, n):
    board = game.get('board')
    constraints = game.get('constraints', {'sudoku_row': True, 'sudoku_column': True, 'sudoku_box': True})

    if True == constraints.get('sudoku_row', False):
        if not constraint_row(game, x, y, n):
            return False

    if True == constraints.get('sudoku_column', False):
        if not constraint_column(game, x, y, n):
            return False

    if True == constraints.get('sudoku_box', False):
        if not constraint_box(game, x, y, n):
            return False

    if True == constraints.get('chess_knight', False):
        if not constraint_chess_knight(game, x, y, n):
            return False

    if True == constraints.get('chess_king', False):
        if not constraint_chess_king(game, x, y, n):
            return False

    if True == constraints.get('thermometers', False):
        if not constraint_thermometer(game, x, y, n):
            return False

    if True == constraints.get('consecutive_orthogonally_adjacent', False):
        if not constraint_consecutive_orthogonally_adjacent(game, x, y, n):
            return False

    if True == constraints.get('sum_areas', False):
        if not constraint_sum_areas(game, x, y, n):
            return False

    return True

def solve(game):
    board = game.get('board')
    #print(np.matrix(board))
    #input('Step?')

    global i
    if i % 100000 == 0:
        print(np.matrix(board))
    i += 1

    for y in range(9):
        for x in range(9):
            if board[y][x] == 0:
                for n in range(1, 10):
                    if possible(game, x, y, n):
                        board[y][x] = n
                        solve(game)
                        board[y][x] = 0
                return
    print(np.matrix(board))
    input('More?')

if __name__ == "__main__":
    game_name = input('Game name: ')

    with open(f'games/{game_name}.json', 'r') as game_file:
        game_data = json.loads(game_file.read())
        solve(game_data)


import argparse
import copy
import json
import os
import glob
import sys
import urllib
import urllib.request
import shutil
import zipfile
import numpy
import nibabel
import tarfile
import re
import nrrd
import xml.etree.ElementTree as et
from collections import defaultdict
from nipype.interfaces.ants import ApplyTransforms
from nipype.interfaces.ants.base import ANTSCommand, ANTSCommandInputSpec
from nipype.interfaces.base import BaseInterface, BaseInterfaceInputSpec, traits, File, Str, TraitedSpec, Directory, CommandLineInputSpec, CommandLine, InputMultiPath, isdefined, Bunch, OutputMultiPath

#from nipype.interfaces.fsl import fslorient

API_SERVER = "http://api.brain-map.org/"
API_DATA_PATH = API_SERVER + "api/v2/data/"

def GetExpID(startRow=0,numRows=2000,totalRows = -1):
	"""
	Queries the Allen Mouse Brain Institute website for all gene expression data available for download.

	Returns:
	--------
	GeneNames: list[dict()]
		list of all genes where expression data is available for download. Dict contains experiment/gene metadata.

	SectionDataSetID : list(int)
		corresponding SectionDataSetID (SectionDataSet: see "http://help.brain-map.org/display/api/Data+Model")
		ID needed to specify download target.

	"""

	startRow = startRow
	numRows = numRows
	totalRows = totalRows
	rows = []
	GeneNames = []
	SectionDataSetID = []
	info = list()
	done = False

	while not done:
		r = "&start_row={0}&num_rows={1}".format(startRow,numRows)
		pagedUrl = API_DATA_PATH + "query.json?criteria=model::SectionDataSet,rma::criteria,products%5Bid$eq5%5D,rma::include,specimen(stereotaxic_injections(primary_injection_structure,structures))" + r
		source = urllib.request.urlopen(pagedUrl).read()
		response = json.loads(source)
		rows += response['msg']
		for x in response['msg']:

			if x['failed'] == False :
				print(x['id'])
				info.append(x['id'])
		if totalRows < 0:
			totalRows = int(response['total_rows'])

		startRow += len(response['msg'])

		if startRow >= totalRows:
			done = True

	return info

def nrrd_to_nifti(file):
	print("Reading " + file)
	readnrrd = nrrd.read(file)
	data = readnrrd[0]
	header = readnrrd[1]
	print(header)
	print("Converting " + file)

	affine_matrix = numpy.array(header["space directions"],dtype=numpy.float)
	affine_matrix = affine_matrix*0.001
	affine_matrix = numpy.insert(affine_matrix,3,[0,0,0], axis=1)
	affine_matrix = numpy.insert(affine_matrix,3,[0,0,0,1], axis=0)

	#Change Orientation from PIR to RAS. Steps: PIR -> RIP -> RPI -> RPS -> RAS
	data.setflags(write=1)
	data = numpy.swapaxes(data,0,2)
	data = numpy.swapaxes(data,1,2)
	data = data[:,:,::-1]
	data = data[:,::-1,:]
	data = data[::-1,:,:] #TODO: Check for Atlas files!!!!!!
	img = nibabel.Nifti1Image(data,affine_matrix)
	nii_path = os.path.join(os.path.dirname(file), os.path.basename(file).split(".")[0] + '.nii')
	nibabel.save(img,nii_path)

	return nii_path

def get_identifying_structure(metadata):
	tree = et.parse(metadata)
	root = tree.getroot()
	struc = root.findall('.//primary-injection-structure/safe-name')[0]
	return struc.text

def get_exp_metadata(exp,path):
	url_meta = API_DATA_PATH + "/SectionDataSet/query.xml?id=" + str(exp) + "&include=specimen(stereotaxic_injections(primary_injection_structure,structures))"
	filename = str(exp) + "_experiment_metadata.xml"
	s = urllib.request.urlopen(url_meta)
	contents = s.read()
	path_to_metadata = os.path.join(path,filename)
	file = open(path_to_metadata, 'wb')
	file.write(contents)
	file.close()

	return path_to_metadata

def download_all_connectivity(info,folder_name,resolution=200):
	"""
	Download all given genes corresponding to SectionDataSetID given in 100um and 25um resolution, converts nrrd to nii, registers to dsurqec... and resamples files to 40 and 200 respectively.

	Parameters:
	-----------
	SectionDataSetID : list(int)
		o=[0.200000002980232 0 0 -6.26999998092651; 0 0.200000002980232 0 -10.6000003814697; 0 0 0.200000002980232 -7.88000011444092; 0 0 0 1]list of SectionDataSetID to download.
	"""
	print(resolution==200)
	if resolution is None:
		res=[100,25]
	elif resolution==40:
		res=[25]
	elif resolution==200:
		res=[100]
		print(res)
	else:
		res = [99]
	print(resolution)
	download_url = "http://api.brain-map.org/grid_data/download_file/"
	print(res)
	for resolution in res:
		if resolution == 100: path_to_res = folder_name
		if resolution == 25: path_to_res = folder_name + "HD"
		if not os.path.isdir(path_to_res):os.mkdir(path_to_res)
		for exp in info:
			path_to_exp = os.path.join(path_to_res,str(exp))
			#TODO: look inside if stuff is there...
			os.mkdir(path_to_exp)
			path_to_metadata = get_exp_metadata(exp,path_to_exp) #TODO: so far no coordinate info. Also, avoid downloading twice
			struc_name=get_identifying_structure(path_to_metadata)
			struc_name = struc_name.lower()
			struc_name= re.sub(" ","_",struc_name)
			struc_name=re.sub("[()]","",struc_name)
			new_name = struc_name + "-" + os.path.basename(path_to_exp)
			new_path = os.path.join(os.path.dirname(path_to_exp),new_name)
			os.rename(path_to_exp,new_path)
			resolution_url = "?image=projection_density&resolution=" + str(resolution)
			url = download_url + str(exp) + resolution_url
			fh = urllib.request.urlretrieve(url)
			filename = str.split((fh[1]._headers[6][1]),'filename=')[1] #TODO: Consistent??
			#TODO: do that differenttly ...
			filename = str.split(filename,";")[0]
			file_path_nrrd = os.path.join(new_path,filename)
			shutil.copy(fh[0],file_path_nrrd)
			os.remove(fh[0])
			#os.rename(fh[0],file_path_nrrd) only works if source and dest are on the same filesystem
			file_path_nii = nrrd_to_nifti(file_path_nrrd)
			os.remove(file_path_nrrd)
			file_path_2dsurqec = apply_composite(file_path_nii,resolution)
			os.remove(file_path_nii)
			#create archives

		if resolution == 25:
			sort_and_archive()

		elif resolution == 100:
			save_info(info,folder_name)
			tarname=folder_name + ".tar.xz"
			create_archive(tarname,folder_name)

	return

def apply_composite(file,resolution):
	#TODO: does this downsample if composite file is low resolution? Currently composite file is 40um. If it does,is it a problem? Target resolution is 40 anyway, but maybe get a
	#composite file at 25um as well? ResampleImage is possibly not needed otherwise, just specify reference image resolution of 40 and 200
	"""
	Uses ANTS ApplyTransforms to register image to

	Parameters :
	------------

	file : str
		path to image

	"""
	at = ApplyTransforms()
	at.inputs.dimension = 3
	at.inputs.input_image = file
	if resolution == 100:
		ref_image = '/usr/share/mouse-brain-atlases/dsurqec_200micron_masked.nii'
		resolution = 200
	else:
		ref_image = '/usr/share/mouse-brain-atlases/dsurqec_40micron_masked.nii'
		resolution = 40

	#TODO: theres got to be an easier way...
	output_image = ""
	for s in os.path.basename(file).split("_"):
		if "um" not in s :
			output_image += s + "_"
		else:
			output_image += (str(resolution) + "um_")
	output_image = output_image[:-1]
	output_image = os.path.join(os.path.dirname(file),output_image)

	at.inputs.reference_image = ref_image
	name = str.split(os.path.basename(output_image),'.nii')[0] + '_2dsurqec.nii.gz'
	#at.inputs.interpolation = 'NearestNeighbor' #TODO: Sure??
	at.inputs.interpolation = 'BSpline'
	output_image = os.path.join(os.path.dirname(output_image),name)
	at.inputs.output_image = output_image
	at.inputs.transforms = '/usr/share/mouse-brain-atlases/abi2dsurqec_Composite.h5'
	at.run()

	#TODO sform to qform
	return output_image

def download_annotation_file(path):
	anno_url_json = "http://api.brain-map.org/api/v2/structure_graph_download/1.json"
	anno_url_xml = "http://api.brain-map.org/api/v2/structure_graph_download/1.xml"
	filename_xml = "structure_graph.xml"
	filename_json = "structure_graph.json"

	if not os.path.isdir(path):os.mkdir(path)

	s = urllib.request.urlopen(anno_url_json)
	contents = s.read()
	file = open(os.path.join(path,filename_json), 'wb')
	file.write(contents)
	file.close()

	s = urllib.request.urlopen(anno_url_xml)
	contents = s.read()
	file = open(os.path.join(path,filename_xml), 'wb')
	file.write(contents)
	file.close()

def sort_and_archive(path="ABI-connectivity-dataHD"):
	arch = dict()
	arch_names_suff = dict()
	#TODO: There has to be an easier way...
	#TODO:check for any file that does not start with a letter
	arch[1] = glob.glob(os.path.join(path,"[Aa]*"))
	arch_names_suff[1] = "a"
	arch[2] = glob.glob(os.path.join(path,"[BbCc]*"))
	arch_names_suff[2] = "b-c"
	arch[3] = glob.glob(os.path.join(path,"[DdEe]*"))
	arch_names_suff[1] = "d-e"
	arch[4] = glob.glob(os.path.join(path,"[FfGgHhIiJj]*"))
	arch_names_suff[4] = "f-j"
	arch[5]= glob.glob(os.path.join(path,"[KkLl]*"))
	arch_names_suff[5] = "k-l"
	arch[6] = glob.glob(os.path.join(path,"[Mm]*"))
	arch_names_suff[6] = "m"
	arch[7] = glob.glob(os.path.join(path,"[NnOo]*"))
	arch_names_suff[7] = "n-o"
	p_list = sorted(glob.glob(os.path.join(path,"[Pp]*")))
	ind = [p_list.index(i) for i in p_list if 'Primary' in i][0]
	arch[8] = p_list[0:ind]
	arch_names_suff[8] = "pa-pre"
	arch[9]= p_list[ind:len(p_list)]
	arch_names_suff[9] = "pri-po"
	arch[10] = glob.glob(os.path.join(path,"[QqRR]*"))
	arch_names_suff[10] = "q-r"
	arch[11] = glob.glob(os.path.join(path,"[Ss]*"))
	arch_names_suff[1] = "a"
	arch[12] = glob.glob(os.path.join(path,"[TtUuVvWwXxYyZz]*"))
	arch_names_suff[12] = "t-z"
	number_of_archives = 12
	number_of_folders = len(os.listdir(path))

	for i in range(1,(number_of_archives+1)):
		folder_name= os.path.join(path,"ABI-connectivity-dataHD_" + arch[i] + "-0.1")
		if not os.path.isdir(folder_name):os.mkdir(folder_name)
		for file in arch[i]:
			new_path = os.path.join(folder_name,os.path.basename(file))
			os.rename(file,new_path)
		tarname=folder_name + ".tar.xz"
		create_archive(tarname,folder_name)

def create_archive(tarname,path):
	path = path
	tar_name = tarname
	print(path)
	print(tar_name)
	with tarfile.open(tar_name, "w:xz") as tar_handle:
		for root,dirs,files in os.walk(path):
			for file in files:
				tar_handle.add(os.path.join(root,file))

#TODO: Do I really need that? Usefule for expression data, but here?
def save_info(info,folder_name):
	path= os.path.join(folder_name,"ABI-connectivity-ids.csv")
	f = open(path,"w")
	for exp in info:
		f.write('\n')
		f.write(str(exp))

def main():
	#TODO: some sort of parallel download should be possible, stating totalrows and startrows differently for simultaneous download
	#TODO: timeout for urllib
	parser = argparse.ArgumentParser(description="Similarity",formatter_class=argparse.ArgumentDefaultsHelpFormatter)
	parser.add_argument('--package_name','-n',type=str,default="ABI-connectivity-data")
	parser.add_argument('--package_version','-v',type=str,default="9999")
	parser.add_argument('--startRow','-s',type=int,default=0)
	parser.add_argument('--numRows','-r',type=int,default=2000)
	parser.add_argument('--totalRows','-t',type=int,default=-1)
	parser.add_argument('--resolution','-x',type=int)
	args=parser.parse_args()

	folder_name = args.package_name + "-" + args.package_version
	download_annotation_file(folder_name)
	info=GetExpID(startRow=args.startRow,numRows=args.numRows,totalRows=args.totalRows)
	download_all_connectivity(info,folder_name=folder_name,resolution=args.resolution)
	#save_info(info)
	#create_archive()
	#sort_and_archive()

if __name__ == "__main__":
	main()


import os

import eventlet
from oslo.config import cfg

from nova import exception
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.servicegroup import api
from nova import utils

evzookeeper = importutils.try_import('evzookeeper')
membership = importutils.try_import('evzookeeper.membersip')
zookeeper = importutils.try_import('zookeeper')

zk_driver_opts = [
    cfg.StrOpt('address',
               default=None,
               help='The ZooKeeper addresses for servicegroup service in the '
                    'format of host1:port,host2:port,host3:port'),
    cfg.IntOpt('recv_timeout',
               default=4000,
               help='recv_timeout parameter for the zk session'),
    cfg.StrOpt('sg_prefix',
               default="/servicegroups",
               help='The prefix used in ZooKeeper to store ephemeral nodes'),
    cfg.IntOpt('sg_retry_interval',
               default=5,
               help='Number of seconds to wait until retrying to join the '
                    'session'),
    ]

CONF = cfg.CONF
CONF.register_opts(zk_driver_opts, group="zookeeper")

LOG = logging.getLogger(__name__)

class ZooKeeperDriver(api.ServiceGroupDriver):
    """ZooKeeper driver for the service group API."""

    def __init__(self, *args, **kwargs):
        """Create the zk session object."""
        if not all([evzookeeper, membership, zookeeper]):
            raise ImportError('zookeeper module not found')
        null = open(os.devnull, "w")
        self._session = evzookeeper.ZKSession(CONF.zookeeper.address,
                                              recv_timeout=
                                                CONF.zookeeper.recv_timeout,
                                              zklog_fd=null)
        self._memberships = {}
        self._monitors = {}
        # Make sure the prefix exists
        try:
            self._session.create(CONF.zookeeper.sg_prefix, "",
                                 acl=[evzookeeper.ZOO_OPEN_ACL_UNSAFE])
        except zookeeper.NodeExistsException:
            pass

        super(ZooKeeperDriver, self).__init__()

    def join(self, member_id, group, service=None):
        """Join the given service with its group."""
        LOG.debug(_('ZooKeeperDriver: join new member %(id)s to the '
                    '%(gr)s group, service=%(sr)s'),
                    {'id': member_id, 'gr': group, 'sr': service})
        member = self._memberships.get((group, member_id), None)
        if member is None:
            # the first time to join. Generate a new object
            path = "%s/%s" % (CONF.zookeeper.sg_prefix, group)
            try:
                member = membership.Membership(self._session, path, member_id)
            except RuntimeError:
                LOG.exception(_("Unable to join. It is possible that either "
                                "another node exists with the same name, or "
                                "this node just restarted. We will try "
                                "again in a short while to make sure."))
                eventlet.sleep(CONF.zookeeper.sg_retry_interval)
                member = membership.Membership(self._session, path, member_id)
            self._memberships[(group, member_id)] = member
        return FakeLoopingCall(self, member_id, group)

    def leave(self, member_id, group):
        """Remove the given member from the service group."""
        LOG.debug(_('ZooKeeperDriver.leave: %(member)s from group %(group)s'),
                  {'member': member_id, 'group': group})
        try:
            key = (group, member_id)
            member = self._memberships[key]
            member.leave()
            del self._memberships[key]
        except KeyError:
            LOG.error(_('ZooKeeperDriver.leave: %(id)s has not joined to the '
                        '%(gr)s group'), {'id': member_id, 'gr': group})

    def is_up(self, service_ref):
        group_id = service_ref['topic']
        member_id = service_ref['host']
        all_members = self.get_all(group_id)
        return member_id in all_members

    def get_all(self, group_id):
        """Return all members in a list, or a ServiceGroupUnavailable
        exception.
        """
        monitor = self._monitors.get(group_id, None)
        if monitor is None:
            path = "%s/%s" % (CONF.zookeeper.sg_prefix, group_id)
            monitor = membership.MembershipMonitor(self._session, path)
            self._monitors[group_id] = monitor
            # Note(maoy): When initialized for the first time, it takes a
            # while to retrieve all members from zookeeper. To prevent
            # None to be returned, we sleep 5 sec max to wait for data to
            # be ready.
            for _retry in range(50):
                eventlet.sleep(0.1)
                all_members = monitor.get_all()
                if all_members is not None:
                    return all_members
        all_members = monitor.get_all()
        if all_members is None:
            raise exception.ServiceGroupUnavailable(driver="ZooKeeperDriver")
        return all_members

class FakeLoopingCall(utils.LoopingCallBase):
    """The fake Looping Call implementation, created for backward
    compatibility with a membership based on DB.
    """
    def __init__(self, driver, host, group):
        self._driver = driver
        self._group = group
        self._host = host

    def stop(self):
        self._driver.leave(self._host, self._group)

    def start(self, interval, initial_delay=None):
        pass

    def wait(self):
        pass


import pytest
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session

from app.core.config import get_settings

settings = get_settings()

def test_read_data_sources(client: TestClient, db: Session) -> None:
    r = client.get(f"{settings.API_V1_STR}/data_source/")
    assert r.status_code == 200

# [1, 2, 3, 4] are the ID's of the data sources which should be tested in the database.
@pytest.mark.parametrize("data_source_id", [1, 2, 3, 4])
def test_return_200_for_existing_data_source(
    client: TestClient, data_source_id: int, db: Session
) -> None:
    r = client.get(f"{settings.API_V1_STR}/data_source/{data_source_id}")
    assert r.status_code == 200
    response_ = r.json()
    assert response_["id"] == data_source_id


import dlib
import face_recognition
import cv2
from PIL import Image, ImageDraw
import numpy as np

# Load a sample picture and learn how to recognize it.
wacef_image = face_recognition.load_image_file("C:/Users/hp/Desktop/Travail_Stage/Faces_data/faces/F1/F16.jpg")
wacef_face_encoding = face_recognition.face_encodings(wacef_image)[0]
# Create arrays of known face encodings and their names
known_face_encodings = [
    wacef_face_encoding
    ]
known_face_names = [
    "Wacef Chachia"
]

cam = cv2.VideoCapture(0)
while True:
    ret, frame = cam.read()

    # Load an image with an unknown face
    #unknown_image = face_recognition.load_image_file("C:/Users/hp/Desktop/Travail_Stage/Faces_data/faces/F1/F24.jpg")

    # Find all the faces and face encodings in the unknown image

    face_locations = face_recognition.face_locations(frame) ######## model='cnn' with GPU #######
    face_encodings = face_recognition.face_encodings(frame, face_locations)

    # Convert the image to a PIL-format image so that we can draw on top of it with the Pillow library
    # See http://pillow.readthedocs.io/ for more about PIL/Pillow
    pil_image = Image.fromarray(frame)
    # Create a Pillow ImageDraw Draw instance to draw with
    draw = ImageDraw.Draw(pil_image)

    # Loop through each face found in the unknown image
    for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
        # See if the face is a match for the known face(s)
        matches = face_recognition.compare_faces(known_face_encodings, face_encoding) #tolerance = 0.6 per default

        name = "Unknown"

        face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
        best_match_index = np.argmin(face_distances)
        if matches[best_match_index]:
            name = known_face_names[best_match_index]
            #print(name)
        else:
            #show the face which we talk about
            draw1 = draw.copy()
            draw1.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))
            cv2.imshow('Face detected',draw1)
            #
            rep = input('Unknown person !. Do you want to save it ? y : yes or n : no')
            while rep not in ['y','n']:
                rep = input('Unknown person !. Do you want to save it ? y : yes or n : no')
            if rep == 'y':
                name = input('So enter his name here : ')
                known_face_names.append(name)
                known_face_encodings.append(face_encoding)
            cv2.destroyWindow('Face detected')

        # Draw a box around the face using the Pillow module
        draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))

        # Draw a label with a name below the face
        text_width, text_height = draw.textsize(name)
        draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))
        draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))

    # Remove the drawing library from memory as per the Pillow docs
    del draw

    # Display the resulting image
    pil_image.show()

    # You can also save a copy of the new image to disk if you want by uncommenting this line
    if name != "Unknown":
        img_name = name + '.jpg'
        pil_image.save(img_name)

    #Show final result
    cv2.imshow('image',draw)
    ##Close window
    k = cv2.waitKey(1)
    if k == ord('q'):
        print("Closing the window")
        break

cam.release()

cv2.destroyAllWindows()


from django.urls import reverse
from .base_home import HomeBaseTest
from apps.client.models import Person, ItemList

class HomeViewDoingTest(HomeBaseTest):
    def test_home_view_doing_returns_correct_amount_DOING_entity(self):
        self.create_and_login()
        person = Person.objects.get(id=self.person.id)

        for status in ['DOING'] * 3:
            person.item_list.add(self.create_card(
                author=self.user, status=status
            ))

        url = reverse('home:specific_status', kwargs={'status': 'doing'})
        response = self.client.get(url)
        context = response.context['item_list'].count()

        person_DOING = person.item_list.filter(status='DOING').count()

        self.assertEqual(context, person_DOING)

    def test_home_view_doing_returns_correct_person(self):
        self.create_and_login()
        person = Person.objects.get(id=self.person.id)

        url = reverse('home:specific_status', kwargs={'status': 'doing'})
        response = self.client.get(url)
        context = response.context['person']

        self.assertIs(person.id, context.id)

    def test_home_view_doing_returns_correct_amount_DOING_entity_logout(self):
        self.user = self.create_user(username='DOING')

        for status in ['DOING'] * 3:
            self.create_card(author=self.user, status=status)

        url = reverse('home:specific_status', kwargs={'status': 'doing'})
        response = self.client.get(url)
        context = response.context['item_list'].count()

        doing = ItemList.objects.filter(
            type='A', status='DOING', root=True
        ).count()

        self.assertEqual(context, doing)

    def test_home_view_doing_invalid_request_error_message(self):
        url = reverse('home:specific_status', kwargs={'status': 'doing'})
        response = self.client.put(url, follow=True)
        content = response.content.decode('utf-8')

        redirect_url = reverse('home:home')
        self.assertIn('Requisição inválida.', content)
        self.assertEqual(redirect_url, response.wsgi_request.path)

    def test_home_view_doing_invalid_status(self):
        url = reverse('home:specific_status', kwargs={'status': 'invalid'})
        response = self.client.put(url, follow=True)
        content = response.content.decode('utf-8')

        redirect_url = reverse('home:home')
        self.assertIn('Status inválido.', content)
        self.assertEqual(redirect_url, response.wsgi_request.path)


# whole registration workflow

import matlab.engine
import numpy as np
import subprocess
import os
import sys
import statistics
from shutil import copyfile
from pathlib import Path

eng = matlab.engine.start_matlab()

source_file = "C:\\Registration\\test_gls_algo\\meshes\\small_meshes_for_test\\larger_rescaling\\bunny_simp.ply"
target_file = "C:\\Registration\\test_gls_algo\\meshes\\small_meshes_for_test\\larger_rescaling\\bunny_simp_rX45_t0-4-3_s0.5.ply"
executable_FGR = "C:\\Registration\\FGR\\FastGlobalRegistration-build\\FastGlobalRegistration\\Release\\FastGlobalRegistration.exe"
transform_prefix = "transform_r45_t0_4_3_s05_K12_lambda"
transform_path = "C:\\Registration\\FGR\\gls_example"
pairs_path = "C:\\Registration\\test_gls_algo\\matching_pairs"
pairs_prefix = "12pairs_lambda"
pairs_suffix = "_file";
target_transformed_path = "C:\\Registration\\FGR\\gls_example\\transformed_target"
ext = ".txt"
mean_and_std_path = "C:\\Registration\\FGR\\gls_example\\mean&std"
executable_cloudCompare = "C:\\Program Files\\CloudCompare\\CloudCompare.exe"
all_means_file = "mean_file.txt";
open(os.path.join(mean_and_std_path, all_means_file), 'w').close()

for i in range(0, 101, 1):
    transform_file = transform_prefix + str(i) + ext;
    pairs_file = pairs_prefix + str(i) + pairs_suffix + ext
    # compute registration
    args = executable_FGR + " " + source_file + " " + target_file + " " + os.path.join(pairs_path, pairs_file) + " " + os.path.join(transform_path, transform_file)
    subprocess.call(args, stdin=None, stdout=None, stderr=None)
    # process registration
    estimated_transform_struct = eng.importdata(os.path.join(transform_path, transform_file),' ', 1)
    estimated_transform = eng.getfield(estimated_transform_struct, 'data')
    output_ply_file = os.path.join(target_transformed_path, transform_prefix + str(i) + ".ply")
    eng.register_pcs(source_file, target_file, estimated_transform, output_ply_file, nargout = 0)
    # compute target registered to source distance
    fgr_c2m_result_file = os.path.join(mean_and_std_path, transform_prefix + str(i) +'_c2m_results.txt')
    open(fgr_c2m_result_file, 'w').close()
    args_c2m = executable_cloudCompare + " -SILENT" + " -o " + output_ply_file + " -o " + source_file + " -NO_TIMESTAMP -C_EXPORT_FMT ASC -c2m_dist"  # compute C2M distance
    subprocess.call(args_c2m, stdin=None, stdout=None, stderr=None)
    # process cloudCompare output
        # get file with c2m distances
    for file in os.listdir(target_transformed_path):
        if "lambda" + str(i) + "_C2M_DIST.asc" in file:
            c2m_file = file

    # get everything in column 4 for c2m
    col_num = 3
    col_data = []
    delimiter = " "
    with open(Path(target_transformed_path) / c2m_file) as f:
        data = f.readlines()
        for line in data:
            col_data.append(line.strip().split(delimiter)[col_num])

    distances_list = list(map(float, col_data))
    signed_mean_c2m_dist = statistics.mean(distances_list)
    unsigned_mean_C2M_dist = statistics.mean(list(map(abs, distances_list)))
    signed_std_c2m = statistics.stdev(distances_list)
    unsigned_std_C2M = statistics.stdev(list(map(abs, distances_list)))
    out_file =open(fgr_c2m_result_file, "a+")
    out_file.write("Mean distance = %5.6f / std deviation = %5.6f\n" % (unsigned_mean_C2M_dist, unsigned_std_C2M))
    out_file.close()
    general_mean_file =open(os.path.join(mean_and_std_path, all_means_file), "a+")
    general_mean_file.write("%5.6f \n" % (unsigned_mean_C2M_dist))
    general_mean_file.close()


from qgis.core import *
from qgis.gui import *
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *

import os
import math
from osgeo import gdal
import geopandas as gp
import sys
import os

# make tiler
# python3 utils/image-export.py "qgis/full-nz.qgz" 32000000,16000000,8000000
# OR
# make QGISPROJECT=qgis/full-nz.qgz.qgz SCALES=32000000,16000000,8000000 image-exports

project_path = sys.argv[1]
scales = sys.argv[2].split(",")

print((scales))

grid = "data/vector/100k_grid.gpkg"

dir_name = os.path.basename(project_path).split(".")[0]
out_base = os.path.join("cog-outputs", dir_name)
os.makedirs(out_base, exist_ok=True)

# Resolutions and scales set per LINZ map tiles standards:
# https://www.linz.govt.nz/data/linz-data-service/guides-and-documentation/nztm2000-map-tile-service-schema
meter_to_inch = 39.3701
dpi = 90.71428571428571

# Supply path to qgis install location
# Create a reference to the QgsApplication.  Setting the
# second argument to False disables the GUI.
qgs = QgsApplication([], False)
QgsApplication.setPrefixPath("/usr", True)
qgs.initQgis()

project = QgsProject.instance()

project.read(project_path)

layers = QgsProject.instance().mapLayers().values()

# Project Extent
proj_extent = project.mapLayersByName("nz-extent")[0].extent()

# Scales
# scales = [32000000, 16000000, 8000000, 4000000, 2000000, 1000000, 500000, 250000, 100000, 50000]
root_scale = min(scales)
sorted_list = sorted(scales, reverse=False)
list_length = len(sorted_list)
gpGrid = gp.read_file(grid)

for index, gtile in gpGrid.iterrows():

    # Set Paths
    raw_path = os.path.join(out_base, str(index), "raw")
    os.makedirs(raw_path, exist_ok=True)

    # Get bounds for processing
    xmin = gtile.geometry.bounds[0]
    ymin = gtile.geometry.bounds[1]
    xmax = gtile.geometry.bounds[2]
    ymax = gtile.geometry.bounds[3]

    # Setting overview and base file name
    ovr_ext = ".ovr"
    ovr_name = str(root_scale) + ".tif"

    # Loop sorted scales list
    for ovr in sorted_list:
        print(f"Scale: {str(ovr)}")
        if ovr != root_scale:
            ovr_name = ovr_name + ovr_ext

        width = math.ceil(
            abs(
                (((xmin - xmax) * meter_to_inch) / float(ovr))
                * dpi
            )
        )
        height = math.ceil(
            abs(
                (((ymin - ymax) * meter_to_inch) / float(ovr))
                * dpi
            )
        )

        file_name = str(ovr) + "_images.png"
        image_path = os.path.join(out_base, file_name)

        # Start Map Settings
        settings = QgsMapSettings()
        settings.setOutputSize(QSize(width, height))

        settings.setDestinationCrs(QgsCoordinateReferenceSystem.fromEpsgId(2193))

        p = QPainter()
        img = QImage(QSize(width, height), QImage.Format_ARGB32_Premultiplied)
        p.begin(img)
        p.setRenderHint(QPainter.Antialiasing)

        # Set layers to render. Only renders "checked" layers
        layers = list([lyr for lyr in project.layerTreeRoot().checkedLayers()])
        settings.setLayers(layers)

        # Set Extent
        settings.setExtent(QgsRectangle(xmin, ymin, xmax, ymax))

        # setup qgis map renderer
        print("Rendering...")
        render = QgsMapRendererCustomPainterJob(settings, p)
        render.start()
        render.waitForFinished()
        p.end()

        # save the image
        print("Saving Image...")
        img.save(image_path, "png")

        gtif_file_name = str(ovr) + "_gtiff_images.tif"
        gtif_path = os.path.join(raw_path, gtif_file_name)

        print("Running Translate...")
        gdal.Translate(gtif_path, image_path, outputBounds=[xmin, ymax, xmax, ymin], bandList=[1,2,3], outputSRS="EPSG:2193")
        os.remove(image_path)


from matplotlib import pyplot as plt
import numpy as np

class Markov_chain:
    def __init__(self,state,trans_matrix):
        self.states=state
        self.trans_prob_dict=dict()
        for x in range(len(self.states)):
            self.trans_prob_dict.update({self.states[x]:trans_matrix[x]})
        self.current_state=np.random.choice(self.states)
    def step(self):
        self.current_state=np.random.choice(a=self.states,p=self.trans_prob_dict[self.current_state])
        return self.current_state
    def reset(self):
        self.current_state=np.random.choice(self.states)
        return
class Bernoulli_gen:
    def __init__(self,MC):
        self.MC=MC
    def step(self):
        return np.random.binomial(n=1,p=self.MC.step())
    def reset(self):
        self.MC.reset()
        return
class Expert:
    def __init__(self,id):
        self.id=id
        self.rel_past=None
    def step(self):
        return self.respective_step()
    def update(self,new_observation):
        self.relevant_update(new_observation)
        return

class Expert_one(Expert):
    def __init__(self, id=1):
        super().__init__(id)
    def respective_step(self):
        return 0
    def relevant_update(self,new_observation):
        return
    def reset(self):
        return
    def __str__(self):
        return "Expert 1"
class Expert_two(Expert):
    def __init__(self, id=2):
        super().__init__(id)
    def respective_step(self):
        return 1
    def relevant_update(self,new_observation):
        return
    def reset(self):
        return
    def __str__(self):
        return "Expert 2"
class Expert_three(Expert):
    def __init__(self, id=3):
        super().__init__(id)
        self.rel_past=dict({0:0,1:0})
    def respective_step(self):
        if self.rel_past[0]>self.rel_past[1]:
            return 0
        return 1
    def reset(self):
        self.rel_past.update({0:0,1:0})
        return
    def relevant_update(self,new_observation):
        self.rel_past.update({new_observation:self.rel_past[new_observation]+1})
        return
    def __str__(self):
        return "Expert 3"
class Expert_four(Expert):
    def __init__(self, id=4):
        super().__init__(id)
        self.rel_past=list()
    def respective_step(self):
        if self.rel_past.count(0)>self.rel_past.count(1):
            return 0
        return 1
    def reset(self):
        self.rel_past=list([])
        return
    def relevant_update(self,new_observation):
        if len(self.rel_past)<10:
            self.rel_past.append(new_observation)
        else:
            self.rel_past.pop(0)
            self.rel_past.append(new_observation)
        return
    def __str__(self):
        return "Expert 4"

class W_MAJ:
    def __init__(self,experts,learning_rate):
        self.experts=experts
        self.learning_rate=learning_rate
        self.weights=dict()
        for x in self.experts:
            self.weights.update({x:1})
        self.current_action=None
        self.current_prediction=list()
    def step(self):

        self.current_prediction=[]
        for x in self.experts:
            self.current_prediction.append(x.step())
        w_pos=0
        w_neg=0
        for x in range(len(self.current_prediction)):
            if self.current_prediction[x]==1:
                w_pos=w_pos+self.weights[self.experts[x]]
            else:
                w_neg=w_neg+self.weights[self.experts[x]]
        if w_pos>=w_neg:
            self.current_action=1
            return 1
        else:
            self.current_action=0
            return 0
    def reset(self):
        for x in self.experts:
            self.weights.update({x:1})
        return
    def update(self,new_observation):

        for x in self.experts:
            x.update(new_observation)
        if self.current_action==new_observation:
            return
        else:
            for x in range(len(self.current_prediction)):
                if self.current_prediction[x]!=new_observation:
                    self.weights.update({self.experts[x]:self.weights[self.experts[x]]-self.learning_rate*self.weights[self.experts[x]]})

    def __str__(self):
        return "W MAJ"

def Bound_test(W_MAJ_mistakes,best_mistakes):
    m=4
    learning_rate=0.1
    return (W_MAJ_mistakes<=2*(1+learning_rate)*best_mistakes+(np.log(m)/learning_rate))
class play_ground:
    def __init__(self,Learners,ADV,num_of_instance=4,T=1000):
        self.Learners=Learners
        self.ADV=ADV
        self.N=num_of_instance
        self.N_list=list([])
        self.T=T
    def step(self):
        container=np.zeros((self.T,len(self.Learners)))

        self.ADV.reset()
        for x in self.Learners:
            x.reset()

        learners_prediction=dict({})

        for x in self.Learners:
            learners_prediction.update({x:0})

        state=np.zeros(len((self.Learners)))
        current=np.zeros(len((self.Learners)))

        for i in range(self.T):

            for x in self.Learners:
                learners_prediction.update({x:x.step()})

            new_observation=self.ADV.step()

            for x in range(len(self.Learners)):
                if learners_prediction[self.Learners[x]]!=new_observation:
                    current[x]=1
                else:
                    current[x]=0
            state=state+current
            container[i]=state
            control_1=Bound_test(state[0],min(state[1:5]))
            if control_1 is False:
                print("Problem")

            for x in self.Learners:
                x.update(new_observation)
        return container
def plot(Obj):
    fig, ax = plt.subplots(2,2)
    fig.set_size_inches(12.5, 8.5, forward=True)

    plt.setp(ax, xticks=np.linspace(0,1000,5),yticks=np.linspace(0,600,11))

    Mat_1=Obj.step()
    # plt.plot(range(Obj.T),Mat_1.transpose()[0], 'r',label="ALG")
    ax[0, 0].plot(range(Obj.T),Mat_1.transpose()[0], 'r',label="ALG") #row=0, col=0
    ax[0, 0].plot(range(Obj.T),Mat_1.transpose()[1], 'b',label="Expert 1")
    ax[0, 0].plot(range(Obj.T),Mat_1.transpose()[2], 'g',label="Expert 2")
    ax[0, 0].plot(range(Obj.T),Mat_1.transpose()[3], 'darkorange',label="Expert 3")
    ax[0, 0].plot(range(Obj.T),Mat_1.transpose()[4], 'k',label="Expert 4")

    Mat_1=Obj.step()
    # plt.plot(range(Obj.T),Mat_1.transpose()[0], 'r',label="ALG")
    ax[0, 1].plot(range(Obj.T),Mat_1.transpose()[0], 'r',label="ALG") #row=0, col=0
    ax[0, 1].plot(range(Obj.T),Mat_1.transpose()[1], 'b',label="Expert 1")
    ax[0, 1].plot(range(Obj.T),Mat_1.transpose()[2], 'g',label="Expert 2")
    ax[0, 1].plot(range(Obj.T),Mat_1.transpose()[3], 'darkorange',label="Expert 3")
    ax[0, 1].plot(range(Obj.T),Mat_1.transpose()[4], 'k',label="Expert 4")

    Mat_1=Obj.step()
    # plt.plot(range(Obj.T),Mat_1.transpose()[0], 'r',label="ALG")
    ax[1, 0].plot(range(Obj.T),Mat_1.transpose()[0], 'r',label="ALG") #row=0, col=0
    ax[1, 0].plot(range(Obj.T),Mat_1.transpose()[1], 'b',label="Expert 1")
    ax[1, 0].plot(range(Obj.T),Mat_1.transpose()[2], 'g',label="Expert 2")
    ax[1, 0].plot(range(Obj.T),Mat_1.transpose()[3], 'darkorange',label="Expert 3")
    ax[1, 0].plot(range(Obj.T),Mat_1.transpose()[4], 'k',label="Expert 4")

    Mat_1=Obj.step()
    # plt.plot(range(Obj.T),Mat_1.transpose()[0], 'r',label="ALG")
    ax[1, 1].plot(range(Obj.T),Mat_1.transpose()[0], 'r',label="ALG") #row=0, col=0
    ax[1, 1].plot(range(Obj.T),Mat_1.transpose()[1], 'b',label="Expert 1")
    ax[1, 1].plot(range(Obj.T),Mat_1.transpose()[2], 'g',label="Expert 2")
    ax[1, 1].plot(range(Obj.T),Mat_1.transpose()[3], 'darkorange',label="Expert 3")
    ax[1, 1].plot(range(Obj.T),Mat_1.transpose()[4], 'k',label="Expert 4")

    ax[0,0].set(xlabel="T", ylabel="Number of Mistakes")
    ax[0,1].set(xlabel="T", ylabel="Number of Mistakes")
    ax[1,0].set(xlabel="T", ylabel="Number of Mistakes")
    ax[1,1].set(xlabel="T", ylabel="Number of Mistakes")

    handles, labels = ax[1,1].get_legend_handles_labels()
    fig.legend(handles, labels, loc='upper right')
    plt.suptitle("Comparison Chart")

    plt.show()
    return

def main():
    trans_matrix=np.array([[0.95,.05],[0.05,0.95]])
    state=[0.2,.8]
    learning_rate=0.1
    MC=Markov_chain(state,trans_matrix)
    ADV=Bernoulli_gen(MC)
    Expert_list=[Expert_one(),Expert_two(),Expert_three(),Expert_four()]
    EXP_1=Expert_one()
    EXP_2=Expert_two()
    EXP_3=Expert_three()
    EXP_4=Expert_four()
    ALG=W_MAJ(Expert_list,learning_rate)
    Learners=[ALG,EXP_1,EXP_2,EXP_3,EXP_4]
    Obj=play_ground(Learners,ADV=ADV)
    plot(Obj)
    return

if __name__=='__main__':
    main()


from bs4 import BeautifulSoup
import requests
import re
import os

linktoday = 'https://www.meteoprog.com/ru/meteograms/Krasnojarsk/' # Ссылка для погоды сегодня
link7days = 'https://krasnoyarsk.nuipogoda.ru/погода-на-неделю' # Ссылка для погоды на неделю
link30days = 'https://krasnoyarsk.nuipogoda.ru/погода-на-месяц' # Ссылка для погоды на месяц

responcetoday = requests.get(linktoday) # Подключение к ссылке для погоды один день
responce7days = requests.get(link7days) # Подключение к ссылке для погоды на 7 дней
responce30days = requests.get(link30days) # Подключение к ссылке для погоды на 30 дней

souptoday = BeautifulSoup(responcetoday.text, 'lxml') # Передача данных в суп за один день
soup7days = BeautifulSoup(responce7days.text, 'lxml') # Передача данных в суп за 7 дней
soup30days = BeautifulSoup(responce30days.text, 'lxml') # Передача данных в суп за 30 дней

def menu():
    print("Погода в Красноярске.\n1. Узнать погоду на сегодня\n2. Узнать погоду на неделю\n3. Узнать погоду на месяц\n4. Выйти")
    UserChoose = input()
    os.system('cls')
    if UserChoose == "1":
        os.system('cls')
        day()
    elif UserChoose == "2":
        os.system('cls')
        week()
    elif UserChoose == "3":
        os.system('cls')
        month()
    elif UserChoose == "4":
        exit()
    else:
        print("Такой команды не существует! Выберите команду предложенную из списка.")
        menu()

def day():

    TodayWeatherBlock = souptoday.find('table').find_all('div', class_='temperature__column') # Поиск таблицы с погодой на сегодня
    TodayWeatherList = re.findall(r"[+-]\d+", str(TodayWeatherBlock)) # Регулярное выражения для поиска градусов погоды
    TodayWeatherLen = len(TodayWeatherList) # Вычисление длины списка погоды для поиска среднего арифметического
    TodayWeatherInt = [] # Объявление пустого списка для присваивания списку типа int

    for weathertoday in TodayWeatherList:
        TodayWeatherInt.append(int(weathertoday)) # Присваивание пустому списку TodayWeatherInt чисел (данных о погоде) типа int

    TodayWeatherSum = sum(TodayWeatherInt) # Сумма всех чисел для поиска среднего арифметического
    print(f"Погода на сегодня: {TodayWeatherSum//TodayWeatherLen}°") # Вывод среднего арифметического погоды за день

def week():

    DayWeekWeatherBlock = soup7days.find('table', class_='weather').find('tbody', class_='tbody-forecast').find_all('tr', class_='last day7') # Поиск погодного блока
    DayWeekWeatherFind = re.findall(r"<span>\d+ ...<\/span>", str(DayWeekWeatherBlock)) # При помощи регекса нахождение даты
    DayWeekWeather = re.findall(r"\d+ ...", str(DayWeekWeatherFind)) # Более точное нахождение даты

    WeekWeatherFindall = re.findall(r"class=.t.>.\d+", str(DayWeekWeatherBlock)) # Нахождение погоды при помощи регекса
    WeekWeatherFind = re.findall(r".\d+", str(WeekWeatherFindall)) # Более точное нахождение погоды

    for i in range(len(WeekWeatherFind)): # Вывод погоды на неделю
        i + 1
        print(f"{DayWeekWeather[i]} ожидается погода: {WeekWeatherFind[i]}")

def month():
    MonthWeatherBlock = soup30days.find('table', class_='weather calendar').find('tbody').find_all('td') # Нахождение блока с погодой

    MonthWeatherFindDay = re.findall(r"\d+[-][а-я]+", str(MonthWeatherBlock)) # Нахождение даты

    MonthWeatherFindallWeather = re.findall(r"class=.max.>[+-]\d+", str(MonthWeatherBlock)) # Нахождение погоды
    MonthWeatherFindWeather = re.findall(r"[+-]\d+", str(MonthWeatherFindallWeather)) # Более точное нахождение погоды

    for i in range(len(MonthWeatherFindDay)): # Вывод погоды
        i + 1
        print(f"{MonthWeatherFindDay[i]} ожидается погода: {MonthWeatherFindWeather[i]}")

if __name__ == '__main__':
    menu()


from collections import namedtuple
from typing import NamedTuple

# pet = ('pet_name', 'pet_type')

Pet = namedtuple('Pet', 'pet_name pet_type')
harrys_pet = Pet('Hedwig', 'owl')
print(harrys_pet.pet_name)

class Pet(NamedTuple):
    pet_name: str
    pet_type: str

    def __repr__(self):
        return f"{self.pet_name}, {self.pet_type}"

harrys_pet = Pet('Hedwig', 'owl')
print('harrys_pet: ', harrys_pet)


import noise
import numpy as np
import matplotlib.pyplot as plt

width, height = 100, 100
scale = 0.1
noise_map = np.zeros((width, height))

for x in range(width):
    for y in range(height):
        noise_map[x][y] = noise.pnoise2(x * scale, y * scale)

plt.imshow(noise_map, cmap='gray')
plt.show()


import numpy as np
import numpy.random as rd
import scipy.stats as st
import matplotlib.pyplot as plt
import pickle as pk
import sys

#Definir les funcions per a fer test
def f_norm(size):
    return st.norm.rvs(0,1,size)

def f_skew(size):
    return st.skewnorm.rvs(7,loc=-1.32,scale=1.65,size=size)

def f_bimodal_asym(size):
    std1 = 0.41
    std2 = 0.71
    sample = np.concatenate([st.norm.rvs(-0.82-0.16,std1,int(size*0.4)),st.norm.rvs(0.82-0.16,std2,int(size*0.6))])
    rd.shuffle(sample)
    return sample

def f_bimodal_sym(size):
    std1 = 0.5
    std2 = 0.5
    sample = np.concatenate([st.norm.rvs(-0.9,std1,int(size*0.5)),st.norm.rvs(0.9,std2,int(size*0.5))])
    rd.shuffle(sample)
    return sample

def f_trimodal_asym(size):
    std1 = 0.65
    std2 = 0.35
    std3 = 0.35
    mu1 = -1.7
    mu2 = 0
    mu3 = 1.3
    sample = np.concatenate([st.norm.rvs(mu1+0.08,std1,int(size*0.2)),st.norm.rvs(mu2+0.08,std2,int(size*0.6)),st.norm.rvs(mu3+0.08,std3,int(size*0.2))])
    rd.shuffle(sample)
    return sample

def f_trimodal_sym(size):
    std1 = 0.65
    std2 = 0.15
    std3 = std1
    mu1 = -1.3
    mu2 = 0
    mu3 = -mu1
    sample = np.concatenate([st.norm.rvs(mu1,std1,int(size*0.25)),st.norm.rvs(mu2,std2,int(size*0.5)),st.norm.rvs(mu3,std3,int(size*0.25))])
    rd.shuffle(sample)
    return sample

def f_student(size):
    return st.t.rvs(3,scale=0.585,size=size)

def f_laplace(size):
    return st.laplace.rvs(loc=0,scale=0.72,size=size)

def f_laplace_sharp(size):
    std1 = 0.2
    std2 = 1
    sample = np.concatenate([st.laplace.rvs(0,std1,int(size*0.5)),st.laplace.rvs(0,std2,int(size*0.5))])
    rd.shuffle(sample)
    return sample

def f_test1(size):
    std1 = 0.5
    std2 = 0.5
    sample = np.concatenate([st.norm.rvs(-0.9,std1,int(size*0.5)),st.norm.rvs(0.9,std2,int(size*0.5))])
    rd.shuffle(sample)
    return sample

def f_test2(size):
    std1 = 0.6
    std2 = 0.6
    sample = np.concatenate([st.norm.rvs(-1.05+0.62,std1,int(size*0.8)), st.norm.rvs(1.05+0.62,std2,int(size*0.2))])
    rd.shuffle(sample)
    return sample


# -*- coding: utf-8 -*-
"""
Compute areal categorical statistics on a space-time raster dataset based on
an input polygon.
"""

import pickle
import tempfile
from datetime import datetime
from copy import deepcopy
from flask import jsonify, make_response
from flask.json import dumps
from actinia_core.processing.actinia_processing.ephemeral_processing import (
    EphemeralProcessing,
)
from actinia_core.rest.base.resource_base import ResourceBase
from actinia_core.core.common.redis_interface import enqueue_job
from actinia_core.core.common.exceptions import AsyncProcessError
from flask_restful_swagger_2 import swagger
from actinia_core.core.common.app import auth
from actinia_core.core.common.api_logger import log_api_call
from .response_models import (
    CategoricalStatisticsResultModel,
    RasterAreaStatsResponseModel,
)
from actinia_core.models.response_models import ProcessingErrorResponseModel

__license__ = "GPLv3"
__author__ = "Sören Gebbert"
__copyright__ = "Copyright 2016, Sören Gebbert"
__maintainer__ = "Sören Gebbert"
__email__ = "soerengebbert@googlemail.com"

SCHEMA_DOC = {
    "tags": ["STRDS Statistics"],
    "description": "Compute areal categorical statistics on a raster map "
    "layer contained in a "
    "space-time raster dataset based on an input polygon. "
    "The input polygon must be provided as GeoJSON content"
    " in the request body. A correct "
    "coordinate reference system must be present in the GeoJSON definition. "
    "For each category the "
    "size of the occupied area, the number of pixel of the area and the "
    "percentage of the area size "
    "in relation to all other categories inclusive NULL data are computed. "
    "Minimum required user role: user.",
    "consumes": ["application/json"],
    "parameters": [
        {
            "name": "location_name",
            "description": "The location name",
            "required": True,
            "in": "path",
            "type": "string",
        },
        {
            "name": "mapset_name",
            "description": "The name of the mapset that contains the required "
            "space-time raster dataset",
            "required": True,
            "in": "path",
            "type": "string",
        },
        {
            "name": "strds_name",
            "description": "The name of the space-time raster dataset to "
            "select the raster map layer from",
            "required": True,
            "in": "path",
            "type": "string",
        },
        {
            "name": "timestamp",
            "description": "The time stamp that should be used for raster map "
            "layer selection. "
            "Required format is: YYYY-MM-DDTHH:MM:SS for example "
            "2001-03-16T12:30:15.",
            "required": True,
            "in": "path",
            "type": "string",
            "format": "dateTime",
        },
        {
            "name": "shape",
            "description": "GeoJSON definition of the polygon to compute the "
            "statistics for. The .",
            "required": True,
            "in": "body",
            "schema": {"type": "string"},
        },
    ],
    "responses": {
        "200": {
            "description": "The result of the areal raster statistical "
            "computation",
            "schema": RasterAreaStatsResponseModel,
        },
        "400": {
            "description": "The error message and a detailed log why raster "
            "statistic did not succeeded",
            "schema": ProcessingErrorResponseModel,
        },
    },
}

class AsyncEphemeralSTRDSAreaStatsResource(ResourceBase):
    """
    Compute area statistics based on a vector map for a single raster layer
    that is temporally sampled from a STRDS by a timestamp.
    """

    decorators = [log_api_call, auth.login_required]

    def _execute(self, location_name, mapset_name, strds_name, timestamp):
        """Prepare and enqueue the raster area statistics

        Raises:
            InvalidUsage: In case the timestamp is wrong or the XML content
                          is missing
        """
        # Check the time stamp
        try:
            datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S")
        except ValueError:
            msg = (
                "Wrong timestamp format. Required format is: "
                "YYYY-MM-DDTHH:MM:SS for example 2001-03-16T12:30:15"
            )
            return self.get_error_response(message=msg)

        rdc = self.preprocess(
            has_json=True,
            has_xml=False,
            location_name=location_name,
            mapset_name=mapset_name,
            map_name=strds_name,
        )
        if rdc:
            rdc.set_user_data(timestamp)
            enqueue_job(self.job_timeout, start_job, rdc)

        return rdc

    @swagger.doc(deepcopy(SCHEMA_DOC))
    def post(self, location_name, mapset_name, strds_name, timestamp):
        """
        Compute area statistics based on a vector map for a single raster
        layer that is temporally sampled from a STRDS by a timestamp.

        Raises:
            InvalidUsage: In case the timestamp is wrong or the XML content
                          is missing
        """
        self._execute(location_name, mapset_name, strds_name, timestamp)
        html_code, response_model = pickle.loads(self.response_data)
        return make_response(jsonify(response_model), html_code)

class SyncEphemeralSTRDSAreaStatsResource(
    AsyncEphemeralSTRDSAreaStatsResource
):
    """Compute area statistics based on a vector map for a single raster layer
    that is temporally sampled from a STRDS by a timestamp.
    """

    decorators = [log_api_call, auth.login_required]

    @swagger.doc(deepcopy(SCHEMA_DOC))
    def post(self, location_name, mapset_name, strds_name, timestamp):
        """Compute area statistics based on a vector map for a single raster
        layer that is temporally sampled from a STRDS by a timestamp.

        Raises:
            InvalidUsage: In case the timestamp is wrong or the XML content
                          is missing

        """
        check = self._execute(
            location_name, mapset_name, strds_name, timestamp
        )
        if check is not None:
            http_code, response_model = self.wait_until_finish()
        else:
            http_code, response_model = pickle.loads(self.response_data)
        return make_response(jsonify(response_model), http_code)

def start_job(*args):
    processing = AsyncEphemeralSTRDSAreaStats(*args)
    processing.run()

class AsyncEphemeralSTRDSAreaStats(EphemeralProcessing):
    """
    Compute area statistics based on a vector map for a single raster layer
    that is temporally sampled from a STRDS by a timestamp.
    """

    def __init__(self, *args):
        EphemeralProcessing.__init__(self, *args)
        self.response_model_class = RasterAreaStatsResponseModel

    def _execute(self):

        self._setup()

        strds_name = self.map_name
        timestamp = self.rdc.user_data

        self.required_mapsets.append(self.mapset_name)
        gml_file = tempfile.NamedTemporaryFile(
            dir=self.temp_file_path, delete=True
        )

        tmp_file = open(gml_file.name, "w")
        tmp_file.write(dumps(self.request_data))
        tmp_file.close()

        pc = {
            "list": [
                {
                    "id": "v_import_1",
                    "module": "v.import",
                    "inputs": [
                        {
                            "param": "input",
                            "value": gml_file.name,
                        }
                    ],
                    "outputs": [
                        {
                            "param": "output",
                            "value": "polygon",
                        }
                    ],
                    "superquiet": True
                },
                {
                    "id": "t_create_2",
                    "module": "t.create",
                    "inputs": [
                        {
                            "param": "type",
                            "value": "stvds",
                        },
                        {
                            "param": "temporaltype",
                            "value": "absolute",
                        },
                        {
                            "param": "semantictype",
                            "value": "mean",
                        },
                        {
                            "param": "title",
                            "value": "Polygon",
                        },
                        {
                            "param": "description",
                            "value": "Polygon",
                        },
                    ],
                    "outputs": [
                        {
                            "param": "output",
                            "value": "polygon_stvds",
                        }
                    ],
                    "superquiet": True
                },
                {
                    "id": "t_register_3",
                    "module": "t.register",
                    "inputs": [
                        {
                            "param": "type",
                            "value": "vector",
                        },
                        {
                            "param": "input",
                            "value": "polygon_stvds",
                        },
                        {
                            "param": "maps",
                            "value": "polygon",
                        },
                        {
                            "param": "start",
                            "value": timestamp,
                        },
                        {
                            "param": "increment",
                            "value": "1 second",
                        },
                    ],
                    "flags": "i",
                    "superquiet": True
                },
                {
                    "id": "t_sample_4",
                    "module": "t.sample",
                    "inputs": [
                        {
                            "param": "sample",
                            "value": "polygon_stvds",
                        },
                        {
                            "param": "inputs",
                            "value": strds_name + "@" + self.mapset_name,
                        },
                        {
                            "param": "samtype",
                            "value": "stvds",
                        },
                        {
                            "param": "intype",
                            "value": "strds",
                        },
                    ],
                    "superquiet": True
                },
            ],
            "version": "1",
        }

        # Setup the grass environment, check the process chain and run the
        # modules
        self.skip_region_check = True
        process_list = (
            self._create_temporary_grass_environment_and_process_list(
                process_chain=pc, skip_permission_check=True
            )
        )
        self._execute_process_list(process_list)

        gml_file.close()

        # Extract raster name
        map_list = self.module_output_log[3]["stdout"]

        self.message_logger.debug("Maplist: " + str(map_list))
        # Check if a map was found
        try:
            raster_name = map_list.split("|")[1]
            # Select the first raster name from a list of names
            if "," in raster_name:
                raster_name = raster_name.split(",")[0]
        except Exception:
            raise AsyncProcessError(
                "No raster maps found for timestamp: " + timestamp
            )

        if raster_name == "None":
            raise AsyncProcessError(
                "No raster maps found for timestamp: " + timestamp
            )

        result_file = tempfile.NamedTemporaryFile(
            dir=self.temp_file_path, delete=True
        )

        pc = {
            "list": [
                {
                    "id": "g_region_5",
                    "module": "g.region",
                    "inputs": [
                        {
                            "param": "vector",
                            "value": "polygon",
                        },
                        {
                            "param": "align",
                            "value": raster_name,
                        },
                    ],
                    "superquiet": True
                },
                {
                    "id": "r_mask_6",
                    "module": "r.mask",
                    "inputs": [
                        {
                            "param": "vector",
                            "value": "polygon",
                        }
                    ],
                    "superquiet": True
                },
                {
                    "id": "r_stats_7",
                    "module": "r.stats",
                    "inputs": [
                        {
                            "param": "input",
                            "value": raster_name,
                        },
                        {
                            "param": "separator",
                            "value": "|",
                        },
                    ],
                    "outputs": [
                        {
                            "param": "output",
                            "value": result_file.name,
                        }
                    ],
                    "flags": "acpl",
                    "superquiet": True
                },
            ],
            "version": "1",
        }

        # Check the process chain and run the modules
        self.skip_region_check = False
        process_list = self._validate_process_chain(
            process_chain=pc, skip_permission_check=True
        )
        self._execute_process_list(process_list)

        result = open(result_file.name, "r").readlines()

        output_list = []
        for line in result:
            stat_list = line.strip().split("|")

            output_list.append(
                CategoricalStatisticsResultModel(
                    cat=stat_list[0],
                    name=stat_list[1],
                    area=float(stat_list[2]),
                    cell_count=int(stat_list[3]),
                    percent=float(stat_list[4].split("%")[0]),
                )
            )

        self.module_results = output_list

        result_file.close()


from PyQt6.QtWidgets import QApplication, QToolButton, QMainWindow
from PyQt6.QtGui import QIcon
import sys

class ToolButtonClass(QMainWindow):

    def __init__(self):
        super(ToolButtonClass, self).__init__()

        self.detailsButton = QToolButton()
        self.toolbar = self.addToolBar("toolBar")

        self.initUI()

    def initUI(self):
        self.setWindowTitle("ToolButton")
        self.setGeometry(400, 400, 300, 260)

        self.detailsButton.setCheckable(True)
        self.detailsButton.setChecked(False)
        self.detailsButton.setIcon(QIcon("key.ico"))
        self.detailsButton.setAutoRaise(True)
        self.detailsButton.clicked.connect(self.showDetail)

        self.toolbar.addWidget(self.detailsButton)

    def showDetail(self):
        if self.detailsButton.isChecked():
            self.statusBar().showMessage("Show Detail....")
        else:
            self.statusBar().showMessage("Close Detail....")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ToolButtonClass()
    ex.show()
    sys.exit(app.exec())


import pandas as pd
from sklearn import preprocessing
import numpy as np
import random

def sample_rct(n_unc):
    df = pd.read_csv("actg175.csv", header=0, index_col=0)

    cd4_baseline = df['cd40']
    cd4_20 = df['cd420']

    outcome = (cd4_20 - cd4_baseline).values
    outcome_norm = preprocessing.scale(outcome)

    cov_cont = df[['age', 'wtkg', 'cd40', 'karnof', 'cd80']]
    cov_cont_norm = preprocessing.scale(cov_cont)

    cov_bin = df[['gender', 'homo', 'race', 'drugs', 'symptom', 'str2', 'hemo']]
    cov_bin_val = cov_bin.values
    t = df[['arms']].values

    data = np.concatenate((cov_cont_norm, cov_bin_val, t.reshape(-1,1), outcome_norm.reshape(-1,1)), axis=1)
    data.shape

    #Only focus on one arm (0=zidovudine, 1=zidovudine and didanosine, 2=zidovudine and zalcitabine,3=didanosine)
    t_1 = 2
    t_0 = 0
    t_ind = (t == t_0) + (t == t_1)

    data_rct = data[t_ind.flatten()]
    #change treatment sign to 1
    data_rct[:,-2] = np.where(data_rct[:,-2] == 2, 1, 0)

    #All data
    x_all = data_rct[:,:-2]
    t_all = data_rct[:,-2].reshape(-1,1)
    y_all = data_rct[:,-1].reshape(-1,1)

    #UNC selection
    ind_unc = random.sample(range(x_all.shape[0]), n_unc)
    x_unc = x_all[ind_unc, ]
    t_unc = t_all[ind_unc, ].reshape(-1,1)
    y_unc = y_all[ind_unc, ].reshape(-1,1)

    x_not_unc = np.delete(x_all, ind_unc, axis = 0)
    t_not_unc = np.delete(t_all, ind_unc)
    y_not_unc = np.delete(y_all, ind_unc)

    #CONF selection - balanced gender - take all females and sample male s.t. ~ balanced
    #Among males, introduce confounding
    ind_f = (x_not_unc[:, 5] == 0)
    ind_m = (x_not_unc[:, 5] == 1)

    ind_m_t = (t_not_unc == 1) * ind_m
    mean = y_not_unc[ind_m_t].mean()
    std = y_not_unc[ind_m_t].std()
    ind_m_t_upper = y_not_unc[ind_m_t] > mean

    x_m_t_upper = x_not_unc[ind_m_t,:][ind_m_t_upper,:]
    t_m_t_upper = t_not_unc[ind_m_t][ind_m_t_upper]
    y_m_t_upper = y_not_unc[ind_m_t][ind_m_t_upper]

    ind_m_c = (t_not_unc == 0) * ind_m
    mean = y_not_unc[ind_m_c].mean()
    std = y_not_unc[ind_m_c].std()
    ind_m_c_lower = y_not_unc[ind_m_c] < mean

    x_m_c_lower = x_not_unc[ind_m_c,:][ind_m_c_lower,:]
    t_m_c_lower = t_not_unc[ind_m_c][ind_m_c_lower]
    y_m_c_lower = y_not_unc[ind_m_c][ind_m_c_lower]

    x_f = x_not_unc[ind_f,:]
    t_f = t_not_unc[ind_f]
    y_f = y_not_unc[ind_f]

    x_conf = np.concatenate((x_m_t_upper, x_m_c_lower, x_f))
    t_conf = np.concatenate((t_m_t_upper, t_m_c_lower, t_f)).reshape(-1,1)
    y_conf = np.concatenate((y_m_t_upper, y_m_c_lower, y_f)).reshape(-1,1)

    x_test = x_not_unc
    t_test = t_not_unc.reshape(-1,1)
    y_test = y_not_unc.reshape(-1,1)

    return {'x_unc': x_unc, 't_unc': t_unc, 'y_unc': y_unc, 'x_conf': x_conf, 't_conf': t_conf, 'y_conf': y_conf, 'x_test': x_test, 't_test': t_test, 'y_test': y_test, 'x_all': x_all, 't_all': t_all, 'y_all': y_all}


import logging
from argparse import Namespace, ArgumentParser, RawTextHelpFormatter
import uvicorn

from wiki_searcher.utils import configure_logger

def parse_arguments() -> Namespace:
    parser = ArgumentParser(formatter_class=RawTextHelpFormatter)
    parser.add_argument("-d", "--debug", dest="debug", default=False, type=bool, help="Enable debug mode")

    return parser.parse_args()

def main():
    args = parse_arguments()
    logger = configure_logger(__package__)
    if args.debug:
        logger.setLevel(logging.DEBUG)
        logger.debug('Debug mode enabled')

    uvicorn.run("wiki_searcher.app:app", host='0.0.0.0', port=8000, reload=True, debug=True, workers=3)

if __name__ == "__main__":
    exit(main())


# This module is responsible for loading the data set and apply ao the data augmentation operations

import os
import os.path

from copy import deepcopy

import numpy as np
from scipy import ndimage

from skimage import data, io, filters, exposure
from skimage.util import random_noise, img_as_uint, invert
from skimage.transform import rotate

import random

from sys import platform as sys_pf
if sys_pf == 'darwin':
    import matplotlib
    matplotlib.use("TkAgg")

def print_data():
    print("Hello from dataset")

def get_faces(path='.'):
    """
    get_faces returns the faces in the data set
    @param path: the data set directory to read the data from. Each person must have a separate folder with
    its corresponding faces
    @return: a slice with each index pointing to a slice containing a person's faces
    """

    dataset = []

    # Get all files in directory except hidden files
    people = [file for file in os.listdir(path) if not file.startswith('.')]

    for person in people:
        person_path = os.path.join(path, person)

        faces = os.listdir(person_path)
        faces.sort()
        dataset.append([])

        for face in faces:
            file = os.path.join(person_path, face)
            img = io.imread(file)
            dataset[-1].append(img)

    return dataset

def enhance_data(dataset):
    """
    enhance_data creates synthetic data for a data set that doesn't have 10 faces per person
    It applies data augmentation techniques to a person's first face to generate new ones and append them into
    the person slice until it reaches 10 images
    @param dataset: the original data set
    @return: the data set after augmentation
    """

    augmented_dataset = deepcopy(dataset)
    for person in augmented_dataset:
        while len(person) < 10:
            # Noise insertion => needed to convert to uint16 type for saving in a file
            img_noised = random_noise(person[0], mode='pepper', amount=0.1)
            img_noised = exposure.rescale_intensity(img_noised, in_range='image', out_range='uint16')
            img_noised = img_noised.astype(np.uint16)
            person.append(img_noised)

            # Inversed colors
            img_inversed = np.invert(person[0])
            person.append(img_inversed)

            # Rotation by a random number of degrees => needed to convert to uint16 type for saving in a file
            angle = random.randint(-40, 40)
            img_rotated = rotate(person[0], angle, mode='edge')
            img_rotated = exposure.rescale_intensity(img_rotated, in_range='image', out_range='uint16')
            img_rotated = img_rotated.astype(np.uint16)
            person.append(img_rotated)

            # # Logarithmic correction
            img_log_correction = exposure.adjust_log(person[0], gain=1.0)
            person.append(img_log_correction)

            # Constrast changed
            v_min, v_max = np.percentile(person[0], (0.1, 60.0))
            img_better_constrast = exposure.rescale_intensity(person[0], in_range=(v_min, v_max))
            person.append(img_better_constrast)

            # Sigmoid correction
            img_sigmoid_correction = exposure.adjust_sigmoid(person[0])
            person.append(img_sigmoid_correction)

            # Horizontal flip
            img_horizontal_flip = person[0][:, ::-1]
            person.append(img_horizontal_flip)

            # Rotation by a random number of degrees => needed to convert to uint16 type for saving in a file
            angle = random.randint(-40, 40)
            img_rotated = rotate(img_horizontal_flip, angle, mode='edge')
            img_rotated = exposure.rescale_intensity(img_rotated, in_range='image',
                                                              out_range='uint16')
            img_rotated = img_rotated.astype(np.uint16)
            person.append(img_rotated)

            # Blur image => not working! There is a problem in the parameters of the function below...
            img_blured = ndimage.uniform_filter(person[0], size=5)
            person.append(img_blured)

    return augmented_dataset

def save_faces(dataset, path):
    """
    save_faces persists the data set. A new directory is created for each person in which the person's faces are
    stored as png files
    @param dataset: the data set to be saved. It must have the structure
        [
            [person_1_face1, person_1_face2, person_1_face3],
            [person_2_face1, person_2_face2, person_2_face3],
            [person_3_face1, person_3_face2, person_3_face3]

        ]
    @param path: the already existed directory where the data set will be saved
    @return:
    """

    for person, person_id in zip(dataset, range(1, len(dataset)+1)):
        person_path = os.path.join(path, "p" + str(person_id))

        try:
            os.makedirs(person_path, exist_ok=True)
        except OSError:
            print("ERROR creating the directory %s" % person_path)
            raise OSError

        for face, file_id in zip(person, range(1, len(person)+1)):
            image_path = os.path.join(person_path, str(file_id) + '.png')
            io.imsave(image_path, face)


import os
import shutil
import urllib
import pandas as pd
import django
import glob
import dateutil.parser
import sys

from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from datetime import datetime
from github import Github

from data.models import Report, Update
from data.keys import GITHUB_PASSWORD

def update():
    started_at = datetime.now()
    """
    g = Github('jackwsellers', GITHUB_PASSWORD)
    repo = g.get_repo('CSSEGISandData/COVID-19')
    reports = repo.get_contents(
        'csse_covid_19_data/csse_covid_19_daily_reports', 'master'
    )
    """
    files_dir = '{}/data/files'.format(os.getcwd())
    db_path = '{}/db.sqlite3'.format(os.getcwd())
    print(os.getcwd())
    print(files_dir)
    print(db_path)
    """
    try:
        shutil.rmtree(files_dir)
    except FileNotFoundError:
        pass

    os.mkdir(files_dir)

    for report in reports:
        url = report.download_url
        if url[-4:] == '.csv':
            urllib.request.urlretrieve(
                url, '{}/{}'.format(files_dir, url[-14:])
            )
            print(url[-14:])
    """
    files = glob.glob(os.path.join(files_dir, '*.csv'))

    for file_name in files:
        csv_data = pd.read_csv(file_name)
        csv_data = csv_data.fillna('')
        csv_data = csv_data.values.tolist()
        for row in csv_data:
            print(
                file_name[-14:][:-4], ',', row[0], ',', row[1], ',',
                row[2], ',', row[3], ',', row[4], ',', row[5]
            )
            try:
                last_update = dateutil.parser.parse(row[2])
                city = ''
                state = row[0]
                region = row[1]
                if row[3]:
                    confirmed = int(row[3])
                else:
                    confirmed = 0
                if row[4]:
                    deaths = int(row[4])
                else:
                    deaths = 0
                if row[5]:
                    recovered = int(row[5])
                else:
                    recovered = 0
            except ParserError:
                last_update = dateutil.parser.parse(row[4])
                city = row[1]
                state = row[2]
                region = row[3]
                if row[7]:
                    confirmed = int(row[7])
                else:
                    confirmed = 0
                if row[8]:
                    deaths = int(row[8])
                else:
                    deaths = 0
                if row[9]:
                    recovered = int(row[9])
                else:
                    recovered = 0
            report_needed = True
            try:
                old_report = Report.objects.get(
                    file_name=file_name[-14:][:-4],
                    city=city,
                    state=state,
                    region=region
                )
                if confirmed > old_report.confirmed:
                    old_report.delete()
                else:
                    report_needed = False
            except ObjectDoesNotExist:
                pass
            """
            if report_needed:
                new_report = Report.objects.create(
                    file_name=file_name[-14:][:-4],
                    city=city,
                    state=state,
                    region=region,
                    last_update=last_update,
                    confirmed=confirmed,
                    deaths=deaths,
                    recovered=recovered
                )
                new_report.save()
            """
    """
    ended_at = datetime.now()
    elapsed_time = ended_at - started_at
    update = Update.objects.create(
        started_at=started_at,
        ended_at=ended_at,
        elapsed_time=elapsed_time
    )
    update.save()
    """

update()


from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
import pandas as pd
import spacy
import PyPDF2
import en_core_web_sm
from nltk.sentiment.vader import SentimentIntensityAnalyzer

def extract_skills(resume_text):
    # nlp = en_core_web_sm.load()
    nlp = spacy.load('en_core_web_sm')
    nlp_text = nlp(resume_text)
    noun_chunks = nlp(resume_text).noun_chunks
    # removing stop words and implementing word tokenization
    tokens = [token.text for token in nlp_text if not token.is_stop]

    # reading the csv file
    data = pd.read_csv("skills.csv")

    # extract values
    skills = list(data.columns.values)

    skillset = []

    # check for one-grams (example: python)
    for token in tokens:
        if token.lower() in skills:
            skillset.append(token)

    # check for bi-grams and tri-grams (example: machine learning)
    for token in noun_chunks:
        token = token.text.lower().strip()
        if token in skills:
            skillset.append(token)

    return [i.capitalize() for i in set([i.lower() for i in skillset])]

class SkillExtractor(APIView):
    def post(self, request):
        fFileObj = open('Resume.pdf', 'rb')
        pdfReader = PyPDF2.PdfReader(fFileObj)
        pageObj = pdfReader.pages[0]
        resume = pageObj.extract_text()
        skills = extract_skills(resume)
        # print(skills)
        return Response({'data': skills})

class SentimentalModelAPI(APIView):
    def get(self, request):
        sid = SentimentIntensityAnalyzer()
        scores_negative = []
        scores_positive = []
        scores_neutral = []
        scores_compound = []
        sentence_sentiment_score = sid.polarity_scores(request.data.get('sentence','no'))
        scores_negative.append(sentence_sentiment_score['neg']*100)
        scores_positive.append(sentence_sentiment_score['neu']*100)
        scores_neutral.append(sentence_sentiment_score['pos']*100)
        scores_compound.append(sentence_sentiment_score['compound']*100)
        return Response({'-ve':scores_negative,'+ve':scores_positive,'meh':scores_neutral,'avg':scores_compound})


from dataclasses import dataclass
import os

@dataclass
class LfaInfo:
    endpoint_url: str
    bucket: str
    profile: str

def get_lfa() -> LfaInfo:
    """Get the LFA information from the LSST_DDS_PARTITION_PREFIX envvar

    Returns
    -------
    `LfaInfo`
        The information for the site LFA

    Raises
    ------
    RuntimeError
        If the value of LSST_DDS_PARTITION_PREFIX is not recognized
    """
    try:
        label = os.environ["LSST_DDS_PARTITION_PREFIX"]
        lfa = None
        if label == "tucson":
            lfa = LfaInfo("https://s3.tu.lsst.org", "rubinobs-lfa-tuc", "tts")
        if label == "base":
            lfa = LfaInfo("https://s3.ls.lsst.org", "rubinobs-lfa-ls", "bts")
        if label == "summit":
            lfa = LfaInfo("https://s3.cp.lsst.org", "rubinobs-lfa-cp", "summit")
        if lfa is not None:
            return lfa
        raise RuntimeError(f"Cannot provide EFD name for {label}.")
    except KeyError:
        raise RuntimeError("LSST_DDS_PARTITION_PREFIX not defined")