# -*- coding:utf-8 -*-
# #######################
# quotes 行情仓库
# by Wooght
# date 2017-12-25
# #######################

from ..Db import *
import json

class Table_quotes():
    table = quotes_item
    cols = table.c

    #存在大于0的行情
    def exists_quotes(self,id=0):
        if(id>0):
            s = self.select_quotes('quotes','code_id',code_id=id)
        else:
            s = self.select_quotes('quotes','code_id')
        code = []
        for quotes in s.fetchall():
            quotes_json = json.loads(quotes[0])
            one = []
            one.append(quotes[1])
            opendate = []
            for dateitem in quotes_json:
                if(float(dateitem['shou'])>0):
                    #行情收大于0 没停盘的才有效
                    opendate.append(dateitem['datatime'])
            one.append(opendate)
            code.append(one)
        # return [codeid,[quotes]]
        return code
    def select_quotes(self,*args,**kwargs):
        columns = []
        for col in args:
            columns.append(self.cols[col])
        r = select(columns)
        if('code_id' in kwargs):
            r = r.where(self.cols['code_id']==kwargs['code_id'])
        s = conn.execute(r)
        return s


#coding=utf-8

import random
import telegram
import datetime
import logging
from telegram.ext import Updater

#MachineGodBot - Telegram Bot designed for helping Warhammer 40.0000 players
updater = Updater(token='apitoken')
logger = logging.basicConfig(filename="DeusMechanicus.log", filemode="w", level= logging.INFO, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')

dispatcher = updater.dispatcher

#Functions
def unknown(bot,update):
    logging.info('Received UNKNOWN command')
    unknown_Message = "La tua preghiera non è stata ascoltata!\n" \
                      "Digita /help per una lista di comandi"
    bot.sendMessage(chat_id=update.message.chat_id, text= unknown_Message, parse_mode=telegram.ParseMode.MARKDOWN)

def feedback(bot,update):
    logging.info('Received FEEDBACK command')
    feedback_Message = "Aiuta l'Omnissiah a crescere di popolarità.\n" \
                       "Clicka [qui](https://telegram.me/storebot?=MachineGodBot) e vota!"
    bot.sendMessage(chat_id=update.message.chat_id, text= feedback_Message, parse_mode=telegram.ParseMode.MARKDOWN)

def help(bot,update):
    logging.info('Received HELP command')
    help_message = "Utilizza i seguenti comandi: \n" \
                    "/help - per mostrare questa finestra di aiuto \n" \
                    "/roll *x* _y_ - tira *x*D6 e restituisce i valori superiori a _y_ \n" \
                    "/feedback - vota e aiutaci a crescere" \
                    # "/start - per avviare il bot \n" \
                    # "/stop - per arrestare il bot \n" \
                    # "/rule _regola_ - restituisce l'estratto della _regola_ dal manuale di 7a edizione"

    bot.sendMessage(chat_id=update.message.chat_id, text=help_message, parse_mode=telegram.ParseMode.MARKDOWN)

def roll(bot,update, args):
    if len(args) == 0:
        roll_message= "La sintassi del comando prevede /roll *x* _y_ \n" \
                      "dove *x* è il numero di d6 da lanciare e _y_ il valore da superare per il test\n" \
                      "_y_ può essere omesso se si desidera solo lanciare dei dadi"
        bot.sendMessage(chat_id=update.message.chat_id, text= roll_message, parse_mode=telegram.ParseMode.MARKDOWN)

    elif len(args)==1:
        results = "Effettuati i seguenti tiri: \n"
        die = int(args[0]) #Numero di dadi

        for x in range(die):
            dice = random.randint(1,6)
            results = results + telegram.Emoji.GAME_DIE + " " + str(dice) + "\n"

        bot.sendMessage(chat_id=update.message.chat_id, text= results, parse_mode=telegram.ParseMode.MARKDOWN)

    else:
        results = "Effettuati i seguenti tiri: \n"
        die = int(args[0]) #Numero di dadi
        value = int(args[1]) #Valore inserito dall'utente
        counter = 0 #Numero di dadi superiori all'input dell'utente

        for x in range(die):
            dice = random.randint(1,6)
            if dice >= value:
                counter=counter+1
            results = results + telegram.Emoji.GAME_DIE + " " + str(dice) + "\n"

        results = results + "\n"
        results = results + telegram.Emoji.DIRECT_HIT + " Prove superate: " + str(counter)

        bot.sendMessage(chat_id=update.message.chat_id, text= results, parse_mode=telegram.ParseMode.MARKDOWN)

def meme(bot, update):
    logging.info('Received MEME command')
    imgNumber = random.randint(1,11)
    img = "/home/pi/MachineGodBot/meme/" + str(imgNumber) + ".jpg"
    bot.sendPhoto(chat_id=update.message.chat_id, photo=open(img,'rb'))

def rule(bot,update,args):
    if len(args)==0:
        rule_message = "La sintassi del comando prevede /rule _regola_\n" \
                       "dove _regola_ è il nome della regola da cercare"
        bot.sendMessage(chat_id=update.message.chat_id, text=rule_message, parse_mode=telegram.ParseMode.MARKDOWN)
    else:
        rule_to_find= args[:]
        index = ''.join(rule_to_find)
        if index.lower() == "aduemani":
            rule_title= telegram.Emoji.BOOKS + " *A DUE MANI* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Un modello che combatte con quest'arma non riceve mai" \
                          " *+1* attacchi in mischia per il fatto che combatte con due armi da mischia"
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "abilepilota":
            rule_title= telegram.Emoji.BOOKS + " *ABILE PILOTA* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Un'unità che contiene almeno un modello con questa regola speciale supera automaticamente" \
                          "i test per i terreni pericolosi e riceve un modificatore di *+1* ai tiri copertura conferiti" \
                          "da Zigzagare (altri tiri copertura non vengono influenzati)"
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "accecare":
            rule_title= telegram.Emoji.BOOKS + " *ACCECARE* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Ogni unità colpita da uno o più armi o modelli con questa regola speciale deve effettura un test" \
                          "d'Iniziativa alla fine della fase in corso. Se lo supera non succede nulla: i guerrieri hanno distolto" \
                          "lo sguardo grazie ad un avvertimento. Se fallisce, i valori di *AC* e *AB* di tutti i modelli nell'unità" \
                          "sono ridotti ad *1* fino alla fine del loro prossimo turno." \
                          "Se l'unità attaccante colpisce se stessa, si suppone che sia preparata e supera il test automaticamente." \
                          "Qualsiasi modello privo della caratteristica di Iniziativa (ad esempio veicoli non Camminatori, edifici ecc.)" \
                          "non è influenzate da questa regola speciale."
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "aggirare":
            rule_title= telegram.Emoji.BOOKS + " *AGGIRARE* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Durante lo schieramento i giocatori possono dichiarare che qualsiasi unità che contiene almeno un modello" \
                          "con questa regola speciale sta tentando di Aggirare il nemico. Ciò significa che compie una lunga manovra" \
                          "di accerchiamento per superare le linee di battaglia avversarie o assalirle da una direzione inaspettata." \
                          "Quando un'unità che Aggira arriva dalla Riserva, ma non dalle Riserve Provvisorie, il giocatore che la controlla" \
                          "tira un D6: con 1-2 l'unità arriva dal bordo del tavolo alla sinistra del tavolo del giocatore che la controlla;" \
                          "con 3-4 arriva da quello a destra; con 5-6 il giocatore sceglie se da quello a destra o a sinistra. I modelli" \
                          "arrivano sul tavolo come descritto per le altre Riserve. Se tale unità si schiera dentro un Trasporto Apposito," \
                          "può Aggirare assieme al proprio Trasporto"
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "altamanovrabilità":
            rule_title= telegram.Emoji.BOOKS + " *ALTA MANOVRABILITA'* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Un modello con questa regola speciale può compiere una rotazione sul posto addizionale di massimo 90° al termine" \
                          "del proprio movimento. Se usa questa rotazione addizionale, esso non può muoversi A tavoletta nella successiva fase" \
                          "di Tiro."
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "ammantato":
            rule_title= telegram.Emoji.BOOKS + " *AMMANTATO* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Un'unità che contiene almeno un modello con questa regola speciale considera i propri tiri copertura di 2 punti migliore" \
                          "del normale. Ciò significa che un modello con la regola speciale Ammantato ha sempre un tiro copertura di almeno *5+*," \
                          "anche in terreno aperto. I modificatori ai tiri copertura per le regole Ammantato e Furtività sono cumulabili (fino ad" \
                          "un tiro copertura massimo di *2+*)."
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "armadistruttrice":
            rule_title= telegram.Emoji.BOOKS + " *ARMA DISTRUTTRICE* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Se nel suo profilo un'arma ha D invece di un valore di Forza, essa è un'arma Distruttrice. Per risolvere l'attacco di tale arma" \
                          "tira per Colpire come faresti con un attacco normale. Se colpisce, tira sulla tabella seguente invece di tirare per Ferire o per" \
                          "la penetrazione della corazza. La maggior parte delle armi Distruttrici ha VP1 o VP2, quindi solutamente non si possono effettuare" \
                          "tiri armatura. I tiri copertura e invulnerabilità possono essere effettuati normalmente, a meno che non si ottenga un risultato" \
                          "Colpo devastante o Colpo fatale. Al fine di determinare se il colpo di un'arma Distruttrice ha la regola speciale Morte Immediata," \
                          "considera che abbia Fo10. Le Ferite o i danni ai Punti Scafo in eccesso inflitti da un colpo di un'arma Distruttrice non vengono assegnati" \
                          "agli altri modelli nell'unità, ma sono perduti."
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)
            bot.sendPhoto(chat_id=update.message.chat_id, photo=open('omnissiah/armadistruttrice.jpg','rb'))

        elif index.lower() == "armaspecialistica":
            rule_title= telegram.Emoji.BOOKS + " *ARMA SPECIALISTICA* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Un modello che combatte con quest'arma non ottiene *+1* Attacchi se combatte con due armi, a meno che sia armato" \
                          "con due o più armi da Mischia con la regola speciale Arma Specialistica."
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "attaccoradente":
            rule_title= telegram.Emoji.BOOKS + " *ATTACCO RADENTE* " + telegram.Emoji.BOOKS +"\n"
            rule_message= "Quando spara con armi d'Assalto, Pesanti, a Cadenza Rapida o a Raffica contro Artiglieria, Bestie, Moto," \
                          "Cavalleria, Fanteria, Creature Mostruore e veicoli che non sono Velivoli né Aeromobili, questo veicolo ha *+1* AB."
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "atterrare":
            rule_title= telegram.Emoji.BOOKS + " *ATTERRARE* " + telegram.Emoji.BOOKS +"\n"
            rule_message="Ogni modello non veicolo che subisce una o più Ferite non salvate o supera uno o più tiri salvezza contro" \
                         "un attacco speciale Atterrare si muove come su un terreno accidentanto fino alla fine del suo turno successivo." \
                         "E' meglio indicare i modelli influenzati con monete o segnalini"
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "avvelenato":
            rule_title= telegram.Emoji.BOOKS + " *ATTERRARE* " + telegram.Emoji.BOOKS +"\n"
            rule_message="Se un modello possiede la regola speciale Avvelenato o se attacca con un'arma da Mischia che ha la regola speciale" \
                         "Avvelenato, in combattimento ferisce sempre con un risultato fisso (generalmente indicato fra parentesi)," \
                         "a meno che non ne sia necessario uno inferiore. Inoltre, se la Forza del portatore (o dell'arma Avvelenata)" \
                         "è superiore alla Resistenza della vittima, esso deve ripetere i tiri per Ferire falliti in combattimento." \
                         "Allo stesso modo, se un modello effettua un attacco da tiro con un'arma che la regola speciale Avvelenato," \
                         "ferisce sempre con un risultato fisso (generalmente indicato fra parentesi), a meno che non ne sia necessario" \
                         "uno inferiore. Se fra parentesi non viene indicato nessun numero, la regola è Avvelenato (*4+*)." \
                         "Se non viene diversamente specificato, le armi Avvelenate vengono sempre considerate avere *Fo1*. La regola" \
                         "speciale Avvelenato non ha effetto contro i veicoli."
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "area":
            rule_title= telegram.Emoji.BOOKS + " *AREA* " + telegram.Emoji.BOOKS +"\n"
            rule_message=""
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

        elif index.lower() == "binata":
            rule_title= telegram.Emoji.BOOKS + " *BINATA* " + telegram.Emoji.BOOKS +"\n"
            rule_message="Per aumentare la precisione, queste armi sono collegate allo stesso sistema di puntamento." \
                         "Le armi Binate non sparano più di quelle normali, ma hanno maggiori probabilità di colpire. Se un'arma da tiro" \
                         "ha la regola speciale Binata, o viene descritta come Binata nella voce dell'equipaggiamento di un modello," \
                         "ripete tutti i tiri per Colpire falliti. \n" \
                         "\n" \
                         "*ARMI AD AREA BINATE\n" \
                         "Se il dado deviazione non ottiene un Colpito! con un'arma ad Area o ad Area Grande Binata, puoi scegliere" \
                         "di ripetere il tiro. In tal caso devi tirare di nuovo sia i 2d6 che il dado deviazione.\n" \
                         "\n" \
                         "*ARMI A SAGOMA BINATE\n" \
                         "Le armi a Sagoma Binate sparano come un'arma singola, ma devono ripetere i tiri per Ferire falliti e quelli" \
                         "per la penetrazione della corazza falliti."
            bot.sendMessage(chat_id=update.message.chat_id, text= rule_title + rule_message, parse_mode=telegram.ParseMode.MARKDOWN)

#Handlers
dispatcher.addUnknownTelegramCommandHandler(unknown)
#dispatcher.addTelegramCommandHandler('start',start)
#dispatcher.addTelegramCommandHandler('stop',stop)
dispatcher.addTelegramCommandHandler('help',help)
dispatcher.addTelegramCommandHandler('roll', roll)
dispatcher.addTelegramCommandHandler('meme', meme)
dispatcher.addTelegramCommandHandler('feedback',feedback)
#dispatcher.addTelegramCommandHandler('rule',rule)

#Bot polling
updater.start_polling()


import tensorflow as tf
import numpy as np
from scipy.interpolate import CubicSpline
from scipy.interpolate import interp1d

class GradCam:
    """
    A class to compute grad-CAM on 1-D input for Keras models.
    ...

    Attributes
    ----------
    model : tf.Keras.Model
        model on which compute grad-CAM.
    testset: np.array
        array of elements on which compute grad-CAM.

    """
    def __init__(self, testset, model):
        self.testset = testset
        self.model = model

    def make_gradcam_heatmap(self, conv_layer_name):
        """
        Compute heatmap for grad-CAM.
        :param conv_layer_name: str
            name of the convolutional layer on which compute grad-CAM.
        :return:
        """
        heatmaps = []
        grad_model = tf.keras.models.Model(
            [self.model.inputs], [self.model.get_layer(conv_layer_name).output, self.model.output]
        )
        for el in self.testset:
            el = np.expand_dims(el, 0)
            with tf.GradientTape() as tape:
                last_conv_layer_output, preds = grad_model(el)
                pred_index = tf.argmax(preds[0])
                class_channel = preds[:, pred_index]

            grads = tape.gradient(class_channel, last_conv_layer_output)

            pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))

            last_conv_layer_output = last_conv_layer_output[0]
            heatmap = last_conv_layer_output * pooled_grads
            heatmaps.append(heatmap.numpy())
        return np.array(heatmaps)

    def cubic_spline_interpolation(self, vector, v_size, input_size):
        """
        it applies cubic spline interpolation to obtain an output that has the same dimension of the input.
        :param vector: np.array
            vector to interpolate
        :param v_size: int
            dimension of the last convolutional layer flatted.
        :param input_size: int
            dimension of the input size.
        :return:
        """
        heatmap = np.squeeze(vector)
        size_feature_map = len(heatmap.flatten())
        feature_map_flat = np.squeeze(heatmap.flatten())
        feature_map_flat = np.expand_dims(feature_map_flat, 1)

        x = np.linspace(0, size_feature_map - 1, v_size)
        f = CubicSpline(x, feature_map_flat, bc_type='natural')
        x_wanted = np.linspace(0, size_feature_map - 1, input_size)
        return_vector = f(x_wanted)

        return_vector = np.where(return_vector > 0, return_vector, 0)
        return return_vector

    def linear_interpolation(self, vector, v_size, input_size):
        """
        it applies linear interpolation to obtain an output that has the same dimension of the input.
        :param vector: np.array
            vector to interpolate
        :param v_size: int
            dimension of the last convolutional layer flatted.
        :param input_size: int
            dimension of the input size.
        :return:
        """
        heatmap = np.squeeze(vector)
        size_feature_map = len(heatmap.flatten())
        feature_map_flat = np.squeeze(heatmap.flatten())
        feature_map_flat = np.expand_dims(feature_map_flat, 1)

        x = np.linspace(0, size_feature_map - 1, v_size)
        f = interp1d(x, feature_map_flat, kind='linear')
        x_wanted = np.linspace(0, size_feature_map - 1, input_size)
        return_vector = f(x_wanted)

        return_vector = np.where(return_vector > 0, return_vector, 0)
        return return_vector

    def matrix_interpolation(self, vector):
        """
        it applies matrix interpolation. A mean for each row is applied.
        :param vector: np.array
            vector to interpolate.
        :return:
        """
        return np.mean(vector, axis = 1)

    def normalize_vector(self, vector):
        """
        normalize vector between 0-1.
        :param vector: np.array
            vector to normalize.
        :return:
        """
        sum = vector.sum()
        return vector / sum


import requests
import tablib
import logging
import time
from import_export import resources
from django.core.management.base import BaseCommand, CommandError
from shared.models import Course, Concentration
from phd.models import CurricularArea
from collections import OrderedDict
from django.db.models import Q #allows for complex queries
logger = logging.getLogger('administration/management/addconcentration.py')

#This command will add concentration each course
class Command(BaseCommand):

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

        #Concentration Course Lists --> hardcoded because it is unavailable through the API
        CE = ["ECE  538", "ECE  539", "ECE  552", "ECE  553", "ECE  554", "ECE  555",
        "ECE  556", "ECE  557", "ECE  558", "ECE  559", "ECE  561", "ECE  562", "ECE  611",
        "ECE  650", "ECE  651", "ECE  652"]
        MNS = ["ECE  511", "ECE  521", "ECE  526", "ECE  528", "ECE  529", "ECE  531",
        "ECE  532", "ECE  537", "ECE  539", "ECE  631"]
        PH = ["ECE  521", "ECE  523", "ECE  541", "ECE  545", "ECE  546", "ECE  722"]
        SW = ["ECE  571", "ECE  572", "ECE  573", "ECE  574", "ECE  575", "ECE  577",
        "ECE  578", "ECE  675", "ECE  676"]
        SPC = ["ECE  581", "ECE  582", "ECE  584", "ECE  585", "ECE  587", "ECE  681",
        "ECE  683", "ECE  686", "ECE  688"]
        #Concentration Objects
        Comp, Compbool = Concentration.objects.get_or_create(title = "Computer Engineering")
        Micro, Microbool = Concentration.objects.get_or_create(title = "Micro-Nano Systems")
        Photo, Photobool = Concentration.objects.get_or_create(title = "Photonics")
        Sense, Sensebool = Concentration.objects.get_or_create(title = "Sensing & Waves")
        Signal, Signalbool = Concentration.objects.get_or_create(title = "Signal Processing & Communications")

        MN, MNbool = CurricularArea.objects.get_or_create(title = "Microelectronics, Photonics, and Nanotechnology")
        PHY, PHYbool = CurricularArea.objects.get_or_create(title = "Engineering Physics")
        CENG, CENGbool = CurricularArea.objects.get_or_create(title = "Computer Engineering")
        SGN, SGNbool = CurricularArea.objects.get_or_create(title = "Signal & Information Processing")
        self.stdout.write(self.style.SUCCESS('CURRICULAR AREAS ADDED'))

        i = 0
        while i < len(CE):
            obj = Course.objects.get(Q(listing__iexact=CE[i]))
            obj.concentration.add(Comp)
            obj.save()
            i+=1

        self.stdout.write(self.style.SUCCESS('COMP ARCH CONCENTRATIONS ADDED'))

        i = 0
        while i < len(MNS):
            obj = Course.objects.get(Q(listing__iexact=MNS[i]))
            obj.concentration.add(Micro)
            obj.save()
            i+=1

        self.stdout.write(self.style.SUCCESS('MICRO NANO SYSTEMS CONCENTRATIONS ADDED'))

        i = 0
        while i < len(PH):
            obj = Course.objects.get(Q(listing__iexact=PH[i]))
            obj.concentration.add(Photo)
            obj.save()
            i+=1

        self.stdout.write(self.style.SUCCESS('PHOTONICS CONCENTRATIONS ADDED'))

        i = 0
        while i < len(SW):
            obj = Course.objects.get(Q(listing__iexact=SW[i]))
            obj.concentration.add(Sense)
            obj.save()
            i+=1

        self.stdout.write(self.style.SUCCESS('SENSING & WAVES CONCENTRATIONS ADDED'))

        i = 0
        while i < len(SPC):
            obj = Course.objects.get(Q(listing__iexact=SPC[i]))
            obj.concentration.add(Signal)
            obj.save()
            i+=1

        self.stdout.write(self.style.SUCCESS('SIGNAL PROCESSING CONCENTRATIONS ADDED'))

        self.stdout.write(self.style.SUCCESS('ALL CONCENTRATIONS ADDED'))


# -*- coding: utf-8 -*-
"""
Created on Sun Aug  1 12:34:17 2021

@author: Ahmet Kasım Erbay
"""
def delete_nth(order,max_e):
    if not order or max_e < 1:
        return []

    counted_order = { x:0 for x in order }
    new_order = []

    for item in order:
        if counted_order[item] < max_e:
            counted_order[item] += 1
            new_order.append(item)

    return new_order

seq = [20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5]

liste = delete_nth(seq, 1)

frequencies = [[i,seq.count(i)] for i in liste]

for i,j in [[i,seq.count(i)] for i in liste]:
    if j%2 == 1:
        print(i)

#%%

import operator
from functools import reduce

def find_it(xs):
    return reduce(operator.xor, xs)

seq = [20,1,-1,2,-2,3,3,5,5,1,2,4,20,4,-1,-2,5]

print(find_it(seq))

#%%
seq = [1, 1, 2, 2, 5, 2, 4, 4, -1, 2, 5]

def check_negative(seq):
    for i in seq:
        if i < 0:
            return True
    return False

def odd_index(seq):

    freq = [0]*(max(seq)+1)
    for i in seq:
        freq[i] += 1

    for i in freq:
        if i % 2 == 1:
            return freq.index(i)

if check_negative(seq):
    mini = -min(seq)
    seq = [i + mini for i in seq]
    result = odd_index(seq) - mini
else:
    result= odd_index(seq)

print(result)


import requests

def get_bot_binary_by_name(bot_name):
    responce = requests.get('https://sscaitournament.com/api/bots.php?bot={}'.format(bot_name))

    re_dic = responce.json()
    return re_dic[0]

def get_bot_binary_all():
    responce = requests.get('https://sscaitournament.com/api/bots.php')
    re_dic = responce.json()
    return re_dic

def main():
    ch = input('Check all bots update? Type 1 : ')
    if ch == '1':
        bots = get_bot_binary_all()
        update_list = []
        for bot in bots:
            update_list.append((bot['update'], bot['name'], bot['race']))

        update_list.sort()
        for i in update_list:
            print(i)

    else:
        while True:
            bot_name = input('Type bot name, Just Enter to Finish : ')
            if bot_name == '':
                break
            bot = get_bot_binary_by_name(bot_name)
            print((bot['update'], bot['name'], bot['race']))

if __name__ == '__main__':
    main()


from datetime import datetime
from os.path import dirname, abspath
import os

class Loggable:
    """This superclass can be inherited by every module willing to have logging (in stdout and/or file) capabilities"""
    def __init__(self, log_prefix):
        self.log_prefix = log_prefix
        self.log_root_path = dirname(dirname(abspath(__file__))) + os.sep + 'logs' + os.sep
        if not os.path.exists(self.log_root_path):
            os.makedirs(self.log_root_path)

    def build_debug_str(self, msg):
        """This function build a debug string appending the current timestamp to the input msg"""
        now = datetime.now()
        date_time = now.strftime("%H:%M:%S")
        return date_time + ' ' + self.log_prefix + ' ' + msg

    def save_log_to_file(self, log_msg):
        """This function saves a string to a file named by date"""
        now = datetime.now()
        log_file_name = now.strftime("%d-%m-%Y") + '.log'
        log_file_path = self.log_root_path + log_file_name
        f = open(log_file_path, "a")
        f.write(log_msg + '\n')
        f.close()

    def print_stdout_and_file(self, log_msg):
        """this function both prints on stdout and file a log string"""
        self.print_log_stdout(log_msg)
        self.save_log_to_file(self.build_debug_str(log_msg))

    def print_log_stdout(self, log_msg):
        """This function print a log message on the stdout"""
        print(self.build_debug_str(log_msg))


import re
from rest_framework import serializers
from ..models import Pokemon, PokemonStats

class PokemonStatsSerializer(serializers.ModelSerializer):
  class Meta:
    model = PokemonStats
    fields = ['pokemon_id','hp' ,'attack' ,'defense' ,'sp_attack' ,'sp_defense' ,'speed']

  def create(self, validated_data):
    id = validated_data['id']
    pokemon = Pokemon.objects.get(pk=id)

    pokemonStats = PokemonStats.objects.create(
      id=id,
      hp=validated_data['hp'],
      attack=validated_data['attack'],
      defense=validated_data['defense'],
      sp_attack=validated_data['sp_attack'],
      sp_defense=validated_data['sp_defense'],
      speed=validated_data['speed'],
      pokemon_id=pokemon.id)
    return pokemonStats

class PokemonStatsListSerializer(serializers.ListSerializer):
  child = PokemonStatsSerializer()


import serial
import time
import cv2
from MazeDetector import MazeDetector

class AutomaticMaze:
    # Initialize AutomaticMaze with the specified serial port for Arduino communication
    def __init__(self, serial_port):
        self.serial_port = serial_port
        self.ser = None

    # Connect to the Arduino via serial communication
    def connect(self, baud_rate=115200, timeout=2):
        self.ser = serial.Serial(self.serial_port, baud_rate)
        self.ser.flush()
        time.sleep(timeout)

    # Disconnect from the Arduino
    def disconnect(self):
        if self.ser:
            self.ser.close()

    # Send data to the Arduino from a file
    def send_data_from_file(self, file_path):
        with open(file_path, "r") as file:
            lines = file.readlines()

        if self.ser:
            num2 = 0.01
            for line in lines:
                parts = line.strip().split()
                if len(parts) == 2:
                    time.sleep(num2)
                    num1 = int(parts[0])
                    num2 = float(parts[1])
                    self.ser.write(str(num1).encode())
                    self.ser.read_all()

    # Create an instance of AutomaticMaze, connect to Arduino, send data, and disconnect
    @classmethod
    def from_file(cls, serial_port, maze_name, baud_rate=115200):
        maze = cls(serial_port)
        maze.connect(baud_rate)

        # Determine the file path based on the detected maze name
        file_path = f"{maze_name}.txt"

        maze.send_data_from_file(file_path)
        maze.disconnect()

#End of AutomaticMaze class

# Example usage:
'''
if __name__ == "__main__":
   serial_port = "/dev/ttyACM0"  # Replace with your Arduino's serial port

    maze_detector = MazeDetector()
    detected_maze = None

    # Continuously detect the maze until found
    while detected_maze is None:
        detected_maze = maze_detector.detect_maze()

    maze_detector.release()  # Release the video capture

    AutomaticMaze.from_file(serial_port, detected_maze)

    if detected_maze:
        print(f"Maze detected: {detected_maze}")
'''


from django.urls import path, include
from users.views import (
    IndexView,
    PostRegView,
    VerifyEmailView,
    VerificationCodeView,
    HomeView,
    ProfileView,
    TestView,
    )

urlpatterns = [
    path('', IndexView.as_view(), name='index'),
    path('post-registration/', PostRegView.as_view(), name='post-reg'),
    path('verify-email/' ,VerifyEmailView.as_view(), name='verify-email'),
    path('verication-code/', VerificationCodeView.as_view(), name='verication-code'),
    path('home/', HomeView.as_view(), name='home'),
    path('profile/', ProfileView.as_view(), name='profile'),
    path('test/', TestView.as_view(), name='test')
]


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

import sys
import unittest

import mxnet as mx
from mxnet import nd
from mxnet import gluon
from mxnet import autograd

sys.path.append('../model')

class Test(unittest.TestCase):

    def test_predict(self):
        from model import hybrid_model
        from model import trainer

        ctx = mx.gpu(1)
        num_of_vertices = 228
        batch_size = 8
        cheb_polys = nd.random_uniform(shape=(num_of_vertices,
                                              num_of_vertices * 3),
                                       ctx=ctx)
        blocks = [[1, 32, 64], [64, 32, 128]]
        x = nd.random_uniform(shape=(batch_size, 1, 12, num_of_vertices))

        net = hybrid_model.STGCN(12, 3, 3, blocks, 1.0,
                                 num_of_vertices, cheb_polys)
        net.initialize(ctx=ctx)
        net.hybridize()

        y = trainer.predict_batch(net, ctx, x, 12)

        self.assertEqual(y.shape, (batch_size, 1, 12, num_of_vertices))

    def test_evaluate(self):
        from model import hybrid_model
        from model import trainer
        from data_loader.data_utils import data_gen
        import numpy as np
        from mxboard import SummaryWriter
        import os
        import shutil

        ctx = mx.gpu(1)
        num_of_vertices = 897
        batch_size = 50

        PeMS_dataset = data_gen('datasets/PeMSD7_V_897.csv', 24)
        print('>> Loading dataset with Mean: {0:.2f}, STD: {1:.2f}'.format(
            PeMS_dataset.mean,
            PeMS_dataset.std
        ))

        test = PeMS_dataset['test'].transpose((0, 3, 1, 2))
        test_x, test_y = test[:100, :, : 12, :], test[:100, :, 12:, :]
        test_loader = gluon.data.DataLoader(
            gluon.data.ArrayDataset(nd.array(test_x), nd.array(test_y)),
            batch_size=batch_size,
            shuffle=False
        )
        print(test_x.shape, test_y.shape)

        cheb_polys = nd.random_uniform(shape=(num_of_vertices,
                                              num_of_vertices * 3))
        blocks = [[1, 32, 64], [64, 32, 128]]
        x = nd.random_uniform(shape=(batch_size, 1, 12, num_of_vertices),
                              ctx=ctx)

        net = hybrid_model.STGCN(12, 3, 3, blocks, 1.0,
                                 num_of_vertices, cheb_polys)
        net.initialize(ctx=ctx)
        net.hybridize()
        net(x)

        ground_truth = (np.concatenate([y.asnumpy() for x, y in test_loader],
                                       axis=0) *
                        PeMS_dataset.std +
                        PeMS_dataset.mean)[:100]

        if os.path.exists('test_logs'):
            shutil.rmtree('test_logs')
        sw = SummaryWriter('test_logs', flush_secs=5)

        trainer.evaluate(net, ctx, ground_truth, test_loader,
                         12, PeMS_dataset.mean, PeMS_dataset.std, sw, 0)
        self.assertEqual(os.path.exists('test_logs'), True)
        sw.close()
        if os.path.exists('test_logs'):
            shutil.rmtree('test_logs')

if __name__ == '__main__':
    unittest.main()


import sys
from cx_Freeze import setup, Executable

build_exe_options = {"packages": ["os"], "includes": ["tkinter", "pandas", "sqlite3", "openpyxl", "datetime", "tkcalendar", "sys"]}

base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(
    name="Meu App",
    version="0.1",
    description="Minha 1° Aplicação!",
    options={"build_exe": build_exe_options},
    executables=[Executable("main.py", base=base)]
)


import hashlib
import hmac
import os
import struct
import sys
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, ec
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.utils import int_to_bytes
from esp_secure_cert.esp_secure_cert_helper import load_private_key

supported_targets_rsa_ds = ['esp32s2', 'esp32s3', 'esp32c3',
                            'esp32c6', 'esp32h2']
supported_key_size_rsa = {'esp32s2': [1024, 2048, 3072, 4096],
                          'esp32c3': [1024, 2048, 3072],
                          'esp32s3': [1024, 2048, 3072, 4096],
                          'esp32c6': [1024, 2048, 3072],
                          'esp32h2': [1024, 2048, 3072]}

supported_targets_ecdsa = ['esp32h2']
supported_key_size_ecdsa = {'esp32h2': [256]}

idf_path = os.getenv('IDF_PATH')
if not idf_path or not os.path.exists(idf_path):
    raise Exception('IDF_PATH not found')

def number_as_bytes(number, pad_bits=None):
    """
    Given a number, format as a little endian array of bytes
    """
    result = int_to_bytes(number)[::-1]
    while pad_bits is not None and len(result) < (pad_bits // 8):
        result += b'\x00'
    return result

# @return
#       c               : ciphertext_c
#       iv              : initialization vector
#       key_size        : key size of the RSA private key in bytes.
# @input
#       privkey         : path to the RSA private key
#       priv_key_pass   : path to the RSA privaete key password
#       hmac_key        : HMAC key value ( to calculate DS params)
#       idf_target      : The target chip for the script (e.g. esp32c3)
# @info
#       The function calculates the encrypted private key parameters.
#       Consult the DS documentation (available for the ESP32-S2)
#       in the esp-idf programming guide for more details
#       about the variables and calculations.
def calculate_rsa_ds_params(privkey, priv_key_pass, hmac_key, idf_target):
    private_key_data = load_private_key(privkey, priv_key_pass)
    private_key = private_key_data["key_instance"]
    if not isinstance(private_key, rsa.RSAPrivateKey):
        print('ERROR: Only RSA private keys are supported')
        sys.exit(-1)
    if hmac_key is None:
        print('ERROR: hmac_key cannot be None')
        sys.exit(-2)

    priv_numbers = private_key.private_numbers()
    pub_numbers = private_key.public_key().public_numbers()
    Y = priv_numbers.d
    M = pub_numbers.n
    key_size = private_key.key_size
    if key_size not in supported_key_size_rsa[idf_target]:
        print('ERROR: Private key size {0} not supported for the target {1},'
              '\nthe supported key sizes are {2}'
              .format(key_size, idf_target,
                      str(supported_key_size_rsa[idf_target])))
        sys.exit(-1)

    iv = os.urandom(16)

    rr = 1 << (key_size * 2)
    rinv = rr % pub_numbers.n
    mprime = - rsa._modinv(M, 1 << 32)
    mprime &= 0xFFFFFFFF
    length = key_size // 32 - 1

    # get max supported key size for the respective target
    max_len = max(supported_key_size_rsa[idf_target])
    aes_key = hmac.HMAC(hmac_key, b'\xFF' * 32, hashlib.sha256).digest()

    md_in = number_as_bytes(Y, max_len) + \
        number_as_bytes(M, max_len) + \
        number_as_bytes(rinv, max_len) + \
        struct.pack('<II', mprime, length) + \
        iv

    # expected_len = max_len_Y + max_len_M + max_len_rinv
    #                + (mprime + length packed (8 bytes))+ iv (16 bytes)
    expected_len = (max_len / 8) * 3 + 8 + 16
    assert len(md_in) == expected_len
    md = hashlib.sha256(md_in).digest()
    # In case of ESP32-S2
    # Y4096 || M4096 || Rb4096 || M_prime32 || LENGTH32 || MD256 || 0x08*8
    # In case of ESP32-C3
    # Y3072 || M3072 || Rb3072 || M_prime32 || LENGTH32 || MD256 || 0x08*8
    p = number_as_bytes(Y, max_len) + \
        number_as_bytes(M, max_len) + \
        number_as_bytes(rinv, max_len) + \
        md + \
        struct.pack('<II', mprime, length) + \
        b'\x08' * 8

    # expected_len = max_len_Y + max_len_M + max_len_rinv
    #                + md (32 bytes) + (mprime + length packed (8bytes))
    #                + padding (8 bytes)
    expected_len = (max_len / 8) * 3 + 32 + 8 + 8
    assert len(p) == expected_len

    cipher = Cipher(algorithms.AES(aes_key),
                    modes.CBC(iv),
                    backend=default_backend())
    encryptor = cipher.encryptor()
    c = encryptor.update(p) + encryptor.finalize()
    return c, iv, key_size

def validate_ds_algorithm(ds_algo, key_size_bits, target_chip):
    if ds_algo == 'RSA':
        if target_chip not in supported_targets_rsa_ds:
            print(f'ERROR: Target {target_chip} does not '
                  'support RSA DS peripheral')
            sys.exit(-1)
        key_size_bits = int(key_size_bits, 10)
        if key_size_bits not in supported_key_size_rsa[target_chip]:
            print(f'ERROR: Target {target_chip} does not support '
                  f'{ds_algo} {key_size_bits}, supported key sizes are '
                  f'{supported_key_size_rsa[target_chip]}')
            sys.exit(-1)

    elif ds_algo == 'ECDSA':
        if target_chip not in supported_targets_ecdsa:
            print(f'ERROR: Target {target_chip} does not support '
                  'ECDSA peripheral')
            sys.exit(-1)

        key_size_bits = int(key_size_bits, 10)
        if key_size_bits not in supported_key_size_ecdsa[target_chip]:
            print(f'ERROR: Target {target_chip} does not support '
                  f'{ds_algo} {key_size_bits}, supported key sizes are '
                  f'{supported_key_size_ecdsa[target_chip]}')
            sys.exit(-1)

    else:
        print(f'ERROR: Invalid DS algorithm {ds_algo} {key_size_bits}')
        sys.exit(-1)

# Returns ecdsa key bytearray
def get_ecdsa_key_bytes(privkey, priv_key_pass, key_length_bytes):
    private_key_data = load_private_key(privkey, priv_key_pass)
    private_key = private_key_data["key_instance"]
    if not isinstance(private_key, ec.EllipticCurvePrivateKey):
        print('ERROR: Invalid private key format.'
              ' Only ECC private keys are supported')
        sys.exit(-1)
    key_length_bits = key_length_bytes * 8
    if (private_key.key_size != key_length_bits):
        print(f'ERROR: key size {private_key.key_size} does not match'
              f' with required key size {key_length_bytes}')
        sys.exit(-1)

    priv_numbers = private_key.private_numbers()
    private = priv_numbers.private_value
    ecdsa_key = private.to_bytes(key_length_bytes, byteorder='big')
    return ecdsa_key


import io
from collections import Counter
from dataclasses import dataclass

import numpy as np

from py4vasp import data, exception, raw
from py4vasp._data import base, slice_, topology
from py4vasp._data.viewer3d import Viewer3d
from py4vasp._util import documentation, import_, reader

ase = import_.optional("ase")
ase_io = import_.optional("ase.io")
mdtraj = import_.optional("mdtraj")

@dataclass
class _Format:
    begin_table: str = ""
    column_separator: str = " "
    row_separator: str = "\n"
    end_table: str = ""
    newline: str = ""

    def comment_line(self, topology, step_string):
        return f"{topology}{step_string}{self.newline}"

    def scaling_factor(self, scale):
        return f"{self._element_to_string(scale)}{self.newline}".lstrip()

    def ion_list(self, topology):
        return f"{topology.to_POSCAR(self.newline)}{self.newline}"

    def coordinate_system(self):
        return f"Direct{self.newline}"

    def vectors_to_table(self, vectors):
        rows = (self._vector_to_row(vector) for vector in vectors)
        return f"{self.begin_table}{self.row_separator.join(rows)}{self.end_table}"

    def _vector_to_row(self, vector):
        elements = (self._element_to_string(element) for element in vector)
        return self.column_separator.join(elements)

    def _element_to_string(self, element):
        return f"{element:21.16f}"

@documentation.format(examples=slice_.examples("structure"))
class Structure(slice_.Mixin, base.Refinery):
    """The structure of the crystal for selected steps of the simulation.

    You can use this class to process structural information from the Vasp
    calculation. Typically you want to do this to inspect the converged structure
    after an ionic relaxation or to visualize the changes of the structure along
    the simulation.

    {examples}
    """

    A_to_nm = 0.1
    "Converting Å to nm used for mdtraj trajectories."

    @classmethod
    def from_POSCAR(cls, poscar, *, elements=None):
        """Generate a structure from string in POSCAR format."""
        poscar = _replace_or_set_elements(str(poscar), elements)
        poscar = io.StringIO(poscar)
        structure = ase_io.read(poscar, format="vasp")
        return cls.from_ase(structure)

    @classmethod
    def from_ase(cls, structure):
        """Generate a structure from the ase Atoms class."""
        structure = raw.Structure(
            topology=topology.raw_topology_from_ase(structure),
            cell=_cell_from_ase(structure),
            positions=structure.get_scaled_positions()[np.newaxis],
        )
        return cls.from_data(structure)

    @base.data_access
    def __str__(self):
        "Generate a string representing the final structure usable as a POSCAR file."
        return self._create_repr()

    @base.data_access
    def _repr_html_(self):
        format_ = _Format(
            begin_table="
\n
",
            column_separator="	",
            row_separator="
\n
",
            end_table="
\n
",
            newline="
",
        )
        return self._create_repr(format_)

    def _create_repr(self, format_=_Format()):
        step = self._get_last_step()
        lines = (
            format_.comment_line(self._topology(), self._step_string()),
            format_.scaling_factor(self._scale()),
            format_.vectors_to_table(self._raw_data.cell.lattice_vectors[step]),
            format_.ion_list(self._topology()),
            format_.coordinate_system(),
            format_.vectors_to_table(self._raw_data.positions[step]),
        )
        return "\n".join(lines)

    @base.data_access
    @documentation.format(examples=slice_.examples("structure", "to_dict"))
    def to_dict(self):
        """Read the structural information into a dictionary.

        Returns
        -------
        dict
            Contains the unit cell of the crystal, as well as the position of
            all the atoms in units of the lattice vectors and the elements of
            the atoms for all selected steps.

        {examples}
        """
        return {
            "lattice_vectors": self._lattice_vectors(),
            "positions": self._positions(),
            "elements": self._topology().elements(),
            "names": self._topology().names(),
        }

    @base.data_access
    @documentation.format(examples=slice_.examples("structure", "to_graph"))
    def plot(self, supercell=None):
        """Generate a 3d representation of the structure(s).

        Parameters
        ----------
        supercell : int or np.ndarray
            If present the structure is replicated the specified number of times
            along each direction.

        Returns
        -------
        Viewer3d
            Visualize the structure(s) as a 3d figure.

        {examples}
        """
        if self._is_slice:
            return self._viewer_from_trajectory()
        else:
            return self._viewer_from_structure(supercell)

    @base.data_access
    @documentation.format(examples=slice_.examples("structure", "to_ase"))
    def to_ase(self, supercell=None):
        """Convert the structure to an ase Atoms object.

        Parameters
        ----------
        supercell : int or np.ndarray
            If present the structure is replicated the specified number of times
            along each direction.

        Returns
        -------
        ase.Atoms
            Structural information for ase package.

        {examples}
        """
        if self._is_slice:
            message = (
                "Converting multiple structures to ASE trajectories is not implemented."
            )
            raise exception.NotImplemented(message)
        data = self.to_dict()
        structure = ase.Atoms(
            symbols=data["elements"],
            cell=data["lattice_vectors"],
            scaled_positions=data["positions"],
            pbc=True,
        )
        num_atoms_prim = len(structure)
        if supercell is not None:
            try:
                structure *= supercell
            except (TypeError, IndexError) as err:
                error_message = (
                    "Generating the supercell failed. Please make sure the requested "
                    "supercell is either an integer or a list of 3 integers."
                )
                raise exception.IncorrectUsage(error_message) from err
        num_atoms_super = len(structure)
        order = sorted(range(num_atoms_super), key=lambda n: n % num_atoms_prim)
        return structure[order]

    @base.data_access
    @documentation.format(examples=slice_.examples("structure", "to_mdtraj"))
    def to_mdtraj(self):
        """Convert the trajectory to mdtraj.Trajectory

        Returns
        -------
        mdtraj.Trajectory
            The mdtraj package offers many functionalities to analyze a MD
            trajectory. By converting the Vasp data to their format, we facilitate
            using all functions of that package.

        {examples}
        """
        if not self._is_slice:
            message = "Converting a single structure to mdtraj is not implemented."
            raise exception.NotImplemented(message)
        data = self.to_dict()
        xyz = data["positions"] @ data["lattice_vectors"] * self.A_to_nm
        trajectory = mdtraj.Trajectory(xyz, self._topology().to_mdtraj())
        trajectory.unitcell_vectors = data["lattice_vectors"] * Structure.A_to_nm
        return trajectory

    @base.data_access
    @documentation.format(examples=slice_.examples("structure", "to_POSCAR"))
    def to_POSCAR(self):
        """Convert the structure(s) to a POSCAR format

        Returns
        -------
        str or list[str]
            Returns the POSCAR of the current or all selected steps.

        {examples}
        """
        if not self._is_slice:
            return self._create_repr()
        else:
            message = "Converting multiple structures to a POSCAR is currently not implemented."
            raise exception.NotImplemented(message)

    @base.data_access
    @documentation.format(examples=slice_.examples("structure", "cartesian_positions"))
    def cartesian_positions(self):
        """Convert the positions from direct coordinates to cartesian ones.

        Returns
        -------
        np.ndarray
            Position of all atoms in cartesian coordinates in Å.

        {examples}
        """
        return self._positions() @ self._lattice_vectors()

    @base.data_access
    @documentation.format(examples=slice_.examples("structure", "volume"))
    def volume(self):
        """Return the volume of the unit cell for the selected steps.

        Returns
        -------
        float or np.ndarray
            The volume(s) of the selected step(s) in Å³.

        {examples}
        """
        return np.abs(np.linalg.det(self._lattice_vectors()))

    @base.data_access
    def number_atoms(self):
        """Return the total number of atoms in the structure."""
        if self._is_trajectory:
            return self._raw_data.positions.shape[1]
        else:
            return self._raw_data.positions.shape[0]

    @base.data_access
    def number_steps(self):
        """Return the number of structures in the trajectory."""
        if self._is_trajectory:
            range_ = range(len(self._raw_data.positions))
            return len(range_[self._slice])
        else:
            return 1

    def _topology(self):
        return data.Topology.from_data(self._raw_data.topology)

    def _lattice_vectors(self):
        lattice_vectors = _LatticeVectors(self._raw_data.cell.lattice_vectors)
        return self._scale() * lattice_vectors[self._get_steps()]

    def _scale(self):
        if not self._raw_data.cell.scale.is_none():
            return self._raw_data.cell.scale[()]
        else:
            return 1.0

    def _positions(self):
        return self._raw_data.positions[self._get_steps()]

    def _viewer_from_structure(self, supercell):
        viewer = Viewer3d.from_structure(self, supercell=supercell)
        viewer.show_cell()
        return viewer

    def _viewer_from_trajectory(self):
        viewer = Viewer3d.from_trajectory(self)
        viewer.show_cell()
        return viewer

    def _get_steps(self):
        return self._steps if self._is_trajectory else ()

    def _get_last_step(self):
        return self._last_step_in_slice if self._is_trajectory else ()

    def _step_string(self):
        if self._is_slice:
            range_ = range(len(self._raw_data.positions))[self._steps]
            return f" from step {range_.start + 1} to {range_.stop + 1}"
        elif self._steps == -1:
            return ""
        else:
            return f" (step {self._steps + 1})"

    def __getitem__(self, steps):
        if not self._is_trajectory:
            message = "The structure is not a Trajectory so accessing individual elements is not allowed."
            raise exception.IncorrectUsage(message)
        return super().__getitem__(steps)

    @property
    def _is_trajectory(self):
        return self._raw_data.positions.ndim == 3

class _LatticeVectors(reader.Reader):
    def error_message(self, key, err):
        key = np.array(key)
        steps = key if key.ndim == 0 else key[0]
        return (
            f"Error reading the lattice vectors. Please check if the steps "
            f"`{steps}` are properly formatted and within the boundaries. "
            "Additionally, you may consider the original error message:\n" + err.args[0]
        )

def _cell_from_ase(structure):
    lattice_vectors = np.array([structure.get_cell()])
    return raw.Cell(lattice_vectors, scale=raw.VaspData(1.0))

def _replace_or_set_elements(poscar, elements):
    line_with_elements = 5
    elements = "" if not elements else " ".join(elements)
    lines = poscar.split("\n")
    if _elements_not_in_poscar(lines[line_with_elements]):
        _raise_error_if_elements_not_set(elements)
        lines.insert(line_with_elements, elements)
    elif elements:
        lines[line_with_elements] = elements
    return "\n".join(lines)

def _elements_not_in_poscar(elements):
    elements = elements.split()
    return any(element.isdecimal() for element in elements)

def _raise_error_if_elements_not_set(elements):
    if not elements:
        message = """The POSCAR file does not specify the elements needed to create a
            Structure. Please pass `elements=[...]` to the `from_POSCAR` routine where
            ... are the elements in the same order as in the POSCAR."""
        raise exception.IncorrectUsage(message)

class Mixin:
    @property
    def _structure(self):
        return Structure.from_data(self._raw_data.structure)


from __future__ import absolute_import, division, print_function
#coding: utf-8
import random
from scitbx.array_family import flex
import scitbx.math
from scitbx import matrix
from libtbx.test_utils import approx_equal
from six.moves import range

def exercise_ellipsoid(n_trials=100, n_sub_trials=10):
  from gltbx import quadrics
  rnd = random.Random(0)
  for i in range(n_trials):
    centre = matrix.col([ rnd.random() for k in range(3) ])
    half_lengths = matrix.col([ 0.1 + rnd.random() for k in range(3) ])
    r = scitbx.math.euler_angles_as_matrix(
      [ rnd.uniform(0, 360) for i in range(3) ], deg=True)
    metrics = r * matrix.diag([ x**2 for x in half_lengths ]) * r.transpose()
    t = quadrics.ellipsoid_to_sphere_transform(centre, metrics.as_sym_mat3())
    assert approx_equal(t.translation_part(), centre)
    m = matrix.sqr(t.linear_part())
    assert m.determinant() > 0
    for j in range(n_sub_trials):
      y = matrix.col([ rnd.random() for k in range(3) ])
      c_y = y.transpose() * y
      x = m*y
      c_x = x.transpose() * metrics.inverse() * x
      assert approx_equal(c_x, c_y)
  r = scitbx.math.euler_angles_as_matrix((30, 115, 260), deg=True)
  centre = matrix.col((-1, 2, 3))
  metrics = r * matrix.diag((-1, 0.1, 1)) * r.transpose()
  t = quadrics.ellipsoid_to_sphere_transform(centre, metrics.as_sym_mat3())
  assert t.non_positive_definite()

def time_ellipsoid(n=1000000):
  from gltbx.quadrics import time_ellipsoid_to_sphere_transform
  import timeit
  u = flex.sym_mat3_double(n, (0.0008, 0.0004, 0.0002,
                               0.0001, 0.00015, 0.00005))
  timer = timeit.Timer(lambda: time_ellipsoid_to_sphere_transform(u))
  # \xb5s is unicode for mu
  print (u"%i ellipsoid --> sphere transforms: %.3g \xb5s per transform"
         % (n, timer.timeit(1)/n*1e6))

def run():
  import sys
  from libtbx.option_parser import option_parser
  try:
    import gltbx.gl
  except ImportError:
    print("Skipping gltbx/tst_ellipsoids.py: gltbx.gl module not available.")
    sys.exit(1)

  exercise_ellipsoid()

  command_line = (option_parser(
    usage="",
    description="")
    .option(None, "--time", action="store_true")
    ).process(args=sys.argv[1:])
  if command_line.options.time:
    if command_line.args:
      time_ellipsoid(int(command_line.args[0]))
    else:
      time_ellipsoid()
  print("OK")

if __name__ == '__main__':
  run()


import functools
import warnings

import logbook

from six import iteritems

import numpy as np
import pandas as pd

from . import risk
from .risk import check_entry

from empyrical import (
    alpha_beta_aligned,
    annual_volatility,
    downside_risk,
    information_ratio,
    sharpe_ratio,
    sortino_ratio
)
from catalyst.patches.stats import (
    max_drawdown,
    cum_returns,
)

from catalyst.constants import LOG_LEVEL

log = logbook.Logger('Risk Period', level=LOG_LEVEL)

choose_treasury = functools.partial(risk.choose_treasury,
                                    risk.select_treasury_duration)

class RiskMetricsPeriod(object):
    def __init__(self, start_session, end_session, returns, trading_calendar,
                 treasury_curves, benchmark_returns, algorithm_leverages=None):
        if treasury_curves.index[-1] >= start_session:
            mask = ((treasury_curves.index >= start_session) &
                    (treasury_curves.index <= end_session))

            self.treasury_curves = treasury_curves[mask]
        else:
            # our test is beyond the treasury curve history
            # so we'll use the last available treasury curve
            self.treasury_curves = treasury_curves[-1:]

        self._start_session = start_session
        self._end_session = end_session
        self.trading_calendar = trading_calendar

        trading_sessions = trading_calendar.sessions_in_range(
            self._start_session,
            self._end_session,
        )
        self.algorithm_returns = self.mask_returns_to_period(returns,
                                                             trading_sessions)

        # Benchmark needs to be masked to the same dates as the algo returns
        self.benchmark_returns = self.mask_returns_to_period(
            benchmark_returns,
            self.algorithm_returns.index
        )
        self.algorithm_leverages = algorithm_leverages

        self.calculate_metrics()

    def calculate_metrics(self):
        warnings.filterwarnings('error')

        try:
            self.benchmark_period_returns = \
                cum_returns(self.benchmark_returns).iloc[-1]
        except Exception:
            # TODO: why is there an error
            self.benchmark_period_returns = 0

        self.algorithm_period_returns = \
            cum_returns(self.algorithm_returns).iloc[-1]

        if not self.algorithm_returns.index.equals(
                self.benchmark_returns.index
        ):
            message = "Mismatch between benchmark_returns ({bm_count}) and \
            algorithm_returns ({algo_count}) in range {start} : {end}"
            message = message.format(
                bm_count=len(self.benchmark_returns),
                algo_count=len(self.algorithm_returns),
                start=self._start_session,
                end=self._end_session
            )
            raise Exception(message)

        self.num_trading_days = len(self.benchmark_returns)

        self.mean_algorithm_returns = (
            self.algorithm_returns.cumsum() /
            np.arange(1, self.num_trading_days + 1, dtype=np.float64)
        )

        self.benchmark_volatility = annual_volatility(self.benchmark_returns)
        self.algorithm_volatility = annual_volatility(self.algorithm_returns)

        self.treasury_period_return = choose_treasury(
            self.treasury_curves,
            self._start_session,
            self._end_session,
            self.trading_calendar,
        )
        self.sharpe = sharpe_ratio(
            self.algorithm_returns,
        )
        # The consumer currently expects a 0.0 value for sharpe in period,
        # this differs from cumulative which was np.nan.
        # When factoring out the sharpe_ratio, the different return types
        # were collapsed into `np.nan`.
        # TODO: Either fix consumer to accept `np.nan` or make the
        # `sharpe_ratio` return type configurable.
        # In the meantime, convert nan values to 0.0
        if pd.isnull(self.sharpe):
            self.sharpe = 0.0
        self.downside_risk = downside_risk(
            self.algorithm_returns.values
        )

        try:
            risk = self.downside_risk
            self.sortino = sortino_ratio(
                self.algorithm_returns.values,
                _downside_risk=risk,
            )
        except Exception:
            # TODO: what causes it to error out?
            self.sortino = 0

        self.information = information_ratio(
            self.algorithm_returns.values,
            self.benchmark_returns.values,
        )
        self.alpha, self.beta = alpha_beta_aligned(
            self.algorithm_returns.values,
            self.benchmark_returns.values,
        )
        self.excess_return = self.algorithm_period_returns \
            - self.treasury_period_return
        self.max_drawdown = max_drawdown(self.algorithm_returns.values)
        self.max_leverage = self.calculate_max_leverage()

        warnings.resetwarnings()

    def to_dict(self):
        """
        Creates a dictionary representing the state of the risk report.
        Returns a dict object of the form:
        """
        period_label = self._end_session.strftime("%Y-%m")
        rval = {
            'trading_days': self.num_trading_days,
            'benchmark_volatility': self.benchmark_volatility,
            'algo_volatility': self.algorithm_volatility,
            'treasury_period_return': self.treasury_period_return,
            'algorithm_period_return': self.algorithm_period_returns,
            'benchmark_period_return': self.benchmark_period_returns,
            'sharpe': self.sharpe,
            'sortino': self.sortino,
            'information': self.information,
            'beta': self.beta,
            'alpha': self.alpha,
            'excess_return': self.excess_return,
            'max_drawdown': self.max_drawdown,
            'max_leverage': self.max_leverage,
            'period_label': period_label
        }

        return {k: None if check_entry(k, v) else v
                for k, v in iteritems(rval)}

    def __repr__(self):
        statements = []
        metrics = [
            "algorithm_period_returns",
            "benchmark_period_returns",
            "excess_return",
            "num_trading_days",
            "benchmark_volatility",
            "algorithm_volatility",
            "sharpe",
            "sortino",
            "information",
            "beta",
            "alpha",
            "max_drawdown",
            "max_leverage",
            "algorithm_returns",
            "benchmark_returns",
        ]

        for metric in metrics:
            value = getattr(self, metric)
            statements.append("{m}:{v}".format(m=metric, v=value))

        return '\n'.join(statements)

    def mask_returns_to_period(self, daily_returns, trading_days):
        if isinstance(daily_returns, list):
            returns = pd.Series([x.returns for x in daily_returns],
                                index=[x.date for x in daily_returns])
        else:  # otherwise we're receiving an index already
            returns = daily_returns

        trade_day_mask = returns.index.normalize().isin(trading_days)

        mask = ((returns.index >= self._start_session) &
                (returns.index <= self._end_session) & trade_day_mask)

        returns = returns[mask]
        return returns

    def calculate_max_leverage(self):
        if self.algorithm_leverages is None:
            return 0.0
        else:
            return max(self.algorithm_leverages)


import pytest

import ezdxf
from ezdxf.entities.underlay import PdfDefinition, PdfUnderlay

@pytest.fixture(scope="module")
def doc():
    return ezdxf.new("R2000")

@pytest.fixture
def pdf_def(doc):
    return PdfDefinition.from_text(PDF_DEFINITION, doc)

def test_pdf_def_properties(pdf_def):
    assert "PDFDEFINITION" == pdf_def.dxftype()
    assert "PDFUNDERLAY" == pdf_def.entity_name

def test_pdf_def_dxf_attribs(pdf_def):
    assert "underlay.pdf" == pdf_def.dxf.filename
    assert "underlay_key" == pdf_def.dxf.name

@pytest.fixture
def pdf(doc):
    return PdfUnderlay.from_text(PDF_UNDERLAY, doc)

def test_pdf_properties(pdf):
    assert "PDFUNDERLAY" == pdf.dxftype()

def test_pdf_dxf_attribs(pdf):
    assert pdf.dxf.insert == (0.0, 0.0, 0.0)
    assert pdf.dxf.scale_x == 2.5
    assert pdf.dxf.scale_y == 2.5
    assert pdf.dxf.scale_z == 2.5
    assert pdf.scaling == (2.5, 2.5, 2.5)
    assert pdf.dxf.flags == 2
    assert pdf.clipping == 0
    assert pdf.on == 1
    assert pdf.monochrome == 0
    assert pdf.adjust_for_background == 0
    assert pdf.dxf.contrast == 100
    assert pdf.dxf.fade == 0
    assert pdf.dxf.underlay_def_handle == "DEAD1"

def test_get_boundary_path(pdf):
    assert pdf.boundary_path == []

def test_reset_boundary_path(pdf):
    pdf.reset_boundary_path()
    assert pdf.boundary_path == []
    assert pdf.clipping is False

def test_set_boundary_path(pdf):
    pdf.set_boundary_path([(0, 0), (640, 180), (320, 360)])  # 3 vertices triangle
    assert pdf.clipping == 1
    assert pdf.boundary_path == [(0, 0), (640, 180), (320, 360)]

def test_set_scale(pdf):
    pdf.scaling = (1.2, 1.3, 1.4)
    assert pdf.scaling == (1.2, 1.3, 1.4)

    pdf.scaling = 1.7
    assert pdf.scaling == (1.7, 1.7, 1.7)

@pytest.fixture
def new_doc():
    # setting up a drawing is expensive - use as few test methods as possible
    return ezdxf.new("R2000")

def test_new_pdf_underlay_def(new_doc):
    rootdict = new_doc.rootdict
    assert "ACAD_PDFDEFINITIONS" not in rootdict
    underlay_def = new_doc.add_underlay_def("underlay.pdf", fmt="pdf", name="u1")

    # check internals pdf_def_owner -> ACAD_PDFDEFINITIONS
    pdf_dict = rootdict["ACAD_PDFDEFINITIONS"]
    assert underlay_def.dxf.owner == pdf_dict.dxf.handle

    assert "underlay.pdf" == underlay_def.dxf.filename
    assert "u1" == underlay_def.dxf.name

def test_new_pdf(new_doc):
    msp = new_doc.modelspace()
    underlay_def = new_doc.add_underlay_def("underlay.pdf")
    underlay = msp.add_underlay(underlay_def, insert=(0, 0, 0), scale=2)
    assert underlay.dxf.insert == (0, 0, 0)
    assert underlay.dxf.scale_x == 2
    assert underlay.dxf.scale_y == 2
    assert underlay.dxf.scale_z == 2
    assert underlay_def.dxf.handle == underlay.dxf.underlay_def_handle
    assert underlay.clipping is False
    assert underlay.on is True
    assert underlay.monochrome is False
    assert underlay.adjust_for_background is True
    assert underlay.dxf.flags == 10

    underlay_def2 = underlay.get_underlay_def()
    assert underlay_def.dxf.handle == underlay_def2.dxf.handle

class TestCopyAndTransformUnderlay:
    @pytest.fixture(scope="class")
    def doc(self):
        return ezdxf.new()

    @pytest.fixture(scope="class")
    def underlay_def(self, doc):
        return doc.add_underlay_def("underlay.pdf")

    @pytest.fixture(scope="class")
    def msp(self, doc):
        return doc.modelspace()

    def test_copied_underlay_has_same_underlay_definition(self, msp, underlay_def):
        underlay = msp.add_underlay(underlay_def, insert=(0, 0, 0), scale=2)
        clone = underlay.copy()
        msp.add_entity(clone)
        assert (
            underlay.get_underlay_def() is clone.get_underlay_def()
        ), "expected the same underlay definition"

    def test_underlay_definition_has_reactor_handles_to_copies(self, msp, underlay_def):
        underlay = msp.add_underlay(underlay_def, insert=(0, 0, 0), scale=2)
        clone = underlay.copy()
        msp.add_entity(clone)

        assert (
            underlay.dxf.handle in underlay_def.reactors
        ), "expected reactor handle of original underlay"
        assert (
            clone.dxf.handle in underlay_def.reactors
        ), "expected reactor handle of cloned underlay"

    def test_transform_underlay(self, msp, underlay_def):
        """The UNDERLAY entity uses the same low-level transform function as INSERT,
        no extensive transformation testing is required.
        """
        underlay = msp.add_underlay(underlay_def, insert=(0, 0, 0), scale=2)
        underlay.translate(1, 2, 3)

        assert underlay.dxf.insert == (1, 2, 3)

PDF_DEFINITION = """  0
PDFDEFINITION
  5
DEAD1
330
DEAD2
100
AcDbUnderlayDefinition
  1
underlay.pdf
  2
underlay_key
"""

PDF_UNDERLAY = """  0
PDFUNDERLAY
  5
DEAD3
330
DEAD4
100
AcDbEntity
  8
0
100
AcDbUnderlayReference
340
DEAD1
 10
0.0
 20
0.0
 30
0.0
 41
2.5
 42
2.5
 43
2.5
280
  2
281
   100
282
     0
"""


import json
import os
from pathlib import Path

from . import logger
from .models.configs import CONFIG_CLASSES
from .models.image import ImageEntry

PATH_TO_CONFIGS = Path(os.environ.get("PATH_TO_CONFIGS"))
CONFIG_CLASS = os.environ.get("CONFIG_CLASS", "BasicConfig")
GLOB_PATTERN = os.environ.get("GLOB_PATTERN", "photos.csv")
OUTPUT_FOLDER = Path(os.environ.get("OUTPUT_FOLDER", "images"))
CROPPED_SUBFOLDER = os.environ.get("CROPPED_SUBFOLDER", "_cropped")
SPLIT_BY_CATEGORY = bool(int(os.environ.get("SPLIT_BY_CATEGORY", 1)))
CROP_DIMENSIONS = json.loads(os.environ.get("CROP_DIMENSIONS", "[[10, 15]]"))
DPCM = int(os.environ.get("DPCM", 120))

ConfigClass = CONFIG_CLASSES[CONFIG_CLASS]
config = ConfigClass.from_csvs(PATH_TO_CONFIGS, GLOB_PATTERN)

for i, entry in enumerate(config.entries):
    logger.info("%s/%s", i + 1, len(config.entries))
    output_dir = OUTPUT_FOLDER
    if SPLIT_BY_CATEGORY and entry.category is not None:
        output_dir /= entry.category
    image = ImageEntry.from_url(url=entry.url,
                                prompt=entry.prompt,
                                output_dir=output_dir)
    image.save()
    for width, height in CROP_DIMENSIONS:
        cropped_image = image.crop_image(width, height, DPCM, CROPPED_SUBFOLDER)
        if cropped_image.prompt:
            cropped_image.embed_prompt()
        cropped_image.save()


import pandas as pd
import re
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.stem import PorterStemmer
from nltk import download
from collections import Counter

# Download NLTK
download('punkt')
download('stopwords')

# Initialize the PorterStemmer
stemmer = PorterStemmer()

# Get stopwords
stop_words = set(stopwords.words('english'))

# Function to clean text
def clean_text(text):
    # Remove punctuations and numbers
    text = re.sub('[^a-zA-Z]', ' ', text)

    # Convert to lowercase
    text = text.lower()

    # Tokenize
    word_tokens = word_tokenize(text)

    # Stopword removal and stemming
    text = [stemmer.stem(word) for word in word_tokens if word not in stop_words]

    text = ' '.join(text)

    return text

# Load the data
data = pd.read_csv('~/newworkspace/amazon_review_polarity_csv/train.csv', header=None, names=['sentiment', 'title', 'review'])

# Fill NaNs with an empty string
data = data.fillna("")

# Apply the function to the 'title' and 'review' columns
data['title'] = data['title'].apply(clean_text)
data['review'] = data['review'].apply(clean_text)

# Select only negative reviews
data = data[data['sentiment'] == 1]

# Remove null values
data = data.dropna()

# Keep only the cleaned 'review' column
data = data['review']

# Reset the index of the DataFrame
data = data.reset_index(drop=True)

# Split the reviews into words and count the occurrences of each word
word_counts = Counter(' '.join(data).split())

# Convert the word counts to a DataFrame and reset the index
word_counts_df = pd.DataFrame.from_dict(word_counts, orient='index').reset_index()

# Rename the columns
word_counts_df.columns = ['Word', 'Count']

# Sort the DataFrame by the counts in descending order
word_counts_df = word_counts_df.sort_values(by='Count', ascending=False)

# Print the top 10 words
print(word_counts_df.head(10))

# Save output to a CSV file
word_counts_df.to_csv('~/newworkspace/word_counts.csv', index=False)


#!/usr/bin/env python
# coding=utf-8
##############################################################
 # File Name : LF_refocusing.py
 # Purpose : Refocus the Light Field Image
 # Creation Date : Wed 16 Aug 2017 02:04:54 PM CST
 # Last Modified : Sun 20 Aug 2017 01:15:39 AM CST
 # Created By : SL Chung
##############################################################
#Usage:
#    python3 LF_refocusing.py ./Img_Directory
import cv2
import numpy as np
import math
import sys
import os
from matplotlib import pyplot as plt

from python_tools import file_io

#def imshow(window_name, img, start_x, start_y):
#    cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
#    cv2.resizeWindow(window_name, 400, 400)
#    cv2.moveWindow(window_name, start_x, start_y)
#    cv2.imshow(window_name, center_img)

def gen_shifted_img(params, light_field, delta_x, delta_y):
    shifted_img = np.zeros((params['height'], params['width'], 3))
    center_coordinate = (params['num_cams_x']//2 + 1, params['num_cams_y']//2 + 1)

    for i in range(params['num_cams_x']):
        for j in range(params['num_cams_y']):
            start_x = (center_coordinate[0] - i) * delta_x
            start_y = (center_coordinate[1] - j) * delta_y
            temp = np.concatenate((light_field[i, j, start_x:, :, :], light_field[i, j, 0:start_x, :, :]), 0)
            temp = np.concatenate((temp[:, start_y:, :], temp[:, 0:start_y, :]), 1)
            shifted_img = shifted_img + temp

    shifted_img = shifted_img / ( params['num_cams_x'] * params['num_cams_y'])
    shifted_img = shifted_img.astype('uint8')
    return shifted_img

if len(sys.argv) < 2:
    print('Error: need input directory of source of GIF!')
    sys.exit()

LF_directory = sys.argv[1]

params = file_io.read_parameters(sys.argv[1])
light_field = file_io.read_lightfield(sys.argv[1])

center_img = light_field[ math.ceil(params['num_cams_x'] / 2),
                          math.ceil(params['num_cams_y'] / 2), :, :, : ]
center_img = center_img.astype('uint8')

average_img = np.sum(light_field, (0, 1)) / ( params['num_cams_x'] * params['num_cams_y'])
average_img = average_img.astype('uint8')

shifted_img = gen_shifted_img(params, light_field, 1, 1);

window=[]
window.append('Original Center Img')
window.append('Average Img')
window.append('Shifted Img')

#start_x = 0
#start_y = 0
#imshow(window[0], center_img, start_x, start_y)
#
#start_x = start_x + 400;
#imshow(window[1], average_img, start_x, start_y)
#
#cv2.waitKey(0)
#cv2.destroyAllWindows()

plt.subplot(1,3,1),plt.imshow(cv2.cvtColor( center_img, cv2.COLOR_BGR2RGB))
plt.title(window[0]), plt.xticks([]), plt.yticks([])
plt.subplot(1,3,2),plt.imshow(cv2.cvtColor(average_img, cv2.COLOR_BGR2RGB))
plt.title(window[1]), plt.xticks([]), plt.yticks([])
plt.subplot(1,3,3),plt.imshow(cv2.cvtColor(shifted_img, cv2.COLOR_BGR2RGB))
plt.title(window[2]), plt.xticks([]), plt.yticks([])

plt.show()

if not os.path.exists('./shifted/'):
    os.makedirs('./shifted')

for i in range(11):
    i = i - 5
    s = gen_shifted_img(params, light_field, i, i);
    cv2.imwrite('./shifted/shift_' + str(i) + '.jpg', s)


#!/usr/bin/python3
import sqlite3
import io
import sys

class Database:
	'''Server database implementation
	To save changes after modifying the database it is necessary to call the method save_changes'''

	def __init__(self, name = ':memory:'):
		'''Init the database'''

		self.con = sqlite3.connect(name, check_same_thread = False)
		try:
			self.create_tables()
		except:
			print("Error creating tables")
			pass

	def print_database(self):
		'''This function is useful for DEBUG'''

		cursor = self.con.cursor()

		def print_lines_db():
			try:
				for line in cursor.fetchall():
					print (line)
			except:
				print("ERROR")

		print('clients:')
		cursor.execute( """ SELECT * FROM clients;""")
		print_lines_db()

		print('tasks:')
		cursor.execute( """ SELECT * FROM tasks;""")
		print_lines_db()

	def connect_client(self, name):
		''' Insert client in clients table
		If client already exists, put it as connected'''

		cursor = self.con.cursor()

		cursor.execute('SELECT client FROM clients WHERE client = ?', (name,))
		exists = cursor.fetchone()

		if not exists:
			#First time that the client connect to server
			cursor.execute("""
				INSERT INTO clients (client, done_tasks, connected)
				VALUES (?, ?, ?)
				""", (name, 0, True))
		else:
			#Client has been connected sometime, so now, just update the status to online
			self.set_client(name, True)

	def set_client(self, name, connected):
		'''To use this method the client needs to be in clients table
		Put in clients table from database if client is connected(1) or disconnected(0) at the moment'''

		cursor = self.con.cursor()

		cursor.execute("""
			UPDATE clients SET connected = ? WHERE client = ?
			""", (connected, name))

	def add_tasks(self, arguments):
		''' Inserts tasks in tasks table
		arguments should be a tuple list
		Each tuple represents argument_1, argument_2 and sent(0) at tasks table from database'''

		cursor = self.con.cursor()

		cursor.executemany("""
			INSERT INTO tasks (argument_1, argument_2, sent, command, ftp)
			VALUES (?, ?, ?, ?, ?)
			""", arguments)

		self.save_changes()

	def get_client_tasks(self, name):
		'''Returns a tasks list where client is executing and haven't send the output file, in other words, unfinished tasks'''

		cursor = self.con.cursor()
		cursor.execute('SELECT id FROM tasks WHERE name_ip = ? and output IS NULL ', (name,))

		return cursor.fetchall()

	def get_task(self):
		'''Returns a tuple (arg_1, arg_2) if exists a task to execute, else returns None'''

		cursor = self.con.cursor()

		cursor.execute('SELECT id, argument_1, argument_2 FROM tasks WHERE sent = ?', (False,))
		return cursor.fetchone()

	def get_all_tasks(self):
		''' Take all tasks. Returns a tasks tuple'''

		cursor = self.con.cursor()

		cursor.execute('SELECT id, argument_1, argument_2, command, ftp FROM tasks WHERE sent = ?', (False,))
		return cursor.fetchall()

	def get_task_id(self, argument_1, argument_2):
		'''Returns the task ID of argument_1 and argument_2'''

		cursor = self.con.cursor()

		cursor.execute('SELECT id FROM tasks WHERE argument_1 = ? and argument_2 = ?', (argument_1, argument_2))
		return cursor.fetchone()

	def update_incomplete_task(self, update):
		'''Take tasks IDs list that were not sucessfully completed by client and change sent value to False '''

		cursor = self.con.cursor()

		cursor.executemany("""
			UPDATE tasks
			SET sent = ?
			WHERE id = ?
			""", update)

		self.save_changes()

	def update_output(self, arg_1, arg_2, task_received_date, output_filename):
		'''Update the output file and task reception time'''

		cursor = self.con.cursor()

		cursor.execute("""
			UPDATE tasks
			SET task_received_date = ?, output = ?
			WHERE argument_1 = ? and argument_2 = ?
			""", (task_received_date, output_filename, arg_1, arg_2))

		self.save_changes()

	def update_sent_task(self, update):
		'''Task sent to client, update: name_ip, task_sent_date and sent'''

		cursor = self.con.cursor()

		cursor.executemany("""
			UPDATE tasks
			SET name_ip = ?, task_sent_date = ?, sent = ?
			WHERE id = ?
			""", update)

		self.save_changes()

	def client_done_task(self, name):
		'''Increments the sent tasks number from client'''

		cursor = self.con.cursor()

		cursor.execute('SELECT done_tasks FROM clients WHERE client = ?', (name,))
		num_done_tasks = cursor.fetchone()
		num_done_tasks = num_done_tasks[0] + 1

		cursor.execute("""
			UPDATE clients
			SET done_tasks = ?
			WHERE client = ?
			""", (num_done_tasks, name))

		self.save_changes()

	def save_changes(self):
		'''Save changes at database'''

		self.con.commit()

	def create_tables(self):
		'''Create tables at database'''

		cursor = self.con.cursor()

		#Create clients table
		cursor.execute("""
		CREATE TABLE IF NOT EXISTS clients(
			client TEXT NOT NULL PRIMARY KEY,
			done_tasks INTEGER NOT NULL,
			connected BOOLEAN NOT NULL
			);
			""")

		#Create tasks table
		cursor.execute("""
		CREATE TABLE IF NOT EXISTS tasks(
			id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
			name_ip TEXT,
			argument_1 TEXT NOT NULL,
			argument_2 TEXT NOT NULL,
			task_sent_date DATE,
			sent BOOLEAN NOT NULL,
			command TEXT NOT NULL,
			task_received_date DATE,
			ftp TEXT NOT NULL,
			output TEXT,
			unique(argument_1,argument_2) ON CONFLICT IGNORE
			);
			""")


# Creates jobs to fetch tweets from twitter for the timeframe since 2016-01-01 until 2016-12-31

import argparse
from requests.utils import quote

# parse command line arguments
parser = argparse.ArgumentParser("jobcomposer")
parser.add_argument("inputfile", help="Filename to parse for headlines", type=str)
parser.add_argument("outputfile", help="Filename to parse for headlines", type=str)
parser.add_argument("database", help="Database to save to", type=str)
parser.add_argument("--limit", help="Max number of tweets to scrap", type=int, default=10000, required=False)
args = parser.parse_args()

# open files
headlines = open(args.inputfile,"r")
jobs = open(args.outputfile,"w")

# construct shell commands that use fetcher and write them to file
count = 0
for line in headlines.read().split("\n"):
    for i in range(3):
        encoded_query = quote(line) + "%20since%3A2016-01-01%20until%3A2016-12-31"
        job = "python fetcher.py " + args.database + " _" + str(count) + "_" + str(i) + " " + encoded_query + " " + str(args.limit) + "\n"
        jobs.write(job)
    count += 1

# close files
headlines.close()
jobs.close()


from django.shortcuts import render

import re
from .models import Slides, AboutUs, AboutUsImages

# Create your views here.

def home(request):
    return render(request, 'home.html', {})

def main_banner(request):
    slides = Slides.objects.all().order_by('slide_number')
    context = {
        'slides': slides
    }

    return render(request, 'main_banner.html', context)

def about_us(request):
    about_us = AboutUs.objects.first()
    about_us_images = AboutUsImages.objects.all().order_by('image_number')

    video_link = about_us.youtube_link
    regex = r'v=(.*)'
    video_id = re.findall(regex, video_link)[0]

    context = {
        'about_us': about_us,
        'images': about_us_images,
        'video_id': video_id,
    }

    return render(request, 'about_area.html', context)