import os
import subprocess
import sys
from distutils.spawn import find_executable

from setuptools import setup
from setuptools.command.build_py import build_py
from setuptools.command.sdist import sdist

# fix permissions for sdist
if 'sdist' in sys.argv:
    os.system('chmod -R a+rX .')
    os.umask(int('022', 8))

def build_npm():
    """Build the static files by using NPM."""
    # build static files if NPM can be found
    if find_executable('npm'):
        subprocess.run(['npm', 'install'], check=True)
        subprocess.run(['npm', 'run', 'build'], check=True)
    # fail if generated files are absent
    with open('muninplot/static/index.html', 'rb') as f:
        f.read()

class NPMbuild_py(build_py):  # noqa: N801
    """Custom build class to build static files with NPM."""

    def run(self):
        """Perform the sdist actions."""
        build_npm()
        build_py.run(self)

class NPMsdist(sdist):
    """Custom sdist class to build static files with NPM."""

    def run(self):
        """Perform the sdist actions."""
        build_npm()
        sdist.run(self)

setup(
    cmdclass={
        'build_py': NPMbuild_py,
        'sdist': NPMsdist,
    },
)


import sys
from collections import namedtuple
from dataclasses import dataclass
from typing import Dict, List, Tuple

SNAPSHOT_INTERVAL = 40
SNAPSHOT_CEIL = 220

Waveform = namedtuple("Waveform", "x cycle")

@dataclass
class Command:
    duration: int
    action: callable

    def execute(self, waveform: Waveform, parameters: Dict) -> Waveform:
        x = self.action(waveform.x, parameters)
        cycle = waveform.cycle + self.duration
        return Waveform(x, cycle)

commands = {
    "noop": Command(1, lambda x, _: x),
    "addx": Command(2, lambda x, p: x + int(p[0])),
}

def parse_command_line(line: str) -> Tuple[Command, Dict]:
    args = line.rstrip().split()
    return commands[args[0]], args[1:]

def update_snapshots(snapshots: List[int], snapshot_cycle: int, previous: Waveform, current: Waveform) -> int:
    wave = None
    if current.cycle == snapshot_cycle:
        wave = current
    elif current.cycle > snapshot_cycle > previous.cycle:
        wave = previous

    if wave is None:
        return snapshot_cycle

    snapshots.append(wave.x * snapshot_cycle)
    next_snapshot_cycle = snapshot_cycle + SNAPSHOT_INTERVAL
    if next_snapshot_cycle > SNAPSHOT_CEIL:
        raise OverflowError
    return next_snapshot_cycle

def get_signal_strengths_sum(filepath: str) -> int:
    current_wave = Waveform(1, 1)
    next_snapshot_cycle = 20
    snapshots = []
    with open(filepath) as f:
        for line in f.readlines():
            command, parameters = parse_command_line(line)
            new_wave = command.execute(current_wave, parameters)
            try:
                next_snapshot_cycle = update_snapshots(snapshots, next_snapshot_cycle, current_wave, new_wave)
            except OverflowError:
                break
            current_wave = new_wave
    return sum(snapshots)

if __name__ == "__main__":
    filepath = sys.argv[1]
    total = get_signal_strengths_sum(filepath)
    print(f"The sum of these signal strengths is {total}.")


#written by Zilin Shen and Daniel de Mello
import os
os.environ["CUDA_VISIBLE_DEVICES"]="1"

import numpy as np
from models.lstm import Lstm
from seq2seq.utils import softmax, print_header, get_events
from seq2seq.seq2seq_attention import Seq2seqAttention
import argparse
import copy
import tensorflow as tf
import random
import os

seed = 1
random.seed(seed)
np.random.seed(seed)
tf.random.set_seed(seed)

def get_args(jupyter_args = None):
    parser = argparse.ArgumentParser()
    parser.add_argument('--permute_truncated', required=False, action='store_true',
                        help="Bool for activating permutation invariance")
    parser.add_argument('--freeze_seq2seq', required=False, action='store_true',
                        help="Bool for keeping seq2seq weights at each relabel round ")
    parser.add_argument('--use_prob_embedding', required=False, action='store_true',
                        help="Bool for using original probability based embedding proposed in the original paper")
    parser.add_argument('--sequence_length', required=False, type=int, default=10,
                        help="Length of truncated subsequences used in the seq2seq training")
    parser.add_argument('--rv', required=False, type=int, default=1,
                        help="'round value' hyperparameter used for probability embedding, if activated")
    parser.add_argument('--ps_epochs', required=False, type=int, default=50,
                        help="number of training epochs for per-step detectors")
    parser.add_argument('--s2s_epochs', required=False, type=int, default=30,
                        help="number of training epochs for seq2seq detector")
    parser.add_argument('--relabel_rounds', required=False, type=int, default=1,
                        help="Number of relabel rounds")
    parser.add_argument('--patience', required=False, type=int, default=None,
                        help="Patience for early stopping. Any value activates early stopping.")
    parser.add_argument('--data_fraction', required=False, type=float, default=1.0,
                        help="Fraction (between 0 and 1) for how much of the training set to use.")
    #parser.add_argument('--name', required=False, type=str, default=None,
    #                    help="Experiment name.")
    parser.add_argument('--use_wandb', required=False, action='store_true',
                        help="Turn on logs with wandb")

    if jupyter_args is not None:
        args = parser.parse_args(jupyter_args)
    else:
        args = parser.parse_args()
    return args

#jupyter_args = ['--permute_truncated', '--use_prob_embedding']
args = get_args()
args.data_fraction = min(args.data_fraction, 1)
seq2seq_config = {"sequence_length": args.sequence_length,
                  "permute_truncated": args.permute_truncated,
                  "use_prob_embedding": args.use_prob_embedding,
                  "rv": args.rv
                  }

# -----------get the preprocessed training and testing saved as .npy files
test_label_infection = np.load('preprocess/saved/test_label_infection.npy')
train_label_infection = np.load('preprocess/saved/train_label_infection.npy')
test_data_infection = np.load('preprocess/saved/test_data_infection.npy')
train_data_infection = np.load('preprocess/saved/train_data_infection.npy')

test_label_reconnaissance = np.load('preprocess/saved/test_label_reconnaissance.npy')
train_label_reconnaissance = np.load('preprocess/saved/train_label_reconnaissance.npy')
test_data_reconnaissance = np.load('preprocess/saved/test_data_reconnaissance.npy')
train_data_reconnaissance = np.load('preprocess/saved/train_data_reconnaissance.npy')

test_label_attack = np.load('preprocess/saved/test_label_attack.npy')
train_label_attack = np.load('preprocess/saved/train_label_attack.npy')
test_data_attack = np.load('preprocess/saved/test_data_attack.npy')
train_data_attack = np.load('preprocess/saved/train_data_attack.npy')

all_data = {"infection":
                        {
                        'train': [train_data_infection, train_label_infection],
                        'test': [test_data_infection, test_label_infection]
                        },
            "attack":
                        {
                        'train': [train_data_attack, train_label_attack],
                        'test': [test_data_attack, test_label_attack]
                        },
            "reconnaissance":
                        {
                        'train': [train_data_reconnaissance, train_label_reconnaissance],
                        'test': [test_data_reconnaissance, test_label_reconnaissance]
                        }
            }

# ---------------------------wandb-------------------------------
if args.use_wandb:
    import wandb
    os.environ["WANDB_API_KEY"] = "8f5046c50251d53a31a4248e1f1ca0dc4e5c8cf2"
    wandb.login()
    run = wandb.init(
        # Set the project where this run will be logged
        project="ra",
        # Track hyperparameters and run metadata
        config={
            "data_fraction": args.data_fraction,
            "ps_epochs": args.ps_epochs,
            },
        name = f"df-{args.data_fraction}-{args.ps_epochs}"
        )

# ----------------create per-step detectors----------------------
ps_attack = Lstm("ps-detector-attack")
ps_attack.add_dataset(all_data['attack'])

ps_recon = Lstm("ps-detector-recon")
ps_recon.add_dataset(all_data['reconnaissance'])

ps_infec = Lstm("ps-detector-infec")
ps_infec.add_dataset(all_data['infection'])

# ----------------train per-step detectors----------------------
metrics_dict_train = {}
metrics_dict_test = {}
for detector in [ps_attack, ps_recon, ps_infec]:
    #train data
    train_data = detector.dataset['train']
    train_examples = train_data[0]
    train_labels = train_data[1]

    #test data
    test_data = detector.dataset['test']
    test_examples = test_data[0]
    test_labels = test_data[1]

    features_len = train_examples.shape[1]
    print('features len is ', features_len)

    print_header("Training {} detector".format(detector.name))
    detector.learning(features_len, train_examples, train_labels, kind='', epochs=args.ps_epochs, patience=args.patience, fraction=args.data_fraction)

    print_header("Measureing {} detector performance on train data".format(detector.name))
    _, _, metrics_dict_ps_train = detector.detection(train_examples, train_labels, kind='')
    print("Metrics: \n", metrics_dict_ps_train)
    metrics_dict_train[detector.name] = metrics_dict_ps_train

    print_header("Measureing {} detector performance on test data".format(detector.name))
    _, _, metrics_dict_ps_test = detector.detection(test_examples, test_labels, kind='')
    print("Metrics: \n", metrics_dict_ps_test)
    metrics_dict_test[detector.name] = metrics_dict_ps_test

if args.use_wandb:
    keys = ('auprc', 'r_at_99p', 'r_at_95p', 'p_at_99r', 'p_at_95r')
    wandb_dict_train = dict((k, metrics_dict_train[ps_infec.name][k]) for k in keys)
    wandb_dict_test = dict((k, metrics_dict_test[ps_infec.name][k]) for k in keys)
    wandb.log({'train': wandb_dict_train, 'test':  wandb_dict_test})

metrics_dict_per_round = []
for r in range(args.relabel_rounds):

    # -----------------seq2seq stage----------------------
    #get events
    events = get_events(ps_attack, ps_recon, ps_infec, all_data['infection']['train'][0])

    #init seq2seq
    if not(args.freeze_seq2seq):
        seq2seq = Seq2seqAttention('seq2seq')
    elif r == 0:
        seq2seq = Seq2seqAttention('seq2seq')

    #train seq2seq
    seq2seq.learning(events, all_data['infection']['train'][1], seq2seq_config, epochs=args.s2s_epochs)

    #get seq2seq tagged events
    events_preds, tagged_seq2seq = seq2seq.analysis(events, all_data['infection']['train'][1], seq2seq_config)

    #get per-step infection detector tagged windows
    preds_ps_infec = ps_infec.predict(all_data['infection']['train'][0], kind='')
    preds_ps_infec = np.array(preds_ps_infec).squeeze()
    print('preds ps infec shape is', preds_ps_infec.shape)
    tagged_ps_infec = []
    for idx, pred in enumerate(preds_ps_infec):
        if pred>0.5:
            tagged_ps_infec.append(idx)

    # -----------------relabeling---------------------
    #strategy 1
    retrain_pos = []
    retrain_neg = []
    for idx in tagged_ps_infec:
        if idx in tagged_seq2seq:
            retrain_pos.append(idx)
        else:
            retrain_neg.append(idx)

    #overwritte original dataset with new positive and negative labels
    retrain_labels = copy.deepcopy(all_data['infection']['train'][1])
    retrain_data = copy.deepcopy(all_data['infection']['train'][0])
    for idx, l in enumerate(retrain_labels):
        if idx in retrain_pos:
            retrain_labels[idx] = 1
        if idx in retrain_neg:
            retrain_labels[idx] = 0

    # -----------------retrain per-step infection detector with new labels---------------------
    #def retrain_detector(detector, retrain_data, retrain_labels, test_data, test_labels):
    features_len = retrain_data.shape[1]
    print('features len is ', features_len)

    print_header("Retraining {} detector".format('infection'))
    ps_infec.learning(features_len, retrain_data, retrain_labels, kind='', epochs=args.ps_epochs)

    print_header("Measureing {} detector performance on test data".format('infection'))
    _, _, metrics_dict_new = ps_infec.detection(detector.dataset['test'][0], detector.dataset['test'][1], kind='')

    print_header("Per-step infection detector metrics BEFORE relabeling")
    print( metrics_dict_test[ps_infec.name])

    print_header("Per-step infection detector metrics AFTER relabeling")
    metrics_dict_per_round.append(metrics_dict_new)
    for r, mdround in enumerate(metrics_dict_per_round):
        print(f'Round {r}:')
        print(mdround)

    if args.use_wandb:
        keys = ('auprc', 'r_at_99p', 'r_at_95p', 'p_at_99r', 'p_at_95r')
        wandb_dict_relabel = dict((k, metrics_dict_per_round[-1][k]) for k in keys)
        wandb.log({f'test_r{r}':  wandb_dict_relabel})

if args.use_wandb:
    wandb.finish()


import math
#btlist = [1,3,9,None,None,15,7,None,None,None,None,67,8,9,0]
btlist = [3,9,20,None,None,15,7]

class BinaryTree:
    def __init__(self, value, deep=0, left=None, right=None) -> None:
      self.value = value
      self.left = left
      self.right = right
      self.deep = deep

index = 0
root=[]
def creating_binary_tree(btlist, index, rtree=root):
  if index >= len(btlist):
    return rtree

  elif len(btlist) > 2*index+1 and len(btlist) > 2*index+2:
    tree = BinaryTree(btlist[index])
    tree.left = btlist[2*index+1]
    tree.right = btlist[2*index+2]
    tree.deep = math.trunc(math.log(index+1,2))+1
    index+=1
    rtree.append(tree)
    return creating_binary_tree(btlist,index,root)

  else:
    tree = BinaryTree(btlist[index])
    tree.deep = math.trunc(math.log(index+1,2))+1
    index+=1
    rtree.append(tree)
    return creating_binary_tree(btlist,index,root)

ftree = creating_binary_tree(btlist,index,root)
print(ftree)
lowest_deep=100
for i in ftree:
  if i.left == None and i.right == None and lowest_deep > i.deep:
    lowest_deep = i.deep

print(lowest_deep)


from pynput import mouse, keyboard

def mouse_position() -> tuple:
    "return a mouse coordinate (0 element - coord x, 1 element - coord y)"
    return mouse.Controller().position

def keyboard_event() -> bool:
    with keyboard.Events() as events:
        event = events.get(1)
        if event is None:
            return False
        if event.key.char == '0':
            return True


import vk_api
import json
import requests
import random
import traceback
import os
import subprocess
from vk_api.longpoll import VkLongPoll, VkEventType
from vk_api.keyboard import VkKeyboard, VkKeyboardColor
from array import *
from random import randint
from vk_api.bot_longpoll import VkBotLongPoll, VkBotEventType
keyboard = VkKeyboard(one_time=True)

vk_session = vk_api.VkApi(token='token')
longpoll = VkBotLongPoll(vk_session, group_id="202796234")
vk = vk_session
num = int
msg_art = str
avk=vk_session.get_api()
##Далее описывается функционал отправки всякой хуйни и выгрузки фото (для последующей отправки)
def sender(id, text):
    avk.messages.send(user_id = id, message = text, random_id = 0, keyboard = keyboard.get_keyboard())
def send_attach(id, url):
    avk.messages.send(user_id = id, attachment = url, random_id = 0, keyboard = keyboard.get_keyboard())
def send_stick(id, number):
    avk.messages.send(user_id = id, sticker_id = number, random_id = 0)
def sender_chat(chat_id, text):
    avk.messages.send(chat_id = chat_id, message = text, random_id = random.randint(0,100))
def send_attach_chat(chat_id, url):
    avk.messages.send(chat_id = chat_id, attachment = url, random_id = 0)

def upload_photo(chat_id, filename):
    link = vk.method('photos.getMessagesUploadServer', {'peer_id': chat_id})['upload_url']
    print(link)
    cookies = vk.http.cookies
    up = json.loads(requests.post(link, files={'photo': open(filename, 'rb')}).text)
    photos = vk.method('photos.saveMessagesPhoto', up)
    print(photos)
    ownerId = photos[0]['owner_id']
    photoId = photos[0]['id']
    vk.method('messages.send', {'peer_id': chat_id, 'random_id': random.randint(0,2048), 'attachment': "photo{}_{}".format(ownerId, photoId)})
while True: ##цикл для лонгпола, без этой хуеты иногда вылетает ошиб_очка, а так на похуй
    try:
        for event in longpoll.listen():
            if event.type == VkBotEventType.MESSAGE_NEW:
                print(event)
                peer_id = event.message['peer_id']
                if peer_id >= 2000000000: ##Если пир айди - это айди беседы, значит бот работает в режиме беседы с одним функционалом
                    if 'action' in event.message:
                        if (event.message['action']['type'] == 'chat_invite_user') and (event.message['action']['member_id'] == -202796234):
                            chat_id = int(event.chat_id)
                            sender_chat(chat_id, 'Вас приветствует бот-идиот. Разрешите боту просматривать всю переписку чтобы команды срабатывали')
                    else:
                        msg = event.message['text'].lower()
                        chat_id = int(event.chat_id)
                        random_id = random.randint(0, 100)
                        attachments = []
                        id = event.message['from_id']
                        ##if msg in ["/art", "/арт", "[club152451931|@random_anime_official], арт", "[club152451931|@random_anime_official], art", "[club152451931|@random_anime_official], /art", "[club152451931|@random_anime_official], /арт", "[club152451931|@random_anime_official] /art", "[club152451931|@random_anime_official] арт", "[club152451931|@random_anime_official] art", "[club152451931|@random_anime_official] /арт"]:
                           ## files = os.listdir("/home/qph7/Yuri pack")
                            ##upload_photo(peer_id, "/home/qph7/Yuri pack/"+files[random.randint(0, len(files)-1)])
                            ##В этих строчках я пытался описать хуйню для добавления сразу нескольких картиночек в одно сообщение, но мне стало похуй
                        if msg in ["пчел"]:
                            send_attach_chat(chat_id, "photo-202796234_457239018") ##На основе вот этой команды предлагаю сделать команду на блок стикеров. Картинка выгружена в альбом паблика и отправляется просто url этой картинки, что даёт почти моментальный респонс
                        if msg in ["нацист"]:
                            send_attach_chat(chat_id, "video-29544671_171117427")
                        if msg in ["совок"]:
                            send_attach_chat(chat_id, "photo-202796234_457239017")
                        if msg in ["навальный", "/navalny", "овальный"]:
                            files = os.listdir("/home/qph7/овальный")
                            upload_photo(peer_id, "/home/qph7/овальный/"+files[random.randint(0, len(files)-1)])
                        if msg in ["/укр", "/ukr", "укр"]:
                            files = os.listdir("/home/qph7/Укр")
                            upload_photo(peer_id, "/home/qph7/Укр/"+files[random.randint(0, len(files)-1)])
                        if msg in ["/консерва", "консерва"]:
                            files = os.listdir("/home/qph7/Консерва")
                            upload_photo(peer_id, "/home/qph7/Консерва/"+files[random.randint(0, len(files)-1)])
                        if msg in ["/gosl"]:
                            files = os.listdir("/home/qph7/Гуслинг")
                            upload_photo(peer_id, "/home/qph7/Гуслинг/"+files[random.randint(0, len(files)-1)])
                else:     ##Если мы не находимся в беседе - функционал другой
                    msg = event.message['text'].lower()
                    id = event.message['from_id']
                    attachments = []
                    if msg in ["привет", "начать", "здравствуйте", "здравствуй", "ку", "хай", "прив", "дарова", "дороу", "привет.", "здравствуйте.", "здравствуй.", "ку.", "хай.", "прив.", "дарова.", "дороу.", "привет!", "здравствуйте!", "здравствуй!", "ку!", "хай!", "прив!", "дарова!", "дороу!"]:
                        sender(id, "Вас приветствует бот")
                        send_stick(id, 21)
                    elif msg in ["арт", "art", "/art", "/арт", "/юри", "юри"]:
                        files = os.listdir("/home/qph7/Yuri pack")
                        upload_photo(peer_id, "/home/qph7/Yuri pack/"+files[random.randint(0, len(files)-1)])
                    if msg in ["/укр", "/ukr", "укр"]:
                        files = os.listdir("/home/qph7/Укр")
                        upload_photo(peer_id, "/home/qph7/Укр/"+files[random.randint(0, len(files)-1)])
                        ##send_attach(id, 'photo-152451931_'+str(randint(457248038, 457251894))) ##photo-152451931_457248038 - photo-152451931_457251894
                    #elif msg[0] == "/art":
                        #msg_art == msg.split()
                        #print(msg_art)
                        #for word in msg_art:
                            #if word.isnumeric():
                                #num == word
                        #if num == num.empty:
                            #send_attach(id, 'photo-152451931_'+str(randint(457248038, 457251894)))
                        #else:
                            #while num > 0:
                                #send_attach(id, 'photo-152451931_'+str(randint(457248038, 457251894)))
                                #num = num - 1
                    ##О, здесь я тоже пытался описать отправку нескольких картинок, можно поржать
                    elif msg in ["включить пк"] and ((id == 428225339) or (id == 245663694)): ##Wake on LAN удобная штука
                        os.system("wakeonlan B4:2E:99:1B:EE:72")
                        sender(id, "Пк включен")
                    elif msg in ["ip"] and ((id == 428225339) or (id == 245663694)): ##А это мне лень было конфижить на роутере DHCP и поэтому я просто каждый раз обращался к боту чтобы он мне писал айпи локальный
                        result = subprocess.check_output("hostname -I", shell=True)
                        b = result[0:11]
                        print(b)
                        sender(id, b)
                    elif msg in ["пак"]:
                        sender(id, "Пак всех артов за всё время:\nyadi.sk/d/RxmjBQkxMeo1tw?w=1")
                    else:
                        sender(id, 'Я тебя не понимаю')
    except (KeyboardInterrupt, SystemExit):
        break
    except:
        traceback.print_exc()


from django.urls import path
from . import views

urlpatterns = [
    path("sanity_check/", views.SanityCheck.as_view(),name="sanity_check"),
    path("latest-news/", views.LatestNewsListView.as_view() ,name="latest-news"),
    path("headline/", views.HackersNewsHeadlineNewsView.as_view(),name="headline"),
    path("headline/hf", views.HackersFeedHeadlineNewsView.as_view(),name="hackersfeed"),
    path("<int:pk>", views.DetailNewsView.as_view(),name="news-details"),
    path("create/", views.NewsItemCreateView.as_view(),name="post-news"),
    path("<int:news_item_id>/comments/", views.CommentCreateView.as_view(),name="comment"),
    path('search/', views.NewsItemSearchView.as_view(),name="search-news"),
]


menu = '''

[d] Depositar
[s] Sacar
[e] Extrato
[q] Sair

=>'''

LIMITE_POR_SAQUE = 500
LIMITE_SAQUE_DIARIO = 3
saldo = 0
numeros_saques = 0
extrato = ''

def converter_para_inteiro(numero: str) -> int | None:
    try:
        numero = int(numero)
    except:
        return None
    return numero

def pedir_numero_inteiro() -> str:
    numero = input('digite um numero inteiro: ')
    return numero

while True:

    opcao = input(menu)

    if opcao == 'd':
        print('Deposito')
        numero = pedir_numero_inteiro()
        inteiro_numero = converter_para_inteiro(numero)
        if not inteiro_numero:
            print('Numero digitado não e um inteiro')
            continue
        saldo += inteiro_numero
        extrato += f'Deposito: {inteiro_numero}\n'

    elif opcao == 's':
        print('Saque')
        numero = pedir_numero_inteiro()
        inteiro_numero = converter_para_inteiro(numero)
        if not inteiro_numero:
            print('Numero digitado não e um inteiro')
            continue
        if inteiro_numero > saldo:
            print('Você não tem dinheiro suficiente na conta')
            continue
        if inteiro_numero > LIMITE_POR_SAQUE:
            print('O limite de saque e 500')
            continue
        if numeros_saques >= LIMITE_SAQUE_DIARIO:
            print('Você chegou ao limite de saque por dia')
            continue
        saldo -= inteiro_numero
        extrato += f'Saque: {inteiro_numero}\n'
        numeros_saques += 1

    elif opcao == 'e':
        print('Extrato ')
        print(f'{extrato} Saldo Total:{saldo}')
    elif opcao == 'q':
        break

    else:
        print('Operação Invalida')


#coding=utf8

import socket
import cv2
import pickle
import numpy as np
from mss import mss
from threading import Thread, Lock
from darkflow.net.build import TFNet
import sys

class VideoCapture(Thread):
	def __init__(self,option=None):
		Thread.__init__(self)
		self.running = True
		self.image = None
		self.lock = Lock()
		self.sct = mss()
		self.mon = {'top':150, 'left':150, 'width':800, 'height':600}
		self.result = None
		self.option = option
		self.tf=None
		self.encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 20]
		self.preconnect()

	def stop(self):
		self.running = False

	def getBuffer(self):
		self.lock.acquire()
		img=cv2.cvtColor(np.array(self.sct.grab(self.mon)),cv2.COLOR_RGBA2RGB)
		check,self.image = cv2.imencode('.jpg', img, self.encode_param)
		self.result = self.tf.return_predict(img)
		self.lock.release()
		return self.image,self.result

	def getImage(self):
		self.lock.acquire()
		img = cv2.cvtColor(np.array(self.sct.grab(self.mon)),cv2.COLOR_RGBA2RGB)
		check,self.image = cv2.imencode('.jpg', img, self.encode_param)
		self.lock.release()
		return self.image

	def connectTf(self):
		self.tf=TFNet(self.getOption(self.option))

		'''
	def run(self):
		while(self.running):
			self.lock.acquire()
			self.image = cv2.cvtColor(np.array(self.sct.grab(self.mon)),cv2.COLOR_RGBA2RGB)
			self.result = self.tf.return_predict(self.image)
			cv2.imshow("Stream Window",self.image)
			cv2.waitKey(1)
			self.lock.release()
			'''

	def getOption(self,option):
		hp="F:\\AnacondaProjects"
		optionHand={"pbLoad":hp+"\\darkflow-master\\built_graph\\hand180905.pb",
		 "metaLoad":hp+ "\\darkflow-master\\built_graph\\hand180905.meta",
		 "threshold":0.4, "gpu":0.7}
		optionPerson={"pbLoad":hp+"\\darkflow-master\\built_graph\\yolo180905.pb",
		 "metaLoad":hp+ "\\darkflow-master\\built_graph\\yolo180905.meta",
		 "threshold":0.4, "gpu":0.7}
		optionDetect={"pbLoad":hp+"\\darkflow-master\\built_graph\\detect180909.pb",
		 "metaLoad":hp+ "\\darkflow-master\\built_graph\\detect180909.meta",
		 "threshold":0.4, "gpu":0.7}
		tfOptions = {"hand" : optionHand, "person" : optionPerson, "detect": optionDetect}
		return tfOptions[option]

	def preconnect(self):
		self.tf=TFNet(self.getOption(self.option))
		img=cv2.cvtColor(np.array(self.sct.grab(self.mon)),cv2.COLOR_RGBA2RGB)
		self.result = self.tf.return_predict(img)

def main():
	host = '0.0.0.0'
	#port = 5001
	port = 6666
	capHand = VideoCapture("hand")
	capPerson = VideoCapture("person")
	capDetect = VideoCapture("detect")
	print('setting up on capThread.')
	capHand.start()
	capPerson.start()
	capDetect.start()
	print('starting up on capThread.')
	#starting up on capThread.
	sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	server_address = (host, port)
	print('starting up on %s port %s\n' % server_address)
	sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	sock.bind(server_address)
	while(True):
		data, address = sock.recvfrom(4)
		if(data == b'hdg'):
			img,result = capHand.getBuffer()
			dopick = {'image' : img.tobytes(), 'result' : result}
			buffer = pickle.dumps(dopick,protocol=2)
			if buffer is None:
				continue

			if len(buffer) > 65507:
				print(len(buffer))
				print("The message is too large to be sent within a single UDP datagram. We do not handle splitting the message in multiple datagrams")
				sock.sendto(b'FAIL',address)
				continue

			sock.sendto(buffer, address)

		elif(data == b'psg'):
			img,result = capPerson.getBuffer()
			dopick = {'image' : img.tobytes(), 'result' : result}
			buffer = pickle.dumps(dopick,protocol=2)
			if buffer is None:
				continue

			if len(buffer) > 65507:
				print(len(buffer))
				print("The message is too large to be sent within a single UDP datagram. We do not handle splitting the message in multiple datagrams")
				sock.sendto(b'FAIL',address)
				continue

			sock.sendto(buffer, address)

		elif(data == b'dtg'):
			img,result = capDetect.getBuffer()
			dopick = {'image' : img.tobytes(), 'result' : result}
			buffer = pickle.dumps(dopick,protocol=2)
			if buffer is None:
				continue

			if len(buffer) > 65507:
				print(len(buffer))
				print("The message is too large to be sent within a single UDP datagram. We do not handle splitting the message in multiple datagrams")
				sock.sendto(b'FAIL',address)
				continue

			sock.sendto(buffer, address)

		elif(data == b'get'):
			img = capPerson.getImage()
			dopick = {'image' : img.tobytes()}
			buffer = pickle.dumps(dopick,protocol=2)
			if buffer is None:
				continue

			if len(buffer) > 65507:
				print(len(buffer))
				print("The message is too large to be sent within a single UDP datagram. We do not handle splitting the message in multiple datagrams")
				sock.sendto(b'FAIL',address)
				continue

			sock.sendto(buffer, address)

		elif(data == "quit"):
			capHand.stop()
			capPerson.stop()

	print("Bye..")
	#capHand.join()
	capPerson.join()
	sock.close()

if __name__=='__main__':
	main()


'''Practice on double click and DragandDrop methods'''

from selenium import webdriver
from selenium.webdriver.common.alert import Alert
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver import ActionChains
import time

#Launch the Browser
driver = webdriver.Chrome(executable_path=ChromeDriverManager().install())
driver.maximize_window()

#Naviagte the Url
driver.get("http://testautomationpractice.blogspot.com/")

#double click on webelement on ui
double_click = driver.find_element_by_xpath(".//button[text()='Copy Text']")

'''ActionChains are a way to automate low level interactions such as
    mouse movements, mouse button actions, key press, and context menu interactions.
    This is useful for doing more complex actions like hover over and drag and drop.'''
action = ActionChains(driver)
action.double_click(double_click).perform()
print("Double click has sucessfully done")

#navigate the Url for Drag and Drop
driver.get("http://testautomationpractice.blogspot.com/")

#using ActionChains we will perform Drag and Drop
source = driver.find_element_by_id("draggable") #Draggable element
time.sleep(2)
target = driver.find_element_by_id("droppable") #droppable element

#use of new (ACtionChains) action class
action2 = ActionChains(driver)
action2.drag_and_drop(source, target).perform()

time.sleep(2)
driver.quit()


#!/usr/bin/python
# -*-coding:utf-8 -*-
__author__ = '99K'

def solution(A, B, C):
    # write your code in Python 3.6
    a, b, c = sorted([(A,'a'), (B,'b'), (C,'c')], key=lambda x:x[0], reverse=True)
    result = [''] * 310
    for i in range(a[0]):
        if i % 2 == 0:
            result[i*3] = a[1]
        else:
            result[(i-1)*3+1] = a[1]
    for i in range(b[0]):
        if i <= a[0]//2:
            result[i*6+2] = b[1]
        else:
            result[(i-a[0]//2-1)*6+3] = b[1]
    for i in range(b[0], b[0]+c[0]):
        if i <= a[0]//2:
            result[i*6+2] = c[1]
        else:
            result[(i-a[0]//2-1)*6+3] = c[1]
        # if i % 2 == 0:
        #     result[i*3+4] = c[1]
        # else:
        #     result[(i-1)*3+5] = c[1]
    result = ''.join(result)
    cur_letter = a[1]
    cur_cnt = 1
    # print(result)
    for i in range(1, len(result)):
        if cur_letter == result[i]:
            cur_cnt += 1
            if cur_cnt >= 3:
                return result[:i]
        else:
            cur_letter = result[i]
            cur_cnt = 1
    return result

print(solution(3, 30, 3))


# -*- coding: utf-8 -*-
from django import forms
from teacher.models import Classroom, TWork
#from student.models import Work, Enroll
from account.models import Message
from student.models import SWork

# 新增一個課程表單
class ClassroomForm(forms.ModelForm):
        class Meta:
           model = Classroom
           fields = ['name','password']

        def __init__(self, *args, **kwargs):
            super(ClassroomForm, self).__init__(*args, **kwargs)
            self.fields['name'].label = "班級名稱"
            self.fields['password'].label = "選課密碼"

# 新增一個課程表單
class AnnounceForm(forms.ModelForm):
        class Meta:
           model = Message
           fields = ['title','content']

        def __init__(self, *args, **kwargs):
            super(AnnounceForm, self).__init__(*args, **kwargs)
            self.fields['title'].label = "公告主旨"
            self.fields['title'].widget.attrs['size'] = 50
            self.fields['content'].label = "公告內容"
            self.fields['content'].widget.attrs['cols'] = 50
            self.fields['content'].widget.attrs['rows'] = 20

# 新增一個作業
class WorkForm(forms.ModelForm):
        class Meta:
           model = TWork
           fields = ['title']

        def __init__(self, *args, **kwargs):
            super(WorkForm, self).__init__(*args, **kwargs)
            self.fields['title'].label = "作業名稱"

# 作業評分表單
class ScoreForm(forms.ModelForm):
        RELEVANCE_CHOICES = (
            (100, "你好棒(100分)"),
            (90, "90分"),
            (80, "80分"),
            (70, "70分"),
            (60, "60分"),
        )
        score = forms.ChoiceField(choices = RELEVANCE_CHOICES, required=True, label="分數")
        #if user.groups.all()[0].name == 'teacher':
        assistant = forms.BooleanField(required=False,label="小老師")

        class Meta:
           model = SWork
           fields = ['score']

        def __init__(self, user, *args, **kwargs):
            super(ScoreForm, self).__init__(*args, **kwargs)
            if user.groups.all().count() == 0 :
                del self.fields['assistant']


def sumdig(num):
    s = 0
    for i in str(num):
        s += int(i)
    return s

import time
t0 = time.time()
#code here

mxsm = 0;
for a in range(1,101):
    for b in range(1,101):
        tmp = sumdig(a**b);
        if tmp>mxsm:
            mxsm = tmp
print(mxsm)
print('time',time.time()-t0)


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        iter = head
        len = 0
        i = 0

        # Count length
        while(iter):
            iter = iter.next
            len += 1

        if(len == n):
            return head.next

        iter = head
        for i in range(1, len-n):
            iter = iter.next

        iter.next = iter.next.next
        return head


#!/usr/bin/env python3
""" Control de la grabación mediante un BOTON PULSADOR
    en RASPBERRY PI >= 2
"""

import  subprocess  as sp
import  gpiozero
from    time        import sleep
import  threading

#################    OPCIONES DE CONFIGURACION    ######################
# GPIO-03_pin-05 <---> GND_pin-06 (tercera pareja de pines)
BOTON = gpiozero.Button(3)  # GPIO-03

# Opción usando uno de los LED integrados en placa (rojo o verde)
#LED   = 'rojo'

# Opción usando un LED dedicado en un pin GPIO
LED   = gpiozero.LED(15)    # GPIO-15 (quinta pareja de pines)
########################################################################

def loop_boton_gpio(tp=3):
    """ BUCLE INFINITO que lee las pulsaciones del botón de control,
        con un tiempo de persistencia tp por defecto 3 segundos.
    """

    def espera_pulsacion():
        """ Comprueba que el botón esté pulsado durante tp segundos
        """
        c = 0
        while True:
            BOTON.wait_for_press()
            c += 1
            sleep(.5)
            if c >= 2 * tp:
                break

    print('PULSAR BOTON PARA INICIAR/PARAR')

    # BUCLE de lectura
    grabar = False
    while True:
        espera_pulsacion()
        grabar = {True:False, False:True}.get(grabar)
        if grabar:
            iniciar_grabacion()
        else:
            detener_grabacion()

def loop_detecta_jack_capture():
    """ BUCLE INFINITO para la detección del proceso 'jack_capture',
        activando entonces el flag JACK_CAPTURE, y gestionando en
        consecuencia las indicaciones de estado (LED y consola)
    """

    global JACK_CAPTURE

    def display_update(estado):
        """ maneja LED y consola
        """
        modo_led = {'PARADO':'off', 'GRABANDO':'normal', 'PREPARANDO':'rapido'}.get(estado, 'off')
        if TIPO_DE_LED == 'gpio':
            led_gpio_blink(modo_led)
        else:
            # el led integrado tiene un loop propio en threading
            pass

        print(f'---> {estado}')

    st = st_prev = 'PARADO'
    while True:

        if GRABACION_INICIADA:

            try:
                sp.check_output('pgrep -f jack_capture'.split())
                JACK_CAPTURE = True
            except:
                JACK_CAPTURE = False

            if JACK_CAPTURE:

                st = 'GRABANDO'
                if st != st_prev:
                    display_update(st)
                st_prev = st

            else:

                st = 'PREPARANDO'
                if st != st_prev:
                    display_update(st)
                st_prev = st

        else:

            st = 'PARADO'
            if st != st_prev:
                display_update(st)
            st_prev = st

        sleep(1)

def loop_led_integrado():
    """ BUCLE INFINITO que gobierna un led integrado en la placa, en función
        del las variables GRABACION_INICIADA y JACK_CAPTURE lo hace parpadar
        o lo mantiene apagado.

        NOTA: los led de placa no están gestionados por la libreria 'gpiozero',
              por tanto necesitamos este LOOP para hacerlo parpadear.
    """

    def blink(frec='normal'):
        t = {'normal': 1.0, 'rapido': 0.1, 'off': 0}.get(frec)
        if t:
            sp.Popen(f"sudo sh -c 'echo {onoff} > /sys/class/leds/{ledX}/brightness'", shell=True)
            sleep(t)
        else:
            sp.Popen(f"sudo sh -c 'echo 0       > /sys/class/leds/{ledX}/brightness'", shell=True)
            sleep(1)

    # Por defecto .get resolverá el LED 'rojo' de la placa 'led1'
    ledX = {'verde': 'led0', 'rojo': 'led1'}.get(LED, 'led1')

    # BUCLE del parpadeo (OjO el sleep está implementado en la subfunción blink)
    onoff = 0
    while True:

        if GRABACION_INICIADA:
            # Parpadeo normal cuando se detecte jack_capture funcionando
            if JACK_CAPTURE:
                blink('normal')
            else:
                blink('rapido')
        else:
            blink('off')

        onoff = {0:1, 1:0}.get(onoff)

def led_gpio_blink(mode='normal'):
    """ Usado para gestionar un LED dedicado en un pin GPIO
        usando la librería gpiozero
    """

    if mode == 'normal':
        ton = 1.5; toff = 1.0
    elif mode == 'rapido':
        ton = 0.15; toff = 0.15
    else:
        LED.off()
        return

    LED.blink(on_time=ton, off_time=toff)

def iniciar_grabacion():

    global GRABACION_INICIADA

    # Ejecuta script de incio de la grabadora
    sp.Popen("~/bin/grabadora_iniciar.sh", shell=True)
    GRABACION_INICIADA = True

def detener_grabacion():

    global GRABACION_INICIADA

    # Ejecuta script de detención de la grabadora
    sp.Popen("~/bin/grabadora_detener.sh", shell=True)
    GRABACION_INICIADA = False

if __name__ == "__main__":

    # Indicativo del tipo de LED en uso
    TIPO_DE_LED = 'integrado' if (type(LED) == str) else 'gpio'

    # Flags indicativos del estado de la grabadora
    GRABACION_INICIADA = False
    JACK_CAPTURE       = False

    # LOOP de lectura del botón de control
    th_boton = threading.Thread(target = loop_boton_gpio)
    th_boton.start()

    # LOOP que detecta si 'jack_capture' está en ejecución y maneja
    # la visualización al usuario en consecuencia.
    th_jack_capture = threading.Thread(target = loop_detecta_jack_capture)
    th_jack_capture.start()

    # LOOP auxiliar para hacer parpadear un LED integrado en placa
    if TIPO_DE_LED == 'integrado':
        th_led = threading.Thread(target = loop_led_integrado)
        th_led.start()


# -*- coding: utf-8 -*-
"""Tests for list command."""
from datetime import datetime, timedelta
from unittest.mock import patch

import habito
import habito.commands
from tests.commands import HabitoCommandTestCase

class HabitoListCommandTestCase(HabitoCommandTestCase):
    def test_habito_list_lists_off_track_habits(self):
        habit = self.create_habit()
        self.add_summary(habit)
        self._run_command(habito.commands.checkin, ["Habit", "-q -9.1"])

        result = self._run_command(habito.commands.list, ["-l"])

        # Habit is off track with quanta <= goal. Verify 'x'
        assert habit.name in result.output
        assert u"-9.1" in result.output

    def test_habito_list_lists_on_track_habits(self):
        habit = self.create_habit()
        self.add_summary(habit)
        self._run_command(habito.commands.checkin, ["Habit", "-q 9.1"])

        result = self._run_command(habito.commands.list, ["-l"])

        # Habit is on track with quanta >= goal. Verify 'tick'
        assert habit.name in result.output
        assert u"9.1" in result.output

    def test_habito_list_skips_inactive_habits(self):
        habit = self.create_habit()
        self.add_summary(habit)
        self._run_command(habito.commands.checkin, ["Habit", "-q 9.1"])
        habit.active = False
        habit.save()

        result = self._run_command(habito.commands.list, ["-l"])

        # Habit is on track with quanta >= goal. Verify 'tick'
        assert habit.name not in result.output
        assert u"9.1" not in result.output

    def test_habito_list_should_show_streak(self):
        habit = self.create_habit()
        self.add_summary(habit, streak=10)

        result = self._run_command(habito.commands.list)

        assert "10 days" in result.output

    @patch("shutil.get_terminal_size")
    def test_habito_list_table_adapts_to_terminal_width(self, term_mock):
        for terminal_width in range(0, 101, 5):
            term_mock.return_value = (terminal_width, 80)
            nr_of_dates = terminal_width//10 - 4
            result = self._run_command(habito.commands.list, ["-l"])
            if nr_of_dates < 1:
                assert "terminal window is too small" in result.output
                assert result.exit_code == 1
            else:
                assert result.exit_code == 0
                for i in range(nr_of_dates):
                    date_string = "{dt.month}/{dt.day}".format(dt=(datetime.now() - timedelta(days=i)))
                    assert date_string in result.output


from datetime import datetime
from pes import *
import logging
import re
import sqlite3
import os
import sys
import time

def regexp(expr, item):
    reg = re.compile(expr)
    return reg.search(item) is not None

class Record(object):

	def __init__(self, db, table, fields, keyField, keyValue = None, autoIncrement = True, loadData = True, row = None):
		self.__db = db
		self.__autoIncrement = autoIncrement
		self.__table = table
		self.__fields = fields
		self.__keyField = keyField
		self.__keyValue = keyValue
		self.__properties = {}
		self.__properties[self.__keyField] = keyValue
		self.__isDirty = False
		self.__con = None
		self.__dirtyFields = []

		if loadData:
			self.refresh()
			self.__dataLoaded = True
		else:
			if row != None and self.__keyValue != None:
				# check all our fields are present in the record
				keys = row.keys()
				for f in self.__fields:
					if f not in keys:
						raise Exception("Record.init: field \"%s\" not found in row for a \"%s\" record" % (f, self.__table))
					self.__properties[f] = row[f]
				self.__isNew = False
				self.__dataLoaded = True
			else:
				self.__dataLoaded = False

	def connect(self):
		if self.__con:
			return self.__con

		self.__con = sqlite3.connect(self.__db)
		self.__con.create_function("REGEXP", 2, regexp)
		self.__con.row_factory = sqlite3.Row
		self.__cur = self.__con.cursor()
		#logging.debug("connected to %s database, using table %s" % (self.__db, self.__table))
		return self.__con

	@staticmethod
	def convertValue(v):
		isNumeric = False
		try:
			float(v)
			isNumeric = True
		except ValueError:
			pass

		if not isNumeric:
			return '"%s"' % v
		return str(v)

	def dataLoaded(self):
		return self.__dataLoaded

	def disconnect(self):
		if self.__con:
			self.__con.close()
		self.__con = None
		#logging.debug("disconnected from %s database, using table %s" % (self.__db, self.__table))

	def doQuery(self, query):
		if not self.__con:
			raise sqlite3.Error('Database %s not connected' % self.__db)
		logging.debug('Record.doQuery: executing query: %s' % query)
		self.__cur.execute(query)
		return self.__cur

	def getDb(self):
		return self.__db

	def getFieldsAsSql(self, includeTableName=False):
		if not includeTableName:
			return ','.join("`%s`" % f for f in self.__fields)
		fields = []
		for f in self.__fields:
			fields.append("`%s`.`%s`" % (self.__table, f))
		return ','.join(fields)

	def getId(self):
		return self.__properties[self.__keyField]

	def getProperty(self, field):
		if self.__dataLoaded:
			if field in self.__properties:
				return self.__properties[field]
		return None

	def __getWritableFields(self):
		l = []
		for f in self.__fields:
			if f != self.__keyField:
				l.append(f)

		return l

	def isDirty(self):
		return len(self.__dirtyFields) > 0

	def isNew(self):
		return self.__isNew

	def refresh(self):
		self.connect()
		if not self.__con:
			raise sqlite3.Error('Database %s not connected' % self.__db)

		if self.__properties[self.__keyField] != None:
			self.doQuery('SELECT %s FROM `%s` WHERE `%s` = %d;' % (','.join("`%s`" % f for f in self.__fields), self.__table, self.__keyField, self.__properties[self.__keyField]))
			row = self.__cur.fetchone()
			if row == None:
				#raise sqlite3.Error('No record found for field "%s" in table "%s"' % (self.__primaryKey, self.__table)
				self.__isNew = True
				self.__dirtyFields = self.__getWritableFields()
			else:
				for f in self.__fields:
					self.__properties[f] = row[f]
				self.__isNew = False
				self._dirtyFields = []
			self.__dataLoaded = True
		else:
			self.__isNew = True
			self.__dataLoaded = False
		self.disconnect()

	def save(self):
		self.connect()
		if not self.__con:
			raise sqlite3.Error('Database %s not connected' % self.__db)

		query = ''
		if self.__isNew:
			i = 0
			writableFields = None
			if self.__autoIncrement:
				writableFields = self.__getWritableFields()
			else:
				writableFields = self.__fields
			total = len(writableFields)
			query = 'INSERT INTO `%s` (' % self.__table
			endQuery = ''
			for f in writableFields:
				if not f in self.__properties:
					self.__properties[f] = "NULL"
				query += '`%s`' % f
				endQuery += self.convertValue(self.__properties[f])
				if i < total - 1:
					query += ','
					endQuery += ','
				i += 1

			query += ') VALUES (%s);' % endQuery

		else:
			i = 0
			total = len(self.__dirtyFields)
			query = 'UPDATE `%s` SET ' % self.__table
			for f in self.__dirtyFields:
				query += '`%s` = %s' % (f, self.convertValue(self.__properties[f]))
				if i < total - 1:
					query += ','
				i += 1
			query += ' WHERE `%s` = %d;' % (self.__keyField, self.__properties[self.__keyField])

		self.doQuery(query)
		self.__con.commit()
		self.disconnect()

		if self.__isNew:
			self.__isNew = False
			self.__properties[self.__keyField] = self.__cur.lastrowid
		self.__dirtyFields = []

	def setProperty(self, field, value):
		self.__properties[field] = value
		if not field in self.__dirtyFields:
			self.__dirtyFields.append(field)

class AchievementUser(Record):

	def __init__(self, db, userId):
		super(AchievementUser, self).__init__(db, 'achievements_user', ['user_id', 'user_name', 'rank', 'total_points'], 'user_id', userId)

	def getGame(self, gameId):
		self.connect()
		cur = self.doQuery('SELECT (SELECT COUNT(*) FROM `achievements_earned`, `achievements_badges` WHERE `achievements_badges`.`game_id` = %d AND `achievements_earned`.`user_id` = %d AND `achievements_badges`.`badge_id` = `achievements_earned`.`badge_id`) AS `totalEarned`, (SELECT SUM(`points`) FROM `achievements_earned`, `achievements_badges` WHERE `achievements_badges`.`game_id` = %d AND `achievements_earned`.`user_id` = %d AND `achievements_badges`.`badge_id` = `achievements_earned`.`badge_id`) AS `totalPoints` FROM `achievements_games` WHERE `achievements_games`.`game_id` = %d ;' % (gameId, self.getId(), gameId, self.getId(), gameId))
		row = cur.fetchone()
		if row == None:
			self.disconnect()
			return None
		totalPoints = 0
		if row['totalPoints']:
			totalPoints = int(row['totalPoints'])
		self.disconnect()
		return AchievementGame(self.getDb(), self.getId(), gameId, int(row['totalEarned']), totalPoints)

	def getGames(self):
		self.connect()
		cur = self.doQuery('SELECT `achievements_games`.`game_id`, (SELECT COUNT(*) FROM `achievements_earned`, `achievements_badges` WHERE `achievements_badges`.`game_id` = `achievements_games`.`game_id` AND `achievements_earned`.`user_id` = %d AND `achievements_badges`.`badge_id` = `achievements_earned`.`badge_id`) AS `totalEarned`, (SELECT SUM(`points`) FROM `achievements_earned`, `achievements_badges` WHERE `achievements_badges`.`game_id` = `achievements_games`.`game_id` AND `achievements_earned`.`user_id` = %d AND `achievements_badges`.`badge_id` = `achievements_earned`.`badge_id`) AS `totalPoints` FROM `achievements_games`;' % (self.getId(), self.getId()))
		games = []
		while True:
			row = cur.fetchone()
			if row == None:
				break
			totalPoints = 0
			if row['totalPoints']:
				totalPoints = int(row['totalPoints'])
			games.append(AchievementGame(self.getDb(), self.getId(), int(row['game_id']), int(row['totalEarned']), totalPoints))
		self.disconnect()
		return games

	def getName(self):
		return self.getProperty('user_name')

	def getRank(self):
		return int(self.getProperty('rank'))

	def getRecentBadges(self, count):
		self.connect()
		cur = self.doQuery('SELECT `achievements_badges`.`badge_id`, `date_earned`, `date_earned_hardcore`, MAX(`date_earned`, `date_earned_hardcore`) AS `date_ts` FROM `achievements_earned`, `achievements_badges` WHERE `achievements_earned`.`badge_id` = `achievements_badges`.`badge_id` AND `user_id` = %d ORDER BY `date_ts` DESC LIMIT 0,%d;' % (self.getProperty('user_id'), count))
		badges = []
		while True:
			row = cur.fetchone()
			if row == None:
				break
			badges.append(Badge(self.getDb(), int(row['badge_id']), int(row['date_earned']), int(row['date_earned_hardcore'])))
		self.disconnect()
		return badges

	def getTotalPoints(self):
		return int(self.getProperty('total_points'))

	def setName(self, name):
		self.setProperty('user_name', name)

	def setTotalPoints(self, points):
		self.setProperty('total_points', int(points))

class AchievementGame(Record):

	def __init__(self, db, userId, gameId, userEarnedTotal=0, userPointsTotal=0):
		super(AchievementGame, self).__init__(db, 'achievements_games', ['game_id', 'console_id', 'achievement_total', 'score_total'], 'game_id', gameId)
		self.__userEarnedTotal = userEarnedTotal
		self.__userPointsTotal = userPointsTotal
		self.__consoleName = None
		self.__userId = userId
		self.__badges = None
		self.__gameId = None
		self.__name = None

	def getAchievementTotal(self):
		return self.getProperty('achievement_total')

	def getConsoleId(self):
		return self.getProperty('console_id')

	def getConsoleName(self):
		if not self.__consoleName:
			self.connect()
			cur = self.doQuery('SELECT `name` FROM `consoles` WHERE `achievement_api_id` = %s' % self.getProperty('console_id'))
			if cur.rowcount == 0:
				raise Exception("Could not find corresponding console for game %s" % self.getId())
			row = cur.fetchone()
			self.__consoleName = row['name']
			self.disconnect()
		return self.__consoleName

	def getBadges(self):
		if self.__badges == None:
			self.connect()
			cur = self.doQuery('SELECT `badge_id`, (SELECT `date_earned` FROM `achievements_earned` WHERE `achievements_badges`.`badge_id` = `achievements_earned`.`badge_id` AND `achievements_earned`.`user_id` = %d) As `date_earned`, (SELECT `date_earned_hardcore` FROM `achievements_earned` WHERE `achievements_badges`.`badge_id` = `achievements_earned`.`badge_id` AND `achievements_earned`.`user_id` = %d) As `date_earned_hardcore` FROM `achievements_badges` WHERE `game_id` = %d ORDER BY `title`;' % (self.__userId, self.__userId, self.getId()))
			self.__badges = []
			while True:
				row = cur.fetchone()
				if row == None:
					break
				dateEarned = None
				dateEarnedHardcore = None
				if row['date_earned']:
					dateEarned = int(row['date_earned'])
				if row['date_earned_hardcore']:
					dateEarnedHardcore = int(row['date_earned_hardcore'])
				self.__badges.append(Badge(self.getDb(), int(row['badge_id']), dateEarned, dateEarnedHardcore))
			self.disconnect()
		return self.__badges

	def getGameId(self):
		# attempt to find the corresponding game
		if self.__gameId == None:
			self.connect()
			name = self.getName().replace("'", "''")
			cur = self.doQuery('SELECT `game_id` FROM `games`, `consoles` WHERE `games`.`console_id` = `consoles`.`console_id` AND `consoles`.`achievement_api_id` = "%d" AND `games`.`achievement_api_id` = %d LIMIT 0,1;' % (self.getConsoleId(), self.getId()))
			row = cur.fetchone()
			if row == None:
				return None
			self.__gameId = int(row['game_id'])
			self.disconnect()
		return self.__gameId

	def getName(self):
		if self.__name == None:
			self.connect()
			cur = self.doQuery('SELECT `name` FROM `games` WHERE `achievement_api_id` = %d;' % self.getId())
			row = cur.fetchone()
			if row == None:
				return None
			self.disconnect()
			self.__name = row['name']
		return self.__name

	def getPercentComplete(self):
		return (float(self.__userEarnedTotal) / float(self.getAchievementTotal())) * 100.0

	def getScoreTotal(self):
		return self.getProperty('score_total')

	def getUserEarnedTotal(self):
		return self.__userEarnedTotal

	def getUserPointsTotal(self):
		return self.__userPointsTotal

class Badge(Record):
	def __init__(self, db, badgeId, dateEarned=None, dateEarnedHardcore=None):
		super(Badge, self).__init__(db, 'achievements_badges', ['badge_id', 'title', 'game_id', 'description', 'points', 'badge_path', 'badge_locked_path'], 'badge_id', badgeId, True)
		self.__dateEarned = dateEarned
		self.__dateEarnedHardcore = dateEarnedHardcore
		if self.__dateEarned or self.__dateEarnedHardcore:
			self.__isLocked = False
		else:
			self.__isLocked = True
		logging.debug("Badge.init: created badge with title: \"%s\"" % self.getTitle())

	def getDateEarned(self, hardcore=False, fmt=None):
		d = self.__dateEarned
		if hardcore:
			d = self.__dateEarnedHardcore
		if d == None or d == 0:
			return None
		timestamp = int(d)
		if timestamp == -1:
			return None
		if fmt == None:
			return timestamp
		return datetime.fromtimestamp(timestamp).strftime(fmt)

	def getDescription(self):
		return self.getProperty('description')

	def getGameId(self):
		return self.getProperty('game_id')

	def getPath(self):
		if self.__isLocked:
			return self.getProperty('badge_locked_path')
		return self.getProperty('badge_path')

	def getPoints(self):
		return self.getProperty('points')

	def getTitle(self):
		return self.getProperty('title')

	def isLocked(self):
		return self.__isLocked

	def setDateEarned(self, earned, hardcore=False):
		if hardcore:
			self.__dateEarnedHardcore = earned
		else:
			self.__dateEarned = earned
		if earned:
			self.__locked = False
		else:
			self.__locked = True

class Console(Record):

	def __init__(self, name, consoleId, thegamesdbApiId, extensions, romDir, command, db, consoleImg, noCoverArtImg, imgCacheDir, emulator):
		super(Console, self).__init__(db, 'consoles', ['console_id', 'name', 'thegamesdb_api_id', 'achievement_api_id'], 'console_id', consoleId, True)
		self.setProperty('name', name)
		self.setProperty('thegamesdb_api_id', thegamesdbApiId)
		self.__extensions = extensions
		self.__romDir = romDir
		self.__consoleImg = consoleImg
		self.__noCoverArtImg = noCoverArtImg
		self.__emulator = emulator
		self.__games = None
		self.__command = command
		self.__imgCacheDir = imgCacheDir
		self.__gameTotal = None
		self.__ignoreRoms = []
		self.__gameDict = {}
		self.__requiredFiles = []

	def addIgnoreRom(self, rom):
		if rom not in self.__ignoreRoms:
			self.__ignoreRoms.append(rom)

	def addRequiredFile(self, f):
		if f not in self.__requiredFiles:
			self.__requiredFiles.append(f)
			logging.debug("Console.addRequiredFile: added %s for console %s" % (f, self.getName()))

	def getAchievementApiId(self):
		return self.getProperty('achievement_api_id')

	def getCommand(self, game):
		return self.__command.replace('%%GAME%%', "\"%s\"" % game.getPath()).replace('%%USERCONFDIR%%', userConfDir)

	def getDir(self):
		return self.__dir

	def getEmulator(self):
		return self.__emulator

	def getGame(self, i):
		return self.__gameDict[i]

	def getGames(self, limit=0, count=0, refeshGames=False):
		if self.__games == None or refeshGames:
			self.__gameDict = {}
			self.connect()
			#query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d ORDER BY UPPER(`name`)' % self.getId()
			query = 'SELECT * FROM `games` WHERE `console_id` = %d ORDER BY UPPER(`name`)' % self.getId()
			if limit >= 0 and count > 0:
				query += ' LIMIT %d, %d' % (limit, count)
			query += ';'
			cur = self.doQuery(query)
			self.__games = []
			while True:
				row = cur.fetchone()
				if row == None:
					break
				g = Game(row['game_id'], self.getDb(), self, False, row)
				self.__gameDict[int(row['game_id'])] = g
				self.__games.append(g)
			self.disconnect()
		return self.__games

	def getGameTotal(self):
		if self.__gameTotal == None:
			self.connect()
			cur = self.doQuery('SELECT COUNT(`game_id`) AS `total` FROM `games` WHERE `console_id` = %d;' % self.getId())
			row = cur.fetchone()
			self.disconnect()
			self.__gameTotal = row['total']
		return self.__gameTotal

	def getGamesWithAchievements(self):
		self.connect()
		games = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d AND `achievement_api_id` > 0 AND (SELECT COUNT(*) FROM `achievements_badges` WHERE `game_id` = `achievement_api_id`) > 0 ORDER BY UPPER(`name`)' % self.getId()
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			games.append(Game(row['game_id'], self.getDb(), self))
		self.disconnect()
		return games

	def getGamesWithAchievementIds(self):
		self.connect()
		games = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d AND `achievement_api_id` > 0 AND (SELECT COUNT(*) FROM `achievements_badges` WHERE `game_id` = `achievement_api_id`) > 0 ORDER BY UPPER(`name`)' % self.getId()
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			games.append(row['game_id'])
		self.disconnect()
		return games

	def getExtensions(self):
		return self.__extensions

	def getFavourites(self, limit=0, count=0):
		self.connect()
		favourites = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d AND `favourite` = 1 ORDER BY UPPER(`name`)' % self.getId()
		if limit >= 0 and count > 0:
			query += ' LIMIT %d, %d' % (limit, count)
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			favourites.append(Game(row['game_id'], self.getDb(), self))
		self.disconnect()
		return favourites

	def getFavouriteIds(self, limit=0, count=0):
		self.connect()
		favourites = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d AND `favourite` = 1 ORDER BY UPPER(`name`)' % self.getId()
		if limit >= 0 and count > 0:
			query += ' LIMIT %d, %d' % (limit, count)
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			favourites.append(row['game_id'])
		self.disconnect()
		return favourites

	def getFavouriteTotal(self):
		self.connect()
		cur = self.doQuery('SELECT COUNT(`game_id`) AS `total` FROM `games` WHERE `favourite` = 1 AND `console_id` = %d;' % self.getId())
		row = cur.fetchone()
		self.disconnect()
		return row['total']

	def getImgCacheDir(self):
		return self.__imgCacheDir

	def getImg(self):
		return self.__consoleImg

	def getName(self):
		return self.getProperty('name')

	def getNoCoverArtImg(self):
		return self.__noCoverArtImg

	def getMostPlayedGames(self, limit=0, count=0):
		self.connect()
		mostPlayed = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d AND `play_count` > 0 ORDER BY `play_count` DESC' % self.getId()
		if limit >= 0 and count > 0:
			query += ' LIMIT %d, %d' % (limit, count)
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			mostPlayed.append(Game(row['game_id'], self.getDb(), self))
		self.disconnect()
		return mostPlayed

	def getMostPlayedGameIds(self, limit=0, count=0):
		self.connect()
		mostPlayed = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d AND `play_count` > 0 ORDER BY `play_count` DESC' % self.getId()
		if limit >= 0 and count > 0:
			query += ' LIMIT %d, %d' % (limit, count)
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			mostPlayed.append(row['game_id'])
		self.disconnect()
		return mostPlayed

	def getRecentlyAddedGames(self, limit=0, count=0):
		self.connect()
		recentlyAdded = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d ORDER BY `added`, UPPER(`name`)' % self.getId()
		if limit >= 0 and count > 0:
			query += ' LIMIT %d, %d' % (limit, count)
		query += ';'
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			recentlyAdded.append(Game(row['game_id'], self.getDb(), self))
		self.disconnect()
		return recentlyAdded

	def getRecentlyAddedGameIds(self, limit=0, count=0):
		self.connect()
		recentlyAdded = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d ORDER BY `added`, UPPER(`name`)' % self.getId()
		if limit >= 0 and count > 0:
			query += ' LIMIT %d, %d' % (limit, count)
		query += ';'
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			recentlyAdded.append(row['game_id'])
		self.disconnect()
		return recentlyAdded

	def getRecentlyPlayedGames(self, limit=0, count=0):
		self.connect()
		recentlyPlayed = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d AND `last_played` > -1 ORDER BY `last_played`' % self.getId()
		if limit >= 0 and count > 0:
			query += ' LIMIT %d, %d' % (limit, count)
		query += ';'
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			recentlyPlayed.append(Game(row['game_id'], self.getDb(), self))
		self.disconnect()
		return recentlyPlayed

	def getRecentlyPlayedGameIds(self, limit=0, count=0):
		self.connect()
		recentlyPlayed = []
		query = 'SELECT `game_id` FROM `games` WHERE `console_id` = %d AND `last_played` > -1 ORDER BY `last_played`' % self.getId()
		if limit >= 0 and count > 0:
			query += ' LIMIT %d, %d' % (limit, count)
		query += ';'
		cur = self.doQuery(query)
		while True:
			row = cur.fetchone()
			if row == None:
				break
			recentlyPlayed.append(row['game_id'])
		self.disconnect()
		return recentlyPlayed

	def getRequiredFiles(self):
		return self.__requiredFiles

	def getRomDir(self):
		return self.__romDir

	def getTheGamesDbApiId(self):
		return self.getProperty('thegamesdb_api_id')

	def ignoreRom(self, rom):
		return rom in self.__ignoreRoms

	def refresh(self):
		super(Console, self).refresh()
		self.__gameTotal = None
		self.__games = None

	def searchForGames(self, regexpStr):
		#regexpStr = regexpStr.replace('.', '\.')
		games = []
		self.connect()
		cur = self.doQuery('SELECT `game_id`, `name` FROM `games` WHERE `console_id` = %d AND `name` REGEXP "%s" ORDER BY UPPER(`name`)' % (self.getId(), regexpStr))
		while True:
			row = cur.fetchone()
			if row == None:
				break
			games.append((row['game_id'], row['name']))
		self.disconnect()
		return games

	def setAchievementApiId(self, apiId):
		self.setProperty('achievement_api_id', apiId)

class Game(Record):

	def __init__(self, gameId, db, console, loadData=True, row=None):
		super(Game, self).__init__(db, 'games', ['thegamesdb_id', 'exists', 'console_id', 'name', 'cover_art', 'game_path', 'overview', 'released', 'last_played', 'favourite', 'play_count', 'size', 'rasum', 'achievement_api_id'], 'game_id', int(gameId), True, loadData, row)
		self.__console = console

	def getAchievementApiId(self):
		return self.getProperty('achievement_api_id')

	def getCommand(self):
		return self.__console.getCommand(self)

	def getConsole(self):
		return self.__console

	def getConsoleId(self):
		return self.getProperty('console_id')

	def getCoverArt(self):
		coverArt = self.getProperty('cover_art')
		if coverArt == '0':
			return None
		if not os.path.exists(coverArt):
			logging.warning('cover art %s does not exist!' % coverArt)
			return None
		return coverArt

	def getLastPlayed(self, fmt=None):
		timestamp = int(self.getProperty('last_played'))
		if timestamp == -1:
			return None
		if fmt == None:
			return timestamp
		return datetime.fromtimestamp(timestamp).strftime(fmt)

	def getName(self):
		return self.getProperty('name')

	def getOverview(self):
		return self.getProperty('overview')

	def getPath(self):
		return self.getProperty('game_path')

	def getPlayCount(self):
		return self.getProperty('play_count')

	def getReleased(self, fmt=None):
		timestamp = self.getProperty('released')
		if fmt == None:
			return timestamp
		return datetime.fromtimestamp(timestamp).strftime(fmt)

	def getSize(self, humanReadable=False):
		if not humanReadable:
			return self.getProperty('size')
		size = self.getProperty('size')
		if size < 1024:
			return "%diB"
		if size < 1048576:
			return "%.1fKiB" % (size / 1024.0)
		if size < 1073741824:
			return "%.1fMiB" % (size / 1048576.0)
		return "%.1fGiB" % (size / 1073741824.0)

	def hasAchievements(self):
		apiId = self.getAchievementApiId()
		if apiId <= 0:
			return False
		self.connect()
		cur = self.doQuery('SELECT `achievement_total` FROM `achievements_games` WHERE `game_id` = %d;' % apiId)
		row = cur.fetchone()
		if row != None:
			return int(row['achievement_total']) > 0
		self.disconnect()
		return False

	def isFavourite(self, yesNoMap=None):
		fav = self.getProperty('favourite') == 1
		if yesNoMap == None:
			return fav
		if fav:
			return yesNoMap[0]
		return yesNoMap[1]

	def setConsoleId(self, consoleId):
		self.setProperty('console_id', consoleId)

	def setCoverArt(self, path):
		self.setProperty('game_path', path)

	def setFavourite(self, fav):
		if fav:
			self.setProperty('favourite', 1)
		else:
			self.setProperty('favourite', 0)

	def setLastPlayed(self, date=None):
		if date == None:
			# use current date/time
			date = int(time.time())
		self.setProperty('last_played', date)

	def setName(self, name):
		self.setProperty('name', name)

	def setOverview(self, overview):
		self.setProperty('overview', overview)

	def setReleased(self, released):
		self.setProperty('released', released)

	def setPath(self, path):
		self.setProperty('game_path', path)

	def setPlayCount(self, x=None):
		if x == None:
			x = self.getPlayCount() + 1
		self.setProperty('play_count', x)

	def setSize(self, s):
		self.setProperty('size')


import collections
from collections.abc import Iterable  # pylint: disable=g-importing-member
import itertools
import warnings

import jax
from jax import core
from jax import lax
from jax.extend import linear_util as lu
from jax.interpreters import partial_eval as pe
import jax.numpy as jnp
import numpy as np

def _pmap_device_order():
  return jax.local_devices()

def replicate(tree, devices=None):
  """Replicates arrays to multiple devices.

  Args:
    tree: a pytree containing the arrays that should be replicated.
    devices: the devices the data is replicated to
      (default: same order as expected by `jax.pmap()`).
  Returns:
    A new pytree containing the replicated arrays.
  """
  devices = devices or _pmap_device_order()
  return jax.device_put_replicated(tree, devices)

def unreplicate(tree):
  """Returns a single instance of a replicated array."""
  return jax.tree_util.tree_map(lambda x: x[0], tree)

def pmean(xs, axis_name):
  warnings.warn("use jax.lax.pmean instead", DeprecationWarning)
  return lax.pmean(xs, axis_name)

def partial_eval_by_shape(fn, input_spec, *args, **kwargs):
  """Lazily evaluate a function by using the shapes of the inputs.

  This function is similar to `jax.eval_shape` with the key difference that
  function outputs that can be computed without a concrete value of the
  inputs are returned as is instead of only the shape. See for example
  `module.init_by_shape` where this functionality is used to initialize a
  model without using input data lr computation.

  Args:
    fn: the function to be lazily evaluated.
    input_spec: an iterable of shapes or (shape, dtype) tuples specifying the
      shape and type of the inputs. If unspecified the dtype is float32.
    *args: other arguments passed to the module's apply function
    **kwargs: keyword arguments passed to the module's apply function
  Returns:
    A pair consisting of the model output and an instance of Model
  """
  # output cannot be returned in lazy_create because jax.eval_shape will only
  # return the shape and dtype.
  # TODO(mattjj,jheek): use a public JAX API
  f = lambda *inputs: fn(*inputs, *args, **kwargs)
  input_structs = [_parse_spec(spec) for spec in input_spec]
  inputs_flat, in_tree = jax.tree_util.tree_flatten(input_structs)
  f_flat, out_tree = jax.api_util.flatten_fun_nokwargs(lu.wrap_init(f), in_tree)
  in_pvals = [
      pe.PartialVal.unknown(core.ShapedArray(x.shape, x.dtype))
      for x in inputs_flat
  ]
  _, out_pvals, _ = pe.trace_to_jaxpr_nounits(f_flat, in_pvals)
  out_flat = [
      const if pv is None else jax.ShapeDtypeStruct(pv.shape, pv.dtype)
      for pv, const in out_pvals
  ]
  return jax.tree_util.tree_unflatten(out_tree(), out_flat)

def _parse_spec(spec):
  """Parse an input spec of the form (shape, dtype) or shape into a jax.ShapeDtypeStruct."""
  spec = tuple(spec)
  if len(spec) == 2 and isinstance(spec[0], Iterable):
    return jax.ShapeDtypeStruct(tuple(spec[0]), spec[1])
  else:
    return jax.ShapeDtypeStruct(spec, jnp.float32)

def prefetch_to_device(iterator, size, devices=None):
  """Shard and prefetch batches on device.

  This utility takes an iterator and returns a new iterator which fills an on
  device prefetch buffer. Eager prefetching can improve the performance of
  training loops significantly by overlapping compute and data transfer.

  This utility is mostly useful for GPUs, for TPUs and CPUs it should not be
  necessary -- the TPU & CPU memory allocators (normally) don't pick a memory
  location that isn't free yet so they don't block. Instead those allocators OOM.

  Args:
    iterator: an iterator that yields a pytree of ndarrays where the first
      dimension is sharded across devices.

    size: the size of the prefetch buffer.

      If you're training on GPUs, 2 is generally the best choice because this
      guarantees that you can overlap a training step on GPU with a data
      prefetch step on CPU.

    devices: the list of devices to which the arrays should be prefetched.

      Defaults to the order of devices expected by `jax.pmap`.

  Yields:
    The original items from the iterator where each ndarray is now sharded to
    the specified devices.
  """
  queue = collections.deque()
  devices = _pmap_device_order() if devices is None else devices

  def _prefetch(xs):
    return jax.device_put_sharded(list(xs), devices)

  def enqueue(n):  # Enqueues *up to* `n` elements from the iterator.
    for data in itertools.islice(iterator, n):
      queue.append(jax.tree_util.tree_map(_prefetch, data))

  enqueue(size)  # Fill up the buffer.
  while queue:
    yield queue.popleft()
    enqueue(1)

def _scan_nd(body_fn, init, xs, n=1, unroll=(1,)):
  """Utility for performing an n-dimensional `lax.scan`.

  The n-d scan is simply recursive call of 1-d scan.
  Args:
    body_fn: the body of the loop of type (c, x) -> (c, y).
    init: initial value for the carry.
    xs: a pytree of tensors to scan over.
    n: number of dimensions to scan over (default: 1)
  Returns:
    A tuple of the final carry and the values returned by the body.
  """
  if n == 1:
    return lax.scan(body_fn, init, xs, unroll=unroll[0])
  else:

    def scan_body(c, x):
      return _scan_nd(body_fn, c, x, n=n - 1, unroll=unroll[1:])

    return lax.scan(scan_body, init, xs, unroll=unroll[0])

def _invert_perm(perm):
  perm_inv = [0] * len(perm)
  for i, j in enumerate(perm):
    perm_inv[j] = i
  return tuple(perm_inv)

def scan_in_dim(body_fn, init, xs, axis=(0,), unroll=(1,), keepdims=False):
  """utility for doing a scan along arbitrary dimensions.

  See `lax.scan` for details on how the scan operation works.

  Note on `unroll`: This argument gets left padded with ones to match the size
  of `axis`. Doing so allows unrolls to performed from the innermost loop first.
  For example, `scan_in_dim(..., axis=(1, 2, 3), unroll=5)` is equivalent to
  `scan_in_dim(..., axis=(1, 2, 3), unroll=(1, 1, 5))`.

  Args:
    body_fn: the body of the loop of type (c, x) -> (c, y).
    init: initial value for the carry.
    xs: a pytree of tensors to scan over.
    axis: the axis to scan over.
    keepdims: keep the dimensions that are scanned over.
    unroll: an optional positive integer, or tuple of positive integers
      showing how many iterations of the loop to be unrolled into a single
      iteration for each axis.
  Returns:
    A tuple of the final carry and the values returned by the body.
  """
  if not isinstance(axis, Iterable):
    axis = (axis,)

  if not isinstance(unroll, Iterable):
    unroll = (unroll,)

  # Pad unroll with ones so we start unrolling from the innermost loop
  len_diff = len(axis) - len(unroll)
  unroll = (1,) * len_diff + unroll

  def transpose_in(x):
    perm = axis + tuple(np.delete(np.arange(x.ndim), axis))
    return x.transpose(perm)

  def transpose_out(x):
    perm = axis + tuple(np.delete(np.arange(x.ndim), axis))
    return x.transpose(_invert_perm(perm))

  def body_wrapper(c, xs):
    if keepdims:
      xs = jax.tree_util.tree_map(
          lambda x: x.reshape((1,) * len(axis) + x.shape), xs
      )
      xs = jax.tree_util.tree_map(transpose_out, xs)
    c, ys = body_fn(c, xs)
    if keepdims:
      ys = jax.tree_util.tree_map(transpose_in, ys)
      ys = jax.tree_util.tree_map(lambda x: x.reshape(x.shape[len(axis) :]), ys)
    return c, ys

  xs = jax.tree_util.tree_map(transpose_in, xs)
  c, ys = _scan_nd(body_wrapper, init, xs, n=len(axis), unroll=unroll)
  ys = jax.tree_util.tree_map(transpose_out, ys)
  return c, ys

# Copied from https://github.com/google-research/big_vision
def pad_shard_unpad(
    wrapped, static_argnums=(0,), static_argnames=(), static_return=False
):
  """Wraps a function with code that pads, shards, then un-shards, un-pads.

  Args:
    wrapped: the function to be wrapped. Signature is `params, *args, *kwargs`.
    static_argnums: indices of arguments to `wrapped` that should _not_ be
      padded and sharded, but instead be forwarded as-is. The default is (0,)
      because by far the most common use-case is to pass `params` first.
    static_argnames: names of kwargs to `wrapped` that should _not_ be padded
      and sharded, but instead be forwarded as-is.
    static_return: whether not to un-shard, and un-pad the return value; static
      return values are typically used with eval steps that compute metrics

  Returns:
    A new function that pads and shards its arguments before passing them to
    the wrapped function, and un-shards and un-pads the returned pytree.

    This is useful for calling a pmap'ed function with inputs that aren't
    divisible by the number of devices. A typical use is:
      @pad_shard_unpad
      @jax.pmap
      def forward(params, x): ...

  Notes:
    The padding is done in host-memory before being passed to the function, and
    the values returned by the function are transferred back to host memory.

    The returned function is augmented with a new keyword-only argument
    `min_device_batch` that, if specified, forces padding inputs to at least
    this size per device. This can be useful to avoid recompiles for the last
    batch and reduce memory fragmentation.

    For more information refer to https://flax.readthedocs.io/en/latest/guides/full_eval.html
  """

  def pad_shard_unpad_wrapper(*args, min_device_batch=None, **kw):
    d = jax.local_device_count()  # d = devices, b = batch
    batch_sizes = set()
    for i, a in enumerate(args):
      if i not in static_argnums:
        batch_sizes |= {t.shape[0] for t in jax.tree_util.tree_leaves(a)}
    for k, v in kw.items():
      if k not in static_argnames:
        batch_sizes |= {t.shape[0] for t in jax.tree_util.tree_leaves(v)}
    assert len(batch_sizes) == 1, f"Inconsistent batch-sizes: {batch_sizes}"
    b = batch_sizes.pop()

    def pad(x):
      _, *shape = x.shape
      db, rest = divmod(b, d)
      if rest:
        x = np.concatenate([x, np.zeros((d - rest, *shape), x.dtype)], axis=0)
        db += 1
      if min_device_batch and db < min_device_batch:
        x = np.concatenate(
            [x, np.zeros((d * (min_device_batch - db), *shape), x.dtype)]
        )
        db = min_device_batch
      return x.reshape(d, db, *shape)

    def maybe_pad(tree, actually_pad=True):
      if not actually_pad:
        return tree  # For call-site convenience below.
      return jax.tree_util.tree_map(pad, tree)

    args = [maybe_pad(a, i not in static_argnums) for i, a in enumerate(args)]
    kw = {k: maybe_pad(v, k not in static_argnames) for k, v in kw.items()}
    out = wrapped(*args, **kw)

    def unpad(x):
      # Transfer back before cutting, to reduce on-device shape diversity.
      return jax.device_get(x).reshape([np.prod(x.shape[:2]), *x.shape[2:]])[:b]

    return out if static_return else jax.tree_util.tree_map(unpad, out)

  return pad_shard_unpad_wrapper


def winnable(arr):
    index = 1
    step = arr[0]
    path = [0]

    if len(arr) < 2:
        return []
    if step >= len(arr):
        return [0]

    for elem in arr[1:-1]:
        if step == 0:
            return []
        if index == len(arr):
            return []
        if elem > step:
            path.append(index)
            index += 1
            step = elem
            if step > (len(arr[index:-1])+1):
                return path
        else:
            step -= 1
            index += 1


import asyncio
import urllib.request
import os
def download(url,file):
    #f = open(file,'wb')
    urllib.request.urlretrieve(url,file)
    #f.close()

def url_gen(url,start=1):
    url_root = url[:url.find('segment')]
    i = start
    while True:
        yield url_root+f'segment{i}.ts'
        i+=1

def segments_gen(url,path,start=1):
    url_root = url[:url.find('segment')]
    i = start
    while True:
        yield (url_root+f'segment{i}.ts',os.path.join(path,f'{i}.ts'))
        i+=1

def download_segments(url,path,start=1):
    url_generator = url_gen(url,start)
    i=start
    try:

        for each in url_generator:
            download(each, os.path.join(path,f'{i}.ts'))
            i+=1
    except urllib.request.HTTPError as e:
        return [n for n in range(start, i)]

def download_segments_parallel(url,path,workers=4,start=1):
    from concurrent.futures import ThreadPoolExecutor
    executor = ThreadPoolExecutor(max_workers=workers)
    for current_url,name in segments_gen(url,path,start):
        #print(current_url,name)
        try:
            result = executor.submit(download,current_url,name)
            result.result()
        except urllib.request.HTTPError as e:
            return

async def download_segments_parallel2(url,path,start=1):
    import aiohttp
    import aiofiles
    async with aiohttp.ClientSession() as session:
        for current_url, name in segments_gen(url,path,start):
            async with session.get(current_url) as resp:
                if resp.status == 200:
                    f = await aiofiles.open(name, mode='wb')
                    await f.write(await resp.read())
                    await f.close()
                elif resp.status == 404:
                    return

def download_segments_parallel_main(url,path,start):
    loop = asyncio.get_event_loop()
    results = loop.run_until_complete(download_segments_parallel2(url,path,start))


import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
r=bin(255)
dac = [10, 9, 11, 5, 6, 13, 19, 26]
number = [int(j) for j in r[2::]]
p = number[::-1]
if len(number)!=8:
    for k in range(8-len(number)):
        p.append(0)
    GPIO.setup(dac, GPIO.OUT)
    l=len(dac)
    for i in range(8):
        GPIO.output(dac[i], p[i])
    time.sleep(15)
    GPIO.output(dac, 0)
    GPIO.clenup()
if len(number)==8:
    GPIO.setup(dac, GPIO.OUT)
    l=len(dac)
    for i in range(8):
        GPIO.output(dac[i], p[i])
    time.sleep(15)
    GPIO.output(dac, 0)
    GPIO.clenup()
print(p)


import network
import urls
import extractors

from extractors import ContentExtractor
from configuration import Configuration

class ArticleDownloadState(object):
    NOT_STARTED = 0
    FAILED_RESPONSE = 1
    SUCCESS = 2

class Article(object):

    def __init__(self, url, title = '',config=None):
        self.config = config or Configuration()
        self.url = urls.prepare_url(url)
        self.html = ''
        self.extractor = ContentExtractor(self)
        self.title = title
        self.imgs = self.images = []
        self.top_img = self.top_image = ''
        self.doc = None

    def download(self, input_html=None):
        if input_html is None:
            html = network.get_html(self.url)
        self.html = html

    def parse(self):
        self.doc = self.config.get_parser().fromstring(self.html)

        self.title = self.extractor.get_title(self.doc)

    #     self.fetch_images()

    # def fetch_images(self):
    #     imgs = self.extractor.get_img_urls(self.doc)
        # imgs = self.extractor.get_img_urls(self.html)


#!/usr/bin/env python3

import socket

target = input('Enter the IP address to scan: ')
port_range = input('Enter the port range to scan: ') # ex.range(5-200)

startport = int(port_range.split('-')[0])
endport = int(port_range.split('-')[1])

print('Scanning host', target, 'from port', startport, 'to port', endport)

for port in range(startport,endport):
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	status = s.connect_ex((target, port))
	if (status == 0):
		print('*** Port', port,'- OPEN ***')
	else:
		print('Port', port,'- CLOSED')
	s.close()


'''
Given a piece of text, create a histogram of letter pairs (order from high to low). For
instance, for the text, “this is a good thing”,
the letter pairs are: th, hi, is, is, go, oo, od, th, hi, in, and ng. (ignore a)
The histogram will be:
th: 2, is: 2, hi: 2 go: 1, oo: 1, od: 1, in: 1, ng: 1

Sample Input/Output:

Enter text: this is a good thing
Histogram: th: 2, is: 2, hi: 2 go: 1, oo: 1, od: 1, in: 1, ng: 1
Enter text: coooooool
Histogram: oo: 6, co: 1, ol: 1
'''
import collections

def create_histogram(text):
    hist = {}
    for i in range(len(text)-1):
        pair = text[i:i+2]
        if ' ' in pair:
            continue
        if pair in hist:
            hist[pair] += 1
        else:
            hist[pair] = 1

    hist_sorted = sorted(hist.items(), key=lambda kv: kv[1], reverse=True)
    hist = collections.OrderedDict(hist_sorted)
    return hist

print(create_histogram('this is a good thing'))


"""ngram_skipd.py
   Modify ngram.py to skip headwords found in only certain dictionaries.
   Notably, PD. As about 1/4 of the words appear ONLY in PD.
"""
import sys,re,codecs
#sys.path.append('hwnorm1')
import hwnorm1
#from sansort import slp_cmp
slp_from = "aAiIuUfFxXeEoOMHkKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzsh"
slp_to =   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw"
slp_from_to = str.maketrans(slp_from,slp_to)

def get_ngrams(x,n,option="all"):
 ans=[]
 nx = len(x)
 if option == "any":
  ibeg = 0
  iend = nx - n + 1
  for i in range(ibeg,iend):
   ans.append(x[i:i+n])
 elif option == "beg":
  ibeg = 0
  iend = n
  if iend <= nx:
   ans.append(x[ibeg:iend])
 elif option == "end":
  ibeg = nx - n
  iend = nx
  if ibeg >= 0:
   ans.append(x[ibeg:iend])
 return ans
def rare_ngrams(fileout,ngramsd):
 filedbg = fileout.replace('.txt','_rare.txt')
 maxinstance = 1
 rarerecs = []
 for key in hwnorm1.HWnorm1rec.d:
  rec = hwnorm1.HWnorm1rec.d[key]
  if not rec.ngramused:
   continue
  ngrams = get_ngrams(key,ngramlen,option)
  for ngram in ngrams:
   if ngramsd[ngram] <= maxinstance:
    rarerecs.append([rec,ngram])
 with codecs.open(filedbg,"w","utf-8") as f:
  for rec,ngram in rarerecs:
   out = "%s:%s:%s" %(ngram,ngramsd[ngram],rec.line)
   f.write(out+'\n')
 print(len(rarerecs),maxinstance,"rare ngram instances written to",filedbg)

if __name__ == "__main__":
 ngramlen = int(sys.argv[1])  # 2,3, etc.
 assert ngramlen>=1,"ngramlen must be >=1"
 option = sys.argv[2] # any,beg,end - location of ngram in word
 # don't count hwnorm1c words appearing ONLY in these dictionaries
 skipdicts0 = sys.argv[3].split(',')
 skipdicts = [x.upper() for x in skipdicts0]
 fileout = sys.argv[4] # "hwnorm1/%sgram.txt"%ngramlen
 filein = "../../sanhw1/hwnorm1c.txt"
 hwnorm1.init_hwnorm1(filein)
 ngramsd = {}
 for key in hwnorm1.HWnorm1rec.d: # normalized headword spelling
  rec = hwnorm1.HWnorm1rec.d[key]
  rec.ngramused = False
  flag = False  # True means we use key for ngrams
  for dictname in rec.dictstrs: # dictname is upper case
   if dictname not in skipdicts:
    flag = True
    # mark so rare_ngrams will know we skipped
    rec.ngramused = True
    break
  if not flag:
   # key occurs only in dictionaries in skipdicts. Don't compute ngrams.
   continue
  ngrams = get_ngrams(key,ngramlen,option)
  for ngram in ngrams:
   if ngram not in ngramsd:
    ngramsd[ngram]=0
   ngramsd[ngram] = ngramsd[ngram] + 1

 keys = list(ngramsd.keys())
 #keys.sort(cmp=slp_cmp)
 keys.sort(key = lambda x: x.translate(slp_from_to))
 with codecs.open(fileout,"w","utf-8") as f:
  for key in keys:
   out = "%s:%s"%(key,ngramsd[key])
   f.write(out + "\n")
 print(len(keys),"ngrams written to",fileout)
 # it is sometimes of interest to find the words which have 'rare' ngrams
 if False:
  rare_ngrams(fileout,ngramsd)


import csv
import numpy as np
import pandas as pd
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
from pandas_datareader import data as pdr
import fix_yahoo_finance as yf

#yf.pdr_override()
df_full = pdr.get_data_yahoo("RELIANCE.NS", start="2018-01-01").reset_index()
df_full.to_csv('RELIANCE.NS.csv',index=False)
df_full.head()

dates = []
prices = []

def get_data(filename):
	with open(filename, 'r') as csvfile:
		csvFileReader = csv.reader(csvfile)
		next(csvFileReader)
		next(csvFileReader)
		for row in csvFileReader:
			dates.append(int(row[0].split('-')[2]))
			prices.append(float(row[4]))
	return

def predict_price(dates, prices, x):
	dates = np.reshape(dates,(len(dates), 1))

	clf = RandomForestRegressor()
	gp = GaussianProcessRegressor()
	tr = DecisionTreeRegressor()
	svr_rbf = SVR(kernel= 'rbf', C= 1e3, gamma= 0.1)
	svr_rbf.fit(dates, prices)
	clf.fit(dates, prices)
	gp.fit(dates, prices)
	tr.fit(dates, prices)

	print('Plotting started:')

	#plotting using Support Vector Regressor
	plt.figure()
	plt.scatter(dates, prices, color= 'black', label= 'Data')
	plt.plot(dates, svr_rbf.predict(dates), color= 'red', label= 'RBF model')
	plt.xlabel('Date')
	plt.ylabel('Price')
	plt.legend()

	#plotting using Gaussin process
	plt.figure()
	plt.scatter(dates, prices, color= 'black', label= 'Data')
	plt.plot(dates,gp.predict(dates), color= 'green', label= 'Gaussian Process')
	plt.xlabel('Date')
	plt.ylabel('Price')
	plt.legend()

	#plotting using Decision tree
	plt.figure()
	plt.scatter(dates, prices, color= 'black', label= 'Data')
	plt.plot(dates,tr.predict(dates), color= 'blue', label= 'Decision Tree')
	plt.xlabel('Date')
	plt.ylabel('Price')
	plt.legend()

	#plotting using Random Forest model
	plt.figure()
	plt.scatter(dates, prices, color= 'black', label= 'Data')
	plt.plot(dates,clf.predict(dates), color= 'yellow', label= 'Random Forest Regression')
	plt.xlabel('Date')
	plt.ylabel('Price')
	plt.legend()

	plt.show()

	for i in range(int(x),int(x)+11):
		i=np.array(i)
		i=i.reshape(-1,1)
		print('')
		print('Prediction of date -',int(i),':')
		print('1.')
		print(svr_rbf.predict(i)[0],)
		print('2.',)
		print(tr.predict(i)[0],)
		print('3.',)
		print(gp.predict(i)[0],)
		print('4.',)
		print(clf.predict(i)[0],)

a = np.array(7)
a = a.reshape(-1,1)
get_data('RELIANCE.NS.csv')
print('Imported Data')
predict_price(dates, prices, a)
print('\nOver')


from datetime import datetime, timezone, timedelta
from alpaca_trade_api.rest import REST
import os

api = REST(os.environ.get("APCA_API_KEY_ID"),
           os.environ.get("APCA_API_SECRET_KEY"),
           api_version='v2')

def get_historical_data(tickers):
    # Maximum number of days per bar
    limit = 365*2

    # RFC3339 date format
    end_date = datetime.now(timezone.utc).astimezone()
    delta = timedelta(days=365*2)
    start_date = end_date-delta
    end_date.isoformat()
    start_date.isoformat()

    historical_data = api.get_barset(tickers,
                                     "day",
                                     limit,
                                     start_date,
                                     end_date)

    return historical_data

def remap_keys(mapping):
    new_mapping = dict()

    for parent_key, parent_value in mapping.items():
        ticker = parent_key[0]
        metric = parent_key[1]

        sorting_list = [{"date": k.date(), metric: v} for k, v in parent_value.items()]
        sorted_data = sorted(sorting_list, key=lambda l: l["date"])

        if ticker not in new_mapping:
            new_mapping[ticker] = [data_point for data_point in sorted_data]
        else:
            for index, element in enumerate(new_mapping[ticker]):
                element[metric] = sorted_data[index][metric]

    return new_mapping


class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits: return []
        match = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}
        res = ['']
        for i in range(len(digits)):
            tmp = []
            for j in res:
                for k in match[digits[i]]:
                    tmp.append(j + k)
            res = tmp
        return res


from .models import Resource
from .tasks import track_request
from .track import (
    TRACKED_RESOURCE_ACTIONS,
    get_resource_from_uri,
    track_request_googleanalytics_async,
    track_request_influxdb_async,
)

class GoogleAnalyticsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # for each API request, trigger a call to Google Analytics to track the request
        track_request_googleanalytics_async(request)

        response = self.get_response(request)

        return response

class InfluxDBMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # for each API request, trigger a call to InfluxDB to track the request
        track_request_influxdb_async(request)

        response = self.get_response(request)

        return response

class APIUsageMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        resource = get_resource_from_uri(request.path)
        if resource in TRACKED_RESOURCE_ACTIONS:
            track_request.delay(
                kwargs={
                    "resource": Resource.get_from_resource_name(resource),
                    "host": request.get_host(),
                    "environment_key": request.headers.get("X-Environment-Key"),
                }
            )

        response = self.get_response(request)

        return response


from GWXtreme import eos_model_selection as ems
import lalsimulation as lalsim
import lal
import numpy as np
import pylab as pl
import glob
import json

p_eos_val = {"AP4":[33.269,2.830,3.445,3.348],
             "MPA1":[33.495,3.446,3.572,2.887],
             "MS1":[33.858,3.224,3.033,1.325]}

def get_data(mkn, trials=1000, narrow=True):
    # Gets all the data we need in an easy to reuse fashion
    # Each eos' : name, lal bayes factor, lal deviation, piecewise polytrope, and
    # piecewise deviation are stored in their own lists

    if narrow == True: typeis = "Narrow"
    else: typeis = "Broad"

    with open("Analysis/Refined_bestof_1_8_eos_global_values.json","r") as f:
        data = json.load(f)

    lal_bfs = [] # Need bayes factors from lal source in list
    lal_sds = []

    pp_bfs = [] # Need bayes factors from piecewise polytrope values in list
    pp_sds = []

    og_pp_bfs = [] # Need bayes factors from paper
    og_pp_sds = []

    if narrow == True: modsel = ems.Model_selection(posteriorFile="posterior_samples/posterior_samples_narrow_spin_prior.dat")

    else: modsel = ems.Model_selection(posteriorFile="posterior_samples/posterior_samples_broad_spin_prior.dat")

    for eos in data:

        print(eos)

        if eos in p_eos_val:

            p1,g1,g2,g3 = p_eos_val[eos]
            og_pp_bf, og_pp_trials = modsel.computeEvidenceRatio([p1,g1,g2,g3],"SLY",trials=trials)
            og_pp_bfs.append(og_pp_bf)
            og_pp_sds.append(np.std(og_pp_trials) * 2)

        else:

            og_pp_bfs.append(0)
            og_pp_sds.append(0)

        lal_bf, lal_trials = modsel.computeEvidenceRatio(eos,"SLY",trials=trials)
        lal_bfs.append(lal_bf)
        lal_sds.append(np.std(lal_trials) * 2)

        p1,g1,g2,g3,_ = data[eos]
        pp_bf, pp_trials = modsel.computeEvidenceRatio([p1,g1,g2,g3],"SLY",trials=trials)
        pp_bfs.append(pp_bf)
        pp_sds.append(np.std(pp_trials) * 2)

    output = np.vstack((og_pp_bfs,og_pp_sds,lal_bfs,lal_sds,pp_bfs,pp_sds)).T
    np.savetxt("Plots/bar_plots/data/bar_plot_data_{}_mk{}.txt".format(typeis,mkn),output,fmt="%f\t%f\t%f\t%f\t%f\t%f")

def plotter(mkn, p_mkn, narrow=True, log=True):
    # Makes bar plot

    if narrow == True: typeis = "Narrow"
    else: typeis = "Broad"

    data = np.loadtxt("Plots/bar_plots/data/bar_plot_data_{}_mk{}.txt".format(typeis,mkn))

    og_pp_bfs,og_pp_sds,lal_bfs,lal_sds,pp_bfs,pp_sds = data.T

    with open("Analysis/Refined_bestof_1_8_eos_global_values.json","r") as f:
        data = json.load(f)

    eos_list = []
    for eos in data: eos_list.append(eos)

    x_axis = np.arange(len(eos_list))

    pl.rcParams.update({"font.size":18})
    pl.figure(figsize=(20,10))

    if log:

        ax = pl.gca()
        ax.set_yscale("log")

    pl.bar(x_axis-.30,lal_bfs,.3,yerr=lal_sds,label="LAL Simulation Method",color="blue")
    pl.bar(x_axis+.00,pp_bfs,.3,yerr=pp_sds,label="Best fit piecewise polytropes (this study)",color="orange")
    pl.bar(x_axis+.30,og_pp_bfs,.3,yerr=og_pp_sds,label="Best fit piecewise polytropes from arXiv:0812.2163",color="green")

    pl.xticks(x_axis,eos_list,rotation=45,ha="right")
    pl.ylabel("Bayes-factor w.r.t SLY")
    pl.title("Likelihood Comparison")

    if log: pl.ylim([1e-4,10])

    pl.legend()
    pl.savefig("Plots/bar_plots/bar_plot_{}_mk{}.png".format(typeis,p_mkn))


from django.db import models
from django.utils.translation import gettext_lazy as _
from django.db.models.signals import post_save
from back.signals.mailing_signals import send_mail_on_creation

from django.contrib.auth import get_user_model

FoxUser = get_user_model()

class ClientManager(FoxUser):
    class Position(models.TextChoices):
        safety_manager = "SafeMan", _("Safety Manager")
        security_manager = "SecMan", _("Security Manager")
        safety_officer = "SecOff", _("Security Officer")
        site_owner = "SiteOwn", _("Site Owner")
        work_owner = "WorkOwn", _("Owner of Work")
        security_guards = "SecGrd", _("Security Guards")

    # name = models.CharField(max_length=128, null=True)
    department = models.CharField(max_length=128, null=True)
    position = models.CharField(
        max_length=10,
        choices=Position.choices,
        default=Position.site_owner,
    )

    class Meta:
        verbose_name = "Client Manager"

    @property
    def info(self):
        return {"client_manager_name": self.name}

post_save.connect(send_mail_on_creation, sender=ClientManager)


from django.urls import path
from . import views

app_name = "shop"
urlpatterns = [
    path("", views.index, name="index"),
    path("datails/<int:p_id>/", views.details, name="detail"),
    path("cart/", views.cart, name="cart"),
    path("show_cart/", views.show_cart, name="show_cart"),
    path("get_date/", views.get_date, name="get_date"),
]