import torch
import torch.nn as nn
import math
import torch.utils.model_zoo as model_zoo
import torchvision.models as models
from operations import *

__all__ = ['ResNet', 'resnet50', 'resnet101','resnet152']

model_urls = {
    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',
}

class Bottleneck(nn.Module):
	expansion = 4

	def __init__(self, inplanes, planes, stride = 1, downsample = None, search = False, op_code = 'conv3d', conv_config = None):
		super(Bottleneck, self).__init__()
		self.conv1 = nn.Conv3d(inplanes, planes, kernel_size=1, bias=False)
		self.bn1 = nn.BatchNorm3d(planes)

		if op_code == 'conv3d':
			expand_ratio = 1
			self.convT = Conv3D(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1)
		elif op_code == 'conv2d':
			expand_ratio = 1
			self.convT = Conv2D(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1)
		elif op_code == 'convp3d':
			expand_ratio = 1
			self.convT = ConvP3D(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1)
		elif op_code == 'convst':
			if search:
				expand_ratio = 2
			else:
				expand_ratio = 1
			self.convT = ConvST(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)

		elif op_code == 'convst_dropout':
			if search:
				expand_ratio = 1
			else:
				expand_ratio = 1
			self.convT = ConvST_Dropout(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)
		elif op_code == 'conv1_2d_dropout':
			if search:
				expand_ratio = 1
			else:
				expand_ratio = 1
			self.convT = Conv1_2D_Dropout(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)
		elif op_code == 'conv1_2_3d_dropout':
			if search:
				expand_ratio = 1
			else:
				expand_ratio = 1
			self.convT = Conv1_2_3D_Dropout(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)

		elif op_code == 'mixconv1d':
			if search:
				expand_ratio = 3
			else:
				expand_ratio = 1
			self.convT = MixConv1D(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)
		elif op_code == 'mixconv2d':
			if search:
				expand_ratio = 3
			else:
				expand_ratio = 1
			self.convT = MixConv2D(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)
		elif op_code == 'mixconvall':
			if search:
				expand_ratio = 7
			else:
				expand_ratio = 1
			self.convT = MixConvAll(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)
		elif op_code == 'conv1_2d':
			if search:
				expand_ratio = 2
			else:
				expand_ratio = 1
			self.convT = Conv1_2D(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)
		elif op_code == 'conv2_3d':
			if search:
				expand_ratio = 2
			else:
				expand_ratio = 1
			self.convT = Conv2_3D(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)
		elif op_code == 'conv1_2_3d':
			if search:
				expand_ratio = 3
			else:
				expand_ratio = 1
			self.convT = Conv1_2_3D(planes, planes*expand_ratio, kernel_size = 3, stride = stride, padding = 1, conv_config = conv_config)
		else:
			raise NotImplementedError

		self.conv3 = nn.Conv3d(planes*expand_ratio, planes * self.expansion, kernel_size=1, bias=False)
		self.bn3 = nn.BatchNorm3d(planes * self.expansion)
		self.relu = nn.ReLU(inplace=True)
		self.downsample = downsample
		self.stride = stride

	def forward(self, x):
		residual = x

		out = self.conv1(x)
		out = self.bn1(out)
		out = self.relu(out)

		out = self.convT(out)

		out = self.conv3(out)
		out = self.bn3(out)

		if self.downsample is not None:
			residual = self.downsample(residual)

		out += residual
		out = self.relu(out)

		return out

class ResNet(nn.Module):

	def __init__(self, block, layers, num_classes=1000, search = False, op_code = 'conv3d', conv_config = None, conv_index = None):
		self.inplanes = 64

		self.search = search
		self.op_code = op_code
		if conv_config is None:
			conv_config = [None] * 200
		self.conv_config = conv_config

		super(ResNet, self).__init__()
		self.conv1 = nn.Conv3d(3, 64, kernel_size=(1,7,7), stride=(1,2,2), padding=(0,3,3),
							   bias=False)
		self.bn1 = nn.BatchNorm3d(64)
		self.relu = nn.ReLU(inplace=True)
		self.maxpool = nn.MaxPool3d(kernel_size=(1,3,3), stride=(1,2,2), padding=(0,1,1))
		self.layer1 = self._make_layer(block, 64,  layers[0], stride=1, search=search, op_code=op_code, conv_config=conv_config[:layers[0]])
		self.layer2 = self._make_layer(block, 128, layers[1], stride=2, search=search, op_code=op_code, conv_config=conv_config[layers[0]:layers[0]+layers[1]])
		self.layer3 = self._make_layer(block, 256, layers[2], stride=2, search=search, op_code=op_code, conv_config=conv_config[layers[0]+layers[1]:layers[0]+layers[1]+layers[2]])
		self.layer4 = self._make_layer(block, 512, layers[3], stride=2, search=search, op_code=op_code, conv_config=conv_config[layers[0]+layers[1]+layers[2]:layers[0]+layers[1]+layers[2]+layers[3]])
		self.avgpool = nn.AvgPool2d(7, stride=1)
		self.fc = nn.Linear(512 * block.expansion, num_classes)

		for m in self.modules():
			if isinstance(m, nn.Conv3d):
				nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
			elif isinstance(m, nn.BatchNorm3d):
				nn.init.constant_(m.weight, 1)
				nn.init.constant_(m.bias, 0)

	def _make_layer(self, block, planes, blocks, stride=1, search=False, op_code='conv3d', conv_config=None):
		downsample = None
		if stride != 1 or self.inplanes != planes * block.expansion:
			downsample = nn.Sequential(
				nn.Conv3d(self.inplanes, planes * block.expansion,
						  kernel_size=1, stride=(1,stride,stride), bias=False),
				nn.BatchNorm3d(planes * block.expansion),
			)

		layers = []
		layers.append(block(self.inplanes, planes, stride, downsample, search=search, op_code=op_code, conv_config=conv_config[0]))
		self.inplanes = planes * block.expansion
		for i in range(1, blocks):
			layers.append(block(self.inplanes, planes, stride=1, downsample=None,  search=search, op_code=op_code, conv_config=conv_config[i]))

		return nn.Sequential(*layers)

	def forward(self, x):
		x = self.conv1(x)
		x = self.bn1(x)
		x = self.relu(x)
		x = self.maxpool(x)

		x = self.layer1(x)
		x = self.layer2(x)
		x = self.layer3(x)
		x = self.layer4(x)
		x = x.transpose(1,2).contiguous()
		x = x.view((-1,)+x.size()[2:])

		x = self.avgpool(x)
		x = x.view(x.size(0), -1)
		x = self.fc(x)

		return x

def resnet50(**kwargs):
	"""Constructs a ResNet-50 based model.
	"""
	model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)
	checkpoint = model_zoo.load_url(model_urls['resnet50'])

	model_dict = model.state_dict()
	new_dict = {}
	#conv_index = kwargs['conv_index']

	### ImageNet pre-trained weight:
	for k, v in checkpoint.items():
		if 'conv' in k or 'downsample.0.weight' in k:
			v = v.unsqueeze(2)
		if 'bn2' in k:
			if kwargs['op_code'] == 'conv3d' or kwargs['op_code'] == 'conv2d':
				k = k.replace('bn2', 'convT.op.1')
			elif kwargs['op_code'] == 'convp3d':
				k = k.replace('bn2', 'convT.op.2')
			elif kwargs['op_code'] == 'convst' or kwargs['op_code'] == 'conv1_2d' or kwargs['op_code'] == 'conv2_3d':
				k = k.replace('bn2', 'convT.out.0')
				if kwargs['search']:
					v = v.repeat(2)
			elif kwargs['op_code'] == 'conv1_2_3d':
				k = k.replace('bn2', 'convT.out.0')
				if kwargs['search']:
					v = v.repeat(3)

			elif kwargs['op_code'] == 'convst_dropout':
				k = k.replace('bn2', 'convT.norm')
				if kwargs['search']:
					v = v.repeat(2)
			elif kwargs['op_code'] == 'conv1_2d_dropout':
				k = k.replace('bn2', 'convT.norm')
				if kwargs['search']:
					v = v.repeat(2)
			elif kwargs['op_code'] == 'conv1_2_3d_dropout':
				k = k.replace('bn2', 'convT.norm')
				if kwargs['search']:
					v = v.repeat(3)

			elif kwargs['op_code'] == 'mixconv1d':
				k = k.replace('bn2', 'convT.out.0')
				if kwargs['search']:
					v = v.repeat(3)
			elif kwargs['op_code'] == 'mixconv2d':
				k = k.replace('bn2', 'convT.out.0')
				if kwargs['search']:
					v = v.repeat(3)
			elif kwargs['op_code'] == 'mixconvall':
				k = k.replace('bn2', 'convT.out.0')
				if kwargs['search']:
					v = v.repeat(7)
		if 'conv2' in k:
			if kwargs['op_code'] == 'conv3d' or kwargs['op_code'] == 'conv2d' or kwargs['op_code'] == 'convp3d':
				k = k.replace('conv2', 'convT.op.0')
				if kwargs['op_code'] == 'conv3d':
					v = v.repeat(1,1,3,1,1) / 3.0
				if kwargs['op_code'] == 'convp3d':
					new_dict[k.replace('convT.op.0','convT.op.1')] = model_dict[k.replace('convT.op.0','convT.op.1')]

			elif kwargs['op_code'] == 'convst' or kwargs['op_code'] == 'convst_dropout' or kwargs['op_code'] == 'conv2_3d':
				k3d = k.replace('conv2', 'convT.convs.0.0')
				k2d = k.replace('conv2', 'convT.convs.1.0')
				if kwargs['search']:
					v3d = v.repeat(1,1,3,1,1) / 3.0
					v2d = v
				else:
					cout3d, _, _, _, _ = model_dict[k3d].size()
					cout2d, _, _, _, _ = model_dict[k2d].size()
					v3d = v[:cout3d,:,:,:,:].repeat(1,1,3,1,1) / 3.0
					v2d = v[cout3d:cout3d+cout2d,:,:,:,:]
				new_dict[k3d] = v3d
				new_dict[k2d] = v2d
				continue
			elif kwargs['op_code'] == 'conv1_2d' or kwargs['op_code'] == 'conv1_2d_dropout':
				k2d = k.replace('conv2', 'convT.convs.0.0')
				k1d = k.replace('conv2', 'convT.convs.1.0')
				if kwargs['search']:
					v2d = v
					v1d = torch.sum(torch.sum(v, dim=3, keepdim=True), dim=4, keepdim=True).repeat(1,1,3,1,1) / 3.0
				else:
					cout2d, _, _, _, _ = model_dict[k2d].size()
					cout1d, _, _, _, _ = model_dict[k1d].size()
					v2d = v[:cout2d,:,:,:,:]
					v1d = torch.sum(torch.sum(v[cout2d:cout2d+cout1d,:,:,:,:], dim=3, keepdim=True), dim=4, keepdim=True).repeat(1,1,3,1,1) / 3.0
				new_dict[k2d] = v2d
				new_dict[k1d] = v1d
				continue
			elif kwargs['op_code'] == 'conv1_2_3d' or kwargs['op_code'] == 'conv1_2_3d_dropout':
				k3d = k.replace('conv2', 'convT.convs.0.0')
				k2d = k.replace('conv2', 'convT.convs.1.0')
				k1d = k.replace('conv2', 'convT.convs.2.0')
				if kwargs['search']:
					v3d = v.repeat(1,1,3,1,1) / 3.0
					v2d = v
					v1d = torch.sum(torch.sum(v, dim=3, keepdim=True), dim=4, keepdim=True).repeat(1,1,3,1,1) / 3.0
				else:
					cout3d, _, _, _, _ = model_dict[k3d].size()
					cout2d, _, _, _, _ = model_dict[k2d].size()
					try:
						cout1d, _, _, _, _ = model_dict[k1d].size()
					except:
						pass
					v3d = v[:cout3d,:,:,:,:].repeat(1,1,3,1,1) / 3.0
					v2d = v[cout3d:cout3d+cout2d,:,:,:,:]
					try:
						v1d = torch.sum(torch.sum(v[cout3d+cout2d:cout3d+cout2d+cout1d,:,:,:,:], dim=3, keepdim=True), dim=4, keepdim=True).repeat(1,1,3,1,1) / 3.0
					except:
						pass
				new_dict[k3d] = v3d
				new_dict[k2d] = v2d
				try:
					if k1d in model_dict:
						new_dict[k1d] = v1d
				except:
					pass
				continue
			elif kwargs['op_code'] == 'mixconv1d':
				### v: cout,cin,1,3,3
				k311 = k.replace('conv2', 'convT.convs.0.0')
				k131 = k.replace('conv2', 'convT.convs.1.0')
				k113 = k.replace('conv2', 'convT.convs.2.0')
				if kwargs['search']:
					#v = torch.mean(torch.mean(v, dim=3, keepdim=True), dim=4, keepdim=True).repeat(1,1,3,1,1)
					v = torch.sum(torch.sum(v, dim=3, keepdim=True), dim=4, keepdim=True).repeat(1,1,3,1,1) / 3.0  ### use sum to keep scale?
					v311 = v
					v131 = v.permute(0,1,3,2,4)
					v113 = v.permute(0,1,4,3,2)
				else:
					v = torch.sum(torch.sum(v, dim=3, keepdim=True), dim=4, keepdim=True).repeat(1,1,3,1,1) / 3.0
					cout311, _, _, _, _ = model_dict[k311].size()
					cout131, _, _, _, _ = model_dict[k131].size()
					cout113, _, _, _, _ = model_dict[k113].size()
					v311 = v[:cout311,:,:,:,:]
					v131 = v[cout311:cout311+cout131,:,:,:,:].permute(0,1,3,2,4)
					v113 = v[cout311+cout131:cout311+cout131+cout113,:,:,:,:].permute(0,1,3,4,2)
				new_dict[k311] = v311
				new_dict[k131] = v131
				new_dict[k113] = v113
			elif kwargs['op_code'] == 'mixconv2d':
				k331 = k.replace('conv2', 'convT.convs.0.0')
				k133 = k.replace('conv2', 'convT.convs.1.0')
				k313 = k.replace('conv2', 'convT.convs.2.0')
				if kwargs['search']:
					v331 = v.permute(0,1,4,3,2)
					v133 = v
					v313 = v.permute(0,1,3,2,4)
				else:
					cout331, _, _, _, _ = model_dict[k331].size()
					cout133, _, _, _, _ = model_dict[k133].size()
					cout313, _, _, _, _ = model_dict[k313].size()
					v331 = v[:cout331,:,:,:,:].permute(0,1,4,3,2)
					v133 = v[cout331:cout331+cout133,:,:,:,:]
					v313 = v[cout331+cout133:cout331+cout133+cout313,:,:,:,:].permute(0,1,3,2,4)
				new_dict[k331] = v331
				new_dict[k133] = v133
				new_dict[k313] = v313

			elif kwargs['op_code'] == 'mixconvall':
				raise NotImplementedError

		if 'conv3' in k:
			if kwargs['search']:
				if kwargs['op_code'] == 'convst' or kwargs['op_code'] == 'conv1_2d' or kwargs['op_code'] == 'conv2_3d':
					### 2 times
					v = v.repeat(1,2,1,1,1)
				elif kwargs['op_code'] == 'mixconv1d' or kwargs['op_code'] == 'mixconv2d' or kwargs['op_code'] == 'conv1_2_3d':
					v = v.repeat(1,3,1,1,1)
				elif kwargs['op_code'] == 'mixconvall':
					v = v.repeat(1,7,1,1,1)

		if k in model_dict:
			new_dict[k] = v

	model.load_state_dict(new_dict)

	return model

def resnet101(**kwargs):
	"""Constructs a ResNet-101 model.
	Args:
		groups
	"""
	model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs)
	checkpoint = model_zoo.load_url(model_urls['resnet101'])
	layer_name = list(checkpoint.keys())
	for ln in layer_name:
		if 'conv' in ln or 'downsample.0.weight' in ln:
			checkpoint[ln] = checkpoint[ln].unsqueeze(2)
		# if 'conv2' in ln:
		# 	n_out, n_in, _, _, _ = checkpoint[ln].size()
		# 	checkpoint[ln] = checkpoint[ln][:n_out // alpha * (alpha - 1), :n_in//beta,:,:,:]
	model.load_state_dict(checkpoint,strict = False)

	return model

def load_state_dict_supernet(net, super_net_dict, conv_index):
	### for convST
	print('length of conv_index:', len(conv_index))
	index = 0
	net_dict = net.state_dict()
	flag1, flag2, flag3 = False, False, False
	print(list(super_net_dict.keys()))
	for k in net_dict:
		print(index, k)
		if 'convT.convs.0.0' in k: # 3d
			if flag1 and flag2 and flag3:
				index += 1
				flag1, flag2, flag3 = False, False, False
			indices = conv_index[index]['kxkxk']
			indices.sort()
			net_dict[k] = super_net_dict[k][indices,:,:,:,:]
			flag1 = True

		if 'convT.convs.1.0' in k: # 2d
			indices = conv_index[index]['1xkxk']
			indices.sort()
			net_dict[k] = super_net_dict[k][indices,:,:,:,:]
			flag2 = True

		if 'convT.out.0' in k: # bn
			if 'num_batches_tracked' in k:
				continue
			channels = super_net_dict[k].shape[0] // 2
			indices0 = conv_index[index]['kxkxk']
			indices1 = [ i+channels for i in conv_index[index]['1xkxk']]
			indices = indices0 + indices1
			net_dict[k] = super_net_dict[k][indices]
			flag3 = True

	net.load_state_dict(net_dict)
	return net


#自定义异常类，具有下列实例属性：
#  low: 合法范围的下限。
#  high: 合法范围的上限。
#  current: 合法范围之外的当前值。
class RangeError(Exception):
    def __init__(self, *args, low=0, high=100, current=-1):
        self.low = low
        self.high = high
        self.current = current
        super().__init__(*args)

    #重写魔术属性__str__。
    def __str__(self):
        extra = ('The legal range is ['
                + str(self.low) + ',' + str(self.high)
                + '], but the current value is '
                + str(self.current) + '. ')
        return extra + super().__str__()

#定义代表温度计的类。
class Thermometer():
    def __init__(self, temperature=0):
        if temperature < -20 or temperature > 50:
            e = RangeError('Out of range!', low=-20, high=50, current=temperature)
            e.add_note("Raise during initialization!")
            raise e
        self.temperature = temperature

    #改变温度计的温度。
    def change(self, delta):
        temperature = self.temperature + delta
        if temperature < -20 or temperature > 50:
            e = RangeError('Out of range!', low=-20, high=50, current=temperature)
            e.add_note("Raise during changing!")
            raise e
        self.temperature = temperature

    #以“-”、“0”、“+”和“@”绘制温度计读数。  四个“-”代表零下温度区域，十个“+”
    # 代表零上温度区域，“0”代表零度。  “@”代表当前温度，需要替换掉一个“-”、
    # “0”或“+”。
    def show(self):
        scale = '----0++++++++++'
        index = self.temperature//5 + 4
        marked_scale = scale[0:index] + '@' + scale[index+1:14]
        print(marked_scale)


import json
import statistics
import pandas
import os

def calculate_latest_closing_price_from_json(x):
    with open(x,"r") as f:
        file_contents = f.read()
        #print (type(file_contents))
        #print (file_contents)

    stock_price = json.loads(file_contents)
    print(stock_price)
    print(type(stock_price))

    # need last refreshed date and "4. closing price"

if __name__ == "__main__":
    print("PARSING SOME STOCK PRICES HERE...")

    aapl_filepath = os.path.join(os.path.dirname(__file__), "..", "data", "stock_prices_aapl.json")

    print(aapl_filepath)
    close_price = calculate_latest_closing_price_from_json(aapl_filepath)
    print(close_price)


#Aula 07/06 - Continuação do código da biblioteca

funcionarios = {}
def cadastrar_funcionario():
    nome = input('Digite o nome do funcionário: ')
    idade = int(input('Digite a idade do funcionário: '))
    cargo = input('Digite o cargo do funcionário: ')
    salario = float(input('Digite o sálario do funcionário: '))

    funcionario = {
        "nome": nome,
        "idade": idade,
        "cargo": cargo,
        "salario": salario
    }

    funcionarios[nome] = funcionario
    print('Funcionário cadastrado com sucesso!')

def exibir_funcionario():
    nome = input('Digite o nome dos funcionários: ')

    if nome in funcionarios:
        funcionario = funcionarios[nome]
        print('Dados do funcionários: ')
        print('Nome:', funcionario['nome'])
        print('Idade',funcionario['idade'])
        print('Cargo',funcionario['cargo'])
        print('salario',funcionario['salario'])
    else:
        print('Funcionário não encontrado.')

def exibir_funcionarios():
    if funcionarios:
        print('Lista de funcionários: ')
        for nome, funcionario in funcionarios.items():

            print('Nome:', funcionario['nome'])
            print('Idade',funcionario['idade'])
            print('Cargo',funcionario['cargo'])
            print('salario',funcionario['salario'])
            print("-"*30)

    else:
        print('Não há funcionários cadastrados.')

def remover_funcionario():
    nome = input("Digite o nome do funcionário: ")
    if nome in funcionarios[nome]:
        print("Funcionário removido com sucesso!")
    else:
        print("Funcionário não encontrado!")

while True:
    print("\n=== Sistema de cadastro de funcionários ===")
    print("1 - Cadastrar funcionário")
    print("2 - exibir dados de um funcionário")
    print("3 - exibir todos os funcionários cadastrados")
    print("4 - Remover funcionário")
    print("0 - Sair")

    opcao = input("Digite a opção desejada: ")
    if opcao == "1":
        cadastrar_funcionario()
    elif opcao == "2":
        exibir_funcionario()
    elif opcao == "3":
        exibir_funcionarios()
    elif opcao == "4":
        remover_funcionario()
    elif opcao == "0":
        print("Sessão finalizada!")
        break
    else:
        print("Opção inválida! digite novamente.")


import logging

from broker.brokers import Brokers
from broker_transaction_management_system.base_transaction_manager import BaseTransactionManager

class ZerodhaTransactionManager(BaseTransactionManager):

    def __init__(self) -> None:
        super().__init__(Brokers.ZERODHA)

    def test_connection(self):
        logging.info('%s: Going to test the broker connection',self.broker)
        kite = self.broker_handle
        try:
            profile = kite.profile()
            return profile
        except Exception as e:
            logging.info('%s Broker Connection failed: %s', self.broker, str(e))
            raise Exception(str(e))

    def get_orders(self):
        logging.info('%s: Going to fetch the user orders', self.broker)
        kite = self.broker_handle
        try:
            orders = kite.orders()
            return orders
        except Exception as e:
            logging.info('%s Failed to fetch the orders: %s',self.broker, str(e))
            raise Exception(str(e))

    def get_positions(self):
        logging.info('%s: Going to fetch the user positions', self.broker)
        kite = self.broker_handle
        try:
            positions = kite.positions()
            return positions
        except Exception as e:
            logging.info('%s Failed to fetch the positions: %s',self.broker, str(e))
            raise Exception(str(e))

    def get_holdings(self):
        logging.info('%s: Going to fetch the user holdings', self.broker)
        kite = self.broker_handle
        try:
            holdings = kite.holdings()
            return holdings
        except Exception as e:
            logging.info('%s Failed to fetch the holdings: %s',self.broker, str(e))
            raise Exception(str(e))


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

# ## Loops in Python
# > #### For and While
#
#

# ### For- Loop
#
# This is used to iterate over a sequence which may be **a List, a tuple, a dictionary, a set, or a string**
#
# _With for loop , you can perform a block of statement over a given sequence_
# > `for each_element in sequence:`
#         >> `block of statements`
#
# **Always take note of the indentation**

# #### Examples
# ##### **ACTIVITIES**
# - Print each score
# - Reduce each score using 0.8
# - store reduced values into a new variable(list) called new_scores
# - Find the average of the score
# - Store average value into variable called avg_score
# - Any score less than 50 should be removed from the new list

# In[20]:

scores_of_students = [34,56,88,90,34,67]
new_scores = []
total = 0

score_length = len(scores_of_students)
for each_score in scores_of_students:
    print(each_score)
    new_scores.append(each_score*0.8)
    total = total + each_score
#print(scores_of_students)
print("Created Scores")
print(new_scores)

avg_score = total / length
#print(total)
#print(avg_score)

for new_each_score in new_scores:
    if float(new_each_score) < 50.0:
        new_scores.remove(new_each_score)

print("refined Scores")
print(new_scores)

# #### Introduction to range
#
# ###### ACTIVITIES
# - What is range
# > `range(start, end, increment)`
# - Print out an example using range
# - Apply range to a for loop

# In[25]:

for each_value in range(1,20,2):
    print(each_value, end=",")

# #### Deeper in **for** loop
# ##### ACTIVITIES
# - Iterate over other sequential data types (string, tuple and dictionary)
# - For the dictionary print the following
#     > - The Keys
#     > - The Values
#     > - The Sum of all the values
# - Introduce us to **break** and **continue**

# In[32]:

fav_fruit = "pineapple"
fav_fruits = ("Banana", "Apple", "Orange", "Guava")
fav_fruits_dict = {"Banana": 5, "Apple": 2, "Orange": 7, "Guava": 6}
for each_fruit in fav_fruits_dict:
    sumo += fav_fruits_dict[each_fruit]
print(sumo)

# #### Break and Continue
# > Use the List of scores above
#
# ##### ACTIVITIES
#  - Explain the concept of break and continue
#  - Excecute example

# In[34]:

scores_of_students = [34,56,88,190,34,67]
for each_score in scores_of_students:
    if each_score > 100:
        print("error in the list")
        break;
    elif each_score > 50:
        print("Score %d is excellent" %each_score)
        continue
    print(each_score)

# #### Nexted Loop
# ##### ACTIVITIES
# - Explain and examples

# In[36]:

fav_fruits = ("Banana", "Apple", "Orange", "Guava")
colors= ('red', 'green','yellow')
for each_fruit in fav_fruits:
    print(each_fruit)
    for color in colors:
        print(color)
    print("Done with inner loop")
print("Done with outer loop")

# #### Pass
# > Take Note: for loop cannot be empty, hence we use pass

# In[37]:

for each_fruit in fav_fruits:
    pass

# ## While - Loops

# In[40]:

a = 1
while a <= 20:
    print(a, end=',')
    a+=1
print("end of loop")

# ### Take Note
# **You can also apply break and continue functionilty to while loop**

# In[43]:

a = 5
while a < 20:
    a+=1
    print(a, end=',')
    if a == 10:
        print("we have gotten to 10 ooo")
        break

# In[ ]:


#!/usr/bin/env python3
import os
import re
from termcolor import colored
import constants
import sys

def searchAll(regs, data):
    matches = []
    for r in regs:
        if type(r) is str:
            r = r.encode()
            mo = re.findall(r, data, re.IGNORECASE)
        else:
            # it was case-sensitive
            mo = re.findall(r, data)
        if len(mo) > 0:
            for m in mo:
                m = m.decode()
                if m not in matches:
                    matches.append(m)
    if len(matches) > 0:
        return matches

def searchWeak(key, dir):
    print(colored('Searching for {}...'.format(key), 'green'))

    for (dirpath, dirnames, filenames) in os.walk(dir, followlinks=True):
        for names in filenames:
            path = '{}/{}'.format(dirpath, names)
            if os.path.isfile(path):
                try:
                    with open(path, 'rb') as f:
                        data = f.read()
                        # break when one family has matched for this file
                        for patterFamily in constants.PATTERNS[key]:
                            res = searchAll(patterFamily[1], data)
                            if res is not None:
                                for m in res:
                                    m = "\t{} : Found pattern '{}'".format(path, m)
                                    sev = patterFamily[0]
                                    if sev == constants.severity.INFO:
                                        print(colored(m, 'green'))
                                    elif sev == constants.severity.WARNING:
                                        print(colored(m, 'yellow'))
                                    elif sev == constants.severity.CRITIC:
                                        print(colored(m, 'red'))
                                    else:
                                        print(m)
                                break
                except PermissionError:
                    print("Skipping, {} : Permission denied".format(path))

if __name__ == "__main__":

    if len(sys.argv) != 2:
        print('Usage : {} <dir>'.format(sys.argv[0]))
        sys.exit(0)

    dir = sys.argv[1]

    if not os.path.isdir(dir):
        print(colored("The directory specified doesn't exist", 'red'))
        sys.exit(0)

    for key in constants.PATTERNS:
        searchWeak(key, dir)


import platform
import time
import traceback
import zlib

import asyncwebsockets
import trio

from ..api.events import EventHandler
from ..utils import encoder, decoder
from ..utils import get_libname, API

class ShardConnection:
    """Represents a websocket connection to a shard."""

    DISPATCH = 0
    HEARTBEAT = 1
    IDENTIFY = 2
    PRESENCE = 3
    VOICE_STATE = 4
    VOICE_PING = 5
    RESUME = 6
    RECONNECT = 7
    REQUEST_MEMBERS = 8
    INVALID_SESSION = 9
    HELLO = 10
    HEARTBEAT_ACK = 11
    GUILD_SYNC = 12

    def __init__(self, client=None, shard_id=None, shard_max=None):
        self.ws = None
        self.alive = False
        self.sequence = None
        self.client = client
        self.is_resume = False
        self.session_id = None
        self.heartbeat_acked = True
        self.handler = EventHandler(self)
        self.shard_info = [shard_id, shard_max]

    async def close(self, code=1000, reason=''):
        if not self.alive:
            return
        self.alive = False
        if self.ws is not None:
            offline = {
                'game': None,
                'afk': False,
                'since': None,
                'status': 'offline'
            }
            await self.send(self.PRESENCE, offline)
            await self.ws.close()

    async def send(self, op=DISPATCH, d=None):
        if self.ws is not None:
            data = encoder({'op': op, 'd': d})
            await self.ws.send_message(data)

    async def ping(self, data=None):
        start = time.time()
        if self.ws is not None:
            await (await self.ws.ping(data))
        return (time.time() - start) * 1000., data

    async def heartbeat(self, interval, nursery):
        await trio.sleep(interval)
        if self.ws is not None:
            if self.heartbeat_acked:
                self.heartbeat_acked = False
                await self.send(self.HEARTBEAT, self.sequence)
                nursery.start_soon(self.heartbeat, interval, nursery)
            else:
                await self.ws.close()

    async def resume(self):
        """ Send resume packet """
        payload = {
            'token': self.client.token,
            'session_id': self.session_id,
            'seq': self.sequence
        }
        await self.send(self.RESUME, payload)

    async def identify(self):
        """Send identification packet"""
        payload = {
            'token': self.client.token,
            'properties': {
                '$os': platform.system(),
                '$browser': get_libname(),
                '$device': get_libname()
            },
            'compress': True,
            'large_threshold': 250,
        }

        if not self.client.is_bot:
            payload['synced_guilds'] = []

        if self.shard_info != (None, None):
            payload['shards'] = self.shard_info

        await self.send(self.IDENTIFY, payload)

    async def read_data(self, nursery):
        """ Start reading data from websocket connection """
        if self.ws is None:
            return

        while True:
            try:
                # unpack data and save sequence number
                try:
                    data = (await self.ws.next_message()).data
                except:
                    await self.close()
                    self.client.running.set()
                    break
                if isinstance(data, bytes):
                    data = zlib.decompress(data, 15, 10490000).decode('utf-8')
                data = decoder(data)

                # handle collected data
                await self.client.emit('raw_data', data)
                await self.handle_data(data, nursery)

            # ignore websocket close exception
            except asyncwebsockets.WebsocketClosed:
                break

            # ignore asyncio cancellation exceptions
            except trio.Cancelled:
                break

            # handle any exceptions
            except:
                traceback.print_exc()
                break

    async def handle_data(self, data, nursery):
        """ handle websocket data """
        # extract message info
        self.sequence = data.get('s') or self.sequence
        op, data, event = data.get('op'), data.get('d'), data.get('t')

        # handle reconnect from gateway
        if op == self.RECONNECT:
            await self.ws.close()

        # handle heartbeat ack
        elif op == self.HEARTBEAT_ACK:
            self.heartbeat_acked = True

        # start session
        elif op == self.HELLO:
            interval = (data['heartbeat_interval'] - 100) / 1000.0
            nursery.start_soon(self.heartbeat, interval, nursery)
            await self.identify()

        # retry connecting if possible
        elif op == self.INVALID_SESSION:
            if data:
                await trio.sleep(5.0)
                await self.ws.close()
            else:
                self.sequence = None
                self.session_id = None
                await self.identify()

        # handle gateway events
        elif op == self.DISPATCH:
            handle = 'handle_{}'.format(event.lower())
            if hasattr(self.handler, handle):
                nursery.start_soon(getattr(self.handler, handle), data)

    async def start(self, url):
        """ Start long-term connection with gateway """
        self.alive = True
        url = url + "/" if not url.endswith('/') else url
        url += API.WS_ENDPOINT

        # start connection loop
        self.ws = await asyncwebsockets.connect_websocket(url)

        async with trio.open_nursery() as nursery:
            while self.alive:
                try:
                    await self.read_data(nursery)
                except KeyboardInterrupt:
                    await self.close()
                    self.client.running.set()
                except Exception as e:
                    await self.client.emit('error', e)


from vkbottle_types.responses import prettyCards
from typing import Optional, Any, List
from .base_category import BaseCategory

class PrettyCardsCategory(BaseCategory):
    async def create(
        self,
        owner_id: int,
        photo: str,
        title: str,
        link: str,
        price: Optional[str] = None,
        price_old: Optional[str] = None,
        button: Optional[str] = None,
        **kwargs
    ) -> prettyCards.CreateResponseModel:
        """prettyCards.create method
        :param owner_id:
        :param photo:
        :param title:
        :param link:
        :param price:
        :param price_old:
        :param button:
        """

        params = self.get_set_params(locals())
        response = await self.api.request("prettyCards.create", params)
        model = prettyCards.CreateResponse
        return model(**response).response

    async def delete(
        self, owner_id: int, card_id: int, **kwargs
    ) -> prettyCards.DeleteResponseModel:
        """prettyCards.delete method
        :param owner_id:
        :param card_id:
        """

        params = self.get_set_params(locals())
        response = await self.api.request("prettyCards.delete", params)
        model = prettyCards.DeleteResponse
        return model(**response).response

    async def edit(
        self,
        owner_id: int,
        card_id: int,
        photo: Optional[str] = None,
        title: Optional[str] = None,
        link: Optional[str] = None,
        price: Optional[str] = None,
        price_old: Optional[str] = None,
        button: Optional[str] = None,
        **kwargs
    ) -> prettyCards.EditResponseModel:
        """prettyCards.edit method
        :param owner_id:
        :param card_id:
        :param photo:
        :param title:
        :param link:
        :param price:
        :param price_old:
        :param button:
        """

        params = self.get_set_params(locals())
        response = await self.api.request("prettyCards.edit", params)
        model = prettyCards.EditResponse
        return model(**response).response

    async def get(
        self,
        owner_id: int,
        offset: Optional[int] = None,
        count: Optional[int] = None,
        **kwargs
    ) -> prettyCards.GetResponseModel:
        """prettyCards.get method
        :param owner_id:
        :param offset:
        :param count:
        """

        params = self.get_set_params(locals())
        response = await self.api.request("prettyCards.get", params)
        model = prettyCards.GetResponse
        return model(**response).response

    async def get_by_id(
        self, owner_id: int, card_ids: List[int], **kwargs
    ) -> prettyCards.GetByIdResponseModel:
        """prettyCards.getById method
        :param owner_id:
        :param card_ids:
        """

        params = self.get_set_params(locals())
        response = await self.api.request("prettyCards.getById", params)
        model = prettyCards.GetByIdResponse
        return model(**response).response

    async def get_upload_url(self, **kwargs) -> prettyCards.GetUploadURLResponseModel:
        """prettyCards.getUploadURL method"""

        params = self.get_set_params(locals())
        response = await self.api.request("prettyCards.getUploadURL", params)
        model = prettyCards.GetUploadURLResponse
        return model(**response).response


from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from discord.webhook.async_ import Webhook

if TYPE_CHECKING:
    from typing import Type, Optional

import aiohttp
import discord
import pytomlpp
import jishaku
from discord.ext import commands

from .webhook_logger import WebhookLogger

jishaku.Flags.FORCE_PAGINATOR = True
jishaku.Flags.NO_UNDERSCORE = True
jishaku.Flags.NO_DM_TRACEBACK = True

class Bot(commands.Bot):
    session: aiohttp.ClientSession
    context: Type[commands.Context]

    def __init__(self, session: aiohttp.ClientSession):
        self.logger = logging.getLogger(__name__)
        self.session = session
        self.config = pytomlpp.load("./config.toml")

        self.hook = Webhook.from_url(
            self.config["bot"]["keys"]["webhook"],
            session=session,
            bot_token=self.config["bot"]["keys"]["token"],
        )

        root = logging.getLogger()
        root.setLevel(logging.INFO)
        handler = logging.StreamHandler()
        handler.setFormatter(
            logging.Formatter("[%(asctime)s] [%(levelname)s] %(name)s: %(message)s")
        )
        root.addHandler(handler)
        handler = WebhookLogger(webhook=self.hook)
        handler.setFormatter(
            logging.Formatter("[%(asctime)s] [%(levelname)s] %(name)s: %(message)s")
        )
        root.addHandler(handler)

        intents = discord.Intents.default()
        intents.members = True

        super().__init__(
            **self.config["bot"]["config"],
            intents=intents,
            allowed_mentions=discord.AllowedMentions.none(),
        )

        for extension in self.config["bot"]["extensions"]:
            try:
                self.load_extension(extension)
            except commands.ExtensionError:
                self.logger.exception("failed to load extension `%s`", extension)
            else:
                self.logger.info("loaded extension `%s`", extension)

    async def get_context(
        self, message, *, cls: Optional[Type[commands.Context]] = None
    ):
        return await super().get_context(message, cls=cls or self.context)


import argparse

parser = argparse.ArgumentParser()

parser.add_argument(
    "-l, --limit",
    type=int,
    help="Max number of stocks to fetch; default 10000",
    default=10000,
    dest="limit"
)

parser.add_argument(
    "-d, --debug",
    type=bool,
    help="Show debug messages",
    default=True,
    dest="debug"
)

parser.add_argument(
    "-p, --print-output",
    type=bool,
    help="Print the scraped data in a tabular format",
    default=False,
    dest="print_output"
)

args = parser.parse_args()

def debug(message: str, force=False):
    if args.debug == True:
        lines = message.split('\n')
        for line in lines:
            print("*** ", line)


def solution(S):
    answer = []
    lst = []

    for i in range(1, len(S) // 2 + 2):
        s = 0
        e = i
        temp = []
        while True:
            temp.append(S[s:e])
            s = s + i
            e = e + i
            if e >= len(S):
                temp.append(S[s:])
                break
        lst.append(temp)

    answer_lst = []
    temp_lst = []
    t = ""

    for l in lst:
        temp_lst.append([l[0], 0])
        for e in l:
            if temp_lst[-1][0] == e:
                temp_lst[-1][1] += 1
            else:
                temp_lst.append([e, 1])

        # temp_lst길이계산
        if temp_lst:
            answer_lst = []
            for ll in temp_lst:
                if ll[1] == 1:
                    answer_lst.append(ll[0])
                else:
                    ll[1] = str(ll[1])
                    answer_lst.append(''.join(ll))

            answer.append(len(''.join(answer_lst)))
            temp_lst = []

    return min(answer)


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

# ___
#

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

get_ipython().run_line_magic('matplotlib', 'inline')

# ## Get the Data
# ** Read the 'KNN_Project_Data csv file into a dataframe **

projectData = pd.read_csv("KNN_Project_Data")

# **Check the head of the dataframe.**

projectData.head()

# Plot pairwise relationships in a dataset.
# hue='TARGET CLASS' --> Variable in `projectData` to map plot aspects to different colors.

sns.pairplot(projectData, palette='coolwarm')

from sklearn.preprocessing import StandardScaler

# ** Create a StandardScaler() object called scaler.**

scaler = StandardScaler()

# ** Fit scaler to the features.**

scaler.fit(projectData.drop('TARGET CLASS', axis=1))

# **Use the .transform() method to transform the features to a scaled version.**

scaled_features = scaler.transform(projectData.drop('TARGET CLASS', axis = 1))

# **Convert the scaled features to a dataframe and check the head of this dataframe to make sure the scaling worked.**

df_feature = pd.DataFrame(scaled_features, columns=projectData.columns[:-1])
df_feature.head()

# # Train Test Split
# **Use train_test_split to split your data into a training set and a testing set.**

from sklearn.model_selection import train_test_split

X = df_feature
y = projectData['TARGET CLASS']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=101)

# **Import KNeighborsClassifier from scikit learn.**

from sklearn.neighbors import KNeighborsClassifier

# **Create a KNN model instance with n_neighbors=1**
knn = KNeighborsClassifier(n_neighbors=1)

# **Fit this KNN model to the training data.**

knn.fit(X_train, y_train)

# **Use the predict method to predict values using your KNN model and X_test.**

prediction = knn.predict(X_test)

# ** Create a confusion matrix and classification report.**

from sklearn.metrics import classification_report, confusion_matrix

print(confusion_matrix(y_test, prediction))

print(classification_report(y_test, prediction))

# checking to see in what value of n_neighbor, the data will be predicted more accuretly
error_rate= []

for i in range(1,40):
    knn = KNeighborsClassifier(n_neighbors=i)
    knn.fit(X_train, y_train)
    prediction_I = knn.predict(X_test)
    error_rate.append(np.mean(prediction_I != y_test))

plt.figure(figsize=(10,6))
plt.plot(range(1,40), error_rate, color='blue', linestyle='--', marker='o', markerfacecolor='red' )

knn = KNeighborsClassifier(n_neighbors=31)
knn.fit(X_train, y_train)
prediction = knn.predict(X_test)

print(confusion_matrix(y_test, prediction))
print(classification_report(y_test, prediction))


class Solution(object):
    def plusOne(self, digits):
        """
        :type digits: List[int]
        :rtype: List[int]
        """
        for i in range(len(digits) - 1, -1, -1):
            index = i
            if digits[index] == 9:
                digits[index] = 0
                if index == 0:
                    digits.insert(0, 1)
                    return digits
            else:
                digits[index] = digits[index] + 1
                return digits

sol = Solution()
print(sol.plusOne([9, 9, 9, 9]))
print(sol.plusOne([1]))
print(sol.plusOne([7,4,5,6,4]))


from collections import namedtuple
import csv, os

from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from django.db.utils import IntegrityError
from django.contrib.gis.geos import Point

from api.models import ParkingViolation

class Command(BaseCommand):

    def __init__(self):
        self.parking_file = os.path.join(settings.ROOT_DIR.root, 'api/fixtures/parking_violations_sample.csv')
        super(Command, self).__init__()

    def handle(self, *args, **options):
        self.stdout.write(self.parking_file)
        self.stdout.write(self.style.NOTICE('Loading %s' % self.parking_file))

        Parking = namedtuple('Parking', 'x, y, objectid, rowid, holiday, violation_code, \
                            violation_description, location, rp_plate_state, body_style, \
                            address_id, streetsegid, xcoord, ycoord, filename, \
                            ticket_issue_datetime')

        parking_violations = (m for m in map(Parking._make, csv.reader(open(self.parking_file, "rU", encoding='utf-8'), delimiter='\t')))
        for violation in parking_violations:
            try:
                obj = ParkingViolation(
                        point = Point((float(violation.x), float(violation.y))),
                        objectid = violation.objectid,
                        rowid = violation.rowid,
                        holiday = violation.holiday,
                        violation_code = violation.violation_code,
                        violation_description = violation.violation_description,
                        address = violation.location,
                        rp_plate_state = violation.rp_plate_state,
                        body_style = violation.body_style,
                        address_id = violation.address_id,
                        streetsegid = violation.streetsegid,
                        xcoord = violation.xcoord,
                        ycoord = violation.ycoord,
                        filename = violation.filename,
                        ticket_issue_datetime = violation.ticket_issue_datetime,
                        )
                obj.save()
            except ValueError as ex:
                self.stdout.write(self.style.ERROR(violation.rowid))
                self.stdout.write(self.style.ERROR(ex))

            except IntegrityError as ex:
                self.stdout.write(self.style.ERROR(violation.rowid))
                self.stdout.write(self.style.ERROR(ex))

        self.stdout.write(self.style.SUCCESS('Loaded %s' % self.parking_file))


import requests
import time
import pyaudio
import numpy as np

def play_sonar_ping(frequency, duration, ping_rate):
    samples = (np.sin(2 * np.pi * frequency * np.arange(duration * 44100) / 44100)).astype(np.float32)
    modulator = np.sin(2 * np.pi * ping_rate * np.arange(duration * 44100) / 44100)
    modulated = samples * modulator * .0000000001

    p = pyaudio.PyAudio()

    stream = p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=True)
    stream.write(modulated.tobytes())

    stream.stop_stream()
    stream.close()
    p.terminate()

def refresh_browser(url, refresh_interval):
    while True:
        tim = time.ctime()
        try:
            response = requests.get(url)
            if response.status_code == 200:
                print(f"{tim}: Website is accessible. Response code: 200 OK")
                play_sonar_ping(500, .05, 30)
            elif response.status_code == 404:
                print(f"{tim}: 404")
            elif response.status_code == 502:
                print(f"{tim}: 502")
            else:
                print(f"{tim}: Website is accessible, but an unexpected response code was received: {response.status_code}")
        except requests.exceptions.RequestException as e:
            print(f"{tim}: Error connecting to the website:", e)

        time.sleep(refresh_interval)

if __name__ == "__main__":
    play_sonar_ping(500, .05, 30)
    url = "https://lcr.churchofjesuschrist.org/?lang=eng"
    refresh_interval = 20  # Refresh interval in seconds

    refresh_browser(url, refresh_interval)


from PyQt5.QtWidgets import *
import sys
import os
from os import listdir

folder_names = []
for entry_name in os.listdir('O:\Jobs'):
    entry_path = os.path.join('O:\Jobs', entry_name)
    if os.path.isdir(entry_path):
        folder_names.append(entry_name)

class Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QGridLayout()
        self.setLayout(layout)

        # auto complete options
        completer = QCompleter(folder_names)

        # create line edit and add auto complete
        self.lineedit = QLineEdit()
        self.lineedit.setCompleter(completer)
        layout.addWidget(self.lineedit, 0, 0)

app = QApplication(sys.argv)
screen = Window()
screen.show()
sys.exit(app.exec_())


from mongo import Mongo
import time
from datetime import datetime
import pymongo

def convert_to_datetime(date, time):
    # date 2015/10/6

    date_pieces = date.split("/")
    year = int(date_pieces[0])
    month = int(date_pieces[1])
    day = int(date_pieces[2])

    # time 07:44:15.001
    time_pieces = time.split(":")
    hour = int(time_pieces[0])
    minutes = int(time_pieces[1])
    seconds = int(float(time_pieces[2]))
    milli_seconds = int(1000000*(float(time_pieces[2])-seconds))

    return datetime(year,month,day,hour,minutes,seconds,milli_seconds)

ticks = Mongo("TenYearNote")

ticks.create_db()
ticks.create_col('raw_ticks')
mycol = ticks.mycol
# delete entries
x = mycol.delete_many({})
print(x.deleted_count," deleted")

# add documents
t1 = time.time()

mylist = []

with open('test_file.txt') as f:
    counter = 0
    lines = f.readlines()
    instrument='TYAH16'

    for i in lines:
        if counter > 0:
            words = i.split(", ")
            my_dict = {'datetime':convert_to_datetime(words[0], words[1]),'instrument':instrument,
                      'price':words[2],'volume':int(words[6]),'delta':int(words[9]) - int(words[8])}

            mylist.append(my_dict)
        counter += 1

ticks.add_documents(mylist)

t2 = time.time()

print(t2-t1," seconds")
# ticks.create_index_datetime()
print(mycol.count_documents({}).__str__()," entries")

instrument = mylist[0]["instrument"]
order=1
aggregate_string = [{"$match":{"instrument":instrument}},{"$sort":{"datetime":order}},{"$limit":1}]
x = mycol.aggregate(aggregate_string)
print(x)

#
# mylist = []
# with open('test_file2.txt') as f:
#     counter = 0
#     lines = f.readlines()
#     instrument='TYAH16'
#
#     for i in lines:
#         if counter > 0:
#             words = i.split(", ")
#             my_dict = {'datetime':convert_to_datetime(words[0], words[1]),'instrument':instrument,
#                       'price':words[2],'volume':int(words[6]),'delta':int(words[9]) - int(words[8])}
#
#             mylist.append(my_dict)
#         counter += 1
#
#
# ticks.add_documents(mylist)
# t2 = time.time()
#
# print(t2-t1," seconds")
# print(mycol.count_documents({}).__str__()," entries")


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

'''
/***************************************************************************
 Offline-MapMatching
                                 A QGIS plugin
 desciption of the plugin
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2018-08-08
        copyright            : (C) 2018 by Christoph Jung
        email                : jagodki.cj@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
'''

__author__ = 'Christoph Jung'
__date__ = '2018-08-08'
__copyright__ = '(C) 2018 by Christoph Jung'

# This will get replaced with a git SHA1 when you do a git archive

__revision__ = '$Format:%H$'
from PyQt5.QtCore import QCoreApplication, QUrl
from PyQt5.QtGui import QIcon
from qgis.core import (QgsProcessing,
                       QgsProcessingAlgorithm,
                       QgsProcessingParameterFeatureSource,
                       QgsProcessingParameterVectorLayer,
                       QgsProcessingParameterField,
                       QgsProcessingParameterString,
                       QgsProcessingParameterNumber,
                       QgsCoordinateReferenceSystem,
                       QgsProject,
                       QgsProcessingParameterFeatureSink,
                       QgsWkbTypes)
import processing
import time, os.path

class ClipNetworkAlgorithm(QgsProcessingAlgorithm):
    '''
    This is an example algorithm that takes a vector layer and
    creates a new identical one.

    It is meant to be used as an example of how to create your own
    algorithms and explain methods and variables used to do it. An
    algorithm like this will be available in all elements, and there
    is not need for additional work.

    All Processing algorithms should extend the QgsProcessingAlgorithm
    class.
    '''

    # Constants used to refer to parameters and outputs. They will be
    # used when calling the algorithm from another algorithm, or when
    # calling from the QGIS console.

    NETWORK = 'NETWORK'
    TRAJECTORY = 'TRAJECTORY'
    ORDER_FIELD = 'ORDER_FIELD'
    BUFFER_RADIUS = 'BUFFER_RADIUS'
    OUTPUT = 'OUTPUT'

    def initAlgorithm(self, config):
        '''
        Here we define the inputs and output of the algorithm, along
        with some other properties.
        '''

        self.addParameter(
            QgsProcessingParameterVectorLayer(
                self.NETWORK,
                self.tr('Network layer'),
                [QgsProcessing.TypeVectorLine]
            )
        )

        self.addParameter(
            QgsProcessingParameterVectorLayer(
                self.TRAJECTORY,
                self.tr('Trajectory layer'),
                [QgsProcessing.TypeVectorPoint]
            )
        )

        self.addParameter(
            QgsProcessingParameterField(
                self.ORDER_FIELD,
                self.tr('Order Trajectory by'),
                parentLayerParameterName=self.TRAJECTORY,
                type=QgsProcessingParameterField.Any
            )
        )

        self.addParameter(
            QgsProcessingParameterNumber(
                self.BUFFER_RADIUS,
                self.tr('Buffer radius around the Trajectory'),
                type=QgsProcessingParameterNumber.Double,
                defaultValue=0,
                minValue=0.0
            )
        )

        self.addParameter(
            QgsProcessingParameterFeatureSink(
                self.OUTPUT,
                self.tr('Clipped Network')
            )
        )

    def processAlgorithm(self, parameters, context, feedback):
        '''
        Here is where the processing itself takes place.
        '''
        start_time = time.time()

        #extract all parameters
        network_layer = self.parameterAsVectorLayer(
            parameters,
            self.NETWORK,
            context
        )

        trajectory_layer = self.parameterAsVectorLayer(
            parameters,
            self.TRAJECTORY,
            context
        )

        trajectory_order_field = self.parameterAsString(
            parameters,
            self.ORDER_FIELD,
            context
        )

        buffer = self.parameterAsDouble(
            parameters,
            self.BUFFER_RADIUS,
            context
        )

        (sink, dest_id) = self.parameterAsSink(
            parameters,
            self.OUTPUT,
            context,
            network_layer.fields(),
            QgsWkbTypes.LineString,
            network_layer.crs()
        )

        #init the progressbar
        max_count = 4
        counter = 0
        feedback.setProgress(int((counter / max_count) * max_count))

        #trajectory to path
        points_to_path = processing.run("qgis:pointstopath", {
            'INPUT':trajectory_layer,
            'ORDER_FIELD':trajectory_order_field,
            'GROUP_FIELD':None,
            'DATE_FORMAT':'',
            'OUTPUT':'memory:path'
        })
        counter += 1
        feedback.setProgress(int((counter / max_count) * max_count))
        if feedback.isCanceled():
            return {'canceled °o°': str(round(time.time() - start_time, 2))}

        #buffer path
        buffer = processing.run("native:buffer", {
            'INPUT':points_to_path['OUTPUT'],
            'DISTANCE':buffer,
            'SEGMENTS':5,
            'END_CAP_STYLE':0,
            'JOIN_STYLE':0,
            'MITER_LIMIT':2,
            'DISSOLVE':False,
            'OUTPUT':'memory:buffer'})
        counter += 1
        feedback.setProgress(int((counter / max_count) * max_count))
        feedback.pushInfo('created buffer successfully')
        if feedback.isCanceled():
            return {'canceled °o°': str(round(time.time() - start_time, 2))}

        #clip network
        clipped_network = processing.run("native:clip", {
            'INPUT':network_layer,
            'OVERLAY':buffer['OUTPUT'],
            'OUTPUT':'memory:clip'})
        counter += 1
        feedback.setProgress(int((counter / max_count) * max_count))
        feedback.pushInfo('clipped buffer successfully')
        if feedback.isCanceled():
            return {'canceled °o°': str(round(time.time() - start_time, 2))}

        #multipart to single part
        single_part_network = processing.run("native:multiparttosingleparts", {
            'INPUT':clipped_network['OUTPUT'],
            'OUTPUT':'memory:omm_clipped_network'})
        counter += 1
        feedback.setProgress(int((counter / max_count) * max_count))
        feedback.pushInfo('created single parts successfully')
        if feedback.isCanceled():
            return {'canceled °o°': str(round(time.time() - start_time, 2))}

        #add the result to the QGIS project
        sink.addFeatures(single_part_network['OUTPUT'].getFeatures())

        return {'OUTPUT': dest_id}

    def name(self):
        '''
        Returns the algorithm name, used for identifying the algorithm. This
        string should be fixed for the algorithm, and must not be localised.
        The name should be unique within each provider. Names should contain
        lowercase alphanumeric characters only and no spaces or other
        formatting characters.
        '''
        return 'clip_network'

    def helpUrl(self):
        '''
        Returns the URL for the help document, if a help document does exist.
        '''
        dir = os.path.dirname(__file__)
        file = os.path.abspath(os.path.join(dir, '..', 'help_docs', 'help.html'))
        if not os.path.exists(file):
            return ''
        return QUrl.fromLocalFile(file).toString(QUrl.FullyEncoded)

    def shortHelpString(self):
        '''Returns the text for the help widget, if a help document does exist.'''
        dir = os.path.dirname(__file__)
        file = os.path.abspath(os.path.join(dir, '..', 'help_docs', 'help_processing_clipping_network.html'))
        if not os.path.exists(file):
            return ''
        with open(file) as helpf:
            help=helpf.read()
        return help

    def displayName(self):
        '''
        Returns the translated algorithm name, which should be used for any
        user-visible display of the algorithm name.
        '''
        return self.tr('Clip Network')

    def group(self):
        '''
        Returns the name of the group this algorithm belongs to. This string
        should be localised.
        '''
        return self.tr(self.groupId())

    def groupId(self):
        '''
        Returns the unique ID of the group this algorithm belongs to. This
        string should be fixed for the algorithm, and must not be localised.
        The group id should be unique within each provider. Group id should
        contain lowercase alphanumeric characters only and no spaces or other
        formatting characters.
        '''
        return 'Preprocessing'

    def tr(self, string):
        return QCoreApplication.translate('Processing', string)

    def createInstance(self):
        return ClipNetworkAlgorithm()

    def icon(self):
        return QIcon(':/plugins/offline_map_matching/icons/clipping_icon.png')


import numpy as np
import skimage.io as sk
from pathlib import Path
from matplotlib import pyplot
from skimage import exposure

def vijay_linear_stretch(input_image):
    minimum = np.min(input_image)
    maximum = np.max(input_image)

    scaling_factor = 255/(maximum-minimum)
    stretch_image = np.zeros(np.shape(input_image))
    stretch_image = (scaling_factor * input_image)

    return stretch_image.astype(int)

def vijay_pow_stretch(input_image):
    maximum = np.max(input_image)
    input_image = input_image / maximum
    average = np.mean(input_image)
    exponent = ((np.log(2))/(np.log(1/average)))
    stretch_image = np.power(input_image, exponent)
    maximum1 = np.max(stretch_image)
    return stretch_image * (255/maximum1)

def vijay_histogram_equalization(input_image, clipping=True):
    [freq1, bins] = exposure.histogram(input_image)
    if clipping:
        clip_limit = np.mean(freq1) * 1.5
        count1 = 1
        freq = freq1.copy()
        while count1:
            freq[freq > clip_limit] == clip_limit
            count = np.count_nonzero(freq1)
            diff = freq1 - freq
            count1 = np.count_nonzero(diff)
            distribution_average = np.sum(diff)/count
            freq = freq + distribution_average
            freq[freq1 == 0] == 0

    else:
        freq = freq1
    pmf = freq/np.sum(freq)
    cdf = [sum([i for i in pmf[:x]]) for x in range(1, len(freq)+1)]
    bins = list(bins)

    def mapping(t):
        return cdf[bins.index(t)]

    he_image = np.vectorize(mapping)(input_image)
    return he_image * 255

def vijay_clahe_equalization(input_image):
    size = np.shape(input_image)
    small_window_size = [int(size[0] / 8), int(size[1] / 8)]

    ahe_input_image = np.zeros(size)
    for i in range(0, size[0], small_window_size[0]):
        for j in range(0, size[1], small_window_size[1]):
            ahe_input_image[i:i + small_window_size[0], j:j + small_window_size[1]] = vijay_histogram_equalization(
                input_image[i:i + small_window_size[0], j:j + small_window_size[1]])

    def overlap_mapping(over_pixel, stone_pixel):
        if over_pixel:
            return (over_pixel + stone_pixel) / 2
        else:
            return stone_pixel

    overlap_ahe_input_image = np.zeros(size)
    overlap_percent = [int(small_window_size[0] / 4), int(small_window_size[1] / 4)]
    for i in range(0, size[0], small_window_size[0]):
        for j in range(0, size[1], small_window_size[1]):
            i_low = i - overlap_percent[0]
            i_high = i + small_window_size[0] + overlap_percent[0]
            j_low = j - overlap_percent[1]
            j_high = j + small_window_size[1] + overlap_percent[1]
            if 0 <= i_low <= i_high and 0 <= j_low <= j_high:
                overlap_ahe_input_image[i_low:i_high, j_low:j_high] = np.vectorize(overlap_mapping)(
                    overlap_ahe_input_image[i_low:i_high, j_low:j_high],
                    vijay_histogram_equalization(input_image[i_low:i_high, j_low:j_high]))
            elif 0 >= i_low and 0 <= j_low <= j_high:
                overlap_ahe_input_image[i:i_high, j_low:j_high] = np.vectorize(overlap_mapping)(
                    overlap_ahe_input_image[i:i_high, j_low:j_high],
                    vijay_histogram_equalization(input_image[i:i_high, j_low:j_high]))
            elif 0 <= i_low <= i_high and 0 >= j_low:
                overlap_ahe_input_image[i_low:i_high, j:j_high] = np.vectorize(overlap_mapping)(
                    overlap_ahe_input_image[i_low:i_high, j:j_high],
                    vijay_histogram_equalization(input_image[i_low:i_high, j:j_high]))
            else:
                overlap_ahe_input_image[i:i_high, j:j_high] = vijay_histogram_equalization(
                    input_image[i:i_high, j:j_high])
    return [ahe_input_image, overlap_ahe_input_image]

def vijay_rgb_contrast_stretch(input_image):
    sat_input_image = np.zeros(np.shape(input_image))
    sat_input_image = input_image.copy()

    sat_input_image[:, :, 0] = vijay_saturated_contrast_stretch(input_image[:, :, 0], 5, 40)
    sat_input_image[:, :, 1] = vijay_saturated_contrast_stretch(input_image[:, :, 1], 5, 40)
    sat_input_image[:, :, 2] = vijay_saturated_contrast_stretch(input_image[:, :, 2], 5, 30)

    linearly_stretch_input_image = input_image.copy()
    linearly_stretch_input_image[:, :, 0] = vijay_linear_stretch(input_image[:, :, 0])
    linearly_stretch_input_image[:, :, 1] = vijay_linear_stretch(input_image[:, :, 1])
    linearly_stretch_input_image[:, :, 2] = vijay_linear_stretch(input_image[:, :, 2])

    return [sat_input_image, linearly_stretch_input_image]

def vijay_saturated_contrast_stretch(input_image, low_percentage, high_percentage):
    histogram = exposure.histogram(input_image)
    total_freq = np.sum(histogram[0])
    low_sat_count = total_freq * low_percentage / 100
    high_sat_count = total_freq * high_percentage / 100
    temp = 0
    maximum = len(histogram[1])-1
    minimum = 0
    for i in range(0, len(histogram[1])):
        if temp > low_sat_count:
            minimum = i
            break
        else:
            temp += histogram[0][i]
    temp = 0
    for j in range(len(histogram[1]) - 1, 0, -1):
        if temp > high_sat_count:
            maximum = j
            break
        else:
            temp += histogram[0][j]

    final_image = input_image.copy()
    gain = 254 / histogram[1][maximum]
    final_image = final_image * gain
    final_image[input_image <= histogram[1][minimum]] = 0
    final_image[input_image >= histogram[1][maximum]] = 255

    return final_image

def vijay_resizing_image(input_image, resizing_factor, interpolation_method='bilinear'):
    size = np.shape(input_image)
    new_size = [round(size[0] * resizing_factor) - 1, round(size[1] * resizing_factor) - 1]
    resized_image = np.zeros(new_size)
    if interpolation_method == 'nearest' or resizing_factor <= 1:
        for i in range(new_size[0]):
            for j in range(new_size[1]):
                resized_image[i, j] = input_image[
                    int(np.floor(i / resizing_factor)), int(np.floor(j / resizing_factor))]
    else:
        for i in range(size[0] - 1):
            for j in range(size[1] - 1):
                x1 = int(i * resizing_factor)
                x2 = int((i + 1) * resizing_factor)
                y1 = int(j * resizing_factor)
                y2 = int((j + 1) * resizing_factor)

                co_mat = np.array(
                    [(1, x1, y1, x1 * y1), (1, x1, y2, x1 * y2), (1, x2, y1, x2 * y1), (1, x2, y2, x2 * y2)])
                b_mat = np.array(
                    [input_image[i, j], input_image[i, j + 1], input_image[i + 1, j], input_image[i + 1, j + 1]])
                a_mat = np.matmul(np.linalg.pinv(co_mat), np.transpose(b_mat))
                for m in range(x1, x2):
                    for n in range(y1, y2):
                        resized_image[m, n] = a_mat[0] + a_mat[1] * m + a_mat[2] * n + a_mat[3] * m * n

                [resized_image[x1, y1], resized_image[x1, y2], resized_image[x2, y1], resized_image[x2, y2]] = [
                    input_image[i, j], input_image[i, j + 1], input_image[i + 1, j], input_image[i + 1, j + 1]]

        return resized_image

def vijay_rotate_image(input_image, degree=90, interpolation_method='nearest'):
    theta = np.deg2rad(degree)
    size = np.shape(input_image)
    rotated_image = np.zeros([size[0] * 2, size[1] * 2])
    c_x, c_y = size[0] / 2, size[1] / 2
    if interpolation_method == 'nearest':
        for i in range(2 * size[0]):
            for j in range(2 * size[1]):
                a1 = round(((i - c_x - c_x) * np.cos(theta) - (j - c_y - c_y) * np.sin(theta)) + c_x)
                a2 = round(((i - c_x - c_x) * np.sin(theta) + (j - c_y - c_y) * np.cos(theta)) + c_y)
                if 0 < a1 < size[0] and 0 < a2 < size[1]:
                    rotated_image[i, j] = input_image[a1, a2]
    elif interpolation_method == 'bilinear':
        for i in range(size[0] - 1):
            for j in range(size[1] - 1):
                x1 = round(((i - c_x) * np.cos(theta) + (j - c_y) * np.sin(theta)) + 2 * c_x)
                y1 = round((-(i - c_x) * np.sin(theta) + (j - c_y) * np.cos(theta)) + 2 * c_y)
                x2 = round(((i - c_x + 1) * np.cos(theta) + (j - c_y + 1) * np.sin(theta)) + 2 * c_x)
                y2 = round((-(i - c_x + 1) * np.sin(theta) + (j - c_y + 1) * np.cos(theta)) + 2 * c_y)
                co_mat = np.array(
                    [(1, x1, y1, x1 * y1), (1, x1, y2, x1 * y2), (1, x2, y1, x2 * y1), (1, x2, y2, x2 * y2)])
                b_mat = np.array(
                    [input_image[i, j], input_image[i, j + 1], input_image[i + 1, j], input_image[i + 1, j + 1]])
                a_mat = np.matmul(np.linalg.pinv(co_mat), np.transpose(b_mat))
                for m in range(x1, x2):
                    for n in range(y1, y2):
                        rotated_image[m, n] = a_mat[0] + a_mat[1] * m + a_mat[2] * n + a_mat[3] * m * n

                [rotated_image[x1, y1], rotated_image[x1, y2], rotated_image[x2, y1], rotated_image[x2, y2]] = [
                    input_image[i, j], input_image[i, j + 1], input_image[i + 1, j], input_image[i + 1, j + 1]]
    return rotated_image


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.interpolate import splprep, splev
from scipy.stats import pearsonr
from math import sqrt,pi
from scipy import stats
import json

pair_to_num = {'Sujet1_Aurélie&Sujet2_Stanislas':'1',
	'Sujet1_Rémy&Sujet2_Margaux':'2',
	'Sujet1_Zaki&Sujet2_Yanis':'3',
	'Sujet1_Thanh&Sujet2_Diane':'4',
	'Sujet1_Sabrina&Sujet2_Quentin':'5',
	'Sujet1_Aniss&Sujet2_Louise':'6',
	'Sujet1_Hugo&Sujet2_Alexandre':'7',
	'Sujet1_Alexia&Sujet2_Bénédicte':'8',
	'Sujet1_Adénikè&Sujet2_Médéric':'9',
	'Sujet1_Anaïs&Sujet2_Mariem':'10',
	'Sujet1_Stéphane&Sujet2_Angélique':'11',
	'Sujet1_Fanny&Sujet2_William':'12',
	'Sujet1_Romane&Sujet2_Corentin':'13',
	'Sujet1_Paul&Sujet2_Mathieu':'14',
	'Sujet1_Marine&Sujet2_Hélène':'15',
	'Sujet1_Sébastien&Sujet2_Nils':'16',
	'Sujet1_Antoine&Sujet2_Médéric_LAAS':'17',
	'Sujet1_Amaury&Sujet2_Jason':'18',
	'Sujet1_Guilhem&Sujet2_César':'19',
	'Sujet1_Alexis&Sujet2_Thibaud':'20'}

traj_name = 'd1_p5_gris_1'
pair_name = 'Sujet1_Amaury&Sujet2_Jason'
pair_num = pair_to_num[pair_name]
N_0 = 50
N_OC = 100
leader = 'Sujet 1 et 2'

path_pred = "/local/imaroger/catkin_ws/src/prediction_table/src/data/prediction/"+\
	str(N_0) + "_" + str(N_OC) + "/" +\
	traj_name + "_" + pair_num + "_" + str(N_0) + "_" + str(N_OC) + ".dat"
pred = np.loadtxt(path_pred)

path_traj = "/local/imaroger/catkin_ws/src/trajectory_with_table/src/Data/Human/"+\
	traj_name + ".json"
f_traj = open(path_traj)
data = json.load(f_traj)['Trajectoires_Individuelles']['Table']

for i in range(len(data)):
	if data[i]["Leader"] == leader and data[i]["Binome"] == pair_name:
		data_x,data_y = data[i]["x"],data[i]["y"]
		data_th = data[i]["Orientation_Globale"]

for i in range(len(pred)):
	pred_x,pred_y,pred_th = pred[i][:N_OC+1],pred[i][N_OC+1:2*N_OC+2],pred[i][2*N_OC+2:3*N_OC+3]
	plt.plot(pred_x,pred_y,linewidth = 0.5)
plt.plot(data_x,data_y,color = "black")

plt.show()


import PIL.Image
import PIL.ImageTk
from random import randint
from tkinter import *
from functools import partial

def negatif(photo):
    '''fonction qui transforme une image en son négatif en soustraiant la valeur du pixel à 255. Prends en argument la photo trasformée par PIL'''
    taille=photo.size #obtiens la taille de la photo
    for i in range (taille[0]): #parcours chaque largeur
        for j in range (taille[1]): #parcours chaque hauteur
            pixel=photo.getpixel((i,j))#obtiens le pixel
            photo.putpixel((i,j),(255-pixel[0],255-pixel[1],255-pixel[2]))#transforme ce pixel en son inverse
    return photo

def filtrergb(photo,index):
    '''fonction qui applique un filtre rouge. Prends en argument une image transfromée pour pillow'''
    taille=photo.size
    for i in range (taille[0]): #parcours chaque largeur
        for j in range(taille[1]):#parcours chaque hauteur
            pixel=photo.getpixel((i,j))

            photo.putpixel((i,j),(pixel[0],0,0)) #transforme le pixel en rouge

    return photo

def NetB(photo, seuil):
    '''fonction qui transforme une image en sa version noir et blanc avec un seuil donné. On calcule le seuil de gris via une formule. Si ce seuil est plus grand que celui rentré par l'utilisateur, le pixel devient noir. Prends en arguments la photo trasformée par PIL et un nombre entier pour le seuil'''
    taille=photo.size
    for i in range (taille[0]): #parcours chaque largeur
        for j in range(taille[1]):#parcours chaque hauteur
            pixel=photo.getpixel((i,j))
            gray = int(round(0.299 * pixel[0] + 0.587 * pixel[1] + 0.114 * pixel[2] ))#calcule le gris
            if gray >= seuil :
                photo.putpixel((i,j),(0,0,0)) #transforme le pixel en pixel noir
            else:
                photo.putpixel((i,j),(255,255,255)) #transforme le pixel en pixel blanc
    return photo

def contour(photo,seuil):
    '''fonction qui transforme une image en sa version "contour" pour un seuil donné. Elle utilise la valeurs absolue de la moyenne de pixels pour définir si le pixel doit devenir blanc ou noir.Prends en arguments la photo trasformée par PIL et un nombre entier pour le seuil'''
    taille=photo.size
    taille = photo.size
    for i in range(0, taille[0] - 1):
        for j in range(0, taille[1] - 1):
            a = photo.getpixel((i, j))
            b = photo.getpixel((i + 1, j)) #obtiens le pixel a droite
            c = photo.getpixel((i, j + 1))#obtiens le pixel en bas
            if abs(moyennepixel(a) - moyennepixel(b)) > seuil or abs(moyennepixel(a) - moyennepixel(c)) > seuil: #calcule la valeur absolue et la compare au seuil
                photo.putpixel((i, j), (0, 0, 0)) #transforme le pixel en pixel noir
            else:
                photo.putpixel((i, j), (255, 255, 255))#transforme le pixel en pixel blanc
    return photo

def miroir(photo):
    '''fonction qui inverse l'image pour un effet miroir, cela en découpant la photo en 2 et en inversant les pixels. Prends en argument la photo trasformée par PIL'''
    taille=photo.size
    for i in range(int(taille[0]/2)): #pour la largeur de l'image divisée par 2
        for j in range(taille[1]):
            a=photo.getpixel((i,j))
            b=photo.getpixel((int(taille[0])-i-1,j)) #obtiens le pixel à l'opposé
            photo.putpixel((i,j),b)#met le pixel b à son opposé(le pixel a)
            photo.putpixel((int(taille[0])-i-1,j),a) #met le pixel a à son opposé (le pixel b)
    return photo

def resizing(photo,facteur):
    '''fonction qui redimensionne l'image pour un facteur donné. Prends en argument la photo trasformée par PIL et un float pour le facteur.'''
    taille=photo.size
    largeur=int(taille[0]*facteur) #crée la largeur de la nouvelle image
    hauteur=int(taille[1]*facteur) #crée la hauteur de la nouvelle image
    diffhauteur=taille[1]-hauteur-2 #calcule la différence de hauteur
    difflargeur=taille[0]-largeur-2 #calcule la différence de largeur
    newImage= PIL.Image.new('RGB',(largeur,hauteur)) #crée une nouvelle image avec ces données
    if facteur>1:
        newImage=photo.resize((largeur,hauteur)) #utilise un fonction pré-enregistrée pour augmenter la taille de l'image
    elif facteur<1:
        def créerindex(différence,tailleimg):
            '''crée une liste d'index de pixels d'une image'''
            liste=[]
            liste1=[]
            liste2=[]
            liste3=[]
            taille1=int(tailleimg/3) #divise l'image par 3
            taille2=int(taille1*2)
            for i in range(0,int(différence/3)):
                liste1.append(randint(0,taille1)) #ajoute des pixels du premier tier de l'image dans une liste
            liste.extend(liste1)#ajoute cette liste à une autre
            for i in range(0,int(différence/3)):#ajoute des pixels du 2ème tier de l'image dans une liste
                liste2.append(randint(taille1,taille2))
            for i in range(0,int(différence/3)):#ajoute des pixels du dernier tier de l'image dans une liste
                liste3.append(randint(taille2,tailleimg))
            liste.extend(liste2)
            liste.extend(liste3)
            return liste
        indexX=créerindex(diffhauteur,taille[1]-1)
        indexY=créerindex(difflargeur,taille[0]-1)
        b=0
        d=0
        for i in range(0,taille[0]-1):
            if i not in indexY: #si i n'est pas une des largeurs à supprimer
                for j in range (0,taille[1]-1):
                    if j not in indexX: #si j n'est pas une des hauteurs à supprimer
                        a=photo.getpixel((i,j))
                        newImage.putpixel((b,d),a) #met le pixel dans la nouvelle image
                        if d!=hauteur-1: #si la hauteur de la nouvelle image n'est pas dépassée, augmente de 1
                            d=d+1
                if b !=largeur-1:#si la largeur  de la nouvelle image n'est pas dépassée, l'incrémente de 1
                    b=b+1
                d=0 #réinitialise la hauteur
    return newImage

def moyennepixel(liste):
    '''fonction qui renvoie la moyenne de 2 pixels. Prend en argument un tuple ou une liste'''
    moyenne=0
    for i in range(0,len(liste)):#parcours toute la liste
        moyenne=moyenne+liste[i]
    moyenne=int(moyenne/len(liste)+1)
    return moyenne

def savephoto():
    '''fonction qui enregistre la photo. Ne prends pas d'arguments'''
    nom=modif+name #ajoute le nom à la liste des modifications
    photo.save(nom)

def checkboxes():
    '''fonction qui montre des cases à cocher et boutons dans l'interface tkinter. Ne prends pas d'arguments '''
    def changementsimage():
        '''fonction qui vérifié si les boutons ont été cochés et applique les filtres sélectionnés. Ne prends pas d'arguments'''
        global photo
        global modif
        if statusnegatif.get()==1: #vérifie si le bouton négatif est coché
            photo=negatif(photo)#éxécute la fonction
            modif=modif+'négatif' #ajoute négatif à une chaîne de caractère

        if statusNB.get()==1:
            seuilNB=int(entrerNB.get())
            photo=NetB(photo,seuilNB)
            modif=modif+'NetB'

        if statuscontour.get()==1:
            seuilContour=int(entrerContour.get())
            photo=contour(photo,seuilContour)
            modif=modif+'contour'

        if statusmiroir.get()==1:
            photo=miroir(photo)
            modif=modif+'miroir'

        if statusrouge.get()==1:
            photo=filtrergb(photo,0)
            modif=modif+'filtrerouge'

        if statusresize.get()==1:
            facteurresize=float(entrerfacteur.get())
            photo=resizing(photo,facteurresize)
            modif=modif+'resize'
        taillenew=photo.size

        if taillenew[0]>400: #si la largeur est supérieure à 400
            newlargeur=400
            newhauteur=int(newlargeur*taillenew[1]/taillenew[0]) #calcule la hauteur de l'image pour une largeur de 400
            photodisplay=photo.resize((newlargeur,newhauteur), PIL.Image.ANTIALIAS) #redimensionne l'image
            photoinTK=PIL.ImageTk.PhotoImage(photodisplay) #convertis pour tkinter
            cadreimage.configure(image=photoinTK)
            cadreimage.image=photoinTK #l'affiche dans le cadre
        else: #sinon affiche l'image dans le cadre
            newphotoinTK=PIL.ImageTk.PhotoImage(photo)
            cadreimage.configure(image=newphotoinTK)
            cadreimage.image=newphotoinTK

    cadreoptions=Frame(fenetre,width=100,height=70,borderwidth=2) #crée un cadre pour afficher les options
    cadreoptions.pack(side=RIGHT,expand=1)

    statusnegatif=IntVar()
    indication= Label(cadreoptions,text="Séléctionnez les options que vous souhaitez appliquer à l'image. Elles seront appliquées consécutivement") #explique le fonctionnement
    indication.pack(padx=20,pady=30) #espace le bouton
    negatifbutton= Checkbutton(cadreoptions,text='Négatif',variable=statusnegatif)#crée un bouton à cocher
    negatifbutton.pack(padx=5,pady=9,anchor='center',fill=X)#espace le bouton

    statusNB=IntVar()
    packNB= Frame(cadreoptions,width=60,height=60,borderwidth=2, relief="sunken")#crée un cadre pour contenir le bouton et le champ texte
    packNB.pack(padx=10,pady=20)
    NBbutton= Checkbutton(packNB,text='Noir Et Blanc',variable=statusNB)
    NBbutton.pack(padx=5,pady=4,anchor='center',fill=X)
    demandeNB= Label(packNB,text='Choix Du Seuil')
    demandeNB.pack(pady=3)
    entrerNB=Entry(packNB,width=10)#l'utilisateur rentre un seuil
    entrerNB.pack(pady=5)

    statuscontour=IntVar()
    packContour= Frame(cadreoptions,width=60,height=60,borderwidth=2, relief="sunken")
    packContour.pack(padx=10,pady=20)
    Contourbutton= Checkbutton(packContour,text='Contour',variable=statuscontour)
    Contourbutton.pack(padx=5,pady=4,anchor='center',fill=X)
    demandeContour= Label(packContour,text='Choix Du Seuil')
    demandeContour.pack(pady=3)
    entrerContour=Entry(packContour,width=10)
    entrerContour.pack(pady=5)

    statusmiroir=IntVar()
    miroirbutton= Checkbutton(cadreoptions,text='Miroir',variable=statusmiroir)
    miroirbutton.pack(padx=5,pady=9,anchor='center',fill=X)

    statusrouge=IntVar()
    rougebutton= Checkbutton(cadreoptions,text='Filtre rouge',variable=statusrouge)
    rougebutton.pack(padx=5,pady=9,anchor='center',fill=X)

    statusresize=IntVar()
    packderesize= Frame(cadreoptions,width=60,height=60,borderwidth=2, relief="sunken")
    packderesize.pack(padx=10,pady=20)
    resizebutton= Checkbutton(packderesize,text="Changement de taille (ne s'affiche pas dans l'apercu",variable=statusresize)
    resizebutton.pack(padx=5,pady=4,anchor='center',fill=X)
    demandefacteur= Label(packderesize,text='Facteur de redimensionnement')
    demandefacteur.pack(pady=3)
    entrerfacteur=Entry(packderesize,width=10)
    entrerfacteur.pack(pady=5)

    global modif
    modif='' #crée une chaîne de caractère qui contiendra l'ensemble des modifications

    boutonvalid= Button(cadreoptions,text="Valider",command=changementsimage) #lance le processus de modification
    boutonvalid.pack(pady=40,padx=20)

    boutonsave=Button(cadreoptions,text="Sauvegarder dans le dossier",command=savephoto) #sauvegarde la photo
    boutonsave.pack(pady=10,padx=20)

def displayimg(namebutton):
    '''fontion qui montre l'image sélectionnée dans une fênetre tkinter. Prends en argument un nom de bouton'''
    global cadreimage
    global name
    name=getEntry(namebutton)#obtiens le nom entré par l'utilisateur
    cadrenom.pack_forget()#cache le cadre pour rentrer le nom
    global photo
    photo= PIL.Image.open(name)#ouvre la photo
    global photoinTK
    photoinTK=PIL.ImageTk.PhotoImage(PIL.Image.open(name)) #convertis l'image pour l'afficher dans Tkinter
    taille=photo.size
    global cadreimage
    if taille[0]>400:#meme fonctionnement que dans changementsimage()
        newlargeur=400
        newhauteur=int(newlargeur*taille[1]/taille[0])
        photodisplay=photo.resize((newlargeur,newhauteur), PIL.Image.ANTIALIAS)
        photoinTK=PIL.ImageTk.PhotoImage(photodisplay)
        cadreimage=Label(fenetre,image=photoinTK)
    else:
        cadreimage=Label(fenetre,image=photoinTK) #crée une fenetre pour récuperer l'image
    cadreimage.pack(side=LEFT, fill='both',expand="yes")
    checkboxes()

def getEntry(var):
    """obtiens le résultat de l'Entry et le retourne sous forme de chaîne de caractères. Prends en argument un nom de variable"""
    name= var.get()
    return str(name)

fenetre= Tk()
fenetre.title('Photoshop Maison')

def askname():
    '''fonction qui demande le nom de l'image grâce à une ihm. Pas d'arguments'''
    #créer un cadre pour demander le nom de l'image
    global cadrenom
    cadrenom=Frame(fenetre,width=90,height=70,borderwidth=1)
    cadrenom.pack(side=LEFT)

    #demander le nom du fichier
    name_label=Label(cadrenom,text="Saissisez le nom de votre image contenue dans le dossier avec l'extension")
    name_label.pack()
    select_photo= Entry(cadrenom,width=30) #l'utilisateur écrit
    select_photo.pack()
    select_photo.focus_set()
    valider_name=Button(cadrenom,text="Valider",command=partial(displayimg,select_photo))#l'utilisateur valide ce qu'il a écrit
    valider_name.pack()

askname() #demande le nom de l'image. Première étape de l'IHM
fenetre.mainloop()#ne lis plus les lignes suivantes et lance l'IHM


from Graph import Graph
import csv
import requests
from bs4 import BeautifulSoup

class Country:

	def __init__(self, name, population):
		self.name = name
		self.population = population

def get_bordering_country_pairs():
	BASE_URL = "https://en.wikipedia.org/wiki/List_of_countries_and_territories_by_number_of_land_borders"
	soup = BeautifulSoup(requests.get(BASE_URL).content, "html.parser")
	i = 0
	pairs = []
	for row in soup.findAll('table')[0].tbody.findAll('tr'):
			if i > 1:
				cell1 = row.find("td").find("a").get_text()
				for c2 in row.findAll("td")[5].findAll("a", title=True):
					c2t = c2.get_text()
					if cell1 is not None and cell1 != "":
						pairs.append((cell1.encode('utf-8'), c2t.encode('utf-8')))
			i += 1
	return pairs

if __name__ == "__main__":

	info_path = r"C:\Users\thoma\Desktop\countries.csv"
	world_map = Graph()
	country_list_text = []
	border_list = get_bordering_country_pairs()

	with open(info_path) as csvfile:
		reader = csv.reader(csvfile, delimiter=',')
		for row in reader:
			country_list_text.append(row[0])

	vertices = set(country_list_text)
	edge_u = set(x[0] for x in border_list)
	edge_v = set(x[1] for x in border_list)

	country_dict = {}

	for a in country_list_text:
		country_dict[a] = a

	for x in border_list:
		country_dict[x[0]] = x[0]
		country_dict[x[1]] = x[1]

	countries = country_dict.keys()
	countries.sort()

	for_correction_set = list(set((edge_u - vertices) | (edge_v - vertices) | (vertices - edge_u) | (vertices - edge_v)))
	for_correction_set.sort()

	country_dict["People's Republic of China"] = "China"
	country_dict["C\xc3\xb4te d'Ivoire"] = "Ivory Coast"
	country_dict["Czechia (Czech Republic)"] = "Czech Republic"
	country_dict["Dominica"] = "Dominican Republic"
	country_dict["Eswatini (fmr. \"Swaziland\") "] = "Eswatini"
	country_dict["Holy See"] = "Vatican City"
	country_dict["Palestine State"] = "Palestine"
	country_dict["The Gambia"] = "Gambia"
	country_dict["United States of America"] = "United States"
	country_dict["state of Palestine"] = "Palestine"

	country_list = []

	for c in country_list_text:
		if c in country_dict:
			country_list.append(country_dict[c])
		else:
			print(c)
			print("Error! Not found in dict...")

	corrected_border_list = []

	for x in border_list:
		u = None
		v = None
		if x[0] in country_dict:
			u = country_dict[x[0]]
		else:
			print("Error! U not found in dict...")

		if x[1] in country_dict:
			v = country_dict[x[1]]
		else:
			print("Error! V not found in dict...")

		if u is not None and v is not None:
			corrected_border_list.append((u,v))

	for c in country_list:
		world_map.add_vertex(c)

	for p in corrected_border_list:
		b = False
		if p[0] in country_list and p[1] in country_list:
			world_map.add_edge(p[0],p[1],1)
			b = True
		if b:
			print("Added: ", p)
		else:
			print("Not Added: ", p)

	predecessor, deltas = world_map.dijkstra("North Macedonia")
	print(predecessor)
	print(deltas)

	print("")
	print("Shortest Paths as follows...")
	print("")

	verts = world_map.vertices.keys()
	verts.sort()

	for v in verts:
		path = [v]
		current = path[0]
		while predecessor[current] is not None:
			path.append(predecessor[current])
			current = predecessor[current]
		path.reverse()
		print("Shortest Path to {} (length {}): {} ".format(v, deltas[v], path))

	#print(world_map.edges["Brazil"])
	#print(world_map.adjacency("Brazil"))


"""Implement quick sort in Python.
Input a list.
Output a sorted list.

Here's how it works:
    First, the quicksort function checks the length of the array. If the length is less than 2, then the array is already sorted, and it is returned as-is.
    If the length of the array is 2 or greater, then the function selects the first element of the array as the pivot value.
    The function then creates two new arrays: one containing all the elements less than or equal to the pivot, and one containing all the elements greater than the pivot.
    Finally, the function recursively sorts the two new arrays (using quicksort) and concatenates them with the pivot value in the middle to produce the final sorted array.
"""

# Define a function to sort an array using the quicksort algorithm
def quicksort(array):
    # Base case: if the array has less than two elements, it is already sorted
    if len(array) < 2:
        return array

    # Choose a pivot element and divide the array into two sub-arrays: one with elements less than or equal to the pivot, and another with elements greater than the pivot
    pivot = array[0]
    less = [x for x in array[1:] if x <= pivot]
    more = [x for x in array[1:] if x > pivot]

    # Recursively sort the two sub-arrays using the same quicksort function
    sorted_less = quicksort(less)
    sorted_more = quicksort(more)

    # Concatenate the sorted sub-arrays along with the pivot to get the final sorted array
    return sorted_less + [pivot] + sorted_more

# Test the quicksort function with a sample array
test = [21, 4, 1, 3, 9, 20, 25, 6, 21, 14]
print(quicksort(test))


from flask import Flask, render_template

app= Flask(__name__)

@app.route('/')
def index():
    # Data to pass to the HTML template
    message = "Hello from Python!"

    # Render the HTML template with the provided data
    return render_template('index.html', message=message)

if __name__ == '__main__':
    app.run(debug=True)


import requests

url = 'https://www.pinterest.com/oauth/'

params = {
    'response_type': 'code',
    'redirect_uri': 'https://mysite.com/',
    'client_id': '1473296',
    'scope': 'boards:read,pins:read',
    'state': '12345ABc'
}

response = requests.get(url, params=params)
print(response.url)