import numpy
import theano
import theano.tensor as T

class NeuralNet():

    '''
    This class creates a neural network object capable of multiple hidden
    layers. The gradient calculation uses theano's symbolic differentiation and
    can take advantage of GPU computation.

    There is a theano MultiLayer Perception (MLP) available at:
    http://deeplearning.net/tutorial/mlp.html

    Parameters
    ----------
    Layers: list of integers specifying the number of nodes in each layer
    '''

    def __init__(self, layers):
        # This method initializes the network object weights and bias nodes

        self.iter = 1000  #number of iterations for training

        self.weights = []
        self.mask = []

        # Setting the seed allows repeatable weight initialization
        rng = numpy.random.RandomState(7)

        # Create weights for each hidden layer
        for index in range(len(layers[:-1])):
            weights, masks = self.createLayer(rng, layers[index],
                                       layers[index + 1], '%d' % index)
            self.weights.append(weights)
            self.mask.append(masks)

        self.params = self.weights

    def createLayer(self, rng, n_in, n_out, suffix):
        # I think of network layers as the activation nodes. Activation nodes
        # are generated by feeding forward through the network.
        # This method creates weights with optimal magnitude for sigmoid
        # activation and stores them as theano tensor variables.

        # n_in & _out: are the number of connections into/out of current layer
        # suffix: designates the current layer in the network

        n_in = n_in + 1 #adding weight for bias nodes

        # Generate weights as numpy matrix.
        W_values = numpy.asarray(rng.uniform(
            low=-numpy.sqrt(6. / (n_in + n_out)),
            high=numpy.sqrt(6. / (n_in + n_out)),
            size=(n_in, n_out)), dtype=theano.config.floatX)
        W_values *= 4

        # Create mask matrix for sparse connectivity
        mask = numpy.ones((n_in, n_out), dtype=theano.config.floatX)

        # Store weighs as shared variable
        w = theano.shared(value=W_values, name='W_{}'.format(suffix))

        return w, mask

    def cost(self, x, y, L2=0.00001):
        # This method calculates the logistic cost with a  correction, L2, for
        # large/biased weight values.

        # x: network input
        # y: expected network result
        # L2: correction factor for large/biased weights

        # Update network out put by feeding input forward with current weights
        self.y = T.dot(x, (self.weights[0] * self.mask[0]))
        self.y = T.nnet.sigmoid(self.y)
        for index in range(len(self.weights[1:])):
            bias = T.ones((T.shape(self.y)[0], 1))
            self.y = T.concatenate((bias, self.y), axis=1)  # Add bias node
            self.y = T.dot(self.y, (self.weights[index + 1] * self.mask[index + 1]))
            self.y = T.nnet.sigmoid(self.y)

         # Calculate logistic error
        logErr = y * T.log(self.y) + (1 - y) * T.log(1 - self.y)
        cost = -1. / y.shape[0] * logErr.sum()

        # Add L2 cost correction
        cost = cost + L2 * sum([(w ** 2).sum() for w in self.weights])

        return cost

    def train(self, data_in, data_out, learning_rate=0.0007, momentum=0.9, L2=0.00001):
        # This method trains the neural network using theano's symbolic gradient
        # calculation. YAY didn't have to write out back propagation.

        # data_in: data input
        # data_out: expected result for data input
        # learning_rate: step factor for gradient move
        # L2: correction factor for large/bias weights

        x = T.matrix('x')
        y = T.matrix('y')

        # Calculate the cost gradient with respect to params (list of weights)
        paramGrad = []
        for param in self.params:
            gradient = T.grad(self.cost(data_in, data_out, L2), wrt=param)
            paramGrad.append(gradient)

        # Update params (weights) by paramGrad
        updates = []
        for param, paramGrad in zip(self.params, paramGrad):
            updates.append((param, momentum * param + (1. - momentum) *
                                          (param - learning_rate * paramGrad)))

        # Create a theano function `trainNet` that returns the cost given the
        # data input and expected result while updating the network weights in
        # `updates`
        self.trainNet = theano.function(inputs=[x, y],
                                        outputs=self.cost(x, y),
                                        updates=updates)

        # Make sure the dtype will work with the theano configuration
        data_in = numpy.array(data_in, dtype=theano.config.floatX)
        data_out = numpy.array(data_out, dtype=theano.config.floatX)

        # Run the train function for n iterations (1000)
        self.icost = []
        for i in range(self.iter):
            self.icost.append(self.trainNet(data_in, data_out))

    def predict(self, x):
        # This method is for a trained network. It feeds the input data, x,
        # through the network and returns the network prediction

        # Make sure the dtype will work with the theano configuration
        x = numpy.array(x, dtype=theano.config.floatX)

        y = T.dot(x, self.weights[0])
        y = self.y = T.nnet.sigmoid(y)
        for index in range(len(self.weights[1:])):
            bias = T.ones((T.shape(self.y)[0], 1))
            self.y = T.concatenate((bias, self.y), axis=1) # Add bias node
            y = T.dot(y, self.weights[index + 1])
            self.y = T.nnet.sigmoid(y)

        return y


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

import json
import socket, time

class Address():
    def __init__(self, ip, mask: int, port: int):
        self.ip = ip;
        self.mask = mask;
        self.port = port;

    def __eq__(self, another):
        return self.ip == another.ip and self.mask == another.mask and self.port == another.port;

class Packet():
    def __init__(self, src: Address = None, dest: Address = None, payload=None, packetType: int = None):
        self.src = src;
        self.dest = dest;
        self.payload = payload;
        self.packetType = packetType;  # 0表示普通数据包，1表示OSPF的链路状态信息数据包,2表示该数据包是一条发送数据包的指令

    # 序列化之后，就可以把序列化后的内容写入磁盘，或者通过网络传输到别的机器上
    def serialize(self):
        return json.dumps(self, default=lambda obj: obj.__dict__);

    def deserialize(self, serialization):
        d = json.loads(serialization);
        self.src = Address(d['src']['ip'], d['src']['mask'], d['src']['port']);
        self.dest = Address(d['dest']['ip'], d['dest']['mask'], d['dest']['port']);
        self.payload = d['payload'];
        self.packetType = int(d['packetType']);

class OSPF_ForwardingTableEntry():
    def __init__(self, dest: str = None, nextHop: str = None):
        self.dest = dest;
        self.nextHop = nextHop;

    def __str__(self):
        return "dest: " + str(self.dest) + ", next-hop: " + str(self.nextHop);

class RIP_RoutingTableEntry():
    def __init__(self, dest: str = None, nextHop: str = None, hopsToDest: int = 0):
        self.dest = dest;
        self.nextHop = nextHop;
        self.hopsToDest = hopsToDest;

    def __str__(self):
        return "dest: " + str(self.dest) + ", next-hop: " + str(self.nextHop) + ", hops-to-dest: " + str(
            self.hopsToDest);

def address_To_name(addr: Address):
    for nodeName in {'D', 'B', 'C', 'A', 'E'}:  # ...................
        if addr == name_To_address(nodeName):
            return nodeName;

def name_To_address(name):
    with open('../Configuration/Nodes/' + name + '.txt', 'r') as f:
        f.readline();

        ip = f.readline().strip();  # strip()把末尾的'\n'删掉
        mask = int(f.readline().strip());
        port = int(f.readline().strip());
        return Address(ip, mask, port);

def get_node_neighbors(name):
    neighbors = {};

    with open('../Configuration/Topo/Cost.txt', 'r') as f:
        line = '';
        for i in range(ord(name) - ord('A') + 1):
            line = f.readline().strip();

        count = 0;
        for n in line.split():
            if int(n) > 0:
                neighbors[chr(65 + count)] = (name_To_address(chr(65 + count)), int(n));
            count += 1;
    return neighbors;

class Node():
    '''
    name: str  # eg: 'A', 'B'
    address: Address
    neighbors: dict  # eg: {'D': (<__main__.Address object at 0x7f3c575d7a90>, 60), 'E': (<__main__.Address object at 0x7f3c575d7ac8>, 20), 'C': (<__main__.Address object at 0x7f3c575d7a58>, 80)}
    socket: socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    '''

    def __init__(self, name):
        self.name = name;
        self.address = name_To_address(name);
        self.neighbors = get_node_neighbors(name);

        self.receiveSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM);  # 采用UDP
        self.receiveSocket.bind((self.address.ip, self.address.port));  # 用于接收数据，相当于UDP server
        self.sendSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM);  # 用于发送数据

        self.OSPF_forwardingTable = [];
        self.RIP_routingTable = [];

    def printOutputMessageHeader(self):
        print(self.name + '(' + time.strftime("%H:%M:%S", time.localtime()) + ') >>> ', end='');

    def printOSPFForwardingTable(self):
        print('   OSPF Forwarding Table of', self.name, ':');
        for i in range(len(self.OSPF_forwardingTable)):
            print(i, ' ****** ', self.OSPF_forwardingTable[i]);

    def printRIPRoutingTable(self):
        print('            RIP Table of', self.name, ':');
        for i in range(len(self.RIP_routingTable)):
            print(i, ' ****** ', self.RIP_routingTable[i]);

    def send_a_normal_packet(self, dest: Address, payload, packetType):
        sendpkt = Packet(self.address, dest, payload, packetType);
        self.forward_a_normal_packet(sendpkt);

    def forward_a_normal_packet(self, recvPkt: Packet):
        packetDest = address_To_name(recvPkt.dest);
        packetSrc = address_To_name(recvPkt.src);

        if packetDest == self.name:
            self.printOutputMessageHeader();
            print('Receive a normal packet. [', 'FROM:', packetSrc, ', CONTENT:', recvPkt.payload, ']');
        # response
        else:
            # OSPF查找自己的forwarding table
            if self.OSPF_forwardingTable:
                for i in range(len(self.OSPF_forwardingTable)):

                    if self.OSPF_forwardingTable[i].dest == packetDest:
                        nextHopAddr = name_To_address(self.OSPF_forwardingTable[i].nextHop);
                        self.sendSocket.sendto(recvPkt.serialize().encode(), (nextHopAddr.ip, nextHopAddr.port));

                        self.printOutputMessageHeader();
                        if packetSrc == self.name:
                            print('Sending a normal packet. [ TO:', packetDest, ', CONTENT:', recvPkt.payload,
                                  ', NEXT-HOP:', self.OSPF_forwardingTable[i].nextHop, ']');
                        else:
                            print('Forwarding a normal packet. [', 'FROM:', packetSrc, ', TO:', packetDest,
                                  ', NEXT-HOP:', self.OSPF_forwardingTable[i].nextHop, ']');

            # RIP
            elif self.RIP_routingTable:
                for i in range(len(self.RIP_routingTable)):

                    if self.RIP_routingTable[i].dest == packetDest:
                        nextHopAddr = name_To_address(self.RIP_routingTable[i].nextHop);
                        self.sendSocket.sendto(recvPkt.serialize().encode(), (nextHopAddr.ip, nextHopAddr.port));

                        self.printOutputMessageHeader();
                        if packetSrc == self.name:
                            print('Sending a normal packet. [ TO:', packetDest, ', CONTENT:', recvPkt.payload,
                                  ', NEXT-HOP:', self.RIP_routingTable[i].nextHop, ']');
                        else:
                            print('Forwarding a normal packet. [', 'FROM:', packetSrc, ', TO:', packetDest,
                                  ', NEXT-HOP:', self.RIP_routingTable[i].nextHop, ']');


import cv2
from os import listdir
from os.path import isfile, join
import numpy as np
import glob
import math

if __name__ == '__main__':
    mypath = 'results/vein_all_cont'

    onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
    onlyfiles.sort()

    # Strips the newline character
    angle = 0
    outpath = 'results/'
    model = outpath + '1_outer_mask'
    img_list = glob.glob(model + '/*.png')
    img_list.sort()

    image_first = cv2.imread(img_list[0], cv2.IMREAD_GRAYSCALE)
    image_last = cv2.imread(img_list[-1], cv2.IMREAD_GRAYSCALE)

    white_points = np.where(image_first == 255)

    points = []
    for i in range(len(white_points[0])):
        points.append((white_points[1][i], white_points[0][i]))

    [x1, y1, w1, h1] = cv2.boundingRect(np.int32(points))

    white_points = np.where(image_last == 255)

    points = []
    for i in range(len(white_points[0])):
        points.append((white_points[1][i], white_points[0][i]))

    [x2, y2, w2, h2] = cv2.boundingRect(np.int32(points))
    z2 = int(img_list[-1][-9:-5])-1554
    letter = img_list[-1][-5]
    if letter == 'b':
        z2 = z2 + 0.33
    elif letter == 'c':
        z2 = z2 + 0.66

    center_first = np.int32((x1+w1/2, y1+h1/2))
    center_last = np.int32((x2+w2/2, y2+h2/2))

    angle_x = math.atan((center_first[0] - center_last[0]) / z2)
    angle_y = math.atan((center_first[1] - center_last[1]) / z2)

    for filename in onlyfiles:
        name = filename[3:7]
        letter = filename[7]

        level = int(name)-1554
        if letter == 'b':
            level = level + 0.33
        elif letter == 'c':
            level = level + 0.66

        image = cv2.imread(mypath + '/' + filename, cv2.IMREAD_GRAYSCALE)

        mask = np.zeros([600, 390])
        cnts = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if len(cnts) == 2 else cnts[1]
        for c in cnts:
            cv2.drawContours(mask, [c], -1, 255, 1)

        white_points = np.where(mask == 255)

        points = []
        for i in range(len(white_points[0])):
            points.append((white_points[1][i], white_points[0][i]))

        x_corr = math.tan(angle_x) * level
        y_corr = math.tan(angle_y) * level

        z_image = math.sqrt(x_corr*x_corr + y_corr*y_corr)

        layer = math.sqrt(z_image*z_image + level*level)

        points_whole_arm = []
        for point in points:
            points_whole_arm.append(
                [np.float(point[0]) + x_corr, np.float(point[1]) + y_corr])

        file1 = open(outpath + 'modelV2/test2.txt', 'a')

        for point in range(0, len(points_whole_arm)):
            str1 = str((points_whole_arm[point][0]) * 0.33) + ';' + str((points_whole_arm[point][1]) * 0.33) \
                + ';' + str(layer) + '\n'
            file1.write(str1)
        file1.write("\n")
        file1.close()


"""Open ports in your router for Home Assistant and provide statistics."""
import asyncio
from ipaddress import ip_address
from operator import itemgetter

import voluptuous as vol

from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv, device_registry as dr
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
from homeassistant.util import get_local_ip

from .const import (
    CONF_LOCAL_IP,
    CONFIG_ENTRY_ST,
    CONFIG_ENTRY_UDN,
    DISCOVERY_LOCATION,
    DISCOVERY_ST,
    DISCOVERY_UDN,
    DISCOVERY_USN,
    DOMAIN,
    DOMAIN_CONFIG,
    DOMAIN_COORDINATORS,
    DOMAIN_DEVICES,
    DOMAIN_LOCAL_IP,
    LOGGER as _LOGGER,
)
from .device import Device

NOTIFICATION_ID = "upnp_notification"
NOTIFICATION_TITLE = "UPnP/IGD Setup"

CONFIG_SCHEMA = vol.Schema(
    {DOMAIN: vol.Schema({vol.Optional(CONF_LOCAL_IP): vol.All(ip_address, cv.string)})},
    extra=vol.ALLOW_EXTRA,
)

async def async_discover_and_construct(
    hass: HomeAssistantType, udn: str = None, st: str = None
) -> Device:
    """Discovery devices and construct a Device for one."""
    # pylint: disable=invalid-name
    discovery_infos = await Device.async_discover(hass)
    _LOGGER.debug("Discovered devices: %s", discovery_infos)
    if not discovery_infos:
        _LOGGER.info("No UPnP/IGD devices discovered")
        return None

    if udn:
        # Get the discovery info with specified UDN/ST.
        filtered = [di for di in discovery_infos if di[DISCOVERY_UDN] == udn]
        if st:
            filtered = [di for di in discovery_infos if di[DISCOVERY_ST] == st]
        if not filtered:
            _LOGGER.warning(
                'Wanted UPnP/IGD device with UDN "%s" not found, aborting', udn
            )
            return None

        # Ensure we're always taking the latest, if we filtered only on UDN.
        filtered = sorted(filtered, key=itemgetter(DISCOVERY_ST), reverse=True)
        discovery_info = filtered[0]
    else:
        # Get the first/any.
        discovery_info = discovery_infos[0]
        if len(discovery_infos) > 1:
            device_name = discovery_info.get(
                DISCOVERY_USN, discovery_info.get(DISCOVERY_LOCATION, "")
            )
            _LOGGER.info("Detected multiple UPnP/IGD devices, using: %s", device_name)

    location = discovery_info[DISCOVERY_LOCATION]
    return await Device.async_create_device(hass, location)

async def async_setup(hass: HomeAssistantType, config: ConfigType):
    """Set up UPnP component."""
    _LOGGER.debug("async_setup, config: %s", config)
    conf_default = CONFIG_SCHEMA({DOMAIN: {}})[DOMAIN]
    conf = config.get(DOMAIN, conf_default)
    local_ip = await hass.async_add_executor_job(get_local_ip)
    hass.data[DOMAIN] = {
        DOMAIN_CONFIG: conf,
        DOMAIN_COORDINATORS: {},
        DOMAIN_DEVICES: {},
        DOMAIN_LOCAL_IP: conf.get(CONF_LOCAL_IP, local_ip),
    }

    # Only start if set up via configuration.yaml.
    if DOMAIN in config:
        hass.async_create_task(
            hass.config_entries.flow.async_init(
                DOMAIN, context={"source": config_entries.SOURCE_IMPORT}
            )
        )

    return True

async def async_setup_entry(hass: HomeAssistantType, config_entry: ConfigEntry) -> bool:
    """Set up UPnP/IGD device from a config entry."""
    _LOGGER.debug("async_setup_entry, config_entry: %s", config_entry.data)

    # discover and construct
    udn = config_entry.data.get(CONFIG_ENTRY_UDN)
    st = config_entry.data.get(CONFIG_ENTRY_ST)  # pylint: disable=invalid-name
    try:
        device = await async_discover_and_construct(hass, udn, st)
    except asyncio.TimeoutError as err:
        raise ConfigEntryNotReady from err

    if not device:
        _LOGGER.info("Unable to create UPnP/IGD, aborting")
        raise ConfigEntryNotReady

    # Save device
    hass.data[DOMAIN][DOMAIN_DEVICES][device.udn] = device

    # Ensure entry has proper unique_id.
    if config_entry.unique_id != device.unique_id:
        hass.config_entries.async_update_entry(
            entry=config_entry,
            unique_id=device.unique_id,
        )

    # Create device registry entry.
    device_registry = await dr.async_get_registry(hass)
    device_registry.async_get_or_create(
        config_entry_id=config_entry.entry_id,
        connections={(dr.CONNECTION_UPNP, device.udn)},
        identifiers={(DOMAIN, device.udn)},
        name=device.name,
        manufacturer=device.manufacturer,
        model=device.model_name,
    )

    # Create sensors.
    _LOGGER.debug("Enabling sensors")
    hass.async_create_task(
        hass.config_entries.async_forward_entry_setup(config_entry, "sensor")
    )

    return True

async def async_unload_entry(
    hass: HomeAssistantType, config_entry: ConfigEntry
) -> bool:
    """Unload a UPnP/IGD device from a config entry."""
    udn = config_entry.data.get(CONFIG_ENTRY_UDN)
    if udn in hass.data[DOMAIN][DOMAIN_DEVICES]:
        del hass.data[DOMAIN][DOMAIN_DEVICES][udn]
    if udn in hass.data[DOMAIN][DOMAIN_COORDINATORS]:
        del hass.data[DOMAIN][DOMAIN_COORDINATORS][udn]

    _LOGGER.debug("Deleting sensors")
    return await hass.config_entries.async_forward_entry_unload(config_entry, "sensor")


from pyspark.conf import SparkConf
from pyspark.sql import SparkSession

my_jars = os.environ.get("SPARK_HOME")
myconf = SparkConf()
myconf.setMaster("local").setAppName("DB2_Test")
myconf.set("spark.jars","%s/jars/log4j-1.2.17.jar" % my_jars)
spark = SparkSession\
 .builder\
 .appName("DB2_Test")\
 .config(conf = myconf) \
 .getOrCreate()

Logger= spark._jvm.org.apache.log4j.Logger
mylogger = Logger.getLogger(__name__)
mylogger.error("some error trace")
mylogger.info("some info trace")


from tqdm import tqdm
import argparse
import math
import model
import cv2
import sys
import pandas as pd
sys.setrecursionlimit(15000)
import os
import torch
import numpy as np
from torch.autograd import Variable
from sklearn import metrics
from PIL import Image
import numpy as np
import torch.utils.data
import torchvision.transforms as transforms
from statistics import mean

parser = argparse.ArgumentParser()
parser.add_argument('--dataset', default ='dataset')
parser.add_argument('--test_set', default ='dataset/validation')
parser.add_argument('--real', default ='validation/real')
parser.add_argument('--fake', default ='validation/fake')
parser.add_argument('--batchSize', type=int, default=10)
parser.add_argument('--imageSize', type=int, default=128)
parser.add_argument('--gpu_id', type=int, default=0)
parser.add_argument('--outf', default='checkpoints/deepfakes')
parser.add_argument('--random_sample', type=int, default=0)
parser.add_argument('--random', action='store_true', default=False)
parser.add_argument('--id',type=int,default=100)
parser.add_argument('--input_dim', type=int, default=3, help='input dimension of lstm')
parser.add_argument('--hidden_dim', type=int, default=256, help='hidden dimension of lstm')
parser.add_argument('--layer_dim', type=int, default=1, help='layer dimension of lstm')
parser.add_argument('--output_dim', type=int, default=2, help='output dimension of lstm')
opt = parser.parse_args()
print(opt)

img_ext_lst = ('jpg', 'jpeg', 'bmp', 'png', 'ppm', 'gif', 'tiff')
vid_ext_lst = ('avi', 'mkv', 'mpeg', 'mpg', 'mp4')

def get_file_list(path, ext_lst):
    file_lst = []

    for f in os.listdir(path):
        if os.path.isfile(os.path.join(path, f)):
            if f.lower().endswith(ext_lst):
                file_lst.append(f)

    return file_lst

def extract_file_name_without_count(in_str, sep_char='@'):
    n = len(in_str)
    pos = 0
    for i in range(n):
        if in_str[i] == sep_char:
            pos = i

    return in_str[0:pos]

def process_file_list(file_lst, sep_char='@'):
    result_lst = []

    for i in range(len(file_lst)):
        #remove extension
        filename = os.path.splitext(file_lst[i])[0]

        filename = extract_file_name_without_count(filename, sep_char)
        result_lst.append(filename)

    return result_lst

def classify_batch(vgg_ext, model, batch):
    n_sub_imgs = len(batch)

    batchSize =n_sub_imgs
    batch = torch.stack(batch)
    t,s,c,h,w=batch.shape
    batch = batch.view(t * s, c, h, w)

    img_tmp=batch

    if opt.gpu_id >= 0:
        img_tmp = img_tmp.cuda(opt.gpu_id)

    input_v = Variable(img_tmp, requires_grad = False)
    # print(input_v.shape)
    x = vgg_ext(input_v)
    # print(x.shape,"shape &&&&&&&&&&&&&")
    class_ = model(x)
    output_p = []
    for t in class_:
        if t[0]>t[1]:
            output_p.append(0)
        else:
            output_p.append(1)

    # output_pred = np.concatenate((output_pred, output_p))
    return output_p

transform_fwd = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
    ])

def classify_frames(vgg_ext, model, path, label):
    file_lst = get_file_list(path, img_ext_lst)
    file_lst.sort()
    length = len(file_lst)
    frames =[]
    if (length == 0):
        return
    elif (length == 1):
        print('Error: Only one file!')
        return

    correct = 0
    count_vid = 0
    file_edited = process_file_list(file_lst)
    vid_name = file_edited[0]
    test_img = transform_fwd(Image.open(os.path.join(path, file_lst[0])))
    # print(type(test
    frames.append(test_img.unsqueeze(0))

    for i in range(1, length):
        if file_edited[i] == vid_name:
            test_img = transform_fwd(Image.open(os.path.join(path, file_lst[i])))
            frames.append(test_img.unsqueeze(0))
        else:
            # clasify the previous frames
            if(len(frames)==10):
                m=classify_batch(vgg_ext, model, frames)
                # print(m)
                o=0
                if(mean(m)>0.5):
                    o=1
                else:
                    o=0
                if o == label:
                    correct = correct + 1
                count_vid = count_vid + 1

            # get new items
            del frames
            frames =[]
            vid_name = file_edited[i]

            #print(vid_name)
            test_img = transform_fwd(Image.open(os.path.join(path, file_lst[i])))
            frames.append(test_img.unsqueeze(0))

    #classify the last frames
    # cls = classify_batch(vgg_ext, model, frames)
    # if cls == label:
    #     correct = correct + 1
    if(len(frames)==10):
        m=classify_batch(vgg_ext, model, frames)
        o=0
        if(mean(m)>0.5):
            o=1
        else:
            o=0
        if o == label:
            correct = correct + 1
        count_vid = count_vid + 1
        # print(path)
        # print('Number of files: %d' %(length))
        # print('Number of videos: %d' %(count_vid))
        # print('Number of correct classifications: %d' %(correct))

    return count_vid, correct

if __name__ == '__main__':
    path_real = os.path.join(opt.dataset, opt.real)
    path_fake = os.path.join(opt.dataset, opt.fake)

    # print(os.listdir(path_real))
    vgg_ext = model.VggExtractor()
    acc=[]
    for i in range(76,100):
        lstm = model.LSTM_Model(opt.gpu_id,opt.input_dim, opt.hidden_dim, opt.layer_dim, opt.output_dim)
        lstm.load_state_dict(torch.load(os.path.join(opt.outf,'lstm_' + str(i+1) + '.pt')))
        lstm.eval()

        if opt.gpu_id >= 0:
            vgg_ext.cuda(opt.gpu_id)
            lstm.cuda(opt.gpu_id)

        ###################################################################
        tol_count_vid = 0
        tol_correct = 0

        # real data
        count_vid, correct = classify_frames(vgg_ext, lstm, path_real, 1)
        tol_count_vid = tol_count_vid + count_vid
        tol_correct = tol_correct + correct

        # fake data
        count_vid, correct = classify_frames(vgg_ext, lstm, path_fake, 0)
        tol_count_vid = tol_count_vid + count_vid
        tol_correct = tol_correct + correct

    # print('##################################')
    # print('Number of videos: %d' %(tol_count_vid))
    # print('Number of correct classifications: %d' %(tol_correct))
    # print('Accuracy: %.2f' %(tol_correct/tol_count_vid*100))
        print('epoch : ',i,' , val acc %.2f' %(tol_correct/tol_count_vid*100))
        acc.append((tol_correct/tol_count_vid*100))
    accuracy={'validation Acc.' :acc }
    df = pd.DataFrame(accuracy)
    df.to_csv('val.csv')


#!/usr/bin/env python3

from aiohttp import web
import traceback
import logging

from pony.orm import Database, Set, Required, db_session, Json, composite_key
from pony.orm.core import MappingError
from validate_email import validate_email

log = logging.getLogger("server")

db = Database()
db.bind('sqlite', ':memory:')
max_name_len = 255

class Error(Exception):
    """ Some module-specific exception as recommended by best practices. """

def my_dict(e):
    """ My super-duper recursive serializer.
        Like pony.orm.serialization.to_dict,
        but dereferences collections into dict/list instead of ids """
    if isinstance(e, db.Entity):
        return e.to_dict()
    if isinstance(e, list):
        return [my_dict(e) for e in e]
    elif isinstance(e, dict):
        return {k: my_dict(v) for k, v in e.items()}
    return e

def validate_emails(emails):
    """ Performs very basic email verification, as many best-practices suggest.
        It could also verify existence of domain name via DNS, but that would
        be overkill for this task, imho.
    """
    if not isinstance(emails, list):
        return False
    if len(emails) < 1:   # as specified in the task
        return False
    if len(emails) > 10:  # suspiciously too many emails
        return False
    return all(validate_email(e) for e in emails)

class Person(db.Entity):
    """ Defines person's representation in the DB.
        The tuple (first name, last name) must be unique (ensured by composite_key)
    """

    fname = Required(str, max_name_len)
    lname = Required(str, max_name_len)
    composite_key(fname, lname)  # unique constraint on first and last names
    emails = Required(Json, py_check=validate_emails)
    groups = Set("Group")
    address_books = Set("AddressBook")

class Group(db.Entity):
    name = Required(str, max_name_len, unique=True)
    members = Set(Person)
    address_books = Set("AddressBook")

class AddressBook(db.Entity):
    name = Required(str, max_name_len, unique=True)
    people = Set(Person)
    groups = Set(Group)

def args_from_uri(f):
    """ Extracts arguments from URI according to URI pattern.
        Like for a path "/plans/678/" and pattern "/plans/{id}/"
        it would extract id=678 and pass it as an argument.
    """
    async def match(self, request):
        args = request.match_info
        return await f(self, request, **args)
    return match

class OhMyRestRouter:
    """ Simple REST router for models like rest_framework.serializers.ModelSerializer. """

    def __init__(self, app, model, name=None):
        self.app = app
        self.model = model
        if name is None:
            name = model.__name__.lower()
        prefix = "/{name}".format(name=name)
        uri_name = lambda method: "{name}_{method}".format(
            name=name, method=method)
        app.router.add_route(
            'GET', prefix + r"/{id:\d+}", self.get, name=uri_name('get'))
        app.router.add_route(
            'PUT',
            prefix +
            r"/{id:\d+}/addto/{field:[a-z]+}",
            self.add,
            name=uri_name('add'))
        app.router.add_route('PUT', prefix, self.put, name=uri_name('put'))
        app.router.add_route('DELETE', prefix +
                             r"/{id:\d+}", self.delete, name=uri_name('del'))

    @args_from_uri
    async def get(self, request, id):
        id = int(id)
        with db_session:
            instance = self.model[id]
            instance_data = instance.to_dict(with_collections=True)
            result = my_dict(instance_data)
        return web.json_response(result)

    async def put(self, request):
        json_data = await request.json()
        log.debug("adding to the database: %s", json_data)
        with db_session:
            instance = self.model(**json_data)
            instance.flush()  # commit instance to populate id
            instance_data = instance.to_dict(with_collections=True)
        return web.json_response(instance_data)

    @args_from_uri
    async def add(self, request, id, field):
        id = int(id)
        if not hasattr(self.model, field):
            raise Error("no such field: %s" % field)
        field = getattr(self.model, field)
        assert isinstance(field, Set), "we can add only to Set() field"
        model = field.py_type  # model of item we are going to add

        json_data = await request.json()

        with db_session:
            instance = self.model[id]
            item = model[json_data['id']]
            collection = getattr(instance, field.name)  # get related field
            collection.add(item)
            data = instance.to_dict(with_collections=True)
            result = my_dict(data)
        return web.json_response(result)

    @args_from_uri
    async def delete(self, request, id):
        id = int(id)
        with db_session:
            self.model[id].delete()

async def error_middleware(app, handler):
    """ Formats backend errors into json message. """
    def json_error(message):
        return web.json_response({'error': message}, status=500)

    async def middleware_handler(request):
        try:
            response = await handler(request)
            return response
        except Exception as ex:
            tb = traceback.format_exc(limit=100)
            log.error("error while serving request:\n%s", tb)

            return json_error(str(ex))
    return middleware_handler

async def find_by_name(request):
    params = request.GET
    fname = params.get('fname')
    lname = params.get('lname')
    response = []
    assert fname or lname, "you need at least one parameter: fname, lname or both"

    with db_session:
        query = Person.select()
        if fname:
            query = query.filter(fname=fname)
        if lname:
            query = query.filter(lname=lname)

        for person in list(query):
            person = person.to_dict(with_collections=True)
            response.append(person)
    return web.json_response(response)

async def find_by_email(request):
    email = request.GET['email']
    response = []
    with db_session:
        query = Person.select(lambda p: email in p.emails)
        for person in list(query):
            person = person.to_dict(with_collections=True)
            response.append(person)
    return web.json_response(response)

def setup_app(loop=None):
    app = web.Application(middlewares=[error_middleware], loop=loop)
    OhMyRestRouter(app=app, model=Person)
    OhMyRestRouter(app=app, model=Group)
    OhMyRestRouter(app=app, model=AddressBook)
    try:

        db.generate_mapping(create_tables=True)
    # ignoring "Mapping was already generated"
    # when py.test runs setup_app second/third time to make new fixtures
    except MappingError:
        pass
    app.router.add_route('GET', r"/person/find/",
                         find_by_name, name='person-find')

    app.router.add_route('GET', r"/person/find-by-email/",
                         find_by_email, name='person-find-by-email')

    return app

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser(
        description="Welcome to the most advanced calendar backend in the World!")
    parser.add_argument('--routes', default=False,
                        action='store_true', help="show routes")
    parser.add_argument('--shell', default=False,
                        action='store_true', help="launch IPython shell")
    parser.add_argument('--no-setup', default=False,
                        action='store_true', help="do not setup routes")
    parser.add_argument('-d', '--debug', default=False,
                        action='store_true', help="debug logging")
    args = parser.parse_args()

    if not args.no_setup:
        app = setup_app()

    if args.routes:
        if args.no_setup:
            print("please remove --no-setup to see routes")
        else:
            print("===== routes ======")
            for resource in app.router.resources():
                print("  ", resource)
            print("== end of routes ==")

    if args.debug:
        logging.basicConfig(level=logging.DEBUG)

    if args.shell:
        from IPython import embed
        print("nothing really to do, spawning an interactive shell")
        with db_session:
            embed()
    else:
        web.run_app(app)


# -*- coding: utf-8 -*-
"""
@author: hrollin

BUT :  Gère l'affichage graphique conventionnel du projet MIG SE
PLAN :
    class Fenetre :
        - afficher()
            1) initialise la fenetre
            2) boucle principale
            3) ferme le prog
        - section UPDATE :
            Recupère les données
        - section FONCTION CONSOMMATION :
            Fonction pour afficher la consommation
        - section AFFICHAGE AVANCéE :
            Fonctions auxilliares de chargement
        - section PLOTTING :
            Affichage
    class MatPlotLibWidget :
        - gère les graphes en PyQt
    main():
        - point de départ

"""
import marshal
from datetime import datetime
from datetime import timedelta
import fonctions_de_recup as fdr
import os
import sys
import random
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4.QtGui import QMessageBox
import main as dem
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as Canvas
from matplotlib.figure import Figure
from matplotlib import rcParams
rcParams['font.size'] = 9

class Fenetre(QtGui.QMainWindow):
    tabDemande=[]
    tabW=[]
    tab=[]
    action=[]
    demande=0
    conso=1
    batiment=2
    confort=3
    effacement=4
    timer=[]
    echelle=1

    taux=100

    deltaTDemande=6
    deltaTConso=6
    deltaTConf=6
    deltaTEco=6
    deltaTEff=6
    cptDemande=0
    cptConso=0
    cptConf=0
    cptEco=0

    # demande
    Dprix=[]
    DgrosLayout=[]
    Dbox1=[]
    Dlay1=[]
    Dg1x=[0]#vvv AFFICHAGE
    Dg1y=[0]
    Dg2x=[0]
    Dg2y=[0]
    Dg3x=[0]
    Dg3y=[0]

    #conso
    Cdef=[]
    Cnom=[]
    CgroupeFichier=[]
    CgroupeApp=[]
    CFlayout=[]
    Cliste=[]
    Cinit=False
    CEff=[]
    CadresseUtile=""
    Ct=[]# AFFICHAGE
    CaffConsoLib=True
    CaffConsoEff=True
    CaffEff=True

    #confort
    Egraph=[]# AFFICHAGE
    EgeneMax=0.2
    Etext=[]
    Elabl=[]
    Eg1x=[]
    Eg1y=[]

    # listes conso
    diffM=[]
    diffTot=[]
    lTot=[]
    lTotNat=[]
    lM=[]
    lMNat=[]
    tpsM=[]

    # donnees
    mat=[]
    matNat=[]
    tps=[]
    temp=[]
    tpsEff=[]
    testMat=True

    def __init__(self,app):
        super(Fenetre,self).__init__()
        self.chargerMat()
        self.addConsoTotale()
        self.addConsoMachines()
        self.initDiff()
        self.afficher()

#--------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------
#                                 AFFICHAGE
#--------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------
    def afficher(self):
        self.afficherFenetre()

#--------------------------------------------------------------------------------------------------
#                                   DEMANDE
#--------------------------------------------------------------------------------------------------
        wid=QtGui.QWidget()
        self.DgrosLayout=[QtGui.QHBoxLayout()]
        # TUNES
        self.Dbox1=[QtGui.QGroupBox(u"Bénéfices clients : ")]
        self.Dprix=[QtGui.QWidget()]
        self.Dlay1=[QtGui.QVBoxLayout()]
        self.Dlay1[0].addWidget(self.Dprix[0])
        self.Dbox1[0].setLayout(self.Dlay1[0])
        self.Dprix[0].mplwidget=MatplotlibWidget(self.Dprix[0],title=u"Bénéfices du client à ce jour",xlabel=u"Temps (h)",ylabel=u"Economies (€)",hold=True, width=6,height=5)
        self.Dprix[0].mplwidget.setFocus()

        # DEMANDE
        box2=QtGui.QGroupBox(u"Marché de l'éléctricité : ")
        self.Dprix+=[QtGui.QWidget(),QtGui.QWidget()]
        lay2=QtGui.QVBoxLayout()
        lay2.addWidget(self.Dprix[1])
        lay2.addWidget(self.Dprix[2])
        box2.setLayout(lay2)
        self.Dprix[1].mplwidget=MatplotlibWidget(self.Dprix[1],title=u"Prix d'achat en gros au kWh",xlabel="Temps (h)",ylabel=u"Prix (€/kWh)",hold=True, width=6,height=2.5)
        self.Dprix[1].mplwidget.setFocus()
        self.Dprix[2].mplwidget=MatplotlibWidget(self.Dprix[2],title=u"Prix de revente au kWh",xlabel="Temps (h)",ylabel=u"Prix (€/kWh)",hold=True, width=6,height=2.5)
        self.Dprix[2].mplwidget.setFocus()
        self.plot(self.Dprix[1].mplwidget.axes)
        self.plotDemande()

        self.DgrosLayout[0].addWidget(self.Dbox1[0])
        self.DgrosLayout[0].addWidget(box2)
        wid.setLayout(self.DgrosLayout[0])
        self.tabW.append(wid)

#--------------------------------------------------------------------------------------------------
#                                        CONSO
#--------------------------------------------------------------------------------------------------
        wid2=QtGui.QWidget()
         # GROS LAYOUT
        self.CgroupeFichier=[QtGui.QGroupBox("Fichiers")]
        self.CgroupeAff=[QtGui.QGroupBox("helloworld.txt")]
        Hlayout=QtGui.QGridLayout()
        Hlayout.addWidget(self.CgroupeFichier[0])
        # necessaire ici car en SLOT de connect

        self.Ct=[QtGui.QWidget()]
        # AFFICHAGE MAT PLOT LIB
        Vform2=QtGui.QVBoxLayout()
        Vform2.addWidget(self.Ct[0])
        self.CgroupeAff[0].setLayout(Vform2)
        self.Ct[0].mplwidget=MatplotlibWidget(self.Ct[0],title="ex",xlabel="fgh",ylabel="fghj",hold=True, width=9,height=5)
        self.Ct[0].mplwidget.setFocus()
        self.plot(self.Ct[0].mplwidget.axes)

        Vform=QtGui.QVBoxLayout()
        self.CgroupeFichier[0].setLayout(Vform)

        # LISTE DE FICHIER
        self.choixEchelle=[QtGui.QComboBox()]
        self.choixEchelle[0].connect(self.choixEchelle[0],QtCore.SIGNAL("currentIndexChanged(int)"),self.changeEchelle)
        self.choixEchelle[0].addItem("1 an")
        self.choixEchelle[0].addItem("1 mois")
        self.choixEchelle[0].addItem("1 semaine")
        self.choixEchelle[0].addItem("1 jour")
        self.choixEchelle[0].setCurrentIndex(3)

        self.Cdef=[QtGui.QComboBox()]
        self.Cdef[0].connect(self.Cdef[0],QtCore.SIGNAL("currentIndexChanged(int)"),self.changeActif)
        self.chargerFichierTest()
        Vform.addWidget(self.Cdef[0])

        Vform.addWidget(QtGui.QLabel(u"\nOptions : \n"))
        Vform.addWidget(self.choixEchelle[0])

        # GESTIONNAIRE D'OPTIONS
        self.CEff+=[QtGui.QCheckBox(u"Consommation effacée")]
        self.CEff[0].setChecked(True)
        self.CEff[0].connect(self.CEff[0],QtCore.SIGNAL("stateChanged()"),self.changeConsoEff)
        Vform.addWidget(self.CEff[0])
        self.CEff+=[QtGui.QCheckBox("Consommation libre")]
        self.CEff[1].setChecked(True)
        self.CEff[1].connect(self.CEff[1],QtCore.SIGNAL("stateChanged()"),self.changeConsoLib)
        Vform.addWidget(self.CEff[1])
        self.CEff+=[QtGui.QCheckBox("Effacement")]
        self.CEff[2].setChecked(True)
        self.CEff[2].connect(self.CEff[2],QtCore.SIGNAL("stateChanged()"),self.changeEff)
        Vform.addWidget(self.CEff[2])
        Vform.addWidget(QtGui.QLabel(""))

        # GESTIONNAIRE DE FICHIER
        boutAjouter=QtGui.QPushButton("Ajouter un fichier")
        boutVider=QtGui.QPushButton("Tout supprimer")
        boutRestaurer=QtGui.QPushButton("Restaurer par defaut")
        boutAjouter.setIcon(QtGui.QIcon("img/bajouterfichier2.png"))
        boutVider.setIcon(QtGui.QIcon("img/bviderfichier2.png"))
        boutRestaurer.setIcon(QtGui.QIcon("img/brestaurerfichier2.png"))
        Vform.addWidget(boutAjouter)
        Vform.addWidget(boutVider)
        Vform.addWidget(boutRestaurer)
        #boutAjouter.connect(boutAjouter,QtCore.SIGNAL("clicked()"),self.adresse)
        #boutVider.connect(boutVider,QtCore.SIGNAL("clicked()"),self.vider)
        #boutRestaurer.connect(boutRestaurer,QtCore.SIGNAL("clicked()"),self.chargerFichierTest)

        Vform.addStretch(1)
        Hlayout.addWidget(self.CgroupeFichier[0],0,0)
        Hlayout.addWidget(self.CgroupeAff[0],0,1,0,3)
        wid2.setLayout(Hlayout)
        self.tabW.append(wid2)
#---------------------------------------------------------------------------------------------------------
#                                       CONFORT
#---------------------------------------------------------------------------------------------------------

        wid3=QtGui.QWidget()
        grosLayout=QtGui.QHBoxLayout()

        # INFORMATION DE CRITERE DE GèNE:
        self.Etext=[QtGui.QDoubleSpinBox()]
        box1=QtGui.QGroupBox(u"Critère de gène : ")
        lay1=QtGui.QVBoxLayout()
        box1.setLayout(lay1)
        box1.setMaximumSize(400,800)
        lay1.addWidget(QtGui.QLabel(""))
        self.Elabl=[QtGui.QLabel((u"< "+str(self.Etext[0].value())))]
        lay1.addWidget(QtGui.QLabel(u"Le critère de gène courrant est : "))
        lay1.addWidget(self.Elabl[0])
        lay1.addWidget(QtGui.QLabel(u"\n\n\nChanger le critère de gène : "))
        self.Etext[0].setAccelerated(True)
        self.Etext[0].setMinimum(0)
        self.Etext[0].setMaximum(1)
        self.Etext[0].setSingleStep(0.01)
        self.Etext[0].setValue(0.2)
        self.updateGene()
        self.Etext[0].connect(self.Etext[0],QtCore.SIGNAL("valueChanged(double)"),self.updateGene)
        lay1.addWidget(self.Etext[0])
        lay1.addStretch(1)

        # GENE = f(T)
        box2=QtGui.QGroupBox(u"Evolution temporelle")
        lay2=QtGui.QVBoxLayout()
        box2.setLayout(lay2)
        self.Egraph=[QtGui.QWidget()]
        self.Egraph[0].mplwidget=MatplotlibWidget(self.Egraph[0],title=u"Evolution du facteur de gène en fonction du temps",xlabel="temps (h)",ylabel=u"Facteur de gène",hold=True, width=9,height=5)
        self.Egraph[0].mplwidget.setFocus()
        self.Egraph[0].setMinimumWidth(700)
        self.plot(self.Egraph[0].mplwidget.axes)
        lay2.addWidget(self.Egraph[0])

        grosLayout.addWidget(box1)
        grosLayout.addWidget(box2)
        wid3.setLayout(grosLayout)

#---------------------------------------------------------------------------------------------------------
#                                       CREATION ONGLETS
#---------------------------------------------------------------------------------------------------------
        self.tabW.append(QtGui.QWidget())
        self.tabW.append(wid3)

        self.tab=[QtGui.QTabWidget()]
        self.tab[0].setTabIcon(1, QtGui.QIcon("img/bconso.png"))
        self.tab[0].addTab(self.tabW[self.demande],u"Demande et Bénéfices")
        self.tab[0].addTab(self.tabW[self.conso],"Consommation")
        #self.tab[0].addTab(self.tabW[self.batiment],u"Bâtiment")
        self.tab[0].addTab(self.tabW[self.confort],u"Confort")
        self.setCentralWidget(self.tab[0])

        self.creerAction()
        self.afficherMenu()

#---------------------------------------------------------------------------------------------------------
#                                              TIMER
#---------------------------------------------------------------------------------------------------------

        self.timer.append(QtCore.QTimer())
        self.timer[0].connect(self.timer[0],QtCore.SIGNAL("timeout()"),self.updateD)
        self.timer[0].start(self.deltaTDemande*self.taux)

        self.timer.append(QtCore.QTimer())
        self.timer[1].connect(self.timer[1],QtCore.SIGNAL("timeout()"),self.updateConso)
        self.timer[1].start(self.deltaTConso*self.taux)

        self.timer.append(QtCore.QTimer())
        self.timer[2].connect(self.timer[2],QtCore.SIGNAL("timeout()"),self.updateConf)
        self.timer[2].start(self.deltaTConf*self.taux)

        self.timer.append(QtCore.QTimer())
        self.timer[3].connect(self.timer[3],QtCore.SIGNAL("timeout()"),self.updateEco)
        self.timer[3].start(self.deltaTEco*self.taux)

        self.timer.append(QtCore.QTimer())
        self.timer[4].connect(self.timer[4],QtCore.SIGNAL("timeout()"),self.updateEff)
        self.timer[4].start(self.deltaTEff*self.taux)

        self.show()
        # FIN DE LA FONCTION PRINCIPALE
#------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------
#                                           ACTUALISATION
#------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------

    def updateEff(self):
        pass

    def updateD(self):
        if self.cptDemande<len(self.tps) :
            p=dem.get_marche(self.cptDemande,dem.opfile_prix_avr)
            self.ajDemande(p[0],p[1])
            self.ajPrix(p[0],self.prixPart(p[0]))
            self.cptDemande+=1
            self.show()

    def updateConso(self):
        if self.cptConso<len(self.tps):
            self.plotC()
            self.cptConso+=1

    def updateConf(self):
        p1=self.cptConf
        p2=random.randint(1,20)
        self.ajGene(p1,p2)
        self.cptConf+=1

    def updateEco(self):
        p=dem.calculGain(self.cptEco,3)
        self.ajBenef(self.cptEco,p)
        self.cptEco+=1

    # DEMANDE ET BENEF
    def ajBenef(self,x,y):
        self.Dg1x+=[x]
        self.Dg1y+=[y+self.Dg1y[-1]]
        self.plotBenef()

    def ajDemande(self,x,y):
        self.Dg2x+=[x]
        self.Dg2y+=[y]
        self.plotDemande()

    def ajPrix(self,x,y):
        self.Dg3x+=[x]
        self.Dg3y+=[y]
        self.plotPrix()

    # GENE
    def ajGene(self,x,y):
        self.Eg1x+=[x]
        self.Eg1y+=[y]
        self.plotGene()

    def updateGene(self):
        self.Elabl[0].setText(u"< "+str(self.Etext[0].value()))

#------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------
#                                           FONCTIONS CONSOMMATION
#------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------

    def changeEchelle(self):
        self.echelle=self.choixEchelle[0].currentIndex()+1
        self.plotC()

    def changeActif(self):
        self.CgroupeAff[0].setTitle(self.Cdef[0].currentText())
        self.plotC()

    def changeConsoLib(self):
        self.CaffConsoLib=self.CEff[1].isChecked()
        self.plotC()

    def changeConsoEff(self):
        self.CaffConsoLib=self.CEff[0].isChecked()
        self.plotC()

    def changeEff(self):
        self.CaffConsoLib=self.CEff[2].isChecked()
        self.plotC()

    def prixPart(self,h):
        if(h%24<7 and h%24>2):
            return 0.1114
        return 0.16

    def vider(self):
        f=QMessageBox.warning(self,"Suppression des fichiers","Voulez-vous vraiment supprimer tous les fichiers de la liste?", QMessageBox.Yes | QMessageBox.No)
        if(f==QMessageBox.Yes):
            self.resetFichier()

    def changer(self):
        for i in range(len(self.Cradio)):
            if(self.Cradio[i].isChecked()):
                self.CgroupeAff[0].setTitle(self.Cnom[i])
                self.Ct[0].mplwidget.axes.set_title(self.Cnom[i])
                self.CadresseUtile=self.Cnom[i]
                # A RAJOUTER PLOTTAGE AUTO
                return

    def chargerFichierTest(self):
        taille=len(self.mat[0][0])
        for i in range(taille):
            stR=self.mat[0][0][i][0]
            self.Cdef[0].addItem(self.endString(stR))
        self.Cdef[0].addItem("Total")

    def informer(self):
        QMessageBox.information(self,self.trUtf8("A propos"),self.trUtf8("\t\tA PROPOS\n\nProgramme realisé par les élèves de MIG SE de l'école des Mines de Paris\navec : \n\t- Anaconda\n\t- PyQt4\n\nMarc BRUN, Yoënn BURBAN, Hugo CISNEROS, Pierre-Etienne DEVINEAU, Rudy GOURY, Raphael HECHT, Aymeric JACQUIN, Quentin PETIT, Pierre POPINEAU, Hugo ROLLIN, Ulysse THUILLIER\net les membres du CMA de Sophia Antipolis"))

    def chargement(self,nom):
        f=QMessageBox.information(self,"Patientez","Chargement du fichier : "+nom+"...\n\n(Cela peut prendre quelque temps)")

    def endString(self, stri):
        return stri.split("/")[-1]

    def adresse(self):
        f=QtGui.QFileDialog.getOpenFileName(self,"Ouvrir un fichier")
        if(f!=""):
            self.chargerFichier(f)

#------------------------------------------------------------------------------------------------------------
#                                           FONCTIONS ACQUISITION
#------------------------------------------------------------------------------------------------------------

    def play(self):
        self.taux=100
        self.updateTimer()

    def fwd(self):
        if(self.taux>=10):
            self.taux/=10
            self.updateTimer()

    def stop(self):
        self.timer[0].stop()
        self.timer[1].stop()
        self.timer[2].stop()
        self.timer[3].stop()

    def updateTimer(self):
        self.timer[0].connect(self.timer[0],QtCore.SIGNAL("timeout()"),self.updateD)
        self.timer[0].start(self.deltaTDemande*self.taux)
        self.timer[1].connect(self.timer[1],QtCore.SIGNAL("timeout()"),self.updateConso)
        self.timer[1].start(self.deltaTConso*self.taux)
        self.timer[2].connect(self.timer[2],QtCore.SIGNAL("timeout()"),self.updateConf)
        self.timer[2].start(self.deltaTConf*self.taux)
        self.timer[3].connect(self.timer[3],QtCore.SIGNAL("timeout()"),self.updateEco)
        self.timer[3].start(self.deltaTEco*self.taux)

#------------------------------------------------------------------------------------------------------------
#                                           FONCTIONS ACQUISITION
#------------------------------------------------------------------------------------------------------------
# A : temps
# B : etat inter
# C : machine
# D : param : nom etat puissance gene

    def chargerMat(self):
        if(self.testMat==True):

            self.tps=[timedelta(seconds=3600*i)+datetime(2014,1,1) for i in range(600)]
            for i in range(300):
                self.mat.append([[["Frigo",0.5,100,1],["Chaudiere",0.7,300,0.6]],[["Frigo",0.6,110,1],["Chaudiere",0.6,270,0.7]]])
                self.mat.append([[["Frigo",0.6,120,1],["Chaudiere",0.5,390,0.7]],[["Frigo",0.2,20,0.9],["Chaudiere",0.8,300,0.8]]])
                self.tpsEff+=[1,1]
                self.temp+=[18,19]
            self.matNat=self.mat
        else:
            pass

    def addConsoTotale(self):
        for k in range (len(self.tps)):
            c=0
            cNat=0
            if self.tpsEff[k]==0:
                pass
            elif self.tpsEff[k]==1:
                for i in self.mat[0][0]:
                    c+=fdr.recupPuissanceFinale(self.mat[k],i[0])
                    cNat+=fdr.recupPuissanceFinale(self.matNat[k],i[0])
            self.lTot.append(c)
            self.lTotNat.append(cNat)

    compteur=0
    def addConsoMachines(self):
        for i in self.mat[0][0]:
            self.lM.append([])
            self.diffM.append([])
            self.lMNat.append([])
        for k in range (len(self.tps)):
            if(self.tpsEff[k]==1):
                for i in range(len(self.mat[0][0])):
                    self.lM[i].append(fdr.recupPuissanceFinale(self.mat[self.compteur],self.mat[0][0][i][0]))
                self.compteur+=1
            else:
                for i in range(len(self.mat[0][0])):
                    self.lM[i].append(fdr.recupPuissanceFinale(self.mat[k],self.matNat[0][0][i][0]))
            for i in range(len(self.mat[0][0])):
                self.lMNat[i].append(fdr.recupPuissanceFinale(self.matNat[k],self.matNat[0][0][i][0]))

    def initDiff(self):
        for i in range(len(self.tps)):
            self.diffTot.append(self.lTotNat[i]-self.lTot[i]+4)
            for k in range(len(self.lM)):
                self.diffM[k].append(self.lMNat[k][i]-self.lM[k][i]+4)

#------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------
#                                           COMMUNICATION AVEC MODULE
#------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------

    def openMai(self):
        os.system("python batimentAffichage.py")

#------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------
#                                           FONCTIONS D'AFFICHAGES AVANCéES
#------------------------------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------------------------------

    def creerAction(self):
        quitter = QtGui.QAction(QtGui.QIcon('img/bajouterfichier2.png"'), '&Quitter', self)
        quitter.setShortcut('Ctrl+Q')
        quitter.setStatusTip(u'Quitter l\'application')
        quitter.triggered.connect(QtGui.qApp.quit)
        self.action.append(quitter)

        aPropos=QtGui.QAction(QtGui.QIcon("img/bajouterfichier2.png"),"&A propos",self)
        aPropos.setShortcut("Ctrl+P")
        aPropos.setStatusTip("A propos du projet")
        aPropos.triggered.connect(self.informer)
        self.action.append(aPropos)

        ajouterFichier=QtGui.QAction(QtGui.QIcon("img/bajouterfichier2.png"),"&Ajouter un fichier de consommation",self)
        ajouterFichier.setShortcut("Ctrl+A")
        ajouterFichier.setStatusTip(u"Ajouter un fichier de données de consommation")
        #ajouterFichier.triggered.connect(self.adresse)
        self.action.append(ajouterFichier)

        viderfichier=QtGui.QAction(QtGui.QIcon("img/bviderfichier2.png"),u"&Supprimer tous les fichiers de consommation",self)
        viderfichier.setShortcut("Ctrl+S")
        viderfichier.setStatusTip(u"Supprimer tous les fichiers de données de consommation")
        #viderfichier.triggered.connect(self.vider)
        self.action.append(viderfichier)

        restfichier=QtGui.QAction(QtGui.QIcon("img/brestaurerfichier2.png"),u"&Restaure les fichiers de consommation par défaut",self)
        restfichier.setShortcut("Ctrl+R")
        restfichier.setStatusTip(u"Restaure les fichiers de consommation par défaut")
        #restfichier.triggered.connect(self.chargerFichierTest)
        self.action.append(restfichier)

        play=QtGui.QAction(QtGui.QIcon("img/play.svg"),u"&Acquisition en temps réel",self)
        play.setShortcut("Space")
        play.setStatusTip(u"Vitesse lente")
        play.triggered.connect(self.play)
        self.action.append(play)

        fwd=QtGui.QAction(QtGui.QIcon("img/fwd.svg"),u"&Acquisition en temps accéléré",self)
        fwd.setShortcut("Ctrl+Space")
        fwd.setStatusTip(u"Vitesse rapide")
        fwd.triggered.connect(self.fwd)
        self.action.append(fwd)

        stp=QtGui.QAction(QtGui.QIcon("img/stop.svg"),u"Met en pause l'acquisition",self)
        stp.setShortcut("Alt+Space")
        stp.setStatusTip(u"Pause")
        stp.triggered.connect(self.stop)
        self.action.append(stp)

        mai=QtGui.QAction(QtGui.QIcon("img/maison.svg"),u"Ouvre le menu intelligent",self)
        mai.setShortcut("Ctrl+E")
        mai.setStatusTip(u"Lance le menu intelligent")
        mai.triggered.connect(self.openMai)
        self.action.append(mai)

        reset=QtGui.QAction(QtGui.QIcon("img/reset.svg"),u"Recharge la simulation",self)
        reset.setShortcut("Ctrl+0")
        reset.setStatusTip(u"Recharge la simulation")
        reset.triggered.connect(self.resetSim)
        self.action.append(reset)

    def resetSim(self):
        self.cptDemande=0
        self.cptEco=0
        self.cptConso=0
        self.cptConf=0
        self.compteur=0
        self.play()

    def afficherFenetre(self):
        self.setGeometry(250,100,1280,800)
        self.setWindowTitle(u"Géstionnaire d'énergie")
        self.setWindowIcon(QtGui.QIcon("img/logo256.png"))
        self.statusBar().showMessage("Pret!")

    def afficherMenu(self):
        barre=self.addToolBar("barre")
        barre.addAction(self.action[2])
        barre.addAction(self.action[3])
        barre.addAction(self.action[4])
        barre.addAction(self.action[7])
        barre.addAction(self.action[5])
        barre.addAction(self.action[6])
        barre.addAction(self.action[9])
        barre.addAction(self.action[8])

        menu = self.menuBar()

        menuFichier = menu.addMenu('&Fichier')
        menuConso=menu.addMenu('&Consommation')
        menuModule =menu.addMenu(u'&Module intelligent')
        menuEffacement=menu.addMenu('&Effacement')
        menuInfo=menu.addMenu('?')

        menuInfo.addAction(self.action[1])
        menuFichier.addAction(self.action[5])
        menuFichier.addAction(self.action[6])
        menuFichier.addAction(self.action[7])
        menuFichier.addAction(self.action[9])
        menuFichier.addAction(self.action[0])
        menuModule.addAction(self.action[8])
        menuConso.addAction(self.action[2])
        menuConso.addAction(self.action[3])
        menuConso.addAction(self.action[4])

#--------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------
#                                       PLOTTING
#--------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------

#-------------------------------------CONSOMMATION-------------------------------------------------
#100-20
#
#
    def plotC(self):
        self.Ct[0].mplwidget.axes.clear()
        if self.echelle==1:
            timeLength=24*365
        elif self.echelle==2:
            timeLength=24*30
        elif self.echelle==3:
            timeLength=24*7
        elif self.echelle==4:
            timeLength=24

        if self.cptConso>timeLength:
            if(self.Cdef[0].currentText()=="Total"):
                if(self.CaffConsoLib==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[self.cptConso-timeLength:self.cptConso],self.lTotNat[self.cptConso-timeLength:self.cptConso],color='r')
                    self.Ct[0].mplwidget.axes.set_xlim(self.cptDemande-timeLength,self.cptDemande)
                if(self.CaffConsoEff==True):
                    self.Ct[0].mplwidget.axes.autofmt_xdate()
                    self.Ct[0].mplwidget.axes.plot(self.tps[self.cptConso-timeLength:self.cptConso],self.lTot[self.cptConso-timeLength:self.cptConso])

                    self.Ct[0].mplwidget.axes.set_xlim(self.cptDemande-timeLength,self.cptDemande)

                if(self.CaffEff==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[self.cptConso-timeLength:self.cptConso],self.diffTot[self.cptConso-timeLength:self.cptConso])
                    self.Ct[0].mplwidget.axes.set_xlim(self.cptDemande-timeLength,self.cptDemande)

            else:
                i =self.Cdef[0].currentIndex()
                if(self.CEff[0].isChecked()==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[self.cptConso-timeLength:self.cptConso],self.lMNat[i][self.cptConso-timeLength:self.cptConso])
                    self.Ct[0].mplwidget.axes.set_xlim(self.cptDemande-timeLength,self.cptDemande)
                if(self.CEff[1].isChecked()==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[self.cptConso-timeLength:self.cptConso],self.lM[i][self.cptConso-timeLength:self.cptConso])
                    self.Ct[0].mplwidget.axes.set_xlim(self.cptDemande-timeLength,self.cptDemande)
                if(self.CEff[2].isChecked()==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[self.cptConso-timeLength:self.cptConso],self.diffM[i][self.cptConso-timeLength:self.cptConso])
                    self.Ct[0].mplwidget.axes.set_xlim(self.cptDemande-timeLength,self.cptDemande)
        else:
            if(self.Cdef[0].currentText()=="Total"):
                if(self.CaffConsoLib==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[:self.cptConso],self.lTotNat[:self.cptConso],color='r')
                if(self.CaffConsoEff==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[:self.cptConso],self.lTot[:self.cptConso])
                if(self.CaffEff==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[:self.cptConso],self.diffTot[:self.cptConso])
            else:
                i =self.Cdef[0].currentIndex()
                if(self.CEff[0].isChecked()==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[:self.cptConso],self.lMNat[i][:self.cptConso])
                if(self.CEff[1].isChecked()==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[:self.cptConso],self.lM[i][:self.cptConso])
                if(self.CEff[2].isChecked()==True):
                    self.Ct[0].mplwidget.axes.plot(self.tps[:self.cptConso],self.diffM[i][:self.cptConso])

        self.Ct[0].mplwidget.axes.set_title(self.Cdef[0].currentText())
        self.Ct[0].mplwidget.axes.set_xlabel(u"Temps (h)")
        self.Ct[0].mplwidget.axes.set_ylabel(u"Puissance consommée (W)")
        self.Ct[0].mplwidget.axes.figure.canvas.draw()

#-------------------------------------DEMANDE------------------------------------------------------

    def plotBenef(self):
        self.Ct[0].mplwidget.axes.clear()
        self.Dprix[0].mplwidget.axes.clear()
        print (len(self.tps[:self.cptDemande]),len(self.Dg1y),self.cptDemande)
        print(" ")
        print(" ")

        print(" ")
        print(" ")
        print(" ")

        self.Dprix[0].mplwidget.axes.plot(self.tps[:self.cptEco],self.Dg1y)

        self.Dprix[0].mplwidget.axes.set_title(u"Bénéfices du client à ce jour")
        self.Dprix[0].mplwidget.axes.set_xlabel(u"Temps (h)")
        self.Dprix[0].mplwidget.axes.set_ylabel(u"Economies (€)")

        self.Dprix[0].mplwidget.axes.set_xlim(0,len(self.tps))

        self.Dprix[0].mplwidget.axes.set_ylim(0,1000)
        self.Dprix[0].mplwidget.axes.figure.canvas.draw()

    def plotDemande(self):
        if self.echelle==1:
            timeLength=24*365
        elif self.echelle==2:
            timeLength=24*30
        elif self.echelle==3:
            timeLength=24*7
        elif self.echelle==4:
            timeLength=24

        if timeLength>self.cptDemande:

            self.Dprix[1].mplwidget.axes.clear()
            self.Dprix[1].mplwidget.axes.plot(self.tps[:self.cptDemande],self.Dg2y[:self.cptDemande])
        else:
            self.Dprix[1].mplwidget.axes.clear()
            self.Dprix[1].mplwidget.axes.plot(self.tps[self.cptDemande-timeLength:self.cptDemande],self.Dg2y[self.cptDemande-timeLength:self.cptDemande])
            self.Dprix[1].mplwidget.axes.set_xlim(self.cptDemande-timeLength,self.cptDemande)

        self.Dprix[1].mplwidget.axes.set_title(u"Prix d'achat en gros du MWh")
        self.Dprix[1].mplwidget.axes.set_xlabel(u"Temps (h)")
        self.Dprix[1].mplwidget.axes.set_ylabel(u"Prix du MWh")
        self.Dprix[1].mplwidget.axes.set_ylim(0,80)
        self.Dprix[1].mplwidget.axes.figure.canvas.draw()

    def plotPrix(self):
        self.Dprix[2].mplwidget.axes.clear()
        self.Dprix[2].mplwidget.axes.plot(self.tps[:self.cptDemande],self.Dg3y)
        self.Dprix[2].mplwidget.axes.set_title(u"Prix de vente de l'éléctricité")
        self.Dprix[2].mplwidget.axes.set_xlabel(u"Temps (h)")
        self.Dprix[2].mplwidget.axes.set_ylabel(u"Prix (€)")
        self.Dprix[2].mplwidget.axes.set_ylim(0,0.2)
        self.Dprix[2].mplwidget.axes.figure.canvas.draw()

#-------------------------------------CONFORT------------------------------------------------------

    def plotGene(self):
        self.Egraph[0].mplwidget.axes.clear()
        self.Egraph[0].mplwidget.axes.set_title(u"Facteur de gène")
        self.Egraph[0].mplwidget.axes.set_xlabel(u"Temps (h")
        self.Egraph[0].mplwidget.axes.set_ylabel(u"Gène")
        self.Egraph[0].mplwidget.axes.plot(self.Eg1x,self.Eg1y)
        self.Egraph[0].mplwidget.axes.set_ylim(0,1.1)
        self.Egraph[0].mplwidget.axes.figure.canvas.draw()

    def plot(self,axes):
        axes.plot(self.Eg1x,self.Eg1y)

# FIN CLASSE FENETRE

class MatplotlibWidget(Canvas):
    def __init__(self, parent=None, title='', xlabel='', ylabel='',
                 xlim=None, ylim=None, xscale='linear', yscale='linear',
                 width=4, height=3, dpi=100, hold=False):
        self.figure = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.figure.add_subplot(111)
        self.axes.set_title(title)
        self.axes.set_xlabel(xlabel)
        self.axes.set_ylabel(ylabel)
        if xscale is not None:
            self.axes.set_xscale(xscale)
        if yscale is not None:
            self.axes.set_yscale(yscale)
        if xlim is not None:
            self.axes.set_xlim(*xlim)
        if ylim is not None:
            self.axes.set_ylim(*ylim)
        self.axes.hold(hold)

        Canvas.__init__(self, self.figure)
        self.setParent(parent)

        Canvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        Canvas.updateGeometry(self)

    def sizeHint(self):
        w, h = self.get_width_height()
        return QtCore.QSize(w, h)

    def minimumSizeHint(self):
        return QtCore.QSize(10, 10)

#"""-----------------------------------------------------------------------------------------------------------------
#                                                LANCEMENT DU MAIN :
#
#-----------------------------------------------------------------------------------------------------------------"""

def main(args):
    # ECRAN DE CHARGEMENT
    app=QtGui.QApplication(sys.argv)
    pix=QtGui.QPixmap("logo/logo256.png")
    splash= QtGui.QSplashScreen(pix)
    splash.show()
    # LANCEMENT
    t=Fenetre(app)
    splash.finish(t);
    r=app.exec_()
    return r

if __name__=="__main__":
    main(sys.argv)


# coding=utf-8

from django.conf.urls import url
from django.contrib.auth.decorators import login_required
from django.views.decorators.clickjacking import xframe_options_exempt
from poster.view.mobile import (
    PosterEditView, PosterView,
    CategoryKeywordsView, CreateFormView,
    SelectTemplateView, PosterPageCreateView,
    UpdateFormView
)

# 创建海报
urlpatterns = [
    url(r'^keywords/$', login_required(CategoryKeywordsView.as_view()),
        name='keywords'),

    url(r'^create-form/$', login_required(CreateFormView.as_view()),
        name='create_form'),

    url(r'^update-form/(?P<pk>[\d]+)/$',
        login_required(UpdateFormView.as_view()),
        name='update_form'),

    url(r'^select-template/(?P<poster_pk>[\d]+)$',
        login_required(SelectTemplateView.as_view()),
        name='select_template'),

    url(r'^posterpage/$', login_required(PosterPageCreateView.as_view()),
        name='posterpage'),
]

# 显示海报
urlpatterns += [
    url(r'^(?P<pk>[\d]+)/$',
        xframe_options_exempt(PosterView.as_view()), name='show'),
]

# 编辑海报url
urlpatterns += [
    url(r'^(?P<poster_pk>[\d]+)/edit$',
        login_required(PosterEditView.as_view()),
        name='edit'),
]


# create a class to fix the pipeline
"""
commenting out: from sklearn.neighbors import KNeighborsClassifier
breaks the code, so need to fix the pipeline,
can do so by creating a class
"""

# required for random
"""this does not give a very good prediction"""
# import random

# Use Euclidean distance
from scipy.spatial import distance

# let a be from training data, b from testing data
def euc(a, b):
    return distance.euclidean(a, b)

# first write a random classifier to guess the label
class ScrappyKNN:
    # train data
    def fit(self, X_train, y_train):
        # store training data in this class
        self.X_train = X_train
        self.y_train = y_train

    # predict data
    def predict(self, X_test):
        # need to return a list of predictions
        """this is because X_test is a 2D array"""
        predictions = []
        # each row contains the features for 1 testing example
        for row in X_test:
            # randomly pick a label from the training data
            """not accurate"""
            # label = random.choice(self.y_train)
            label = self.closest(row)
            predictions.append(label)
        return predictions

    def closest(self, row):
        # keep track the shortest distance found so far
        best_dist = euc(row, self.X_train[0])
        # keep track of the index of the training point that's closest
        best_index = 0
        # requires loop to retrieve its label
        for i in range(1, len(self.X_train)):
            # iterate over all the other training points
            dist = euc(row, self.X_train[i])
            # everytime a closer point is found, update variable
            if dist < best_dist:
                best_dist = dist
                best_index = i
            # use index to return the label for the closest training example
            return self.y_train[best_index]

# import iris dataset
from sklearn import datasets

iris = datasets.load_iris()

# let x be features, and y be labels
"""
think of it as f(x) = y
in other words, x is input, y is output
"""
X = iris.data
y = iris.target

# partition dataset into 2 sets: train and test
from sklearn.cross_validation import train_test_split

"""
X_train & y_train are the features and labels for the training set
X_test & y_test are the features and labels for the testing set
use test_size to split accordingly,
if 0.5, means train set is 50%, test set is 50%
"""
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.5)

# create classifier
"""Use 2 different classifier types"""
# from sklearn import tree
# from sklearn.neighbors import KNeighborsClassifier

"""decision tree"""
#my_classifier = tree.DecisionTreeClassifier()
"""K nearest Neighbors
since KNeighborsClassifier import has been commented, need to change
"""
# my_classifier = KNeighborsClassifier()
my_classifier = ScrappyKNN()

# train classifier
my_classifier.fit(X_train, y_train)

# call predict method to classify testing data
predictions = my_classifier.predict(X_test)

# compare accuracy by comparing predicted labels to true labels
from sklearn.metrics import accuracy_score
print(accuracy_score(y_test, predictions))

# classifier function for reusability
"""
def classify(features)
   # do some logic
   return label
"""