from odoo import models, fields, api, _
import xlwt
import io
import base64
from xlwt import easyxf
import datetime
import calendar
import os
from collections import defaultdict

class ReporteComisiones(models.TransientModel):
    _name = "reporte.comisiones"

    @api.model
    def _get_from_date(self):
        mes = datetime.date.today().strftime("%m")
        anio = datetime.date.today().strftime("%Y")
        return "%s-%s-01" % (anio, mes)

    from_date = fields.Date(string='Desde',default=_get_from_date)
    to_date = fields.Date(string='hasta',default=datetime.date.today())

    invoice_report_printed = fields.Boolean('Imprimir Reporte')
    invoice_summary_file = fields.Binary('Reporte Comisiones')
    file_name = fields.Char('Reporte')

    @api.multi
    def action_print_comision_summary(self):
        workbook = xlwt.Workbook()
        xlwt.add_palette_colour("gris", 0x21)
        workbook.set_colour_RGB(0x21, 191, 191, 191)

        worksheet_general = workbook.add_sheet('Reporte General')
        worksheet_detallado = workbook.add_sheet('Reporte Detallado')

        periodo_1 = "Comisiones: " + self.from_date +' - '+ self.to_date
        fecha_inicio = self.from_date
        fecha_fin = self.to_date

    ####################################    ESTILOS         ###########################################
        titulo_tabla = easyxf('font:height 200; align: horiz center, vert center, wrap yes; font:bold True, name Cambria;border: top_color black, left_color black, right_color black, bottom_color black, left thin,right thin,top thin,bottom thin;')
        cont_left_izde_arab = easyxf('font:height 190; align: vert center, wrap yes; font:name Cambria;border: left_color black, right_color black, top_color black, bottom_color black, left thin,right thin, top thin,bottom thin;')
        cont_center_izde_arab = easyxf('font:height 190; align: horiz center; font:name Cambria;border: left_color black, right_color black, top_color black, bottom_color black, left thin,right thin, top thin,bottom thin;')
        number_1 = easyxf('font:height 190; align: vert center, wrap yes; font:name Cambria; align: horiz right; border: left_color black, right_color black, top_color black, bottom_color black, left thin,right thin, top thin,bottom thin;', num_format_str= "#,##0.00")
        number_2 = easyxf('font:height 200, bold True; font:name Cambria; align: horiz right;border: left_color black, right_color black, top_color black, bottom_color black, left thin,right thin, top thin,bottom thin;', num_format_str= "#,##0.00")

    ####################################    CABECERAS         ###########################################
        worksheet_general.write(0, 1, periodo_1, easyxf('font:height 280; font:bold True, name Cambria;'))
        worksheet_general.write_merge(1, 1, 1, 3, 'Reporte de Comisiones', easyxf('font:height 360; align: horiz center; font:bold True, name Cambria;'))
        worksheet_general.write(3, 1, 'ITEM', titulo_tabla)
        worksheet_general.write(3, 2, 'VENDEDOR', titulo_tabla)
        worksheet_general.write(3, 3, 'COMISION', titulo_tabla)

        worksheet_general.col(1).width = 2500
        worksheet_general.col(2).width = 12000
        worksheet_general.col(3).width = 3500

        worksheet_detallado.write(0, 1, periodo_1, easyxf('font:height 280; font:bold True, name Cambria;'))
        worksheet_detallado.write_merge(1, 1, 1, 8, 'REPORTE DETALLADO DE COMISIONES', easyxf('font:height 360; align: horiz center; font:bold True, name Cambria;'))
        worksheet_detallado.write_merge(3, 4, 1, 1, 'ITEM', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 2, 2, 'VENDEDOR', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 3, 3, 'PRODUCTO', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 4, 4, 'MONTO VENDIDO', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 5, 5, 'MONTO RECTIFI.', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 6, 6, 'MONTO TOTAL', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 7, 7, 'COMISION', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 8, 8, 'TOTAL', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 9, 9, 'DETALLE VENTAS', titulo_tabla)
        worksheet_detallado.write_merge(3, 4, 10, 10, 'DETALLE RECTIFICATIVAS', titulo_tabla)

        worksheet_detallado.col(1).width = 2500
        worksheet_detallado.col(2).width = 10000
        worksheet_detallado.col(3).width = 14000
        worksheet_detallado.col(4).width = 3500
        worksheet_detallado.col(5).width = 3500
        worksheet_detallado.col(6).width = 3500
        worksheet_detallado.col(7).width = 3500
        worksheet_detallado.col(8).width = 3500
        worksheet_detallado.col(9).width = 8000
        worksheet_detallado.col(10).width = 8000
        worksheet_detallado.row(3).set_style(easyxf('font:height 240;'))
        worksheet_detallado.row(4).set_style(easyxf('font:height 240;'))

    ########################  Consultas  ########################
        obj_empleados = self.env['hr.employee'].search([('active', '=', True)])
        cont_general = 4
        cont_detallado = 5
        item_general = 0
        item_detallado = 0
        for empleado in obj_empleados:
            producto_precio = defaultdict(float)
            producto_nombre = defaultdict(str)
            producto_id = defaultdict(int)
            producto_pre_total = defaultdict(float)
            monto_vendido = defaultdict(float)
            monto_rectificativa = defaultdict(float)
            detalle_venta = defaultdict(str)
            detalle_rectificativa = defaultdict(str)
            ajajaja = ""
            item_general += 1
            comi_total = 0

            obj_factura_rectificativas = self.env['account.invoice'].search([('type', '=', 'out_refund'), ('state', 'in', ['open','paid']),
                                                                             ('date_invoice', '>=', fecha_inicio), ('date_invoice', '<=', fecha_fin),
                                                                             ])

            obj_facturas_ventas = self.env['account.invoice'].search([('date_invoice', '>=', fecha_inicio), ('date_invoice', '<=', fecha_fin),
                                                                     ('type', '=', 'out_invoice'), ('state', 'in', ['open','paid']),
                                                                     ('move_name', '!=', False), ('user_id.id', '=', empleado.user_id.id)])
            for factura in obj_facturas_ventas:
                obje_invoice_line_ids = self.env['account.invoice.line'].search([('invoice_id', '=', factura.id)])

                for line in obje_invoice_line_ids:
                    detalle_venta[line.product_id.product_tmpl_id.id] +=  factura.number + ' | '
                    producto_precio[line.product_id.product_tmpl_id.id] +=  (line.price_subtotal*(1/(line.invoice_id.currency_id.rate or 1)))
                    producto_nombre[line.product_id.product_tmpl_id.id] =  line.product_id.name
                    producto_id[line.product_id.product_tmpl_id.id] =  line.product_id.product_tmpl_id.id
                    producto_pre_total[line.product_id.product_tmpl_id.id] += (line.price_subtotal*(1/(line.invoice_id.currency_id.rate or 1)))
                    monto_vendido[line.product_id.product_tmpl_id.id] += (line.price_subtotal *(1/(line.invoice_id.currency_id.rate or 1)))

            for factura in obj_factura_rectificativas:
                obje_factura_inicial = self.env['account.invoice'].search([('number', '=', factura.origin), ('user_id.id', '=', empleado.user_id.id),('state', 'in', ['open','paid'])]) #

                for fac in obje_factura_inicial:
                    obje_rectificativa_invoice_line_ids = self.env['account.invoice.line'].search([('invoice_id.origin', '=', fac.number), ('invoice_id','=',factura.id)]) #
                    for line in obje_rectificativa_invoice_line_ids:
                        detalle_rectificativa[line.product_id.product_tmpl_id.id] +=  factura.number + ' | '
                        producto_precio[line.product_id.product_tmpl_id.id] -=  (line.price_subtotal*(1/(line.invoice_id.currency_id.rate or 1)))
                        producto_nombre[line.product_id.product_tmpl_id.id] =  line.product_id.name
                        producto_id[line.product_id.product_tmpl_id.id] =  line.product_id.product_tmpl_id.id
                        producto_pre_total[line.product_id.product_tmpl_id.id] -= (line.price_subtotal*(1/(line.invoice_id.currency_id.rate or 1)))
                        monto_rectificativa[line.product_id.product_tmpl_id.id] += (line.price_subtotal*(1/(line.invoice_id.currency_id.rate or 1)))

            inicio = cont_detallado
            for i in list(producto_id):
                item_detallado += 1
                aux_comision = 0
                total = producto_pre_total[i]
                multiplo=total/(abs(total) or 1)
                porcen = 0
                aux_total = abs(total)
                aux_anterior = 0
                obj_comisiones = self.env['product.porcentaje.line'].search([('product_id.id', '=', producto_id[i])])
                comisiones_porcen = defaultdict(float)
                comisiones_monto = defaultdict(int)
                for com in obj_comisiones:
                    if abs(total) >= com.porcentaje_id.name:
                        aux_total -= (com.porcentaje_id.name-aux_anterior)
                        porcen = porcen + ((com.porcentaje_id.name-aux_anterior)*com.monto/100)
                        aux_anterior = com.porcentaje_id.name
                        aux_comision = com.monto
                    elif abs(total)<com.porcentaje_id.name and abs(total)>=aux_anterior:
                        porcen = porcen + (aux_total*com.monto/100)
                        aux_total -= (com.porcentaje_id.name-aux_anterior)
                        aux_comision = com.monto
                        aux_anterior = com.porcentaje_id.name
                if  aux_total >0:
                    porcen = porcen +(aux_total*aux_comision/100)

                comi_total += porcen*multiplo

                worksheet_detallado.write(cont_detallado, 1, str(item_detallado).zfill(2), cont_center_izde_arab) #TIPO DE TABLA (2)
                worksheet_detallado.write(cont_detallado, 2, empleado.user_id.name, cont_left_izde_arab) #TIPO DE TABLA (2)
                worksheet_detallado.write(cont_detallado, 3, producto_nombre[i], cont_left_izde_arab) #TIPO DE TABLA (2)
                worksheet_detallado.write(cont_detallado, 4, monto_vendido[i], number_1)
                worksheet_detallado.write(cont_detallado, 5, monto_rectificativa[i], number_1)
                worksheet_detallado.write(cont_detallado, 6, total, number_1)
                worksheet_detallado.write(cont_detallado, 7, porcen*multiplo, number_1)
                worksheet_detallado.write(cont_detallado, 9,  detalle_venta[i], cont_left_izde_arab)
                worksheet_detallado.write(cont_detallado, 10,  detalle_rectificativa[i], cont_left_izde_arab)
                cont_detallado += 1
            fin = cont_detallado -1
            if inicio<=fin:
                worksheet_detallado.write_merge(inicio, fin, 8, 8, comi_total, number_1)
                #worksheet_detallado.write_merge(inicio, fin, 9, 9, 'VENTAS: ' + detalle_venta[i] + ' \n ' +'RECTIFICATIVAS: '+ detalle_rectificativa[i], cont_left_izde_arab)
            worksheet_general.write(cont_general, 1, str(item_general).zfill(2), cont_center_izde_arab)
            worksheet_general.write(cont_general, 2, empleado.user_id.name, cont_left_izde_arab)
            worksheet_general.write(cont_general, 3, comi_total, number_1)
            cont_general += 1
    ####################################    FINAL    ###################################################
        fp = io.BytesIO()
        workbook.save(fp)
        excel_file = base64.encodestring(fp.getvalue())
        self.invoice_summary_file = excel_file
        self.file_name =  periodo_1 +'.xls'
        self.invoice_report_printed = True
        fp.close()
        return {
                'view_mode': 'form',
                'res_id': self.id,
                'res_model': 'reporte.comisiones',
                'view_type': 'form',
                'type': 'ir.actions.act_window',
                'context': self.env.context,
                'target': 'new',
        }


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

# ---------------------------------------------------------------------
# Copyright (c) 2012 Michael Hull.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  - Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  - Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ----------------------------------------------------------------------

from morphforge.morphology.ui.morphmaths import MorphologyForRenderingOperator

from morphforge.morphology.visitor import DictBuilderSectionVisitorHomo

import numpy
import numpy as np

class MatPlotLibViewer(object):

    """
    Plot Projections of a morphology onto XY, XZ, and YZ axes.
    """

    plot_views = [0, 1, 2]

    _projMatXY = numpy.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]])
    _projMatXZ = numpy.array([[0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0]])
    _projMatYZ = numpy.array([[1.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0]])

    _figure_projections = {0: _projMatXY, 1: _projMatXZ, 2: _projMatYZ}
    _figure_labels = {0: ('X', 'Y'), 1: ('Z', 'Y'), 2: ('X', 'Z')}
    _figure_positions = {0:221, 1:222, 2:223}
    _figure_titles = {0:'View From Above', 1:'View From Side', 2:'View From Front'}

    def __init__(self, morph, use_pca=True, fig_kwargs=None):

        if morph == None:
            raise ValueError('No Cell')

        self.morph = morph

        self.fig = None
        self.fig_kwargs = fig_kwargs if fig_kwargs is not None else {}
        self.subplots = {}
        self.normaliser = None

        self.build_plot(use_pca)

    def build_draw_sub_plot(self, rotatedSectionDict, fig, i, plotLims):
        import pylab
        from matplotlib.path import Path
        from matplotlib import patches

        subplotnum = self._figure_positions[i]
        title = self._figure_titles[i]
        proj_matrix = self._figure_projections[i]
        labels = self._figure_labels[i]

        ax = fig.add_subplot(subplotnum, aspect='equal')

        # Find the depth extremes for coloring:

        (z_min, z_max) = (None, None)
        for seg in self.morph:
            xyzProj = numpy.dot(proj_matrix, rotatedSectionDict[seg])
            z_min = (xyzProj[2] if not z_min else min(z_min, xyzProj[2]))
            z_max = (xyzProj[2] if not z_max else max(z_max, xyzProj[2]))
        zrange = z_max - z_min

        for seg in self.morph:
            xyzProj = numpy.dot(proj_matrix, rotatedSectionDict[seg])
            xy_proj = numpy.array([xyzProj[0], xyzProj[1]])

            xyz_proj_parent = numpy.dot(proj_matrix, rotatedSectionDict[seg.parent])
            xy_proj_parent = numpy.array([xyz_proj_parent[0], xyz_proj_parent[1]])

            color = str((xyzProj[2] - z_min) / zrange) if zrange > 0.001 else 'grey'

            linewidth = (seg.d_r + seg.p_r) / 2.0 * 2.0

            # Test if we have just tried to draw a point, if so then draw a circle:
            if numpy.linalg.norm(xy_proj - xy_proj_parent) < 0.0001:
                try:
                    ax.add_patch(pylab.Circle(xy_proj, radius=linewidth/2.0, color=color))
                    ax.plot(xy_proj[0], xy_proj[1], '+', markersize=linewidth/2.0, color='red')
                except:
                    pass
            else:

                # Simple version, which doesn't work so well:
                # ax.plot([xy_proj[0], xy_proj_parent[0]], [xy_proj[1], xy_proj_parent[1]], linewidth=linewidth, color=color)

                # More complex patch version:
                joining_vec = xy_proj - xy_proj_parent
                joining_vec_norm = joining_vec / numpy.linalg.norm(joining_vec)

                perp_vec = np.array((joining_vec_norm[1], joining_vec_norm[0] * -1))

                assert np.fabs(np.dot(joining_vec_norm, perp_vec)) < 0.01

                # The points:
                p1 = xy_proj + (perp_vec * seg.d_r)
                p2 = xy_proj - (perp_vec * seg.d_r)

                p3 = xy_proj_parent - (perp_vec * seg.p_r)
                p4 = xy_proj_parent + (perp_vec * seg.p_r)

                verts = [p1, p2, p3, p4, (0, 0)]
                codes = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]
                path = Path(verts, codes)
                patch = patches.PathPatch(path, facecolor=color, lw=1)
                ax.add_patch(patch)

        ax.set_title(title)
        ax.set_xlim(plotLims)
        ax.set_ylim(plotLims)
        ax.set_xlabel(labels[0])
        ax.set_ylabel(labels[1])

        from matplotlib.ticker import MaxNLocator
        ax.xaxis.set_major_locator(MaxNLocator(4))
        ax.yaxis.set_major_locator(MaxNLocator(4))

        ax.grid(True)
        return ax

    def build_plot(self, usePCA):
        import pylab

        self.normaliser = MorphologyForRenderingOperator(self.morph,
                                                         usePCA=usePCA)

        # Find the Point that is the furthest distance way from
        # the centre when the cell is centred and rotated:
        rotator = lambda s: self.normaliser(s.get_distal_npa3())

        rotated_section_dict = DictBuilderSectionVisitorHomo(morph=self.morph, functor=rotator) ()

        # Add in the parents manually:
        dummy_scetion = self.morph._dummysection
        rotated_section_dict[dummy_scetion] = self.normaliser(dummy_scetion.get_distal_npa3())

        max_axis = max([numpy.linalg.norm(rotated_section_pt) for rotated_section_pt in rotated_section_dict.values()])
        plot_lims = (max_axis * -1.1, max_axis * 1.1)

        max_x = max([numpy.fabs(rotated_section_pt[0]) for rotated_section_pt in rotated_section_dict.values()])
        max_y = max([numpy.fabs(rotated_section_pt[1]) for rotated_section_pt in rotated_section_dict.values()])
        max_z = max([numpy.fabs(rotated_section_pt[2]) for rotated_section_pt in rotated_section_dict.values()])

        maxes = [max_x, max_y, max_z]

        # allMax = max(maxes)
        for i in self.plot_views:
            maxes[i] = maxes[i] + 0.2 * max([max_x, max_y, max_z])

        self.fig = pylab.figure(**self.fig_kwargs) #figsize=(7, 7))
        self.fig.subplots_adjust(
            left=0.05,
            top=0.95,
            right=0.95,
            bottom=0.05,
            wspace=0.15,
            hspace=0.15,
            )

        self.subplots = {}
        for i in self.plot_views:
            self.subplots[i] = self.build_draw_sub_plot(rotated_section_dict, self.fig, i, plot_lims)


from django.urls import path
from .views import EmpleadoCrear, EmpleadoDelete, EmpleadoEdit, EmpleadoList, GastosList, RubroGastoList,RubroGastoEdit,RubroGastoCrear,RubroGastoDelete, RubroVentaEdit,RubroVentaList,RubroVentaCrear,RubroVentaDelete,SubrubroGastoList,SubrubroGastoCrear,SubrubroGastoEdit,SubrubroGastoDelete, UmedidaList,UmedidaCrear,UmedidaEdit,UmedidaDelete,ClienteList,ClienteCrear,ClienteEdit,ClienteDelete,ProveedorList,ProveedorCrear,ProveedorEdit,ProveedorDelete,GastosList,GastoCrear,GastoEdit,GastoDelete,listado_gastos

app_name = 'economico'

urlpatterns = [
    path('rubro/gastos/', RubroGastoList.as_view(), name='rubro-gasto'),
    path('rubro/gastos/crear/', RubroGastoCrear.as_view(), name='rubro-gasto-crear'),
    path('rubro/gastos/editar/<int:pk>/', RubroGastoEdit.as_view(), name='rubro-gasto-edit'),
    path('rubro/gastos/borrar/<int:pk>/', RubroGastoDelete.as_view(), name='rubro-gasto-delete'),

    path('subrubro/gastos/', SubrubroGastoList.as_view(), name='subrubro-gasto'),
    path('subrubro/gastos/crear/', SubrubroGastoCrear.as_view(), name='subrubro-gasto-crear'),
    path('subrubro/gastos/editar/<int:pk>/', SubrubroGastoEdit.as_view(), name='subrubro-gasto-edit'),
    path('subrubro/gastos/borrar/<int:pk>/', SubrubroGastoDelete.as_view(), name='subrubro-gasto-delete'),

    path('rubro/ventas/', RubroVentaList.as_view(), name='rubro-venta'),
    path('rubro/ventas/crear/', RubroVentaCrear.as_view(), name='rubro-venta-crear'),
    path('rubro/ventas/editar/<int:pk>/', RubroVentaEdit.as_view(), name='rubro-venta-edit'),
    path('rubro/ventas/borrar/<int:pk>/', RubroVentaDelete.as_view(), name='rubro-venta-delete'),

    path('datos/u_medida/', UmedidaList.as_view(), name='dato-umedida'),
    path('datos/u_medida/crear/', UmedidaCrear.as_view(), name='dato-umedida-crear'),
    path('datos/u_medida/editar/<int:pk>/', UmedidaEdit.as_view(), name='dato-umedida-edit'),
    path('datos/u_medida/borrar/<int:pk>/', UmedidaDelete.as_view(), name='dato-umedida-delete'),

    path('datos/empleados/', EmpleadoList, name='dato-empleado'),
    path('datos/empleados/crear/', EmpleadoCrear.as_view(), name='dato-empleado-crear'),
    path('datos/empleados/editar/<int:pk>/', EmpleadoEdit.as_view(), name='dato-empleado-edit'),
    path('datos/empleados/borrar/<int:pk>/', EmpleadoDelete.as_view(), name='dato-empleado-delete'),

    path('datos/clientes/', ClienteList, name='dato-cliente'),
    path('datos/clientes/crear/', ClienteCrear.as_view(), name='dato-cliente-crear'),
    path('datos/clientes/editar/<int:pk>/', ClienteEdit.as_view(), name='dato-cliente-edit'),
    path('datos/clientes/borrar/<int:pk>/', ClienteDelete.as_view(), name='dato-cliente-delete'),

    path('datos/proveedores/', ProveedorList, name='dato-proveedor'),
    path('datos/proveedores/crear/', ProveedorCrear.as_view(), name='dato-proveedor-crear'),
    path('datos/proveedores/editar/<int:pk>/', ProveedorEdit.as_view(), name='dato-proveedor-edit'),
    path('datos/proveedores/borrar/<int:pk>/', ProveedorDelete.as_view(), name='dato-proveedor-delete'),

    path('gastos/', GastosList, name='gasto'),
    path('listado/gastos', listado_gastos, name='listado-gastos'),
    path('gastos/nuevo/', GastoCrear.as_view(), name='gasto-crear'),
    path('gastos/editar/<int:pk>/', GastoEdit.as_view(), name='gasto-edit'),
    path('gastos/eliminar/<int:pk>/', GastoDelete.as_view(), name='gasto-delete'),
]


#Para ejecutar python APY.py extension_audio user
#Para ejecutar python APY.py wav Issac
import csv
import os
import sys
import datetime
import pandas as pd
from glob import glob
from os import system
from pydub import AudioSegment
from pydub.playback import play
from inaSpeechSegmenter import Segmenter

def getFolders(name):
    folders = []
    for x in glob(name):
        folders.append(x)
    return folders

def WriteResult(data,user):
    df = pd.DataFrame(data, columns = ['Audio','Genero','Edad','Region'])
    dt = datetime.datetime.now()
    filename = user+'_Reporte_'+str(dt)
    df.to_csv(filename+'.csv', index = None, header=True)
    df.to_json(filename +'.json',orient='records')
    system("clear")
    print(df)

def Gender(folders,ext,seg):
    list_result = []
    for folder in folders:
        name = folder.split("/")[-1]
        audio = folder + "/individuales/" + name + "01"+ext
        audio = folder
        result = seg(audio)
        list_result.append(result[0][0])
    return list_result

def Range_old(folders,ext):
    list_result = []
    for folder in folders:
        name = folder.split("/")[-1]
        audio = folder + "/comunes/" + name + "01"+ext
        audio = folder
        sound = AudioSegment.from_wav(audio)
        system("clear")
        play(sound)
        print("Rango de edades")
        print("a) 19-21")
        print("b) 22-24")
        print("c) 25-28")
        print("d) 29-32")
        print("e) 33-36")
        print("f) 37-40")
        print("g) 41-44")
        print("h) 45-48")
        print("i) 49-51")
        edad = input("Ingrese rango:")
        list_result.append(edad)
    return list_result

def Reporte(folders,G,E,R):
    Rango = {"a": "19-21","b":"22-24","c":"25-28","d": "29-32",
        "e":"33-36","f":"37-40","g":"41-44","h":"45-48","i":"49-51","":"-"}
    Generos = {"male":"Hombre","female":"Mujer"}
    list_result = []
    i = 0
    for folder in folders:
        name = folder.split("/")[-1]
        try:
            Genero = Generos[G[i]]
        except:
            Genero = '-'
        try:
            Edad = Rango[E[i]]
        except:
            Edad = '-'
        list_result.append([name,Genero,Edad,R])
        i = i + 1

    return list_result
def main():
    list_result = []
    seg = Segmenter(detect_gender= True)
    ext = "."+str(sys.argv[1])
    user =  str(sys.argv[2])
    Path = os.getcwd()+"/CorpusMe/*"
    folders = getFolders(Path)
    folders = sorted(folders)
    Edades = Range_old(folders, ext)
    Generos = Gender(folders, ext,seg)
    data = Reporte(folders,Generos,Edades,'Mexico')
    WriteResult(data,user)

main()


import serial,datetime,csv

ser = serial.Serial(
    port='COM3',baudrate=9600)

# write data in csv file
myFile = open('data.txt', 'w',newline='')
with myFile:
    writer = csv.writer(myFile,delimiter=',')
    writer.writerow(['Time','Price'])
    myFile.close()
print("connected to: " + ser.portstr)
data=[]
while True:
    # read data from ardiono
    line = ser.readline()
    data=(line.decode().rstrip())
    # read time
    date = datetime.datetime.now()
    # write data in readable way
    date= str(date.strftime("%Sd"))[:-1]
    data=[date,data]
    print(data)
    # write data in csv file
    myFile = open('data.txt', 'a',newline='')
    with myFile:
        writer = csv.writer(myFile,delimiter=',')
        writer.writerow(data)
        myFile.close()

ser.close()


import numpy as np
from skimage import data, exposure
from PIL import Image
import cv2
import csv

#zmienne globalne, do przechowywania wzorc�w literek - ka�dy index to inna linijka

chars=['G','9','8','7','6','5','4','3','2','1','0','Z','Y','X','W','V',
       'U','T','S','R','Q','P','O','N','H','F','E','D','B','M','L','K','J','C','A','I']
horz = []
vert = []

def load32(all):
    for i in range(36):
        horz.append(all[i][:32])
        vert.append(all[i][32:])

#wczytujemy do struktur dane
def load_csv(file):
    with open(file,'r') as filey:
        for line in filey:
            line=line.split('|') #nie wiem co ta linijka robi, ale jak j� usun�, to si� crashuje program
            line[-1]=line[-1][:-1]
            for lines in line:
                lines=lines.split(',')
                lines=list(filter(None,lines)) #usuni�cie warto�ci None (NULL dla cpp, nil dla PASCALa)
                horz.append(lines[1:17])
                vert.append(lines[17:])

class Plate:
    h=0; w=0; img=np.ndarray(0); letters=[np.ndarray(0)]; name='';
	#inicjujemy wszystkie zmienne
    def __init__(self,name):
        self.name=name
        self.img=data.imread('plates/'+name+'.jpg', as_grey=True).copy()
        self.h,self.w=self.img.shape[:2]
		#rzutujemy na warto�ci 0-255
        self.img = exposure.rescale_intensity(self.img, out_range=(0,255)).copy()
		#rozmycie gaussa, by pozby� si� ma�ego syfu
        self.img = cv2.GaussianBlur(self.img,(5,5),0)
    def thresh(self):
        for row in range(self.h):
            for value in range(self.w):
				#warto�� thresholdu ustawiona tak, by jak najlepiej (bez ��cze�) oznacza�a literki
                if self.img[row][value] < np.percentile(self.img,75):
                    self.img[row][value]=0
                else:
                    self.img[row][value]=255
	#1. z 0-255 na 0-1 2. podnosimy do kwadratu 3. z 0-1 na 0-255
    def invertngamma(self):
        for row in range(self.h):
            for value in range(self.w):
                self.img[row][value]=((1-self.img[row][value]/255)**2)*255
    def save(self): Image.fromarray(self.img).convert('RGB').save('plates/'+self.name+'2.jpg')
	#wyci�ganie liter z tablic. najwa�niejsza cz��
    def save_letters(self):
		#musimy rzutowa� warto�ci na cv2_int8, �eby traktowa�o nparray'e jako obrazy
        self.img=cv2.convertScaleAbs(self.img)
		#cnt to kolekcja kontur�w
        _,cnt,_= cv2.findContours(self.img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
        print(self.name)
        for contour in cnt:
			#dla ka�dego znalezionego kontura znajdujemy minimalny opisuj�cy prostok�t
            rect=cv2.minAreaRect(contour)
			#poni�ej zabawa ze wsp�rz�dnymi
            box=np.int0(cv2.boxPoints(rect))
            tx=[x[0] for x in box]
            ty=[y[1] for y in box]
            boxx=min(tx),min(ty),max(tx),max(ty)
            temp_w=np.int0(max(tx)-min(tx))
            temp_h=np.int0(max(ty)-min(ty))
			#wy�uskujemy te kontury o rozmiarze min 5x15
            if temp_w>4:
                if temp_h>15:
					#pod zmienn� rcc zapisujemy aktualny prostok�t zawieraj�cy w sobie literk�
                    rcc=self.img[min(ty):max(ty),min(tx):max(tx)].copy()
					#jeszcze raz threshold z typem float32 (kolejne wymogi Open CV)
                    for x in range(temp_h):
                        for y in range(temp_w):
                            if rcc[x][y]>0: rcc[x][y]=np.float32(255)
                            else: rcc[x][y]=np.float32(0)
					#erozja dla poprawienia literki (cz�sto wycina 'chude' chary)
                    rcc = cv2.erode(rcc,(2,2),iterations=1)
					#normalizacja do rozmiaru 16x16 (dla wzorca 16x16)
                    rcc = cv2.resize( rcc, (16,16), interpolation=cv2.INTER_AREA)
					#obliczanie histogram�w dla wyci�tego symbolu
                    t_horz = np.sum(rcc == 0, axis=0)
                    t_vert = np.sum(rcc == 0, axis=1)
					#inicjalizacja zmiennych do funkcji dopasowuj�cej - spory error, bo szukamy minimum
                    t_error=100000000;t_id=6;wx=1;wy=1;t_err2=10000000;t_id2=0;
                    #dla ka�dego wzorca symbolu
                    for l in range(36):
                    #konwertujemy stringi na inty
                        horz[l]=[int(x) for x in horz[l]]
                        vert[l]=[int(x) for x in vert[l]]
						#wyliczamy r�nic� mi�dzy wzorcem a symbolem
                        t_x = t_horz - horz[l]
						#wszystkie r�nice podnosimy do kwadratu
                        t_x = [x*x for x in t_x]
						#i sumujemy
                        e_x = np.sum(t_x)
						#jw
                        t_y = t_vert - vert[l]
                        t_y = [y*y for y in t_y]
                        e_y = np.sum(t_y)
                        if e_x+e_y < t_error:
							#wskazujemy nowy b��d oraz id literki
                            t_err2=t_error
                            t_id2=t_id
                            t_error = (wx*e_x)+(wy*e_y)
                            t_id=l
                    print(np.sqrt(t_error), chars[t_id])
					#wypisanie na obrazie literki - przesuni�cie o min(tx) pozwala zachowa� przesuni�cie z tablicy rejestracyjnej
                    img=cv2.imread('out/'+self.name+'.jpg',1)
                    cv2.putText(img, chars[t_id], (50+min(tx),50), cv2.FONT_ITALIC, 1, (0,255,0), 2)
                    cv2.imwrite('out/'+self.name+'.jpg', img)
					#wypisujemy w konsoli najbardziej pasuj�cy symbol

class IMGArray:
    nparray=np.ndarray(0); h=0; w=0; ndim=0; cnt=np.ndarray(0); temp=np.array(0); bw=np.array(0); plate=(0,np.ndarray(0));address='x'
    def __init__(self,address):
	#wczytujemy obraz do pami�ci
        self.address=address
        self.temp = data.imread('img3/P60400'+address+'.jpg', as_grey=True).copy();
        self.bw = data.imread('img3/P60400'+address+'.jpg', as_grey=True).copy();
        self.nparray = data.imread('img3/P60400'+address+'.jpg').copy();
        self.ndim=self.nparray.ndim
        self.h,self.w=self.nparray.shape[:2]
    def save(self,name): Image.fromarray(self.nparray).convert('RGB').save('img2/'+name+'.jpg')
	#wyszukujemy kraw�dzie, a nast�pnie 'zamykamy' obszary z wieloma kraw�dziami, bia�ymi prostok�tami o wymiarach 30x5
    def change(self):
        self.temp = cv2.GaussianBlur(self.temp,(5,5),0)
        self.temp = cv2.Sobel(self.temp, cv2.CV_8U, 1, 0, ksize=3)
        _,self.temp=cv2.threshold(self.temp,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
        temp_se = cv2.getStructuringElement(cv2.MORPH_RECT,(30,5))
        self.temp = cv2.morphologyEx(self.temp,cv2.MORPH_CLOSE, temp_se)
	#zwracamy kolekcj� kontur�w
    def find_cnt(self): _,self.cnt,_ = cv2.findContours(self.temp,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
    def color_cnt(self):
        for contour in self.cnt:
			#przetwarzamy pocz�tkowo ka�dy element kolekcji, w poszukiwaniu tablicy
            rect=0;box=0;tx=0;ty=0;
            rect=cv2.minAreaRect(contour)
            box=np.int0(np.around(cv2.boxPoints(rect)))
            tx=[x[0] for x in box]
            ty=[y[1] for y in box]
            boxx=(min(tx),min(ty),max(tx),max(ty))
            temp_w=np.int0(max(tx)-min(tx))
            temp_h=np.int0(max(ty)-min(ty))
			#sprawdzamy warunki pocz�tkowe, kt�re zwi�zane s� z tablicami rejestracyjnymi
            if(temp_w*temp_h > 5000):
                if(temp_w>temp_h):
                    if(temp_h<50):
                        if(temp_w<250):
                            print('{} {}'.format(temp_w,temp_h))
							#zaznaczamy na r�owo tablic� na obrazie
                            cv2.drawContours(self.nparray,[box],0,(255,0,255),2)
                            input=Image.open('img3/P60400'+self.address+'.jpg')
                            self.plate=input.crop(boxx)
                            #wycinamy i zapisujemy tablic� jako BW
                            self.plate.save('plates/'+self.address+'.jpg')

#generuje obrazy tablic rejestracyjnych. wymagane za 1. razem
def init_plates(imgs):
    for value in imgs:
        newimage=IMGArray(value)
        newimage.change()
        newimage.find_cnt()
        newimage.color_cnt()
        newimage.save(value)

def clear_out(img):
    temp = data.imread('img2/' + img + '.jpg').copy();
    Image.fromarray(temp).convert('RGB').save('out/' + img + '.jpg')

if __name__ == '__main__':
    numbers = ['03','05','06','12', '13', '15','16', '21', '27', '29', '30', '42', '51', '55', '59', '63', '64', '66']
    #init_plates(numbers)
    load_csv('nn16.csv')
    #load32()
    for plate in numbers:
        clear_out(plate)
        newplate=Plate(plate)
        newplate.invertngamma()
        newplate.thresh()
        newplate.save_letters()
        newplate.save()


from z3 import *
from itertools import product
from hjk.CEGIS import *
from operator import eq
import time

start = 0
end = 0
T = 60*3

def b2t_search(bmExpr, checker):
    funcDefine = ' '.join(['define-fun', checker.synFunction.name, '(', ' '.join(list(map(lambda l: '(' + ' '.join(l) + ')', checker.synFunction.argList))), ')', checker.synFunction.retSort])
    intSet = [[],[]]
    boolSet = [[],[]]
    i2iops = []
    b2bops = []
    i2bops = []
    b2iops = ['ite']
    exprs = [intSet, boolSet]
    ops = [i2iops, b2bops, i2bops, b2iops]

    progSize = 1

    for e in bmExpr[1][4][0][2][:-1]:
        if isinstance(e, tuple):
            intSet[1].append(e[1])
        elif isinstance(e, list):
            if e[0] in ['+', '-', '*', '/', 'mod']:
                i2iops.append(e[0])
            elif e[0] in ['<=', '>=', '<', '>', '=']:
                i2bops.append(e[0])
            elif e[0] in ['or', 'and']:
                b2bops.append(e[0])
        elif isinstance(e, str):
            intSet[1].append(e)

    for e in bmExpr[1][4][1][2]:
        if isinstance(e, tuple):
            intSet[1].append(e[1])
        elif isinstance(e, list):
            if e[0] in ['+', '-', '*', '/', 'mod']:
                i2iops.append(e[0])
            elif e[0] in ['<=', '>=', '<', '>', '=']:
                i2bops.append(e[0])
            elif e[0] in ['or', 'and']:
                b2bops.append(e[0])
        elif isinstance(e, str):
            intSet[1].append(e)

    while True:
        mc = MyChecker('', checker)
        c = 1
        for ie in intSet[progSize]:

            program = expr2prog(funcDefine, ie)
            mc.program = program
            #print(program)
            """
            (conflict, counterexample) = mc.check()
            print("%d %s" %(c, program))
            c += 1

            if not conflict:
                if counterexample == None:
                    print(program)
                    return
                else:
                    mc.pts.append(counterexample)
            """
            counterexample = checker.check(program)
            if counterexample is None:
                return program

            #print("%d %s" %(c, program))
            c += 1

        progSize += 1
        enum_exprs(exprs, progSize, ops)

        cut_branch(exprs, progSize)

    #print('Not found!!!')

def enum_exprs(exprs, progsize, ops):
    i2iops = ops[0]
    b2bops = ops[1]
    i2bops = ops[2]
    b2iops = ops[3]
    intSet = exprs[0]
    boolSet = exprs[1]
    intSet.append([])
    boolSet.append([])
    if progsize <= 1:
        for ps1 in range(1, progsize-1):
            ps2 = progsize-1-ps1
            intSet[progsize].extend(list(product(i2iops, intSet[ps1], intSet[ps2])))

    for ps1 in range(1, progsize-1):
        for ps2 in range(1, progsize-ps1-1):
            ps3 = progsize-1-ps1-ps2
            intSet[progsize].extend(list(product(b2iops, boolSet[ps1], intSet[ps2], intSet[ps3])))

    for ps1 in range(1, progsize-1):
        ps2 = progsize-1-ps1
        boolSet[progsize].extend(list(product(i2bops, intSet[ps1], intSet[ps2])))
    """
    for ps1 in range(1, progsize-1):
        ps2 = progsize-1-ps1
        boolSet[progsize].extend(list(product(b2bops, boolSet[ps1], boolSet[ps2])))
    """

def expr2prog(funcDefine, expr):
    return '(' + funcDefine + ' ' + muti2str(expr) + ')'

def muti2str(t):
    if not isinstance(t, tuple) and not isinstance(t, list):
        return str(t)
    return '('+' '.join(list(map(lambda x: muti2str(x), t)))+')'

def cut_branch(exprs, progSize):
    intSet = exprs[0][progSize]
    boolSet = exprs[1][progSize]

    intSet = list(filter(intfilter, intSet))

    boolSet = list(filter(boolfilter, boolSet))
    exprs[0][progSize] = intSet
    exprs[1][progSize] = boolSet

def intfilter(ie):
    if not isinstance(ie, list):
        return True
    op = ie[0]
    if op == 'ite':
        if eq(ie[2], ie[3]):
            return False
    return True

def boolfilter(be):
    if isinstance(be[1], int) or isinstance(be[2], int):
        return False
    if eq(be[1], be[2]):
        return False
    return True


#
#  Module: strips
#
#  This module provides classes for representing STRIPS-based
#  planning domains:
#     Predicate - used to represent conditions in states and operators
#     Operator  - used to represent STRIPS operators
#     STRIPS - a "SearchDomain" for planning with STRIPS operators
#
#  (c) Luis Seabra Lopes
#  Inteligência Artificial & Introducao a Inteligencia Artificial, 2019
#

import sys
from tree_search import *
from functools import reduce
from itertools import product
import math

comp_menor = lambda x,y: True if x<y else False

def sort(list, sorted_list):
    pos=0
    menor_pos=0
    menor = list[0]
    if len(list)>2:
        for value in list[1:]: #skips the first element cause its already stored
            pos+=1
            if  not comp_menor(menor, value):
                menor_pos=pos
                menor = value
        sorted_list.append(menor)
        list.pop(menor_pos)
        return(sort(list, sorted_list))
    elif len(list)==2:
        if comp_menor(list[0], list[1]):
            sorted_list.append(list[0])
            sorted_list.append(list[1])
        else:
            sorted_list.append(list[1])
            sorted_list.append(list[0])
        return sorted_list
    else:
        return list

def menor(lista):
    sorted_list=[]
    return sort(lista, sorted_list)[0]

def second_menor(lista):
    sorted_list=[]
    return sort(lista, sorted_list)[1]

def distance(p1, p2):
    return math.sqrt( ((p1[0]-p2[0])**2)+((p1[1]-p2[1])**2) )

# Predicates used to describe states, preconditions and effects
class Predicate:
    def __str__(self):
        argsstr = args2string(self.args)
        return type(self).__name__ + "(" + argsstr + ")"
    def __repr__(self):
        return str(self)
    def __eq__(self,predicate):   # allows for comparisons with "==", etc.
        return str(self)==str(predicate)

    def __hash__(self):
       return hash(str(self))

    def substitute(self,assign): # Substitute the arguments in a predicate by constants according to a given assignment (i.e. a dictionary)
        la = self.args
        return type(self)(assign[la[0]])

# STRIPS operators
# -- operators for a specific domain will be subclasses
# -- concrete actions will be instances of specific operators
class Operator:

    def __init__(self,args,pc,neg,pos):
        self.args = args
        self.pc  = pc
        self.neg = neg
        self.pos = pos
    def __str__(self):
        return type(self).__name__ + '(' + args2string(self.args) + ')'
    def __repr__(self):
        argsstr = args2string(self.args)
        return type(self).__name__ + "(" + argsstr + ")"

    # Produce a concrete action by instanciating a specific
    # operator (i.e. the "Operator" subclass where the method was
    # called) for the arguments given in "args"
    # ( returns None if the action is not applicable in the given "state" )
    @classmethod
    def instanciate(cls,args):
        if len(args)!=len(cls.args):
            return None
        assign = dict(zip(cls.args, args))
        pc  = [ p.substitute(assign) for p in cls.pc ]
        neg = [ p.substitute(assign) for p in cls.neg ]
        pos = [ p.substitute(assign) for p in cls.pos ]
        return cls(args,pc,neg,pos)

# Search domains based on STRIPS actions
class STRIPS(SearchDomain):

    # constructor
    def __init__(self):
        pass

    # list of applicable actions in a given "state"
    def actions(self, state):
        keeper_pos = get_keeper_pos(state)[0]
        constants = state_constants(state)
        operators = Operator.__subclasses__()
        actions = []
        for op in operators:
            #A linha seguinte remove de lassign todos os predicados onde se verifiquem as seguintes condições
            #X não foi mapeado para uma posição que é a do keeper
            #Y foi mapeado para uma posição que não é contígua a X
            #Z foi mapeado para uma posição que não é contígua a Y e a 2 blocos de X
            lassign = [ assign for assign in assignments(op.args,constants, keeper_pos) if assign['X']==keeper_pos and distance(assign['Y'], keeper_pos)==1 and ('Z' not in list(assign.keys()) or (distance(assign['Z'], keeper_pos) == 2 and distance(assign['Z'], assign['Y'])==1 ))]

            for assign in lassign:
                argvalues = [assign[a] for a in op.args]
                action = op.instanciate(argvalues)
                if all(c in state for c in action.pc):
                    #print(action)
                    actions.append(action)
        #print(actions)
        return actions

    # Result of a given "action" in a given "state"
    # ( returns None, if the action is not applicable in the state)
    def result(self, state, action):
        #efeitos negativos
        newstate = [p for p in state if p not in action.neg] #Apaga do estado anterior (ou não adiciona ao novo estado, depende de como quisermos ver) as propriedades que deixam de ser verdade ao executar a ação
        #efeitos positivos
        newstate.extend(action.pos)#Adiciona aos estado atual as propriedades que passam a ser verdade ao executar a ação
        return set(newstate)

    def cost(self, state, action):
        if type(action).__name__ == 'Move_Keeper':
            return 2
        return 1

    def heuristic(self, state, goal):
        #return -1*len([p for p in goal if p in state])
        #return len([p for p in goal if p in state])
        #return 0

        distances=[]
        box_distances = []
        keeper_distances = []
        boxes_pos= [p.args for p in state if type(p).__name__ == 'Box_On' or type(p).__name__ == 'Box_On_Goal'] #todas as caixas
        box_not_on_goal_pos = [p.args for p in state if type(p).__name__ == 'Box_On' ] #todas as caixas not on goal
        #print(box_not_on_goal_pos)
        box_on_goal_pos = [p.args for p in state if type(p).__name__ == 'Box_On_Goal'] #caixas no goal
        print(box_on_goal_pos)
        goals_pos=[pos.args for pos in goal] #todos os goals
        free_goals_pos=[pos for pos in goals_pos if pos not in boxes_pos] #goals que não têm caixas
        keeper_distance_to_every_box=[]
        shortest_distance_to_box=10000
        #Calcula menor distância do keeper a uma caixa
        for pos in boxes_pos:
            shortest_distance_to_box=min([shortest_distance_to_box, distance(get_keeper_pos(state)[0], pos)])
        #calcula a distância mínima de cada caixa a um goal livre
        for pos in box_not_on_goal_pos:
            box_distances_to_every_goal = []
            for goal in free_goals_pos:
                box_distances_to_every_goal.append(distance(pos, goal))
            try:
                box_distances.append(menor(box_distances_to_every_goal))
            except IndexError:
                pass

        distances.append(shortest_distance_to_box)
        distances[0:0]=box_distances[:]
        soma = sum(distances)
        #print(soma)
        return soma
        """

        goals_pos=[pos.args for pos in goal] #todos os goals
        boxes_pos= [p.args for p in state if type(p).__name__ == 'Box_On' or type(p).__name__ == 'Box_On_Goal'] #todas as caixas
        unplaced_boxes = [p.args for p in state if type(p).__name__ == 'Box_On' ] #todas as caixas not on goal
        unfilled_goals = [pos for pos in goals_pos if pos not in boxes_pos] #goals que não têm caixas

        if not unplaced_boxes:
            return 0
        if not unfilled_goals:
            return 0

        player_dist = min([distance(get_keeper_pos(state)[0], box) for box in unplaced_boxes])
        box_distances = sum([min([distance(box, goal) for goal in unfilled_goals]) for box in unplaced_boxes])

        return player_dist + box_distances
        """

    # Checks if a given "goal" is satisfied in a given "state"
    def satisfies(self, state, goal):
        return all(p in state for p in goal)

# Auxiliary functions

def get_keeper_pos(state):
    return [pred.args for pred in state if type(pred).__name__ == 'Keeper_On_Box_Allowed' or type(pred).__name__ == 'Keeper_On_Box_Not_Allowed' ]
def state_constants(state):
    return [pred.args for pred in state]

def assignments(lvars,lconsts, keeper_pos):
    lcombs = product(lconsts,repeat=len(lvars))

    makeassign = lambda comb : dict(zip(lvars,comb))
    return list(map(makeassign,lcombs))

def args2string(args):
    if args == []:
        return ""
    return str(args)


#!/usr/bin/env python3

from operator import add as op_add
import copy
import argparse
import time
import psutil
import memory_profiler
import pygame
import sys

parser = argparse.ArgumentParser()
parser.add_argument('-gui', default=False, required=False, action='store_true')
parser.add_argument('-diff', default=2)

def get_enemy(player):
    if player == 'a':
        return 'n'
    return 'a'

def draw_board(display, board):
    width_grid = height_grid = 100
    rects = []

    for i in range(8):
        for j in range(8):
            rect = pygame.Rect(i * (width_grid+1), j *
                               (height_grid+1), width_grid, height_grid)
            rects.append(rect)

            pygame.draw.rect(display, (255, 255, 255), rect)

            val = board.get_val(i, j)
            if val == 'a':
                pygame.draw.circle(display, (0, 0, 0),
                                   rect.center, width_grid // 2 - 2, 4)
            elif val == 'n':
                pygame.draw.circle(display, (0, 0, 0),
                                   rect.center, width_grid // 2 - 2)

    pygame.display.flip()
    return rects

class Game:
    MIN_PLAYER = None
    MAX_PLAYER = None

    def __init__(self):
        self.board = self.new_board()
        self.set_val(3, 3, 'a')
        self.set_val(3, 4, 'n')
        self.set_val(4, 3, 'n')
        self.set_val(4, 4, 'a')

    def __str__(self):
        string = '   a b c d e f g h\n'
        string += '  ' + '-' * 16 + '\n'
        for i in range(8):
            string += str(i) + ' |'
            for j in range(8):
                string += self.get_val(i, j) + ' '
            string += '\n'

        return string

    def new_board(self):
        return ['#'] * 64

    def get_val(self, i, j):
        if 0 <= i <= 7 and 0 <= j <= 7:
            return self.board[i*8 + j]
        return None

    def set_val(self, i, j, val):
        if 0 <= i <= 7 and 0 <= j <= 7:
            self.board[i*8 + j] = val
        else:
            return None

    def get_distance(self, pos_1, pos_2):
        # Line
        if pos_1[0] == pos_2[0]:
            return abs(pos_2[1] - pos_1[1])

        # Column
        if pos_1[1] == pos_2[1]:
            return abs(pos_2[0] - pos_1[0])

        # Diagonal; Does not matter what subtraction we do
        return abs(pos_2[0] - pos_1[0])

    def get_moves(self, player):
        '''
        Returns a list of all the valid moves
        '''
        enemy_val = get_enemy(player)

        # A valid move must be adjacent to an enemy piece

        # Get all enemies
        enemies = []
        for i in range(8):
            for j in range(8):
                if self.get_val(i, j) == enemy_val:
                    enemies.append((i, j))

        # For all enemies get empty adjacent positions
        possible_moves = []
        for enemy in enemies:
            i = enemy[0]
            j = enemy[1]
            # Top Left
            if self.get_val(i-1, j-1) == '#' and (i-1, j-1) not in possible_moves:
                possible_moves.append((i-1, j-1))
            # Top
            if self.get_val(i-1, j) == '#' and (i-1, j) not in possible_moves:
                possible_moves.append((i-1, j))
            # Top Right
            if self.get_val(i-1, j+1) == '#' and (i-1, j+1) not in possible_moves:
                possible_moves.append((i-1, j+1))
            # Left
            if self.get_val(i, j-1) == '#' and (i, j-1) not in possible_moves:
                possible_moves.append((i, j-1))
            # Right
            if self.get_val(i, j+1) == '#' and (i, j+1) not in possible_moves:
                possible_moves.append((i, j+1))
            # Bot Left
            if self.get_val(i+1, j-1) == '#' and (i+1, j-1) not in possible_moves:
                possible_moves.append((i+1, j-1))
            # Bot
            if self.get_val(i+1, j) == '#' and (i+1, j) not in possible_moves:
                possible_moves.append((i+1, j))
            # Bot Right
            if self.get_val(i+1, j+1) == '#' and (i+1, j+1) not in possible_moves:
                possible_moves.append((i+1, j+1))

        # Check if moves are valid
        valid_moves = []
        for move in possible_moves:
            valid, junk = self.valid_move(move, player)
            if valid and move not in valid_moves:
                valid_moves.append(move)

        return valid_moves

    def valid_move(self, piece, player):
        '''
        Returns True if a piece can be placed on the given position.
        Also if i can be placed, returns the position of the furthest valid ally (to form a line)
        '''
        # Move on all 8 axis
        # If you find an empty space or reach the end of the board, then abandon that axis
        # I think this should look like bf
        # Maybe this function should return the farthest valid allied piece, if there is any
        # Tuple: (pos, direction, enemies)
        enemy = get_enemy(player)
        max_piece = None
        max_enemies = 0
        valid = False
        queue = []
        # Top Left
        queue.append((piece, (-1, -1), 0))
        # Top
        queue.append((piece, (-1, 0), 0))
        # Top Right
        queue.append((piece, (-1, 1), 0))
        # Left
        queue.append((piece, (0, -1), 0))
        # Right
        queue.append((piece, (0, 1), 0))
        # Bot Left
        queue.append((piece, (1, -1), 0))
        # Bot
        queue.append((piece, (1, 0), 0))
        # Bot Right
        queue.append((piece, (1, 1), 0))

        while len(queue) > 0:
            curr = queue.pop(0)
            curr_pos = curr[0]
            curr_enemies = curr[2]
            # If we are on the starting piece, then increment with direction and continue
            if curr_pos == piece:
                curr_pos = tuple(map(op_add, curr[0], curr[1]))

            curr_pos_val = self.get_val(curr_pos[0], curr_pos[1])

            # Check if out of bounds or empty space
            if curr_pos_val == None or curr_pos_val == '#':
                continue

            # Check if curr_pos is a player piece, if it is make the move valid and check if that is the best distance
            elif curr_pos_val == player and curr_enemies > 0:
                valid = True
                if max_piece == None or curr_enemies > max_enemies:
                    max_piece = curr_pos
                    max_enemies = curr_enemies

            # Check if curr_pos is an enemy piece, if it is increment the position
            elif curr_pos_val == enemy:
                curr_enemies += 1
                new_pos = tuple(map(op_add, curr[0], curr[1]))
                queue.append((new_pos, curr[1], curr_enemies))

        return valid, max_piece

    def move(self, start, dest, player):
        '''
        Sets all the pieces in a line from start to dest to the value of the start
        '''
        #player = self.get_val(start[0], start[1])
        curr_pos = start

        step_i = 1
        if start[0] > dest[0]:
            step_i = -1
        elif start[0] == dest[0]:
            step_i = 0

        step_j = 1
        if start[1] > dest[1]:
            step_j = -1
        elif start[1] == dest[1]:
            step_j = 0

        while(curr_pos != dest):
            #curr_pos[0] += step_i
            #curr_pos[1] += step_j
            self.set_val(curr_pos[0], curr_pos[1], player)
            curr_pos = tuple(map(op_add, curr_pos, (step_i, step_j)))

        self.set_val(curr_pos[0], curr_pos[1], player)

    def final(self):
        '''
        If there are no more moves for both players, returns True. Else returns False
        '''
        return len(self.get_moves('a')) == 0 and len(self.get_moves('n')) == 0

    def count_pieces(self):
        '''
        Returns the number of white and black pieces
        '''
        num_a = 0
        num_n = 0
        for i in range(8):
            for j in range(8):
                val = self.get_val(i, j)
                if val == 'a':
                    num_a += 1
                elif val == 'n':
                    num_n += 1

        return num_a, num_n

    def get_winner(self):
        '''
        Returns the winner. If the game has not ended it returns None
        '''
        if not self.final():
            return None
        num_a, num_n = self.count_pieces()

        if num_a > num_n:
            return 'a'
        elif num_n > num_a:
            return 'n'
        else:
            return 'tie'

    def estimate_score(self, depth):
        final = self.final()
        score_max = 0
        score_min = 0
        if Game.MAX_PLAYER == 'a':
            score_max, score_min = self.count_pieces()
        else:
            score_min, score_max = self.count_pieces()

        # If game has ended
        if final:
            # If MAX wins
            if score_max > score_min:
                return 100 + depth
            # If MIN wins
            elif score_min > score_max:
                return -100 + depth
            # If TIE
            else:
                return 0
        else:
            return score_max - score_min

class State:
    def __init__(self, board, curr_player, depth, score=None):
        self.board = board
        self.curr_player = curr_player
        self.depth = depth
        self.score = score
        self.chosen_state = None

    def get_moves(self):
        enemy = get_enemy(self.curr_player)
        moves = self.board.get_moves(self.curr_player)

        move_states = []
        for move in moves:
            new_board = copy.deepcopy(self.board)
            junk, dest = new_board.valid_move(move, self.curr_player)
            new_board.move(move, dest, self.curr_player)
            move_states.append(State(new_board, enemy, self.depth-1))

        return move_states

def min_max(state):
    if state.depth == 0 or state.board.final() or len(state.get_moves()) == 0:
        state.score = state.board.estimate_score(state.depth)
        return state

    state.moves = state.get_moves()

    moves_score = [min_max(state) for state in state.moves]

    if state.curr_player == Game.MAX_PLAYER:
        state.chosen_state = max(moves_score, key=lambda x: x.score)
    else:
        state.chosen_state = min(moves_score, key=lambda x: x.score)

    state.score = state.chosen_state.score
    return state

def alpha_beta(alpha, beta, state):
    '''
    ceva debug stuff

    print(alpha, beta, state.depth)
    if alpha == 0 and beta == 2 and state.depth == 2:
        print('crash')
        print(state.curr_player)
        print(state.board)
        print('moves', len(state.get_moves()))
    '''

    if state.depth == 0 or state.board.final() or len(state.get_moves()) == 0:
        state.score = state.board.estimate_score(state.depth)
        return state

    if alpha > beta:
        return state

    state.moves = state.get_moves()

    if state.curr_player == Game.MAX_PLAYER:
        curr_score = float('-inf')

        for move in state.moves:
            new_state = alpha_beta(alpha, beta, move)
            if curr_score < new_state.score:
                state.chosen_state = new_state
                curr_score = new_state.score

            if alpha < new_state.score:
                alpha = new_state.score
                if alpha >= beta:
                    break

    elif state.curr_player == Game.MIN_PLAYER:
        curr_score = float('inf')

        for move in state.moves:
            new_state = alpha_beta(alpha, beta, move)

            if curr_score > new_state.score:
                state.chosen_state = new_state
                curr_score = new_state.score

            if beta > new_state.score:
                beta = new_state.score
                if alpha >= beta:
                    break

    state.score = state.chosen_state.score

    return state

def play_game(algo, player, depth, gui):
    enemy = get_enemy(player)

    Game.MIN_PLAYER = player
    Game.MAX_PLAYER = enemy
    board = Game()

    print('\nInitial:')
    print(str(board))

    state = State(board, 'n', depth)

    if gui:
        # Init pygame
        pygame.init()
        pygame.display.set_caption('Reversi')
        display = pygame.display.set_mode(size=(810, 810))

        rectangles = draw_board(display, board)
    while True:
        if state.curr_player == Game.MIN_PLAYER:
            # Player turn
            print('Player turn')
            valid_moves = state.board.get_moves(Game.MIN_PLAYER)
            print('valid moves:', len(valid_moves))
            for move in valid_moves:
                print(chr(move[1] + ord('a')), move[0])
            if len(valid_moves) == 0:
                print('No valid moves')
            else:
                while True:
                    if gui:
                        # Go through events
                        valid_move = False
                        for event in pygame.event.get():
                            if event.type == pygame.QUIT:
                                pygame.quit()
                                sys.exit()

                            elif event.type == pygame.MOUSEBUTTONDOWN:
                                pos = pygame.mouse.get_pos()

                                for rect in range(len(rectangles)):
                                    if rectangles[rect].collidepoint(pos):
                                        line = rect // 8
                                        col = rect % 8

                                        if (line, col) in valid_moves:
                                            valid_move = True
                                            break

                        if valid_move:
                            break

                    else:
                        # If not GUI
                        try:
                            player_input = input('\n> ')
                            col = player_input[0].lower()
                            line = int(player_input[1])

                            if 0 <= line <= 7 and 'a' <= col <= 'h':
                                # Transformam coloana in nr
                                col = ord(col) - ord('a')
                                if (line, col) in valid_moves:
                                    # Valid move
                                    break
                                else:
                                    # Invalid move
                                    print('Invalid move')
                            else:
                                print('Invalid input')

                        except Exception as e:
                            print('error %s\n' % e)

                junk, dest = state.board.valid_move(
                    (line, col), Game.MIN_PLAYER)
                print('move:', (line, col), dest)
                state.board.move((line, col), dest, Game.MIN_PLAYER)

        else:
            # CPU turn
            print('CPU turn')
            valid_moves = state.board.get_moves(Game.MAX_PLAYER)
            if len(valid_moves) == 0:
                print('No valid moves')
            else:
                t1 = time.time()

                new_state = None
                mem_usage = None
                if algo == 'minmax':
                    mem_usage, new_state = memory_profiler.memory_usage(
                        (min_max, [state]), retval=True, max_usage=True)
                else:
                    mem_usage, new_state = memory_profiler.memory_usage(
                        (alpha_beta, [-500, 500, state]), retval=True, max_usage=True)

                state.board = new_state.chosen_state.board

                t2 = time.time()
                dt = t2-t1
                print('Time to move:', round(dt * 1000), 'ms')

                if mem_usage != None:
                    print('Mem Usage:', mem_usage[0], 'MiB\n')

        # Print board, check winner and change player
        print(str(state.board))
        draw_board(display, state.board)
        num_a, num_n = state.board.count_pieces()
        print('White pieces:', num_a, '\nBlack pieces:', num_n, '\n')
        winner = state.board.get_winner()
        if winner != None:
            if winner == 'a':
                print('White has won')
            elif winner == 'b':
                print('Black has won')
            else:
                print('Tie')
            break
        state.curr_player = get_enemy(state.curr_player)

if __name__ == "__main__":
    args = parser.parse_args()

    while True:
        algo = input('1. Min Max\n2. Alpha Beta\n\n> ')
        if algo == '1':
            algo = 'minmax'
            break
        elif algo == '2':
            algo = 'alphabeta'
            break
        else:
            print('Invalid answer')

    while True:
        player = input('1. White\n2. Black\n\n> ')
        if player == '1':
            player = 'a'
            break
        elif player == '2':
            player = 'n'
            break
        else:
            print('Invalid answer')

    play_game(algo, player, int(args.diff), bool(args.gui))


# coding=utf-8
# --------------------------------------------------------------------------
# --------------------------------------------------------------------------

from msrest.serialization import Model

class StorageAccountCreateParameters(Model):
    """
    The parameters to provide for the account.

    :param str location: Resource location
    :param dict tags: Resource tags
    :param StorageAccountPropertiesCreateParameters properties:
    """

    _validation = {
        'location': {'required': True},
    }

    _attribute_map = {
        'location': {'key': 'location', 'type': 'str'},
        'tags': {'key': 'tags', 'type': '{str}'},
        'properties': {'key': 'properties', 'type': 'StorageAccountPropertiesCreateParameters'},
    }

    def __init__(self, location, tags=None, properties=None, **kwargs):
        self.location = location
        self.tags = tags
        self.properties = properties


import matplotlib.pyplot as plt
import numpy as np
from sympy import symbols  # importamos la libreria sympy
from sympy import lambdify
from sympy import sympify

x = symbols('x') # establecemos a x como variable simbolica

a = int(input('Introduzca a = '))
b = int(input('Introduzca b = '))
n = int(input('Introduzca n = '))
expr = input('Introduzca f(x) = ')
expr = sympify(expr)

#evaluamos la funcion
f = lambda valor: expr.subs(x, valor).evalf()

#def f(valor):
#    return expr.subs(x, valor).evalf()

# valor = 2
# 2**2
# 4

h = (b - a) / n
# I = (h/2)*(f(a)+ 2*sumatoria(f(xi)) + f(b))
s = 0
for i in range(1, n):
    print('i: ', i)
    s = s + f(a + h * i)
I = (h / 2) * (f(a) + 2 * s + f(b))
print('El aproximado es: ', I)

# Graficamos la funcion
lam_x = lambdify(x, expr, modules=['numpy'])
x_vals = np.linspace(a - 5, b + 5, 100)
y_vals = lam_x(x_vals)

plt.title(expr)
plt.xlabel('x')
plt.ylabel('y')

plt.plot(x_vals, y_vals)
plt.grid(True)
plt.show()


# encoding: utf-8
from __future__ import print_function

import json
import pytest
from model_mommy import mommy

from nepal.models import Container
from toolbox.icepick import ordered

@pytest.fixture
def setUp(request):
	container1 = {
		'id': 1,
		'name': 'container1',
		'config': {}
	}

	Container.objects.create(**container1)

	def tearDown():
		pass
	request.addfinalizer(tearDown)

@pytest.mark.django_db
def test_create_new_container(setUp, client):
	data = {
		'name': 'container_test',
		'config': {
			"registry": {
				"image": "registry:2.4",
				"environment": [
					"RACK_ENV=development",
					"SHOW=true",
					"DEBUG=False"
				],
				"volumes": [
					"/opt/registry/tmp:/tmp/registry-dev:Z",
					"/opt/nginx/certs:/certs:Z"
				],
				"expose": [
					5000
				],
				"ports": [
					"5000:5000"
				]
			}
		}

	}

	result = client.post('/containers', data=json.dumps(data), content_type='application/json', headers={'Content-Type': 'application/json'})
	# TODO: must be assert more things
	assert 201 == result.status_code

	result_db = Container.objects.get(name='container_test')
	assert 'container_test' == result_db.name
	assert ordered(data.get('config')) == ordered(result_db.config)

@pytest.mark.django_db
def test_get_container_all(setUp, client):
	req = client.get('/containers', headers={'Content-Type': 'application/json'} )
	assert 1 == len(req.data)

@pytest.mark.django_db
def test_get_container_by_id(setUp, client):
	req = client.get('/containers/1', headers={'Content-Type': 'application/json'} )
	result = req.data

	assert 200 == req.status_code
	assert 1 == result.get('id')

@pytest.mark.django_db
def test_update_container_ok(setUp, client):
	data = {
		'name': 'container1',
		'config': {}
	}

	req = client.put('/containers/1', data=json.dumps(data), content_type='application/json', headers={'Content-Type': 'application/json'})
	result = req.data

	assert 200 == req.status_code

@pytest.mark.django_db
def test_try_update_container_not_found(setUp, client):
	req = client.put('/containers/132', data=json.dumps({}), content_type='application/json', headers={'Content-Type': 'application/json'})

	assert 404 == req.status_code

@pytest.mark.django_db
def test_delete_container_ok(setUp, client):
	result = client.delete('/containers/1', headers={'Content-Type': 'application/json'})
	assert 204 == result.status_code

@pytest.mark.django_db
def test_try_delete_container_that_not_exist(setUp, client):
	result = client.delete('/containers/122', headers={'Content-Type': 'application/json'})
	assert 404 == result.status_code


# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

from .models import Document
from .forms import DocumentForm
from .models import PatientEval
from .forms import PatientEvalForm
#from .models import PatientEvals
from .forms import PatientsEvalForm

def documentsView(request):
    # Handle file upload
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = Document(docfile = request.FILES['docfile'])
            newdoc.save()

            # Redirect to the document list after POST
            return HttpResponseRedirect(reverse('myproject.myapp.views.documents'))
    else:
        form = DocumentForm() # A empty, unbound form

    # Load documents for the list page
    documents = Document.objects.all()

    # Render list page with the documents and the form
    return render_to_response(
        'myapp/documents.html',
        {'documents': documents, 'form': form},
        context_instance=RequestContext(request)
    )

def patientsEvalView(request):
    # Handle file upload
    if request.method == 'POST':
        form = PatientsEvalForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = PatientEval(docfile = request.FILES['docfile'])
            newdoc.save()

            # Redirect to the document list after POST
            return HttpResponseRedirect(reverse('myproject.myapp.views.patientsEval'))
    else:
        form = PatientsEvalForm() # A empty, unbound form

    # Load documents for the list page
    patientsEval = PatientEval.objects.all()

    # Render list page with the documents and the form
    return render_to_response(
        'myapp/patientsEval.html',
        {'patientsEval': patientsEval, 'form': form},
        context_instance=RequestContext(request)
    )

def patientEvalView(request):
    # Handle file upload
    if request.method == 'POST':
        form = PatientEvalForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = PatientEval(docfile = request.FILES['docfile'])
            newdoc.save()

            # Redirect to the document list after POST
            return HttpResponseRedirect(reverse('myproject.myapp.views.patientEval'))
    else:
        form = PatientEvalForm() # A empty, unbound form

    # Load documents for the list page
    patientEval = PatientEval.objects.first()
    #patientEvals = PatientEval.objects.all()

    # Render list page with the documents and the form
    return render_to_response(
        'myapp/patientEval.html',
        {'patientEval': patientEval, 'form': form},
        context_instance=RequestContext(request)
    )


import math
import torch
import torch.nn as nn
import torch.nn.functional as F

class TGCN(nn.Module):

    def __init__(self, num_nodes, num_features, gru_units, seq_len,
                 pre_len):

        super(TGCN, self).__init__()

        self._nodes = num_nodes  # 图的节点数
        self._units = gru_units  # gru个数
        self._features = num_features
        self._len = pre_len
        self.grucell1 = nn.GRUCell(input_size=num_features,
                                   hidden_size=gru_units, bias=True)
        self.linear = nn.Linear(in_features=gru_units,
                                out_features=pre_len)

    def forward(self, A_hat, X, state):
        """
        :param X: Input data of shape (seq_len, batch_size, num_nodes).
        :param state: state of shape (batch_size, num_nodes, gru_units).
        :param A_hat: Normalized adjacency matrix(num_nodes, num_nodes).
        """

        ##hx = torch.zeros(X.size(0), self.hidden_size, dtype=input.dtype, device=input.device)
        for i in range(X.size(0)):
            Ax = torch.einsum("ij,jk->ki", [A_hat, X[i].permute(1, 0)])
            state = torch.einsum("ij,jkl->kil", [A_hat, state.permute(1, 0, 2)])
            Ax = Ax.reshape(-1, self._features)

            state = state.reshape(-1, self._units)
            state = self.grucell1(Ax, state)
            state = state.reshape(-1, self._nodes, self._units)

        ##state: state of shape (batch_size, num_nodes, gru_units).

        output = state.reshape(-1, self._units)
        ## output:(batch * num_nodes,gru_units)

        output = self.linear(output)

        ## output:(batch * num_nodes,pre_len)
        output = output.reshape(-1, self._nodes, self._len)
        ## output:(batch,num_nodes,pre_len)
        output = output.permute(0,2,1)

        return output

class GCNBlock(nn.Module):

    def __init__(self, num_nodes, gru_units,output_size):

        super(GCNBlock, self).__init__()
        self._nodes = num_nodes
        self._outputsize = output_size
        self.linear = nn.Linear(in_features=gru_units+1,
                                out_features=output_size,bias=True)

    def forward(self,A_hat, X, state):
        """
        :param X: Input data of shape (batch_size, num_nodes).
        :param state: state of shape (batch_size, num_nodes, gru_units).
        :param A_hat: Normalized adjacency matrix(num_nodes, num_nodes).
        """
        X = X.unsqueeze(dim=2)
        ## inputs:(batch,num_nodes,1)

        x_s = torch.cat((X, state), axis=2)
        ## x_s:(batch,num_nodes,gru_units+1)

        input_size = x_s.shape[2]
        # input_size == gru_units+1

        x0 = x_s.permute(1, 2, 0)
        ## x0:(num_nodes,input_size,-1)
        ## x0:(num_nodes,gru_units+1,batch)

        x0 = x0.reshape(self._nodes, -1)
        ## x0:(num_nodes,input_size*batch)
        ## x0:(num_nodes,(gru_units+1)*batch)

        x1 = torch.matmul(A_hat, x0)
        ## x1:(num_nodes,input_size*batch)

        x = x1.reshape(self._nodes, input_size, -1)
        ## x:(num_nodes,gru_units+1,batch)

        x = x.permute(2,0,1)
        ## x:(batch,num_nodes,gru_units+1)

        x = x.reshape(-1, input_size)
        ## x:(batch * num_nodes,gru_units+1)

        x = self.linear(x)

        x = x.reshape(-1, self._nodes, self._outputsize)
        x = x.reshape(-1, self._nodes * self._outputsize)
        ## x:(batch, num_nodes * output_size)

        return x

class TGCN2(nn.Module):

    def __init__(self, num_nodes, num_features, gru_units, seq_len,
                 pre_len):

        super(TGCN2, self).__init__()

        self._nodes = num_nodes  # 图的节点数
        self._units = gru_units  # gru个数
        self._features = num_features
        self._len = pre_len
        self.gc1 = GCNBlock(num_nodes=num_nodes,gru_units=gru_units,
                            output_size=2*gru_units)
        self.gc2 = GCNBlock(num_nodes=num_nodes, gru_units=gru_units,
                            output_size=gru_units)

        self.linear = nn.Linear(in_features=gru_units,
                                out_features=pre_len)

    def forward(self, A_hat, X, state):
        """
        :param X: Input data of shape (seq_len, batch_size, num_nodes).
        :param state: state of shape (batch_size, num_nodes, gru_units).
        :param A_hat: Normalized adjacency matrix(num_nodes, num_nodes).
        """

        ##hx = torch.zeros(X.size(0), self.hidden_size, dtype=input.dtype, device=input.device)
        for i in range(X.size(0)):
            value = torch.sigmoid(self.gc1(A_hat, X[i], state))
            value = value.chunk(2,dim = 1)
            r = value[0]
            u = value[1]
            # r, u: (batch,num_nodes * gru_units)
            r_state = r * state.reshape(len(state),-1)
            c = torch.tanh(self.gc2(A_hat, X[i], r_state.reshape(-1,self._nodes,self._units)))
            state = u * state.reshape(len(state),-1) + (1 - u) * c
            state = state.reshape(-1,self._nodes,self._units)

        ##state: state of shape (batch_size, num_nodes, gru_units).

        output = state.reshape(-1, self._units)
        ## output:(batch * num_nodes,gru_units)

        output = self.linear(output)

        ## output:(batch * num_nodes,pre_len)
        output = output.reshape(-1, self._nodes, self._len)
        ## output:(batch,num_nodes,pre_len)
        output = output.permute(0,2,1)

        return output

'''
visualizaton.py
'''

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

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

def plot_result(test_result,test_label1,path):
    ##all test result visualization
    fig1 = plt.figure(figsize=(7,1.5))
#    ax1 = fig1.add_subplot(1,1,1)
    a_pred = test_result[:,0]
    a_true = test_label1[:,0]
    plt.plot(a_pred,'r-',label='prediction')
    plt.plot(a_true,'b-',label='true')
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/test_all.jpg')
    plt.show()
    ## oneday test result visualization
    fig1 = plt.figure(figsize=(7,1.5))
#    ax1 = fig1.add_subplot(1,1,1)
    a_pred = test_result[0:96,0]
    a_true = test_label1[0:96,0]
    plt.plot(a_pred,'r-',label="prediction")
    plt.plot(a_true,'b-',label="true")
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/test_oneday.jpg')
    plt.show()

def plot_result_3ave(test_result,test_label1,path):
    ##all test result visualization
    a_pred = np.zeros((int(test_result.shape[0]/3)+2, test_result.shape[1]))
    a_pred[0, :]=test_result[0, :]
    a_pred[-1, :] = test_result[-1, :]
    a_pred[1, :]=(test_result[1, :]+test_result[3, :])/2
    a_pred[-2, :] = (test_result[-2, :] + test_result[-4, :]) / 2

    a_true = np.zeros((int(test_label1.shape[0] / 3)+2, test_label1.shape[1]))
    a_true[0, :] = test_label1[0, :]
    a_true[-1, :] = test_label1[-1, :]
    a_true[1, :] = (test_label1[1, :] + test_label1[3, :]) / 2
    a_true[-2, :] = (test_label1[-2, :] + test_label1[-4, :]) / 2

    for i in range(2, len(a_pred)-2):
        a_pred[i, :]= (test_result[3*i, :]+test_result[3*i-2, :]+test_result[3*i-4, :]) /3

    for i in range(2, len(a_true)-2):
        a_true[i, :]= (test_label1[3*i, :]+test_label1[3*i-2, :]+test_label1[3*i-4, :]) /3

    fig1 = plt.figure(figsize=(7,1.5))
#    ax1 = fig1.add_subplot(1,1,1)
    print(len(a_true))
    time_range = pd.date_range('2015-01-25 22:30:00', periods=len(a_true), freq='15min')
    #data = np.random.randn(1000)

    a_true = pd.DataFrame(a_true[:, 0], index=time_range)
    a_pred = pd.DataFrame(a_pred[:, 0], index=time_range)
    #df.plot(title='default plot')
    #df = df.resample('30min', how='sum')
    #df.plot(title='resampled plot')
    #a_pred = a_pred[:,0]
    #a_true = a_true[:,0]
    plt.plot(a_pred,'r-',label='prediction')
    plt.plot(a_true,'b-',label='true')
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/test_all3.jpg')
    plt.show()
    ## oneday test result visualization
    fig1 = plt.figure(figsize=(7,1.5))
#    ax1 = fig1.add_subplot(1,1,1)
    a_pred = a_pred[0:96]
    a_true = a_true[0:96]
    plt.plot(a_pred,'r-',label="prediction")
    plt.plot(a_true,'b-',label="true")
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/test_oneday3.jpg')
    plt.show()

def plot_error(train_rmse,train_loss,test_rmse,test_acc,test_mae,path):
    ###train_rmse & test_rmse
    fig1 = plt.figure(figsize=(5,3))
    plt.plot(train_rmse, 'r-', label="train_rmse")
    plt.plot(test_rmse, 'b-', label="test_rmse")
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/rmse.jpg')
    plt.show()
    #### train_loss & train_rmse
    fig1 = plt.figure(figsize=(5,3))
    plt.plot(train_loss,'b-', label='train_loss')
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/train_loss.jpg')
    plt.show()

    fig1 = plt.figure(figsize=(5,3))
    plt.plot(train_rmse,'b-', label='train_rmse')
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/train_rmse.jpg')
    plt.show()

    ### accuracy
    fig1 = plt.figure(figsize=(5,3))
    plt.plot(test_acc, 'b-', label="test_acc")
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/test_acc.jpg')
    plt.show()
    ### rmse
    fig1 = plt.figure(figsize=(5,3))
    plt.plot(test_rmse, 'b-', label="test_rmse")
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/test_rmse.jpg')
    plt.show()
    ### mae
    fig1 = plt.figure(figsize=(5,3))
    plt.plot(test_mae, 'b-', label="test_mae")
    plt.legend(loc='best',fontsize=10)
    plt.savefig(path+'/test_mae.jpg')
    plt.show()


import json
import logging
import os
import zipfile

import click
from src import utility

logger = logging.getLogger()

# pylint: disable=no-value-for-parameter

def extract_contents(source_filename):
    """Returns a stream of text extracted from downloaded content.json package file.

    Parameters
    ----------
    source_filename : str
        name of downloaded KB-LAB package files

    Yields
    -------
    Iterator[str, str, str, str]
        Stream of extracted (package-id, text, filename, date) tuples
    """
    with zipfile.ZipFile(source_filename, 'r') as zf:

        for package_id, filenames in utility.zip_folder_glob(zf, "*.json"):

            content_name = os.path.join(package_id, "content.json")
            meta_name = os.path.join(package_id, "meta.json")

            if content_name not in filenames:
                logger.warning("package {} has no content".format(package_id))
                continue

            if meta_name not in filenames:
                logger.warning("package {} has no meta".format(package_id))
                continue

            json_content = json.loads(zf.read(content_name).decode("utf-8"))
            json_meta = json.loads(zf.read(meta_name).decode("utf-8"))

            document = ''.join([block['content'] for block in json_content])

            # parts = package_id.split('-')
            filename = "{}.txt".format(package_id.replace('-', '_'))  # , json_meta['created'])
            print(filename)
            yield package_id, document, filename, json_meta['created']

@click.command()
@click.option('--source-filename', default='content.zip', help='Archive containing content.json files.')
@click.option('--target-filename', default='content_corpus.zip', help='Target text corpus filename.')
def extract_corpus(source_filename, target_filename):
    """Extracts text from downloaded content.json files and stores text in Zip-file.

    Parameters
    ----------
    source_filename : str
        name of archive that contains the downloaded KB-LAB package files
    target_filename : str
        Result (Zip) filename

    """
    texts = ((filename, text) for _, text, filename, _ in extract_contents(source_filename))
    utility.store_to_zipfile(target_filename, texts)

if __name__ == '__main__':

    #     source_filename = "/home/roger/tmp/riksdagens_protokoll_content.zip"
    #     target_filename = "/home/roger/tmp/riksdagens_protokoll_content_corpus.zip"
    #     extract_corpus(source_filename, target_filename)

    extract_corpus()


import pygame
import os
import random
import sys

pygame.init()

FPS = 50
WIDTH = 1000
HEIGHT = 800

image = pygame.Surface([100, 100])
size = WIDTH, HEIGHT
screen = pygame.display.set_mode(size)
pygame.mouse.set_visible(False)
clock = pygame.time.Clock()

def load_image(name, colorkey=None):
    fullname = os.path.join('data', name)
    image = pygame.image.load(fullname)
    if colorkey is not None:
        if colorkey == -1:
            colorkey = image.get_at((0, 0))
            pygame.display.flip()
        image.set_colorkey(colorkey)
    else:
        image = image.convert_alpha()
    return image

def start_screen():

    curpos = [0, 0]
    cursor = load_image("arrow.png", pygame.Color('white'))
    cursor = pygame.transform.scale(cursor, (50, 50))
    intro_text = ["Здравствуйте!", "",
                  "Для начала игры",
                  "Нажмите любую клавишу"]

    fon = pygame.transform.scale(load_image('fon.jpg'), (WIDTH, HEIGHT))
    foneg = pygame.transform.scale(load_image('foneg.jpg'), (WIDTH, HEIGHT))
    fonlosash = pygame.transform.scale(load_image('fonlosash.jpg'), (WIDTH, HEIGHT))
    foncrosh = pygame.transform.scale(load_image('foncrosh.jpg'), (WIDTH, HEIGHT))
    font = pygame.font.Font(None, 30)
    text_coord = 50
    running = True

    for line in intro_text:
        string_rendered = font.render(line, 1, pygame.Color('black'))
        intro_rect = string_rendered.get_rect()
        text_coord += 10
        intro_rect.top = text_coord
        intro_rect.x = 10
        text_coord += intro_rect.height
        screen.blit(string_rendered, intro_rect)

    while running:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            elif pygame.MOUSEBUTTONDOWN == event.type and 388 < event.pos[0] < 577 and \
                    711 > event.pos[1] > 431:
                Crosh()

            elif 388 < pygame.mouse.get_pos()[0] < 577 and \
                    711 > pygame.mouse.get_pos()[1] > 431:
                screen.blit(foncrosh, (0, 0))
                curpos = pygame.mouse.get_pos()

            elif 183 < pygame.mouse.get_pos()[0] < 348 and \
                    672 > pygame.mouse.get_pos()[1] > 386:
                screen.blit(fonlosash, (0, 0))
                curpos = pygame.mouse.get_pos()

            elif 626 < pygame.mouse.get_pos()[0] < 822 and \
                    688 > pygame.mouse.get_pos()[1] > 450:

                screen.blit(foneg, (0, 0))
                curpos = pygame.mouse.get_pos()
            elif pygame.MOUSEBUTTONDOWN == event.type and 626 < pygame.mouse.get_pos()[0] < 822 and \
                                    688 > pygame.mouse.get_pos()[1] > 450:

                screen.blit(foneg, (0, 0))
                curpos = pygame.mouse.get_pos()

            elif event.type == pygame.MOUSEMOTION:
                curpos = event.pos

                screen.blit(fon, (0, 0))
            else:
                screen.blit(fon, (0, 0))
        screen.blit(cursor, curpos)
        pygame.display.flip()

class Bullet(pygame.sprite.Sprite):
    bullet = load_image("bullet.png", -1)
    bullet = pygame.transform.scale(bullet, (70, 70))

    def __init__(self, x, y):
        super().__init__(bullet_group)
        self.startX = x
        self.startY = y
        self.speed = 15
        self.image = Bullet.bullet
        self.xv = self.speed
        self.rect = self.image.get_rect().move(x, y)

    def update(self):
        self.rect.x += self.xv

class Crosh_bot(pygame.sprite.Sprite):
    image2 = load_image("crosh.png", -1)
    image2 = pygame.transform.scale(image2, (200, 200))

    def __init__(self, x, y):
        super().__init__(bot)
        self.image = Crosh_bot.image2
        self.rect = self.image.get_rect().move(x, y)
        self.life = 100
        self.FPS = 10

    def collide(self, bullet):
        if pygame.sprite.collide_rect(self, bullet):
            self.life -= 1
            if self.life < 0:
                Win()

    def crosh2(self):
        ch = random.choice(['DOWN', 'UP', 'DOWN', 'UP', 'LEFT', 'RIGHT', 'DOWN',
                            'UP', 'DOWN', 'UP', 'LEFT', 'RIGHT', 'DOWN', 'UP',
                            'LEFT', 'RIGHT', 'DOWN', 'UP', 'DOWN', 'UP', 'LEFT',
                            'RIGHT', 'DOWN', 'UP', 'LEFT', 'RIGHT'])
        if 1000 > self.rect.x > 0 and 500 > self.rect.y > 0:
            if ch == 'DOWN':
                self.rect.x, self.rect.y = self.rect.x, self.rect.y + 15
                screen.blit(self.image2, [self.rect.x, self.rect.y])

            elif ch == 'UP':
                self.rect.x, self.rect.y = self.rect.x, self.rect.y - 15
                screen.blit(self.image2, [self.rect.x, self.rect.y])

            elif ch == 'LEFT':
                self.rect.x, self.rect.y = self.rect.x - 15, self.rect.y
                screen.blit(self.image2, [self.rect.x, self.rect.y])

            elif ch == 'RIGHT':
                self.rect.x, self.rect.y = self.rect.x + 15, self.rect.y
                screen.blit(self.image2, [self.rect.x, self.rect.y])

        elif self.rect.x >= 1000 or self.rect.y >= 500:
            self.rect.x, self.rect.y = self.rect.x - 20, self.rect.y - 20

        elif self.rect.x <= 0 or self.rect.y <= 0:
            self.rect.x, self.rect.y = self.rect.x + 20, self.rect.y + 20

        else:
            self.rect.x, self.rect.y = self.rect.x + 20, self.rect.y + 20
        screen.blit(self.image2, [self.rect.x, self.rect.y])
        clock.tick(self.FPS)

bot = pygame.sprite.Group()
bullet_group = pygame.sprite.Group()
bullets = []
crosh_bot = Crosh_bot(500, 100)

class Crosh():
    def __init__(self, pos=(100, 100), pos2=(500, 100)):
        self.image = load_image("creature1.png", -1)
        self.running = True
        self.pos = pos
        self.pos2 = pos2
        self.motion = 0
        self.size = 1000, 800
        self.FPS = 10
        self.screen = pygame.display.set_mode(size)
        pygame.mouse.set_visible(False)
        fon = pygame.transform.scale(load_image('secondfon.jpg'), (1000, 800))

        while self.running:
            screen.blit(fon, (0, 0))
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_DOWN:
                        self.motion = 'DOWN'
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        self.motion = 'UP'
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        self.motion = 'LEFT'
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RIGHT:
                        self.motion = 'RIGHT'
                if event.type == pygame.KEYUP:
                    self.motion = 0
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        Menu(self.pos, self.pos2)
                    if event.key == pygame.K_SPACE:
                        bullets.append(Bullet(self.pos[0] + 100, self.pos[1] + 100))

            crosh_bot.crosh2()
            for x in bullets:
                crosh_bot.collide(x)

            if self.motion == 'DOWN':
                self.pos = [self.pos[0], self.pos[1] + 5]
            elif self.motion == 'UP':
                self.pos = [self.pos[0], self.pos[1] - 5]
            elif self.motion == 'LEFT':
                self.pos = [self.pos[0] - 5, self.pos[1]]
            elif self.motion == 'RIGHT':
                self.pos = [self.pos[0] + 5, self.pos[1]]

            screen.blit(self.image, self.pos)

            for x in bullets:
                x.update()
            bullet_group.draw(screen)
            pygame.display.flip()

class Menu:
    def __init__(self, pos, pos2):
        self.fonpause = pygame.transform.scale(load_image('fonpause.jpg'), (1000, 800))
        self.pos = pos
        self.pos2 = pos2
        self.running = True
        self.cursor = load_image("arrow.png", pygame.Color('white'))
        self.cursor = pygame.transform.scale(self.cursor, (50, 50))
        self.curpos = [0, 0]
        self.FPS = 50

        while self.running:
            screen.blit(self.fonpause, (0, 0))

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False

                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        Crosh(self.pos, self.pos2)

                elif event.type == pygame.MOUSEMOTION:
                    self.curpos = event.pos

            screen.blit(self.cursor, self.curpos)
            pygame.display.flip()
            clock.tick(self.FPS)

class Win():
    def __init__(self):
        self.running =  True
        self.fonwin  = pygame.transform.scale(load_image('fonwin.jpg'), (1000, 800))
        self.fonwinbutton = pygame.transform.scale(load_image('fonwinbutton.jpg'), (1000, 800))
        self.FPS = 50
        self.cursor = load_image("arrow.png", pygame.Color('white'))
        self.cursor = pygame.transform.scale(self.cursor, (50, 50))
        self.curpos = [0, 0]
        while self.running:
            screen.blit(self.fonwin, (0, 0))
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        start_screen()
                # elif 602 < pygame.mouse.get_pos()[0] < 788 and 648 > pygame.mouse.get_pos()[1] > 701:
                #     screen.blit(self.fonwinbutton, (0, 0))
                #     curpos = pygame.mouse.get_pos()

                elif event.type == pygame.MOUSEMOTION:
                    self.curpos = event.pos
                    print(event.pos)
            screen.blit(self.cursor, self.curpos)
            pygame.display.flip()
            clock.tick(self.FPS)

# переделать
# class Tile(pygame.sprite.Sprite):
#     def __init__(self, tile_type, pos_x, pos_y):
#         super().__init__(tiles_group, all_sprites)
#         self.image = tile_images[tile_type]
#         self.rect = self.image.get_rect().move(tile_width * pos_x, tile_height * pos_y)
#         self.abs_pos = (self.rect.x, self.rect.y)
#
#
# class Player(pygame.sprite.Sprite):
#     def __init__(self, pos_x, pos_y):
#         super().__init__(player_group, all_sprites)
#         self.image = player_image
#         self.rect = self.image.get_rect().move(tile_width * pos_x + 15, tile_height * pos_y + 5)
#         self.pos = (pos_x, pos_y)
#
#     def move(self, x, y):
#         camera.dx -= tile_width * (x - self.pos[0])
#         camera.dy -= tile_height * (y - self.pos[1])
#         self.pos = (x, y)
#         for sprite in tiles_group:
#             camera.apply(sprite)
#
#
# class Camera:
#     def __init__(self):
#         self.dx = 0
#         self.dy = 0
#
#     def apply(self, obj):
#         obj.rect.x = obj.abs_pos[0] + self.dx
#         obj.rect.y = obj.abs_pos[1] + self.dy
#
#     def update(self, target):
#         self.dx = 0
#         self.dy = 0
#
#
# def move(hero, movement):
#     x, y = hero.pos
#     if movement == 'up':
#         if y > 0 and level_map[y - 1][x] in '.@':
#             hero.move(x, y - 1)
#     elif movement == 'down':
#         if y < 10 and level_map[y + 1][x] in '.@':
#             hero.move(x, y + 1)
#     elif movement == 'left':
#         if x > 0 and level_map[y][x - 1] in '.@':
#             hero.move(x - 1, y)
#     elif movement == 'right':
#         if x < 10 and level_map[y][x + 1] in '.@':
#             hero.move(x + 1, y)
#
#
# def generate_level(level):
#     new_player, x, y = None, None, None
#     for y in range(len(level)):
#         for x in range(len(level[y])):
#             if level[y][x] == '.':
#                 Tile('empty', x, y)
#             elif level[y][x] == '#':
#                 Tile('wall', x, y)
#             elif level[y][x] == '@':
#                 Tile('empty', x, y)
#                 new_player = Player(x, y)
#     # вернем игрока, а также размер поля в клетках
#     return new_player, x, y
#
#
# def load_level(filename):
#     filename = "data/" + filename
#     # читаем уровень, убирая символы перевода строки
#     try:
#         with open(filename, 'r') as mapFile:
#             level_map = [line.strip() for line in mapFile]
#
#         # и подсчитываем максимальную длину
#         max_width = max(map(len, level_map))
#
#         # дополняем каждую строку пустыми клетками ('.')
#         return list(map(lambda x: x.ljust(max_width, '.'), level_map))
#     except Exception:
#         return 'Error'
#
#
# def terminate():
#     pygame.quit()
#     sys.exit()
#
#
# file_name = ''
# a = load_level(file_name)
# camera = Camera()
# clock = pygame.time.Clock()
#
# player = None
# tile_images = {'wall': load_image('box.png'), 'empty': load_image('grass.png')}
# player_image = load_image('mar.png')
#
# tile_width = tile_height = 50
#
# all_sprites = pygame.sprite.Group()
# tiles_group = pygame.sprite.Group()
# player_group = pygame.sprite.Group()
# sprite_group = pygame.sprite.Group()
#
# level_map = load_level(file_name)
# # player, level_x, level_y = generate_level(a)
# running = True
# camera.update(player)
# while running:
#     for event in pygame.event.get():
#         if event.type == pygame.QUIT:
#             running = False
#         elif event.type == pygame.KEYDOWN:
#             if event.key == pygame.K_UP:
#                 move(player, 'up')
#             elif event.key == pygame.K_DOWN:
#                 move(player, 'down')
#             elif event.key == pygame.K_LEFT:
#                 move(player, 'left')
#             elif event.key == pygame.K_RIGHT:
#                 move(player, 'right')
#
#     screen.fill((0, 0, 0))
#     all_sprites.draw(screen)
#     player_group.draw(screen)
#     clock.tick(FPS)
#     pygame.display.flip()

start_screen()