import difflib

def matchFilter(input_string, product_string):
    weight = 0

    product_string = product_string.replace(',','')

    split_input = input_string.split()
    split_product = product_string.split()

    for i in range(len(split_input)):
        for j in range(len(split_product)):

            if split_input[i] in split_product[j]:
                print(f'{split_input[i]} yes')
                weight += 1

    print(weight)
    print(len(split_input))
    result = weight/len(split_input)
    return result


#Carter Johnson
#MNIST Tutorial - Part 2 - Improving accuracy
#familiarizing with the Tensorflow package with the MNNIST dataset
#building a Multilayer Convolutional Network

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf

#function for initializing weights between neurons
def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

#function for initializing biases on neural layer
def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)

#convolution with stride of one and zero padded, so output is same size as input
def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

#pooling is plain old max pooling over 2x2 blocks
def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
#data set split into mnist.train (55,000 data points),
#mnist.test (10,000 data points), mnist.validation (5,000 points)
#each point has an image of a digit (28x28 pixels = 784 flattened vector)
#		mnist.train.images - tensor - shape [55000, 784]
# and a corresponding label - mnist.train.labels -  [55000, 10]

sess = tf.InteractiveSession()
#more flexible class for TensorFlow - lets you build computation graph as you run
#good for IPython notebooks

x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
#start to build computation graph by creating nodes for the imput images and target output

W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
#build Variables into TensorFlow's computation graph
#these will be used AND modified by the computation

sess.run(tf.global_variables_initializer())
#must initialize all variables before they can be used in a session
#this step takes specified inital values and assigns them to each Variable in the graph

#implement regression model
y = tf.matmul(x,W) + b

#specify cost function using cross-entropy between target and softmax activation function applied to the regression
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))
#numerically stable version of tutorial calculation

#Train the model using Steepest Gradient Descent
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
#adds new operations to the computation graph
#including gradient computations, parameter update steps (computation and application)
#when this step is run, it will apply grad descent to the model and update the parameters

for i in range(1000):
  batch = mnist.train.next_batch(100)
  train_step.run(feed_dict={x: batch[0], y_: batch[1]})

#Evaluate the model

#list of booleans- whether highest prob matches true label
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
#percent correct
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
#evaluate accuracy on test data
print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))


count_1 = 0
count_2 = 0

first_word = input('Первое сообщение: ')

count_1 += list(first_word).count('!')
count_1 += list(first_word).count('?')

second_word = input('Второе сообщение: ')

count_2 += list(second_word).count('!')
count_2 += list(second_word).count('?')

if count_1 > count_2:
    print('Третье сообщение:', first_word, second_word)
elif count_1 < count_2:
    print('Третье сообщение:', second_word, first_word)
else:
    print('Ой')


# https://atcoder.jp/contests/abc146/tasks/abc146_c
# C - Buy an Integer
# 値段に単調性 (大きい整数ほど値段も高い) ので、二分探索を利用する

def check(N):
    dN = len(str(N))
    return A * N + B * dN

A, B, X = map(int, input().split())

ok = 0
ng = 10**9 + 1

while ok + 1 != ng:
    md = (ok + ng) // 2
    if check(md) <= X:
        ok = md
    else:
        ng = md

print(ok)


# @Author: amishkin
# @Date:   18-08-17
# @Email:  amishkin@cs.ubc.ca
# @Last modified by:   amishkin
# @Last modified time: 18-08-17

import math
import numpy as np
from scipy.stats import truncnorm
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
from torch.nn.parameter import Parameter
from torch.nn import Module

from torch.nn.utils import parameters_to_vector, vector_to_parameters

class MultiheadMLP(nn.Module):
    # Pass number of classes per task
    def __init__(self, input_size, hidden_sizes, output_size, act_func, no_classes, is_multihead):
        super(MultiheadMLP, self).__init__()
        self.input_size = input_size
        if output_size:
            self.output_size = output_size
            self.squeeze_output = False
        else :
            self.output_size = 1
            self.squeeze_output = True
        self.act = F.tanh if act_func == "tanh" else F.relu
        if len(hidden_sizes) == 0:
            self.hidden_layers = []
            self.output_layer = nn.Linear(self.input_size, self.output_size)
        else:
            self.hidden_layers = nn.ModuleList([nn.Linear(in_size, out_size) for in_size, out_size in zip([self.input_size] + hidden_sizes[:-1], hidden_sizes)])
            self.output_layer = nn.Linear(hidden_sizes[-1], self.output_size)

            for l in self.hidden_layers:
                l.weight.data = torch.from_numpy(truncnorm.rvs(a=-2, b=2, loc=0., scale=.1, size=l.weight.data.shape).astype(np.float32))
                l.bias.data = torch.from_numpy(truncnorm.rvs(a=-2, b=2, loc=0., scale=.1, size=l.bias.data.shape).astype(np.float32))
            self.output_layer.weight.data = torch.from_numpy(
                truncnorm.rvs(a=-2, b=2, loc=0., scale=.1, size=self.output_layer.weight.data.shape).astype(np.float32))
            self.output_layer.bias.data = torch.from_numpy(
                truncnorm.rvs(a=-2, b=2, loc=0., scale=.1, size=self.output_layer.bias.data.shape).astype(np.float32))

            print(self.output_layer.weight.data)
            print(self.output_layer.bias.data)

        self.no_classes = no_classes
        self.is_multihead = is_multihead
        self.hidden_sizes = hidden_sizes

    def forward(self, x, task_id=0, individual_grads=False):
        '''
            x: The input patterns/features.
            individual_grads: Whether or not the activations tensors and linear
                combination tensors from each layer are returned. These tensors
                are necessary for computing the GGN using compute_ggn.goodfellow_ggn
        '''

        # return super(MultiheadMLP, self).forward(x)

        x = x.view(-1, self.input_size)
        out = x
        # Save the model inputs, which are considered the activations of the
        # 0'th layer.
        if individual_grads:
            H_list = [out]
            Z_list = []

        for layer in self.hidden_layers:
            Z = layer(out)
            out = self.act(Z)

            # Save the activations and linear combinations from this layer.
            if individual_grads:
                H_list.append(out)
                Z.retain_grad()
                Z.requires_grad_(True)
                Z_list.append(Z)

        # print('out')
        # print(out)
        # print('output_layer')
        # print(self.output_layer)
        # print('weight')
        # print(self.output_layer.weight)
        # print('bias')
        # print(self.output_layer.bias)
        logits = self.output_layer(out)
        # print('logits')
        # print(logits)
        if self.is_multihead:
            logits = logits[:, task_id * self.no_classes : (task_id + 1) * self.no_classes]

        if self.squeeze_output:
            logits = torch.squeeze(logits)

        # Save the final model outputs, which are the linear combinations
        # from the final layer.
        if individual_grads:
            logits.retain_grad()
            logits.requires_grad_(True)
            Z_list.append(logits)

        if individual_grads:
            return (logits, H_list, Z_list)

        return logits

    # Add units for additional classes in the final layer.
    # Required for continual learning with multihead network
    def add_head(self, no_add_outputs, use_cuda=False):
        self.output_size += no_add_outputs
        if len(self.hidden_sizes) == 0:
            in_size = self.input_size
        else:
            in_size = self.hidden_sizes[-1]

        if use_cuda:
            self.output_layer.weight = torch.nn.Parameter(torch.cat([
                self.output_layer.weight,
                torch.tensor(np.random.normal(
                    0., .1, (no_add_outputs, in_size)).astype(np.float32)).cuda()],
                dim=0))

            self.output_layer.bias = torch.nn.Parameter(torch.cat([
                self.output_layer.bias,
                torch.tensor(np.random.normal(
                    0., .1, (no_add_outputs)).astype(np.float32)).cuda()],
                dim=0))
        else:
            self.output_layer.weight = torch.nn.Parameter(torch.cat([
                self.output_layer.weight,
                torch.tensor(np.random.normal(
                    0., .1, (no_add_outputs, in_size)).astype(np.float32))],
                dim=0))

            self.output_layer.bias = torch.nn.Parameter(torch.cat([
                self.output_layer.bias,
                torch.tensor(np.random.normal(
                    0., .1, (no_add_outputs)).astype(np.float32))],
                dim=0))


# Merge k sorted linked lists and return it as one sorted list.

# Example :

# 1 -> 10 -> 20
# 4 -> 11 -> 13
# 3 -> 8 -> 9
# will result in

# 1 -> 3 -> 4 -> 8 -> 9 -> 10 -> 11 -> 13 -> 20
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
def buildHeap(arr,n):
    for i in range(n//2,-1,-1):
        heapifyDown(arr,i,n)

def heapifyDown(arr,i,n):
    left = 2*i+1
    right = 2*i+2
    smallest = i
    if (left<n and arr[left][0]<arr[smallest][0]):
        smallest = left
    if right<n and arr[right][0]<arr[smallest][0]:
        smallest = right
    if smallest!=i:
        arr[i],arr[smallest] = arr[smallest],arr[i]
        heapifyDown(arr,smallest,n)

def mergeKLists(self, A):
    k = len(A)
    root = None
    result_list = []
    current = None
    arr = []
    for i in range(k):
        arr.append([A[i].val,i])
    buildHeap(arr,len(arr))
    import sys
    inf = sys.maxsize
    z = 0
    while z!=k:
        val = arr[0][0]
        index = arr[0][1]
        if current==None:
            root = ListNode(val)
            result_list.append(val)
            current=root
        else:
            current.next = ListNode(val)
            result_list.append(val)
            current = current.next
        temp = A[index]
        if temp.next==None:
            arr[0][0] = inf
            heapifyDown(arr,0,k)
            z+=1
        else:
            temp = temp.next
            arr[0][0] = temp.val
            A[index] = temp
            heapifyDown(arr,0,k)
        print(arr)
    print(result_list)
    printLinkList(root)

def printLinkList(root):
    temp = root
    while temp:
        print(temp.val,"->",end=" ")
        temp = temp.next
# A = ListNode(1)
# A.next = ListNode(2)
# A.next.next = ListNode(3)
# A.next.next.next = ListNode(4)
# A.next.next.next.next = ListNode(5)

# C = ListNode(10)
# C.next = ListNode(45)
# C.next.next = ListNode(54)
# C.next.next.next = ListNode(59)
# C.next.next.next.next = ListNode(62)
# B = [C,A,ListNode(9),ListNode(11)]
# mergeKLists("",B)

# arr= [10,9,8,5,1,2,3,6]
# print(arr)
# buildHeap(arr,len(arr))
# print(arr)
# 10 9 8 20 38 44 55 65 66 79 87 2 68 72 5 5 55 61 73 89 2 30 73 4 28 73 84 96 3 54 82 83 5 15 33 38 94 100 1 4 5 22 32 42 64 86 2 11 78

def getList():
    k = int(input())
    res = []
    while k>0:
        arr = [int(x) for x in input().split()]
        root = ListNode(arr[1])
        current = root
        for i in arr[2:]:
            current.next = ListNode(i)
            current = current.next
        res.append(root)
        k-=1
    return res
mergeKLists("",getList())


# import sys,pytest
# sys.path.append(".")
import pytest
import torch
import torch.nn as nn
import random
# from model.decoder import *
# from model.backbone import *
# from model.hybrid_encoder import *
from model import (
    RTDETRTransformer,
    MLP,
    Backbone,
    MSDeformableAttention,
    HybridEncoder,
    TransformerDecoderLayer)

import dynamic_yaml

class Testdecoder:
    with open("model_config.yaml") as file:
        cfg = dynamic_yaml.load(file)
    device = cfg['device']

    def test_MLP(self):
        model = MLP(
            input_dim = 256,
            hidden_dim = 512,
            output_dim = 1024,
            num_layers= 2,
            act='gelu'
        ).to(self.device)
        x = torch.ones([16,256]).to(self.device)
        assert model(x).shape == torch.Size([16,1024])

    @pytest. mark. skip(reason="passnow because i dont have any choice")
    def test_MSDeformableAttention(self):
        """
        Args:
            query (Tensor): [bs, query_length, C]
            reference_points (Tensor): [bs, query_length, n_levels, 2], range in [0, 1], top-left (0,0),
                bottom-right (1, 1), including padding area

            value (Tensor): [bs, value_length, C]
            value_spatial_shapes (List): [n_levels, 2], [(H_0, W_0), (H_1, W_1), ..., (H_{L-1}, W_{L-1})]
            value_level_start_index (List): [n_levels], [0, H_0*W_0, H_0*W_0+H_1*W_1, ...]
            value_mask (Tensor): [bs, value_length], True for non-padding elements, False for padding elements

        Returns:
            output (Tensor): [bs, Length_{query}, C]
        """
        batch_szie = 4
        query_length = 256
        value_length = 1024
        classify = 80
        n_levels = 4

        querysize = torch.ones([batch_szie,query_length,classify]).to(self.device)
        reference_point = torch.ones([batch_szie,query_length,n_levels,2]).to(self.device)

        value = torch.ones([batch_szie,value_length,classify]).to(self.device)

        value_spatial_shapes = [(random.random(),random.random()) for _ in range(n_levels) ]
        value_mask = None

        model = MSDeformableAttention(
            embed_dim = 256 ,
            num_heads = 8 ,
            num_levels = n_levels ,
            num_points = 4
        ).to(self.device)

        output = model(
            query = querysize,
            reference_points =reference_point,
            value =value,
            value_spatial_shapes = value_spatial_shapes,
            value_mask =value_mask
        ).to(self.device)

        print()
        print(output.shape)
        assert 1 ==2
                # value,
                # value_spatial_shapes,
                # value_mask=None):
    @pytest. mark. skip(reason="passnow because i dont have any choice too")
    def test_TransformerDecoderLayer(self):
        D_MODELs = 512
        nhead = 8
        model = TransformerDecoderLayer(
            d_model=D_MODELs,
            n_head=nhead,
            dim_feedforward = 1024,
            activation= "silu"
        ).to(self.device)
        x = torch.ones([9,3,D_MODELs]).to(self.device)
        output = model(x)
        print()

        print(output.shape)
        assert 1 == 22

    # @pytest. mark. skip(reason="passnow because i dont have any choice")
    def test_RTDETRTransformer(self):

        x = torch.ones(1,3,800,800).to(self.device)

        bmodel = Backbone(
            backbone='resnet50',
            norm_layer=None
        ).to(self.device)

        hybird = HybridEncoder(

            in_channels=[512, 1024, 2048],
            feat_strides=[8, 16, 32],
            hidden_dim=256,
            nhead=8,
            dim_feedforward = 256,
            dropout=0.0,
            enc_act='gelu',
            use_encoder_idx=[2],
            num_encoder_layers=1,
            pe_temperature=10000,
            expansion=1.0,
            depth_mult=1.0,
            act='silu',
            eval_spatial_size = None
        ).to(self.device)

        model = RTDETRTransformer(
                num_classes=80,
                hidden_dim=256,
                num_queries=300,
                position_embed_type='sine',
                feat_channels=[256,256,256],
                feat_strides=[8, 16, 32],
                num_levels=3,
                num_decoder_points=4,
                nhead=8,
                num_decoder_layers=6,
                dim_feedforward=1024,
                dropout=0.,
                activation="relu",
                num_denoising=0,
                label_noise_ratio=0.5,
                box_noise_scale=1.0,
                learnt_init_query=False,
                eval_spatial_size=None,
                eval_idx=-1,
                eps=1e-2,
                aux_loss=True).to(self.device)

        out = bmodel(x)

        with open("data/coco.yaml","r") as file:
            cfg = dynamic_yaml.load(file)

        out = hybird(out)
        out = model(feats= out,
                    targets= list(dict(cfg.names).keys()))

        print("#"*80)
        print("condee output")
        print(out.keys())
        print('pred_logits',out['pred_logits'].shape)
        print(out['pred_logits'])
        assert out['pred_logits'].shape == torch.Size([1, 300, 80])
        print('pred_boxes',out['pred_boxes'].shape)
        print(out['pred_boxes'])
        assert out['pred_boxes'].shape == torch.Size([1, 300, 4])

        print('#######aux_outputs######')
        assert len(out['aux_outputs']) ==6

        for item in out['aux_outputs']:
            print(item.keys(),item['pred_logits'].shape,item['pred_boxes'].shape)
        for item in out['aux_outputs']:
            print(item.keys(),item['pred_logits'].shape,item['pred_boxes'].shape)
            assert item['pred_logits'].shape == torch.Size([1, 300, 80])
            assert item['pred_boxes'].shape == torch.Size([1, 300, 4])

        # assert 11==22


import numpy as np
from pycpd import RigidRegistration
from functools import partial
from scipy.spatial import distance
import argparse
import open3d as o3d
from vtkplotter import *
from vtkplotter.plotter import *
from point_cloud_funcs import *
from visualizer import *

def loadObject(file_path, thresholds=None):

    #Load object from file_path
    load_object = load(file_path)

    object_mesh = mesh.Mesh()

    #If object is loaded from a volume image or dicom series, isosurface the volume
    if isinstance(load_object, volume.Volume):

        load_object = load_object.gaussianSmooth(sigma=(.6, .6, .6)).medianSmooth(neighbours=(1,1,1))

        #Extract surface from given threshold values OR use automatic thresholding if no threshold is specified
        if thresholds is not None:
            object_mesh = load_object.isosurface(threshold= thresholds).extractLargestRegion().extractLargestRegion()
        else:
            object_mesh = load_object.isosurface().extractLargestRegion().extractLargestRegion()

        object_mesh

        if len(object_mesh.points()) > 1000000:
            object_mesh = object_mesh.decimate(N=100000, method='pro', boundaries=False)

    else:
        object_mesh = load_object.triangulate()
    return object_mesh

def compareMesh(src_mesh, tgt_mesh, tolerance):

    src_points = src_mesh.points(copy=True)
    tgt_points = tgt_mesh.points(copy=True)

    #Sample points over surface of both meshes
    src_samples = generateSamples(src_mesh, 2000)
    tgt_samples = generateSamples(tgt_mesh, 2000)

    hull_pt1, hull_pt2 = furthest_pts(src_samples)
    cnt_pnt = (hull_pt1+hull_pt2)/2
    src_points = src_points - cnt_pnt
    src_samples = src_samples - cnt_pnt
    pt_a, pt_b = furthest_pts(tgt_samples)
    orig_dist = pt_dist(pt_a, pt_b)
    new_dist = pt_dist(hull_pt1, hull_pt2)
    const_mult = orig_dist/new_dist
    src_points = src_points*const_mult
    src_samples = src_samples*const_mult

    vp = Plotter(interactive=0, axes=7, size='fullscreen', bg='bb')
    vp.legendBC = (0.22, 0.22, 0.22)
    vp.legendPos = 1
    txt = Text2D("Loading Models...", pos = 8, c='gray', s=1.31)
    vp += txt
    tgt_pts = Points(tgt_samples, r=6, c='deepskyblue', alpha= 1).legend("Target")
    vp += tgt_pts
    vp.show()
    txt.SetText(7, "Initiating Alignment")
    src_pts = Points(src_samples, r=6, c='yellow', alpha = 1).legend("Source")
    vp += src_pts
    vp.show()

    #Roughly align both meshes (global registration)
    spacing = np.mean(distance.pdist(src_samples))
    src_samples, src_points = perform_global_registration(src_samples,tgt_samples,src_points, spacing)

    txt.SetText(7, "Refining Alignment")
    vp.show()

    #Refine mesh alignment (local registration)
    cpd_ittr = 60
    callback = partial(visualize, vp=vp, pts = src_pts, text = txt, max_ittr = cpd_ittr)
    reg = RigidRegistration(max_iterations = cpd_ittr, **{ 'X': tgt_samples, 'Y': src_samples })
    src_samples, [s,R,t] = reg.register(callback)
    src_points = s*np.dot(src_points, R) + t
    src_pts.points(src_samples)

    vp.renderer.RemoveAllViewProps()
    txt.SetText(7, "Alignment Complete")
    vp.show()

    for i in range(360):
        if i == 60:
            txt.SetText(7, "")
        vp.camera.Azimuth(.75)
        vp.show()

    src_mesh.points(src_points)

    tgt_samples = generateSamples(tgt_mesh, 6000)
    txt.SetText(7,"Performing Added Surface Analysis...")
    vp.show()

    ratio = 2000/min(len(tgt_points), len(src_points))
    spacing = 3*spacing*ratio
    #Generate distances for heat map
    dists = distance.cdist(src_points,tgt_samples).min(axis=1)
    txt.SetText(7,"Press Q to Continue")
    vp.show(interactive=1)
    show_mesh(src_mesh, dists, vp, spacing/2, tolerance=tolerance)
    txt2 = Text2D("Displaying Input Object 1 \n \nUse slider to isolate \ndefective/added surfaces")
    vp += txt2
    vp.addGlobalAxes(axtype=8, c='white')
    vp.show(axes=8, interactive=1)
    txt.SetText(7,"Performing Missing Surface Analysis...")
    vp += txt
    vp.show(interactive=0)
    src_mesh.points(src_points)
    src_samples = generateSamples(src_mesh, 6000)
    #Generate distances for heat map
    dists = distance.cdist(tgt_points,src_samples).min(axis=1)
    show_mesh(tgt_mesh, dists, vp, spacing/2, tolerance=tolerance)
    txt2.SetText(2,"Displaying Input Object 2 \n \nUse slider to isolate \ndefective/missing surfaces")
    vp += txt2
    vp.addGlobalAxes(axtype=8, c='white')
    vp.show(axes=8, interactive=1)

def main(argv):

    src_mesh = loadObject(argv.filePath1, thresholds = argv.thresholds1)
    tgt_mesh = loadObject(argv.filePath2, thresholds = argv.thresholds2)
    compareMesh(src_mesh, tgt_mesh, tolerance=argv.errorTolerance)

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='Compares two objects to each other for geometric similarity. Accepts inputs of volume images, dicom series or mesh object. Input objects do not have to be the same type.')

    parser.add_argument('-f1', '--filePath1', type=str, help = "File path to input object: Accepts volume image (.tiff, .vti, .slc etc...), directory containing Dicom series, or mesh objects (.stl, .obj, .ply etc...)", required = True)

    parser.add_argument('-f2', '--filePath2', type=str, help = "File path to original object: Accepts volume image (.tiff, .vti, .slc etc...), directory containing Dicom series, or mesh objects (.stl, .obj, .ply etc...)", required = True)

    parser.add_argument('-t1', '--thresholds1', nargs='+', type=int, help = "Optional: Dual threshold values for feature extraction for input object. Ex: -200, 100, -500, 200")

    parser.add_argument('-t2', '--thresholds2', nargs='+', type=int, help = "Optional: Dual threshold values for feature extraction for original object. Ex: -200, 100, -500, 200")

    parser.add_argument('-et', '--errorTolerance', type=float, help = "Optional: Provide a maximum error tolerance for automatic error detection.")

    main(parser.parse_args())


data = open("./2021/day3/input.txt").read()
rows = data.splitlines()
ones = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
rowCountHalf = len(rows) / 2
d = 0

for r in rows:
    for i in range(len(r)):
        if r[i] == "1":
            ones[i] += 1

binGamma = ""
binEpsilon = ""
for i in ones:
    if i > rowCountHalf:
        binGamma += "1"
        binEpsilon += "0"
    else:
        binGamma += "0"
        binEpsilon += "1"

gamma = int(binGamma, base=2)
epsilon = int(binEpsilon, base=2)
print("binGamma", binGamma, gamma)
print("binEpsilon", binEpsilon, epsilon)
print("mult", gamma * epsilon)


"""just try replicating the following line of final_automated.m

get_time_delay_automated('042318', '8000a', [1, 2, 3, 4, 5, 6]);
"""
from os.path import join

from scipy.io import loadmat
import numpy as np
import h5py

from thesis_v2 import dir_dict
from thesis_v2.spike_data_processing.yuanyuan_8k import config_8k

def main():
    for prefix in config_8k.get_file_names(flat=False).keys():
        print(f'check {prefix}')
        with h5py.File(join(config_8k.result_root_dir, 'time_delay.hdf5'), 'r') as f:
            best_delay = f[prefix]['best_delay'][()] - 100
            best_correlation = f[prefix]['best_correlation'][()]

        # load reference file.
        ref_data = loadmat(join(dir_dict['private_data'], 'yuanyuan_8k', 'delay', f'delay_{prefix}.mat'))
        best_delay_ref = ref_data['time_delay'].ravel()
        assert np.array_equal(best_delay_ref, best_delay)
        best_correlation_ref = ref_data['neurons'][2]
        assert best_correlation_ref.shape == best_correlation.shape
        print(abs(best_correlation_ref - best_correlation).max())
        assert abs(best_correlation_ref - best_correlation).max() < 1e-8

if __name__ == '__main__':
    main()


from copy import deepcopy
import sys
input = sys.stdin.readline

def bfs(start, end, color, input_arr):
    visited = [[0] * N for _ in range(N)]
    que = []
    que.append((start, end))
    visited[start][end] = 1
    input_arr[start][end] = 0
    while que:
        i, j = que.pop(0)
        for k in range(4):
            ni, nj = i + di[k], j + dj[k]
            if 0 <= ni < N and 0 <= nj < N:
                if input_arr[ni][nj] == color and visited[ni][nj] == 0:
                    input_arr[ni][nj] = 0
                    que.append((ni, nj))
                    visited[ni][nj] = 1
    return input_arr

di = [1, 0, -1, 0]
dj = [0, 1, 0, -1]
N = int(input())
arr = [list(input()) for _ in range(N)]
arr_green = deepcopy(arr)
colors = ['R', 'G', 'B']
cnt = 0
cnt_green = 0
for i in range(N):
    for j in range(N):
        if arr_green[i][j] == 'G':
            arr_green[i][j] = 'R'

for i in range(N):
    for j in range(N):
        if arr[i][j] in colors:
            arr = bfs(i, j, arr[i][j], arr)
            cnt += 1
        if arr_green[i][j] in colors:
            arr_green = bfs(i, j, arr_green[i][j], arr_green)
            cnt_green += 1

print(cnt, cnt_green)


# NAIVE BAYE SFROM SCRATCH AVEC : https://machinelearningmastery.com/naive-bayes-classifier-scratch-python/

# 1 ) On importe les données

import csv
def loadCsv(filename):
	lines = csv.reader(open(filename,"rt"))
	dataset = list(lines)
	for i in range(len(dataset)):
		dataset[i] = [float(x) for x in  dataset[i]]
	return dataset

# Test import : IT WORKS

#filename = 'pima-indians-diabetes.data.csv'
#dataset = loadCsv(filename=filename)
#print('load data au format',filename, 'avec', len(dataset) ,'lignes ')

# Séparation des données

import random
def splitDataset(dataset,splitRatio):
	trainSize = int(len(dataset)*splitRatio)
	trainSet = []
	copy = list(dataset)
	while (len(trainSet)<trainSize):
		index=random.randrange(len(copy))
		trainSet.append(copy.pop(index))
	return [trainSet,copy]

# Test split : IT WORKS

#dataset = [[1],[2],[3],[4],[5]]
#splitRatio = (2/3)
#train, test = splitDataset(dataset=dataset, splitRatio=splitRatio)
#print('on a split avec en test :',test,'et en train : ',train)

# 2 ) Sommaire des données

# Separation des données

# On ajoute une variable qui définit la colonne qui contient la réponse = la classe dans le dataset
def separateByClass(dataset,columnWithClassResponse):
	separated = {}
	for i in range(len(dataset)):
		vector = dataset[i]
		# On crée la ligne de la classe si elle existe pas
		if ( vector[columnWithClassResponse] not in separated):
			separated[vector[columnWithClassResponse]]=[]
		separated[vector[columnWithClassResponse]].append(vector)
	return separated

# Test separation des donnees : IT WORKS

#dataset = [[1,20,1],[2,34,4],[1,34,4],[2,20,1]]
#separated0 = separateByClass(dataset=dataset, columnWithClassResponse=0)
#separated1 = separateByClass(dataset=dataset, columnWithClassResponse=1)
#separated_1 = separateByClass(dataset=dataset, columnWithClassResponse=-1)
#print('separation 1 sur col 0', separated0)
#print('separation 2 sur col 1', separated1)
#print('separation 3 sur col -1', separated_1)

# Calcul de données de stats :

import math
def mean(numbers):
	return sum(numbers)/len(numbers)

def stdev2(numbers):
	avg = mean(numbers=numbers)
	variance = sum([pow(x-avg,2)for x in numbers])/float(len(numbers)-1)
	return math.sqrt(variance)

# Test : IT WORKS
#numbers = [1,2,3,4,5]
#print('moyenne',mean(numbers=numbers))
#print('variance', stdev(numbers=numbers))

#Sommaire des données : mode général :
#The zip function groups the values for each attribute across our data instances
# #into their own lists so that we can compute the mean and standard deviation values for the attribute.
# On ajoute la frequence de la classe y comme approximation de p(y)
def summarize(dataset,columnWithClassResponse,frequence_y):
	summary = [(mean(attribute), stdev2(attribute),frequence_y) for attribute in zip(*dataset)]
	del summary[columnWithClassResponse]
	return summary

# Test summarize : IT WORKS
#dataset = [[1,20,1],[2,34,4],[1,34,4],[2,20,1]]
#frequence_y=0.8
#summary0 = summarize(dataset=dataset, columnWithClassResponse=0,frequence_y=frequence_y)
#summary1 = summarize(dataset=dataset, columnWithClassResponse=1,frequence_y=frequnce_y)
#summary_1 = summarize(dataset=dataset, columnWithClassResponse=-1,frequence_y=frequnce_y)
#print('sommaire 1 en enlevant col 0', summary0)
#print('sommaire 2 en enlevant col 1', summary1)
#print('sommaire 3 en enlevant col -1', summary_1)

# Sommaire par classe !
def summarizedByClass(dataset,columnWithClassResponse):
	separated = separateByClass(dataset=dataset,columnWithClassResponse=columnWithClassResponse)
	summaries = {}
	for classValue, instance in separated.items():
		# On ajoute la frequence d'apparition de la classe comme approximation de p(y)
		frequence_y=(len(instance) / len(dataset))
		summaries[classValue] = summarize(dataset=instance,columnWithClassResponse=columnWithClassResponse,frequence_y=frequence_y)
	return summaries

# Test summarizeByClass : IT WORKS
#dataset = [[1,20,1],[2,34,4],[1,34,4],[2,20,1],[1,24,4],[3,4,4],[3,4,4]]
#summaryByC0 = summarizedByClass(dataset=dataset, columnWithClassResponse=0)
#summaryByC1 = summarizedByClass(dataset=dataset, columnWithClassResponse=1)
#summaryByC_1 = summarizedByClass(dataset=dataset, columnWithClassResponse=-1)
#print('sommaire 1 par classe en col 0', summaryByC0)
#print('sommaire 2 par classe en col col 1', summaryByC1)
#print('sommaire 3 par classe en col col -1', summaryByC_1)

# 3 ) Make predictions : CAS NAIVE BAYES

#Calculate Gaussian Probability Density Function
#C'est cette fonction qui devra être changée et donc on fera la MAJ avec les fonctions de notre kernel !
import math
# Ici on devra faire 2 parties :
# une pour proba haute et une autre pour proba basse
#CALCUL PROBA CONDITIONNELLE
def calculateProbabilityNaiveBayes(x, mean, stdev2):
	exponent = math.exp(-(math.pow(x-mean,2)/(2*math.pow(stdev2,2))))
	return (1/(math.sqrt(2*math.pi)*stdev2)) *exponent

# Test calcul proba : IT WORKS !
#x = 71.5
#mean = 73
#stdev = 6.2
#frequence_y=0.5
#probability = calculateProbability(x=x,mean=mean,stdev=stdev,frequence_y=frequence_y)
#print('Proba de x = 71.5 d appartenir a la classe de moyenne 71.5 et stdev 6.2 selon Naive Bayes:',probability)

# Calcul des probas de classes maintenant !

'''
Now that we can calculate the probability of an attribute belonging to a class,
we can combine the probabilities of all of the attribute values for a data instance
and come up with a probability of the entire data instance belonging to the class.

We combine probabilities together by multiplying them. In the calculateClassProbabilities() below,
the probability of a given data instance is calculated by multiplying together
the attribute probabilities for each class. the result is a map of class values to probabilities.
'''

def calculateClassProbabilitiesNaiveBayes(summaries,inputVector): #,columnWithClassResponse): Pas important ici je pense
	probabilities = {}
	for classValue,classSummaries in summaries.items():
		probabilities[classValue] = 1 #Initialisation pour la multiplication ensuite des probas
		for i in range(len(classSummaries)):
			mean, stdev2, frequence_y = classSummaries[i]
			x = inputVector[i]
			probabilities[classValue] *= calculateProbabilityNaiveBayes(x=x, mean=mean, stdev2=stdev2)
			probabilities[classValue] *= frequence_y # multiplication par l'estimation de p(y)
	return probabilities

#Test proba par classe : IT WORKS
#summaries = {0:[(1, 0.5,.8)], 1:[(20, 5.0,.2)]}
#inputVector = [1.1] # pas besoin ici de mettre une fausse valeur en y ou même de faire inputVector = [1.1, ]
#probabilities = calculateClassProbabilities(summaries, inputVector)
#print('Probabilities for each class: ',probabilities)

# 4 ) Prédictions !

# Retourner 1 prediction :

def predictNaiveBayes(summaries, inputVector):
	probabilities = calculateClassProbabilitiesNaiveBayes(summaries, inputVector)
	bestLabel, bestProb = None, -1
	for classValue, probability in probabilities.items():
		if bestLabel is None or probability > bestProb:
			bestProb = probability
			bestLabel = classValue
	return bestLabel

# Test prediction : IT WORKS

#summaries = {0:[(1, 0.5)], 1:[(20, 5.0)]}
#inputVector = [20.1] # pas besoin ici de mettre une fausse valeur en y ou même de faire inputVector = [1.1, ]
#prediction = predict(summaries, inputVector)
#print('Prediction de la classe class: ',prediction)

# Predictions sur un jeu de test complet :
def getPredictionsNaiveBayes(summaries, testSet):
	predictions = []
	for i in range(len(testSet)):
		result = predictNaiveBayes(summaries, testSet[i])
		predictions.append(result)
	return predictions

# Test : IT WORKS
#summaries = {'A':[(1, 0.5)], 'B':[(20, 5.0)]}
#testSet = [[1.1], [19.1],[18],[0]]
#predictions = getPredictions(summaries, testSet)
#print('Predictions: ',predictions)

# 5 ) Moyenne des erreurs :

def getAccuracyNaiveBayes(testSet, predictions, columnWithClassResponse):
	correct = 0
	for x in range(len(testSet)):
		if testSet[x][columnWithClassResponse] == predictions[x]:
			correct += 1
	return (correct/float(len(testSet))) * 100.0

# Test :
#testSet = [[1,1,1,'a'], [2,2,2,'a'], [3,3,3,'b']]
#predictions = ['a', 'a', 'a']
#accuracy = getAccuracy(testSet, predictions,3)
#print('Accuracy: ',accuracy)

# ADAPTATION D UNE PARTIE DU CODE POUR L UTILISATION DE NOTRE KERNEL IMPRECIS :
# 3 ) Make predictions :

# ON UTILISE LES FONCTIONS DU KERNEL PLUTOT QUE CELLE LA POUR NOS ESTIMATION

def InitHOptKernelImprecise(dataset):
	from statistics import stdev
	sigma=stdev(dataset)
	hOpt = 1.06 * sigma * (len(dataset)) ** (-1 / 5)
	return hOpt

#Cette fonction est la MAJ avec les fonctions de notre kernel !
#import math
# Ici on devra faire 2 parties :
# une pour proba haute et une autre pour proba basse

import math
def calculsDi(x,Xi):
	sumDi = 0
	#print('Xi = ',Xi)
	#print('x= ',x)
	for i in range(len(Xi)):
		sumDi += abs(x-Xi[i])
	meanDi = sumDi/len(Xi)
	return sumDi, meanDi

#CALCUL PROBA CONDITIONNELLE
def calculateLowProbabilityImpreciseKernel(x, dataset, h,epsilon,N):
	#TRIER LES DONNEES DU DATASET ET ENSUITE MAJ LA SOMME A CHAQUE ITERATION :)
	sortedDataset = sorted(dataset)

	n = len(dataset)
	print('hOpt = ',h)
	print('EPSILON=',epsilon)
	f_i_moins_epsilon = []
	f_i_plus_epsilon = []
	f_i_moins_Di = []
	f_i_plus_Di = []
	Di=[]
	f_i_moins_Di.append(10**5)
	f_i_plus_Di.append(10**5)
	f_i_moins_epsilon.append(10**5)
	f_i_plus_epsilon.append(10**5)
	for i in range(n):
		Di.append(abs(x - sortedDataset[i])) # Mise à part car on a besoin de D(i+1) après
	for i in range(n):
		#print(' i = ',i)
		#print('x= ',x)
		#print('dataset ',i,' = ',dataset[i])
		sumDi, meanDi = calculsDi(x, sortedDataset[0:i+1])
		#print('Di= ',Di[i])
		if(h>epsilon and i == (n-1)):
			f_i_moins_epsilon.append(((i+1)/(N*(h-epsilon))) - (sumDi)/(N*((h-epsilon)**2)))
			#print('h>epsilon and i == (n-1), F i moins epsilon = ', f_i_moins_epsilon[(len(f_i_moins_epsilon)-1)])
		if(i == (n-1)):
			f_i_plus_epsilon.append((((i+1)/(N*(h+epsilon))) - (sumDi)/(N*((h+epsilon)**2))))
			#print('CAS PLUS EPSILON i == (n-1), F i plus epsilon = ', f_i_plus_epsilon[(len(f_i_plus_epsilon)-1)])
		if(Di[i]<2*epsilon and x!= Di[i]):
			f_i_moins_Di.append(((i+1) / (N * (x - Di[i]))) - (sumDi) / (N * ((x - Di[i]) ** 2)))
			#print('i ==',i,', F i moins Di = ', f_i_moins_Di[(len(f_i_moins_Di)-1)])
			f_i_plus_Di.append((((i+1) / (N * (x + Di[i]))) - (sumDi) / (N * ((x + Di[i]) ** 2))))
			#print('i == ',i,', F i plus Di = ', f_i_plus_Di[(len(f_i_plus_Di)-1)])
	lowProbability = min(min(f_i_moins_epsilon),min(f_i_plus_epsilon),min(f_i_moins_Di),min(f_i_plus_Di))
	if lowProbability < 0:
		lowProbability = 0
	#print('Low probability = ', lowProbability, 'avec hOpt = ',h)
	return lowProbability

def calculateHightProbabilityImpreciseKernel(x, dataset, h,epsilon,N):
	# TRIER LES DONNEES DU DATASET ET ENSUITE MAJ LA SOMME A CHAQUE ITERATION :)
	sortedDataset = sorted(dataset)
	n = len(dataset)
	#print('n=', n)
	f_i_moins_epsilon = []
	f_i_plus_epsilon = []
	f_i_moins_Di = []
	f_i_plus_Di = []
	f_i_2_E_Di = []
	Di = []
	f_i_moins_Di.append(0)
	f_i_plus_Di.append(0)
	f_i_moins_epsilon.append(0)
	f_i_plus_epsilon.append(0)
	f_i_2_E_Di.append(0)

	for i in range(n):
		Di.append(abs(x - sortedDataset[i])) # Mise à part car on a besoin de D(i+1) après
	for i in range(n):
		#print(' i = ', i)
		#print('x= ', x)
		#print('dataset ', i, ' = ', dataset[i])
		#print('dataset trie : ',sortedDataset)
		sumDi, meanDi = calculsDi(x, sortedDataset[0:i+1])
		#print('Di= ', Di[i])
		if(h>epsilon and i == (n-1)):
			f_i_moins_epsilon.append(((i+1) / (N * (h - epsilon))) - (sumDi) / (N * ((h - epsilon) ** 2)))
			#print('F i moins epsilon = ', f_i_moins_epsilon[i])
		if(i == (n-1)):
			f_i_plus_epsilon.append((((i+1) / (N * (h + epsilon))) - (sumDi) / (N * ((h + epsilon) ** 2))))
			#print('F i plus epsilon = ', f_i_plus_epsilon[i])
		if(Di[i]<2*epsilon and x!= Di[i]):
			f_i_moins_Di.append(((i+1) / (N * (x - Di[i]))) - (sumDi) / (N * ((x - Di[i]) ** 2)))
			#print('F i moins Di = ', f_i_moins_Di[i])
			f_i_plus_Di.append((((i+1) / (N * (x + Di[i]))) - (sumDi) / (N * ((x + Di[i]) ** 2))))
			#print('F i plus Di = ', f_i_plus_Di[i])
		if(meanDi > Di[i] and i>=0 and i != (n-1) and meanDi < Di[i+1] ):
			#print('E(Di) = ',meanDi)
			#print('epsilon = ', epsilon)
			f_i_2_E_Di.append((((i+1) / (N * (2*meanDi))) - (sumDi) / (N * ((2*meanDi) ** 2))))
			#print('F i plus 2 E(Di) = ', f_i_2_E_Di[i])

	hightProbability = max(max(f_i_moins_epsilon), max(f_i_plus_epsilon), max(f_i_moins_Di), max(f_i_plus_Di),max(f_i_2_E_Di))

	#print('Hight probability = ', hightProbability)
	return hightProbability

# Test calcul proba : IT WORKS !
#x = 71.5
#mean = 73
#stdev = 6.2
#frequence_y=0.5
#lowProbability = calculateLowProbability(x=x,mean=mean,stdev=stdev)
#hightProbability = calculateHightProbability(x=x,mean=mean,stdev=stdev)
#print('Proba de x = 71.5 d appartenir a la classe de moyenne 71.5 et stdev 6.2 selon Naive Bayes:',probability)

# Separation des classes en enlevant la colonne de la réponse:
# On ajoute une variable qui définit la colonne qui contient la réponse = la classe dans le dataset
# columnWithClassResponse doit être la premiere colonne (0) ou la dernière (-1)
def separateByClassWithoutResponse(dataset,columnWithClassResponse):
	separated = {}
	for i in range(len(dataset)):
		vector = dataset[i]
		# On crée la ligne de la classe si elle existe pas
		if ( vector[columnWithClassResponse] not in separated):
			separated[vector[columnWithClassResponse]] = []
		if (columnWithClassResponse == -1):
			separated[vector[columnWithClassResponse]].append(vector[0:columnWithClassResponse]) # On supprime la var avec la classe
		else:
			separated[vector[columnWithClassResponse]].append(vector[1:])  # On supprime la var avec la classe
	return separated

# Calcul des probas de classes maintenant !

'''
Now that we can calculate the probability of an attribute belonging to a class,
we can combine the probabilities of all of the attribute values for a data instance
and come up with a probability of the entire data instance belonging to the class.

We combine probabilities together by multiplying them. In the calculateClassProbabilities() below,
the probability of a given data instance is calculated by multiplying together
the attribute probabilities for each class. the result is a map of class values to probabilities.
'''

# FAIRE UNE INITIALISATION DES PARAMETRES POUR KERNEL IMPRECIS AVANT CETTE FONCTION
# PASSER EN PARAMETRE CES DONNES POUR LA FONCTION SUIVANTE AFIN DE POUVOIR LANCER ComputeHMaxFromInterval

def calculateClassLowProbabilitiesImpreciseKernel(dataset,columnWithClassResponse,inputVector,margeEpsilon): #,columnWithClassResponse): Pas important ici je pense
	N = len(dataset)
	separated = separateByClassWithoutResponse(dataset,columnWithClassResponse)
	dataset2 = []
	hOpt=[]
	for i in range(len(dataset)):
		if(columnWithClassResponse == -1):
			dataset2.append(dataset[i][0:columnWithClassResponse])
		else:
			dataset2.append(dataset[i][1:])
	dataset2Separated = [attribute1 for attribute1 in zip(*dataset2)]
	for i in range(len(dataset2Separated)):
		hOpt.append(InitHOptKernelImprecise(dataset2Separated[i]))
	#print(len(separated.items()))
	lowProbabilities = {}
	for classValue,classDataset in separated.items():
		#print('classDataset :',classDataset)
		#print('len classDataset',len(classDataset))
		# Separation des colonnes pour qu'une colonne corresponde à une seule variable d'entrée
		#print('zip : ',zip(*classDataset))
		classDatasetWithColSeparated = [attribute for attribute in zip(*classDataset)]
		#print('class : ',classDatasetWithColSeparated)
		#print(len(classDatasetWithColSeparated))
		lowProbabilities[classValue] = 1 #Initialisation pour la multiplication ensuite des probas
		frequence_y = len(classDataset)/N
		for i in range(len(classDatasetWithColSeparated)):
			#print(i)
			x = inputVector[i]
			#print(x)
			## CALCUL MEANDI ET SUMDI ET ENSUITE ON ENVOIE !
			#mean, stdev, frequence_y = classSummaries[i]
			lowProbabilities[classValue] *= calculateLowProbabilityImpreciseKernel(x=x, dataset=classDatasetWithColSeparated[i], h=hOpt[i], epsilon=margeEpsilon*hOpt[i], N=N)
			lowProbabilities[classValue] *= frequence_y # multiplication par l'estimation de p(y)
	return lowProbabilities

#testLow=calculateClassLowProbabilitiesImpreciseKernel(dataset=[[1,3,2,5],[2,6,3,5],[1,4,4,5]],columnWithClassResponse=0,inputVector=[4,7,7],hOpt=10,margeEpsilon=0.5)
#print('testLow = ',testLow)

def calculateClassHightProbabilitiesImpreciseKernel(dataset,columnWithClassResponse,inputVector,margeEpsilon): #,columnWithClassResponse): Pas important ici je pense
	N = len(dataset)
	dataset2 = []
	hOpt = []
	separated = separateByClassWithoutResponse(dataset, columnWithClassResponse)
	for i in range(len(dataset)):
		if (columnWithClassResponse == -1):
			dataset2.append(dataset[i][0:columnWithClassResponse])
		else:
			dataset2.append(dataset[i][1:])
	dataset2Separated = [attribute1 for attribute1 in zip(*dataset2)]
	for i in range(len(dataset2Separated)):
		hOpt.append(InitHOptKernelImprecise(dataset2Separated[i]))
		# print(len(separated.items()))
	hightProbabilities = {}
	for classValue, classDataset in separated.items():
		#print('classDataset :', classDataset)
		#print('len classDataset', len(classDataset))
		# Separation des colonnes pour qu'une colonne corresponde à une seule variable d'entrée
		# print('zip : ',zip(*classDataset))
		classDatasetWithColSeparated = [attribute for attribute in zip(*classDataset)]
		# print('class : ',classDatasetWithColSeparated)
		# print(len(classDatasetWithColSeparated))
		hightProbabilities[classValue] = 1  # Initialisation pour la multiplication ensuite des probas
		frequence_y = len(classDataset) / N
		for i in range(len(classDatasetWithColSeparated)):
			#print(i)
			x = inputVector[i]
			#print(x)
			## CALCUL MEANDI ET SUMDI ET ENSUITE ON ENVOIE !
			# mean, stdev, frequence_y = classSummaries[i]
			hightProbabilities[classValue] *= calculateHightProbabilityImpreciseKernel(x=x,dataset=classDatasetWithColSeparated[i], h=hOpt[i], epsilon=margeEpsilon*hOpt[i], N=N)
			hightProbabilities[classValue] *= frequence_y  # multiplication par l'estimation de p(y)
	return hightProbabilities

#testHight=calculateClassHightProbabilitiesImpreciseKernel(dataset=[[1,3,2,5],[2,6,3,5],[1,4,4,5]],columnWithClassResponse=0,inputVector=[4,7,7],hOpt=10,margeEpsilon=0.3)
#print('testhight = ',testHight)

#Test proba par classe : IT WORKS
#summaries = {0:[(1, 0.5,.8)], 1:[(20, 5.0,.2)]}
#inputVector = [1.1] # pas besoin ici de mettre une fausse valeur en y ou même de faire inputVector = [1.1, ]
#probabilities = calculateClassProbabilities(summaries, inputVector)
#print('Probabilities for each class: ',probabilities)

# 4 ) Prédictions !

# Retourner 1 prediction avec 1 ou plusieurs classes :

def predictImpreciseKernel(dataset,columnWithClassResponse,inputVector,margeEpsilon):
	lowProbabilities = calculateClassLowProbabilitiesImpreciseKernel(dataset,columnWithClassResponse,inputVector,margeEpsilon)
	hightProbabilities = calculateClassHightProbabilitiesImpreciseKernel(dataset,columnWithClassResponse,inputVector,margeEpsilon)
	bestLabel = []
	#print('prediction de low probabilities : ',lowProbabilities)
	for classValueLow,lowProba in lowProbabilities.items():
		#print('class Value = ',classValueLow)
		#print('lowProba =',lowProba)
		tjrsSup = 1
		for classValueHight,hightProba in hightProbabilities.items():
			if classValueHight != classValueLow :
				#print('hightProba = ',hightProba)
				if lowProba > hightProba and tjrsSup == 1:
					tjrsSup = 1
				else:
					tjrsSup = 0
		if(tjrsSup == 1):
			bestLabel.append(classValueLow)
	if(bestLabel == []):
		#On teste si notre proba haute est inf à toutes les probas basses
		#Si c'est le cas on ne met pas la classe dans les potentielles classes de retour
		#Sinon on ajoute la classe aux classes de retour
		print('passage par le deuxième cycle de comparaison avec pour hight :',hightProbabilities,' et pour low : ',lowProbabilities)
		for classValueHight2, hightProba2 in hightProbabilities.items():
			#print('2e partie : class Value = ', classValueHight2)
			#print('2e partie : hightProba =', hightProba2)
			tjrsInf = 1
			for classValueLow2, lowProba2 in lowProbabilities.items():
				if classValueHight2 != classValueLow2:
					#print('2e partie : lowProba = ', lowProba2)
					if lowProba2 > hightProba2 and tjrsInf == 1:
						tjrsInf = 1
					else:
						tjrsInf = 0
			if (tjrsInf != 1):
				bestLabel.append(classValueHight2)

	return bestLabel

# Test prediction : IT WORKS

#testPredict=predictImpreciseKernel(dataset=[[1,3,2,5],[2,6,3,5],[1,3.5,2.2,5.1],[3,3,2,5],[3,3.5,2.2,5.1]],columnWithClassResponse=0,inputVector=[3.5,2.8,6],hOpt=5,margeEpsilon=0.1)
#print('testpredict = ',testPredict)

# Predictions sur un jeu de test complet :
def getPredictionsImpreciseKernel(dataset,columnWithClassResponse,testSet,margeEpsilon):
	predictions = []
	#print('test set passé en argument =',testSet)
	for i in range(len(testSet)):
		print('test set de ',i,' = ',testSet[i])
		result = predictImpreciseKernel(dataset,columnWithClassResponse,testSet[i], margeEpsilon)
		print('resultat pour la ligne ',i,' : ',result)
		predictions.append(result)
	return predictions

# Test : IT WORKS
#testSet=[[3.5,2.8,6],[3,3,5],[10.1,12.1,14.1]]
#testPredictions=getPredictionsImpreciseKernel(dataset=[[1,3,2,5],[2,10,12,14],[1,3.5,2.2,5.1],[3,3,2,5],[3,3.5,2.2,5.1]],columnWithClassResponse=0,testSet=testSet,hOpt=5,margeEpsilon=0.1)
#print('testpredictions = ',testPredictions)

# 5 ) Moyenne des erreurs :

def getAccuracyImpreciseKernel(testSet, predictions, columnWithClassResponse):
	correct = 0
	for x in range(len(testSet)):
		if testSet[x][columnWithClassResponse] in predictions[x]:
			correct += 1/len(predictions[x])
	return (correct/float(len(testSet))) * 100.0

# Test :
#testSet = [[1,1,1,'a'], [2,2,2,'a'], [3,3,3,'b']]
#predictions = ['a', 'a', ['a','b']]
#accuracy = getAccuracyImpreciseKernel(testSet, predictions,3)
#print('Accuracy: ',accuracy)

# CODE POUR LANCER LES FONCTIONS ET PREDIRE :

def main():
	file = 'iris.data.csv'
	splitRatio = 0.99
	dataset = loadCsv(file)
	trainingSet, testSet = splitDataset(dataset, splitRatio)
	# prepare model
	print('Split ',len(dataset),' rows into train=',len(trainingSet),' and test=',len(testSet),' rows')
	summaries = summarizedByClass(trainingSet,columnWithClassResponse=4)
	print('testSet = ',testSet)
	testSet2 = []
	for i in range(len(testSet)):
		testSet2.append(testSet[i][0:4])
	# test model
	#predictionsNB = getPredictionsNaiveBayes(summaries, testSet)
	predictionsIK = getPredictionsImpreciseKernel(dataset, columnWithClassResponse=-1,testSet=testSet2,margeEpsilon=0.5)
	print('predictions IK =',predictionsIK)
	#accuracyNB = getAccuracyNaiveBayes(testSet, predictionsNB,(4))
	accuracyIK = getAccuracyImpreciseKernel(testSet, predictionsIK,(4))
	#print('Accuracy Naive Bayes : ',accuracyNB)
	print('Accuracy Imprecise Kernel : ',accuracyIK)

main()

# Tableaau des identifiants des réponses :
#0 = setosa
#1 = versicolor
#2 = virginica


import pygame as pg
from level_data import *
from setting import *

class Node(pg.sprite.Sprite):
    def __init__(self, position, status, icon_speed, idx):
        super().__init__()
        self.image = pg.Surface((100, 80))
        if status:
            self.image = pg.image.load(levels[idx][LevelProperties.NODE_PNG()])
            self.image = pg.transform.scale(self.image, (200, 200))
        else:
            self.image = pg.image.load(levels[idx][LevelProperties.NODE_LOCK()])
            self.image = pg.transform.scale(self.image, (200, 200))
        self.rect = self.image.get_rect(center = position)
        self.detection_zone = pg.Rect(self.rect.centerx - (icon_speed / 2), self.rect.centery - (icon_speed / 2), icon_speed, icon_speed)

class Icon(pg.sprite.Sprite):
    def __init__(self, position):
        super().__init__()
        self.position = position
        self.image = pg.image.load(ICON_PATH)
        self.image = pg.transform.scale(self.image, (100, 100))
        self.rect = self.image.get_rect(center = position)
        self.is_right = True
        flipped_image = pg.transform.flip(self.image, True, False)
        self.image = flipped_image

    def update(self):
        self.rect.center = self.position

    def flip(self):
        flipped_image = pg.transform.flip(self.image, True, False)
        self.image = flipped_image

class Overworld:
    def __init__(self, start_level, max_level, surface, create_level):
        self.display_surface = surface
        self.max_level = max_level
        self.current_level = start_level
        self.create_level = create_level

        self.move_direction = pg.math.Vector2(0, 0)
        self.speed = 18
        self.is_moving = False

        self.setup_nodes()
        self.setup_icon()

    def setup_nodes(self):
        self.nodes = pg.sprite.Group()

        for node_idx, node_data in enumerate(levels.values()):
            if node_idx <= self.max_level:
                node_sprite = Node(node_data[LevelProperties.NODE_POS()], True, self.speed, node_idx)
            else:
                node_sprite = Node(node_data[LevelProperties.NODE_POS()], False, self.speed, node_idx)
            self.nodes.add(node_sprite)

    def draw_path(self):
        points = [node[LevelProperties.NODE_POS()] for idx, node in enumerate(levels.values()) if idx <= self.max_level]
        if len(points) < 2:
            return
        pg.draw.lines(self.display_surface, 'white', False, points, width=30)
        pg.draw.lines(self.display_surface, 'black', False, points, width=20)

    def setup_icon(self):
        self.icon = pg.sprite.GroupSingle()
        icon_sprite = Icon(self.nodes.sprites()[self.current_level].rect.center)
        self.icon.add(icon_sprite)

    def gather_input(self):
        keys = pg.key.get_pressed()

        if not self.is_moving:
            if keys[pg.K_RIGHT] and self.current_level < self.max_level:
                self.move_direction = self.get_movement_data(1)
                self.current_level += 1
                self.is_moving = True
                if not self.icon.sprite.is_right:
                    self.icon.sprite.flip()
                self.icon.sprite.is_right = True
            elif keys[pg.K_LEFT] and self.current_level > 0:
                self.move_direction = self.get_movement_data(-1)
                self.current_level -= 1
                self.is_moving = True
                if self.icon.sprite.is_right:
                    self.icon.sprite.flip()
                self.icon.sprite.is_right = False
            elif keys[pg.K_RETURN]:
                self.create_level(self.current_level)

    def restart(self):
        self.create_level(self.current_level)

    def get_movement_data(self, move_factor):
        start = pg.math.Vector2(self.nodes.sprites()[self.current_level].rect.center)
        idx = self.current_level + move_factor
        if idx > len(self.nodes.sprites()) - 1:
            idx = len(self.nodes.sprites()) - 1
        if idx < 0:
            idx = 0
        end = pg.math.Vector2(self.nodes.sprites()[idx].rect.center)
        vec = end - start
        if vec.length() == 0:
            return vec
        return (end - start).normalize()

    def update_icon_position(self):
        if self.is_moving and self.move_direction:
            self.icon.sprite.position += self.move_direction * self.speed;
            target_node = self.nodes.sprites()[self.current_level]
            if target_node.detection_zone.collidepoint(self.icon.sprite.position):
                self.is_moving = False
                self.move_direction = pg.math.Vector2(0, 0)

    def run(self):
        self.gather_input()
        self.update_icon_position()
        self.draw_path()
        self.nodes.draw(self.display_surface)
        self.icon.update()
        self.icon.draw(self.display_surface)


import sqlite3
import html2text
import re
from datetime import datetime
import os

class TenderWeightCalculator:
    def __init__(self, db_file='mydatabase.db'):
        script_dir = os.path.dirname(os.path.abspath(__file__))
        self.db_file = os.path.join(script_dir, db_file)

    def count_weight(self, target_text, conn):
        cursor = conn.cursor()
        # 遍历词汇表中的每个单词，并将匹配的 w 值进行累加
        total_weight = 0
        for row in cursor.execute("SELECT word, w FROM dictionary"):
            if re.search(row[0], target_text):
                print("匹配到关键词：", row[0], "，w 值为：", row[1])
                total_weight += row[1]

        # 返回总 w 值汇总分数
        return total_weight

    def update_tender_weight(self, refresh_all=False):
        # 连接 SQLite 数据库
        conn = sqlite3.connect(self.db_file)

        # 扫描所有字段 has_crawled>=1 的数据
        print("Scanning records...")
        now = datetime.now()
        today = now.strftime("%Y-%m-%d")
        if refresh_all:  # 刷新所有数据
            sql = f"SELECT id, title, weight, href, html FROM tender WHERE has_crawled >= 1"
        else:  # 只刷新今天的数据
            sql = f"SELECT id, title, weight, href, html FROM tender WHERE post_date = '{today}' AND " \
                  f"has_crawled >= 1 AND weight is null"
        cursor = conn.execute(sql)
        rows = cursor.fetchall()
        print(f"Found {len(rows)} records.")

        # 逐条将字段 html 的内容转为纯文字，并把 weight 累加起来
        print("Updating record weights...")

        for i, row in enumerate(rows):
            id, title, weight, href, html = row
            # print(row)
            if html:
                text = html2text.html2text(html)
                total_weight = self.count_weight(title + text, conn)

                print(f"{i + 1}. 标题：{title}，权重值：{total_weight}，链接：{href}")

                # 更新 tender 表 weight 字段的值
                sql = f"UPDATE tender SET weight = {total_weight} WHERE id = {id}"
                conn.execute(sql)

        # 提交事务
        conn.commit()
        print("Update complete.")

        # 关闭数据库连接
        conn.close()

if __name__ == '__main__':
    print("Updating tender weights...")
    tender_calc = TenderWeightCalculator()
    tender_calc.update_tender_weight(refresh_all=False)


from flask import Flask, render_template, request
from src.pipeline.predict_pipeline import PredictPipeline
import pandas as pd
import numpy as np
import datetime as dt
import math

app = Flask(__name__)

airline_names = ['Air India','Air Asia', 'Spice Jet','Indigo','GoAir','Jet Airways','Jet Airways Business','Multiple carriers', 'Multiple carriers Premium economy','Trujet', 'Vistara', 'Vistara Premium economy']
sources = ['Banglore','Kolkata','Delhi','Chennai','Mumbai']
destination = ['New Delhi','Banglore','Cochin','Kolkata','Delhi','Hyerbad']
stops = ['non-stop','1 stop','2 stops','3 stops','4 stops']
@app.route('/',methods=['GET','POST'])
def home():
    return render_template('index.html',airways=airline_names,source = sources,destination=destination,stops=stops)

@app.route('/predict',methods=['GET','POST'])
def predict():
    print('predicting...')
    print(request.method)
    if request.method == 'POST':
        airway= request.form.get('Airline')
        date = request.form.get('date')
        source = request.form.get('Source')
        destination = request.form.get('Destination')
        dep_time = request.form.get('dep_time')
        arr_time = request.form.get('arr_time')
        stops = request.form.get('Total_Stops')

        dl = date.split('-')
        date = dl[2]+'/'+dl[1]+'/'+dl[0]
        print(date)
        print(dep_time,',',arr_time)
        dur = f"{abs(int(arr_time.split(':')[0])- int(dep_time.split(':')[0]))}h {abs(int(arr_time.split(':')[1]) - int(dep_time.split(':')[1]))}m"
        print(dur)
        data = {
            "Airline" : airway,
            "Date_of_Journey" : date,
            "Source" : sources,
            "Destination" : destination,
            "Route" : "route",
            "Dep_Time" : dep_time,
            "Arrival_Time" : arr_time,
            "Duration" : dur,
            "Total_Stops" : stops,
            "Additional_Info" : "info"
        }
        df = pd.DataFrame(data)
        pred = PredictPipeline().predict(df.iloc[0])
        print(pred)

        return render_template('predict.html',h1=math.ceil(pred[0]))
    else:
        return render_template('predict.html',h1='error')

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0',port=5000)


# URI 1009 em Python 3.9
# Programador: Matheus Felipe Alves Durães
# Não copie códigos, apenas leia-os e
# tente entender O QUE e POR QUE fazem o que fazem.

def main():
    # Variavel nome recebe uma string do nome da pessoa
    nome = input()

    # Variavel salario_fixo recebe um valor float do salario fixo
    salario_fixo = float(input())

    # Variavel vendas recebe um valor float das vendas dele
    vendas = float(input())

    # Salario final é a soma do salario fixo com 15% das vendas
    salario_final = salario_fixo + (vendas * 0.15)

    # Imprimindo os resultados
    # PS: %.2f para imprimir somente 2 casas decimais do float
    print("TOTAL = R$ %.2f" %(salario_final) )

main()


import math
import itertools
import json

def load_hmm_data(filepath):
    with open(filepath, 'r') as file:
        data = json.load(file)
    return data

def is_valid_emission(emission_sequence, emission_symbols):
    return all(symbol in emission_symbols for symbol in emission_sequence)

def is_valid_transition(sequence, transition_matrix, state_symbols, initial_probabilities):
    n = len(sequence)
    m = 0
    is_possible = True

    if abs(initial_probabilities[state_symbols.index(sequence[0])]) < 1e-10:
        is_possible = False

    while m < n - 1 and is_possible:
        i = state_symbols.index(sequence[m])
        j = state_symbols.index(sequence[m + 1])

        if abs(transition_matrix[i][j]) < 1e-10:
            is_possible = False

        m += 1

    return is_possible

def find_emission_states(emission, emission_matrix, emission_symbols, num_states):
    emission_index = emission_symbols.index(emission)
    emitting_states = set()

    for i in range(num_states):
        if abs(emission_matrix[i][emission_index]) >= 1e-10:
            emitting_states.add(i)

    return emitting_states

def calculate_sequence_probability(state_sequence, emission_sequence, state_symbols, emission_symbols, transition_matrix, emission_matrix, initial_probabilities):
    sequence_length = len(state_sequence)
    probability = initial_probabilities[state_symbols.index(state_sequence[0])]

    for i in range(sequence_length):
        row_transition = state_symbols.index(state_sequence[i - 1]) if i > 0 else -1
        col_transition = state_symbols.index(state_sequence[i])
        col_emission = emission_symbols.index(emission_sequence[i])

        prob_transition = 1.0 if row_transition == -1 else transition_matrix[row_transition][col_transition]
        prob_emission = emission_matrix[col_transition][col_emission]

        probability *= prob_transition * prob_emission

    return probability

def hmm_path_finder():
    filepath = input("Enter the file path for HMM data: ")
    data = load_hmm_data(filepath)

    state_symbols = data['states']
    emission_symbols = data['emissions']
    transition_matrix = data['transition_matrix']
    emission_matrix = data['emission_matrix']
    initial_probabilities = data['initial_probabilities']

    while True:
        emission_sequence = input("Enter the next emission sequence (type 'exit' to quit): ")

        if emission_sequence == "exit":
            break

        if is_valid_emission(emission_sequence, emission_symbols):
            possible_transitions = []
            emission_sequence_length = len(emission_sequence)

            emission_state_sets = []
            for symbol in emission_sequence:
                emission_state_sets.append(find_emission_states(symbol, emission_matrix, emission_symbols, len(state_symbols)))

            cartesian_product_states = list(itertools.product(*emission_state_sets))

            for transition in cartesian_product_states:
                if is_valid_transition([state_symbols[state] for state in transition], transition_matrix, state_symbols, initial_probabilities):
                    possible_transitions.append(transition)

            state_probability_pairs = []
            max_probability_sequence = ('', 0.0)

            for path in possible_transitions:
                probability = calculate_sequence_probability([state_symbols[state] for state in path], emission_sequence, state_symbols, emission_symbols, transition_matrix, emission_matrix, initial_probabilities)
                state_sequence = [state_symbols[state] for state in path]
                state_probability_pairs.append((state_sequence, probability))
                print("Next probable sequence is:", state_sequence, "with probability:", probability)

                if max_probability_sequence[1] < probability:
                    max_probability_sequence = (state_sequence, probability)

            print("Maximum probability sequence is:", max_probability_sequence[0], "with probability:", max_probability_sequence[1])
        else:
            print("Invalid emission sequence. Please enter a valid sequence.")

hmm_path_finder()


import numpy as np
from matplotlib import pyplot as plt
# 实现折线形式的随机漫步
# n = int(input("请输入你想要慢步的次数"))
# y_values = []
# for y in range(0,n):
#     y_values.append(np.random.sample())
# x_values = [x for x in np.arange(0,n)]
# plt.figure()
# plt.plot(x_values,y_values,linewidth=1,color='red')
# plt.show()

#随机点式的漫步：
#如上换成scatter就可以了。，
# 注意点的随机漫步也要随机x轴
n = int(input("请输入你想要漫步的次数："))
x_values = []
y_values = []
for x in range(n):
    x_values.append(np.random.randint(low=-2,high=3))
x = np.cumsum(x_values)
for y in range(n):
    y_values.append(np.random.rand())
y = np.cumsum(y_values)
plt.figure()
plt.scatter(x,y,edgecolors='blue')
plt.show()


#!/usr/bin/python3
from argparse import ArgumentParser
from os import system
from subprocess import Popen
from time import sleep

delay = 5
modes = ["H", "B", "R", "X"]

# Parses the input arguments.
parser = ArgumentParser(description="Generates the SlowHTTPTest pcap file")
parser.add_argument("--app", default="slowhttptest-1.6", help="the name of the application")
parser.add_argument("--os", default="linux-4.17.0", help="the name of the OS")
parser.add_argument("--folder", default=".", help="the folder that will contain the produced pcap file")
parser.add_argument("urls", help="the comma separated list of target URLs")
args = parser.parse_args()

# Builds the URL list.
urls = args.urls.split(",")

# Captures the traffic.
# pcap = "%s/%s_%s_none.pcap" % (args.folder, args.app, args.os)
# system("tshark -Q -F libpcap -w %s \"tcp and (port 443 or port 80)\" &> /dev/null &" % pcap)
for mode in modes:
    # Builds the URL list.
    print("Mode %s" % mode)
    print("%d URLs" % len(urls))
    pcap = "%s/%s-%s_%s_none.pcap" % (args.folder, args.app, mode, args.os)
    system("tshark -Q -F libpcap -w %s \"tcp and (port 443 or port 80)\" &> /dev/null &" % pcap)
    sleep(delay)
    count = 1
    for i in urls:
        print("%d) %s" % (count, i))
        pid = Popen(["slowhttptest", "-%s" % mode, "-u", i]).pid
        sleep(60)
        system("killall slowhttptest")
        count += 1
    sleep(delay)
    system("killall tshark")
    sleep(delay)


import os
import argparse
import pandas
import sys
import shutil
import re
from subprocess import Popen

import func as mcfn

# Preliminaries
pyenv, bashenv, mercuryOG_path, rslts_path = mcfn.read_envfile("envfile.txt", "all")

if rslts_path.endswith("/"):
    rslts_path = rslts_path[:-1]
if mercuryOG_path.endswith("/"):
    mercuryOG_path = mercuryOG_path[:-1]

parser = argparse.ArgumentParser()
parser.add_argument('--files', '-f',
                    dest='files',
                    action='store')
args = parser.parse_args()

options = args.files
ftype, rang = options.split(",")

# Get relevant output files and their destination after conversion
outputs = os.listdir("{}/outputs/".format(rslts_path))
outputs = mcfn.sort(outputs, ftype, rang)
destination = "{}/converted_outputs".format(rslts_path)
if not os.path.exists(destination):
    os.mkdir(destination)

# Rename output files, convert, rename and move to destination
for outfile in outputs:
    shutil.copyfile("{}/outputs/{}".format(rslts_path, outfile),
            "converter/{}".format(outfile[-6:]))
    ftype = outfile[-6:-4]
    k = outfile[:-7]
    if ftype == "xv":
        os.system("(cd converter/; ./element6)")
        ext = ".aei"
    elif ftype == "ce":
        os.system("(cd converter/; ./close6)")
        ext = ".clo"
    convfiles = [file for file in os.listdir("converter/") if file.endswith(ext)]
    [shutil.copyfile("converter/{}".format(file), "{}/{}-{}".format(destination, k, file))
            for file in convfiles]

    # clean converter directory
    [os.remove("converter/{}".format(file)) for file in convfiles]
    [os.remove("converter/{}".format(file)) for file in os.listdir("converter/")
            if file.endswith(".out")]


# -----------------------------------------------------------------------------
# Name:        HaulsModel.py
# Purpose:     Model for Hauls and Sets (Observer)
#
# Author:      Will Smith <will.smith@noaa.gov>
#
# Created:     Feb 24, 2016
# License:     MIT
# ------------------------------------------------------------------------------

import textwrap

from playhouse.shortcuts import model_to_dict
from PyQt5.QtCore import pyqtSlot

from py.common.FramListModel import FramListModel
from py.common.FramUtil import FramUtil
from py.observer.ObserverDBModels import FishingActivities, FishingLocations

class HaulSetModel(FramListModel):
    """
    Contains multiple FishingActivities
    """

    GEAR_TYPE_TRAWL = "Trawl"
    GEAR_TYPE_FIXED_GEAR = "Fixed Gear"

    def __init__(self, parent=None):
        super().__init__(parent)
        for role_name in self.haul_set_rolenames:
            self.add_role_name(role_name)

    @property
    def haul_set_rolenames(self):
        """
        :return:
        """
        rolenames = FramUtil.get_model_props(FishingActivities)
        # Add additional roles not specified in DB (e.g. Vessel Name, to be acquired via FK)
        rolenames.append('trip_id')
        rolenames.append('target_strategy_code')
        rolenames.append('location_start_end')
        rolenames.append('errors')
        return rolenames

    def most_recent_haul_set_id(self):
        """
        Get empty haul if empty, or newest haul in the list
        Useful for deletions
        TODO db ID instead?
        :return: string '-1' if no hauls, haul_id otherwise
        """
        if self.count == 0:
            return '-1'
        else:
            lastitem = self.items[-1]
            return lastitem['fishing_activity_num']

    def add_haul(self, db_model):
        """
        :param db_model: peewee model object (cursor) created elsewhere (in Hauls)
        :return: FramListModel index of new trip (int)
        """
        try:
            newhaul = self._get_haul_set_dict(db_model)
            newidx = self.appendItem(newhaul)
            self._logger.debug('Added haul #' + str(newhaul['fishing_activity_num']))
            return newidx

        except ValueError as e:
            self._logger.error('Error adding new haul ' + str(e))
            return -1

    def add_set(self, db_model):
        """
        :param db_model: peewee model object (cursor) created elsewhere (in Hauls)
        :return: FramListModel index of new trip (int)
        """
        try:
            newset = self._get_haul_set_dict(db_model)
            newidx = self.appendItem(newset)
            self._logger.debug('Added set #' + str(newset['fishing_activity_num']))
            return newidx

        except ValueError as e:
            self._logger.error('Error adding new set ' + str(e))
            return -1

    def remove_haul_set(self, activity_id):
        """
        :param activity_id: ID of haul or set (int) to axe
        """
        try:
            # Delete from FramListModel
            model_idx = self.get_item_index('fishing_activity', activity_id)
            if model_idx >= 0:
                self.remove(model_idx)
                return True
            else:
                self._logger.error('Unable to find and remove haul/set {} from model.'.format(activity_id))
        except ValueError as e:
            self._logger.error('Error deleting haul/set: ' + str(e))
        return False

    def get_fishing_num_index(self, fishing_num):
        return self.get_item_index('fishing_activity_num', fishing_num)

    def get_haul_set_index(self, activity_id):
        return self.get_item_index('fishing_activity', activity_id)

    def _get_haul_set_dict(self, db_model):
        """
        Build a dict that matches HaulsModel out of a peewee model
        Purpose is for storing peewee model <-> FramListModel
        :param db_model: peewee model to convert
        :return: dict with values translated as desired to be FramListModel friendly
        """
        haul_set_dict = model_to_dict(db_model)

        # Rename from model-> dict:
        # hauldict['new_thing'] = hauldict.pop('old_thing')
        # Add ID's for reference, if needed...
        # hauldict['trip_id'] = db_model.trip.trip
        haul_set_dict['target_strategy_code'] = \
            db_model.target_strategy.catch_category_code if db_model.target_strategy else None
        start, end = self._get_haul_set_start_end(db_model.fishing_activity)
        haul_set_dict['location_start_end'] = textwrap.fill('{} to {}'.format(start, end), width=20)
        haul_set_dict['errors'] = ''

        return haul_set_dict

    @pyqtSlot(int, result='QVariant', name='getLocationData')
    def get_location_data(self, activity_id):
        """
        Get Set/Up/Location info
        @param activity_id: DB ID
        @return: 2D Array built from Set/Up/# locations
        """
        self._logger.info('Loading FishingLocationsModel for haul ID {}'.format(activity_id))
        location_data_var = []
        locs_q = FishingLocations.select().where(FishingLocations.fishing_activity == activity_id)
        if len(locs_q) > 0:
            for loc in locs_q:  # Build FramListModel
                date_str, time_str = loc.location_date.split(' ')
                lat_deg, lat_min = FramUtil.convert_decimal_degs(loc.latitude)
                long_deg, long_min = FramUtil.convert_decimal_degs(loc.longitude)
                location_data_var.append({
                    'haul_db_id': loc.fishing_activity.fishing_activity,  # id
                    'loc_id': loc.fishing_location,
                    'position': loc.position,  # position -1, 0, ... (Set, Up, etc)
                    'date_str': date_str,
                    'time_str': time_str,
                    'lat_deg': lat_deg,
                    'lat_min': lat_min,
                    'long_deg': long_deg,
                    'long_min': long_min,
                    'depth': loc.depth
                })

        return location_data_var

    def _get_haul_set_start_end(self, activity_id):
        # locs_q = FishingLocations.select().where(FishingLocations.fishing_activity == haul_id)

        start_loc = self.get_loc_set(activity_id)
        end_loc = self.get_loc_up(activity_id)
        set_str = '{}'.format(start_loc.location_date) if start_loc else '-'
        # FIELD-846, use start date if no end date
        up_str = '{}'.format(end_loc.location_date) \
            if end_loc else ('({})'.format(set_str) if start_loc else '-')
        return set_str, up_str

    @staticmethod
    def _get_haul_set_loc(activity_id, position):
        try:
            loc = FishingLocations.get(FishingLocations.fishing_activity == activity_id,
                                       FishingLocations.position == position)
        except FishingLocations.DoesNotExist:
            loc = None
        return loc

    @pyqtSlot(int, result='QVariant', name='getLocationSet')
    def get_loc_set(self, haul_id):  # start of haul
        return self._get_haul_set_loc(haul_id, -1)

    @pyqtSlot(int, result='QVariant', name='getLocationUp')
    def get_loc_up(self, haul_id):  # end of haul
        return self._get_haul_set_loc(haul_id, 0)


from receptors import *
from processors import *
from event import *
from datasource import *
import logging

class InstanceFactory(object):
    """
    Factory and Registry class that can register object instances and
    matches instance references (@id in config files)

    @author Jannis Mosshammer <jannis.mosshammer@netways.de>
    """

    def __init__(self, config):
        """
        Initialize with the base edbc.cfg file as a starting point.
        The section global will be ignored here.
        """
        self.config = config
        self.deferred = {}
        instanceDefs = self.config.get_instance_definitions()
        self.instances = { "all": {} }
        for instance_id in instanceDefs:
            if instance_id == "global":
                continue
            cfg_object = instanceDefs[instance_id]
            self.register(instance_id, cfg_object)

        logging.debug("Registered %i instances", len (self.instances["all"]))

    def defer_registration(self, required, args):
        """ If an instance can' t be registered, because dependencies are missing
            registration will be deferred until the dependencies are met
        """
        if not required in self.deferred:
            self.deferred[required] = []

        self.deferred[required].append(args)

    def apply_template(self, cfg_object):
        """ Reads the basic config of the parent instance and applies it to the given cfg_object

        """
        parent = self.__getitem__(cfg_object["template"])
        for i in parent.base_config:
            if not i in cfg_object:
                cfg_object[i] = parent.base_config[i]

    def register(self, instance_id, cfg_object, factory_fn = None):
        """
        Registers an object cfg_object with the identifier id.
        the cfg_object is expected to have a class attribute, which will be registered and
        used for instance creation.

        If factory_fn is given, this will be called (class is
        only being registered here and not used for instance creation), otherwise
        %class%.setup(id, cfg_object) is called.

        Instances look like
        {
            "class": "CLASSNAME",
            "type" : "typename",
            "arg1" : "argval1"
            ...
            "argN" : "argvalN"
            "ref1" : "@referencedId"
        }

        """
        # type myType and class myClass will be called MyTypeMyClass()
        required = self.resolve_references(cfg_object)
        if required != None:
            self.defer_registration(required,(instance_id, cfg_object, factory_fn))
            return False

        r = None

        if "template" in cfg_object:
            if not cfg_object["template"] in self.instances["all"]:
                self.defer_registration(required,(instance_id, cfg_object, factory_fn))
                return False
            else:
                self.apply_template(cfg_object)

        if not cfg_object["class"] in self.instances:
            self.register_class(cfg_object["class"])

        if factory_fn == None:
            # Default factory using the setup method
            instance_cls = cfg_object["class"].capitalize()
            configname = cfg_object["type"].capitalize()+instance_cls
            if not configname in globals():
                logging.error("Couldn't find %s, %s won't work.", configname, instance_id)
                return False

            r = globals()[configname]()

            logging.debug("Instance of %s : %s (instance_id=%i)", instance_id, r, id(r))
            r.setup(instance_id, cfg_object)
        else:
            # Pass instance creation to factory function
            r = factory_fn(instance_id, cfg_object)
        try:
            r.base_config = cfg_object
        except:
            pass
        self.instances[cfg_object["class"]][instance_id] = r
        self.instances["all"][instance_id] = r
        self.handle_unresolved(instance_id)
        return True

    def handle_unresolved(self, instance_id):
        """ Checks if deferred registrations can now be completed and completes them if so

        """
        if "@"+instance_id in self.deferred:

            unmatched = []
            while self.deferred["@"+instance_id]:
                item = self.deferred["@"+instance_id].pop()
                if not self.register(item[0], item[1], item[2]):
                    unmatched.append(item)
            if unmatched:
                self.deferred["@"+instance_id] = unmatched
            else:
                del self.deferred["@"+instance_id]

    def has_unmatched_dependencies(self):
        """ Returns true if there are instances waiting for dependencies to be fully registered

        """
        logging.debug(self.deferred)
        return len(self.deferred) > 0

    def resolve_references(self, cfgobject):
        """ resolves config variables beginning with @, i.e. refrences to other instances

        """
        for i in cfgobject:
            if not isinstance(cfgobject[i], basestring):
                continue
            if cfgobject[i].startswith('@'):
                resolved = self.__getitem__(cfgobject[i])
                if not resolved:
                    return cfgobject[i]
                cfgobject[i] = resolved

    def register_class(self, classname):
        """ Registers the class with classname in the factories instances list and creates a
            get%Classname% method to allow convenient access

        """
        classname = classname.strip()
        self.instances[classname] = {}

        # register class methods so they are available with get%CLASS%(id)
        getter = lambda id: self.instances[classname][(id, id[1:])[id[0] == '@']]
        getter.__name__ = "get"+classname.capitalize()
        setattr(self, getter.__name__, getter)

        # register getAll%Class%Instances method
        getter = lambda : self.instances[classname]
        logging.debug("Registering %s ", "getAll"+classname.capitalize()+"Instances")
        getter.__name__ = "getAll"+classname.capitalize()+"Instances"
        setattr(self, getter.__name__, getter)

    def getAllChainInstances(self):
        if "chain" in self.instances:
            return self.instances["chain"]
        return []

    def __getitem__(self, instance_id):
        """
        Returns the object instance that can be found under the id "id"
    """
        if instance_id[0] == '@':
            instance_id = instance_id[1:]
        if instance_id in self.instances:
            return self.instances[instance_id]
        if instance_id in self.instances["all"]:
            return self.instances["all"][instance_id]
        return None


# encoding: utf-8

from yast import import_module
import_module('UI')
from yast import *
class SpecialWidgetClient:
    def main(self):
      # Build a dialog with a "special" widget - one that may not be supported
      # by all UIs.

      # Ask the UI whether or not it supports this widget.

      if UI.HasSpecialWidget("DummySpecialWidget"):
        # Only create a dialog with this kind of widget if it is supported

        UI.OpenDialog(
          VBox(DummySpecialWidget(), PushButton(Opt("default"), "&OK"))
        )
      else:
        # Always provide a fallback: Either try to create a simpler dialog
        # without the special widget, or terminate with an error message.

        UI.OpenDialog(
          VBox(
            Label("Special Widget not supported!"),
            PushButton(Opt("default"), "&Oops!")
          )
        )

      UI.UserInput()
      UI.CloseDialog()

SpecialWidgetClient().main()


"""
Solutions to Day 1 of Advent of Code by Alvaro Clemente
"""
from itertools import combinations

# Parse input
with open("input.txt", "r") as f:
    lines = f.readlines()
    nums = [int(x.strip()) for x in lines]

# Solution for #1
for a, b in combinations(nums, 2):
    if a + b == 2020:
        print(f"Solution combination is {a} + {b} = 2020 -> solution is {a * b}")

# Solution for #2
for a, b, c in combinations(nums, 3):
    if a + b + c == 2020:
        print(f"Solution combination is {a} + {b} + {c} = 2020 -> solution is {a * b * c}")


"""
跳跃游戏 II
给出一个非负整数数组，你最初定位在数组的第一个位置。
数组中的每个元素代表你在那个位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
样例
给出数组A = [2,3,1,1,4]，最少到达数组最后一个位置的跳跃次数是2(从数组下标0跳一步到数组下标1，然后跳3步到数组的最后一个位置，一共跳跃2次)"""
#://leetcode.com/discuss/422/is-there-better-solution-for-jump-game-ii?show=422#q422
"""
In DP, if you use an array to track the min step at [i], not only will you know the minimum steps needed to get to the destination, but also how to get there. With simple calculation on your array, you can find every optimal road to the end.

This unnecessary information lead to unnecessary cost.

What we really need to do is to calculate: with k steps, what's the furthest point I can reach.

public static int jump(int[] A){ // Jump Game II
    if(null == A || A.length <= 1) return 0;

    int minSteps = 0;
    int furthest = 0;
    int toCheck = 0;
    while(furthest < A.length - 1){
        int endIndex = furthest;
        while(toCheck <= endIndex){
            furthest = Math.max(furthest, toCheck + A[toCheck]);
            toCheck++;
        }
        if(furthest == endIndex) return -1; // this.time.furthest == last.time.furthest: we're trapped, which means the destination cannot be reached.
        minSteps++;
    }
    return minSteps;
}
"""
class Solution:
    # @param A, a list of integers
    # @return an integer
    def jump(self, A):
        length = len(A)
        if length <= 0:
            return 0
        steps, maxjump, i = 0, 0, 0
        while maxjump < length- 1:
            temp = maxjump
            while i<= temp:
                maxjump = max(maxjump, i+ A[i])
                i += 1
            if maxjump == temp:
                return False
            steps += 1
        return steps


'''
@author: Xing Zheng
Extracts elevations at station points of a cross-section from an intermediate file
'''

import string
import os
import sys
import numpy as np

def ReadGIS(GISfilename): # reads from txt file and writes to excel
    Data = open(sys.path[0] + "\\" + GISfilename+'.txt','r')
    lines = Data.readlines()
    i = 0
    Riverstring = "River Name"
    Reachstring = "Reach Name"
    Stationstring = "RiverStation"
    for i in range(len(lines)):
        if lines[i].startswith(Riverstring):
            Rivername = lines[i][11:-2]
            Rivername = Rivername.replace(" ","_")
        elif lines[i].startswith(Reachstring):
            Reachname = lines[i][11:-2]
            Reachname = Reachname.strip(" ")
            Reachname = Reachname.replace(" ","_")
        elif lines[i].startswith(Stationstring) and '*' not in lines[i] :
            if lines[i+1].startswith("XS"):
                Riverstation = lines[i][13:-2]
                Riverstation = Riverstation.strip(" ")
                X = []
                Y = []
                XY = []
                Distance = [0]
                Datapair = int(lines[i+1][16:-1]) # Get the number of GIS co-ordinate points
                Filename = Rivername + '_' + Reachname + '_' + Riverstation
                output = open(os.getcwd() + "\\Result\\GIS\\" + Filename + ".csv", 'w') # write the distance to XLS
                for j in range(Datapair):
                    XY = lines[i+3+j][:-1].split(",")
                    X.append(XY[0])
                    Y.append(XY[1])
                output.write("X(ft),Y(ft),Distance(ft)\n")
                output.write(X[0]+","+Y[0]+",0"+"\n")
                for j in range(1,Datapair):
                    Distance.append(((float(X[j])-float(X[j-1]))**2+(float(Y[j])-float(Y[j-1]))**2)**0.5 + Distance[j-1])
                    output.write(X[j]+","+Y[j]+","+str(Distance[j])+"\n")
                output.close()

def ReadGeometry(Geometryfilename): # station elevation table and write to CSV

    Data = open(sys.path[0] + "\\" + Geometryfilename + ".txt","r")
    lines = Data.readlines()
    i = 0
    Riverstring = "River Name"
    Reachstring = "Reach Name"
    Stationstring = "RiverStation"
    for i in range(len(lines)):
        if lines[i].startswith(Riverstring):
            Rivername = lines[i][11:-2]
            Rivername = Rivername.replace(" ","_")
        elif lines[i].startswith(Reachstring):
            Reachname = lines[i][11:-2]
            Reachname = Reachname.strip(" ")
            Reachname = Reachname.replace(" ","_")
        elif lines[i].startswith(Stationstring) and '*' not in lines[i] :
            if lines[i+1].startswith("#Sta/Elev"):
                Riverstation = lines[i][13:-1].strip(' ')
                Filename = Rivername + '_' + Reachname + '_' + Riverstation
                output = open(os.getcwd() + "\\Result\\Geometry\\" + Filename + ".csv", 'w')
                output.write("Station(ft),Elevation(ft)\n")
    ##        elif lines[i].startswith('#Sta/Elev'):
                Datapair = int(lines[i+1][11:-1])
                for j in range(Datapair):
                    output.write(lines[i+3+j])
                output.close()

def CreatePoint(): # Interpolate X,Y,Z for each station point
    GISfolder = sys.path[0] + "\\Result\\GIS"
    Geometryfolder = sys.path[0] + "\\Result\\Geometry"
    Pointfolder = sys.path[0] + "\\Result\\Point"
    for GISfilename in os.listdir(GISfolder):
        for Geometryfilename in os.listdir(Geometryfolder):
            if GISfilename == Geometryfilename:
                Pointfilename = GISfilename
                Pointfilelocation = Pointfolder + "\\" + Pointfilename
                GISfilelocation = GISfolder + "\\" + GISfilename
                X, Y, Distance = np.loadtxt(GISfilelocation, delimiter=",", skiprows=1, usecols=(0,1,2), unpack=True)
                Geometryfilelocation = Geometryfolder + "\\" + Geometryfilename
                S, H = np.loadtxt(Geometryfilelocation, delimiter=",", skiprows=1, usecols=(0,1), unpack=True)
                PointX = np.empty(len(S))
                PointY = np.empty(len(S))
                PointM = np.empty(len(S))
                PointM = S*(Distance[-1]/S[-1])
                PointX = np.interp(S,Distance,X)
                PointY = np.interp(S,Distance,Y)
                np.savetxt(Pointfilelocation, np.column_stack((PointX,PointY,H,PointM)), fmt='%16.8f',delimiter=',', newline='\n', header='PointX,PointY,PointZ,PointM', comments='')
                continue

def XSPointmerge(): # make one big xls file

    Pointfolder = sys.path[0] + "\\Result\\Point"
    XSPoint = open(os.getcwd() + "\\Result\\XSPoint.csv", 'a')
    XSPoint.write("PointX,PointY,PointZ,PointM\n")
    for Pointfilename in os.listdir(Pointfolder):
        if Pointfilename.endswith(".csv"):
            XSPointpath = open(Pointfolder + "\\" + Pointfilename, 'r')
            XSPointset = XSPointpath.readlines()[1:]
            for line in XSPointset:
                XSPoint.write(line)
    XSPoint.close

def main():
    GISfilename = 'XSGIS'
    Geometryfilename = 'XSGeometry'
    ReadGIS(GISfilename)
    ReadGeometry(Geometryfilename)
    CreatePoint()
    XSPointmerge()
    print ("Work done! Please go to your project folder "
           + os.getcwd() + "\\Result" + " to check your result\n")

    done = raw_input('(press ENTER to quit)')

if __name__ == "__main__":
    main()