import discord          #on fait un bot pour discord, c'est de première nécessité
import random           #importe la bilbiothèque nécessaire pour créer de l'aléatoire
import math             #importe le module math pour la valeur aboslue
import re               #importe les expressions régulières
import datetime         #importe la date du jour et des méthodes en rapport
import time             #permet d'utiliser sleep
import json             #pour interragir avec des fichiers json
import os               #pour interragir avec le système, lancer des commandes en bash par exemple
import subprocess       #même idée
from chat import *

from discord.ext import commands

bot = commands.Bot(command_prefix = '$') #création du préfixe qui servira à dire "ceci est une commande"

#************ FERMETURE DU BOT *************************************************

@bot.command(hidden=True)
async def quit(ctx):
    if ctx.author.id == 404395089389944832 :
        await ctx.send("Au revoir")
        print("Bot éteint sans anicroches")
        await bot.close()
    else :
        await ctx.send("nope")

#************* JEU DE HASARD ***************************************************
#première commande du bot pour découvrir la librairie discord.py

@bot.command(help="Un petit jeu pour tuer le temps : il faut taper $score suivi d'un guess entre 0 et 100. Le bot trouve un nombre mystère aléatoire et fait la différence avec ton guess. Plus celle-ci est petite, plus tu es lucky")                           #commande $score : permet de faire un guess et d'obtenir la différence avec ce guess
async def score(ctx, guess):

    random.seed()                           #initialise la seed et
    score = random.randint(0,100)           #renvoie un nb pseudo aléatoire dans l'intervalle [0;100]

    guess = int(guess)
    delta = abs(score-guess)  # 2 lignes pour calculer la différence absolue entre le guess et le score obtenu (abs vient de la bibliothèque math)

    await ctx.send('nombre mystère : {}'.format(score)) #renvoie le résultat en msg discord
    await ctx.send('différence : {}'.format(delta))     #renvoie la différence

    from datetime import date
    today = date.today()       #2 lignes pour écrire la date d'obtention du score

    resultats = open("resultats.txt","a")   #ouvre le fichier resultats.txt en mode "append" : chaque écriture se fait à la suite de ce qui est déjà écrit
    resultats.writelines([str(ctx.message.author), " : " ,str(delta), " : ", str(today),"\n"]) #ecrit le nom d'utilisateur, le score et la date dans chaque nouvelle ligne du .txt
    resultats.close()   # a priori utile de fermer le fichier une fois écrit pour pouvoir l'ouvrir dans une autre commande

# gestion d'erreurs pour le mini jeu
@score.error
async def score_error(ctx, error):
    if isinstance(error, commands.MissingRequiredArgument):
        await ctx.send("Il faut mettre un nombre après $score")
    elif(error, commands.CommandInvokeError):
        await ctx.send("$score n'accepte pas les chaines de caractères :rage:")
    else:
        await ctx.send("erreur")

# COMMANDE BEST
@bot.command(help="Cette commande renvoie le nom d'utilisateur ayant eu le meilleur delta par rapport à son guess.\nLes résultats sont rentrés dans un fichier quand $score est appelé, et cette commande lit le fichier qui en résulte.")
#commande pour extraire celui ayant le meilleur guess, accompagné de la date
async def best(ctx):
    resultats = open("resultats.txt", "r")
    min = 101
    for i, line in enumerate(resultats):
        match = re.search('(: )(\d?\d)( :)', line) #chaque expression entre parenthèse correspond à un groupe
        if match:
            score_obtenu = match.group(2)          #le group(2) fait référence aux deuxièmes parenthèses du match
            score_obtenu = int(score_obtenu)
            if (score_obtenu < min):
                min = score_obtenu
                match = re.search('[^0-9^#]*', line)
                if match:
                    nom = match.group(0)
                match = re.search('\d{4}-\d{2}-\d{2}', line)
                if match:
                    date = match.group(0)
        else:
            print("il n'y a pas encore de résultat")
    await ctx.send("{} a obtenu le meilleur delta, à savoir {} le {}".format(nom, min, date))

#************* SUPPRESSION DE MESSAGES *****************************************

@bot.command(help="efface le nombre de messages indiqué", hidden=True)
@commands.has_permissions(manage_messages=True)
async def clear(ctx, nb_messages : int):
    await ctx.channel.purge(limit=nb_messages+1)

@clear.error
async def clear_error():
    if isinstance(error, commands.MissingPermissions):
        await ctx.send("tu n'as pas les droits, loser !")
    elif (isinstance(error, commands.MissingRequiredArgument)):
        await ctx.send("Il faut mettre un nombre après $score")

#************* UNE FONCTION POUR LIMITER LES DISTRACTIONS **********************
@bot.command(help="Pour récupérer l'accès aux salons")
async def retour(ctx):
    role_m1 = discord.utils.get(ctx.guild.roles, id=627581972025442314)
    role_retour = discord.utils.get(ctx.guild.roles, id=671289711846883328)
    await ctx.author.add_roles(role_m1, reason=None, atomic=True)
    await ctx.author.remove_roles(role_retour, reason=None, atomic=True)

@bot.command(help="Quand tu as besoin d'éliminer les distractions liées à ce discord")
async def silence(ctx):
    role_m1 = discord.utils.get(ctx.guild.roles, id=627581972025442314)
    role_retour = discord.utils.get(ctx.guild.roles, id=671289711846883328)
    await ctx.author.remove_roles(role_m1, reason=None, atomic=True)
    await ctx.author.add_roles(role_retour, reason=None, atomic=True)

#************* GESTIONS DE SALONS **********************************************
#création de salons privés
@bot.command(help="Ecrire la commande suivie du nom du salon.\nPour ecrire plusieurs mots, ecrire la phrase entre guillemets")
@commands.has_permissions(administrator=True)
async def salon(ctx, arg):   #nom de la commande
#création du rôle
    guild = ctx.guild
    role = await guild.create_role(name=arg)

#création du salon
    cat=ctx.channel.category #permet de connaitre la catégorie du salon textuel, sinon le salon est créé tout en haut dans le serveur
    roles = {
    guild.default_role: discord.PermissionOverwrite(read_messages=False),
    role: discord.PermissionOverwrite(read_messages=True)
}
    await guild.create_text_channel(name=arg, overwrites=roles, category=cat)   #puis création du salon avec le même nom
@salon.error
async def salon_error():
    if isinstance(error, commands.MissingPermissions):
        await ctx.send("tu n'as pas les droits, loser !")

#suppression des rôles et salons
@bot.command(help="Supprime un salon et un rôle\nDonner le nom du salon et du rôle en arguments de la commande\nPour les noms composés de plusieurs mots, utiliser les guillemets")
@commands.has_permissions(administrator=True)
async def dels(ctx, ch : discord.TextChannel, rl : discord.Role):
    await rl.delete()
    await ch.delete()
@dels.error
async def dels_error():
    if isinstance(error, commands.MissingPermissions):
        await ctx.send("tu n'as pas les droits, loser !")

#************ PARTIE COMPTAGE DES MESSAGES / EVENTS ****************************

#Comptage des messages, envoi de messages aléatoire et réaction aux messages ***
@bot.event
async def on_message(message):

    #partie comptage ---------
    if message.guild.id == 621610918429851649 and len(message.content)>2 :
        auteur=str(message.author)
        try :
            with open("rangs.json", "r+") as rangs:
                liste_auteurs=json.load(rangs)
                if auteur in liste_auteurs :
                    liste_auteurs[auteur] = liste_auteurs[auteur] +1
                else :
                    liste_auteurs[auteur] = 1
        except :
            pass
        try :
            with open("rangs.json", "w+") as rangs:
                rangs.write(json.dumps(liste_auteurs, sort_keys=True, indent=4))
        except :
            pass
    #fonctions issues de "chat.py" //usage humoristique
    await rand_mess(message)    #envoi aléatoire de message
    await react_emoji(message)  #réaction par emoji à certains messages
    await react_mess(message)   #réaction textuelle à certains messages
    #await discut(message)       #réaction à une mention du bot, pas encore implémentée

    await bot.process_commands(message)

#Nombre de messages de l'auteur
@bot.command()
async def mess(ctx):
    somme = 0
    auteur = (str(ctx.message.author))
    with open("rangs.json", "r") as auteurs:
        liste = json.load(auteurs)
        nb_messages = liste[auteur]
    max = 0
    for auteur in liste :
        somme += int(liste[auteur])
        if int(liste[auteur]) > max :
            max = int(liste[auteur])
            print(max)
    if nb_messages >= max-1 :
        message = (f"Tu as envoyé {nb_messages} messages {ctx.message.author.mention}\n T'es le top 1, le king, on ne voit que toi sur discord, félicitations BG")
    elif nb_messages/somme > 1/10 :
        message = (f"Tu as envoyé {nb_messages} messages {ctx.message.author.mention}\nTu fais partie de l'élite, le top 10%, GG")
    elif nb_messages/somme > 1/15 :
        message = (f"Tu as envoyé {nb_messages} messages {ctx.message.author.mention}\nPas dégueu, merci de rendre ce forum actif !")
    elif nb_messages/somme > 1/30 :
        message = (f"Tu as envoyé {nb_messages} messages {ctx.message.author.mention}\nDes gens parlent plus, des gens parlent moins")
    elif nb_messages/somme > 1/60 :
        message = (f"Tu as envoyé {nb_messages} messages {ctx.message.author.mention}\nQuelques efforts sont à fournir")
    elif nb_messages/somme > 1/100 :
        message = (f"Tu as envoyé {nb_messages} messages {ctx.message.author.mention}\nIl va falloir penser à se réveiller")
    else :
        message = (f"Tu as envoyé {nb_messages} messages {ctx.message.author.mention}\nJe crois que je ne peux plus rien pour toi...")
    await ctx.send(message)

#Personnes les plus bavardes du chat
@bot.command()
async def rank(ctx):
    top=5
    liste_auteurs = []
    with open("rangs.json", "r") as rangs:
        dict = json.load(rangs)
        for key, value in dict.items():
            temp = [key,value]
            liste_auteurs.append(temp)
            if len(liste_auteurs)<int(top) :
                top = int(len(liste_auteurs))
    liste_auteurs.sort(key=lambda liste_auteurs: liste_auteurs[1], reverse=True)
    sortie = ""
    i = 1
    for auteur in liste_auteurs :
        sortie = sortie + (f"Top {i} : {auteur[0]} avec {str(auteur[1])} messages\n")
        i+=1
    embed = discord.Embed(title="Qui spam le plus le salon ?", description=sortie)
    await ctx.send(embed=embed)

#************ ON AFFICHE LES BOLCHEVIKS ET ON LOG LES MESSAGES SUPPRIMES *******

#en cas de suppression de message
@bot.event
async def on_message_delete(message):
    if len(message.content) > 2 and not message.author.bot :
        now=datetime.datetime.now()
        now=now - datetime.timedelta(hours=1, seconds=3)
        #On vérifie si le message a été supprimé par son auteur ou par un modérateur
        guild=message.guild
        #Pour cela, on va chercher le dernier log de suppression de message
        async for entry in guild.audit_logs(limit=1, after=now, action=discord.AuditLogAction.message_delete):
            censeur=entry.user        #on récupère le nom du modo
            date_supr=entry.created_at
        if now<date_supr :
            embed = discord.Embed(
                title="Alerte !",
                description=(f"{censeur} a supprimé un message de manière inopinée, \
                    c'est innacceptable ! \nT'es pire qu'un bolchevik {censeur}"))
            embed.add_field(
                name=("Voyons ce que contenait ce message victime de despotisme : "),
                value=(f"{message.content}\nPar : {message.author}"))
            await message.channel.send(embed=embed)
        else :
            await message.channel.send("🤫")

#********** COMMANDE D'AIDE ****************************************************

@bot.command()
async def aide(ctx):
    embed = discord.Embed(title="Aide",
    description="Comment utiliser les différentes commandes ? \
        \nLa commande $help joue un rôle similaire, en moins bien \
        \nUtiliser $help <commande> te permettra (ou pas) d'obtenir des informations plus détaillés sur la commande")
    embed.add_field(
        name="$score",
        value="Mini jeu : le but est de d'entrer un nombre entre 0 et 100 après la commande. \
        Le bot te dira quel nombre il avait tiré et la différence entre avec ton tirage")
    embed.add_field(
        name="$best",
        value="Renvoie le nom de celui ayant la plus petite différence. Je reset la commande quand quelqu'un a un 0")
    embed.add_field(
        name="$serrano, $teletchea, $mekaouche, $godart",
        value="Juste pour rire :)")
    embed.add_field(
        name="$salon",
        value="Crée un salon et un rôle dont le nom est donné en argument, réservé aux admins")
    embed.add_field(
        name="$dels",
        value="Efface un salon et un rôle. \
        Il faut mettre le nom du salon en premier argument et le nom du rôle en deuxième argument, réservé aux admins")
    embed.add_field(
        name="$mess",
        value="Te dit combien de messages tu as envoyé pendant que le bot est up")
    embed.add_field(
        name="$rank",
        value="Le classement des gens les plus bavards")
    embed.add_field(
        name="$jeux",
        value="Appelle le bot de jeux s'il n'est pas en ligne\n\
        Celui-ci permet de jouer à puissance 4 pour l'instant")
    embed.add_field(
        name="$silence, $retour",
        value="$silence permet de masquer la majorité des salons, $retour permet de revenir à la normale")
    await ctx.send(embed=embed)

#************** APPEL DU BOT DE TESTING ****************************************
# Ouvre un bot servant à tester du code sans avoir à mettre le bot principal offline
@bot.command(help="Apelle un bébé bot afin de réaliser des tests à l'éthique discutable")
async def BOT(ctx):
    await ctx.send("Je t'envoie mon fils, il est un peu bordélique mais parfois il est utile...")
    with open("summon.txt", "w+") as summon :
        summon.write(str(ctx.channel.id))
    subprocess.Popen("py -3 child.py")

#************** APPEL DU BOT DE JEUX *******************************************

@bot.command(help="Appelle le bot de jeux")
async def jeux(ctx):
    channel = bot.get_channel(667101857948237844)
    await ctx.send("Prend garde, le maître des jeux arrive !")
    if ctx.channel.id not in [667101857948237844, 640263768764317699] :
        await ctx.send(f"Pour la suite, ça se passe ici : {channel.mention}")
    with open("summon.txt", "w+") as summon :
        summon.write(str(ctx.channel.id))
    subprocess.Popen("py -3 p4.py")

#gestion des conflits avec un autre bot
@bot.command(hidden=True)
async def panic(ctx):
    await ctx.send("Utilises **panic* si tu souhaites connaitre ton niveau de panique")

#************* GESTION GLOBALE DES ERREURS *************************************
from discord.ext.commands import CommandNotFound
@bot.event
async def on_command_error(ctx, error):
    pass
    if isinstance(error, CommandNotFound):
        await ctx.send("Cette commande n'existe pas")
    else:
        #pass
        print(error)

#*************MESSAGE D'ACCUEIL ************************************************

@bot.event
async def on_ready():
    print('bonjour')
    global process
    process = subprocess.Popen("py -3 panic.py") #ouverture du PanicBot
    await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name="vos conneries"))

#************ FIN ***********************FIN ***********************************

with open('token.txt', 'r') as token :
    t=token.read()
    bot.run(t)


# course: Object-oriented programming, year 2, semester 1
# academic year: 201920
# author: B. Schoen-Phelan
# date: 08-10-2019
# purpose: Lab 3

import string

class WordScramble:
    def __init__(self):
        self.user_input = input("Please give me a sentence: ")

    def scramble(self):
        newWord=''
        # print what was input
        print("The user input was:         ", self.user_input)
        if len(self.user_input)>3:
            newWord = self.user_input[0]+self.user_input[-2]+self.user_input[1]+self.user_input[-1]
            print(newWord+' Line 19')
        elif len(self.user_input)<=3:
            print('This is a short word')
            newWord = self.user_input+'-'+self.user_input[1:]+self.user_input[0]
            print(newWord+' Line 23')
        else:
            print('try again')
            newWord=false

        Sentence=self.user_input.strip().split()
        for word in Sentence:
            Temp_word=list(word)
            if len(Sentence)>3:
                if(',' in Temp_word):
                    Tempo=Temp_word[1]
                    Temp_word[1]=Temp_word[3]
                    Temp_word[3]=Tempo
                    print(Temp_word+' Line 36')
            else:
                    Tempo=Temp_word[1]
                    Temp_word[1]=Temp_word[2]
                    Temp_word[2]=Tempo
                    Swapped=''.join(Temp_word)
                    print(Swapped+' line 41')
        #my_string = 'hello'
        #print(my_string[0])

        # Xstring = list(self.user_input)
        # Moon=Xstring[1]
        # Temp=Xstring[0]
        # Xstring[0] = Xstring[-1]
        # Xstring[1]=Xstring[-2]
        # Xstring[-1]=Temp
        # Xstring[-2]=Moon
        # print(Xstring)
        # print(''.join(Xstring))

        # first scramble is just one word
        # reverse two indices
        # particularly good to use is to switch the first two
        # and the last two
        # this only makes sense if you have a world that is longer than 3

        # now try to scramble one sentence
        # do just words first, then you can move on to work on
        # punctuation

word_scrambler = WordScramble()
word_scrambler.scramble()


import pandas as pd

df_old = pd.read_excel('공공KOLASIII0617.xlsx')
df_new = pd.read_excel('공공KOLASIII0622.xlsx')

df_old['ver'] = 'old'
df_new['ver'] = 'new'

id_dropped = set(df_old['LIB_CODE']) - set(df_new['LIB_CODE'])
id_added = set(df_new['LIB_CODE']) - set(df_old['LIB_CODE'])

df_dropped = df_old[df_old['LIB_CODE'].isin(id_dropped)].iloc[:,:-1]
df_added = df_new[df_new['LIB_CODE'].isin(id_added)].iloc[:,:-1]

# 두 데이터프레임을 하나로 합칩니다.
df_concatted = pd.concat([df_old, df_new], ignore_index=True)
# 모든 컬럼의 내용이 중복되는 데이터는 삭제합니다.
changes = df_concatted.drop_duplicates(df_concatted.columns[:-1], keep='last')

# 남은 데이터 중 동일한 아이디 값이 두개 이상 존재한다면
# 정보가 변경된 데이터입니다.
duplicated_list = changes[changes['LIB_CODE'].duplicated()]['LIB_CODE'].to_list()
df_changed = changes[changes['LIB_CODE'].isin(duplicated_list)]

df_changed_old = df_changed[df_changed['ver'] == 'old'].iloc[:,:-1]
df_changed_old.sort_values(by='LIB_CODE', inplace=True)

df_changed_new = df_changed[df_changed['ver'] == 'new'].iloc[:,:-1]
df_changed_new.sort_values(by='LIB_CODE', inplace=True)

df_info_changed = df_changed_old.copy()
for i in range(len(df_changed_new.index)):
    for j in range(len(df_changed_new.columns)):
        if(df_changed_new.iloc[i, j] != df_changed_old.iloc[i, j]):
            df_info_changed.iloc[i, j] = str(df_changed_old.iloc[i, j]) + " ==> " + str(df_changed_new.iloc[i,j])

with pd.ExcelWriter('compared_result.xlsx') as writer:
    df_info_changed.to_excel(writer, sheet_name='info chaged', index_label=False)
    df_added.to_excel(writer, sheet_name='added', index=False)
    df_dropped.to_excel(writer, sheet_name='dropped')


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

# задания:
# 3. за каждый год определить дату в которую была зафиксирована
#    наибольшая температура воздуха
#    примечание - даты в файле расположены произвольно
# 3. ответ:

import meteo

parsedMeteo = iter( meteo.parse('21432.dat') )
parsedMeteo = ( ( dt[4], dt[1] )
                    for dt in parsedMeteo
                    if dt[4] is not None )

year_temp = dict()
for data in parsedMeteo:
    year = data[1].year
    if year in year_temp:
        if year_temp[year] < data:
            year_temp[year] = data
    else:
        year_temp[year] = data

for key, value in year_temp.items():
    print( key, '=>', value )

# задание:
# 1. на основе имеющихся функций написать функцию (не генератор!) которая возвращает словарь состоящий из среднемесячных максимальных теператур за весь период наблюдения
# примечание - файл данных считивается один раз

'''
for data in parsedMeteo:
    year = data[1].year
    try:
        if year_temp[year] < data:
            year_temp[year] = data
    except KeyError:
        year_temp[year] = data

print( year_temp )
'''


import unittest
import random
from chained_hash import ChainedHash

class TestChainedHash(unittest.TestCase):
    def testInsertion(self):
        htable = ChainedHash()
        htable.insert(11)
        htable.insert(33)
        htable.insert(102)
        htable.insert(101)

        self.assertTrue(htable.search(11))
        self.assertTrue(htable.search(33))
        self.assertTrue(htable.search(102))
        self.assertFalse(htable.search(1012))

        self.assertTrue(htable.delete(11))
        self.assertFalse(htable.search(11))

    def testCollision(self):
        htable = ChainedHash(True, 10)
        trial = 1
        while not htable.has_collision:
            htable.insert(random.randint(0, 10000))
            trial += 1

        self.assertLess(trial, 80)

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


# Import CherryPy global namespace
import cherrypy
import copy
import urllib
import urllib2
import urlparse
import os.path
import json

import conf.data
import httpls_client
import shaper

import conf

class DriplsController(object):
    '''DripLS Controller'''

    def on_start(self):
        pass

    def on_stop(self):
        pass

    def on_server_start(self):
        pass

    @cherrypy.expose
    def ostatus(self, s=None):
        """ Throw with a specified status """

        raise cherrypy.HTTPError(int(s), message="Custom error raised : {0}".format(s))

    @cherrypy.expose
    def cache_info(self, cid=None, r=None, tag=None, **kwargs):
        """ Cache and rewrite a m3u8 """

        info = self.cache_stream(cid, r, tag, kwargs)

        return json.dumps(info, sort_keys=True, indent=4)

    @cherrypy.expose
    def updatesegment(self, url, new_action):
        """ Update a previously shaped segment on the fly """

        shaper.update_shaped_segment(url, new_action)

        return "OK"

    @cherrypy.expose
    def master_m3u8(self, cid=None, r=None, tag=None, **kwargs):
        """ Cache and stream back a shaped playlist """

        cached_cid = self.cache_stream(cid, r, tag, kwargs)["id"]

        with open("{0}/playlists/m_{1}.m3u8".format(shaper.shaper_store_path, cached_cid), "r") as pf:
            master_content = pf.read()

        # return the rewritten master
        cherrypy.response.headers['Content-Type'] = "application/vnd.apple.mpegurl"
        cherrypy.response.headers['Content-Disposition'] = "inline; filename={0}.m3u8".format(cid)

        return master_content

    @cherrypy.expose
    def playlist_m3u8(self, p=None, **kwargs):
        """ Stream back a cached playlist """

        with open("{0}/playlists/{1}.m3u8".format(shaper.shaper_store_path,p), "r") as pf:
            playlist_content = pf.read()

        cherrypy.response.headers['Content-Type'] = "application/vnd.apple.mpegurl"
        cherrypy.response.headers['Content-Disposition'] = "inline; filename={0}.m3u8".format(p)

        return playlist_content

    @cherrypy.expose
    def tag_m3u8(self, tag=None, **kwargs):
        """ Do the shaping off of a pre-made tag """

        with open("{0}/playlists/tag_{1}".format(shaper.shaper_store_path, tag) , "r") as pf:
            tag_qs = pf.read()

        #add old keys
        tag_args = urlparse.parse_qs(tag_qs)
        for key in tag_args:
            tag_args[key] = tag_args[key][0]

        #add any new kes that we might have gotten(some might override old keys)
        for key in kwargs:
            tag_args[key] = kwargs[key]

        #run master with the tag args
        return self.master_m3u8(**tag_args);

    def cache_stream(self, cid=None, r=None, tag=None, kwargs=None):
        """ Perform the actual caching and shaping  of the stream """

        rules = shaper.parse_rules(r)

        seeded_content_id = conf.common.get_seeded_cid(cid)
        master_playlist = conf.data.provider.pull_master_m3u8(cid, kwargs)

        info = shaper.cache_and_shape(master_playlist, seeded_content_id, rules)
        info["url"] = conf.common.get_final_url("playlist.m3u8","p=m_{0}".format(seeded_content_id))

        # if we have a tag, store
        if tag:
            self.store_tag(cid, r, tag, kwargs)

        return info

    def store_tag(self, cid, r, tag, kwargs):
        """ Store all arguments recieved on the url as the associated tag """
        tag_args = conf.data.provider.get_tag_kwargs(kwargs)
        tag_args["cid"] = cid

        if r:
            tag_args["r"] = r

        with open("{0}/playlists/tag_{1}".format(shaper.shaper_store_path, tag), "w") as pf:
            pf.write("{0}".format(urllib.urlencode(tag_args)))

conf.dripls_main_site_url = conf.app['root_url']
root = DriplsController()

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

app_config = {
    '/playlists': {
         'tools.staticdir.on': True,
         'tools.staticdir.dir': os.path.join(shaper.shaper_store_path, 'playlists'),
         'tools.staticdir.content_types': {
             'ts': 'video/mp2t',
             'm3u8': 'application/vnd.apple.mpegurl'
         }
    }
}

cherrypy.config.update({
    'log.error_file': conf.error_log,
    'log.screen': True
})

app = cherrypy.tree.mount(root, '/', app_config)


import numpy as np
import skimage.color as color
import skimage.transform as transform
import skimage.io as iio
import tensorflow as tf
import tensorflow.keras as keras

class ItemPool:
    """
    This function stores the tensors of fake images into one tensor.

    """
    def __init__(self, pool_size=50):
        self.pool_size = pool_size
        self.items = []

    def __call__(self, in_items):

        if self.pool_size == 0:
            return in_items

        out_items = []
        for in_item in in_items:
            if len(self.items) < self.pool_size:
                self.items.append(in_item)
                out_items.append(in_item)
            else:
                if np.random.rand() > 0.5:
                    idx = np.random.randint(0, len(self.items))
                    out_item, self.items[idx] = self.items[idx], in_item
                    out_items.append(out_item)
                else:
                    out_items.append(in_item)
        return tf.stack(out_items, axis=0)

class LinearDecay(keras.optimizers.schedules.LearningRateSchedule):
    # if `step` < `step_decay`: use fixed learning rate
    # else: linearly decay the learning rate to zero

    def __init__(self, initial_learning_rate, total_steps, step_decay):
        super(LinearDecay, self).__init__()
        self._initial_learning_rate = initial_learning_rate
        self._steps = total_steps
        self._step_decay = step_decay
        self.current_learning_rate = tf.Variable(initial_value=initial_learning_rate, trainable=False, dtype=tf.float32)

    def __call__(self, step):
        self.current_learning_rate.assign(tf.cond(
            step >= self._step_decay,
            true_fn=lambda: self._initial_learning_rate * (1 - 1 / (self._steps - self._step_decay) * (step - self._step_decay)),
            false_fn=lambda: self._initial_learning_rate
        ))
        return self.current_learning_rate

class Checkpoint:
    """Enhanced "tf.train.Checkpoint"."""

    def __init__(self,
                 checkpoint_kwargs,  # for "tf.train.Checkpoint"
                 directory,  # for "tf.train.CheckpointManager"
                 max_to_keep=5,
                 keep_checkpoint_every_n_hours=None):
        self.checkpoint = tf.train.Checkpoint(**checkpoint_kwargs)
        self.manager = tf.train.CheckpointManager(self.checkpoint, directory, max_to_keep, keep_checkpoint_every_n_hours)

    def restore(self, save_path=None):
        save_path = self.manager.latest_checkpoint if save_path is None else save_path
        return self.checkpoint.restore(save_path)

    def save(self, file_prefix_or_checkpoint_number=None, session=None):
        if isinstance(file_prefix_or_checkpoint_number, str):
            return self.checkpoint.save(file_prefix_or_checkpoint_number, session=session)
        else:
            return self.manager.save(checkpoint_number=file_prefix_or_checkpoint_number)

    def __getattr__(self, attr):
        if hasattr(self.checkpoint, attr):
            return getattr(self.checkpoint, attr)
        elif hasattr(self.manager, attr):
            return getattr(self.manager, attr)
        else:
            self.__getattribute__(attr)  # this will raise an exception

def summary(name_data_dict,
            step=None,
            types=['mean', 'std', 'max', 'min', 'sparsity', 'histogram'],
            historgram_buckets=None,
            name='summary'):
    """Summary.
    Examples
    --------
    >>> summary({'a': data_a, 'b': data_b})
    """
    def _summary(name, data):
        if data.shape == ():
            tf.summary.scalar(name, data, step=step)
        else:
            if 'mean' in types:
                tf.summary.scalar(name + '-mean', tf.math.reduce_mean(data), step=step)
            if 'std' in types:
                tf.summary.scalar(name + '-std', tf.math.reduce_std(data), step=step)
            if 'max' in types:
                tf.summary.scalar(name + '-max', tf.math.reduce_max(data), step=step)
            if 'min' in types:
                tf.summary.scalar(name + '-min', tf.math.reduce_min(data), step=step)
            if 'sparsity' in types:
                tf.summary.scalar(name + '-sparsity', tf.math.zero_fraction(data), step=step)
            if 'histogram' in types:
                tf.summary.histogram(name, data, step=step, buckets=historgram_buckets)

    with tf.name_scope(name):
        for name, data in name_data_dict.items():
            _summary(name, data)

def immerge(images, n_rows=None, n_cols=None, padding=0, pad_value=0):
    """Merge images to an image with (n_rows * h) * (n_cols * w).
    Parameters
    ----------
    images : numpy.array or object which can be converted to numpy.array
        Images in shape of N * H * W(* C=1 or 3).
    """
    images = np.array(images)
    n = images.shape[0]
    if n_rows:
        n_rows = max(min(n_rows, n), 1)
        n_cols = int(n - 0.5) // n_rows + 1
    elif n_cols:
        n_cols = max(min(n_cols, n), 1)
        n_rows = int(n - 0.5) // n_cols + 1
    else:
        n_rows = int(n ** 0.5)
        n_cols = int(n - 0.5) // n_rows + 1

    h, w = images.shape[1], images.shape[2]
    shape = (h * n_rows + padding * (n_rows - 1),
             w * n_cols + padding * (n_cols - 1))
    if images.ndim == 4:
        shape += (images.shape[3],)
    img = np.full(shape, pad_value, dtype=images.dtype)

    for idx, image in enumerate(images):
        i = idx % n_cols
        j = idx // n_cols
        img[j * (h + padding):j * (h + padding) + h,
            i * (w + padding):i * (w + padding) + w, ...] = image

    return img

def to_range(images, min_value=0.0, max_value=1.0, dtype=None):
    """Transform images from [-1.0, 1.0] to [min_value, max_value] of dtype."""
    dtype = dtype if dtype else images.dtype
    return ((images + 1.) / 2. * (max_value - min_value) + min_value).astype(dtype)

def im2uint(images):
    """Transform images from [-1.0, 1.0] to uint8."""
    return to_range(images, 0, 255, np.uint8)

def imwrite(image, path, quality=95, **plugin_args):
    """Save a [-1.0, 1.0] image."""
    iio.imsave(path, im2uint(image), quality=quality, **plugin_args)


"""Game sample application"""

import time
import random
import math
import pygame

from scene import Scene
from object3d import Object3d
from camera import Camera
from mesh import Mesh
from material import Material
from color import Color
from vector3 import Vector3, dot_product, cross_product
from quaternion import Quaternion
from perlin import noise2d

# Computes the height of the terrain at the given x,y point
def sample_height(x, y):
    """Samples a pseudo heighmap, built with 2-octaves of 2d perlin noise. This is
    clamped near the player, so we have a nice flat area near him. We also clamp it to
    values above 0, so it looks more natural"""
    # 2 octave noise, with a given scale
    scale_noise = 0.4
    noise_height = 5
    n = 0.5 * noise2d(x * scale_noise, y * scale_noise)
    n += 0.25 * noise2d(x * scale_noise * 2, y * scale_noise * 2)
    n *= noise_height
    if ((n < 0) or (y < 8)):
        n = 0

    return n

def create_terrain():
    """Creates a terrain to use as a background in the game"""
    # Size of the terrain
    size_x = 16
    size_z = 16
    # Number of divisions of the terrain. Vertex count scales with the square of this
    div = 20

    px = size_x / div
    pz = size_z / div

    # For centering the terrain on the object center
    origin = Vector3(-size_x * 0.5, 0, 0)

    terrain_mesh = Mesh("Terrain")

    # Create the geometry of the terrain and add it to the mesh
    for dz in range(0, div):
        for dx in range(0, div):
            p1 = Vector3(dx * px, 0, dz * pz) + origin
            p2 = Vector3((dx + 1) * px, 0, dz * pz) + origin
            p3 = Vector3((dx + 1) * px, 0, (dz + 1) * pz) + origin
            p4 = Vector3(dx * px, 0, (dz + 1) * pz) + origin

            p1.y = sample_height(p1.x, p1.z)
            p2.y = sample_height(p2.x, p2.z)
            p3.y = sample_height(p3.x, p3.z)
            p4.y = sample_height(p4.x, p4.z)

            poly = []
            poly.append(p1)
            poly.append(p2)
            poly.append(p3)
            poly.append(p4)

            terrain_mesh.polygons.append(poly)

    # Create materials for the terrain
    terrain_material = Material(Color(0.1, 0.6, 0.1, 1), "TerrainMaterial")

    # Create object to display the terrain
    obj = Object3d("TerrainObject")
    obj.scale = Vector3(1, 1, 1)
    obj.position = Vector3(0, -1, 1)
    obj.mesh = terrain_mesh
    obj.material = terrain_material

    return obj

def main():
    """Main function, it implements the application loop"""

    # Initialize pygame, with the default parameters
    pygame.init()

    # Define the size/resolution of our window
    res_x = 1280
    res_y = 720

    # Create a window and a display surface
    screen = pygame.display.set_mode((res_x, res_y))

    # Create a scene
    scene = Scene("TestScene")
    scene.camera = Camera(False, res_x, res_y)

    # Moves the camera back 2 units
    scene.camera.position -= Vector3(0, 0, 0)

    # Creates the terrain meshes and materials
    terrain_object = create_terrain()
    scene.add_object(terrain_object)

    # Timer
    delta_time = 0
    prev_time = time.time()

    # Game loop, runs forever
    while True:
        # Process OS events
        for event in pygame.event.get():
            # Checks if the user closed the window
            if event.type == pygame.QUIT:
                # Exits the application immediately
                return
            key_state = pygame.key.get_pressed()
            if key_state[pygame.K_ESCAPE]:
                return
            if key_state[pygame.K_d]:
                scene.camera.position = Vector3(scene.camera.position.x+0.1,scene.camera.position.y,scene.camera.position.z)
            if key_state[pygame.K_a]:
                scene.camera.position = Vector3(scene.camera.position.x-0.1,scene.camera.position.y,scene.camera.position.z)
            if key_state[pygame.K_w]:
                scene.camera.position = Vector3(scene.camera.position.x,scene.camera.position.y,scene.camera.position.z+0.1)
            if key_state[pygame.K_s]:
                scene.camera.position = Vector3(scene.camera.position.x,scene.camera.position.y,scene.camera.position.z-0.1)

        # Clears the screen with a very dark blue (0, 0, 20)
        screen.fill((0, 0, 20))

        # Render scene
        scene.render(screen)

        # Swaps the back and front buffer, effectively displaying what we rendered
        pygame.display.flip()

        # Updates the timer, so we we know how long has it been since the last frame
        delta_time = time.time() - prev_time
        prev_time = time.time()

# Run the main function
main()


##This script prepares covariate file containing covariates and target phenotype for the
## given Case Control group in the merged GWAS data from ADNI1/2/3. Also extracts the GWAS data for the analysis

#Author: Subash Khanal
import shlex
import os
import subprocess
import pandas as pd
from collections import Counter

diagnosis = 'DX_bl' # DX or DX_bl from ADNIMERGE.csv column
control='CN'
case='AD'
analysis = control+'_'+case

root_path = '/mnt/gpfs2_16m/pscratch/nja224_uksr/SKH259/LinLab/ADNI_Genetics/Genomics/data/GWAS/'

diag_path = os.path.join(root_path,'ADNIMERGE.csv')
analysis_path=os.path.join(root_path,analysis)
data_path = os.path.join(analysis_path)
orig_data_path=root_path+'GWAS_1_2_3_clean'

with open(orig_data_path+'.fam', 'r') as famf:
    t = famf.read().split('\n')[:-1]
fid_iid = [l.split(' ')[0]+' '+ l.split(' ')[1] for l in t]
sub = [l.split(' ')[1] for l in t]

adni_merge = pd.read_csv(diag_path)
my_merge = adni_merge[pd.DataFrame(adni_merge.PTID.tolist()).isin(sub).any(1).values]
my_merge = my_merge[my_merge['VISCODE']=='bl']
my_merge = my_merge[(my_merge[diagnosis]==control) | (my_merge[diagnosis]==case)]
my_merge.to_csv(analysis_path+'/my_MERGE.csv')

fid_iid = [s for s in fid_iid if s.split(' ')[1] in list(my_merge.PTID)]
sub = [l.split(' ')[1] for l in fid_iid]

print('----------------------------------------------------')
print("ANALYSIS FOR THE CASE CONTROL DISTRIBUTION")
print(Counter(my_merge[diagnosis]))
print('----------------------------------------------------')

header = 'FID IID AGE PTGENDER PTEDUCAT MMSE DIAG'

with open(analysis_path+'/cov_pheno.txt','w') as outfile:
    myfid_iid = ''
    text = header + '\n'
    for s in fid_iid:
        AGE = my_merge[my_merge['PTID']==s.split(' ')[1]]['AGE'].item()
        PTGENDER = my_merge[my_merge['PTID']==s.split(' ')[1]]['PTGENDER'].item()
        if PTGENDER == 'Male':
            PTGENDER = 1
        elif PTGENDER == 'Female':
            PTGENDER = 2
        else:
            PTGENDER = 0
        PTEDUCAT = my_merge[my_merge['PTID']==s.split(' ')[1]]['PTEDUCAT'].item()
        MMSE = my_merge[my_merge['PTID']==s.split(' ')[1]]['MMSE'].item()
        DIAG = my_merge[my_merge['PTID']==s.split(' ')[1]][diagnosis].item()
        if DIAG == control:
            DIAG = 1
        elif DIAG == case:
            DIAG = 2
        else:
            DIAG = -9

        text = text+ ' '.join([s,str(AGE),str(PTGENDER),str(PTEDUCAT),str(MMSE),str(DIAG)])+'\n'
        myfid_iid = myfid_iid +s+'\n'
    outfile.write(text.strip())

with open(analysis_path+'/myFID_IIDs.txt','w') as outfile:
    outfile.write(myfid_iid.strip())

print('----------------------------------------------------')
print("PREPARATION OF PHENOTYPE AND COVARIATE FILE COMPLETE")
print('----------------------------------------------------')

os.chdir(analysis_path)

plink_command = "plink --bfile "+orig_data_path+" --keep myFID_IIDs.txt --make-bed --out GWAS_1_2_3_clean_"+analysis+" --noweb"
process = subprocess.Popen(shlex.split(plink_command))

print('----------------------------------------------------')
print("PREPARATION OF DATA FOR CASE CONTROL ANALYSIS STARTED")
print('----------------------------------------------------')


from pathlib import Path
from config import RAPIDAPI_KEY
from aggregator import Aggregator

async def update_mocks():
    directory = Path(__file__).parent
    aggr = Aggregator(rapidapi_key=RAPIDAPI_KEY)

    for source in aggr._sources:
        source_name = type(source).__name__
        file_path = directory / f'mock_response_{source_name}.txt'
        response = await source.load_data()
        with file_path.open('w') as file:
            file.write(response)


import requests
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(ChromeDriverManager().install())
import time

url = 'https://vnexpress.net/bong-da'
def cr(url,filename):
    driver.get(url)
    total_height = int(driver.execute_script("return document.body.scrollHeight"))

    for k in range(1, total_height, 5):
        driver.execute_script("window.scrollTo(0, {});".format(k))
    listOfImage = []
    i = 1

    # eleList = driver.find_element_by_tag_name("article")
    # print(eleList)
    # ele = eleList
    try:
        while(i<34):
            if i==6 or i==13 or i ==20 or i==27:
                i+=1
            urlI = "/html/body/section[5]/div/div[1]/div[2]/article["+str(i)+"]/div/a/picture/img"

            urlAbstract = driver.find_element(By.XPATH,urlI).get_attribute('src')
            if(urlAbstract):
                print(i,'.',urlAbstract)
                listOfImage.append(urlAbstract)

                print(urlAbstract)
                i+=1
            else:
                i+=1

    except:
        pass
    j = 1
    while listOfImage:
        link = listOfImage.pop()
        print(link)
        img = Image.open(requests.get(link, stream=True).raw)
        filename1 = filename+"hinh"+str(j)+".png"
        img.save('./xe_train/'+filename1 ,'')
        j+=1
p = 1
url = 'https://vnexpress.net/bong-da'
filename = "page"+str(p)
cr(url,filename)
while(p<20):
    p+=1
    url = 'https://vnexpress.net/bong-da-p'
    url+=str(p)
    filename = "page"+str(p)
    cr(url,filename)

driver.close()
driver.quit


import os
import pypandoc

md_files = []
formats = {
    # File format, Pandoc format
    "from": ("docx", "docx"),
    "to": ("md", "gfm")
}
doc = "UpdatedCases"

for root, dirs, files in os.walk("./"):
    for file in files:
        if file == f"{doc}.{formats['from'][0]}":
            print(f"Converting {doc}.{formats['from'][0]} to {doc}.{formats['to'][0]} in {root}")
            pypandoc.convert_file(
                source_file=os.path.join(root, f"{doc}.{formats['from'][0]}"),
                format=formats['from'][1],
                to=formats['to'][1],
                outputfile=os.path.join(root, f"{doc}.{formats['to'][0]}"),
            )


#! /usr/bin/env python3
import sys
import socket
import json
import struct

host = 'localhost'
port = 9998

def send_message(sock, command, data=''):
        data_to_encode = (command, data)
        data_to_send = json.dumps(data_to_encode)
        sock.send(data_to_send.encode())

def recv_message(sock):
    data_to_decode = sock.recv(1024).decode()
    command, data = json.loads(data_to_decode)
    return command, data

s = socket.socket()
s.connect((host, port))

cmd = sys.argv[1]

if cmd == 'a':
    send_message(s, 'addJob', ["HPtest", "bash", 1])
    command, result = recv_message(s)
    print('result', result)
    s.close()

elif cmd == 'j':
    send_message(s, 'getAllJobs')
    command, jobs = recv_message(s)
    print(jobs)
    s.close()

elif cmd == 'i':
    send_message(s, 'getJobInfo', str(sys.argv[2]))
    command, job_Info = recv_message(s)
    if job_Info != -1:
        print(job_Info)
    else:
        print('bad ID')
    s.close()

elif cmd == 'r':
    send_message(s, 'removeJob', str(sys.argv[2]))
    command, result = recv_message(s)
    if result != 0:
        print('bad ID')
    s.close()

elif cmd == 'q':
    send_message(s, 'shutdown')

else:
    print('invalid command')
    sys.exit(-1)


#calss header
class _NIACIN():
	def __init__(self,):
		self.name = "NIACIN"
		self.definitions = [u'one of the vitamin B complex found in foods such as wheat, beef, chicken, and milk, important for producing energy from food and for keeping the digestion and nervous system healthy']

		self.parents = []
		self.childen = []
		self.properties = []
		self.jsondata = {}

		self.specie = 'nouns'

	def run(self, obj1 = [], obj2 = []):
		return self.jsondata


r"""
Given an n-ary tree, return its level order traversal.

Note: an n-ary tree is a tree in which each node has no more than N
children.

Ex: Give the following n-ary tree...

       8
     / | \
    2  3  29

return [[8], [2, 3, 29]]

Ex: Given the following n-ary tree...

         2
       / | \
      1  6  9
     /   |   \
    8    2    2
       / | \
     19 12 90

return [[2], [1, 6, 9], [8, 2, 2], [19, 12, 90]]
"""
from data_types.node_nary_tree import build_nary_tree, level_order_traversal

def main() -> None:
    """Main function"""
    tree = build_nary_tree([8, [2, 3, 29]])
    # tree = build_nary_tree([2, [[1, [8]], [6, [[2, [19, 12, 90]]]], [9, [2]]]])

    print(level_order_traversal(tree))

if __name__ == "__main__":
    main()


# 2953: 나는 요리사다

import sys

scores = []
for _ in range(5):
    score = list(map(int, sys.stdin.readline().split()))
    scores.append(sum(score))

mx = max(scores)
idx = scores.index(mx) + 1

print(idx, mx)

"""
"나는 요리사다"는 다섯 참가자들이 서로의 요리 실력을 뽐내는 티비 프로이다.
 각 참가자는 자신있는 음식을 하나씩 만들어오고, 서로 다른 사람의 음식을 점수로 평가해준다. 점수는 1점부터 5점까지 있다.

각 참가자가 얻은 점수는 다른 사람이 평가해 준 점수의 합이다. 이 쇼의 우승자는 가장 많은 점수를 얻은 사람이 된다.

각 참가자가 얻은 평가 점수가 주어졌을 때, 우승자와 그의 점수를 구하는 프로그램을 작성하시오.
"""


"""
	Show how to use a sprite backed by a graphic.

"""

import pygame

# use of the main function in Ch. 9

# defining colors as global constants
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# draw a snowman
def draw_snowman(screen, x, y):
	# draw a circle for head
	pygame.draw.ellipse(screen, WHITE,[35+x, 0+y, 25, 25])
	# draw middle
	pygame.draw.ellipse(screen, WHITE,[23+x, 20+y, 50, 50])
	# draw bottom circle
	pygame.draw.ellipse(screen, WHITE,[0+x, 65+y, 100, 100])

# draw a stick figure
def draw_stickfigure(screen, x, y):
	# head
	pygame.draw.ellipse(screen, BLACK, [1+x,y,10,10], 0)

	# legs
	pygame.draw.line(screen, BLACK, [5+x,17+y], [10+x,27+y], 2)
	pygame.draw.line(screen, BLACK, [5+x,17+y], [x,27+y], 2)

	# body
	pygame.draw.line(screen, RED, [5+x,17+y], [5+x,7+y], 2)

	# arms
	pygame.draw.line(screen, RED, [5+x,7+y], [9+x,17+y], 2)
	pygame.draw.line(screen, RED, [5+x,7+y], [1+x,17+y], 2)

def main():
	""" Main function for the game. """
	pygame.init()

	# set width, height of screen
	size = [700, 500]
	screen = pygame.display.set_mode(size)

	pygame.display.set_caption("Game of Badassdom")

	# loop until user clicks close button
	done = False

	clock = pygame.time.Clock()

	# Hide the mouse cursor
	pygame.mouse.set_visible(False)

	# speed in pixels per frame
	x_speed = 0
	y_speed = 0

	# current position
	x_coord = 10
	y_coord = 10

	# count joysticks
	joystick_count = pygame.joystick.get_count()
	if joystick_count == 0:
		# no joysticks!
		print("Error, I didn't find any joysticks.")
	else:
		# use joystick #0 and initialize it
		my_joystick = pygame.joystick.Joystick(0)
		my_joystick.init()

	# --- Main Program Loop ---
	while not done:
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				done = True
			# user pressed a key down
			if event.type == pygame.KEYDOWN:
				# is it an arrow key? if yes, adjust speed
				if event.key == pygame.K_LEFT:
					x_speed = -3
				if event.key == pygame.K_RIGHT:
					x_speed = 3
				if event.key == pygame.K_UP:
					y_speed = -3
				if event.key == pygame.K_DOWN:
					y_speed = 3

			# user let up on a key
			if event.type == pygame.KEYUP:
				# if it's an arrow key, reset vector to zero
				if event.key == pygame.K_LEFT:
					x_speed = 0
				if event.key == pygame.K_RIGHT:
					x_speed = 0
				if event.key == pygame.K_UP:
					y_speed = 0
				if event.key == pygame.K_DOWN:
					y_speed = 0

		# move object according to speed vector
		x_coord += x_speed
		y_coord += y_speed

		# prevent stickman from leaving screen - mostly
		if x_coord < 0:
			x_coord = 0
		if x_coord > 690:
			x_coord = 690
		if y_coord < 0:
			y_coord = 0
		if y_coord > 490:
			y_coord = 490

		pos = pygame.mouse.get_pos()
		x = pos[0]
		y = pos[1]

		# joystick stuff
		if joystick_count != 0:
			# gets position of axis on controller
			# returns a number between -1.0 and 1.0
			horiz_axis_pos = my_joystick.get_axis(0)
			vert_axis_pos = my_joystick.get_axis(1)

			# move according to the axis. multiply to speed up movement
			# convert to an int because pixels can only be drawn at whole numbers
			x_coord = x_coord + int(horiz_axis_pos * 10)
			y_coord = y_coord + int(vert_axis_pos * 10)

		screen.fill(WHITE)

		draw_stickfigure(screen, x_coord, y_coord)

		pygame.display.flip()

		clock.tick(60)

	pygame.quit()

if __name__ == "__main__":
	main()


class Codon:

    codon_dict={'TTT':'F','TTC':'F','TTA':'L','TTG':'L',
                'TCT':'S','TCC':'S','TCA':'S','TCG':'S',
                'TAT':'Y','TAC':'Y','TAA':'*','TAG':'*',
                'TGT':'C','TGC':'C','TGA':'*','TGG':'W',
                'CTT':'L','CTC':'L','CTA':'L','CTG':'L',
                'CCT':'P','CCC':'P','CCA':'P','CCG':'P',
                'CAT':'H','CAC':'H','CAA':'Q','CAG':'Q',
                'CGT':'R','CGC':'R','CGA':'R','CGG':'R',
                'ATT':'I','ATC':'I','ATA':'I','ATG':'M',
                'ACT':'T','ACC':'T','ACA':'T','ACG':'T',
                'AAT':'N','AAC':'N','AAA':'K','AAG':'K',
                'AGT':'S','AGC':'S','AGA':'R','AGG':'R',
                'GTT':'V','GTC':'V','GTA':'V','GTG':'V',
                'GCT':'A','GCC':'A','GCA':'A','GCG':'A',
                'GAT':'D','GAC':'D','GAA':'E','GAG':'E',
                'GGT':'G','GGC':'G','GGA':'G','GGG':'G',
                '---':'-','XXX':'-','???':'?'}

    mixture_dict={'W':'AT','R':'AG','K':'GT','Y':'CT',
                  'S':'CG','M':'AC','V':'AGC','H':'ATC',
                  'D':'ATG','B':'TGC','N':'ATGC','-':'-'}

    def __init__(self, codon_string):
        self.codon = codon_string

    @classmethod
    def resolveCodon(cls, codon):
        nonmix = []
        if (codon in cls.codon_dict):
            return[codon]
        elif ((codon.count('-') + codon.count('X')) == 3):
            return ['---']
        elif (1 <= codon.count('-') <= 2) or (1 <= codon.count('X') <= 2):
            return['???']
        for base in codon:
            #Check for mixtures
            if (base in cls.mixture_dict):
                if (not nonmix):
                    nonmix = [x for x in cls.mixture_dict[base]]
                else:
                    nonmix=[x +y for x in nonmix for y in cls.mixture_dict[base]]
            else:
                if (not nonmix):
                    nonmix.append(base)
                else:
                    nonmix = [x + base for x in nonmix]
        return nonmix


from ursina import *

class FirstPersonController(Entity):

    def __init__(self, **kwargs):
        super().__init__()
        self.speed = 5

        self.i = 0
        self.update_interval = 30

        self.cursor = Entity(
            parent = camera.ui,
            model = 'quad',
            color = color.pink,
            scale = .008,
            rotation_z = 45
            )

        self.position = (0, 1, 1)
        camera.position = self.position
        camera.rotation = (0,0,0)
        camera.fov = 90
        mouse.locked = True
        self.target_smoothing = 100
        self.smoothing = self.target_smoothing

        for key, value in kwargs.items():
            setattr(self, key ,value)

    def update(self):
        self.rotation_y += mouse.velocity[0] * 40
        camera.rotation_x -= mouse.velocity[1] * 40
        camera.rotation_x = clamp(camera.rotation_x, -90, 90)

        self.y += held_keys['e']
        self.y -= held_keys['q']

        self.direction = Vec3(
            self.forward * (held_keys['w'] - held_keys['s'])
            + self.right * (held_keys['d'] - held_keys['a'])
            ).normalized()

        self.smoothing = lerp(self.smoothing, self.target_smoothing, 4*time.dt)
        camera.position = lerp(
            camera.position,
            self.position + (self.up*1.5),
            time.dt * self.smoothing)

        camera.rotation_y = self.rotation_y

        origin = self.world_position + self.up + (self.direction/2)
        middle_ray = raycast(origin , self.direction, ignore=[self,], distance=1.3, debug=False)
        left_ray =   raycast(origin, lerp(self.left, self.forward, .5), ignore=[self,], distance=1.4, debug=False)
        right_ray =   raycast(origin, lerp(self.right, self.forward, .5), ignore=[self,], distance=1.4, debug=False)

        # push away from the wall
        if left_ray.hit:
            self.smoothing = 2
            self.position -= lerp(self.left, self.forward, .5) * (1.399-left_ray.distance)

        elif right_ray.hit:
            self.smoothing = 2
            self.position -= lerp(self.right, self.forward, .5) * (1.399-right_ray.distance)

        if not middle_ray.hit:
            self.position += self.direction * self.speed * time.dt

if __name__ == '__main__':
    app = Ursina()
    Sky(color=color.gray)
    Entity(model='plane', scale=100, color=color.yellow.tint(-.2), texture='white_cube', texture_scale=(100,100))
    e = Entity(
        model='cube',
        scale=(1, 5, 10),
        x=2,
        y=.01,
        rotation_y = 45,
        collider='box',
        texture='white_cube',
    )
    e.texture_scale = (e.scale_z, e.scale_y)
    e = Entity(
        model='cube',
        scale=(1, 5, 10),
        x=-2,
        y=.01,
        collider='box',
        texture='white_cube',
    )
    e.texture_scale = (e.scale_z, e.scale_y)
    FirstPersonController()

    app.run()


#Copyright 2012 Google Inc. All Rights Reserved.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0

#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.

"""An App Engine site for making calls from a list of phone numbers.

This module handles the data scheme, authentication details, and RPC methods
that control interaction with the frontend.
It was originally built to manage a public opinion poll in Somalia.

    Main(): Renders the home page.
    Admin(): Renders the admin page.
    RPCHandler(): Unpacks incoming requests and throws to RPCMethods.
    RPCMethods(): Processes most incoming requests to the datastore.
"""

import csv
import datetime
import os
from django.utils import simplejson as json
from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app

class UserModel(db.Model):
  """Model for users whitelisted to use the site.

  Note: this is not the same as the list of admins on the site,
  which is set in the App Engine instance's control panel.

  Attributes:
    user: user property, storing name and email of whitelisted user.
  """

  user = db.UserProperty()

class CallRecipient(db.Model):
  """Model for the recipients of the poll.

  Attributes:
    caller: user who made the call.
    phone_number: int of number to call.
    contacted: boolean, defaults to false.
    last_contact: if contacted, the date and time.
    contact_response: string of contact response (e.g. no answer).
  """

  caller = db.UserProperty()
  contact_response = db.StringProperty()
  contacted = db.BooleanProperty(default=False)
  last_contact = db.DateTimeProperty()
  phone_number = db.IntegerProperty()

class Form(db.Model):
  """Model containing single key for the survey form.

  This application uses a form to collect responses.
  This model stores the URI key for that form.
  There should be only one key stored at a time for this app.

  Attributes:
    form_key: string of key.
  """

  form_key = db.StringProperty()

def GetForm():
  """Method for getting current survey form's key.

  Args:
    (none).

  Returns:
    A string of the form's unique key.
  """

  form = db.GqlQuery("SELECT * FROM Form").get()
  if form:
    return form.form_key
  return None

class Admin(webapp.RequestHandler):
  """Renders /admin, where survey key and users are added.

  No log-in logic is necessary: only admins are authorized,
  which is managed through app.yaml.

    Get: Retrieves all current users, and current form.
  """

  def get(self):
    """Renders whitelisted users and survey key on /admin.

    Args:
      (none).

    Returns:
      (none, renders admin page template).
    """

    if users.is_current_user_admin():
      current_users = UserModel.all()
      users_email = [user_model.user.email() for user_model in current_users]

      form_key = GetForm()

      template_values = {"current_users_email": users_email,
                         "form_key": form_key,
                         "logout_url": users.create_logout_url("/")}
      template_page = "admin.html"

    else:
      self.error(403)
      template_values = {"message": "Sorry! The user isn't authorized."}
      template_page = "error.html"

    path = os.path.join(os.path.dirname(__file__), template_page)
    self.response.out.write(template.render(path, template_values))

  def post(self):
    """Receives .csv of phone numbers, stores in CallRecipients.

    Will ignore any numbers already in database.

    Args:
      csv: a csv file with 1 column, and n rows of phone numbers.

    Returns:
      Redirect to admin page.
    """
    if users.is_current_user_admin():
      csv_object = csv.reader(self.request.get("phone-number-csv").split())

      for row in csv_object:
        q = "SELECT * FROM CallRecipient WHERE phone_number = %d" % int(row[0])
        if db.GqlQuery(q).get() is None:
          call_recipient = CallRecipient(phone_number=int(row[0]))
          call_recipient.put()

      self.redirect("/admin")

    else:
      self.error(403)
      template_values = {"message": "Sorry! The user isn't authorized."}
      template_page = "error.html"

      path = os.path.join(os.path.dirname(__file__), template_page)
      self.response.out.write(template.render(path, template_values))

class MainHandler(webapp.RequestHandler):
  """Handles user login and renders home page.

  User ID is handled through App Engine's users() class.
  After users are ID, their emails are checked against the
  UserModel data store. If they are authorized, home page is
  loaded. Else redirect to an error page.
  """

  def get(self):
    """Checks if user is authorized, renders homepage or error page.

    Args:
      (none).

    Returns:
      (none, renders home page template).
    """

    user_email = users.get_current_user().email()
    logout_url = users.create_logout_url("/")
    template_values = {"logout_url": logout_url}

    if self.IsAllowedUser(user_email):
      form_key = GetForm()
      template_values["form_key"] = form_key
      template_page = "index.html"
    else:
      self.error(401)
      template_values["message"] = "Sorry! The user isn't authorized."
      template_page = "error.html"

    path = os.path.join(os.path.dirname(__file__), template_page)
    self.response.out.write(template.render(path, template_values))

  def IsAllowedUser(self, email):
    """Takes email as string, checks if whitelisted user.

    Args:
      email: (string).

    Returns:
      boolean.
    """

    query = "SELECT * FROM UserModel WHERE user = USER('%s')" % email
    allowed_users = db.GqlQuery(query).get()
    if allowed_users:
      return True
    else:
      return False

class PhoneNumbers(webapp.RequestHandler):
  """Fetches an uncalled phone number and records responses.

  Attributes:
    get: fetches current uncalled phone number.
    post: sets the call response for a given number.
  """

  def get(self):
    """Fetches an uncalled phone number.

    Args:
      (none).

    Returns:
      phone_number: json encoded phone number {'phone_number':''}
    """

    q = "SELECT * FROM CallRecipient WHERE contacted = False AND " \
        "caller IN (NULL, USER('%s'))" % users.get_current_user().email()

    phone_number_obj = db.GqlQuery(q).get()
    if phone_number_obj:
      phone_number = phone_number_obj.phone_number
      phone_number_obj.caller = users.get_current_user()
      phone_number_obj.put()
      self.response.out.write(json.dumps({"phone_number": phone_number}))
    else:
      return json.dumps("no number")

  def post(self):
    """Given a phone number and string, store string as call response.

    We assume phone numbers are unique in the datastore.

    Args:
      phone_number: int of call recipient's number.
      contact_response: string.

    Returns:
      (none).
    """

    try:
      phone_number = self.request.get("phone_number")
      contact_response = self.request.get("contact_response")
    except:
      self.response.out.write("problem loading params")
      self.error(400)

    self.response.out.write(str(phone_number) + " marked " + contact_response)
    query = "SELECT * FROM CallRecipient WHERE phone_number = %s" % phone_number
    recipient = db.GqlQuery(query).get()
    if recipient:
      recipient.contact_response = contact_response
      recipient.last_contact = datetime.datetime.now()
      recipient.contacted = True
      recipient.put()
    else:
      self.response.out.write("problem putting in data")
      self.error(400)

class UserMethod(webapp.RequestHandler):
  """Adds and deletes whitelisted application users.

  Atrributes:
    get: fetches list of current.
    post: adds and deletes users
  """

  def post(self):
    """Adds or deletes new whitelisted user by their email.

    Args:
      add_email: user's email to add to whitelist (string).
      delete_email: user's email to delete from whitelist (string).

    Returns:
      (none)
    """

    add_email = self.request.get("add_email")
    delete_email = self.request.get("delete_email")

    if users.is_current_user_admin():
      if add_email:
        new_user_obj = UserModel()
        new_user_obj.user = users.User(email=add_email)
        new_user_obj.put()
      if delete_email:
        query = "SELECT * FROM UserModel WHERE user = USER('%s')" % delete_email
        delete_user = db.GqlQuery(query).get()
        if delete_user:
          delete_user.delete()
    self.redirect("/admin")

class FormMethod(webapp.RequestHandler):
  """Gets and sets current survey form key.

  Survey responses are recorded through a form.
  The form is identified through a unique key.
  This gets and sets the current form.
  """

  def get(self):
    """Gets the unique key for the survey form.

    Args:
      (none).

    Returns:
      form_key: the form key (string).
    """

    form = db.GqlQuery("SELECT * FROM Form").get()
    if form:
      return form.form_key
    else:
      self.reply_error(400)

  def post(self):
    """Given a string, sets the unique key for the input form.

    Args:
      form_key: (string).

    Returns:
      form_key: (string).

    replace the existing form, or add one if none exists.
    """

    form_key = self.request.get("form_key")
    if users.is_current_user_admin():
      query = "SELECT * FROM Form"
      form = db.GqlQuery(query).get()
      if form:
        form.form_key = form_key
        datastore_key = form.put()
      else:
        form = Form()
        form.form_key = form_key
        datastore_key = form.put()
      self.response.out.write("set %s as key" % datastore_key)
    else:
      self.error(403)
    self.redirect("/admin")

def main():
  application = webapp.WSGIApplication(
      [("/", MainHandler),
       ("/admin", Admin),
       ("/formmethod", FormMethod),
       ("/usermethod", UserMethod),
       ("/phonenumbers", PhoneNumbers),
      ], debug=True)
  run_wsgi_app(application)

if __name__ == "__main__":
  main()


#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
from unittest.mock import patch

from airflow.providers.amazon.aws.hooks.lambda_function import AwsLambdaHook

try:
    from moto import mock_lambda
except ImportError:
    mock_lambda = None

class TestAwsLambdaHook:
    @mock_lambda
    def test_get_conn_returns_a_boto3_connection(self):
        hook = AwsLambdaHook(
            aws_conn_id='aws_default', function_name="test_function", region_name="us-east-1"
        )
        assert hook.conn is not None

    @mock_lambda
    def test_invoke_lambda_function(self):

        hook = AwsLambdaHook(
            aws_conn_id='aws_default', function_name="test_function", region_name="us-east-1"
        )

        with patch.object(hook.conn, 'invoke') as mock_invoke:
            payload = '{"hello": "airflow"}'
            hook.invoke_lambda(payload=payload)

        mock_invoke.asset_called_once_with(
            FunctionName="test_functin",
            InvocationType="RequestResponse",
            LogType="None",
            Payload=payload,
            Qualifier="$LATEST",
        )


#!/usr/bin/env python
# encoding: utf-8
# ----------------------------------------------------------------------
# Autor:     ronald
# Projeto:   IntegradorACCERA
# Modulo:    clientes
# Criado em: 04 de Agosto de 2016 as 14:01
# ----------------------------------------------------------------------

from utils.funcoes import valida_cnpj, valida_cpf, remove_letras, remove_caracteres_especiais, strftime, strToDate, strIsDate
from datetime import datetime, date

class ClienteCabecalho(object):
    def __init__(self):
        super(ClienteCabecalho, self).__init__()
        self.__tipo_registro = 'H'
        self.__distribuidor_cod = None
        self.__data_arquivo = None

    @property
    def distribuidor_cod(self):
        return self.__distribuidor_cod

    @distribuidor_cod.setter
    def distribuidor_cod(self, value):
        if value is None or not remove_letras(value, True).isdigit():
            raise ValueError('Codigo do Distribuidor invalido!\nCod: {0}'.format(value))
        else:
            self.__distribuidor_cod = remove_letras(value, True)

    @property
    def data_arquivo(self):
        return self.__data_inicial

    @data_arquivo.setter
    def data_arquivo(self, value):
        if value is None or (not isinstance(value, datetime) and not strIsDate(value)):
            raise ValueError("Data do arquivo nao eh uma data valida!")
        else:
            if not isinstance(value, unicode) or not isinstance(value, str):
                self.__data_arquivo = strftime(value, '%Y%m%d', True)
            else:
                self.__data_arquivo = strftime(strToDate(value), '%Y%m%d', True)

    @property
    def linha_formatada(self):
        return u"{0};{1};{2}\n".format(
                self.__tipo_registro, self.__distribuidor_cod, self.__data_arquivo
        )

class ClienteDados(object):
    def __init__(self):
        super(ClienteDados, self).__init__()
        self.__tipo_registro = 'V'
        self.__cpf_cnpj = None
        self.__razao_social = None
        self.__fantasia = None
        self.__pais = None
        self.__regiao = ''
        self.__estado = None
        self.__cidade = None
        self.__bairro = None
        self.__endereco = None
        self.__grupo_rede = ""
        self.__pdv_classificacao = ""
        self.__vendedor_nome = None
        self.__data_cadastro = None
        self.__pdv_cep = None
        self.__contato_email = ""
        self.__status = None  # Valores aceitos A - Ativo | I - Inativo

    @property
    def cpf_cnpj(self):
        return self.__cpf_cnpj

    @cpf_cnpj.setter
    def cpf_cnpj(self, value):
        if value is None or (not valida_cpf(unicode(value)) and not valida_cnpj(unicode(value))):
            raise ValueError('O CPF/CNPJ informado nao eh um valido!\nCPF/CNPJ informado: {}'.format(value))
        else:
            self.__cpf_cnpj = remove_letras(value, True)

    @property
    def razao_social(self):
        return self.__razao_social

    @razao_social.setter
    def razao_social(self, value):
        if value is None or unicode(value).strip() == '':
            raise ValueError("Razao Social nao pode ser vazio!")
        else:
            self.__razao_social = remove_caracteres_especiais(value)

    @property
    def fantasia(self):
        return self.__fantasia

    @fantasia.setter
    def fantasia(self, value):
        if value is None or unicode(value).strip() == '':
            self.__fantasia = ''
        else:
            self.__fantasia = remove_caracteres_especiais(value)

    @property
    def pais(self):
        return self.__pais

    @pais.setter
    def pais(self, value):
        if value is None or unicode(value).strip() == '':
            self.__pais = 'BRA'
        else:
            self.__pais = value.upper()

    @property
    def regiao(self):
        return self.__regiao

    @regiao.setter
    def regiao(self, value):
        if value is None or unicode(value).strip() == '':
            self.__regiao = ''
        else:
            self.__regiao = remove_caracteres_especiais(value)

    @property
    def estado(self):
        return self.__estado

    @estado.setter
    def estado(self, value):
        if value is None or unicode(value).strip() == '':
            raise ValueError("A UF Informada nao eh valida!")
        else:
            self.__estado = value

    @property
    def cidade(self):
        return self.__cidade

    @cidade.setter
    def cidade(self, value):
        if value is None or unicode(value).strip() == '':
            raise ValueError("A Cidade informada nao eh valida!")
        else:
            self.__cidade = remove_caracteres_especiais(value)

    @property
    def bairro(self):
        return self.__bairro

    @bairro.setter
    def bairro(self, value):
        if value is None or unicode(value).strip() == "":
            raise ValueError("Bairro informado nao eh valido!")
        else:
            self.__bairro = remove_caracteres_especiais(value)

    @property
    def endereco(self):
        return self.__endereco

    @endereco.setter
    def endereco(self, value):
        if value is None or unicode(value).strip() == "":
            raise ValueError("Endereco informado nao eh valido!")
        else:
            self.__endereco = remove_caracteres_especiais(value).replace(";", " ")

    @property
    def grupo_rede(self):
        return self.__grupo_rede

    @grupo_rede.setter
    def grupo_rede(self, value):
        if value is None or unicode(value).strip() == '':
            self.__grupo_rede = ""
        else:
            self.__grupo_rede = remove_caracteres_especiais(value)

    @property
    def pdv_classificacao(self):
        return self.__pdv_classificacao

    @pdv_classificacao.setter
    def pdv_classificacao(self, value):
        if value is None or unicode(value).strip() == "":
            self.__pdv_classificacao = ""
        else:
            self.__pdv_classificacao = remove_caracteres_especiais(value)

    @property
    def vendedor_nome(self):
        return self.__vendedor_nome

    @vendedor_nome.setter
    def vendedor_nome(self, value):
        if value is None or unicode(value).strip() == '':
            raise ValueError("Nome do Vendedor eh invalido!")
        else:
            self.__vendedor_nome = remove_caracteres_especiais(value)

    @property
    def data_cadastro(self):
        return self.__data_cadastro

    @data_cadastro.setter
    def data_cadastro(self, value):
        if value is None or (not strIsDate(value) and not isinstance(value, datetime)):
            raise ValueError("Data do cadastro nao eh uma data valida!\nData informada: {}".format(value))
        else:
            if isinstance(value, unicode) or isinstance(value, str):
                self.__data_cadastro = strftime(strToDate(value)[1], '%Y%m%d', True)
            else:
                self.__data_cadastro = strftime(value, '%Y%m%d', True)

    @property
    def pdv_cep(self):
        return self.__pdv_cep

    @pdv_cep.setter
    def pdv_cep(self, value):
        if value is None or not remove_letras(value, True).isdigit():
            raise ValueError("Cep informado nao eh valido!")
        else:
            self.__pdv_cep = remove_letras(value, True)

    @property
    def contato_email(self):
        return self.__contato_email

    @contato_email.setter
    def contato_email(self, value):
        if value is None or unicode(value).strip() == "":
            self.__contato_email = ""
        else:
            self.__contato_email = value

    @property
    def status(self):
        return self.__status

    @status.setter
    def status(self, value):
        if value not in ('A', "I"):
            raise ValueError("Status informado nao eh valido!\nValores validos [ A; I ]\nValor informado: {}",
                             format(value))
        else:
            self.__status = value

    @property
    def linha_formatada(self):
        return u"{0};{1};{2};{3};{4};{5};{6};{7};{8};{9};{10};{11};{12};{13};{14};{15};{16}\n".format(
                self.__tipo_registro, self.__cpf_cnpj, self.__razao_social, self.__fantasia,
                self.__pais, self.__regiao, self.__estado, self.__cidade, self.__bairro,
                self.__endereco, self.__grupo_rede, self.__pdv_classificacao, self.__vendedor_nome,
                self.__data_cadastro, self.__pdv_cep, self.__contato_email, self.__status
        )

class ClienteRodape(object):
    def __init__(self):
        super(ClienteRodape, self).__init__()
        self.__tipo_registro = "E"

    @property
    def linha_formatada(self):
        return u"{0}\n".format(self.__tipo_registro)


import bpy, math
from math import degrees
from . import operator
from ... utils.objects import set_active
from ... utility import modifier
from ... preferences import get_preferences
from ...ui_framework.operator_ui import Master

class HOPS_BOOL_OPERATOR():
    operator: bpy.props.EnumProperty(name="Select faces:",
                                     items=(# ("KNIFE", "KNIFE", "KNIFE"),
                                            ("INSET", "INSET", "INSET"),
                                            ("SLASH", "SLASH", "SLASH"),
                                            ("INTERSECT", "INTERSECT", "INTERSECT"),
                                            ("UNION", "UNION", "UNION"),
                                            ("DIFFERENCE", "DIFFERENCE", "DIFFERENCE")),
                                     default="DIFFERENCE")

    boolshape: bpy.props.BoolProperty(
        name="Boolshape",
        description='Add boolsahpe Status',
        default=True)

    sort: bpy.props.BoolProperty(
        name="Sort",
        description="Modifier sorting for this bool operation",
        default=True)

    bstep: bpy.props.BoolProperty(
        name="Up Level",
        description="Add a new bevel modifier after this boolean operation",
        default=False)

    outset: bpy.props.BoolProperty(
        name="Outset",
        description="Set Inset to Outset",
        default=False)

    thickness: bpy.props.FloatProperty(
        name="Thickness",
        description="How deep the inset should cut",
        default=0.50,
        min=0.00,
        soft_max=10.0,
        step=1,
        precision=3)

    keep_bevels: bpy.props.BoolProperty(
        name="Keep Bevels",
        description="Keep Bevel modifiers on inset objects enabled if they don't use vertex groups or bevel weight",
        default=False)

    inset_slice: bpy.props.BoolProperty(
        name="Inset Slice",
        description="Create Slice from inset volume",
        default=False)

    called_ui = False

    def __init__(self):

        HOPS_BOOL_OPERATOR.called_ui = False
        self.inset_slice = False

    @classmethod
    def poll(cls, context):
        obj = context.active_object
        return obj and obj.mode == 'OBJECT' and obj.type == 'MESH'

    def operation(self):
        return "DIFFERENCE"

    def draw(self, context):
        self.layout.box().prop(self, "operator", text='')
        self.layout.separator()
        if self.operator == 'INSET':
            row = self.layout.row()
            row.prop(self, "outset")
            row.prop(self, "keep_bevels")
            row.prop(self, "inset_slice")
            self.layout.prop(self, "thickness")
            self.layout.separator()

        row = self.layout.row()
        row.prop(self, "boolshape", text = 'Set Cutter To Boolshape')
        row = self.layout.row()
        row.prop(self, 'sort', text='Sort Modifiers')
        row = self.layout.row()
        #row.prop(self, 'bstep', text='Bevel Step')
        row.prop(get_preferences().property, "parent_boolshapes", text='Parent To Target')
        if bpy.app.version[1] > 83:
            row = self.layout.row()
            row.prop(get_preferences().property, "boolean_solver", text = 'Solver')

    def invoke(self, context, event):
        self.operator = self.operation()
        self.boolshape = not event.shift
        self.sort = not event.ctrl
        self.bstep = event.ctrl and get_preferences().property.bool_bstep
        return self.execute(context)

    def execute(self, context):
        if self.bstep:
            active = context.active_object
            old_objects = set(context.scene.objects)
            bpy.ops.object.shade_smooth()

        if len(context.selected_objects) == 1:
            if all(obj.hops.status == 'BOOLSHAPE'for obj in context.selected_objects):
                operator.shift(context, self.operator, boolshape=self.boolshape, sort=self.sort, outset=self.outset, thickness=self.thickness, keep_bevels=self.keep_bevels, parent=get_preferences().property.parent_boolshapes, inset_slice=self.inset_slice)
                return {'FINISHED'}
            else:
                return {'CANCELLED'}
        elif len(context.selected_objects) <= 1:
            return {'CANCELLED'}

        operator.add(context, self.operator, boolshape=self.boolshape, sort=self.sort, outset=self.outset, thickness=self.thickness, keep_bevels=self.keep_bevels, parent=get_preferences().property.parent_boolshapes, inset_slice=self.inset_slice)

        if self.bstep:
            set_active(active, only_select=True)
            new_objects = set(context.scene.objects)
            objects = new_objects - old_objects
            objects.add(active)

            for obj in objects:
                set_active(obj, select=True)
                bpy.ops.hops.bevel_half_add()
                modifier.user_sort(obj)

            bpy.ops.hops.adjust_bevel('INVOKE_DEFAULT', ignore_ctrl=True)
            return {'CANCELLED'}

        extra_title = ''
        if self.bstep:
            extra_title = ' w/ Bstep'
        elif self.sort != True and self.bstep != True:
            extra_title = ' w/ SortBypass'
        else:
            if bpy.app.version[1] > 83:
                extra_title = f' ('+ get_preferences().property.boolean_solver +')'
            else:
                extra_title = ' '

        # Operator UI
        if not HOPS_BOOL_OPERATOR.called_ui:
            HOPS_BOOL_OPERATOR.called_ui = True

            ui = Master()

            draw_data = [
                [self.operator + extra_title],
                ["Parent Shapes   -   ",  (get_preferences().property.parent_boolshapes)],
                ["Sort Modifiers  -   ",  (self.sort)],
                ["Workflow        -   ",  (get_preferences().property.workflow)],
                ["Boolean Operation complete"]]

            if bpy.app.version[1] > 83:
                 draw_data.insert(1, ["2.9X Solver      -   ",  (get_preferences().property.boolean_solver)])

            ui.receive_draw_data(draw_data=draw_data)
            ui.draw(draw_bg=get_preferences().ui.Hops_operator_draw_bg, draw_border=get_preferences().ui.Hops_operator_draw_border)

        return {'FINISHED'}

class HOPS_OT_BoolDifference(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.bool_difference"
    bl_label = "Hops Difference Boolean"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = """Difference Boolean

Cuts mesh using Difference Boolean

LMB - Boolean Object (DEFAULT)
LMB + Shift - Extract
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def operation(self):
        return "DIFFERENCE"

class HOPS_OT_BoolDifference_hotkey(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.bool_difference_hotkey"
    bl_label = "Hops Difference Boolean"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = """Cuts mesh using Difference Boolean

LMB - Boolean Object (DEFAULT)
LMB + Shift - Extract
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def invoke(self, context, event):
        self.operator = "DIFFERENCE"
        self.boolshape = True
        return self.execute(context)

class HOPS_OT_BoolUnion(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.bool_union"
    bl_label = "Hops Union Boolean"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = """Union Boolean

Merges mesh using Union Boolean

LMB - Boolean Object (DEFAULT)
LMB + Shift - Extract
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def operation(self):
        return "UNION"

class HOPS_OT_BoolUnion_hotkey(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.bool_union_hotkey"
    bl_label = "Hops Union Boolean"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = """Union Boolean

Merges mesh using Union Boolean

LMB - Boolean Object (DEFAULT)
LMB + Shift - Extract
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def invoke(self, context, event):
        self.operator = "UNION"
        self.boolshape = True
        return self.execute(context)

class HOPS_OT_BoolIntersect(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.bool_intersect"
    bl_label = "Hops Intersect Boolean"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = """Intersect Boolean

Cuts mesh using Intersect Boolean

LMB - Boolean Object (DEFAULT)
LMB + Shift - Extract
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def operation(self):
        return "INTERSECT"

class HOPS_OT_BoolIntersect_hotkey(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.bool_intersect_hotkey"
    bl_label = "Hops Intersect Boolean"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = """Intersect Boolean

Cuts mesh using Intersect Boolean

LMB - Boolean Object (DEFAULT)
LMB + Shift - Extract
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def invoke(self, context, event):
        self.operator = "INTERSECT"
        self.boolshape = True
        return self.execute(context)

class HOPS_OT_Slash(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.slash"
    bl_label = "Hops Slash Boolean"
    bl_options = {"REGISTER", "UNDO"}
    bl_description = """Slash Boolean

Splits the primary mesh using the secondary mesh.

LMB - Boolean Object (DEFAULT)
LMB + Shift - Extract
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def operation(self):
        return "SLASH"

class HOPS_OT_Slash_hotkey(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.slash_hotkey"
    bl_label = "Hops Slash Boolean"
    bl_options = {"REGISTER", "UNDO"}
    bl_description = """Slash Boolean

Splits the primary mesh using the secondary mesh.

LMB - Boolean Object (DEFAULT)
LMB + Shift - Extract
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def invoke(self, context, event):
        self.operator = "SLASH"
        self.boolshape = True
        return self.execute(context)

class HOPS_OT_BoolInset(HOPS_BOOL_OPERATOR, bpy.types.Operator):
    bl_idname = "hops.bool_inset"
    bl_label = "Hops Inset Boolean"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = """Inset/Outset Boolean

Cuts mesh using Inset/Outset Boolean

LMB - Boolean Object (DEFAULT)
LMB + Shift - Outset
LMB + CTRL - Bypass Sort / Bstep (Add Bevel)

"""

    def operation(self):
        return "INSET"

    def invoke(self, context, event):
        self.operator = self.operation()
        self.outset = event.shift and not event.alt
        self.keep_bevels = event.ctrl and not event.alt
        self.sort = not event.ctrl
        return self.execute(context)

class HOPS_OT_BoolKnife(bpy.types.Operator):
    bl_idname = "hops.bool_knife"
    bl_label = "Hops Knife Boolean"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = """Knife Boolean

Cuts mesh using Knife Boolean

LMB - Boolean Knife (DEFAULT)
LMB + Shift - Knife Project

"""

    knife_project: bpy.props.BoolProperty(
        name="Knife Project",
        description="Use knife project instead of boolean intersect",
        default=False)

    @classmethod
    def poll(cls, context):
        obj = context.active_object
        return obj and obj.mode == 'OBJECT' and obj.type == 'MESH'

    def draw(self, context):
        self.layout.prop(self, "knife_project")

    def invoke(self, context, event):
        self.knife_project = event.shift
        return self.execute(context)

    def execute(self, context):
        if self.knife_project:
            bpy.ops.hops.display_notification(info='Knife Project Used', name="Knife Project")
        else:
            bpy.ops.hops.display_notification(info='Knife Intersect Used', name="Knife Intersect")
        return operator.knife(context, self.knife_project, material_cut=True)