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

from django.shortcuts import render , redirect, render_to_response
import json

from django.http import HttpResponseServerError, HttpResponse,  HttpResponseBadRequest,  HttpResponseNotAllowed
from django.db.models import Model

# from models import *
# from .models import data_info, index, emballage, tecnology, client, contact, footer
from django.contrib.auth.models import User
from django.contrib.auth import login, authenticate,logout
from emballages_pt.forms import ptadd_form1, ptadd_form2, ptadd_form3, ptadd_form4, ptadd_form5, ptadd_form6
from emballages_pt import models
from django.core.mail import EmailMessage
# Create your views here.
def ptclientes (request):
	if request.method == 'GET':
		index = models.ptindex.objects.last()
		clients = models.ptclient.objects.last()
		footer = models.ptfooter.objects.last()
		context_data = {'index': index, 'clients': clients,'footer': footer}
		return render(request, 'clientes_pt.html', context_data)

def ptcontactanos (request):
	if request.method == 'POST':
		formulario = ptadd_form5(request.POST)
		if formulario.is_valid():
			asunto = 'Mensaje de página Web Emusa'
			nombre = request.POST['name']
			email = request.POST['email']
			numero = request.POST['number']
			mensaje = request.POST['textarea1']
			body = "Nombre:  %s \nNumero:  %s \nEmail:   %s \nMensaje: %s" %(nombre, numero, email, mensaje)
			mail = EmailMessage(asunto, body, to=['customerservice@emusa.com.pe'])
			mail.send()
		return redirect("/contactanos_pt.html")
	else:
		index = models.ptindex.objects.last()
		contacts = models.ptcontact.objects.last()
		footer = models.ptfooter.objects.last()
		context_data = {'index': index, 'contacts': contacts,'footer': footer}
		return render(request, 'contactanos_pt.html', context_data)

def ptindex (request):
	if request.method == 'GET':
		index = models.ptindex.objects.last()
		footer = models.ptfooter.objects.last()
		context_data = {'index': index, 'footer': footer}
		return render(request, 'index_pt.html',context_data)

def ptempacate (request):
	if request.method == 'POST':
		formulario = ptadd_form5(request.POST)
		if formulario.is_valid():
			asunto = 'Este es un mensaje de un usuario en emusa.com.pe'
			nombre = request.POST['name']
			email = request.POST['email']
			numero = request.POST['number']
			mensaje = request.POST['textarea1']
			body = "Nombre:  %s \nNumero:  %s \nEmail:   %s \nMensaje: %s" %(nombre, numero, email, mensaje)
			mail = EmailMessage(asunto, body, to=['customerservice@emusa.com.pe'])
			mail.send()
		return redirect("/empacate_pt.html")
	else:
		index = models.ptindex.objects.last()
		empacar = models.ptemballage.objects.last()
		footer = models.ptfooter.objects.last()
		context_data = {'index': index, 'empacar': empacar,'footer': footer}
		return render(request, 'empacate_pt.html',context_data)

def ptgaleria (request):
	if request.method == 'GET':
		index = models.ptindex.objects.last()
		context_data = {'index': index}
		return render(request, 'galeria_pt.html', context_data)

def pttecnologia (request):
	if request.method == 'GET':
		index = models.ptindex.objects.last()
		tecnologys = models.pttecnology.objects.last()
		footer = models.ptfooter.objects.last()
		context_data = {'index': index, 'tecnologys': tecnologys,'footer': footer}
		return render(request, 'tecnologia_pt.html', context_data)

def ptadd_new_form (request):
	if request.method == "POST":
		instance1 = models.ptindex.objects.last()
		instance2 = models.ptemballage.objects.last()
		instance3 = models.pttecnology.objects.last()
		instance4 = models.ptclient.objects.last()
		instance5 = models.ptcontact.objects.last()
		instance6 = models.ptfooter.objects.last()
		modelform1 = ptadd_form1(request.POST, request.FILES, instance= instance1)
		modelform2 = ptadd_form2(request.POST, request.FILES, instance= instance2)
		modelform3 = ptadd_form3(request.POST, request.FILES, instance= instance3)
		modelform4 = ptadd_form4(request.POST, request.FILES, instance= instance4)
		modelform5 = ptadd_form5(request.POST, request.FILES, instance= instance5)
		modelform6 = ptadd_form6(request.POST, request.FILES, instance= instance6)
		if modelform1.is_valid() and modelform2.is_valid() and modelform3.is_valid() and modelform4.is_valid() and modelform5.is_valid() and modelform6.is_valid():
			modelform1.save()
			modelform2.save()
			modelform3.save()
			modelform4.save()
			modelform5.save()
			modelform6.save()
			return redirect("/form_pt.html")
	else:
		modelform1 = ptadd_form1()
		modelform2 = ptadd_form2()
		modelform3 = ptadd_form3()
		modelform4 = ptadd_form4()
		modelform5 = ptadd_form5()
		modelform6 = ptadd_form6()

	# print models.ptdata_info.objects.last()
	return render(request, "form_pt.html", {"form1": modelform1,"form2": modelform2,"form3": modelform3,"form4": modelform4,"form5": modelform5,"form6": modelform6})


#!/usr/bin/env python3

import sys
import pandas as pd
from matplotlib import pyplot as plt

if __name__ == '__main__':
    if len(sys.argv) != 3:
        raise SyntaxError("Wrong number of arguments")

    tlib = sys.argv[1]
    dromajo = sys.argv[2]

    df_tlib = pd.read_csv(tlib)
    df_dromajo = pd.read_csv(dromajo)

    print(df_tlib)

    plt.show()


"""Scikit manifold oblique random forests."""
import logging
import os
import sys

__version__ = "0.3.0dev0"
logger = logging.getLogger(__name__)

# On OSX, we can get a runtime error due to multiple OpenMP libraries loaded
# simultaneously. This can happen for instance when calling BLAS inside a
# prange. Setting the following environment variable allows multiple OpenMP
# libraries to be loaded. It should not degrade performances since we manually
# take care of potential over-subcription performance issues, in sections of
# the code where nested OpenMP loops can happen, by dynamically reconfiguring
# the inner OpenMP runtime to temporarily disable it while under the scope of
# the outer OpenMP parallel section.
os.environ.setdefault("KMP_DUPLICATE_LIB_OK", "True")

# Workaround issue discovered in intel-openmp 2019.5:
# https://github.com/ContinuumIO/anaconda-issues/issues/11294
os.environ.setdefault("KMP_INIT_AT_FORK", "FALSE")

try:
    # This variable is injected in the __builtins__ by the build
    # process. It is used to enable importing subpackages of sklearn when
    # the binaries are not built
    __sktree_SETUP__  # type: ignore
except NameError:
    __sktree_SETUP__ = False

if __sktree_SETUP__:
    sys.stderr.write("Running from Scikit-Tree source directory.\n")
    sys.stderr.write("Partial import of sktree during the build process.\n")
    # We are not importing the rest of scikit-tree during the build
    # process, as it may not be compiled yet
else:
    try:
        from . import _lib, tree, ensemble, experimental, stats
        from ._lib.sklearn.ensemble._forest import (
            RandomForestClassifier,
            RandomForestRegressor,
            ExtraTreesClassifier,
            ExtraTreesRegressor,
        )
        from .neighbors import NearestNeighborsMetaEstimator
        from .ensemble import ExtendedIsolationForest, MultiViewRandomForestClassifier
        from .ensemble._unsupervised_forest import (
            UnsupervisedRandomForest,
            UnsupervisedObliqueRandomForest,
        )
        from .ensemble._supervised_forest import (
            ExtraObliqueRandomForestClassifier,
            ExtraObliqueRandomForestRegressor,
            ObliqueRandomForestClassifier,
            ObliqueRandomForestRegressor,
            PatchObliqueRandomForestClassifier,
            PatchObliqueRandomForestRegressor,
        )
        from .ensemble._honest_forest import HonestForestClassifier
    except ImportError as e:
        print(e.msg)
        msg = """Error importing scikit-tree: you cannot import scikit-tree while
        being in scikit-tree source directory; please exit the scikit-tree source
        tree first and relaunch your Python interpreter."""
        raise ImportError(msg) from e

    __all__ = [
        "_lib",
        "tree",
        "experimental",
        "ensemble",
        "stats",
        "ExtraObliqueRandomForestClassifier",
        "ExtraObliqueRandomForestRegressor",
        "NearestNeighborsMetaEstimator",
        "ObliqueRandomForestClassifier",
        "ObliqueRandomForestRegressor",
        "PatchObliqueRandomForestClassifier",
        "PatchObliqueRandomForestRegressor",
        "UnsupervisedRandomForest",
        "UnsupervisedObliqueRandomForest",
        "HonestForestClassifier",
        "RandomForestClassifier",
        "RandomForestRegressor",
        "ExtraTreesClassifier",
        "ExtraTreesRegressor",
        "ExtendedIsolationForest",
        "MultiViewRandomForestClassifier",
    ]


# Author:Aliex ZJ
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import requests
from pyDes import des, CBC, PAD_PKCS5
import binascii

# 秘钥
KEY='mHAxsLYz'
def des_encrypt(s):
    """
    DES 加密
    :param s: 原始字符串
    :return: 加密后字符串，16进制
    """
    secret_key = KEY
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    en = k.encrypt(s, padmode=PAD_PKCS5)
    return binascii.b2a_hex(en)

def des_descrypt(s):
    """
    DES 解密
    :param s: 加密后的字符串，16进制
    :return:  解密后的字符串
    """
    secret_key = KEY
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
    return de

a = '100%u7C73'
a= a.replace('%','\\').encode('utf-8')
print(a)
print(type(a))

a = '100%u7C73'.replace('%','\\')
a = bytes.decode(a)
print(a.encode('utf-8'))

print(type(a))
# a = str(a,encoding='utf-8')
print(a)
print(type(a))

s = '100\u7c73'
s.encode('UTF-8')
# s = s.decode().encode('unicode_escape')
print(s)
print(type(s))


import os
import tkinter as tk
from tkinter import filedialog
import json
import pdfplumber
import PyPDF2
import webbrowser

def convert_to_json():
    file_path = filedialog.askopenfilename(filetypes=[("PDF files", "*.pdf")])
    if file_path.endswith('.pdf'):
        try:
            with pdfplumber.open(file_path) as pdf:
                pdf_data = []
                for page_num, page in enumerate(pdf.pages, start=1):
                    page_text = page.extract_text()
                    pdf_data.append({'page': page_num, 'text': page_text})

                file_name = os.path.splitext(os.path.basename(file_path))[0]
                directory = os.path.dirname(file_path)
                json_file_path = os.path.join(directory, f"{file_name}.json")

        except Exception as e:
            print(f"Error with pdfplumber: {e}. Trying with PyPDF2...")
            try:
                pdf_file = open(file_path, 'rb')
                pdf_reader = PyPDF2.PdfReader(pdf_file)

                pdf_data = []
                for page_num in range(len(pdf_reader.pages)):
                    page = pdf_reader.pages[page_num]
                    page_text = page.extract_text()
                    pdf_data.append({'page': page_num + 1, 'text': page_text})

                pdf_file.close()
                file_name = os.path.splitext(os.path.basename(file_path))[0]
                directory = os.path.dirname(file_path)
                json_file_path = os.path.join(directory, f"{file_name}.json")

            except Exception as e:
                print(f"Error with PyPDF2: {e}. Cannot extract text from PDF.")
                result_label.config(text="¡Error! No se puede extraer texto del PDF.")
                return

        json_data = json.dumps(pdf_data, indent=2)

        with open(json_file_path, 'w') as json_file:
            json_file.write(json_data)
        result_label.config(text=f"¡Conversión completada! Archivo '{file_name}.json' generado.", fg="black")
        convert_button.pack_forget()  # Oculta el botón "Convertir a JSON"
        view_json_button.pack()  # Muestra el botón "Ver JSON"

    else:
        result_label.config(text="¡Error! Selecciona un archivo PDF.", fg="black")

def view_json():
    json_file_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])
    if json_file_path.endswith('.json'):
        json_directory = os.path.dirname(json_file_path)
        result_label.config(text=f"El archivo JSON está en: {json_directory}", fg="black")
        webbrowser.open(json_file_path)  # Abre el archivo JSON en el navegador

root = tk.Tk()
root.title("PDF to JSON Converter")
root.geometry("300x200")
root.configure(bg="#F9DCC5")

instructions = tk.Label(root, text="Por favor, selecciona un archivo PDF:", fg="black", bg="#F9DCC5")
instructions.pack()

convert_button = tk.Button(root, text="Convertir a JSON", command=convert_to_json, bg="#FC9C4F")
convert_button.pack()

result_label = tk.Label(root, text="", fg="black", bg="#F9DCC5")
result_label.pack()

view_json_button = tk.Button(root, text="Ver JSON", command=view_json, bg="#FC9C4F")  # Mostrará el botón "Ver JSON" después de la conversión
view_json_button.pack()
view_json_button.pack_forget()  # Se oculta inicialmente

root.mainloop()


from random import randint
from random import randrange
import pygame_gui as pg_gui
import pygame as pg

pg.init()

pg.time.set_timer(pg.USEREVENT, 10000)
clock = pg.time.Clock()

# создаем таймеры

sc = pg.display.set_mode((620, 620))
pg.display.set_caption("КАЛЬЯННЫЙ ГОНЩИК: ВОЗМЕЗДИЕ")
# разрешение окна и заголовок окна

icon = pg.image.load('logoblack.png')
pg.display.set_icon(icon)
# логотип

sc = pg.display.set_mode((620, 620))
pg.display.set_caption("КАЛЬЯННЫЙ ГОНЩИК: ВОЗМЕЗДИЕ")

icon = pg.image.load('logoblack.png')
pg.display.set_icon(icon)

BAD_COOMARS = ('sprites/Bad_Coomar/1.png', 'sprites/Bad_Coomar/2.png',)
BAD_COOMARS_NEW = [pg.transform.scale(pg.image.load(i), (300, 150)) for i in BAD_COOMARS]

BAD_APPLES = ('sprites/Bad_Apple/1.png', 'sprites/Bad_Apple/2.png',
              'sprites/Bad_Apple/3.png', 'sprites/Bad_Apple/4.png',
              'sprites/Bad_Apple/5.png', 'sprites/Bad_Apple/6.png')
BAD_APPLES_NEW = [pg.transform.scale(pg.image.load(i), (150, 150)) for i in BAD_APPLES]

GREEN_APPLES = ('sprites/Green_Apple/1.png', 'sprites/Green_Apple/2.png',
                'sprites/Green_Apple/3.png', 'sprites/Green_Apple/4.png',
                'sprites/Green_Apple/5.png', 'sprites/Green_Apple/6.png')
GREEN_APPLES_NEW = [pg.transform.scale(pg.image.load(i), (150, 150)) for i in GREEN_APPLES]

RED_APPLES = ('sprites/Red_Apple/1.png', 'sprites/Red_Apple/2.png',
              'sprites/Red_Apple/3.png')
RED_APPLES_NEW = [pg.transform.scale(pg.image.load(i), (150, 150)) for i in RED_APPLES]

HOOKAH = ('sprites/Hookah/1.png', 'sprites/Hookah/2.png', 'sprites/Hookah/3.png',
          'sprites/Hookah/4.png', 'sprites/Hookah/5.png', 'sprites/Hookah/6.png',)
HOOKAH_NEW = [pg.transform.scale(pg.image.load(i), (200, 200)) for i in HOOKAH]

HOOKAH_LEFT = pg.transform.scale(pg.image.load('sprites/Hookah/left.png'), (200, 200))
HOOKAH_RIGHT = pg.transform.scale(pg.image.load('sprites/Hookah/right.png'), (200, 200))

# работа со спрайтами

bg = pg.image.load('bg1.jpg')
bg = pg.transform.scale(bg, (620, 620))
logo = pg.image.load('logo.png')
logo = pg.transform.scale(logo, (300, 300))
logomini = logo.copy()

bg_music = pg.mixer.Sound('sounds/bg1.mp3')
menu_music = pg.mixer.Sound('sounds/menu.mp3')
hit_sound = pg.mixer.Sound('sounds/hit.mp3')
heal_sound = pg.mixer.Sound('sounds/heal.mp3')
exp_sound = pg.mixer.Sound('sounds/exp.mp3')
lose = pg.mixer.Sound('sounds/lose.mp3')
menu_music.play(-1)
menu_music.set_volume(0.5)
bg_music.set_volume(0.5)
hit_sound.set_volume(0.9)
exp_sound.set_volume(0.9)
heal_sound.set_volume(0.9)
lose.set_volume(0.9)

x = 220
y = 450
width = 30
height = 30
speed = 2
level = 1

# базовые характеристики игро

left = False
right = False
animCount = 0
run = None

hp = 3
hp_image = pg.image.load('sprites/HP_and_EXP/hp.png')
hp_bg_image = pg.image.load('sprites/HP_and_EXP/hpbg.png')
hp_name = pg.image.load('sprites/HP_and_EXP/healthname.png')

exp = 0
exp_image = pg.image.load('sprites/HP_and_EXP/exp.png')
exp_name = pg.image.load('sprites/HP_and_EXP/expname.png')
exp_bg_image = pg.image.load('sprites/HP_and_EXP/expbg.png')

# инициализация характеристик для очков здоровья и опыта

def HealthBar():
    sc.blit(hp_bg_image, (10, 0))
    sc.blit(hp_name, (160, 0))
    x = 10
    show = 0
    while show != hp:
        sc.blit(hp_image, (x, 0))
        x += 50
        show += 1

# функция полоски здоровья

def control():
    global left
    global right
    global x
    global y
    global animCount
    keys = pg.key.get_pressed()
    if keys[pg.K_a] and x > 5:
        left = True
        right = False
        x -= speed + 2 + level * 2
        animCount = 0
    elif keys[pg.K_d] and x < 450 - width - 5:
        left = False
        right = True
        x += speed + 2 + level * 2
        animCount = 0
    else:
        left = False
        right = False
    if keys[pg.K_w] and y > 5:
        y -= speed
    if keys[pg.K_s] and y < 600 - height - 5:
        y += speed
    if keys[pg.K_ESCAPE]:
        pause()

# функция управления

def ExpBar():
    sc.blit(exp_bg_image, (0, 30))
    sc.blit(exp_name, (250, 30))
    x = 10
    show = 0
    while show != exp:
        sc.blit(exp_image, (x, 30))
        x += 50
        show += 1

# функция полоски опыта
    # Движение заднего фона

def BgAnimation():
    global bg_y
    global bg
    sc.blit(bg, (0, bg_y))
    sc.blit(bg, (0, bg_y - 620))
    bg_y += 2
    if bg_y == 620:
        bg_y = 0

# функция анимации заднего фона

def drawWindow():
    global animCount
    global Alive
    global level
    global hp
    global exp
    global bg_music
    global bg
    if animCount + 1 >= 30:
        animCount = 0
    if left:
        sc.blit(HOOKAH_LEFT, (x, y))
    elif right:
        sc.blit(HOOKAH_RIGHT, (x, y))
    else:
        sc.blit(HOOKAH_NEW[animCount // 5], (x, y))
        animCount += 1

    # условия анимирования

    HOOKAH_rect = pg.Rect(x + 65, y + 45, 60, 75)
    # exp = 0
    for exp_apple in exp_apples:
        if HOOKAH_rect.colliderect(exp_apple.rect):
            exp_apples.remove(exp_apple)
            exp_sound.play(0)
            if exp < 5:
                exp += 1
            if exp == 5:
                if level < 4:
                    level += 1
                if level == 2:
                    bg_music.stop()
                    bg_music = pg.mixer.Sound('sounds/bg2.mp3')
                    bg_music.play(-1)
                    bg = pg.image.load('bg2.jpg')
                    bg = pg.transform.scale(bg, (620, 620))
                if level == 3:
                    bg_music.stop()
                    bg_music = pg.mixer.Sound('sounds/bg3.mp3')
                    bg_music.play(-1)
                    bg = pg.image.load('bg3.jpg')
                    bg = pg.transform.scale(bg, (620, 620))
    for heal_apple in heal_apples:
        if HOOKAH_rect.colliderect(heal_apple.rect):
            heal_apples.remove(heal_apple)
            heal_sound.play(0)
            if hp < 3:
                hp += 1

    for bad_apple in bad_apples:
        if HOOKAH_rect.colliderect(bad_apple.rect):
            bad_apples.remove(bad_apple)
            hit_sound.play(0)
            # дается три жизни
            hp -= 1
            if hp == 0:
                Alive = False
    for bad_coomar in bad_coomars:
        if HOOKAH_rect.colliderect(bad_coomar.rect):
            bad_apples.remove(bad_coomar)
            hit_sound.play(0)
            # дается три жизни
            hp -= 1
            if hp == 0:
                Alive = False

    # циклы отслеживания соприкосновени
    heal_apples.draw(sc)
    exp_apples.draw(sc)
    bad_apples.draw(sc)
    bad_coomars.draw(sc)

    HealthBar()
    ExpBar()

    pg.display.update()

# функция рисования объекто

# инциализуруем переменные для pg_gui и вводим кнопки нашего меню
manager = pg_gui.UIManager((620, 620))

hello_button = pg_gui.elements.UIButton(relative_rect=pg.Rect((15, 250), (175, 50)),
                                        text='НАЧАТЬ БЕЗУМИЕ',
                                        manager=manager)
exit_button = pg_gui.elements.UIButton(relative_rect=pg.Rect((15, 325), (175, 50)),
                                       text='Я БОЮСЬ',
                                       manager=manager)

font = pg.font.Font('Fixedsys.ttf', size=32)

def draw_text(text, font, text_col, x, y):
    img = font.render(text, False, text_col)
    sc.blit(img, (x, y))

# функция вывода текста

def pause():
    transparent = pg.Surface((620, 620))
    transparent.set_alpha(60)

    # переход
    for i in range(7):
        sc.blit(transparent, (0, 0))
        pg.display.flip()
        pg.time.wait(30)

    manager = pg_gui.UIManager((620, 620))
    hello_button = pg_gui.elements.UIButton(relative_rect=pg.Rect((15, 200), (195, 50)),
                                            text='ПРОДОЛЖИТЬ?',
                                            manager=manager)
    exit_button = pg_gui.elements.UIButton(relative_rect=pg.Rect((15, 350), (195, 50)),
                                           text='СТРАХ СЛИШКОМ СИЛЁН',
                                           manager=manager)
    pause = True
    while pause:
        time_delta2 = clock.tick(60) / 1000
        for i in pg.event.get():
            if i.type == pg.QUIT:
                quit()

            if i.type == pg.MOUSEBUTTONDOWN:
                if exit_button.rect.collidepoint(i.pos):
                    quit()
                if hello_button.rect.collidepoint(i.pos):
                    pause = not pause

            manager.process_events(i)
        manager.update(time_delta2)
        manager.draw_ui(sc)
        draw_text('ПАУЗА', font, (255, 255, 255), 70, 280)
        pg.display.update()

# функция паузы

lose_img = pg.image.load('loseimg.png')

# экран проигрыша
def losewindow():  # доделать функцию
    global Alive
    global hp
    global exp
    global x
    global y
    global level
    sc.fill((0, 0, 0))
    huager = pg_gui.UIManager((620, 620))
    hello_button2 = pg_gui.elements.UIButton(relative_rect=pg.Rect((100, 400), (200, 50)),
                                             text='ЕЩЕ РАЗ',
                                             manager=huager)
    exit_button2 = pg_gui.elements.UIButton(relative_rect=pg.Rect((320, 400), (200, 50)),
                                            text='Я БОЮСЬ',
                                            manager=huager)

    dead = True
    bg_music.stop()
    lose.play(-1)
    while dead:
        time_delta2 = clock.tick(60) / 1000
        for i in pg.event.get():
            if i.type == pg.QUIT:
                quit()
            if i.type == pg.KEYDOWN:
                if i.key == pg.K_ESCAPE:
                    quit()
            if i.type == pg.MOUSEBUTTONDOWN:
                if exit_button2.rect.collidepoint(i.pos):
                    quit()
                if hello_button2.rect.collidepoint(i.pos):
                    Alive = True
                    dead = False
                    hp = 3
                    exp = 0
                    x = 220
                    y = 450
                    lose.stop()
                    bg_music.play(-1)
            huager.process_events(i)
        huager.update(time_delta2)
        sc.blit(lose_img, (0, 0))
        huager.draw_ui(sc)
        pg.display.update()

def fade_out(surface, fade_speed, x, y):  # Функция для плавного исчезновения
    alpha = 255
    while alpha > 0:
        alpha -= fade_speed
        surface.set_alpha(alpha)
        sc.fill((0, 0, 0))
        sc.blit(surface, (x, y))
        pg.display.update()
        clock.tick(60)

def fade_in(surface, fade_speed, x, y):  # Функция для плавного появления
    alpha = 0
    while alpha < 255:
        alpha += fade_speed
        surface.set_alpha(alpha)
        sc.fill((0, 0, 0))
        sc.blit(surface, (x, y))
        pg.display.update()
        clock.tick(60)

fade_in(logo, 1, 150, 150)  # появление логотипа

fade_in(logo, 1, 150, 150)

fade_out(logo, 6, 150, 150)  # затухание логотипа вначале (поверхность, скорость изменения альфа, координаты х у)

sc.blit(bg, (0, 0))  # (фон для менюшки, лого в нижнем углу и текст)
sc.blit(pg.transform.scale(logomini, (165, 165)), (430, 450))
draw_text('КАЛЬЯННЫЙ ГОНЩИК', font, (255, 255, 255), 15, 110)

menu_img = pg.image.load('menu.png')
# цикл меню, который работает через pygame_gui, при нажатии кнопки hello_button запускает игровой цикл
menu = True  # цикл для gui менюшки
while menu:
    time_delta = clock.tick(60) / 1000.0
    for i in pg.event.get():
        if i.type == pg.QUIT:
            menu = False
        if i.type == pg_gui.UI_BUTTON_PRESSED:
            if i.ui_element == hello_button:
                run = True
                menu = False
                menu_music.stop()
                bg_music.play(-1)
            if i.ui_element == exit_button:
                menu = False
                run = False
        manager.process_events(i)
    sc.blit(menu_img, (0, 0))
    manager.update(time_delta)
    manager.draw_ui(sc)
    pg.display.update()

class HealApple(pg.sprite.Sprite):
    def __init__(self, x, surf, group):
        pg.sprite.Sprite.__init__(self)
        self.images = surf.copy()
        self.cur = 0
        self.image = self.images[self.cur]
        self.rect = self.image.get_rect(center=(x, 0))
        # добавляем в группу
        self.add(group)
        # у машин будет разная скорость
        self.speed = 3

    def update(self):
        self.cur = (self.cur + 1) % len(self.images)
        self.image = self.images[self.cur]
        if self.rect.y < 620:
            self.rect.y += self.speed
        else:
            # теперь не перебрасываем вверх, а удаляем из всех групп
            self.kill()

class ExpApple(pg.sprite.Sprite):
    def __init__(self, x, surf, group):
        pg.sprite.Sprite.__init__(self)
        self.images = surf.copy()
        self.cur = 0
        self.image = self.images[self.cur]
        self.rect = self.image.get_rect(center=(x, 0))
        # добавляем в группу
        self.add(group)
        # у машин будет разная скорость
        self.speed = 3

    def update(self):
        self.cur = (self.cur + 1) % len(self.images)
        self.image = self.images[self.cur]
        if self.rect.y < 620:
            self.rect.y += self.speed
        else:
            # теперь не перебрасываем вверх, а удаляем из всех групп
            self.kill()

class BadApple(pg.sprite.Sprite):
    def __init__(self, x, surf, group):
        pg.sprite.Sprite.__init__(self)
        self.images = surf.copy()
        self.cur = 0
        self.image = self.images[self.cur]
        self.rect = self.image.get_rect(center=(x, 0))
        # добавляем в группу
        self.add(group)
        # у машин будет разная скорость
        self.speed = randint(3, 4)

    def update(self):
        self.cur = (self.cur + 1) % len(self.images)
        self.image = self.images[self.cur]
        if self.rect.y < 620:
            self.rect.y += self.speed
        else:
            # теперь не перебрасываем вверх, а удаляем из всех групп
            self.kill()
class BadCoomar(pg.sprite.Sprite):
    def __init__(self, x, surf, group):
        pg.sprite.Sprite.__init__(self)
        self.images = surf.copy()
        self.cur = 0
        self.image = self.images[self.cur]
        self.rect = self.image.get_rect(center=(x, 0))
        # добавляем в группу
        self.add(group)
        # у машин будет разная скорость
        self.speed = 2

    def update(self):
        self.cur = (self.cur + 1) % len(self.images)
        self.image = self.images[self.cur]
        if self.rect.y < 620:
            self.rect.y += self.speed
        else:
            # теперь не перебрасываем вверх, а удаляем из всех групп
            self.kill()

bad_coomars = pg.sprite.Group()

heal_apples = pg.sprite.Group()
exp_apples = pg.sprite.Group()
bad_apples = pg.sprite.Group()

# классы врагов

bg_y = 0
bad_timer = pg.USEREVENT + 1
red_timer = bad_timer + 100  # xd
very_bad_timer = bad_timer + 100  # xd
bad_coom_timer = bad_timer + 1
green_timer = bad_timer + 1000  # xd
pg.time.set_timer(very_bad_timer, 10000)
pg.time.set_timer(bad_coom_timer, 2000)
pg.time.set_timer(bad_timer, 2500)  # частота появления гнилых яблок
pg.time.set_timer(red_timer, 8000)  # частота появления красных яблок
pg.time.set_timer(green_timer, 10000)  # частота появления зеленых яблок

tolvl1_img = pg.image.load('tolvl1.png')
tolvl2_img = pg.image.load('tolvl2.png')
tolvl3_img = pg.image.load('tolvl3.png')
winscreen = pg.image.load('winscreen.png')
tolvl1 = tolvl2 = tolvl3 = 1

man = pg_gui.UIManager((620, 620))

exit_button3 = pg_gui.elements.UIButton(relative_rect=pg.Rect((235, 325), (175, 50)),
                                        text='ПРОЩАЙ, КАЛИК!',
                                        manager=man)

def LEVEL1():
    if i.type == pg.QUIT:
        pg.quit()
    elif i.type == bad_timer:
        BadApple(randrange(106, 533, 205), BAD_APPLES_NEW, bad_apples)
    elif i.type == red_timer:
        HealApple(randrange(106, 533, 205), RED_APPLES_NEW, heal_apples)
    elif i.type == green_timer:
        ExpApple(randrange(106, 533, 205), GREEN_APPLES_NEW, exp_apples)

def LEVEL2():
    if i.type == pg.QUIT:
        pg.quit()
    # elif i.type == bad_coom_timer:
    #     BadCoomar(randrange(106, 320, 205), BAD_COOMARS_NEW, bad_coomars)
    elif i.type == very_bad_timer:
        BadApple(randrange(106, 533, 205), BAD_APPLES_NEW, bad_apples)
    elif i.type == green_timer:
        ExpApple(randrange(106, 533, 205), GREEN_APPLES_NEW, exp_apples)
    elif i.type == red_timer:
        HealApple(randrange(106, 533, 205), RED_APPLES_NEW, heal_apples)

def LEVEL3():
    if i.type == pg.QUIT:
        pg.quit()
    elif i.type == very_bad_timer:
        BadApple(randrange(106, 533, 205), BAD_APPLES_NEW, bad_apples)
    elif i.type == green_timer:
        ExpApple(randrange(106, 533, 205), GREEN_APPLES_NEW, exp_apples)
    elif i.type == red_timer:
        HealApple(randrange(106, 533, 205), RED_APPLES_NEW, heal_apples)

def WIN():
    if i.type == pg.QUIT:
        pg.quit()
    if i.type == pg.MOUSEBUTTONDOWN:
        if exit_button3.rect.collidepoint(i.pos):
            quit()

Alive = True
# главный цикл
while run:
    if Alive:
        control()
        if level == 1:
            if tolvl1 == 1:
                fade_in(tolvl1_img, 2, 0, 0)
                fade_out(tolvl1_img, 2, 0, 0)
                hp = 3
                exp = 0
                tolvl1 = 0
            for i in pg.event.get():
                LEVEL1()
            BgAnimation()
            drawWindow()
        elif level == 2:
            if tolvl2 == 1:
                fade_in(tolvl2_img, 2, 0, 0)
                fade_out(tolvl2_img, 2, 0, 0)
                hp = 3
                exp = 0
                tolvl2 = 0
            for i in pg.event.get():
                LEVEL2()
            BgAnimation()
            drawWindow()
        elif level == 3:
            if tolvl3 == 1:
                fade_in(tolvl3_img, 2, 0, 0)
                fade_out(tolvl3_img, 2, 0, 0)
                hp = 3
                exp = 0
                tolvl3 = 0
            for i in pg.event.get():
                LEVEL3()
            BgAnimation()
            drawWindow()
        elif level == 4:
            sc.blit(winscreen, (0, 0))
            man.update(time_delta)
            man.draw_ui(sc)
            pg.display.update()
            for i in pg.event.get():
                bg_music.stop()
                win = pg.mixer.Sound('sounds/win.mp3')
                win.play(-1)
                win.set_volume(0.5)
                WIN()
        '''ПОМОГИТЕ КНОПКУ ВЫХОДА СДЕЛАТЬ КОВШ!!!'''

    else:
        # level = 1
        losewindow()

    pg.display.update()
    pg.time.delay(0)
    clock.tick(60)
    heal_apples.update()
    exp_apples.update()

    bad_coomars.update()
    bad_apples.update()


# -*- coding:utf-8 -*-
# @Time : 2019/8/25 19:28
# @Author : Thanlon
# @Email : thanlon@sina.com
# @File : index.py
# @Project : code_count
from flask import render_template, Blueprint, session, redirect, request
import os, uuid
from settings import Config
from ..utils import helper

bp_index = Blueprint('index', __name__)

@bp_index.before_request
def process_request():
    if not session.get('user_info'):
        return redirect('/login')

# @bp_index.route('/index')
# def index():
#     title = {'title': '欢迎使用代码统计系统!'}
#     return render_template('index.html', title=title)

@bp_index.route('/')
def user_list():
    title = {'title': '用户列表'}
    sql = 'select id,user,nickname from userinfo'
    args = []
    data_list = helper.fetch_all(sql, args)
    return render_template('user_list.html', title=title, data_list=data_list)

@bp_index.route('/detail/<int:nid>')  # 默认nid是string类型
def detail(nid):
    sql = 'select id,line,ctime from record where user_id = %s'
    args = nid
    record_list = helper.fetch_all(sql, args)
    # print(record_list)
    data_list = []
    time_list = []
    for row in record_list:
        data_list.append(row['line'])
        time_list.append(float(row['ctime'].strftime("%m.%d")))  # datetime类型转换成字符串
    title = {'title': '提交代码详情页面'}
    return render_template('detail.html', title=title, record_list=record_list, data_list=data_list,
                           time_list=time_list, )

@bp_index.route('/upload', methods=['get', 'post'])  # 默认nid是string类型
def upload():
    title = {'title': '代码上传'}
    msg = ''
    if request.method == 'GET':
        return render_template('upload.html', title=title)
    file_obj = request.files.get('code')  # <FileStorage: '' ('application/octet-stream')>,把上传的东西方内存了
    # print(file_obj.filename)  # 上传的文件名(带扩展名)
    # print(file_obj.stream)  # 文件的内容被封装到对象中
    # 1.检查上传文件的后缀名
    filename_ext = file_obj.filename.rsplit('.', maxsplit=1)  # 元组
    if len(filename_ext) != 2:
        msg = '请上传压缩文件!'
        return render_template('upload.html', msg=msg, title=title)
    if filename_ext[1] != 'zip':
        msg = '请上传后缀名为zip的文件'
        return render_template('upload.html', msg=msg, title=title)

    # 2.接受用户上传的文件并写入到服务器本地
    file_path = os.path.join('files', file_obj.filename)
    file_obj.save(file_path)  # save的本质是：从file_obj.stream中读取内容写入到文件
    # 3.解压zip文件
    import shutil
    target_path = os.path.join('files', str(uuid.uuid4()))  # 允许上传的文件名相同
    # print(target_path)#files/549fb0e2-924c-460d-a993-935fcc8e3274
    # 通过open打开i压缩文件，读取内容再进行解压
    shutil._unpack_zipfile(file_path, target_path)

    # 2和3步合并，接受用户上传的文件，并解压至指定目录
    # import shutil
    # shutil._unpack_zipfile(file_obj.stream, r'/home/thanlon/PycharmProjects/code_count/files')
    # 4. 遍历目录下的所有文件
    # for item in os.listdir(target_path):
    #     print(item)
    # for item in os.walk(target_path):
    #     # 每一个item是一个元组，每一个元组有三个元素，分别是当前路径、当前路径下所有文件夹、当前路径下的所有文件
    #      print(item)  # ('files/79d81a3d-455f-4124-ba24-7d7b8a990c4a/keymaps', [], ['Default Proper Redo.xml'])
    sum_num = 0
    for base_path, folder_list, file_list in os.walk(target_path):
        for file_name in file_list:
            file_path = os.path.join(base_path, file_name)
            # print(file_path)  # files/b39a2b87-69b3-4094-942a-58103e70b8a6/options/databaseDrivers.xml
            file_ext = file_path.rsplit('.', 1)
            if len(file_ext) != 2:
                continue
            if file_ext[1] != 'py':
                continue
            file_num = 0
            with open(file_path, 'rb') as f:
                for line in f:
                    line = line.strip()
                    if not line:
                        continue
                    if line.startswith(b'#'):
                        continue
                    file_num += 1
            # print(file_num, file_path)  # 每一个文件行数
            sum_num += file_num
    # print(sum_num)
    # 获取当前时间
    import datetime
    # ctime = datetime.datetime.now()
    ctime = datetime.date.today()  # 当前日期
    # print(sum_num, ctime, session['user_info']['id'])
    '''
    插入数据之前需要查询今天是否已经提交
    '''
    sql = 'select id from record where ctime = %s and user_id = %s'
    args = (ctime, session['user_info']['id'])
    data = helper.fetchone(sql, args)
    if data:
        return '今天的代码已经上传了!'
    sql = 'insert record(line,ctime,user_id) values(%s,%s,%s)'
    args = (sum_num, ctime, session['user_info']['id'])
    helper.insert(sql, args)
    return '上传成功!'


# This code is heavily based on Phil Tabor Q learning:
# https://github.com/philtabor/Deep-Q-Learning-Paper-To-Code/blob/master/q_learning/q_learning_agent.py

# Here it were added a DeepQ network also based on Phil Tabor's code:
# https://github.com/philtabor/Deep-Q-Learning-Paper-To-Code/blob/master/DQN/deep_q_network.py

# Some hints on how to train the Neural Networks were obtained in this example from begooboi Reddit
# user (based on Keras):
# https://www.reddit.com/r/learnmachinelearning/comments/9vasqm/review_my_code_dqn_for_gym_frozenlake/

import numpy as np

import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torch as T

from collections import deque
import random

class LinearDeepQNetwork(nn.Module):
    def __init__(self, lr, input, n_actions):
        super(LinearDeepQNetwork, self).__init__()

        self.fc1 = nn.Linear(input, 128)
        self.fc2 = nn.Linear(128, n_actions)

        # Phil Tabor: self.parameters() from inherited class Module
        self.optimizer = optim.Adam(self.parameters(), lr=lr)
        self.loss = nn.MSELoss()
        self.device = T.device('cuda:0' if T.cuda.is_available() else 'cpu')
        # Phil Tabor: pytorch have different tensors for cuda/cpu devices
        self.to(self.device)

    def forward(self, state):
        layer1 = F.relu(self.fc1(state))
        # Phil Tabor: MSELoss will take care of activation for us...
        actions = self.fc2(layer1)

        return actions

class Agent():
    def __init__(self, lr, state_space, action_space, gamma=0.90,
                 epsilon=1.0, eps_dec=1e-5, eps_min=0.01):
        """ Agent init takes:
        --
        lr - alpha learning rate factor
        state_space - environment state space dimension
        action_space - environment actions space dimension
        gamma - discount factor on MDP rewards
        epsilon - Epsilon Greedy initial value (exploration threshold)
        eps_dec - Epsilon Greedy decrease factor
        eps_min - Epsilon Greedy minimum, final value (must be > 0)

        """
        self.lr = lr
        self.input_dims = state_space
        self.n_actions = action_space
        self.gamma = gamma
        self.epsilon = epsilon
        self.eps_dec = eps_dec
        self.eps_min = eps_min
        self.action_space = [i for i in range(self.n_actions)]
        self.np_arrays = []
        for i in range(self.input_dims):
            self.np_arrays.append(self.one_hot_state(i))

        self.memory = deque(maxlen=2000)

        self.Q = LinearDeepQNetwork(self.lr, self.input_dims, self.n_actions)

        # print_snapshot constants
        self.action_str = ['<', '.', '>', '^']
        self.map_str = []
        self.map_str.append(['S', 'F', 'F', 'F'])
        self.map_str.append(['F', 'H', 'F', 'H'])
        self.map_str.append(['F', 'F', 'F', 'H'])
        self.map_str.append(['H', 'F', 'F', 'G'])

    def one_hot_state(self, state):
        state_m = np.zeros((1, self.input_dims))
        state_m[0][state] = 1
        return state_m

    def choose_action(self, observation):
        ''' Choose Epsilon Greedy action for a given state '''
        rand_ = np.random.random()

        if rand_ > self.epsilon:
            state = T.tensor(self.np_arrays[observation], dtype=T.float).to(self.Q.device)
            # https://stackoverflow.com/questions/64192810/runtime-error-both-arguments-to-matmul-need-to-be-at-least-1d-but-they-are-0d
            actions = self.Q.forward(state.unsqueeze(dim=0))
            action = T.argmax(actions).item()
        else:
            action = np.random.choice(self.action_space)

        return action

    def decrement_epsilon(self):
        ''' Epsilon decrease function (linear) '''
        # Look: my beloved C ternary in python terms!
        self.epsilon = self.epsilon - self.eps_dec \
            if self.epsilon > self.eps_min else self.eps_min

    def learn(self, state, action, reward, state_, done):
        """ Off Policy (always Greedy) Learn function
        --
        Here defined as plain Bellman equation, state_ is state'
        """
        self.Q.optimizer.zero_grad()
        state_T = T.tensor(self.np_arrays[state_], dtype=T.float).to(self.Q.device)

        if not done:
            actions_T = self.Q.forward(state_T.unsqueeze(dim=0))
            rewardT = reward + self.gamma * T.max(actions_T)
        else:
            rewardT = T.tensor(reward, dtype=T.float).to(self.Q.device)

        stateT = T.tensor(self.np_arrays[state], dtype=T.float).to(self.Q.device)

        q_pred = self.Q.forward(stateT.unsqueeze(dim=0))
        q_target = self.Q.forward(stateT.unsqueeze(dim=0))
        q_target[0][0][action] = rewardT
        loss = self.Q.loss(q_pred, q_target).to(self.Q.device)

        # Phil Tabor: Backpropagate cost and add a step on our optimizer.
        #             These two calls are critical for learn loop.
        loss.backward()
        self.Q.optimizer.step()

        self.decrement_epsilon()

    def batch_learn(self, batch_size):
        minibatch = random.sample(self.memory, batch_size)
        for state, action, reward, next_state, done in minibatch:
            self.learn(state, action, reward, next_state, done)

    def print_learn_snapshot(self):
        """
        Print a snapshot of learning situation.

        Sample:
        --
        Learn snapshot:
        |S(<) 0.061||F(^) 0.095||F(<)-0.036||F(<) 0.049|
        |F(^) 0.074||H(0) ~~~~ ||F(>)-0.018||H(0) ~~~~ |
        |F(<) 0.000||F(^) 0.043||F(>) 0.037||H(0) ~~~~ |
        |H(0) ~~~~ ||F(<) 0.066||F(<) 0.072||G(1)  \o/ |
        --

        Cell format: <status>(<best_action>)<best_action_value>
          status      - 'S'=start, 'G'=goal, 'F'=frozen, 'H'=hole
          best_action - '<'=start, '.'=down, '>'=right, '^'=up
                      - '1'=reward
          best_value  - Extracted value for best_action from NN tensor

        End cells:
          bad ending - ~~~~ (water)
          good ending -  \o/ (happy)

        """

        print('--\nLearn snapshot: ')

        for line in range(4):
            for col in range(4):
                stateT = T.tensor(self.np_arrays[line * 4 + col], dtype=T.float).to(self.Q.device)
                actionsT = self.Q.forward(stateT.unsqueeze(dim=0))
                if self.map_str[line][col] == 'F' or self.map_str[line][col] == 'S':
                    action_max = self.action_str[T.argmax(actionsT).item()]
                    action_max_value = f'{T.max(actionsT).item(): 4.3f}'
                elif self.map_str[line][col] == 'H':
                    action_max = ' '
                    action_max_value = ' ~~~~ '
                else:
                    action_max = '1'
                    action_max_value = '  \o/ '

                print(f'|{self.map_str[line][col]}({action_max}){action_max_value}|', end='')
            print('')
        print('--\n')


from __future__ import division
import scipy.io as sio
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
from scipy import optimize as opt

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def h0x(X, theta):
    m = len(X)
    ones = np.ones((m, 1))
    a1 = np.hstack((ones, X))
    a2 = sigmoid(np.dot(a1, theta[0].T))
    a2 = np.hstack((ones, a2))
    h = sigmoid(np.dot(a2, theta[1].T))

    return h

def cost_func(nn_params, hidden_layer_size, X, y_d, lmbda):
    input_layer_size = len(X[0])  # 400
    num_labels = len(y_one_hot.values[0])  # 10
    m = len(X)
    theta1 = np.reshape(nn_params[:hidden_layer_size*(input_layer_size+1)], (hidden_layer_size, input_layer_size+1), 'F')
    theta2 = np.reshape(nn_params[hidden_layer_size*(input_layer_size+1):], (num_labels, hidden_layer_size+1), 'F')

    h = h0x(X, [theta1, theta2])

    temp1 = np.multiply(y_d, np.log(h))
    temp2 = np.multiply(1 - y_d, np.log(1-h))
    temp3 = np.sum(temp1 + temp2)

    sum1 = np.sum(np.sum(np.power(theta1[:, 1:], 2), axis=1))
    sum2 = np.sum(np.sum(np.power(theta2[:, 1:], 2), axis=1))

    return np.sum(temp3 / (-m)) + (sum1 + sum2) * lmbda / (2*m)

def rand_weights(L_in, L_out):
    epi = (6 ** 1/2) / (L_in + L_out) ** 1/2
    W = np.random.rand(L_out, L_in + 1) * (2 * epi) - epi

    return W

def sigmoid_derivative(z):
    return np.multiply(sigmoid(z), 1-sigmoid(z))

def visualize(X, example_width=None, figsize=(10, 10)):
    """
    Displays 2D data stored in X in a nice grid.
    """
    # Compute rows, cols
    if X.ndim == 2:
        m, n = X.shape
    elif X.ndim == 1:
        n = X.size
        m = 1
        X = X[None]  # Promote to a 2 dimensional array
    else:
        raise IndexError('Input X should be 1 or 2 dimensional.')

    example_width = example_width or int(np.round(np.sqrt(n)))
    example_height = n / example_width

    # Compute number of items to display
    display_rows = int(np.floor(np.sqrt(m)))
    display_cols = int(np.ceil(m / display_rows))

    fig, ax_array = plt.subplots(display_rows, display_cols, figsize=figsize)
    fig.subplots_adjust(wspace=0.025, hspace=0.025)

    ax_array = [ax_array] if m == 1 else ax_array.ravel()

    for i, ax in enumerate(ax_array):
        # Display Image
        h = ax.imshow(X[i].reshape(example_width, example_width, order='F'),
                      cmap='Greys', extent=[0, 1, 0, 1])
        ax.axis('off')

    plt.show()

def back_propagation(nn_params, hidden_layer_size, X, y_d, lmbda):
    input_layer_size = len(X[0])  # 400
    num_labels = len(y_d.values[0])  # 10
    initial_theta1 = np.reshape(nn_params[:hidden_layer_size*(input_layer_size+1)], (hidden_layer_size, input_layer_size+1), 'F')
    initial_theta2 = np.reshape(nn_params[hidden_layer_size*(input_layer_size+1):], (num_labels, hidden_layer_size+1), 'F')
    delta1 = np.zeros(initial_theta1.shape)
    delta2 = np.zeros(initial_theta2.shape)
    m = len(y_d)

    for i in range(X.shape[0]):
        ones = np.ones(1)
        a1 = np.hstack((ones, X[i]))
        z2 = np.dot(a1, initial_theta1.T)
        a2 = np.hstack((ones, sigmoid(z2)))
        z3 = np.dot(a2, initial_theta2.T)
        a3 = sigmoid(z3)

        d3 = a3 - y_d.iloc[i, :][np.newaxis, :]
        z2 = np.hstack((ones, z2))
        d2 = np.multiply(np.dot(initial_theta2.T, d3.T), sigmoid_derivative(z2).T[:,np.newaxis])
        delta1 = delta1 + np.dot(d2[1:, :], a1[np.newaxis, :])
        delta2 = delta2 + np.dot(d3.T, a2[np.newaxis, :])

    delta1 /= m
    delta2 /= m
    delta1[:, 1:] = delta1[:, 1:] + initial_theta1[:, 1:] * lmbda / m
    delta2[:, 1:] = delta2[:, 1:] + initial_theta2[:, 1:] * lmbda / m

    return np.hstack((delta1.ravel(order='F'), delta2.ravel(order='F')))

def gradient_check(nn_initial_params, nn_backprop_params, hidden_layer_size, X, y_d, lmbda):
    myeps = 0.0001
    flattened = nn_initial_params
    flattenedDs = nn_backprop_params
    n_elems = len(flattened)
    # Pick ten random elements, compute numerical gradient, compare to respective D's
    for i in range(10):
        x = int(np.random.rand()*n_elems)
        epsvec = np.zeros((n_elems, 1))
        epsvec[x] = myeps

        cost_high = cost_func(flattened + epsvec.flatten(), hidden_layer_size, X, y_d, lmbda)
        cost_low = cost_func(flattened - epsvec.flatten(), hidden_layer_size, X, y_d, lmbda)
        mygrad = (cost_high - cost_low) / float(2*myeps)
        print("Element: {0}. Numerical Gradient = {1:.9f}. BackProp Gradient = {2:.9f}."
              .format(x, mygrad, flattenedDs[x]))

if __name__ == '__main__':
    # 1
    file_path = os.path.join(os.path.dirname(__file__), 'data', 'ex4data1.mat')
    data = sio.loadmat(file_path)
    y = data.get('y')
    X = data.get('X')

    # 2
    file_path = os.path.join(os.path.dirname(__file__), 'data', 'ex4weights.mat')
    weights = sio.loadmat(file_path)

    theta1 = weights.get('Theta1')
    theta2 = weights.get('Theta2')

    nn_params = np.hstack((theta1.ravel(order='F'), theta2.ravel(order='F')))  # unroll parameters
    # neural network hyperparameters
    hidden_layer_size = len(theta2[0]) - 1
    lmbda = 1
    print("hidden_layer_size: ", hidden_layer_size)

    # 3
    print("Sigmoid with x=2:", sigmoid(2), "Approximately: 0.88")
    pred = h0x(X, [theta1, theta2])

    # 4
    pred = np.argmax(pred, axis=1) + 1
    predictions = 0
    for i in range(len(pred)):
        if pred[i] == y[i][0]:
            predictions += 1
    print("Accuracy: ", predictions / len(y) * 100)
    # 95.12 (log) vs 97.52 (nn)

    # 5
    #        1   2   3   4   5   6   7   8   9   10
    # 0      0   0   0   0   0   0   0   0   0   1
    # 1      0   0   0   0   0   0   0   0   0   1
    # 2      0   0   0   0   0   0   0   0   0   1
    y_one_hot = pd.get_dummies(y.flatten())

    # 6
    cost = cost_func(nn_params, hidden_layer_size, X, y_one_hot, 0)
    print("Cost:", cost, "Approximately: 0.287629")

    # 7
    cost = cost_func(nn_params, hidden_layer_size, X, y_one_hot, lmbda)
    print("Cost:", cost, "Approximately: 0.383770")

    # 8
    print("::Sigmoid derivative:: ", "Approximately: sg(2) = 0.1", sigmoid_derivative(2))

    # 9
    input_layer_size = len(X[0])  # 400
    num_labels = len(y_one_hot.values[0])  # 10
    initial_Theta1 = rand_weights(input_layer_size, hidden_layer_size)
    initial_Theta2 = rand_weights(hidden_layer_size, num_labels)
    initial_nn_params = np.append(initial_Theta1.flatten(), initial_Theta2.flatten())

    # 10
    backprop_params = back_propagation(initial_nn_params, hidden_layer_size, X, y_one_hot, 0)

    # 11
    gradient_check(initial_nn_params, backprop_params, hidden_layer_size, X, y_one_hot, 0)

    # 12-13
    print("L2 regularization: with lambda = 1")
    backprop_params = back_propagation(initial_nn_params, hidden_layer_size, X, y_one_hot, lmbda)
    gradient_check(initial_nn_params, backprop_params, hidden_layer_size, X, y_one_hot, lmbda)

    # 14
    theta_opt = opt.fmin_cg(maxiter=30, f=cost_func, x0=initial_nn_params, fprime=back_propagation,
                            args=(hidden_layer_size, X, y_one_hot, lmbda))
    print(theta_opt)
    theta1_opt = np.reshape(theta_opt[:hidden_layer_size*(input_layer_size+1)], (hidden_layer_size, input_layer_size+1), 'F')
    theta2_opt = np.reshape(theta_opt[hidden_layer_size*(input_layer_size+1):], (num_labels, hidden_layer_size+1), 'F')

    # 15
    pred = h0x(X, [theta1_opt, theta2_opt])
    pred = np.argmax(pred, axis=1) + 1
    predictions = 0
    for i in range(len(pred)):
        if pred[i] == y[i][0]:
            predictions += 1
    print("Accuracy: ", predictions / len(y) * 100)

    # 16
    visualize(theta1_opt[:, 1:])

    # 17
    print("Optimal theta searching...")
    # TODO: implement the rest part
    lambda_values = [0, 0.0001, 0.001, 0.002, 0.005, 0.01, 0.1, 0.2, 0.5]
    val_err = []
    accur = []
    for lamb in lambda_values:
        theta_opt = opt.fmin_cg(maxiter=30, f=cost_func, x0=initial_nn_params, fprime=back_propagation,
                                args=(hidden_layer_size, X, y_one_hot, lamb))
        val_err.append(cost_func(theta_opt, hidden_layer_size, X, y_one_hot, 0))
        theta1_opt = np.reshape(theta_opt[:hidden_layer_size*(input_layer_size+1)], (hidden_layer_size, input_layer_size+1), 'F')
        theta2_opt = np.reshape(theta_opt[hidden_layer_size*(input_layer_size+1):], (num_labels, hidden_layer_size+1), 'F')

        pred = h0x(X, [theta1_opt, theta2_opt])
        pred = np.argmax(pred, axis=1) + 1
        predictions = 0
        for i in range(len(pred)):
            if pred[i] == y[i][0]:
                predictions += 1
        accur.append(predictions / len(y) * 100)
    plt.plot(lambda_values, val_err, c="b", linewidth=2)
    plt.axis([0, 0.5, 0.4, 0.6])
    plt.grid()
    plt.xlabel("lambda", fontsize=14)
    plt.ylabel("error", fontsize=14)
    plt.title("Validation Curve", fontsize=16)
    plt.show()

    plt.plot(lambda_values, accur, c="b", linewidth=2)
    plt.axis([0, 0.5, 90, 100])
    plt.grid()
    plt.xlabel("lambda", fontsize=14)
    plt.ylabel("accurcy", fontsize=14)
    plt.title("Validation Curve", fontsize=16)
    plt.show()

    theta_opt = opt.fmin_cg(maxiter=30, f=cost_func, x0=initial_nn_params, fprime=back_propagation,
                            args=(hidden_layer_size, X, y_one_hot, 0.1))
    theta1_opt = np.reshape(theta_opt[:hidden_layer_size*(input_layer_size+1)], (hidden_layer_size, input_layer_size+1), 'F')
    visualize(theta1_opt[:, 1:])

    theta_opt = opt.fmin_cg(maxiter=30, f=cost_func, x0=initial_nn_params, fprime=back_propagation,
                            args=(hidden_layer_size, X, y_one_hot, 100))
    theta1_opt = np.reshape(theta_opt[:hidden_layer_size*(input_layer_size+1)], (hidden_layer_size, input_layer_size+1), 'F')
    visualize(theta1_opt[:, 1:])


# -*- coding: utf-8 -*-
"""
Created on Sat May 27 23:10:03 2017

@author: L
"""
import tensorflow as tf
import numpy as np
import pandas as pd
from data_util import *
import sys
import os
from sklearn.decomposition import PCA
#时间平移
from pandas.tseries.offsets import DateOffset
from pandas.tseries.offsets import Week
from pandas.tseries.offsets import Day
from pandas.tseries.offsets import Minute

import matplotlib.pyplot as plt
import json
import pickle

from arima_bp import bp_net
from rbf_test import rbf_net
from time_series_analysis_p1 import *
from time_series_analysis_p2 import *
from gbdt import *

train_f = r'../train/'
arima_path = r'../arima/'

def bp_pca(_x):
    pca = PCA(n_components=10)
    pca.fit(_x)
    print(pca.explained_variance_ratio_)
    return pca.transform(_x)

def load(fdir='time_union.csv',start='10/8/2016 06:00',freq='T',normalize = False,pat = False,periods=72,days=7):
    return gen_df(fdir=fdir,start=start,normalize = normalize,pat = pat,periods=periods,days=days)

def train(GLOBAL,start='10/8/2016 06:00',freq = '20Min',p=4,q=4,days=7,periods=12,this=''):
    '''
    主要的内容是:数据按照时间分割,送入ARIMA训练,得到结果1
	      整合结果1,送入BPNN训练,得到训练好的网络
         输出:每个tollgate一个模型
    '''
    df,train_seq = load(start=start,freq=freq,normalize = False,periods=periods,days=days,pat=True)

    df.loc[:,'day'] = df['time_window_s'].dt.dayofyear
    inter = df.groupby('intersection_id')
    outputlist = []
    for t,tgroup in inter:
        ds = tgroup.groupby('tollgate_id')
        for d,dgroup in ds:
            group = dgroup.set_index('time_window_s')[['travel_time']]
#            data_check()

            print('time seq',train_seq[0],train_seq[-1])
#            sys.exit()
            day = train_seq.day[0]
            hour = train_seq.hour[0]
            ts = group.loc[train_seq,:]
            param = ''.join([this,str(t),str(d),str(hour)])
            while np.any(pd.isnull(ts)):
                print(param,'train nan')
                print(ts[pd.isnull(ts)])
                sys.exit()
            print(param,'ARIMA模型,训练X天的数据,默认时间序列周期为一天,通过建立模型,保存模型')

            ts['travel_time'] = modification(ts['travel_time'],method=3,show=False)
#            sys.exit()
#

            ####以下为各个模型训练部分

            model = ARIMA_V1(name=param)
            model.build(maxar=p,maxma=q,maxdiff=6,test_size=6,save_path=arima_path)
            pred = model.train(ts)
            GLOBAL[param] = str(model.diffn)
            model.save_model()

            #还原
            ts.loc[:,'pred'] = pred
            plot_compare(ts['travel_time'],ts['pred'],0)
            ts.loc[:,'tollgate_id'] = d
            ts.loc[:,'intersection_id'] = t
            ts.index.name = 'time_window_s'
            outputlist.append(ts)
#        sys.exit(0)
    output = pd.concat(outputlist)
    output.to_csv('output1.csv')
    df = df.set_index(['intersection_id','tollgate_id','time_window_s'])
    df = df.join(output.reset_index().set_index(['intersection_id','tollgate_id','time_window_s'])[['pred']])
    df.to_csv('total_arima_bp_log1.csv',index = True)
    return GLOBAL,df
#        sys.exit(0)

def arima_pred(GLOBAL,start='10/18/2016 06:00',freq = '20Min',periods=6,days=7,this=''):
    '''
    '''
#    sys.exit()
    pred2hour=[]
    pred4hour=[]
    df,train_seq = load(start=start,freq=freq,normalize = False,periods=12,days=days)
    _,seq = load(start=start,freq=freq,normalize = False,periods=6,pat=False,days=days)
    seq = seq + Hour(2)
    df.loc[:,'day'] = df['time_window_s'].dt.dayofyear
    print(df.head())
    tolls = df.groupby('intersection_id')
    for t,tgroup in tolls:
        ds = tgroup.groupby('tollgate_id')
        for d,dgroup in ds:
            group = dgroup.set_index('time_window_s')
            ts = group.loc[train_seq,:]
            hour = train_seq.hour[0]
            param = ''.join([this,str(t),str(d),str(hour)])
            diffn = GLOBAL[param]

            model = ARIMA_V1(name=param)
            model.build(save_path=arima_path)
            model.diffn = diffn
            pred = model.predict(load=True,step=len(ts))

            print(len(train_seq))
            print(len(pred))
            print(len(ts))
            df = predict_recover(pred,ts['travel_time'],0)
#            print(df)
            temp = pd.Series(data=df['Series'].values,index=ts.index)
            ts.loc[:,'pred'] = temp
            ts.loc[:,'intersection_id'] = t
            ts.loc[:,'tollgate_id'] = d
            ts.loc[:,'time_window_e'] = ts.index + Minute(20)
            ts.index.name = 'time_window_s'
#            plot_compare(ts['volume'],ts['pred'],0)
            print(ts.loc[seq,:].head(12))
#            sys.exit()
            pred4hour.append(ts)
            pred2hour.append(ts.loc[seq,:])

    return pd.concat(pred4hour),pd.concat(pred2hour)

def bp_tt(start='10/18/2016 06:00',test_size=12,freq='20Min',periods=12,
          days=7,predict=False,test=False,train=False,this='',bp_train_iter=1000):

    outputlist = []

    _,train_seq = load(start=start,freq=freq,normalize = False,periods=periods,days=days,pat=True)
    if test:
        df = pd.read_csv(r'time_final_bp.csv')
    else:
        df = pd.read_csv(r'time_total.csv')
    df.loc[:,'time_window_s']=pd.to_datetime(df['time_window_s'],format=r'%Y/%m/%d %H:%M:%S')
#    df.loc[:,'residual'] = np.log(df['travel_time'])-np.log(df['pred'])

    hour = train_seq.hour[0]#param
    if predict:
        train_seq = train_seq + Hour(2)
#    df.to_csv(r'bp.csv',index=False)
    df = df[pd.notnull(df['pred'])]
    inter = df.groupby('intersection_id')
    for t,tgroup in inter:
        ds = tgroup.groupby('tollgate_id')
        for d,dgroup in ds:
            batch_x = dgroup.set_index('time_window_s').loc[train_seq,:]
#            print(batch_x['travel_time'])
            batch_x['travel_time'] = modification(batch_x['travel_time'],method=3,show=False)
            batch_x.loc[:,'residual'] = np.log(batch_x['travel_time'])-np.log(batch_x['pred'])
            while np.any(pd.isnull(batch_x)):
                print('nan found ',t,'',d)
                print(batch_x.head())
                batch_x = batch_x.bfill()
                batch_x = batch_x.ffill()
#                print(batch_x.head())
#                sys.exit()
            columns = ['Friday','Monday','Saturday','Sunday','Thursday','Tuesday','Wednesday','midnight','morning',\
            'noon','afternoon','evening','w0','w20','w40','000','100','102','103','104','105','107','108','109','110',\
            '111','112','115','116','119','120','122','123','out_link_cross_count','in_link_cross_conut','length',\
            'link_count','1_length','2_length','3_length','4_length','pressure','sea_pressure','wind_direction',\
            'wind_speed','temperature','rel_humidity','precipitation','pattern']
#            print(batch_x.dtypes)
#            print(batch_x[columns])

            x_data = bp_pca(np.array(batch_x[columns]))
#    x_data = np.array(batch_x[['pressure','sea_pressure','wind_direction','wind_speed',
#                                'temperature','rel_humidity','precipitation',
#                                'dayofweek','hour','minute','direction','pattern']])

            y_data = np.array(batch_x.loc[:,'residual'])#修改为残差
            y_data = y_data.reshape((len(y_data),1))

            train_size = len(x_data)-int(test_size)
            X=x_data[:train_size]
            Y=y_data[:train_size]
            Xtest=x_data[train_size:]
            Ytest=y_data[train_size:]

            if train:
                #begin bp train
                bp = bp_net()
                N,D = x_data.shape
                K = len(y_data[0])
                bp.middle = 60
                bp.modelname = ''.join([this,str(t),str(d),str(hour)])
                bp.training_iters = bp_train_iter
                bp.build(D,K)
                bp.fit(X,Y,Xtest,Ytest)
            #    print(train_seq)
                print('train',X.shape,Y.shape)
                print('train seq ',train_seq[0],train_seq[-1])
            else:
                #begin bp test
                bp = bp_net()
                bp.modelname = ''.join([this,str(t),str(d),str(hour)])
                bp.training_iters = bp_train_iter
                pred = bp.predict(x_data)
                print(np.sum(pred,axis=0))
                print(np.sum(y_data,axis=0))
                #预测结束后
                print('pred length',len(pred))
                print('true length ',len(y_data))
                pred = pd.Series(data=np.array(pred).flatten(),index = train_seq)

#                pred = filter(pred)
                pred = modification(pred,3)

                plot_compare(batch_x['residual'],pred,0)
#                sys.exit()
                batch_x.loc[:,'residual'] = pred
                batch_x.loc[:,'bp'] = np.exp((batch_x['residual']+np.log(batch_x['pred'])))
                outputlist.append(batch_x)
    if len(outputlist)>0:
        print('ouputlist',len(outputlist))
        df = pd.concat(outputlist)
        df.index.name = 'time_window_s'
        return df

def gbdt_tt(start='10/18/2016 06:00',freq='20Min',days=7,periods=12,train=False,test=False,predict=False,this=''):

    outputlist=[]

    _,train_seq = load(start=start,freq=freq,normalize = False,periods=periods,days=days,pat=True)
    if test:
        df = pd.read_csv(r'time_final_bp.csv')
    else:
        df = pd.read_csv(r'time_total.csv')

    df.loc[:,'time_window_s']=pd.to_datetime(df['time_window_s'],format=r'%Y/%m/%d %H:%M:%S')
    df.loc[:,'residual'] = df['travel_time']-df['pred']
    df.loc[:,'residual'] = np.log(df['travel_time'])-np.log(df['pred'])

    hour = train_seq.hour[0]#param
    if predict:
        train_seq = train_seq + Hour(2)
#    df.to_csv(r'bp.csv',index=False)
    df = df[pd.notnull(df['pred'])]
    inter = df.groupby('intersection_id')
    for t,tgroup in inter:
        ds = tgroup.groupby('tollgate_id')
        for d,dgroup in ds:
            batch_x = dgroup.set_index('time_window_s').loc[train_seq,:]
            while np.any(pd.isnull(batch_x)):
                print('nan found ',t,'',d)
                print(batch_x[pd.isnull(batch_x)])
                batch_x = batch_x.bfill()
                batch_x = batch_x.ffill()

            batch_x['wind_direction'] = batch_x['wind_direction'].astype('category')
            batch_x['dayofweek'] = batch_x['dayofweek'].astype('category')
            batch_x['hour'] = batch_x['hour'].astype('category')
            batch_x['minute'] = batch_x['minute'].astype('category')
            batch_x['pattern'] = batch_x['pattern'].astype('category')

            feature = ['pressure','wind_direction','wind_speed',
                                'temperature','rel_humidity','precipitation',
                                'dayofweek','hour','minute','pattern']
            x_data = np.array(batch_x[feature])

#    x_data = np.array(batch_x[['pressure','sea_pressure','wind_direction','wind_speed',
#                                'temperature','rel_humidity','precipitation',
#                                'dayofweek','hour','minute','direction','pattern']])
            train_size = len(x_data)-12
            y_data = np.log(np.array(batch_x.loc[:,'travel_time']))#修改为残差
            y_data = y_data.reshape((len(y_data),1))

            if train:
                gbdt = kdd_gbdt()
                gbdt.save_name = ''.join([this,str(t),str(d),str(hour)])
                gbdt.train_times = 1

                best_params = gbdt.choose(x_data,y_data)
                print(best_params)
                gbdt.params = best_params
                gbdt.train(x_data,y_data)
                gbdt.save_model()
            else:
                gbdt = kdd_gbdt()
                gbdt.save_name = ''.join([this,str(t),str(d),str(hour)])
                gbdt.load_model()
                pred = gbdt.predict(x_data)
                print('pred length',len(pred))
                print('true length ',len(y_data))
                pred = pd.Series(data=np.array(pred).flatten(),index = train_seq)
                pred = modification(pred,method=3,show=True)
                batch_x.loc[:,'gbdt'] = np.exp(pred)
                outputlist.append(batch_x[['intersection_id','tollgate_id','travel_time','gbdt']])
    if len(outputlist)>0:
        print('ouputlist',len(outputlist))
        df = pd.concat(outputlist)
        df.index.name = 'time_window_s'
        return df

def evalute(df,start='10/18/2016 06:00',freq = '20Min',predict=False,days=7):
    '''
    主要的内容是:数据按照时间分割,送入ARIMA训练,得到结果1
	      整合结果1,送入BPNN训练,得到训练好的网络
         输出:每个tollgate一个模型
    '''

    bp_result = []
    arima_result=[]

    origin,train_seq = load(start=start,freq=freq,normalize = False,periods=6,days=days)
    if predict:
        train_seq = train_seq + Hour(2)
    #生成这个时间段上的前1天序列
    plot_seq = pd.date_range(start=train_seq[0]-Day(1)-Hour(2),freq=freq,periods=12)
    plot_seq = plot_seq + train_seq
    inter = df.groupby('intersection_id')
    for t,tgroup in inter:
        ds = tgroup.groupby('tollgate_id')
        for d,dgroup in ds:
            #计算MAPE
            import MAPE
            group = dgroup.set_index('time_window_s')[['travel_time','bp']].loc[train_seq,:]
            plot_group = origin[(origin['intersection_id']==t) & (origin['tollgate_id']==d)]
            plot_group = plot_group.set_index('time_window_s')[['travel_time']].loc[plot_seq,:]
            plot_group.loc[:,'bp'] = group['bp']
            bp_result.append(MAPE.mape(group))
            #plot
#            print(plot_group)
#            sys.exit()
            plot_compare(plot_group['travel_time'],plot_group['bp'],0)

    result = np.sum(bp_result)/len(bp_result)
    print('final',result)
    result = np.sum(arima_result)/len(arima_result)
    print('arima',result)
    return result

def bp_modification(df,start='10/18/2016 06:00',freq = '20Min',predict=False,days=7,method=2):
    '''
     数据修正
    '''
    modifyed = []
    origin,train_seq = load(start=start,freq=freq,normalize = False,periods=6,days=days)
    if predict:
        train_seq = train_seq + Hour(2)
    #生成这个时间段上的前1天序列
    plot_seq = pd.date_range(start=train_seq[0]-Day(1)-Hour(2),freq=freq,periods=12)
    plot_seq = plot_seq + train_seq
    inter = df.groupby('intersection_id')
    for t,tgroup in inter:
        ds = tgroup.groupby('tollgate_id')
        for d,dgroup in ds:
            group = dgroup.set_index('time_window_s')[['travel_time','bp']].loc[train_seq,:]

            #这里可以添加一个权值处理,即线性回归
            print(group)
#            group.loc[:,'bp'] = 0.4*group.loc[:,'bp'] + 0.6*group.loc[:,'pred']
            print(group['bp'])
#            sys.exit()
#            if t=='B' and d == 1:
#                print(group)
            ts = modification(group['bp'],method=method)
            if ts.sum() < 10:
                print(group)
                sys.exit()
            group.loc[:,'bp'] = ts
            group.loc[:,'intersection_id'] = t
            group.loc[:,'tollgate_id'] = d
            modifyed.append(group)
    return pd.concat(modifyed)

def linear_reg(fdir = r'bp_test_result.csv',feature = ['pred','bp','gbdt'],predict=False):
    df = load_volume(fdir)
    print('线性回归 travel_time pred bp 这三列')
    feature = feature
    X = df[feature]
    y = df['travel_time']
    from sklearn.cross_validation import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
    from sklearn.linear_model import LinearRegression
    linreg = LinearRegression()
    linreg.fit(X_train, y_train)
    print(linreg.intercept_)
    print(linreg.coef_)
    print(zip(feature, linreg.coef_))
    y_pred = linreg.predict(X_test)
    from sklearn import metrics
    print( "MAE:",metrics.mean_absolute_error(y_test, y_pred))
    param = dict(zip(feature, linreg.coef_))
    return df,param

def cache(config,fdir='global_config.txt',this=''):
    if len(config)>0:
        f = open(''.join([this,fdir]),'w')
        json.dump(config,f)
        f.close()
        return config
    else:
        f = open(''.join([this,fdir]),'r')
        config = json.load(f)
        f.close()
        return config
def final_agg(fdir=r'time_final.csv'):
    df = pd.read_csv(fdir)
    df.loc[:,'time_window'] = '[' + df['time_window_s'] +','+ df['time_window_e'] +')'
    df.loc[:,'travel_time'] = df.loc[:,'pred']
    df = df[['intersection_id','tollgate_id','time_window','travel_time']]
    df.columns = ['intersection_id','tollgate_id','time_window','avg_travel_time']
    if len(df) != 504:
        print(len(df))
        df.to_csv('temp.csv')
        sys.exit()
    df.to_csv(r'..result/arima_time.csv',index=False)

def bp_final_agg(fdir=r'bp_test_result.csv',this=''):
    df = load_volume(fdir)
    df.loc[:,'time_window_e'] = df.time_window_s + Minute(20)
    df.to_csv(fdir,index = False)
    df =  pd.read_csv(fdir)
    df.loc[:,'time_window'] = '[' + df['time_window_s'] +','+ df['time_window_e'] +')'
    df.loc[:,'travel_time'] = df.loc[:,'bp']
    df = df[['intersection_id','tollgate_id','time_window','travel_time']]
    df.columns = ['intersection_id','tollgate_id','time_window','avg_travel_time']
    df.to_csv(''.join([r'..result/',this,'bp_submit_time.csv']),index=False)

#
#GLOBAL = {}
#train_f = r'../train/'
#arima_path = r'../arima/'
#this = 'time'
#bp_train_iter = 50000
#if __name__ == '__main__':
#    GLOBAL = cache(GLOBAL)
#    print(GLOBAL)
#    traints = ['10/8/2016 06:00','10/8/2016 15:00']
#    testts = ['10/25/2016 06:00','10/25/2016 15:00']
#    trainlist = []
#    testlist=[]
#    bp_list = []
#####    #arima train and test
#    for i in range(len(traints)):
#        GLOBAL,traindf = train(GLOBAL,start=traints[i],freq='20Min',days=17,periods=12)
#        pred4hour,pred2hour = arima_pred(GLOBAL,start=testts[i],freq='20Min',periods=12,days=7)
#        trainlist.append(traindf)
#        testlist.append(pred2hour)
#        bp_list.append(pred4hour)
#    df = pd.concat(testlist)
#    df.index.name = 'time_window_s'
#    df.to_csv(r'time_final.csv')#预测集结果
#    df = pd.concat(bp_list)
#    df.to_csv(r'time_final_bp.csv')#预测集4小时结果
#    df = pd.concat(trainlist)
#    df.to_csv(r'time_total.csv')#训练集预测结果
#    GLOBAL = cache(GLOBAL)
#    final_agg()
#
##    for i in range(len(traints)):
##        bp_tt(start=traints[i],days=17,train=True)
###
##    #GBDT训练
##    for i in range(len(traints)):
##        gbdt_tt(start=traints[i],days=17)
#
#    #####训练集BP修正
##    dflist = []
##    for i in range(len(traints)):
##        df = bp_tt(start=traints[i],predict=False,days=17)
##        dflist.append(df)
##    df = pd.concat(dflist)
##    df.to_csv(r'bp_result.csv')
##
##    ###GBDT 测试
###    dflist = []
###    for i in range(len(traints)):
###        df = bp_test(start=traints[i],predict=False,days=17)
###        dflist.append(df)
###    df = pd.concat(dflist)
###    df.to_csv(r'bp_result.csv')
##
##    ###使用model继续训练
##
##    ###evalute
##    df = load_volume(fdir=r'bp_result.csv')
##    df = df[pd.notnull(df['bp'])]
##    for i in range(len(traints)):
##        evalute(df,start=traints[i],predict=False,days=17)
##
###############################################################
##    '''
##        在测试集上，使用BP预训练模型测试
##        测试集BP修正
##    '''
#    predict = True
#    test = True
#    day = 7
#    reg = False
#    if test:
#        ll = testts
#    else:
#        ll = traints
#    dflist = []
#    for i in range(len(ll)):
#        df = bp_tt(start=ll[i],test=test,predict=predict,days=day)
#        dflist.append(df)
#    df = pd.concat(dflist)
#    df.to_csv(r'bp_test_result.csv')
#
#    ###GBDT 测试
#    dflist = []
#    for i in range(len(ll)):
#        gbdt = gbdt_tt(start=ll[i],train=False,test=test,predict=predict,days=day)
#        dflist.append(gbdt)
#    print(len(dflist))
#    gbdt = pd.concat(dflist)
#    gbdt.to_csv(r'gbdt_test_result.csv')
#
#    ##线性回归
#    df = df.reset_index().set_index(['intersection_id','tollgate_id','time_window_s'])
#    gbdt = gbdt.reset_index().set_index(['intersection_id','tollgate_id','time_window_s'])
#    df = df.join(gbdt[['gbdt']])
#    df.to_csv('bp_gbdt.csv')
#    if reg:
#        feature = ['pred','bp','gbdt']
#        paramlist = linear_reg(fdir = r'bp_gbdt.csv',feature =feature,predict=predict)
#        print(paramlist)
#        print(paramlist['pred'])
#        print(paramlist['bp'])
#        print(paramlist['gbdt'])
#        print(df.dtypes)
#        df['bp']=paramlist['pred']*df.loc[:,'pred'] + paramlist['bp']*df.loc[:,'bp'] +paramlist['gbdt']*df.loc[:,'gbdt']
#        GLOBAL['linear'] = paramlist
#        GLOBAL = cache(GLOBAL)
#    else:
#        paramlist = GLOBAL['linear']
#        print(paramlist)
#        df['bp']=paramlist['pred']*df.loc[:,'pred'] + paramlist['bp']*df.loc[:,'bp'] +paramlist['gbdt']*df.loc[:,'gbdt']
#    df.to_csv(r'after_linear.csv')
#
#    modifyed = []
#    df = load_volume(fdir=r'after_linear.csv')
#    df = df[pd.notnull(df['bp'])]
#    for i in range(len(ll)):
#        df1 = bp_modification(df,start=ll[i],predict=predict,days=day,method=3)
#        modifyed.append(df1)
#    df = pd.concat(modifyed)
#    df.index.name = 'time_window_s'
#    df.to_csv(r'bp_modifyed.csv')
##
##
#    #evalute
#    df = load_volume(fdir=r'bp_modifyed.csv')
#    df = df[pd.notnull(df['bp'])]
#    for i in range(len(testts)):
#        evalute(df,start=testts[i],predict=predict,days=7)
##
##
#    bp_final_agg(fdir=r'bp_modifyed.csv')
##
#
#
#
#    '''
#    输入点为当前时间t
#    输出为需要预测的时间t+T
#
#    所以预测8：20的流量 ，需要将时间点设置为8:00
#
#    '''


from sphinx.errors import SphinxError

import lib.yaml_writer as yaml_writer

# Following keys may be given a default in base (first) language
# and other language versions are allowed to omit them.

ACCEPTED_INDEX_DEFAULT_KEYS = [
    'description', 'contact', 'contact_phone', 'assistants',
    'start', 'end', 'static_dir', 'numerate_ignoring_modules',
    'module_types', 'exercise_types',
]
ACCEPTED_CATEGORY_DEFAULT_KEYS = [
    'status', 'points_to_pass',
]
ACCEPTED_MODULE_DEFAULT_KEYS = [
    'status', 'type', 'points_to_pass',
    'open', 'close', 'duration', 'late_close', 'late_duration', 'late_penalty',
]
ACCEPTED_CHILDREN_DEFAULT_KEYS = [
    'status', 'type', 'category', 'config', 'static_content',
    'max_submissions', 'max_points', 'points_to_pass',
    'min_group_size', 'max_group_size',
    'allow_assistant_viewing', 'allow_assistant_grading',
    'use_wide_column', 'generate_table_of_contents',
]
IDENTICAL_EXERCISE_KEYS = [
    'category', 'max_points', 'difficulty', 'max_submissions',
    'min_group_size', 'max_group_size', 'points_to_pass', 'feedback',
]
# Internal keys that may be joined in the |i18n format. Internal keys are only
# used inside the a-plus-rst-tools to pass information forward.
INTERNAL_KEYS_TO_JOIN = ['_rst_srcpath']

def join(app, indexes):
    base_lang,base = indexes[0]
    if len(indexes) < 2:
        return base
    joiner = IndexJoiner(app, base_lang, base)
    for lang,index in indexes[1:]:
        joiner.join(lang, index)
    return joiner.get_joined()

class IndexJoiner:

    def __init__(self, app, base_lang, base):
        self.app = app
        self.base_lang = base_lang
        self.joined = base
        self.joined['language'] = [base_lang]
        self.errors = 0
        self.skip_errors = app.config.skip_language_inconsistencies

    def get_joined(self):
        if self.errors > 0:
            msg = "Language versions have previously reported {:d} inconsistencies!".format(self.errors)
            if self.app.config.skip_language_inconsistencies:
                self.app.warn(msg + (
                    " The 'skip_language_inconsistencies' option is set and"
                    " therefore incomplete version of the course is compiled."
                    " This setting should only be used in development phase!"
                ))
            else:
                raise SphinxError(msg + " Fix the problems to compile the course.")
        return self.joined

    def join(self, lang2, index2):
        lang1 = self.base_lang
        index1 = self.joined
        path = []
        index = {}
        self.require_identical_dict_keys(path, lang1, index1, lang2, index2, ACCEPTED_INDEX_DEFAULT_KEYS)
        for k,v in index1.items():
            if k == 'language':
                index[k] = v + [lang2]
            elif k == 'name':
                index[k] = join_values(lang1, v, lang2, index2.get(k, v))
            elif k == 'categories':
                p = path + ['categories']
                index[k] = self.join_categories(p, lang1, v, lang2, index2.get(k, {}))
            elif k == 'modules':
                p = path + ['modules']
                index[k] = self.join_modules(p, lang1, v, lang2, index2.get(k, []))
            elif deep_equals(v, index2.get(k, v)):
                index[k] = v
            else:
                self.raise_unequal(path, lang2, k)
        self.joined = index

    def join_categories(self, path, lang1, c1_map, lang2, c2_map):
        c_map = {}
        self.require_identical_dict_keys(path, lang1, c1_map, lang2, c2_map)
        for n,c1 in c1_map.items():
            c2 = c2_map.get(n, {})
            c_path = path + [n]
            c = {}
            self.require_identical_dict_keys(c_path, lang1, c1, lang2, c2, ACCEPTED_CATEGORY_DEFAULT_KEYS)
            for k,v in c1.items():
                if k == 'name':
                    c[k] = join_values(lang1, v, lang2, c2.get(k, v))
                elif deep_equals(v, c2.get(k, v)):
                    c[k] = v
                else:
                    self.raise_unequal(c_path, lang2, k)
            c_map[n] = c
        return c_map

    def join_modules(self, path, lang1, m1_list, lang2, m2_list):
        m_list = []
        for i,m1 in enumerate(
            self.require_identical_list_len(path, lang1, m1_list, lang2, m2_list)
        ):
            m2 = m2_list[i]
            m_path = path + [str(i + 1)]
            m = {}
            self.require_identical_dict_keys(m_path, lang1, m1, lang2, m2, ACCEPTED_MODULE_DEFAULT_KEYS)
            for k,v in m1.items():
                if k == 'key':
                    m[k] = join_keys(lang1, v, lang2, m2.get(k, v))
                elif k in ('name', 'title'):
                    m[k] = join_values(lang1, v, lang2, m2.get(k, v))
                elif k == 'children':
                    m[k] = self.join_children(m_path, lang1, v, lang2, m2.get(k, []))
                elif deep_equals(v, m2.get(k, v)):
                    m[k] = v
                else:
                    self.raise_unequal(m_path, lang2, k)
            m_list.append(m)
        return m_list

    def join_children(self, path, lang1, c1_list, lang2, c2_list):
        c_list = []
        for i,c1 in enumerate(
            self.require_identical_list_len(path, lang1, c1_list, lang2, c2_list)
        ):
            c2 = c2_list[i]
            c_path = path + [str(i + 1)]
            c = {}
            self.require_identical_dict_keys(c_path, lang1, c1, lang2, c2, ACCEPTED_CHILDREN_DEFAULT_KEYS)
            key = join_keys(lang1, c1.get('key', ''), lang2, c2.get('key', ''))
            for k,v in c1.items():
                if k == 'key':
                    c[k] = key
                elif k in ('name', 'title', 'static_content'):
                    c[k] = join_values(lang1, v, lang2, c2.get(k, v))
                elif k == 'config':
                    e1 = yaml_writer.read(yaml_writer.file_path(self.app.env, v))
                    e2 = yaml_writer.read(yaml_writer.file_path(self.app.env, c2.get(k, v)))
                    yaml_writer.write(
                        yaml_writer.file_path(self.app.env, key),
                        self.join_exercises(key, lang1, e1, lang2, e2)
                    )
                    c[k] = key + '.yaml'
                elif k == 'children':
                    c[k] = self.join_children(c_path, lang1, v, lang2, c2.get(k, []))
                elif k in INTERNAL_KEYS_TO_JOIN:
                    c[k + '|i18n'] = join_values(lang1, v, lang2, c2.get(k, v))
                elif deep_equals(v, c2.get(k, v)):
                    c[k] = v
                else:
                    self.raise_unequal(c_path, lang2, k)
            c_list.append(c)
        return c_list

    def join_exercises(self, key, lang1, c1, lang2, c2):
        path = [key]
        c = {}
        for k,v in c1.items():
            if k == 'key':
                c[k] = key
            elif k == 'url':
                override = self.app.env.config.override.get(c1.get('category'), {})
                if k in override:
                    c[k] = override[k].format(key=key)
                elif v != c2.get(k, v):
                    self.raise_unequal(path, lang2, k)
                else:
                    c[k] = v
            elif k in IDENTICAL_EXERCISE_KEYS:
                if v != c2.get(k, v):
                    self.raise_unequal(path, lang2, k)
                c[k] = v
            else:
                self.join_exercise_values(path, k, c, lang1, c1, lang2, c2)
        return c

    def join_exercise_values(self, path, k, d, lang1, d1, lang2, d2):
        v1 = d1[k]
        if k.endswith('|i18n'):
            v2 = d2.get(k, d2.get(k[:-5]))
            if v2 is None:
                d[k] = v1
            else:
                d[k] = join_values(lang1, v1, lang2, v2)
        else:
            v2 = d2.get(k)
            if has_identical_dict_keys(v1, v2):
                dd = {}
                for kk in v1.keys():
                    self.join_exercise_values(path + [k], kk, dd, lang1, v1, lang2, v2)
                d[k] = dd
            elif has_identical_len_and_dict_keys(v1, v2):
                ll = []
                for i,vv in enumerate(v1):
                    dd = {}
                    pp = path + [k, str(i + 1)]
                    for kk in vv.keys():
                        self.join_exercise_values(pp, kk, dd, lang1, vv, lang2, v2[i])
                    ll.append(dd)
                d[k] = ll
            else:
                if v2 is None or deep_equals(v1, v2):
                    d[k] = v1
                else:
                    d[k + '|i18n'] = join_values(lang1, v1, lang2, v2)

    def require_identical_dict_keys(self, path, lang1, d1, lang2, d2, defaults=None):
        d1d2 = set(d1.keys()) - set(d2.keys()) - set(defaults or [])
        if len(d1d2) > 0:
            self.raise_error('Missing {:d} fields at {} in {}: {}'.format(
                len(d1d2),
                path_names(path, d1d2),
                lang2,
                ', '.join(d1d2)
            ))
        d2d1 = set(d2.keys()) - set(d1.keys())
        if len(d2d1) > 0:
            self.raise_error('Surplus {:d} fields at {} in {}: {}'.format(
                len(d2d1),
                path_names(path, d2d1),
                lang2,
                ', '.join(d2d1)
            ))
        return d1.items()

    def require_identical_list_len(self, path, lang1, l1, lang2, l2):
        d = len(l2) - len(l1)
        if d > 0:
            self.raise_error('Surplus {:d} elements at {} in {}: {}'.format(
                d,
                path_names(path),
                lang2,
                key_names(l2[-d:])
            ))
            return l1
        if d < 0:
            self.raise_error('Missing {:d} elements at {} in {}: {}'.format(
                -d,
                path_names(path),
                lang2,
                key_names(l1[d:])
            ))
            return  l1[:d]
        return l1

    def raise_unequal(self, path, lang, key):
        self.raise_error('Unequal field not accepted in {}: {}'.format(
            lang,
            path_names(path, key)
        ))

    def raise_error(self, msg):
        self.app.warn(msg)
        self.errors += 1

def path_names(path, fields=None):
    if not fields:
        return '.'.join(path)
    if type(fields) not in (list, set):
        fields = [fields]
    return ' '.join('.'.join(path + [f]) for f in fields)

def key_names(elements):
    return ', '.join(str(e.get('key', '[missing key]')) for e in elements)

def join_keys(lang1, key1, lang2, key2):
    if key1 == key2 or key2 == '':
        return key1
    SEP = ('_', '-')
    k = ""
    l2 = len(key2)
    for i,c in enumerate(key1):
        if i < l2 and c == key2[i]:
            if not c in SEP or k == "" or k[-1] != c:
                k += c
    if not k or k in SEP:
        raise SphinxError(
            "Corresponding RST file names must match in multilingual courses:\n"
            + key1 + "\n" + key2)
    if k[-1] in SEP:
        k = k[:-1]
    if k[0] in SEP:
        k = k[1:]
    return k

def join_values(lang1, val1, lang2, val2):
    if type(val1) == dict and lang1 in val1:
        if type(val2) == dict and lang2 in val2:
            val1[lang2] = val2[lang2]
        else:
            val1[lang2] = val2
        return val1
    if val1 == val2:
        return val1
    return {
        lang1: val1,
        lang2: val2
    }

def has_identical_dict_keys(d1, d2):
    return (
        type(d1) == type(d2) == dict
        and len(set(d1.keys()) ^ set(d2.keys())) == 0
    )

def has_identical_len_and_dict_keys(l1, l2):
    if (
        not (type(l1) == type(l2) == list)
        or len(l1) != len(l2)
    ):
        return False
    for i,d1 in enumerate(l1):
        if not has_identical_dict_keys(d1, l2[i]):
            return False
    return True

def deep_equals(a, b):
    ta = type(a)
    tb = type(b)

    if ta == dict and tb == dict:
        if len(set(a.keys()) ^ set(b.keys())) > 0:
            return False
        for k,v in a.items():
            if not deep_equals(v, b[k]):
                return False

    elif ta == list and tb == list:
        if len(a) != len(b):
            return False
        for i,v in enumerate(a):
            if not deep_equals(v, b[i]):
                return False

    elif a != b:
        return False

    return True


from models import MaterialBody
from models import MaterialPoint
from models import Space_mesh
from models import Space_point
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
import numpy as np
#Эйлеров подход
# Получим поле скоростей
def get_velfield (x11,x12,x21,x22,meshpoints,t):
    Mesh = Space_mesh(x11,x12,x21,x22,meshpoints)
    Points_space = []
    X1 = []
    X2 = []
    x1 = x11
    x2 = x21
    for i in range (0,meshpoints):
        X1.append(x1)
        x1 = x1 + abs((x11 - x12)/meshpoints)
        X2.append(x2)
        x2 = x2 + abs((x21 - x22) / meshpoints)
    print (X1,X2)

    def f1(x,t):
        f = -x * t**2
        return f

    def f2(x,t):
        f = -x**3*t
        return f
    for i in range (0,len(X1)):
        for j in range (0,len(X1)):
            P = Space_point(X1[i],X2[j],f1(X1[i],t),f2(X2[j],t))
            Points_space.append(P)
    return Points_space, Mesh

# Движение сковозь пространство
def Move_through_space():
    # функции для скорости
    def f1(x,t):
        f = -x * t**2
        return f

    def f2(x,t):
        try:
            f = -x**3*t
        except Exception:
            f = 0*x*t
        return f

    # параметры сетки
    x11 = -10
    x12 = 0
    x21 = 0
    x22 = 10
    meshpoints = 10
    steps = 100
    lines = 10
    tfl = 1.5
# количество временных точе
    ntp = 3
    plt.figure()
    # постороим линии тока
    for h in range (1,2*ntp + 1,2):
        t =  (tfl)/ntp*h
        SP, Mesh = get_velfield(x11, x12, x21, x22,meshpoints, t)
        L1 = {}
        L2 = {}

        for j in range(0, lines):
            X1l = []
            X2l = []
            x1 = x11
            x2 = x21 + abs(x22 - x21) / lines * j
            for i in range(0, steps):
                X1l.append(x1)
                X2l.append(x2)

                x2 += f2(x2, t) / f1(x1, t)*abs(x12 - x11) / steps
                x1 += abs(x12 - x11) / steps
                # print (x2)
            L1.update({'L1+' + str(j): X1l})
            L2.update({'L1+' + str(j): X2l})
        n1 = []
        n2 = []
        x1 = x11
        x2 = x21
        for i in range(0, meshpoints):
            n1.append(x1)
            x1 = x1 + abs((x11 - x12) / meshpoints)
            n2.append(x2)
            x2 = x2 + abs((x21 - x21) / meshpoints)

        plt.subplot(2, ntp, h,aspect = 'equal')
        plt.title('t = ' + str(t))
        plt.ylim(ymin=0, ymax=10, auto=False)
        plt.xlim(xmin=-10, xmax=0, auto=False)
        # посторим поле скоростей
        for i in SP:
            print (i.x2)
            plt.quiver(i.x1, i.x2,i.v1,i.v2, color='black')

            x, y = np.meshgrid(n1, n2)

        plt.plot(x, y)

        segs1 = np.stack((x, y), axis=2)
        segs2 = segs1.transpose(1, 0, 2)
        plt.gca().add_collection(LineCollection(segs1))
        plt.gca().add_collection(LineCollection(segs2))

        plt.subplot(2, ntp, h + 1,aspect = 'equal')
        plt.title('t = ' + str(t))
        for n in L1.keys():
            plt.ylim(ymin=0, ymax=10, auto=False)
            plt.xlim(xmin=-10, xmax=0, auto=False)
            plt.plot(L1[n], L2[n])

#Лагранжев подход
# Функция для интегратора

def integrator (steps,y0,x0,xf,f):
    step = (xf - x0)/steps
    Yd = {'y 0': y0}
    x = x0
    X = [x]
    for i in range (1,steps):
        x = x + step
        X.append(x)
        yn = Yd['y ' + str(i - 1)]
        y = yn + step*1/6*f(x)*yn
        y = y + step*4/6*f(x + 1/2*step)*(yn + 1/2*step*f(x)*f(x)*yn)
        y = y + step * 1 / 6 * f(x + step)*(yn -1*step*f(x)*(f(x + 1/2*step)*(yn + 1/2*step*f(x)*f(x)*yn)) + 2*step*f(x)*(f(x + 1/2*step)*(yn + 1/2*step*f(x)*f(x)*yn)))

        Yd.update({'y ' + str(i):y})
    Y = []
    for i in Yd.keys():
        Y.append(Yd[i])
    return Y,X
# Функция для получения траектории
def get_trajectory(steps,t0,tf,X1,X2):
    def f1(x):
        f =  -(x**2)
        return f
    def f2(x):
        f = -x**3
        return f

    x1,T = integrator(steps,X1,t0,tf,f1)
    x2,T = integrator(steps,X2,t0,tf,f2)
    x1f = x1[len(x1)-1]
    x2f = x1[len(x2)-1]
    v1 = f1(x1f)
    v2 = f2(x2f)
    return  x1,x2,v1,v2,x1f,x2f
# функция для создания тела
def create_body():
    def get_Materialpoints(points,C1,C2):
        def f1(x):
            f = -1.0* x**2
            return f
        def f2(x):
            f = x
            return f
        Points = []
        for prt in range(1, 3):
            for prt2 in range(1, 3):
                for i in range(0, points):
                    for j in range(0, points):
                        A1 = C1 + (-1)**prt * 2 / points * i
                        A2 = C2 + (-1)**(prt2) * 2 / points * j
                        if (A1 - C1) ** 2 + (A2 - C2) ** 2 <= 4 and (A1 - C1) ** 2 + (A2 - C2) ** 2 >= 3:
                            v2 = f2(A2)
                            v1 = f1(A2)
                            M = MaterialPoint(A1, A2, A1, A2,v1,v2,[],[])
                            Points.append(M)
            for prt in range(0, 2):
                for prt2 in range(0, 2):
                    for i in range(0, points):
                        for j in range(0, points):
                            A1 = C1 + (-1) ** prt * 2 / points * i
                            A2 = C2 + (-1) ** (prt2) * 2 / points * j
                            if (A1 - C1) ** 2 + (A2 - C2) ** 2 <= 4 and (A1 - C1) ** 2 + (A2 - C2) ** 2 >= 3:
                                v2 = f2(A2)
                                v1 = f1(A2)
                                M = MaterialPoint(A1, A2, A1, A2, v1, v2, [], [])
                                Points.append(M)

            return Points
    Body = MaterialBody( -2,2,10,get_Materialpoints(10,-2,2))

    return Body

# движение материального тела

def move_material_body (Body):
    def f1(x):
        f =  -1.0 * (x**2)
        return f
    def f2(x):
        f = x
        return f
    for i in Body.Points:
        T1, T2, x1, x2, v1, v2 = get_trajectory(100,0,2,i.X1,i.X2)
        i.x1 = x1
        i.x2 = x2
        i.v1 = v1
        i.v2 = v2
        i.T1 = T1
        i.T2 = T2

        OX1 = np.zeros(1000)
        OY1 = np.linspace(-10, 10, 1000)
        OY2 = np.zeros(1000)
        OX2 = np.linspace(-10, 10, 1000)
        plt.Figure(figsize=(2, 2))
        plt.ylim(ymin=-10, ymax=10, auto=False)
        plt.xlim(xmin=-10, xmax=10, auto=False)

        for i in Body.Points:

            plt.scatter(i.X1, i.X2)

            plt.plot(i.T1, i.T2)

        plt.plot(OX1, OY1, c='y')
        plt.plot(OX2, OY2, c='y')

    return Body


import sqlite3
from sqlite3 import Error
import os.path

"""
Description:
    Creates connection to the database, if this function is called for the first
    time it creates the database and all its tables, otherwise just the connection
    is created.

Return:
    this function returns the connection to the database, in case some error occurs
    during the connection/creation of the database then None is returned.

Parameters:
    Database file path.
"""

DB_FILE = os.getcwd() + os.path.sep + "db" + os.path.sep + "EPS.db"
EPS_SQL = os.getcwd() + os.path.sep + "modules" + os.path.sep + "EPS.sql"

def create_or_connect():
    conn = None
    try:
        conn = sqlite3.connect(DB_FILE)
        conn.execute("PRAGMA foreign_keys = 1")
        cursor = conn.cursor()
        sql_file = open(EPS_SQL)
        sql_as_string = sql_file.read()
        cursor.executescript(sql_as_string)
        return conn
    except Error as e:
        print(e)
    return conn


from django import forms
from django.forms import ModelForm
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Hidden, HTML
from crispy_forms.bootstrap import Field
from core.forms.base import FormulaireBase
from core.models import SMS, ConfigurationSMS, Rattachement
from core.utils.utils_commandes import Commandes
from outils.forms.editeur_sms import EXTRA_HTML
from outils.widgets import Texte_SMS

class Formulaire(FormulaireBase, ModelForm):
    objet = forms.CharField(label="Objet", required=False)
    destinataire = forms.ChoiceField(label="Destinataire", choices=[], required=True)

    class Meta:
        model = SMS
        fields = "__all__"
        widgets = {
            "texte": Texte_SMS(),
        }
        help_texts = {
            "objet": "Saisissez un titre qui vous permettra de retrouver plus facilement ce SMS dans l'historique. Ce titre n'apparaît pas dans le SMS."
        }

    def __init__(self, *args, **kwargs):
        idsms = kwargs.pop("idsms", None)
        super(Formulaire, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_id = 'form_editeur_sms'
        self.helper.form_method = 'post'
        self.helper.attrs = {'enctype': 'multipart/form-data'}

        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-2'
        self.helper.field_class = 'col-md-10'

        # Sélectionne l'adresse d'expédition
        self.fields["configuration_sms"].queryset = ConfigurationSMS.objects.filter(pk__in=self.request.user.Get_configurations_sms_possibles())
        if not idsms:
            self.fields['configuration_sms'].initial = self.request.user.Get_configuration_sms_defaut()

        # Définit la taille max du texte
        configuration_sms = self.instance.configuration_sms if self.instance.pk else self.fields['configuration_sms'].initial
        if configuration_sms:
            self.fields['texte'].widget.attrs['maxlength'] = configuration_sms.nbre_caracteres

        # Destinataire
        if self.instance:
            destinataire = self.instance.destinataires.first()

            if destinataire.famille:
                rattachements = Rattachement.objects.select_related("individu").filter(famille=destinataire.famille, titulaire=True).order_by("individu__nom", "individu__prenom")
                self.fields["destinataire"].choices = [(None, "---------")] + [(rattachement.individu.tel_mobile, "%s (%s)" % (rattachement.individu.tel_mobile, rattachement.individu.Get_nom())) for rattachement in rattachements if rattachement.individu.tel_mobile]
                self.fields["destinataire"].initial = destinataire.famille.mobile

            if destinataire.collaborateur:
                self.fields["destinataire"].choices = [(None, "---------")]
                if destinataire.collaborateur.tel_mobile:
                    self.fields["destinataire"].choices.append((destinataire.collaborateur.tel_mobile, "%s (%s)" % (destinataire.collaborateur.tel_mobile, destinataire.collaborateur.Get_nom())))
                    self.fields["destinataire"].initial = destinataire.collaborateur.tel_mobile

        # Affichage
        self.helper.layout = Layout(
            Hidden("idsms", value=self.instance.pk),
            Commandes(enregistrer=False, ajouter=False, annuler=False, aide=False,
                      autres_commandes=[
                          HTML("""Envoyer """),
                          HTML("""Fermer """),
                          HTML("""<button type="submit" name="enregistrer_brouillon" title="Enregistrer le brouillon" class="btn btn-default">Enregistrer le brouillon</button> """),
                          HTML(EXTRA_HTML),
                      ],
            ),
            Field('objet'),
            Field('configuration_sms'),
            Field('destinataire'),
            Field('texte'),
        )


# simple.py
import logging
log_format = "DKA: %(asctime)s %(filename)s:%(lineno)-3d %(levelname)s %(message)s"
#logging.basicConfig(level=logging.WARNING, format=log_format, filename='simple.log')

formatter = logging.Formatter(log_format)

file_handler = logging.FileHandler('simple.log')
file_handler.setLevel(logging.WARNING)
file_handler.setFormatter(formatter)

console_handler = logging.StreamHandler()
#console_handler.setLevel(logging.DEBUG)
console_handler.setLevel(logging.NOTSET)
console_handler.setFormatter(formatter)

logger = logging.getLogger()
#logger.setLevel(logging.DEBUG)
logger.setLevel(logging.NOTSET)
logger.addHandler(file_handler)
logger.addHandler(console_handler)

def my_fun(n):
    for i in range(0, n):
        logging.debug(i)
        if i == 50:
            logging.warning("DKA: i is 50")

        try:
            print('Out: ', i / (50 - i))
        except ZeroDivisionError:
            logging.error("DKA: Divide by zero. i was {}!".format(i))

if __name__ == "__main__":
    my_fun(100)