import numpy as np
from scipy.integrate import odeint

def dry_matter_production(W_p0, LAI0, leaf0, root0, stem0, fruit0, t, t_start,
                          T_average, C_ppm, DIS_1, DIS_2, DIS_3, PAR, TEP,
                          k_ext, WT_1, WT_2, WT_3, C_f, f):
    """Simulates the dry matter production of tomato plant.

    Parameters
    ----------
    W_p0 : float
      Initial dry weight of the whole tomato plant [g DM]
    LAI_0 : float
      Initial leaf area index of the tomato plant [g DM]
    leaf0 : float
      Initial dry weight of the tomato plant leaves [g DM]
    root0 : float
      Initial dry weight of the tomato plant roots [g DM]
    stem0 : float
      Initial dry weight of the tomato plant stem [g DM]
    fruit0 : float
      Initial dry weight of the tomato plant fruits [g DM]
    t : ???
      timestep
    t_start: int
      is the planting data (t_start_th day of the year)
    T_average : float
      the average temperature inside greenhouse
    C_ppm : int
      CO2 concentration
    DIS_i :int
      the distance coefficient of gauss integral (i is the layer number of the canopy layers)
    PAR : int
      photosynthetically active radiation
    TEP : int
      the cumulative PAR
    k_ext: float
      the extinction coefficient of canopy
    WT_i : float
      Weight factor for Gaussian integration
    C_f : float
      Conversion factor from assimilates to dry matter
    f : float
     Regression parameter

    Returns
    -------
    Given a set of initial values (y0) calculated by diff , it returns an array containing the value of y for each
    desired time in t, with the initial value `y0` in the first row.

    Array of values for Leaf Area Index, Whole plant dry weight, & Leaf, stem, fruit, root dry weights.

    Notes
    -----
    # are all the parameters just lists???????
            """

    def diff(y, t):
        """Define state variables (y) at a timestep (t).

        Parameters
        ----------
        y : ???
          list of state variables
        t : ???
          timestep

        Variables
        ---------
        C_a : int
          CO2 concentraion [ppm]
        ghe : float
         'Gamma' the CO2 compensation point in absence of dark respiration
        eps :
          leaf initial light use efficiency [g.CO2.j^−1]
        P_gm : float
          the maximum photosynthesis rate
        R_m : float
          maintenance rate - of respiration?
        dWdt : float
          Whole Plant growth rate
        RGR : float
          Relative Growth Rate
        PIS : float
          Partition Index Shoot
        PIR : float
          Partition Index Root
        d_rootdt : float
          root growth rate
        PIL : float
          Partition Index Leaf
        PIST : float
          Partition Index Stem
        PIF : float
          Partition Index Fruit
        d_leafdt : float
          leaf growth rate
        d_stemdt : float
          stem growth rate
        d_fruitdt : float
          fruit growth rate
        SLA : float
          Specific Leaf Area

        Returns
        -------
        Val - a list of values (rate of change - ODE) calculated for timestep (t):
        Whole plant dry weight
        Leaf Area Index
        Leaf dry weight
        Root dry weight
        Stem dry weight
        fruit dry weight

        Notes
        -----
        # are all the parameters just lists???????
        # check t_maybe and find out which it is t or t_start

                """
        W_p = y[0]  # [g DM]
        LAI = y[1]  # LAI has no unit
        leaf = y[2]  # [g DM]
        root = y[3]  # [g DM]
        stem = y[4]  # [g DM]
        fruit = y[5]  # [g DM]
        # calculate the eps and P_gm based on temperature and co2 concentration
        C_a = C_ppm
        ghe = 42.7 + 1.68 * (T_average - 25) + 0.012 * (T_average - 25) ** 2
        eps = 1.544 * 10 ** -5 * (C_a - ghe) / (C_a + 2 * ghe)
        P_gm = 0.013 * (C_a - ghe)
        # calculate the plant photosynthetic rate [g CO2 m**-2 h**-1]
        P_g = layer_photosyn(eps, P_gm, DIS_1, DIS_2, DIS_3, WT_1, WT_2, WT_3,
                             LAI, PAR, k_ext)

        # simulate growth rate (dry matter production rate) of plant [g DM h**-1]
        # maintenance rate R_m is calculated based on the four type of organs of tomato plant
        R_m = (0.03 * leaf + 0.015 * stem + 0.01 * root +
               0.01 * fruit) / 24 * 2 ** ((T_average - 25) / 10)

        # CO2 released by growth respiration is calculated as a factor times dWdt, for implementation
        # , the equation is divided by 1.191
        dWdt = C_f * (P_g * 30 / 44 - R_m *
                      (1 - np.exp(-f *
                                  (-0.0008 * np.log(W_p) + 0.0055)))) / 1.191
        # RGR is computed by equation -0.0008*np.log(W_p)+0.0055 obtained using linear regression analysis (Appendix 2)
        # 30/44 converts from CO2 to assimilates [g CH2O g**-1 CO2]

        # tomato dry matter partition (first partition to root and shoot)
        # PIS is the partition index of shoot
        # PIR is the partition index of root
        PIS = 1 - 0.12 * np.exp(-TEP / 100)
        PIR = 1 - PIS
        # simulate root growth
        d_rootdt = dWdt * PIR

        # partitioning of leaf, stem and fruit is based on the dry matter partitioned to the shoot
        # PIL is the partition index of leaf
        # PIST is the partition index of stem
        # PIF is the partition index of fruit
        PIL = PIS * (0.23 + 0.59 * np.exp(-TEP / 110))

        # simulate leaf growth rate
        d_leafdt = dWdt * PIL

        PIST = np.piecewise(TEP, [0 <= TEP <= 21, 21 < TEP],
                            [0.02 * TEP, 0.2 + 0.3 * np.exp(-TEP / 108)]) * PIS
        # simulate stem growth rate
        d_stemdt = dWdt * PIST

        PIF = PIS * (1 - PIL - PIST)
        PIF_p = np.piecewise(PIF, [PIF < 0, 0 <= PIF], [0, PIF])

        # simulate fruit growth rate
        d_fruitdt = dWdt * PIF_p
        # simulate specific leaf area based on t_start - t_ could be 't' or 't_start' try both
        t_maybe = t
        SLA = (266 + 88 * np.sin(2 * np.pi *
                                 (t_maybe / 24 + 68 + t_start) / 365)) * 1 * 10 ** -4
        # simulate leaf area index using leaf dry matter production
        d_laidt = np.piecewise(LAI, [0 <= LAI <= 3, LAI > 3],
                               [SLA * d_leafdt, 0])
        val = [dWdt, d_laidt, d_leafdt, d_rootdt, d_stemdt, d_fruitdt]

        return val

    # set initial state for the differential equation
    y0 = np.asarray([W_p0, LAI0, leaf0, root0, stem0, fruit0])
    # solve the differential equation using ‘odeint’ (integrate a system of ordinary differential equations)
    rez = odeint(diff, y0, t, full_output=0)
    return rez


#!/usr/bin/env python3
#
# SPDX-License-Identifier: MIT
#
# This file is formatted with Python Black
#

import attr
import enum
import logging

from typing import List

from gi.repository import GObject

import ratbag
import ratbag.hid
import ratbag.driver
import ratbag.util
from ratbag.parser import Spec, Parser

logger = logging.getLogger(__name__)

class OIPage(enum.IntEnum):
    INFO = 0x00
    GIMMICKS = 0xFD
    DEBUG = 0xFE
    ERROR = 0xFF

class OIFunction(enum.IntEnum):
    VERSION = 0x00
    FW_INFO = 0x01
    SUPPORTED_FUNCTION_PAGES = 0x02
    SUPPORTED_FUNCTIONS = 0x03

class OIFWField(enum.IntEnum):
    VENDOR = 0x00
    VERSION = 0x01
    NAME = 0x02

class OIError(enum.IntEnum):
    INVALID_VALUE = 0x01
    UNSUPPORTED_FUNCTION = 0x02
    CUSTOM = 0xFE

class ReportID(enum.IntEnum):
    SHORT = 0x20
    LONG = 0x21

    @property
    def size(self):
        return {
            ReportID.SHORT: 8,
            ReportID.LONG: 32,
        }[self]

REPORT_RATES = (125, 250, 500, 750, 1000)

@attr.s
class Query(object):
    device: ratbag.driver.Rodent = attr.ib()
    report_id: ReportID = attr.ib(
        default=ReportID.SHORT, validator=attr.validators.in_(ReportID)
    )
    query_spec: List[Spec] = attr.ib(default=attr.Factory(list))
    reply_spec: List[Spec] = attr.ib(default=attr.Factory(list))

    def run(self):
        # header is always the same
        spec = [
            Spec("B", "report_id"),
            Spec("B", "function_page"),
            Spec("B", "function"),
        ] + self.query_spec
        query = Parser.from_object(self, spec, pad_to=self.report_id.size)

        self.device.send(bytes(query))
        reply = self.device.recv()
        self.reply = self._autoparse(reply)
        self.parse_reply(reply)
        return self

    def _autoparse(self, bytes):
        if not self.reply_spec:

            class ReplyObject(object):
                pass

            return ReplyObject()

        spec = [
            Spec("B", "report_id"),
            Spec("B", "function_page"),
            Spec("B", "function"),
        ] + self.reply_spec

        result = Parser.to_object(bytes, spec)
        return result.object

    def parse_reply(self, data: bytes):
        """
        Override this in the subclass if :attr:`reply_spec` autoparsing is
        insufficient. Parse the given bytes and set the required instance
        attributes. :attr:`reply` is set with the bytes from the reply.
        """
        pass

@attr.s
class QueryFWVersion(Query):
    report_id = attr.ib(default=ReportID.SHORT)
    function_page = attr.ib(default=OIPage.INFO)
    function = attr.ib(default=OIFunction.VERSION)
    query_spec = attr.ib(default=attr.Factory(list))
    reply_spec = attr.ib(
        default=[
            Spec("B", "major"),
            Spec("B", "minor"),
            Spec("B", "patch"),
        ]
    )

    @classmethod
    def instance(cls, device):
        return cls(device=device)

@attr.s
class QueryFWInfo(Query):
    report_id = attr.ib(default=ReportID.SHORT)
    function_page = attr.ib(default=OIPage.INFO)
    function = attr.ib(default=OIFunction.FW_INFO)
    field_id: OIFWField = attr.ib(default=OIFWField.VERSION)
    query_spec = attr.ib(
        default=[
            Spec("B", "field_id"),
        ]
    )
    reply_spec = attr.ib(
        default=[
            Spec(
                "B",
                "string",
                greedy=True,
                convert_from_data=lambda s: bytes(s).decode("utf-8"),
            )
        ]
    )

    @classmethod
    def instance(cls, device, field_id: OIFWField):
        return cls(device=device, field_id=field_id)

@attr.s
class QuerySupportedPages(Query):
    report_id = attr.ib(default=ReportID.SHORT)
    function_page = attr.ib(default=OIPage.INFO)
    function = attr.ib(default=OIFunction.SUPPORTED_FUNCTION_PAGES)
    start_index = attr.ib(default=0)
    query_spec = attr.ib(
        default=[
            Spec("B", "start_index"),
        ]
    )
    reply_spec = attr.ib(
        default=[
            Spec("B", "count"),
            Spec("B", "remaining"),
            Spec("B", "pages", greedy=True),
        ]
    )

    @classmethod
    def instance(cls, device, start_index: int):
        return cls(device=device, start_index=start_index)

@attr.s
class QuerySupportedFunctions(Query):
    report_id = attr.ib(default=ReportID.SHORT)
    function_page = attr.ib(default=OIPage.INFO)
    function = attr.ib(default=OIFunction.SUPPORTED_FUNCTIONS)
    page = attr.ib(default=0)
    start_index = attr.ib(default=0)
    query_spec = attr.ib(
        default=[
            Spec("B", "page"),
            Spec("B", "start_index"),
        ]
    )
    reply_spec = attr.ib(
        default=[
            Spec("B", "count"),
            Spec("B", "remaining"),
            Spec("B", "functions", greedy=True),
        ]
    )

    @classmethod
    def instance(cls, device, page: int, start_index: int):
        return cls(device=device, page=page, start_index=start_index)

class OpenInputDevice(GObject.Object):
    def __init__(self, driver, rodent):
        GObject.Object.__init__(self)
        self.driver = driver
        self.rodent = rodent

    def start(self):
        output_reports = self.rodent.report_ids["output"]
        input_reports = self.rodent.report_ids["input"]
        if ReportID.SHORT not in output_reports or ReportID.SHORT not in input_reports:
            raise ratbag.driver.SomethingIsMissingError.from_rodent(
                self.rodent, "Missing Report ID {ReportID.SHORT.value:0x}"
            )

        query = QueryFWVersion.instance(self.rodent).run()
        logger.debug(
            f"protocol version {query.reply.major}.{query.reply.minor}.{query.reply.patch}"
        )

        vendor = QueryFWInfo.instance(self.rodent, OIFWField.VENDOR).run().reply.string
        version = (
            QueryFWInfo.instance(self.rodent, OIFWField.VERSION).run().reply.string
        )
        name = QueryFWInfo.instance(self.rodent, OIFWField.NAME).run().reply.string

        logger.debug(f"FW vendor: {vendor}, version: {version}, name: {name}")

        pages = []
        offset = 0
        while True:
            query = QuerySupportedPages.instance(self.rodent, offset).run()
            pages.extend(query.reply.pages[: query.reply.count])
            if query.reply.remaining <= 0:
                break

        logger.debug(f"Pages: {[OIPage(p) for p in pages]}")

        for p in pages:
            functions = []
            offset = 0
            while True:
                query = QuerySupportedFunctions.instance(self.rodent, p, offset).run()
                functions.extend(query.reply.functions[: query.reply.count])
                if query.reply.remaining <= 0:
                    break
            logger.debug(f"Page {p}: {[OIFunction(f) for f in functions]}")

        # This code is a port from the libratbag openinput driver. Which
        # does... nothing. It inits some profiles with hardcode values but
        # other than that - nothing.
        raise ratbag.driver.SomethingIsMissingError.from_rodent(
            self.rodent, "This driver doesn't do anything else...oops "
        )

@ratbag.driver.ratbag_driver("openinput")
class OpenInputDriver(ratbag.driver.HidrawDriver):
    def probe(
        self,
        rodent: ratbag.driver.Rodent,
        config: ratbag.driver.DeviceConfig,
    ) -> None:
        # This is the device that will handle everything for us
        roccat_device = OpenInputDevice(self, rodent)

        # Calling start() will make the device talk to the physical device
        ratbag_device = roccat_device.start()
        self.emit("device-added", ratbag_device)


# -*- coding: utf-8 -*-
"""
Created on Tue Mar 10 14:56:19 2020

@author: kse18nru
"""

#%% Import modules and scripts
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import iris
import iris.coord_categorisation
import iris.plot as iplt
import model_foundry as foundry
import pandas as pd

#%% global definitions
Case = '0p5km'
variable = 'air_potential_temperature'

if Case == '0p5km':
    #%% first load and extract data
    thcube = iris.load_cube(f'../../Model_Data/u-bk574/nc/Control/{variable}/{Case}_{variable}_24hrs.nc', variable)
    thdata = thcube.data
    lmcube = iris.load_cube(f'../../Model_Data/u-bk574/nc/Control/land_binary_mask/{Case}_land_binary_mask_301.nc')
    lmdata = lmcube.data
    model_lat = thcube.coord('grid_latitude').points
    model_lon = thcube.coord('grid_longitude').points
    polelat = thcube.coord('grid_latitude').coord_system.grid_north_pole_latitude
    polelon = thcube.coord('grid_longitude').coord_system.grid_north_pole_longitude
    ## free up memory/ unpoint cubes
    thcube = None

    #%% unrotate pole
    lons, lats = foundry.modf.unrotate_coords(model_lon, model_lat, polelon, polelat)

    #%% make plots
    counter = 0
    for level in range(20):
        for time in range(48):
            if level == 19:
                if time == 30:
                    counter = level*time + 1 + time; print('counter:',counter, 'time:', time, 'level:', level)
                    fig0,ax0, my_norm = foundry.plot_hoz_xsec_mass(thdata, lmdata, model_lon, model_lat, lons, lats, model_lon, model_lat, time, level,
                                                                     data_label = r'w, [ms$^{-1}$]', domain = 'fulldomain',
                                                                     flight = 301, savefig = False, res = '0p5km', unrotated = False,
                                                                     variable_name = 'Potential temperature', time_norm = False,
                                                                     variable_in_file_name = 'air_potential_temperature',
                                                                     figure_path_pdf = f'../../Figures/PDF/301/Model_levels/{variable}/Horizontal/{Case}',
                                                                     figure_path_png = f'../../Figures/PNG/301/Model_levels/{variable}/Horizontal/{Case}',
                                                                     contour_type = 'pcolor', colourmap = 'plasma')

                    #%% load 60s dataset from database

                    # using pandas
                    database = pd.read_csv('../../Obvs_Data/Databases/IGP_flights_database_obs_60s_301.txt', delimiter = ' ')
                    #print(database['meantime'])
                    #print(database[['altgps', 'lon', 'lat']])
                    leg = 6
                    db_leg = np.array(database['legno'])
                    db_alt = np.array(database['altgps'])[np.where(db_leg == leg)]
                    db_theta = np.array(database['theta'])[np.where(db_leg == leg)]
                    db_lon = np.array(database['lon'])[np.where(db_leg == leg)]
                    db_lat = np.array(database['lat'])[np.where(db_leg == leg)]
                    db_time = np.array(database['meantime'])[np.where(db_leg == leg)]/3600 # mean time coordinate in hours
                    print(np.mean(db_alt), 'm')
                    print(db_theta)
                    #%% Rotate coordinates to model frame
                    # extract rotated north pole coordinates
                    NPoleLon = lmcube.coord('grid_longitude').coord_system.grid_north_pole_longitude
                    NPoleLat = lmcube.coord('grid_latitude').coord_system.grid_north_pole_latitude
                    # rotate database coordinates
                    db_rot_lon, db_rot_lat = iris.analysis.cartography.rotate_pole(db_lon, db_lat, NPoleLon, NPoleLat)

                    q = ax0.scatter(db_rot_lon + 360, db_rot_lat, db_theta, norm = my_norm, cmap = 'plasma')

                    plt.show()

 #%%
if Case == '1p5km':
    #%% first load and extract data
    thcube = iris.load_cube(f'../../Model_Data/u-bk574/nc/Control/{variable}/{Case}_{variable}_24hrs.nc', variable)
    thdata = thcube.data
    lmcube = iris.load_cube(f'../../Model_Data/u-bk574/nc/Control/land_binary_mask/{Case}_land_binary_mask_301.nc')
    lmdata = lmcube.data
    model_lat = thcube.coord('grid_latitude').points
    model_lon = thcube.coord('grid_longitude').points
    polelat = thcube.coord('grid_latitude').coord_system.grid_north_pole_latitude
    polelon = thcube.coord('grid_longitude').coord_system.grid_north_pole_longitude
    ## free up memory/ unpoint cubes
    thcube = None; lmcube = None

    #%% Subset to fit 0p5km domain
    ## boundaries (in points):
    South = 90; North = 320; West = 75; East = 215

    # subset 4d data
    sub_data_region1 = foundry.modf.subset_4d(thdata, South, North, West, East)

    # two-dimensional subsetting of land-mask
    sub_land_region1 = foundry.modf.subset_2d(lmdata, South, North, West, East )

    # subset coordinates and unrotate
    sub_lon1 = foundry.modf.subset_1d(model_lon, West, East)
    sub_lat1 = foundry.modf.subset_1d(model_lat, South, North)
    #%% unrotate pole
    lons, lats = foundry.modf.unrotate_coords(sub_lon1, sub_lat1, polelon, polelat)

    #%% make plots
    counter = 0
    for level in range(20):
        for time in range(48):
            counter = level*time + 1 + time; print('counter:',counter, 'time:', time, 'level:', level)
            fig0,ax0 = foundry.plot_hoz_xsec_mass(sub_data_region1, sub_land_region1, sub_lon1, sub_lat1, lons, lats, sub_lon1, sub_lat1, time, level,
                                                             data_label = r'w, [ms$^{-1}$]', domain = 'fulldomain',
                                                             flight = 301, savefig = True, res = '1p5km', unrotated = False,
                                                             variable_name = 'Potential temperature', time_norm = False,
                                                             variable_in_file_name = 'air_potential_temperature',
                                                             figure_path_pdf = f'../../Figures/PDF/301/Model_levels/{variable}/Horizontal/{Case}',
                                                             figure_path_png = f'../../Figures/PNG/301/Model_levels/{variable}/Horizontal/{Case}',
                                                             contour_type = 'pcolor', colourmap = 'plasma')

            plt.close()


import json
import requests
from bs4 import BeautifulSoup

def DumpChannelsFromNAVER():
  """
  네이버에서 제공하는 EPG의 채널 목록을 파싱합니다. \n
  @return [
    {
      'Name': '채널이름',
      'Source': 'NAVER',
      'ServiceId': '서비스ID',
      'Query': 'Search Term'
    }
  ] \n
  @request_count: 6
  """

  print('Naver에서 정보를 가져오고 있습니다 . . .')

  URL = "https://m.search.naver.com/p/csearch/content/nqapirender.nhn"
  UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0'
  category = [
    {'name': '지상파', 'u1':'100'},
    {'name': '종합 편성', 'u1': '500'},
    {'name': '케이블', 'u1': '200'},
    {'name': '스카이라이프', 'u1': '300'},
    {'name': '해외위성', 'u1': '9000'},
    {'name': '라디오', 'u1': '400'}
  ]

  result = []
  for cat in category:
    params = {
      'pkid': '66',
      'where': 'nexearch',
      'u1': cat['u1'],
      'key': 'ScheduleChannelList'
    }

    try:
      req = requests.get(URL, headers={'User-Agent': UA}, params=params)
      print('Status Code: ', req.status_code)
    except Exception as e:
      print('API 요청 중 에러: %s' % str(e))

    html = BeautifulSoup(json.loads(req.text)['dataHtml'], 'html.parser')
    channels = html.select('li.item')

    for channel in channels:
      ch_name = channel.find('div', attrs={'class': "channel_name"}).string
      ch_id = channel.find('div', attrs={'class': "u_likeit_list_module _reactionModule zzim"})['data-cid']
      ch_query = channel.find('a', attrs={'class': 'lk'})['href']

      result.append({
        'Name': str(ch_name).strip(),
        'Source': 'NAVER',
        'ServiceId': ch_id.strip(),
        'Query': ch_query.strip()
      })

  return result


from flask import Flask
from flask_cors import CORS, cross_origin  #Para poder atender las peticiones localmente
from flask import jsonify
from persontext import predict_personalidad
import os

app = Flask(__name__)

#Para poder atender las peticiones locales
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'

APP_ROOT=os.path.dirname(os.path.abspath(__file__))

@app.route('/')
def home():
    """
    Página inicial
    """
    return "<h1>Bienvenidos a ApiPersonText v0.12<h1>"

@app.errorhandler(404)
def resource_not_found(e):
    return jsonify(error=str(e)), 404

@app.route('/persontext/apertura/<texto>',methods=["GET","POST"])
@cross_origin() #Para poder atender las peticiones locales
def persontext_apertura(texto):
    datos = {}
    prediccion = predict_personalidad("apertura", texto.lower())
    datos["presenta_personalidad"] = prediccion
    return jsonify(datos)

@app.route('/persontext/responsabilidad/<texto>',methods=["GET","POST"])
@cross_origin() #Para poder atender las peticiones locales
def persontext_responsabilidad(texto):
    datos = {}
    prediccion = predict_personalidad("responsabilidad", texto.lower())
    datos["presenta_personalidad"] = prediccion
    return jsonify(datos)

@app.route('/persontext/sociabilidad/<texto>',methods=["GET","POST"])
@cross_origin() #Para poder atender las peticiones locales
def persontext_sociabilidad(texto):
    datos = {}
    prediccion = predict_personalidad("sociabilidad", texto.lower())
    datos["presenta_personalidad"] = prediccion
    return jsonify(datos)

@app.route('/persontext/amabilidad/<texto>',methods=["GET","POST"])
@cross_origin() #Para poder atender las peticiones locales
def persontext_amabilidad(texto):
    datos = {}
    prediccion = predict_personalidad("amabilidad", texto.lower())
    datos["presenta_personalidad"] = prediccion
    return jsonify(datos)

@app.route('/persontext/neuroticismo/<texto>',methods=["GET","POST"])
@cross_origin() #Para poder atender las peticiones locales
def persontext_neuroticismo(texto):
    datos = {}
    prediccion = predict_personalidad("neuroticismo", texto.lower())
    datos["presenta_personalidad"] = prediccion
    return jsonify(datos)

if __name__ == "__main__":
   app.run() ##Replaced with below code to run it using waitress
   #serve(app, host='0.0.0.0', port=5000, url_scheme='https')


from __future__ import print_function
import os
import re
import sys
import argparse
import gfapy
from Bio import SeqIO

#----------------------------------------------------
# Arg parser
#----------------------------------------------------
parser = argparse.ArgumentParser(prog="vcf2gfa.py", usage="%(prog)s -vcf <vcfFile.vcf> -fa <fastaFile.fasta> -out <outputGFAFile> [options]", \
                                formatter_class=argparse.RawTextHelpFormatter, \
                                description=("Convert a VCF file containing the insertions coordinates to a GFA file (GFA 2.0). We can filter the insertions by the contigs' sizes on both sides (long enough for ex to get enough barcodes). As for some insertions, there are a few micro-homologies (mh), we are not sure that the given position in the VCF file is the exact position, so extend the insertion by '--extension' bp on both sides of the insertion"))

parser.add_argument("-vcf", dest="vcf", action="store", help="VCF file containing the insertions coordinates (format: 'xxx.vcf')", required=True)
parser.add_argument("-fa", dest="fasta", action="store", help="FASTA file of the reference genome (format: 'xxx.fasta' or 'xxx.fa')", required=True)
parser.add_argument("-contigs", dest="contigs_size", action="store", type=int, help="Minimum size of the flanking contigs of the insertion to treat as a target")
parser.add_argument("-extension", dest="ext_size", action="store", type=int, default=50, help="Size of the extension of the Indel (bp): extend the Indel by '--extension' bp on both sides of the Indel [default: 50]")
parser.add_argument("-out", dest="outGFA", action="store", help="Name of the output GFA file")

args = parser.parse_args()

if re.match('^.*.vcf$', args.vcf) is None:
    parser.error("The suffix of the input VCF file should be: '.vcf'")

if (re.match('^.*.fasta$', args.fasta) is None) and (re.match('^.*.fa$', args.fasta) is None):
    parser.error("The suffix of the input FASTA file should be: '.fasta' or '.fa'")

#----------------------------------------------------
# Input files
#----------------------------------------------------
# VCF file.
vcfFile = os.path.abspath(args.vcf)
if not os.path.exists(args.vcf):
    parser.error("The path of the input VCF file doesn't exist")
vcf_name = vcfFile.split('/')[-1]
print("\nInput VCF file: " + vcfFile)

# FASTA file.
fastaFile = os.path.abspath(args.fasta)
if not os.path.exists(args.fasta):
    parser.error("The path of the input FASTA file doesn't exist")
fasta_name = fastaFile.split('/')[-1]
print("Input FASTA file: " + fastaFile)

#----------------------------------------------------
# Directory for saving results
#----------------------------------------------------
cwd = os.getcwd()
outDir = cwd
print("\nThe results are saved in " + outDir)

#----------------------------------------------------
# VCF to GFA
#----------------------------------------------------
try:
    # Create a dictionary containing the Indels' coordinates for each scaffold.
    indels_Coords = {}

    # Iterate over the variants in the VCF file.
    with open(vcfFile, "r") as vcf_file:
        for line in vcf_file:
            if line.startswith("#"):
                continue
            else:
                chrom, pos, sv_id, ref, alt, __, __, info, *__ = line.rstrip().split("\t")
                sv_type = str(info).split('SVTYPE=')[1].split(';')[0]

                # Process the Indels.
                if (sv_type == "INS") or (sv_type == "DEL"):

                    ## Get the start and end positions of the Indel' coordinates.
                    indelCoord_start = int(pos) - args.ext_size
                    end_pos = str(info).split('END=')[1]
                    if ";" in end_pos:
                        end_pos = end_pos.split(';')[0]
                    indelCoord_end = int(end_pos) + args.ext_size

                    ## Get the size of the Indel region (e.g. the target size).
                    target_size = indelCoord_end - indelCoord_start

                    ## Append the dictionary 'indels_Coords' with the Indels' coordinates (e.g. targets) for each scaffold.
                    ## key = scaffold_name ; value = list of positions of targets
                    if chrom in indels_Coords:
                        indels_Coords[chrom].append([indelCoord_start, indelCoord_end])
                    else:
                        indels_Coords[chrom] = [[indelCoord_start, indelCoord_end]]

    # For each Indel, get the Indels' length and the left and right flanking sequences.
    with open(fastaFile, "r") as fasta_file:
        for record in SeqIO.parse(fasta_file, "fasta"):
            if record.id in indels_Coords:

                # Iterate over the Indels of 'indels_Coords' for each scaffold.
                indels_coordinatesList = indels_Coords[record.id]
                indels_coordinatesList.sort()
                for i in range(len(indels_coordinatesList)):

                    # Get the length of the Indel.
                    indel_length = int(indels_coordinatesList[i][1]) - int(indels_coordinatesList[i][0])

                    # Get the left flanking sequence.
                    if i == 0:      #first target
                        left_start_index = 0
                        left_end_index = indels_coordinatesList[i][0]
                    else:
                        left_start_index = indels_coordinatesList[i-1][1]
                        left_end_index = indels_coordinatesList[i][0]
                    left_flanking_seq = record.seq[int(left_start_index):int(left_end_index)]

                    # Get the right flanking sequence.
                    if i == len(indels_coordinatesList)-1:     #last target
                        right_start_index = indels_coordinatesList[i][1]
                        right_end_index = len(record.seq)
                    else:
                        right_start_index = indels_coordinatesList[i][1]
                        right_end_index = indels_coordinatesList[i+1][0]
                    right_flanking_seq = record.seq[int(right_start_index):int(right_end_index)]

                    # If left and right sequences > 'contigs_size', add the Indel/target to the output GFA file.
                    if (args.contigs_size is not None) and (len(left_flanking_seq) < int(args.contigs_size)) and (len(right_flanking_seq) < int(args.contigs_size)):
                        continue
                    else:
                        os.chdir(outDir)

                        #----------------------------------------------------
                        # FASTA files (left/right sequences)
                        #----------------------------------------------------
                        if args.contigs_size is None:
                            minContigSize = "noMinFlank"
                        else:
                            minContigSize = args.contigs_size

                        # Left flanking contig.
                        left_name = str(record.id) +"_"+ str(left_start_index) +"-"+ str(left_end_index) +"-L"
                        left_contig = left_name + "+"
                        left_length = len(left_flanking_seq)

                        # Right flanking contig.
                        right_name = str(record.id) +"_"+ str(right_start_index) +"-"+ str(right_end_index) +"-R"
                        right_contig = right_name + "+"
                        right_length = len(right_flanking_seq)

                        # Output FASTA files containing the flanking sequences of the current gap.
                        ##Left
                        left_fastaFile = os.path.abspath(fasta_name.split(".fa")[0] + "_" + str(record.id) +"_"+ str(left_start_index) +"-"+ str(left_end_index) +".g"+ str(indel_length) + ".left.fasta")
                        with open(left_fastaFile, "w") as left:
                            left.write(">{} _ len {}".format(left_name, str(left_length)))
                            left.write("\n" + str(left_flanking_seq) + "\n")

                        ##Right
                        right_fastaFile = os.path.abspath(fasta_name.split(".fa")[0] + "_" + str(record.id) +"_"+ str(right_start_index) +"-"+ str(right_end_index) +".g"+ str(indel_length) + ".right.fasta")
                        with open(right_fastaFile, "w") as right:
                            right.write((">{} _ len {}".format(right_name, str(right_length))))
                            right.write("\n" + str(right_flanking_seq) + "\n")

                        #----------------------------------------------------
                        # GFA file
                        #----------------------------------------------------
                        os.chdir(outDir)
                        if args.outGFA is not None:
                            gfaFile = os.path.abspath(str(args.outGFA))
                        else:
                            gfaFile = os.path.abspath(fasta_name.split(".fa")[0] + "_indels_extension_" + str(args.ext_size) + "_contigs_" + str(minContigSize) + ".gfa")

                        # Initiate the GFA file.
                        if not os.path.exists(gfaFile):
                            with open(gfaFile, "w") as f:
                                gfa = gfapy.Gfa()
                                gfa.add_line("H\tVN:Z:2.0")
                                gfa.to_file(gfaFile)

                        # Add corresponding lines to the GFA file.
                        with open(gfaFile, "a") as f:
                            gfa = gfapy.Gfa.from_file(gfaFile)
                            gfa.add_line("S\t{}\t{}\t*\tUR:Z:{}".format(left_name, left_length, os.path.join(outDir, left_fastaFile)))
                            gfa.add_line("S\t{}\t{}\t*\tUR:Z:{}".format(right_name, right_length, os.path.join(outDir, right_fastaFile)))
                            gfa.add_line("G\t*\t{}\t{}\t{}\t*".format(left_contig, right_contig, indel_length))
                            gfa.to_file(gfaFile)

except Exception as e:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
    print("\nException-")
    print(exc_type, fname, exc_tb.tb_lineno)
    sys.exit(1)

print("\nThe output GFA file and the corresponding FASTA files are saved in " + outDir)
print("Output GFA file: " + gfaFile)


import cv2
import numpy as np
def neg(event,x,y,flags,param):
    global x_in, y_in,drawing,tl,br

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing=True
        x_in,y_in=x,y
    elif event==cv2.EVENT_MOUSEMOVE:
        if drawing:
            tl=(min(x_in,x),min(y_in,y))
            br=(max(x_in,x),max(y_in,y))
            #img[y_init:y,  x_init:x]=255   -	img[y_init:y,x_init:x]
    elif event==cv2.EVENT_LBUTTONUP:
        drawing= False
        tl=(min(x_in,x),min(y_in,y))
        br=(max(x_in,x),max(y_in,y))
        #img[y_in:y, x_in:x]=255-img[y_in:y, x_in:x]
if __name__=='__main__'        :
    drawing = False
    tl,br=(-1,-1),(-1,-1)
    cam=cv2.VideoCapture(0)

    if not cam.isOpened():
        raise IOError("Cam not open")
    cv2.namedWindow('webcam')
    cv2.setMouseCallback('webcam',neg)
    while True:
        ret,frame=cam.read()
        img=cv2.resize(frame,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)
        (x0,y0),(x1,y1)=tl,br
        img[y0:y1,x0:x1]=255-img[y0:y1,x0:x1]
        cv2.imshow('webcam',img)

        c=cv2.waitKey(1)
        if c==27:
            break
    cap.release()
    cv2.destroyAllWindows()


import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data.sampler import SubsetRandomSampler

import numpy as np
import scipy
import pdb
import json

def test(model, test_loader, device):
    test_loss = 0
    correct = 0
    model.eval()
    with torch.no_grad():
        predictions, probs = [], []
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()    # sum up batch loss
            pred = output.argmax(dim=1, keepdim=True)    # get the index of the max log-probability
            correct += pred.eq(target.view_as(pred)).sum().item()
            predictions.append(pred.cpu())
            probs.append(output.cpu())
    predictions = np.concatenate(predictions).reshape(-1)
    probs = np.concatenate(probs)
    acc = correct / len(predictions)
    return test_loss, acc, predictions, probs

def train(model, train_loader, valid_loader, device,
                    EPOCHS=50, LOG_INTERVAL=10, PATIENCE=5, verbose=True):
    optimizer = optim.Adam(model.parameters(), weight_decay=3/len(train_loader.dataset))
    batch_idx = 0
    best_acc, patience = -1, 0
    for epoch in range(1, EPOCHS+1):
        model.train()
        total_loss = 0.
        for data, color, target in train_loader:
            data, target = data.to(device), target.to(device)
            batch_idx += 1
            optimizer.zero_grad()
            output = model(data)
            loss = F.nll_loss(output, target)
            loss.backward()
            optimizer.step()

            total_loss += loss.item()

        # calculate validation
        valid_loss, valid_acc, predictions, probs = test(model, valid_loader, device)
        if valid_acc > best_acc:
            best_acc = valid_acc
        else:
            patience += 1

        if epoch % LOG_INTERVAL == 1 and epoch != 1 and verbose:
            print(' | Epoch %d: valid loss %.2f, valid accuracy %.2f' % (epoch, valid_loss, valid_acc))

        if patience == PATIENCE:
            break

    if verbose:
        print(' | Final epoch %d: valid loss %.2f, valid accuracy %.2f' % (epoch, valid_loss, valid_acc))

def random_sampling(model, train_loader, pool_idx, n, device):
    return np.random.choice(pool_idx, size=n)

def uncertainty_sampling(model, train_loader, pool_idx, n, device):
    # generate answers
    outputs = []
    model.eval()
    with torch.no_grad():
        for data, target in train_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            outputs.append(output.cpu())

    outputs = np.concatenate(outputs)

    # max entropy
    probs = scipy.special.softmax(outputs, axis=1)
    H = scipy.stats.entropy(probs, axis=1)
    #results.add_result('probs', probs.tolist())

    sorted_idx = H.argsort()
    sorted_idx = sorted_idx[np.isin(sorted_idx, pool_idx)]

    # larger is more uncertain
    return sorted_idx[:-n-1:-1]

def sample_balanced(pool_idx, n_per_class, targets, classes):
    idxs = []
    for c in classes:
        pool_class_idx = pool_idx[targets == c]
        idx = np.random.choice(pool_class_idx, size=n_per_class)
        idxs.append(idx)
    return np.concatenate(idxs)

class al_results:
    def __init__(self):
        self.rounds = []

    def add_round(self):
        self.rounds.append({})

    def add_result(self, key, result):
        self.rounds[-1][key] = result

    def save(self, path):
        with open(path, 'wt') as fh:
            lines = [ json.dumps(d) for d in self.rounds ]
            fh.write('\n'.join(lines))

def active_learning(sampling_func, model_class, dataset1, train_loader, valid_loader, test_loader,
        classes, pool_idx, device, verbose=True, ROUNDS=50, TOTAL_DATA=1000, batch_size=8, **kwargs):
    # sample balanced
    DATA_PER_ROUND = int(TOTAL_DATA / ROUNDS)
    train_idx = sample_balanced(pool_idx, int(DATA_PER_ROUND/len(classes)), dataset1.targets[pool_idx], classes)
    pool_idx = np.setdiff1d(pool_idx, train_idx)

    global results
    results = al_results()

    for round in range(1, ROUNDS+1):
        print('Round %d: %d training points' % (round, len(train_idx)))
        results.add_round()
        train_sampler = SubsetRandomSampler(train_idx)
        it_train_loader = torch.utils.data.DataLoader(dataset1, sampler=train_sampler, batch_size=batch_size)

        # train
        model = model_class()
        model.to(device)
        train(model, it_train_loader, valid_loader, device, **kwargs)

        # test
        test_loss, test_acc, predictions, probs = test(model, test_loader, device)
        results.add_result('train_size', len(train_idx))
        results.add_result('train_idx', train_idx.tolist())
        results.add_result('test_acc', test_acc)
        results.add_result('test_predictions', predictions.tolist())

        # sample
        new_idx = sampling_func(model, train_loader, pool_idx, DATA_PER_ROUND, device)
        train_idx = np.concatenate([train_idx, new_idx])
        pool_idx = np.setdiff1d(pool_idx, train_idx)

        if verbose:
            print('Test loss %.2f, test acc %.2f' % (test_loss, test_acc))
            print()

    return results


import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np

class Trainer:
    def __init__(self, model, learning_rate, gamma):
        self.model = model
        self.learning_rate = learning_rate
        self.gamma = gamma
        self.optimizer = optim.Adam(model.parameters(), lr=self.learning_rate)
        self.loss_func = nn.MSELoss()

    def _reshape(self, state, action, reward, next_state, game_over):
        state = torch.unsqueeze(state, 0)
        next_state = torch.unsqueeze(next_state, 0)
        action = torch.unsqueeze(action, 0)
        reward = torch.unsqueeze(reward, 0)
        game_over = (game_over, )

        return state, action, reward, next_state, game_over

    def _use_gpu(self, state, action, reward, next_state):
        state.cuda()
        next_state.cuda()
        action.cuda()
        reward.cuda()

    def train_step(self, state, action, reward, next_state, game_over):
        state = torch.tensor(np.array(state), dtype=torch.float)
        next_state = torch.tensor(np.array(next_state), dtype=torch.float)
        action = torch.tensor(np.array(action), dtype=torch.float)
        reward = torch.tensor(np.array(reward), dtype=torch.float)

        self._use_gpu(state, action, reward, next_state)

        if len(state.shape) == 1:
            state, action, reward, next_state, game_over = self._reshape(state, action, reward, next_state, game_over)

        # prediction of Q values in current state
        pred = self.model(state)

        target = pred.clone()

        for index, item in enumerate(game_over):
            Q_new = reward[index]
            if not game_over[index]:
                Q_new = reward[index] + self.gamma * torch.max(self.model(next_state[index]))

            target[index][torch.argmax(action).item()] = Q_new

        self.optimizer.zero_grad()
        loss = self.loss_func(target, pred)
        loss.backward()

        self.optimizer.step()


"""
This module provides a simple lazy-loading mechanism for various libraries.
"""
from typing import Callable, cast, Generic, Set, TypeVar

_lazy_attribute_blacklist: Set[str] = set([
    # IPython
    "_ipython_canary_method_should_not_exist_",
    "_ipython_display_",
    "_repr_mimebundle_",
    "_repr_html_",
    "_repr_markdown_",
    "_repr_svg_",
    "_repr_png_",
    "_repr_pdf_",
    "_repr_jpeg_",
    "_repr_latex_",
    "_repr_json_",
    "_repr_javascript_"
])

T = TypeVar("T")

class LazyWrapper(Generic[T]):
    """
    Lazily load/create an object.
    """
    def __init__(self, name: str, factory: Callable[[], T]):
        self.__name = name
        self.__factory = factory
        self.__wrapped_object = None

    @property
    def __is_loaded__(self):
        return self.__wrapped_object is not None

    def __load__(self) -> T:
        if self.__wrapped_object is None:
            self.__wrapped_object = self.__factory()
        return self.__wrapped_object

    @property
    def __wrapped_object__(self):
        return self.__load__()

    def __call__(self, *args, **kwargs):
        obj = self.__wrapped_object__
        return obj(*args, **kwargs) # type: ignore

    def __getattr__(self, attr):
        if self.__wrapped_object is not None and attr in _lazy_attribute_blacklist:
            raise AttributeError(f"Attribute {attr} is not available.")
        return getattr(self.__wrapped_object__, attr)

    def __repr__(self):
        return f"LazyObject({self.__name})"

def lazy_wrapper(factory: Callable[[], T]) -> T:
    """
    A decorator to lazily evaluate a function while providing all available type information.

    In most situations, the import function must be defined in the following format:

    ```py
    @lazy_wrapper
    def name():
        import name
        return name
    ```

    When dealing with local imports, it may be necessary to delete the globals.

    ```py
    @lazy_wrapper
    def name():
        del globals()["name"]
        from . import name
        return name
    ```
    """
    return cast(T, LazyWrapper(factory.__name__, factory))


# -*- coding: utf-8 -*-
"""
Created on Wed Jan 27 19:01:20 2021

@author: Muhammad Waseem
"""
from subprocess import call
import tkinter as tk
from tkinter import*
from PIL import Image,ImageTk,ImageDraw

class Wellcome_Window:
    def __init__(self,root):
        self.root=root
        self.root.title('WELCOME')
        self.root.geometry('1350x700+0+0')
        self.root.config(bg='#08A3D2')
       # title=Label(self.root,text="Welcome to Black Box",font=('time new roman',50,'bold'),bg='#04444a',fg='white').place(x=0,y=5,relwidth=1)
        #BACKGROUND
        #FRAME
        main_frame=Frame(self.root,bg='white')
        main_frame.place(x=250,y=100,width=900,height=500)

        title=Label(main_frame,text='UNIVERSITY OF BALTISTAN,SKARDU',font=('time new roman',25,'bold'),bg='white',fg='green').place(x=250,y=50)

        project=Label(main_frame,text='(Two Step Encryption,Decryption)',font=('time new roman',20,'bold'),bg='white',fg='gray').place(x=270,y=150)

        btn_img=Button(main_frame,text='START (TSED)',command = self.Text,font=('time new roman',20,'bold'),fg='white',bg='#081923').place(x=200,y=350,width=650)

        self.lbl=Label(self.root,text='\nWELCOME',font=('Book Antiqua',25,'bold'),compound=BOTTOM,fg='white',bg='#081923',bd=0)
        self.lbl.place(x=90,y=120,height=450,width=350)
        self.logo_set()

    def Text(self):
        #self.root.destroy()
        call(["python", "1st_encryption.py"])

    def logo(self):
        logo = Image.new('RGB',(400,400),(8,25,35))
        draw=ImageDraw.Draw(logo)
        bg=Image.open('logo.png')
        bg=bg.resize((300,300),Image.ANTIALIAS)
        logo.paste(bg,(50,50))
        draw.ellipse((195,195,210,210))
        logo.save('logo_new.png')

    def logo_set(self):
         self.img=ImageTk.PhotoImage(file='logo_new.png')
         self.lbl.config(image=self.img)
         self.lbl.after(200,self.logo)

root =tk.Tk()
obj = Wellcome_Window(root)
root.mainloop()


import logging
import os.path

from oslo_serialization import jsonutils

from osc_lib.command import command

from mistralclient.commands.v2 import base
from mistralclient.commands.v2 import executions
from mistralclient import utils

LOG = logging.getLogger(__name__)

class TaskFormatter(base.MistralFormatter):
    COLUMNS = [
        ('id', 'ID'),
        ('name', 'Name'),
        ('workflow_name', 'Workflow name'),
        ('workflow_namespace', 'Workflow namespace'),
        ('workflow_execution_id', 'Workflow Execution ID'),
        ('state', 'State'),
        ('state_info', 'State info'),
        ('created_at', 'Created at'),
        ('started_at', 'Started at'),
        ('finished_at', 'Finished at'),
        ('duration', 'Duration', True),
    ]

    @staticmethod
    def format(task=None, lister=False):
        if task:
            state_info = (task.state_info if not lister
                          else base.cut(task.state_info))

            duration = base.get_duration_str(task.started_at, task.finished_at)

            data = (
                task.id,
                task.name,
                task.workflow_name,
                task.workflow_namespace,
                task.workflow_execution_id,
                task.state,
                state_info,
                task.created_at,
                task.started_at or '<none>',
                task.finished_at or '<none>',
                duration
            )
        else:
            data = (tuple('' for _ in range(len(TaskFormatter.COLUMNS))),)

        return TaskFormatter.headings(), data

class List(base.MistralExecutionLister):
    """List all tasks."""

    def get_parser(self, prog_name):
        parser = super(List, self).get_parser(prog_name)

        parser.add_argument(
            'workflow_execution',
            nargs='?',
            help='Workflow execution ID associated with list of Tasks.'
        )
        return parser

    def _get_format_function(self):
        return TaskFormatter.format_list

    def _get_resources(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine

        return mistral_client.tasks.list(
            parsed_args.workflow_execution,
            marker=parsed_args.marker,
            limit=parsed_args.limit,
            sort_keys=parsed_args.sort_keys,
            sort_dirs=parsed_args.sort_dirs,
            fields=TaskFormatter.fields(),
            **base.get_filters(parsed_args)
        )

class Get(command.ShowOne):
    """Show specific task."""

    def get_parser(self, prog_name):
        parser = super(Get, self).get_parser(prog_name)

        parser.add_argument('task', help='Task identifier')

        return parser

    def take_action(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine
        execution = mistral_client.tasks.get(parsed_args.task)

        return TaskFormatter.format(execution)

class GetResult(command.Command):
    """Show task output data."""

    def get_parser(self, prog_name):
        parser = super(GetResult, self).get_parser(prog_name)
        parser.add_argument(
            'id',
            help='Task ID')

        return parser

    def take_action(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine
        result = mistral_client.tasks.get(parsed_args.id).result

        try:
            result = jsonutils.loads(result)
            result = jsonutils.dumps(result, indent=4) + "\n"
        except Exception:
            LOG.debug("Task result is not JSON.")

        self.app.stdout.write(result or "\n")

class GetPublished(command.Command):
    """Show task published variables."""

    def get_parser(self, prog_name):
        parser = super(GetPublished, self).get_parser(prog_name)
        parser.add_argument(
            'id',
            help='Task ID')

        return parser

    def take_action(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine
        res = mistral_client.tasks.get(parsed_args.id)
        published = res.published
        published_glob = res.published_global \
            if hasattr(res, 'published_global') else None

        try:
            published = jsonutils.loads(published)
            published = jsonutils.dumps(published, indent=4) + "\n"

            if published_glob:
                published_glob = jsonutils.loads(published_glob)
                published += jsonutils.dumps(published_glob, indent=4) + "\n"
        except Exception:
            LOG.debug("Task result is not JSON.")

        self.app.stdout.write(published or "\n")

class Rerun(command.ShowOne):
    """Rerun an existing task."""

    def get_parser(self, prog_name):
        parser = super(Rerun, self).get_parser(prog_name)

        parser.add_argument(
            'id',
            help='Task identifier'
        )

        parser.add_argument(
            '--resume',
            action='store_true',
            dest='resume',
            default=False,
            help=('rerun only failed or unstarted action '
                  'executions for with-items task')
        )

        parser.add_argument(
            '-e',
            '--env',
            dest='env',
            help='Environment variables'
        )

        return parser

    def take_action(self, parsed_args):
        mistral_client = self.app.client_manager.workflow_engine

        env = (
            utils.load_file(parsed_args.env)
            if parsed_args.env and os.path.isfile(parsed_args.env)
            else utils.load_content(parsed_args.env)
        )

        execution = mistral_client.tasks.rerun(
            parsed_args.id,
            reset=(not parsed_args.resume),
            env=env
        )

        return TaskFormatter.format(execution)

class SubExecutionsLister(executions.SubExecutionsBaseLister):

    def _get_format_function(self):
        return executions.ExecutionFormatter.format_list

    def _get_resources_function(self):
        mistral_client = self.app.client_manager.workflow_engine

        return mistral_client.tasks.get_task_sub_executions


import csv
import os
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from django.contrib.gis.geos import Point
from apps.core.models import Airport
from apps.core.models import Airline
from apps.core.models import Equipment
from apps.core.models import Route
from tqdm import tqdm

def is_float(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

class Command(BaseCommand):
    help = 'Updates airport data'

    def add_arguments(self, parser):
        parser.add_argument('data_dir', type=str)

    def handle(self, *args, **options):

        print("Delete old airport data...")
        Airport.objects.all().delete()
        print("Load new aiport data from {}...".format(os.path.join(options['data_dir'], 'airports.csv')))

        with open(os.path.join(options['data_dir'], 'airports.csv')) as f:
            csv_reader = csv.DictReader(f)
            for row in tqdm(csv_reader):
                airport = Airport(
                    name=row['name'],
                    city=row['city'],
                    country=row['country'],
                    iata=row['iata'] if row['iata'].isalnum() else None,
                    icao=row['icao'] if row['icao'].isalnum() else None,
                    location=Point(float(row['lon']), float(row['lat']), float(row['altitude'])),
                    evcent=row['evcent'] if is_float(row['evcent']) else None,
                    pagerank=row['pagerank'] if is_float(row['pagerank']) else None,
                    degree=row['degree_centrality'] if is_float(row['degree_centrality']) else None,
                    betweenness=row['betweenness'] if is_float(row['betweenness']) else None,
                    closeness=row['closeness'] if is_float(row['closeness']) else None)
                airport.save()

        print("Delete old airline data...")
        Airline.objects.all().delete()
        print("Load new airline data from {}...".format(os.path.join(options['data_dir'], 'airlines.csv')))

        with open(os.path.join(options['data_dir'], 'airlines.csv')) as f:
            csv_reader = csv.DictReader(f)
            for row in tqdm(csv_reader):
                airport = Airline(
                    name=row['name'],
                    alias=row['alias'],
                    iata=row['iata'] if row['iata'].isalnum() else None,
                    icao=row['icao'] if row['icao'].isalnum() else None,
                    callsign=row['callsign'],
                    country=row['country'],
                    active=row['active'] == 'Y',
                    openflights_id=row['id'])
                airport.save()

        print("Delete old equipment data...")
        Equipment.objects.all().delete()
        print("Load new equpment data from {}...".format(os.path.join(options['data_dir'], 'planes.csv')))

        with open(os.path.join(options['data_dir'], 'planes.csv')) as f:
            csv_reader = csv.DictReader(f)
            for row in tqdm(csv_reader):
                equpment = Equipment(
                    name=row['name'],
                    iata=row['iata'] if row['iata'].isalnum() else None,
                    icao=row['icao'] if row['icao'].isalnum() else None)
                equpment.save()

        print("Delete old routes data...")
        Route.objects.all().delete()
        print("Load new routes data from {}...".format(os.path.join(options['data_dir'], 'routes.csv')))

        with open(os.path.join(options['data_dir'], 'routes.csv')) as f:
            csv_reader = csv.DictReader(f)
            for row in tqdm(csv_reader):

                if row['airline_id'].isdigit():
                    airline = Airline.objects.get(openflights_id=row['airline_id'])
                else:
                    airline = None

                if row['equipment'].isalnum():
                    try:
                        equipment = Equipment.objects.get(iata=row['equipment'])
                    except Exception:
                        equipment = None
                else:
                    equipment = None

                if row['source_airport'].isalnum():
                    try:
                        source_airport = Airport.objects.get(iata=row['source_airport'])
                    except Exception:
                        source_airport = None
                else:
                    source_airport = None

                if row['dest_airport'].isalnum():
                    try:
                        dest_airport = Airport.objects.get(iata=row['dest_airport'])
                    except Exception:
                        dest_airport = None
                else:
                    dest_airport = None

                route = Route(
                    airline=airline,
                    equipment=equipment,
                    source=source_airport,
                    dest=dest_airport,
                    stops=row['stops'],
                    codeshare=row['codeshare'] == 'Y', )

                route.save()


import setuptools

with open('README.md', 'r') as fh:
    long_description = fh.read()

setuptools.setup(
    name='pyhighlight',
    version='1.0.2',
    author='Tyler Burdsall',
    author_email='tylerburdsall@gmail.com',
    description='Tiny package to help highlight portions of an image with matplotlib',
    long_description=long_description,
    long_description_content_type='text/markdown',
    url='https://github.com/iamtheburd/pyhighlight',
    packages=setuptools.find_packages(),
    classified=(
        'Programming Language :: Python :: 3',
        'License :: OSI Approved :: MIT License',
        'Operating System :: OS Independent'
    )
)


from django.urls import path
from .views import ListaRoom,CrearRoom,EliminarRoom,ModRoom,manageReservations,editarUsuario

urlpatterns = [
path('adminRoom',ListaRoom.as_view(), name='listarRoom'),
path('anadirRoom',CrearRoom.as_view(), name='anadirRoom'),
path('eliminarRoom/<int:pk>/', EliminarRoom.as_view(), name='eliminarRoom'),
path('modRoom/<int:pk>/', ModRoom.as_view(), name='modRoom'),
path('manageReservation/', manageReservations, name='manageReservation'),
path('editarUsuario/<int:user_id>/', editarUsuario.as_view(), name='editarUsuario'),

]


from cvzone.HandTrackingModule import HandDetector
import cv2
import serial
import time
from math import atan2, pi
import math
import inspire_hand_r
import pyrealsense2 as rs

_inspire_hand_r = inspire_hand_r.InspireHandR()
_inspire_hand_r.__init__()

cap = cv2.VideoCapture('/dev/video0')
detector = HandDetector(detectionCon=0.5, maxHands=2)

# Serial COM
port ='/dev/ttyUSB0'
ser = serial.Serial(port='/dev/ttyUSB0', baudrate=115200, bytesize=8,
                    stopbits=1, writeTimeout=0, timeout=0)

if ser.is_open:
    print(f"Connexion établie avec succès sur {port}")
else:
    print(f"Impossible d'établir la connexion sur {port}")

time.sleep(2)
ser.readline()

tempo=0
count1 = 0
count2 = 0
count3 = 0
count4 = 0
count5 = 0
count6 = 0
count7 = 0
count8 = 0
count9 = 0
count10 = 0
count11 = 0
count12 = 0
count13 = 0
count14 = 0
count15 = 0
indexV=0
middle_fingerV=0
ring_fingerV=0
little_fingerV=0
thumbV=0

def angle(A, B, C):

    Ax, Ay = A[0]-B[0], A[1]-B[1]
    Cx, Cy = C[0]-B[0], C[1]-B[1]
    a = atan2(Ay, Ax)
    c = atan2(Cy, Cx)
    if a < 0:
        a += pi*2
    if c < 0:
        c += pi*2
    result = (pi*2 + c - a) if a > c else (c - a)
    result *= (180/math.pi)
    if result > 180:
        result = 360 - result
    return result

def map_angle(angle):
    angle_min = 50
    angle_max = 165
    value_min = 2000
    value_max = 0

    # Check if the angle is within the valid range
    if angle < angle_min:
        angle = angle_min
    elif angle > angle_max:
        angle = angle_max

    # Calculate the mapped value
    mapped_value = ((angle - angle_min) / (angle_max - angle_min)) * (value_max - value_min) + value_min

    # Convert the mapped value to a byte sequence
    #byte_value = mapped_value.to_bytes(2, 'big')

    int_mapped_value = int(mapped_value)

    return int_mapped_value

while True:
    # Get image frame
    success, img = cap.read()
    # Find the hand and its landmarks
    hands, img = detector.findHands(img)  # with draw
    # hands = detector.findHands(img, draw=False)  # without draw
    try:
        if  len(hands) >= 1:

            hand1 = hands[0]
            lmList1 = hand1["lmList"]  # List of 21 Landmark points
            bbox1 = hand1["bbox"]  # Bounding box info x,y,w,h
            centerPoint1 = hand1['center']  # center of the hand cx,cy
            handType1 = hand1["type"]  # Handtype Left or Right
            if handType1 == 'Left':
                cv2.circle(img, lmList1[8][:2], 15, (0, 0, 255), -1)
                cv2.circle(img, lmList1[12][:2], 15, (0, 0, 255), -1)
                cv2.circle(img, lmList1[16][:2], 15, (0, 0, 255), -1)
                cv2.circle(img, lmList1[20][:2], 15, (0, 0, 255), -1)
                cv2.circle(img, lmList1[4][:2], 15, (0, 0, 255), -1)
            else:
                cv2.circle(img, lmList1[8][:2], 15, (0, 255, 255), -1)
                cv2.circle(img, lmList1[12][:2], 15, (0, 255, 255), -1)
                cv2.circle(img, lmList1[16][:2], 15, (0, 255, 255), -1)
                cv2.circle(img, lmList1[20][:2], 15, (0, 255, 255), -1)
                cv2.circle(img, lmList1[4][:2], 15, (0, 255, 255), -1)

            result = dict({'index': angle(lmList1[8][:2], lmList1[6][:2], lmList1[5][:2]),
                           'middle_finger': angle(lmList1[12][:2], lmList1[10][:2], lmList1[9][:2]),
                           'ring_finger': angle(lmList1[16][:2], lmList1[14][:2], lmList1[13][:2]),
                           'little_finger': angle(lmList1[20][:2], lmList1[18][:2], lmList1[17][:2]),
                           'thumb': angle(lmList1[4][:2], lmList1[2][:2], lmList1[1][:2])})

            precision=50

            for key, value in result.items():
                if key == 'index':
                        # time.sleep(1)
                        if count1 == 15:
                            temp=indexV
                            indexV= map_angle(value)#  ser.write(b'\x01')
                            if not(indexV > temp + precision or indexV <temp-precision) :
                                 indexV=temp

                            #print(f'key: {key} , value: {indexV}')
                            print(f'key: {key} , ANGLEvalue: {value}')
                            count1 == 0
                        else:
                            count1 += 1

                if key == 'middle_finger':
                        if count4 == 15:
                            temp=middle_fingerV
                            middle_fingerV= map_angle(value)#  ser.write(b'\x01')
                            if not(middle_fingerV > temp + precision or middle_fingerV <temp-precision) :
                                 middle_fingerV=temp
                            count4 == 0
                            #print(f'key: {key} , value: {middle_fingerV}')
                            print(f'key: {key} , ANGLEvalue: {value}')

                        else:
                            count4 += 1

                if key == 'ring_finger':
                        if count7 == 15:
                            temp=ring_fingerV
                            ring_fingerV= map_angle(value)#  ser.write(b'\x01')
                            if not(ring_fingerV > temp + precision or ring_fingerV <temp-precision) :
                                 ring_fingerV=temp
                            count7 == 0
                            #print(f'key: {key} , value: {ring_fingerV}')
                            print(f'key: {key} , ANGLEvalue: {value}')

                        else:
                            count7 += 1

                if key == 'little_finger':
                        if count10 == 15:
                            temp=little_fingerV
                            little_fingerV= map_angle(value)#  ser.write(b'\x01')
                            if not(little_fingerV > temp + precision or little_fingerV <temp-precision) :
                                 little_fingerV=temp
                            count10 == 0
                            #print(f'key: {key} , value: {little_fingerV}')
                            print(f'key: {key} , ANGLEvalue: {value}')

                        else:
                            count10 += 1

                if key == 'thumb':
                        if count13 == 15:
                            temp=thumbV
                            thumbV= map_angle(value)#  ser.write(b'\x01')
                            if not(thumbV > temp + precision or thumbV <temp-precision) :
                                 thumbV=temp
                            count13 == 0
                            #print(f'key: {key} , value: {thumbV}')
                            print(f'key: {key} , ANGLEvalue: {value}')

                        else:
                            count13 += 1

        if len(hands) == 2:
            # Hand 2
            hand2 = hands[1]
            lmList2 = hand2["lmList"]  # List of 21 Landmark points
            bbox2 = hand2["bbox"]  # Bounding box info x,y,w,h
            centerPoint2 = hand2['center']  # center of the hand cx,cy
            handType2 = hand2["type"]  # Hand Type "Left" or "Right"

            if handType2 == 'Left':
                cv2.circle(img, lmList2[8][:2], 15, (0, 0, 255), -1)
                cv2.circle(img, lmList2[12][:2], 15, (0, 0, 255), -1)
                cv2.circle(img, lmList2[16][:2], 15, (0, 0, 255), -1)
                cv2.circle(img, lmList2[20][:2], 15, (0, 0, 255), -1)
                cv2.circle(img, lmList2[4][:2], 15, (0, 0, 255), -1)
            else:
                cv2.circle(img, lmList2[8][:2], 15, (0, 255, 255), -1)
                cv2.circle(img, lmList2[12][:2], 15, (0, 255, 255), -1)
                cv2.circle(img, lmList2[16][:2], 15, (0, 255, 255), -1)
                cv2.circle(img, lmList2[20][:2], 15, (0, 255, 255), -1)
                cv2.circle(img, lmList2[4][:2], 15, (0, 255, 255), -1)

        if tempo == 3:
            _inspire_hand_r.setpos(little_fingerV,ring_fingerV,middle_fingerV,indexV,thumbV,0)
            #_inspire_hand_r.setpos(0,1000,0,100.50,0,0)
            tempo=0
        else:
            tempo=tempo+1

    except:
        continue

        # Display
    cv2.imshow("Image", img)
    if cv2.waitKey(1) & 0xFF == ord('q'):

        break
cap.release()
cv2.destroyAllWindows()


import logging
import os
from functools import partial
from typing import Any, Dict, List, Tuple, Union

import numpy as np
import openai
import pandas as pd
import torch
from joblib import Parallel, delayed
from numpy.typing import NDArray
from sacrebleu import BLEU
from sacrebleu.metrics.base import Metric
from tenacity import retry, stop_after_attempt, wait_random_exponential
from torch import nn
from tqdm import tqdm

from llm_studio.src.datasets.text_utils import get_texts
from llm_studio.src.utils.logging_utils import TqdmToLogger

logger = logging.getLogger(__name__)

def sacrebleu_score(
    cfg: Any, results: Dict, val_df: pd.DataFrame, metric: Metric
) -> NDArray:
    scores = []
    for predicted_text, target_text in zip(
        results["predicted_text"], results["target_text"]
    ):
        if target_text == "":
            score = 0.0
        else:
            score = metric.sentence_score(predicted_text, [target_text]).score
        scores.append(score)
    return np.array(scores)

@retry(
    reraise=True,
    wait=wait_random_exponential(multiplier=1, max=60),
    stop=stop_after_attempt(3),
)
def call_openai_api(template, model, deployment_id=None):
    response = openai.ChatCompletion.create(
        deployment_id=deployment_id,
        model=model,
        messages=[
            {
                "role": "system",
                "content": "You are a helpful and precise assistant "
                "for checking the quality of the answer.",
            },
            {
                "role": "user",
                "content": template,
            },
        ],
        temperature=0.0,
        max_tokens=1024,
    )
    ret = response["choices"][0]["message"]["content"]
    try:
        ret = ret.split("\n")
        score = ret[0].lower().replace("score:", "").strip().split(",")[0].split(" ")[0]
        score = float(score)
    except ValueError:
        raise ValueError(f"Could not parse score from response: {ret}")
    return score, " ".join(ret[1:]).strip()

def rate_reply(question, reference_answer, assistant_answer, model, deployment_id=None):
    # motivated by https://github.com/lm-sys/FastChat/tree/main/fastchat/eval
    template = open("prompts/eval_template.txt", "r").read()

    template = template.format(
        question=question,
        reference_answer=reference_answer,
        assistant_answer=assistant_answer,
    )

    try:
        return call_openai_api(template, model, deployment_id)
    except Exception as e:
        logger.warning(f"Exception caught in api call: {e}")
        return 0.0, ""

def gpt_score(
    cfg: Any,
    results: Dict,
    val_df: pd.DataFrame,
    raw_results: bool = False,
) -> Union[NDArray, Tuple[NDArray, List[str]]]:
    prompts = get_texts(val_df, cfg, separator="")

    if os.getenv("OPENAI_API_TYPE", "open_ai") == "azure":
        deployment_id = os.getenv("OPENAI_API_DEPLOYMENT_ID")
    else:
        deployment_id = None

    model = cfg.prediction.metric_gpt_model

    ret = Parallel(n_jobs=8, backend="multiprocessing")(
        delayed(rate_reply)(
            prompt,
            target_text,
            predicted_text,
            model,
            deployment_id=deployment_id,
        )
        for prompt, predicted_text, target_text in tqdm(
            zip(
                prompts,
                results["predicted_text"],
                results["target_text"],
            ),
            file=TqdmToLogger(logger, level=logging.INFO),
            desc=f"GPT eval {model}",
            total=len(prompts),
        )
    )
    scores = [x[0] for x in ret]
    explanations = [x[1] for x in ret]

    if raw_results:
        return np.array(scores), explanations
    return np.mean(scores)

class Perplexity(nn.Module):
    def __init__(self, cfg: Any, reduce: bool = True):
        super().__init__()
        self.cfg = cfg
        self.loss_fn = nn.CrossEntropyLoss()
        self.reduce = reduce

    def forward(self, logits, labels):
        shift_logits = logits[..., :-1, :].contiguous()
        shift_labels = labels[..., 1:].contiguous()

        perplexity = []
        for i in range(labels.shape[0]):
            perplexity.append(self.loss_fn(shift_logits[i], shift_labels[i]))
        perplexity = torch.stack(perplexity, dim=0)
        perplexity = torch.exp(perplexity)
        if self.reduce:
            perplexity = torch.mean(perplexity)
        return perplexity

def perplexity(cfg: Any, results: Dict, val_df: pd.DataFrame):
    return results["perplexity"].detach().float().cpu().numpy()

class Metrics:
    """
    Metrics factory. Returns:
        - metric value
        - should it be maximized or minimized
        - Reduce function

    Maximized or minimized is needed for early stopping (saving best checkpoint)
    Reduce function to generate a single metric value, usually "mean" or "none"
    """

    _metrics = {
        "Perplexity": (perplexity, "min", "mean"),
        "BLEU": (
            partial(sacrebleu_score, metric=BLEU(effective_order=True)),
            "max",
            "mean",
        ),
        "GPT": (gpt_score, "max", "mean"),
    }

    @classmethod
    def names(cls) -> List[str]:
        return sorted(cls._metrics.keys())

    @classmethod
    def get(cls, name: str) -> Any:
        """Access to Metrics.

        Args:
            name: metrics name
        Returns:
            A class to build the Metrics
        """
        return cls._metrics.get(name, "GPT")

    @classmethod
    def suitable_metrics(cls, cfg: Any, results: Dict, val_df: pd.DataFrame) -> Dict:
        """Access to All Suitable Metrics. For some problem types (e.g. classification)
        there might be metrics (e.g. Micro Averaged F1) that are only suitable in
        specific cases (multiclass not binary). There might also be additional
        metrics returned, which are not possible to select as validation metrics,
        e.g. threshold dependant metrics

        Returns:
            A dictionary of all suitable metrics for current problem setup
        """
        return cls._metrics

    @classmethod
    def all_metrics(cls) -> Dict:
        """Access to All Metrics. There might also be additional
        metrics returned, which are not possible to select as validation metrics,
        e.g. threshold dependant metrics

        Returns:
            A dictionary of all metrics (including not suitable metrics).
        """
        return cls._metrics


#This code demonstrate how to show location of hand landmark
import cv2
import mediapipe as mp
import numpy as np

cap = cv2.VideoCapture(0)

#Call hand pipe line module
mpHands = mp.solutions.hands
hands = mpHands.Hands()
mpDraw = mp.solutions.drawing_utils

axis = np.zeros((21, 2))
#print(axis)
while True:
    finger = []
    success, img = cap.read()
    imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    results = hands.process(imgRGB)
    #print(results.multi_hand_landmarks)
    if results.multi_hand_landmarks:
        for handRms in results.multi_hand_landmarks:
            for id, lm in enumerate(handRms.landmark):
                h, w, c = img.shape
                cx, cy = int(lm.x*w), int(lm.y*h)
                axis[id] = [cx, cy] # [ 0, 1 ]
                #print(id , axis[id])
            if axis[4, 0] > axis[3, 0]:
                finger.append("Thumbs")
            if axis[8, 1] < axis[7, 1]:
                finger.append("Index")
            if axis[12, 1] < axis[11, 1]:
                finger.append("Middle")
            if axis[16, 1] < axis[15, 1]:
                finger.append("Ring")
            if axis[20, 1] < axis[19, 1]:
                finger.append("Pinky")

            mpDraw.draw_landmarks(img, handRms, mpHands.HAND_CONNECTIONS)
    Nfing = len(finger)
    cv2.putText(img, str(Nfing), (10, 150), cv2.FONT_HERSHEY_PLAIN, 1.5,
                (0, 0, 252), 2)
    cv2.putText(img, str(finger), (10, 70), cv2.FONT_HERSHEY_PLAIN, 1.5,
                (0, 0, 252), 2)
    cv2.imshow("Index finger of right-hand system", img)
    cv2.waitKey(1)
#Closeing all open windows
#cv2.destroyAllWindows()


"""
9.13. Using a Metaclass to Control Instance Creation

Problem: You want to change the way in which instances are created in order to implement
         singletons, caching, or other similar features.
"""

from typing import Any

# as python programmer know, if you define a class, you call it like a function to
# create instance, Eg:
class Spam:
    def __init__(self, name) -> None:
        self.name = name

a = Spam("Guido")
b = Spam("Diana")

# If you want to customize this step, you can do it by defining a metaclass and
# reimplementing its __call__() method in some way.

class NoInstance(type):
    def __call__(self, *args: Any, **kwds: Any) -> Any:
        raise TypeError("Can't instantiate directly")

# Example
class Spam(metaclass=NoInstance):
    @staticmethod
    def grok(x):
        print("Spam.grok")

# In this case, users can call the defined static method, but it's impossible to create
# an instance in the normal way. Eg:
Spam.grok(42)
# s = Spam() # will throw error

# Now, suppose you want to implement the singleton pattern (i.e., a class where only on
# instance is ever created). That is also relatively straightforward, as shown here..
class Singleton(type):
    def __init__(self, *args, **kwargs) -> None:
        self.__instance = None
        super().__init__(*args, **kwargs)

    def __call__(self, *args: Any, **kwargs: Any) -> Any:
        if self.__instance is None:
            self.__instance = super().__call__(*args, **kwargs)
            return self.__instance
        else:
            return self.__instance

# Example
class Spam(metaclass=Singleton):
    def __init__(self) -> None:
        print("Creating Spam...")

a = Spam()
b = Spam()
print(a is b)

# finally, suppose you want to create cached instances, here's a metaclass to implement it.
import weakref

class Cached(type):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.__cache = weakref.WeakValueDictionary()

    def __call__(self, *args: Any, **kwds: Any) -> Any:
        if args in self.__cache:
            return self.__cache[args]
        else:
            obj = super().__call__(*args)
            self.__cache[args] = obj
            return obj

# Example
class Spam(metaclass=Cached):
    def __init__(self, name) -> None:
        print("Creating Spam({!r})".format(name))
        self.name = name

a = Spam("Guido")
b = Spam("Diana")
c = Spam("Guido") # cached

print(a is b)
print(b is c)
print(c is a) # cached value returned


import machine, logging
import ustruct as struct

log = logging.getLogger(__name__)

# From https://github.com/pkucmus/micropython-pms7003
# Hacked down to just return the PM2.5 concentration

# PMS_PM1_0 = 0
# PMS_PM2_5 = 1
# PMS_PM10_0 = 2
# PMS_PM1_0_ATM = 3
PMS_PM2_5_ATM = 4  # PM2.5 concentration ug/m3 ("atmospheric" environment)
# PMS_PM10_0_ATM = 5
PMS_PCNT_0_3 = 6
# PMS_PCNT_0_5 = 7
# PMS_PCNT_1_0 = 8
PMS_PCNT_2_5 = 9
# PMS_PCNT_5_0 = 10
# PMS_PCNT_10_0 = 11
# PMS_VERSION = 12
# PMS_ERROR = 13
PMS_CHECKSUM = 14

# parsing states
S_INIT = 0  # looking for start char (0x42)
S_STARTED = 1  # looking for second char (0x4D)
S_LEN = 2  # ready to read packet length
S_DATA = 3  # ready to read packet body & checksum

from machine import Pin

trig = Pin(12, Pin.OUT)
trig(0)

class PMSx003:
    def __init__(self, uart=2, tx=3, rx=4):
        self._uart = machine.UART(2, 9600, tx=tx, rx=rx)
        self._uart.init(9600, bits=8, parity=None, stop=1)
        self._state = S_INIT
        log.debug(str(self._uart))

    def _assert_byte(self, byte, expected):
        if byte is None or len(byte) < 1 or ord(byte) != expected:
            return False
        return True

    def read(self):
        cnt = self._uart.any()
        if cnt > 250:
            log.warning("PMSx003: uart overrun")
            self._uart.read(300)
            return None
        if cnt == 0:
            return None
        # read first header char
        while self._state == S_INIT:
            if cnt == 0:
                return None
            if self._assert_byte(self._uart.read(1), 0x42):
                self._state = S_STARTED
            cnt -= 1
        # read second header char
        if self._state == S_STARTED:
            if cnt == 0:
                return None
            if not self._assert_byte(self._uart.read(1), 0x4D):
                self._state = S_INIT
                return None
            cnt -= 1
            self._state = S_LEN
        # read packet length
        if self._state == S_LEN:
            if cnt < 2:
                return None
            hdr = self._uart.read(2)
            if len(hdr) != 2:
                log.warning("PMSx003: len vanished")
                self._state = S_INIT
                return None
            ll = hdr[0] * 256 + hdr[1]
            cnt -= 2
            # print("PMSx003: len={}".format(ll))
            if ll != 2 * 13 + 2:
                log.warning("PMSx003: bad length ({})".format(ll))
                self._state = S_INIT
                return None
            self._state = S_DATA
        # read packet body
        if self._state == S_DATA:
            if cnt < 28:
                return None
            read_buffer = self._uart.read(28)
            self._state = S_INIT
            if len(read_buffer) != 28:
                log.warning("PMSx003: data vanished")
                return None
            if False:
                for i in range(len(read_buffer)):
                    print("0x{:02x} ".format(read_buffer[i]), end="")
                print(" (cnt={})".format(cnt - 28))
            data = struct.unpack("!HHHHHHHHHHHHBBH", read_buffer)
            # verify checksum
            checksum = 0x42 + 0x4D + 28
            for c in read_buffer[0:26]:
                checksum += c
            if checksum == data[PMS_CHECKSUM]:
                # print("PMSx003:", data)
                return (data[PMS_PM2_5_ATM], data[PMS_PCNT_0_3] - data[PMS_PCNT_2_5])
            trig(1)
            log.warning("PMSx003: bad checksum")

        return None

#           {
#                'FRAME_LENGTH': data[self.PMS_FRAME_LENGTH],
#                'PM1_0': data[self.PMS_PM1_0],
#                'PM2_5': data[self.PMS_PM2_5],
#                'PM10_0': data[self.PMS_PM10_0],
#                'PM1_0_ATM': data[self.PMS_PM1_0_ATM],
#                'PM2_5_ATM': data[self.PMS_PM2_5_ATM],
#                'PM10_0_ATM': data[self.PMS_PM10_0_ATM],
#                'PCNT_0_3': data[self.PMS_PCNT_0_3],
#                'PCNT_0_5': data[self.PMS_PCNT_0_5],
#                'PCNT_1_0': data[self.PMS_PCNT_1_0],
#                'PCNT_2_5': data[self.PMS_PCNT_2_5],
#                'PCNT_5_0': data[self.PMS_PCNT_5_0],
#                'PCNT_10_0': data[self.PMS_PCNT_10_0],
#                'VERSION': data[self.PMS_VERSION],
#                'ERROR': data[self.PMS_ERROR],
#                'CHECKSUM': data[self.PMS_CHECKSUM],
#            }


from __future__ import absolute_import, unicode_literals
from django.db import IntegrityError
from django.core.exceptions import ObjectDoesNotExist

from celery.utils.log import get_task_logger
from celery import shared_task
from celery.task.schedules import crontab
from celery.decorators import periodic_task

import traceback
import requests
import logging
import json
import os

from tpobot.settings import AT
from bot.models import User, Company
from bot.intentParser import Intent, Greeting, Question
from bot.spider import crawl
from bot.apis import callWit, getUserFromGraphAPI, sendFBText
from bot.messages import *

logger = get_task_logger(__name__)
# print('logger', __name__)
entityTypes = {
    'intent': Intent(),
    'greetings': Greeting(),
    'question': Question(),
}#all classes imported from intentParser

if os.environ.get('development', '') == 'True':
    mins = 1
else:
    mins = 15

@shared_task
def completeProfile(psid, received_msg):
    user = User.objects.get(psid=psid)
    received_msg = received_msg.strip().split(' ')
    if len(received_msg) != 1:
        msg = message_dict['reg_error']
        return sendFBText(psid, msg)

    value = received_msg[0].lower()

    if '@' in value and not user.email:#it's email and user hasn't set it yet
        if 'itbhu.ac.in' in value:
            temp = value.split('@')[0].split('.')[-1]
            if len(temp) != 5: #like eee15
                msg = message_dict['invalid_email']
                return sendFBText(psid, msg)
            try:
                if int(temp[3:]) >= 15:#let facchas get updates
                    user.purpose = 'internship'
                else:
                    user.purpose = 'placement'
                user.year = int(temp[3:])
                user.department = temp[:3]#eee
                user.email = value
                user.save()
                print('user course: %s\n\n' %user.purpose)
                msg = message_dict['email_set'].format(value)
                sendFBText(psid, msg)
                msg = message_dict['get_course']
                return sendFBText(psid, msg)
            except Exception as e:
                print(e)
                msg = message_dict['invalid_email']
                return sendFBText(psid, msg)
        else:
            msg = message_dict['not_iit_email']
            return sendFBText(psid, msg)

    elif (value=='idd' or value=='btech' or value=='imd') and \
                                not user.course and user.email:
        #true when email is set, course isn't, you got a valid value

        user.course = value
        user.profile_completed = True

        if (value=='idd' or value=='imd') and user.year == 14:
            user.valid=False#idd 4rth yr peeps, zivan ka koi purpose nhi
            user.save()
            msg = message_dict['idd_imd_4th_year']
            return sendFBText(psid, msg)
        user.save()
        msg = message_dict['course_set'].format(value)
        sendFBText(psid, msg)
        updateNewUser(psid)
        msg = message_dict['reg_success']
        return sendFBText(psid, msg)

    else:
        msg = message_dict['reg_error']
        return sendFBText(psid, msg)

#will use graph API to save few user fields, rest to be asked in complete profile function
@shared_task
def newUser(psid):
    data = getUserFromGraphAPI(psid)
    user = User.objects.create(psid=psid,
                            first_name = data['first_name'],
                            last_name = data['last_name'],
                            gender = data['gender'],
                            profile_pic = data['profile_pic'])
    msg = message_dict['welcome']
    sendFBText(psid, msg)
    msg = message_dict['get_email']
    sendFBText(psid, msg)

@shared_task
def analyseMessage(psid, message):
    response, status = callWit(message)
    msg_sent_count = 0
    if status:
        #entity like `intent`, `greetings`, `question` etc
        for entity in response:
            logging.info('Entity %s\n' % str(entity))
            entityClass = entityTypes[entity]
            logging.info('Enitity Class: %s\n' % entityClass.__class__.__name__)
            #every entity has a list of entity types like my `intent` has `happiness`
            for entityType in response[entity]:
                logging.info('Checking entityType: %s\n' % entityType)
                method = getattr(entityClass, entityType['value'])
                logging.info('Calling method: %s\n' % method.__name__)
                msgSent = method(psid, entityType['confidence'])
                msg_sent_count += bool(msgSent)

    else:#WitError
        msg = message_dict['wit_error']
        msgSent = sendFBText(psid, msg)
        msg_sent_count += bool(msgSent)

    logging.info("msg_sent_count: %s\n" % msg_sent_count)
    if msg_sent_count == 0:
        msg = message_dict['no_idea']
        sendFBText(psid, msg)

def updateNewUser(psid):
    user = User.objects.get(psid=psid)
    #logging.info('Gotta update new user %s ', user)
    companies = Company.objects.filter(course__icontains=user.course,
                             department__icontains=user.department,
                             purpose__icontains=user.purpose)

    if len(companies):
         msg = 'Companies opened for you so far:\n\n'
         sendFBText(psid, msg)
    else:
        msg = 'No company is open for you as for now, will inform you when one opens :)'
        return sendFBText(psid, msg)

    for company in companies:
        c = company.__dict__

        msg = c['company_name'] + '\n\n'
        for field in field_msg_dict:
            if c[field]:#if not none
                msg += field_msg_dict[field] + ': ' + c[field] + '\n'

        #logging.info(msg)
        sendFBText(psid, msg)

    msg = "That's it for now, will keep updating you :)"
    return sendFBText(psid, msg)

@shared_task
def informUsersAboutNewCompany(data_dict):
    msg = message_dict['new_company'].format(**data_dict)
    print('\n\n\n informUsersAboutNewCompany')
    for user in User.objects.filter(valid=True,
                            subscribed=True,
                            profile_completed=True,
                            course__in=data_dict['course'].split(),
                            department__in=data_dict['department'].split(),
                            purpose__in=data_dict['purpose'].lower().split()):

        sendFBText(user.psid, msg)

@shared_task
def updateUserAboutThisCompany(data_dict, changed_fields):
    company = Company.objects.get(company_name=data_dict['company_name'])

    msg = ''
    temp = '{0}: {1}\n'
    for field in changed_fields:
        msg += temp.format(field_msg_dict[field], data_dict[field])

    final_msg = message_dict['updated_company'].format(
                                                data_dict['company_name'],
                                                msg,
                                                data_dict['updated_at'])

    for user in User.objects.filter(valid=True,
                            subscribed=True,
                            profile_completed=True,
                            course__in=company.course.split(),
                            department__in=company.department.split(),
                            purpose__in=company.purpose.lower().split()):
        sendFBText(user.psid, final_msg)

@shared_task
def gotInactiveUser(psid):
    msg = message_dict['user_invalid']
    sendFBText(psid, msg)

@periodic_task(run_every=(crontab(minute='*/%d' %mins)), name="crawl_tpo", ignore_result=True)
def crawl_tpo():
    logging.info('Crawling TPO')
    data = crawl()#defined in spider

    for index in data:
        data_dict = data[index]
        try:
            company = Company.objects.get(company_name=data_dict['company_name'])
            if data_dict['updated_at'] != company.updated_at:
                changed_fields = company.update(data_dict)
                logging.info(data_dict['company_name'] + str(changed_fields))
                changed_fields.remove('updated_at')
                updateUserAboutThisCompany(data_dict, changed_fields)

        except ObjectDoesNotExist:
            logging.info("Got a new company")
            Company.objects.create(**data_dict)
            informUsersAboutNewCompany(data_dict)

        except Exception as e:
            logging.info("Got Error in updateUserAboutCompany %s" % e)
            logging.info(traceback.format_exc())

    logging.info('Crawling Done')


import os
from utils.prepro_data import process_base
from utils.data_utils import Dataset, boolean_string
from utils.configs import Configurations
from models.base import BaseModel
from argparse import ArgumentParser

# parser
parser = ArgumentParser()
parser.add_argument("--mode", type=int, default=0, help="fix to 0 for basic settings")
parser.add_argument("--use_gpu", type=boolean_string, default=True, help="if use GPU for training")
parser.add_argument("--gpu_idx", type=str, default="0", help="indicate which GPU is used for training and inference")
parser.add_argument("--random_seed", type=int, default=86, help="random seed")
parser.add_argument("--train", type=boolean_string, default=True, help="if True, train the model")
parser.add_argument("--restore_model", type=boolean_string, default=False, help="restore pretrained and fine-tune")
parser.add_argument("--restore_best", type=boolean_string, default=False, help="restore best model for testing")
parser.add_argument("--at", type=boolean_string, default=False, help="if True, use adversarial training")
parser.add_argument("--norm_emb", type=boolean_string, default=False, help="if True, normalizing embeddings for AT")
parser.add_argument("--language", default="spanish", help="specify the task language")
parser.add_argument("--iobes", type=boolean_string, default=True, help="if True, use IOBES scheme, otherwise, IOB2")
parser.add_argument("--dev_for_train", type=boolean_string, default=False, help="use development dataset for training")
parser.add_argument("--train_ratio", default="1.0", help="training dataset ratio")
parser.add_argument("--word_lowercase", type=boolean_string, default=True, help="lowercase words")
parser.add_argument("--char_lowercase", type=boolean_string, default=False, help="lowercase characters")
parser.add_argument("--threshold", type=int, default=20, help="character threshold")
parser.add_argument("--word_dim", type=int, default=50, help="word embedding dimension")
parser.add_argument("--word_project", type=boolean_string, default=False, help="word project")
parser.add_argument("--char_dim", type=int, default=30, help="character embedding dimension")
parser.add_argument("--tune_emb", type=boolean_string, default=False, help="optimizing word embeddings while training")
parser.add_argument("--highway_layers", type=int, default=2, help="number of highway layers used")
parser.add_argument("--char_kernels", type=int, nargs="+", default=[2, 3, 4], help="CNN kernels for char")
parser.add_argument("--char_kernel_features", type=int, nargs="+", default=[20, 20, 20], help="CNN features for char")
parser.add_argument("--concat_rnn", type=boolean_string, default=True, help="concatenate outputs of bi-rnn layer")
parser.add_argument("--num_units", type=int, default=100, help="number of units for RNN")
parser.add_argument("--epsilon", type=float, default=5.0, help="epsilon")
parser.add_argument("--lr", type=float, default=0.001, help="learning rate")
parser.add_argument("--use_lr_decay", type=boolean_string, default=True, help="apply learning rate decay at each epoch")
parser.add_argument("--lr_decay", type=float, default=0.05, help="learning rate decay factor")
parser.add_argument("--decay_step", type=int, default=1, help="learning rate decay steps")
parser.add_argument("--minimal_lr", type=float, default=1e-4, help="minimal learning rate")
parser.add_argument("--optimizer", type=str, default="adam", help="optimizer: [rmsprop | adadelta | adam | ...]")
parser.add_argument("--grad_clip", type=float, default=5.0, help="maximal gradient norm")
parser.add_argument("--epochs", type=int, default=50, help="train epochs")
parser.add_argument("--batch_size", type=int, default=16, help="batch size")
parser.add_argument("--emb_drop_rate", type=float, default=0.2, help="dropout rate for embeddings")
parser.add_argument("--rnn_drop_rate", type=float, default=0.5, help="dropout rate for embeddings")
parser.add_argument("--max_to_keep", type=int, default=1, help="maximum trained model to be saved")
parser.add_argument("--no_imprv_tolerance", type=int, default=None, help="no improvement tolerance")
config = Configurations(parser.parse_args())

# os environment
os.environ['TF_CPP_MIN_LOG_LEVEL'] = "3"
os.environ["CUDA_VISIBLE_DEVICES"] = config.gpu_idx

# if dataset is not prepared, then build it
if not os.path.exists(config.save_path) or not os.listdir(config.save_path):
    process_base(config)

print("load dataset...")
train_ratio = int(config.train_ratio) if float(config.train_ratio) > 1.0 else float(config.train_ratio)
dataset = Dataset(config.train_set, config.dev_set, config.test_set, batch_size=config.batch_size,
                  train_rate=train_ratio, shuffle=True)

print("build model and train...")
model = BaseModel(config)
if config.restore_model:
    model.restore_last_session()
if config.train:
    model.train(dataset)
model.restore_last_session()
model.evaluate_data(dataset.get_data_batches("test"), name="test")
model.close_session()


import pygame
import random
from Item import Item

WIDTH = 1200
HEIGHT = 800

class Bomb(Item):
    def __init__(self, path, bombHeight, bombWidth):
        super().__init__()
        self.image = pygame.image.load(path)
        self.image = pygame.transform.scale(self.image, (bombWidth, bombHeight)).convert_alpha()
        self.rect = self.image.get_rect()
        x = random.randrange(0, WIDTH)
        y = random.randrange(-85, -35)
        self.rect.center = (x, y)
        self.bombWidth = bombWidth
        self.bombHeight = bombHeight
        self.speed = random.randrange(1, 6)

    def update(self, *args, **kwargs) -> None:
        super().update()

        if self.rect.y > HEIGHT-60:
            self.rect.y = random.randrange(-50,-8)
            self.rect.x = random.randrange(self.bombWidth, WIDTH-self.bombWidth)
            self.speed = random.randrange(1, 6)