#Name: MENDIOLA, LOGIE | Year & Section: BSCPE 1-5 | Object Oriented Programming | Finals Project

#Instructions:
#Create “your” own covid contact tracing app with GUI
#Create a program that ask user for typical information found in covid contact tracing app
#Write the collected information in a file (use any format you like)
#The app should be able to add and search entry
#Please don’t follow any online contact tracing programming tutorial

####### LAYOUT DRAFT FOR PROGRAM ######

#Main Window
from tkinter import *
import tkinter as tk

from tkinter import messagebox

#Call another file to overwrite and save data entry
def covid_prompt_info(info):
    with open("covid_contact_entry.txt", "a") as entry_file:
        for key, value in info.items():
            entry_file.write(f"{key}: {value}\n")
        entry_file.write(str(info) + "\n")

#Record of input entries from users
def submit_records():
    symptom_four_values = {
        "Fever": symptom_four_chk1_var.get(),
        "Cough": symptom_four_chk2_var.get(),
        "Colds": symptom_four_chk3_var.get(),
        "Muscle/body pains": symptom_four_chk4_var.get(),
        "Sore Throat": symptom_four_chk5_var.get(),
        "Diarrhea": symptom_four_chk6_var.get(),
        "None of the above": symptom_four_chk7_var.get(),
        "Headache": symptom_four_chk8_var.get(),
        "Shortness of breath": symptom_four_chk9_var.get(),
        "Difficulty of breathing": symptom_four_chk10_var.get(),
        "Loss of taste": symptom_four_chk11_var.get(),
        "Loss of smell": symptom_four_chk12_var.get()
    }

    data = {
        "First Name": first_name_prsnl_input.get(),
        "Middle Name": middle_name_prsnl_input.get(),
        "Last Name": last_name_prsnl_input.get(),
        "Current Address": current_address_prsnl_input.get("1.0", "end-1c"),
        "Permanent Address": permanent_address_prsnl_input.get("1.0", "end-1c"),
        "Birth Date": calendar.get_date(),
        "Contact Number / Landline": contact_prsnl_input.get(),
        "E-mail Address": email_prsnl_input.get(),
        "Occupation": occupy_prsnl_input.get(),
        "Workplace Name / School Name": workplace_name_input.get(),
        "Workplace Address / School Address": workplace_add_input.get(),
        "Emergency Contact - Name": name_emrgncy_input.get(),
        "Emergency Contact - Address": address_emergncy_input.get(),
        "Emergency Contact - Contact Number / Landline": contact_emergncy_input.get(),
        "Emergency Contact - E-mail Address": email_emergncy_input.get(),
        "Emergency Contact - Relationship": relationship_emergncy_input.get(),
        "Have you been vaccinated for COVID-19?": symptom_one.get(),
        "What is your current dose/booster of vaccination shot?": symptom_two.get(),
        "What is the brand of your vaccination for COVID-19?": covid_symptom_three_input.get(),
        "Are you experiencing symptoms in the past 7 days?": symptom_four_values,
        "Have you had exposure to probable or confirm case in the last 7 days?": symptom_five.get(),
        "Have you had contact with others with COVID-19 Symptoms in the last 7 days?": symptom_six.get(),
        "Have you been tested for COVID-19 in the last 14 days?": symptom_seven.get(),
        "Most recent visited area/place?": addtnl_one_input.get(),
        "Number of people you saw in the visited area/place?": addtnl_two_input.get(),
        "Mode of Transportation": additional_three_qstn.get(),
        "Recent Medication Intake / Vitamin Intake?": addtnl_four_input.get()
    }
    covid_prompt_info(data)

    # Should ask user to confirm if the inputs are correct or not (Yes or No, Continue Editing)
    # If Yes, End Program
    # If Not, should be able to edit given data again
    response = messagebox.askyesno("Data Collection Complete!", "Do you want to save the data?")

    if response:
        covid_prompt.destroy()

#function for searching entries
def scan_covid_prompt_info():
    #use for searching for keywords in the search entry
    keywords = identify_search.get().lower()
    print("Searching for:", keywords)

    matching_entry = []
    entry_record = {}
    with open("covid_contact_entry.txt", "r") as entry_file:
        entry_lines = entry_file.readlines()
        for line in entry_lines:
            if not line.strip():

                if entry_record:

                    # Check if the keyword exists in any of the values of the entry
                    if any(keywords in val.lower() for val in entry_record.values()):
                        matching_entry.append(entry_record.copy())
                    entry_record = {}
            else:
                if ':' in line:
                    key, value = line.strip().split(': ', 1)
                    entry_record[key] = value

    # Check the last entry if there was no blank line after it
    if entry_record:
        if any(keywords in val.lower() for val in entry_record.values()):
            matching_entry.append(entry_record)

    # Display the results from the search entry
    if matching_entry:
        entry_result = []
        for entry in matching_entry:
            entry_value = "\n".join([f"{key}: {value}" for key, value in entry.items()])
            entry_result.append(entry_value)
        results = "\n\n".join(entry_result)
        print(results)

    else:
        print("No matching results found.")

covid_prompt = tk.Tk()
covid_prompt.title("(CCT) Covid Contact Tracer - BetaTest v.0.0")
covid_prompt.geometry("1530x1530")

#Entry widget for the main window
covid_contact_entry = tk.Entry(covid_prompt)

#Pre-Form Message
pre_form_message = Label(covid_prompt, text ="Fill out the form with outmost honesty for safety measures and the well being of others.\nMaraming Salamat Po!")
pre_form_message.place(x = 10, y = 20)

#Form for Asking Personal Questions:
# Name: (First Name, Middle Name, Last Name)
first_name_prsnl = Label(covid_prompt, text = "First Name:")
first_name_prsnl.place(x = 10, y = 60)

first_name_prsnl_input = Entry(covid_prompt, width = "30")
first_name_prsnl_input.place(x = 10, y = 80)

middle_name_prsnl = Label(covid_prompt, text = "Middle Name:")
middle_name_prsnl.place(x = 220, y = 60)

middle_name_prsnl_input = Entry(covid_prompt, width = "30")
middle_name_prsnl_input.place(x = 220, y = 80)

last_name_prsnl = Label(covid_prompt, text = "Last Name:")
last_name_prsnl.place(x = 10, y = 110)

last_name_prsnl_input = Entry(covid_prompt, width = "30")
last_name_prsnl_input.place(x = 10, y = 130)

# - Address: (Current & Permanent)
current_address_prsnl = Label(covid_prompt, text = "Current Address:")
current_address_prsnl.place(x = 10, y = 180)

current_address_prsnl_input = Text(covid_prompt, width = "23", height = "10")
current_address_prsnl_input.place(x = 10, y = 200)

permanent_address_prsnl = Label(covid_prompt, text = "Permanent Address:")
permanent_address_prsnl.place(x = 220, y = 180)

permanent_address_prsnl_input = Text(covid_prompt, width = "23", height = "10")
permanent_address_prsnl_input.place(x = 220, y = 200)

# - Birthdate:
birth_date = Label(covid_prompt, text ="Birth Date:")
birth_date.place(x = 10, y = 400)

from tkcalendar import Calendar
calendar = Calendar(covid_prompt, selectmode = 'day', year = 2023, month = 7, day = 18)
calendar.place(x = 10, y = 430)

# - Contact Number/Landline:
contact_prsnl = Label(covid_prompt, text = "Contact Number / Landline:")
contact_prsnl.place(x = 10, y = 630)

contact_prsnl_input = Entry(covid_prompt, width = "30")
contact_prsnl_input.place(x = 10, y = 650)

# - Email Address:
email_prsnl = Label(covid_prompt, text = "E-mail Address:")
email_prsnl.place(x = 10, y = 680)

email_prsnl_input = Entry(covid_prompt, width = "30")
email_prsnl_input.place(x = 10, y = 700)

# - Occupation:
occupy_prsnl = Label(covid_prompt, text = "Occupation:")
occupy_prsnl.place(x = 10, y = 730)

occupy_prsnl_input = Entry(covid_prompt, width = "30")
occupy_prsnl_input.place(x = 10, y = 750)

# - Workplace Name/ School or University Name:
workplace_name = Label(covid_prompt, text = "Workplace Name / School Name:")
workplace_name.place(x = 220, y = 630)

workplace_name_input = Entry(covid_prompt, width= "30")
workplace_name_input.place(x = 220, y = 650)

# - Workplace Address / School or University Address
workplace_add = Label(covid_prompt, text = "Workplace Address / School Address:")
workplace_add.place(x = 220, y= 680)

workplace_add_input = Entry(covid_prompt, width = "30")
workplace_add_input.place (x = 220, y = 700)

#Emergency Contact:
emergency_contact = Label(covid_prompt, text = "Emergency Contact")
emergency_contact.place(x = 600, y = 10)

# -Name (First Name, Last Name)
name_emrgncy = Label(covid_prompt, text = "Name (First Name, Last Name):")
name_emrgncy.place(x = 600, y = 30)

name_emrgncy_input = Entry(covid_prompt, width ="30")
name_emrgncy_input.place(x = 600, y = 50)

# -Address:
address_emergncy = Label(covid_prompt, text = "Address:")
address_emergncy.place(x = 820, y= 30)

address_emergncy_input = Entry(covid_prompt, width ="30")
address_emergncy_input.place(x = 820, y = 50)

# -Contact Number/Landline
contact_emergncy = Label(covid_prompt, text = "Contact Number / Landline:")
contact_emergncy.place(x = 600, y = 90)

contact_emergncy_input = Entry(covid_prompt, width = "30")
contact_emergncy_input.place(x = 600, y = 110)

# -Email Address
email_emergncy = Label(covid_prompt, text ="E-mail Address:")
email_emergncy.place(x = 820, y = 90)

email_emergncy_input = Entry(covid_prompt, width ="30")
email_emergncy_input.place(x = 820, y = 110)

# -Relationship to the Contact Person
relationship_emergncy = Label(covid_prompt, text = "Relationship to the Contact Person:")
relationship_emergncy.place(x = 600, y = 150)

relationship_emergncy_input = Entry(covid_prompt, width="30")
relationship_emergncy_input.place(x =600, y = 180)

#Questions to Assure Covid Symptoms of User:
covid_symptom = Label(covid_prompt, text = "Assessment for Signs and Symptoms of Covid-19")
covid_symptom.place(x = 600, y = 200)

# - Have you been vaccinated for COVID-19?
covid_symptom_one = Label(covid_prompt, text = "Have you been vaccinated for COVID-19?")
covid_symptom_one.place(x = 600, y = 240)

symptom_one = IntVar()
covid_symptom_one_rbtn1 = Radiobutton(covid_prompt, text = "Yes", variable = symptom_one, value = "1")
covid_symptom_one_rbtn1.place(x = 600, y = 260)

covid_symptom_one_rbtn2 = Radiobutton(covid_prompt, text = "No", variable = symptom_one, value = "2")
covid_symptom_one_rbtn2.place(x = 600, y = 280)

# What is your current number of vaccination shot?
covid_symptom_two = Label(covid_prompt, text = "What is your current dose/booster of vaccination shot?")
covid_symptom_two.place(x = 600, y = 320)

symptom_two = IntVar()
covid_symptom_two_rbtn1 = Radiobutton(covid_prompt, text = "1st Dose", variable = symptom_two, value = "1")
covid_symptom_two_rbtn1.place(x = 600, y = 340)

covid_symptom_two_rbtn2 = Radiobutton(covid_prompt, text = "2nd Dose", variable = symptom_two, value = "2")
covid_symptom_two_rbtn2.place(x = 600, y = 360)

covid_symptom_two_rbtn3 = Radiobutton(covid_prompt, text = "1st Booster", variable = symptom_two, value = "3")
covid_symptom_two_rbtn3.place(x = 600, y = 380)

covid_symptom_two_rbtn4 = Radiobutton(covid_prompt, text = "2nd Booster", variable = symptom_two, value = "4")
covid_symptom_two_rbtn4.place(x = 600, y = 400)

covid_symptom_two_rbtn5 = Radiobutton(covid_prompt, text = "N/A", variable = symptom_two, value = "5")
covid_symptom_two_rbtn5.place(x = 600, y = 420)

# - What is the brand of your COVID-19 Vaccination
covid_symptom_three = Label(covid_prompt, text = "What is the brand of your vaccination for COVID-19?")
covid_symptom_three.place(x = 600, y = 460)

covid_symptom_three_input = Entry(covid_prompt, width = "30")
covid_symptom_three_input.place(x = 600, y = 480)

# - Are you experiencing symptoms in the past 7 days
covid_symptom_four = Label(covid_prompt, text = "Are you experiencing these symptoms in the past 7 days?")
covid_symptom_four.place(x = 600, y = 510)

symptom_four_chk1_var = IntVar()
symptom_four_chk1 = Checkbutton(covid_prompt, text = "Fever", variable= symptom_four_chk1_var)
symptom_four_chk1.place(x = 600, y = 530)

symptom_four_chk2_var = IntVar()
symptom_four_chk2 = Checkbutton(covid_prompt, text = "Cough", variable= symptom_four_chk2_var)
symptom_four_chk2.place(x = 600, y = 550)

symptom_four_chk3_var = IntVar()
symptom_four_chk3 = Checkbutton(covid_prompt, text = "Colds", variable= symptom_four_chk3_var)
symptom_four_chk3.place(x = 600, y = 570)

symptom_four_chk4_var = IntVar()
symptom_four_chk4 = Checkbutton(covid_prompt, text = "Muscle/body pains", variable= symptom_four_chk4_var)
symptom_four_chk4.place(x = 600, y = 590)

symptom_four_chk5_var = IntVar()
symptom_four_chk5 = Checkbutton(covid_prompt, text = "Sore Throat", variable= symptom_four_chk5_var)
symptom_four_chk5.place(x = 600, y = 610)

symptom_four_chk6_var = IntVar()
symptom_four_chk6 = Checkbutton(covid_prompt, text = "Diarrhea", variable= symptom_four_chk6_var)
symptom_four_chk6.place(x = 600, y = 630)

symptom_four_chk7_var = IntVar()
symptom_four_chk7 = Checkbutton(covid_prompt, text = "None of the above", variable= symptom_four_chk7_var)
symptom_four_chk7.place(x = 600, y = 650)

symptom_four_chk8_var = IntVar()
symptom_four_chk8 = Checkbutton(covid_prompt, text = "Headache", variable= symptom_four_chk8_var)
symptom_four_chk8.place(x = 820, y = 530)

symptom_four_chk9_var = IntVar()
symptom_four_chk9 = Checkbutton(covid_prompt, text = "Shortness of breath", variable= symptom_four_chk9_var)
symptom_four_chk9.place(x = 820, y = 550)

symptom_four_chk10_var = IntVar()
symptom_four_chk10 = Checkbutton(covid_prompt, text = "Difficulty of breathing", variable= symptom_four_chk10_var)
symptom_four_chk10.place(x = 820, y = 570)

symptom_four_chk11_var = IntVar()
symptom_four_chk11 = Checkbutton(covid_prompt, text = "Loss of taste", variable= symptom_four_chk11_var)
symptom_four_chk11.place(x = 820, y = 590)

symptom_four_chk12_var = IntVar()
symptom_four_chk12 = Checkbutton(covid_prompt, text = "Loss of smell", variable= symptom_four_chk12_var)
symptom_four_chk12.place(x = 820, y = 610)

# - Have you had exposure to probable or confirm case in the last 7 days?
covid_symptom_five = Label(covid_prompt, text = "Have you had exposure to probable or confirm case in the last 7 days?")
covid_symptom_five.place(x = 600, y = 680)

symptom_five = IntVar()
covid_symptom_five_rbtn1 = Radiobutton(covid_prompt, text = "Yes", variable = symptom_five, value = "1")
covid_symptom_five_rbtn1.place(x = 600, y = 700)

covid_symptom_five_rbtn2 = Radiobutton(covid_prompt, text = "No", variable = symptom_five, value = "2")
covid_symptom_five_rbtn2.place(x = 600, y = 720)

# - Had contact with others with COVID Symptoms?
covid_symptom_six = Label(covid_prompt, text = "Have you had contact with others with COVID-19 Symptoms in the last 7 days?")
covid_symptom_six.place(x = 1100, y = 20)

symptom_six = IntVar()
covid_symptom_six_rbtn1 = Radiobutton(covid_prompt, text = "Yes", variable = symptom_six, value = "1")
covid_symptom_six_rbtn1.place(x = 1100, y = 40)

covid_symptom_six_rbtn2 = Radiobutton(covid_prompt, text = "No", variable = symptom_six, value = "2")
covid_symptom_six_rbtn2.place(x = 1100, y = 60)

# - Have you been tested for COVID-19 in the last 14 days?
covid_symptom_seven = Label(covid_prompt, text = "Have you been tested for COVID-19 in the last 14 days?")
covid_symptom_seven.place(x = 1100, y = 100)

symptom_seven = IntVar()
covid_symptom_seven_rbtn1 = Radiobutton(covid_prompt, text = "Yes (Positive)", variable = symptom_seven, value = "1")
covid_symptom_seven_rbtn1.place(x = 1100, y = 120)

covid_symptom_seven_rbtn2 = Radiobutton(covid_prompt, text = "Yes (Negative)", variable = symptom_seven, value = "2")
covid_symptom_seven_rbtn2.place(x = 1100, y = 140)

covid_symptom_seven_rbtn3 = Radiobutton(covid_prompt, text = "No", variable = symptom_seven, value = "3")
covid_symptom_seven_rbtn3.place(x = 1100, y = 160)

#Additional Questions:
addtnl_question = Label(covid_prompt, text="Additional Questions")
addtnl_question.place(x= 1100 , y = 210 )

# - Most recent visited place
addtnl_one = Label(covid_prompt, text= "Most recent visited area/place?")
addtnl_one.place(x= 1100 , y = 230 )

addtnl_one_input = Entry(covid_prompt, width="30")
addtnl_one_input.place(x = 1100, y = 260)

# - Number of people you saw in the area
addtnl_two = Label(covid_prompt, text="Number of people you saw in the visited area/place?")
addtnl_two.place(x = 1100 , y = 290)

addtnl_two_input = Entry(covid_prompt, width="30")
addtnl_two_input.place(x = 1100, y = 310)

# - Mode of Transportation
addtnl_three = Label(covid_prompt, text="Mode of Transportation?")
addtnl_three.place(x = 1100, y = 340)

additional_three_qstn = IntVar()
addtnl_three_input  = Radiobutton(covid_prompt, text = "Public Transportation", variable = additional_three_qstn, value = "1")
addtnl_three_input.place(x = 1100, y = 360)

addtnl_three_input  = Radiobutton(covid_prompt, text = "Private Transportation", variable = additional_three_qstn, value = "2")
addtnl_three_input.place(x = 1100, y = 380)

# - Recent Medication Intake/Vitamin Intake
addtnl_four = Label(covid_prompt, text = "Recent Medication Intake / Vitamin Intake?")
addtnl_four.place(x = 1100, y = 420)

addtnl_four_input = Entry(covid_prompt, width = "30")
addtnl_four_input.place(x = 1100, y = 440)

# Submit Button:
submission_button = Button(covid_prompt, text ="Submit", width = "10", command = submit_records)
submission_button.place(x = 1150, y = 470)

# Last Message: Picture or Slogan Quote of Covid Safety Measures
from PIL import Image, ImageTk

img_message = "covid_poster.jpg"
image = Image.open(img_message)
img = ImageTk.PhotoImage(image)

img_message_input = Label(covid_prompt, image=img, width = "500", height= "400")
img_message_input.place(x=1100, y=550)

#Adding search entry to be able to look for keywords
identify_search = Entry(covid_prompt, width="30")
identify_search.place(x=1200, y=530)

scan_btn = Button(covid_prompt, text="Search", width="10", command = scan_covid_prompt_info)
scan_btn.place(x=1100, y=530)

covid_prompt.mainloop()


from matplotlib import pyplot as plt
import numpy as np
import librosa
from librosa import  display
import os
from utils import load_spectrograms
from hyperparams import Hyperparams as hp
# import the necessary packages
from skimage.measure import structural_similarity as ssim
import matplotlib.pyplot as plt
import numpy as np
import cv2

cinco_org= np.load('../savedir/synthesized-audios/RTISI-LA/5-org.npy')

savedir='../savedir/spectogramas/'
vocoders = ['RTISI-LA','Griff-Lim']
for voco in vocoders:
    diretory = os.path.join('../savedir/synthesized-audios/',voco)
    arquivos = ['1.wav','5.wav','5-org.wav','3.wav','3-org.wav']
    for i in arquivos:
        _,_,mag= load_spectrograms(os.path.join(diretory,i))
        print  (os.path.join(diretory,i),' :',mag.shape)
        if i == '5.wav':
            mag = mag[:cinco_org.shape[0]][:]
        np.save( os.path.join(diretory,i.replace('.wav','')), mag)
        # transpose
        mag = mag.T

        # de-noramlize
        mag = (np.clip(mag, 0, 1) * hp.max_db) - hp.max_db + hp.ref_db
        # to amplitude
        mag = np.power(10.0, mag * 0.05)
        mag = mag**hp.power
        display.specshow(librosa.amplitude_to_db(mag,ref=np.max), y_axis='log', x_axis='time')
        plt.title('Espectrograma STFT')
        plt.colorbar(format='%+2.0f dB')
        plt.tight_layout()
        plt.savefig(os.path.join(savedir,voco,'spectrograma-'+voco+'-'+i.replace('.wav','')+'.png'))
        plt.cla()   # Clear axis
        plt.clf()
        #plt.show()

## R2 Calcule
import numpy as np
from sklearn.metrics import r2_score

y_true= np.load('../savedir/synthesized-audios/RTISI-LA/5-org.npy')
predito_dctts = np.load('samples/5.png.npy')

# unpad
predito =  predito_dctts[:y_true.shape[0]][:]
#predito = predito.reshape(-1)
#y_true = y_true.reshape(-1)
print( " Predito vs esperado R Square: ",r2_score(y_true, predito, multioutput='variance_weighted'))

y_pred = np.load('../savedir/synthesized-audios/Griff-Lim/5.npy')
y_true = predito_dctts[:y_pred.shape[0]][:]
#y_true = y_true.reshape(-1)
#y_pred = y_pred.reshape(-1)
print( " Predito vs Griff-Lim R Square: ",r2_score(y_true, y_pred, multioutput='variance_weighted'))

y_pred = np.load('../savedir/synthesized-audios/RTISI-LA/5.npy')
y_true = predito_dctts[:y_pred.shape[0]][:]
#y_true = y_true.reshape(-1)
#y_pred = y_pred.reshape(-1)
print( " Predito vs RTISI-LA R Square: ",r2_score(y_true, y_pred, multioutput='variance_weighted'))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Oct 26 10:46:50 2022

-Compute EWS and DL predictions rolling over chick heart data

@author: tbury
"""

import time
start_time = time.time()

import numpy as np
import pandas as pd

import ewstools

import tensorflow as tf
from tensorflow.keras.models import load_model

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--inc', type=int,
                    help='Time increment between DL predictions',
                    default=50)
parser.add_argument('--use_inter_classifier', type=bool, help='Use the intermediate classifier as opposed to the hard saved classifier', default=True)

args = parser.parse_args()
inc = args.inc
use_inter_classifier = True if args.use_inter_classifier=='true' else False
print('Using time increment of {} for DL predictions'.format(inc))

np.random.seed(0)

# Load in DL models
if use_inter_classifier:
    filepath_classifier = '../dl_train/output/'
else:
    filepath_classifier = '../../data/'

m1 = load_model(filepath_classifier+'classifier_1.pkl')
m2 = load_model(filepath_classifier+'classifier_2.pkl')
print('TF models loaded')

# EWS parameters
rw = 0.5 # rolling window
bw = 20 # Gaussian band width (# beats)

# Load in trajectory data
df_traj = pd.read_csv('../../data/df_chick.csv')
df_traj_pd = df_traj[df_traj['type']=='pd']
df_traj_null = df_traj[df_traj['type']=='neutral']

# Load in transition times
df_transition = pd.read_csv('output/df_transitions.csv')

#--------
# Compute EWS for period-doubling trajectories
#--------

list_ews = []
list_dl = []

list_tsid = df_traj_pd['tsid'].unique()
# for tsid in list_tsid:
for tsid in list_tsid:

    df_spec = df_traj_pd[df_traj_pd['tsid']==tsid].set_index('Beat number')
    transition = df_transition[df_transition['tsid']==tsid]['transition'].iloc[0]
    s = df_spec['IBI (s)'].iloc[:]

    # Compute EWS
    ts = ewstools.TimeSeries(s, transition=transition)
    # ts.detrend(method='Lowess', span=50)
    ts.detrend(method='Gaussian', bandwidth=bw)

    ts.compute_var(rolling_window=rw)
    ts.compute_auto(rolling_window=rw, lag=1)

    # Get DL predictions for forced trajectory
    ts.apply_classifier_inc(m1, inc=inc, name='m1', verbose=0)
    ts.apply_classifier_inc(m2, inc=inc, name='m2', verbose=0)

    # Save data to lists
    df_dl = ts.dl_preds.groupby('time').mean(numeric_only=True) # use mean DL pred
    df_dl['tsid'] = tsid
    df_dl.reset_index(inplace=True)
    df_dl = df_dl.rename({'time':'Beat number'}, axis=1)
    list_dl.append(df_dl)

    df_ews = ts.state.join(ts.ews)
    df_ews['tsid'] = tsid
    list_ews.append(df_ews)

    print('Complete for tsid={}'.format(tsid))

df_ews_pd = pd.concat(list_ews)
df_dl_pd = pd.concat(list_dl)

# Export period-doubling EWS
df_ews_pd.to_csv('output/df_ews_pd_rolling.csv')
df_dl_pd.to_csv('output/df_dl_pd_rolling.csv', index=False)

#--------
# Compute EWS for null trajectories
#--------

list_ews = []
list_dl = []
list_tsid = df_traj_null['tsid'].unique()
for tsid in list_tsid:

    df_spec = df_traj_null[df_traj_null['tsid']==tsid].set_index('Beat number')
    s = df_spec['IBI (s)'].iloc[:]

    # Compute EWS
    ts = ewstools.TimeSeries(s)
    # ts.detrend(method='Lowess', span=50)
    ts.detrend(method='Gaussian', bandwidth=bw)

    ts.compute_var(rolling_window=rw)
    ts.compute_auto(rolling_window=rw, lag=1)

    # Get DL predictions for null trajectory
    ts.apply_classifier_inc(m1, inc=inc, name='m1', verbose=0)
    ts.apply_classifier_inc(m2, inc=inc, name='m2', verbose=0)

    df_dl = ts.dl_preds.groupby('time').mean(numeric_only=True) # use mean DL pred
    df_dl['tsid'] = tsid
    df_dl.reset_index(inplace=True)
    df_dl = df_dl.rename({'time':'Beat number'}, axis=1)
    list_dl.append(df_dl)

    df_ews = ts.state.join(ts.ews)
    df_ews['tsid'] = tsid
    list_ews.append(df_ews)

    print('Complete for tsid={}'.format(tsid))

df_ews_null = pd.concat(list_ews)
df_dl_null = pd.concat(list_dl)

# Export null EWS
df_ews_null.to_csv('output/df_ews_null_rolling.csv')
df_dl_null.to_csv('output/df_dl_null_rolling.csv', index=False)

# Time taken for script to run
end_time = time.time()
time_taken = end_time - start_time
print('Ran in {:.2f}s'.format(time_taken))


import FWCore.ParameterSet.Config as cms

process = cms.Process('TEST')
process.load('SUSYBSMAnalysis.SusyCAF.ntuple_cff')

process.load('FWCore.MessageService.MessageLogger_cfi')
process.load('Configuration.StandardSequences.Services_cff')
process.add_( cms.Service( "TFileService",
                           fileName = cms.string( 'testTree.root' ),
                           closeFileFast = cms.untracked.bool(True)  ) )

process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(1000) )
process.source = cms.Source (
    "PoolSource",
    fileNames = cms.untracked.vstring('file:/disk1/user/nmohr/E81DF107-84AB-DE11-A089-001E4F3F28DC.root'),
    secondaryFileNames = cms.untracked.vstring())


from selenium import webdriver
from selenium.webdriver.common.by import By

product_url = 'https://www.amazon.com/Nike-Romaleos-Training-White-Black/dp/B01FZ3H4TQ/ref=sr_1_13?crid=RWB8BXT454CN&keywords=adidas%2Bpowerlift%2Bshoes&qid=1697802294&sprefix=adidas%2Bpowerlift%2Bshoe%2Caps%2C186&sr=8-13&th=1&psc=1'

chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("detach", True)

driver = webdriver.Chrome(options=chrome_options)
driver.get(product_url)

price_dollars = driver.find_element(By.CLASS_NAME, value='a-price-whole')
price_cents = driver.find_element(By.CLASS_NAME, value='a-price-fraction')
print(f"The price is {price_dollars.text}.{price_cents.text}")
#
# button = driver.find_element(By.ID, value='submit')
# print(button.size)
# doc_link = driver.find_element(By.CSS_SELECTOR, value='.doc-widget a')

bug_link = driver.find_element(By.XPATH, value='//*[@id="bylineInfo"]')
print(bug_link.text)
# driver.close()
driver.quit()


class Segmentation:
    def __init__(self, path, encoding='utf-8'):
        dict_file = open(path, encoding=encoding)
        self.__words__ = dict_file.read().split()
        self.__construct_index__(self.__words__)

    def __construct_index__(self, words):
        htable = dict()
        htable[words[0][0]] = [0, -1]
        for i in range(1, len(words)):
            if words[i][0] != words[i-1][0]:
                htable[words[i-1][0]][1] = i
                htable[words[i][0]] = [i, -1]
        htable[words[len(words)-1][0]][1] = len(words)
        self.__htable__ = htable

    def __get_dict__(self, first_char=''):
        if first_char == '':
            res_array = self.__words__
        else:
            idx = self.__htable__[first_char]
            res_array = self.__words__[idx[0]:idx[1]]
        return res_array

    def __get_dict_max_len__(self):
        return max(map(len, self.__words__))

    def __fmm_cut__(self, text):
        res = list()
        while len(text) > 0:
            tmp_dict = self.__get_dict__(text[0])
            wnd_size = min(len(text), max(map(len, tmp_dict)))
            while text[:wnd_size] not in tmp_dict and wnd_size > 1:
                wnd_size -= 1
            res.append(text[:wnd_size])
            text = text[wnd_size:]
        return res

    def __rmm_cut__(self, text):
        res = list()
        wnd_max_size = self.__get_dict_max_len__()
        while len(text) > 0:
            wnd_size = min(len(text), wnd_max_size)
            while text[-wnd_size:] not in self.__get_dict__(text[-wnd_size]) and wnd_size > 1:
                wnd_size -= 1
            res.append(text[-wnd_size:])
            text = text[:-wnd_size]
        res.reverse()
        return res

    def cut(self, text, method='mixed'):
        if method == 'fmm':
            res = self.__fmm_cut__(text)
        if method == 'rmm':
            res = self.__rmm_cut__(text)
        else:
            res_fmm = self.__fmm_cut__(text)
            res_rmm = self.__rmm_cut__(text)
            if len(res_fmm) != len(res_rmm):
                res = res_rmm if len(res_rmm) < len(res_fmm) else res_fmm
            elif res_fmm == res_rmm:
                res = res_fmm
            else:
                fmm_s_cnt = len([w for w in res_fmm if len(w) == 1])
                rmm_s_cnt = len([w for w in res_rmm if len(w) == 1])
                res = res_rmm if rmm_s_cnt < fmm_s_cnt else res_fmm
        return res


"""Refaça o Ex051, lendo o primeiro termo e a razão de uma PA,
mostrando os 10 primeiros termos utilizando o while."""

print('Geradores de PA')
print('-=' * 10)

# utilizando FOR
primeiro = int(input('Primeiro termo: '))  # por onde começar a contagem.
razao = int(input('Razão: '))
decimo = primeiro + (10 - 1 + 1) * razao
for c in range(primeiro, decimo, razao):
    print('{}'.format(c), end=' - ')
print('FIM')

#utilizando WHILE
p = int(input('Primeiro termo: '))
r = int(input('Razão da PA: '))
t = p
c = 1
while c <= 10:
    print('{} - '.format(t), end='')
    t += r
    c += 1
print('ACABOU')


jun = {"name": "Jun Yang", "id": 1, "rating": 4.7}
rob = {"name": "Robert Duvall", "id": 2, "rating": 4.3}
jeff = {"name": "Jeff Forbes", "id": 3, "rating": 4.1}
susan = {"name": "Susan Rodger", "id": 4, "rating": 2.1}
astrachan = {"name": "Astrachan", "id": 5, "rating": 1.2}
amy = {"name": "Amy Anderson", "id": 6, "rating": 4.7}
orin = {"name": "Orin Starn", "id": 7, "rating": 2.1}

class1 = {"id": "0", "num": 316, "dept": "Compsci", "name": "Databases", "overall": 4.1,
"difficulty": 1.2, "nextSemProf": jun}

class2 = {"id": "1", "num": 201, "dept": "Compsci", "name": "Algorithms", "overall": 3.7,
"difficulty": 4.5, "nextSemProf": jeff}

class3 = {"id": "2", "num": 250, "dept": "Compsci", "name": "Computer Architecture", "overall": 2.1,
"difficulty": 4.9, "nextSemProf": rob}

class4 = {"id": "4", "num": 101, "dept": "Compsci", "name": "Python", "overall": 4.9,
"difficulty": 2.3, "nextSemProf": susan}

class5 = {"id": "5", "num": 101, "dept": "CulAnth", "name": "Cultural Anthropology", "overall": 3.2,
"difficulty": 3.1, "nextSemProf": orin}

class6 = {"id": "6", "num": 101, "dept": "Educ", "name": "Foundations of Education", "overall": 4.3,
"difficulty": 3.6, "nextSemProf": amy}

def getMajors():
    return [class1, class2, class3]

def getTreqs():
    return [class5, class4, class6]


import os
from time import sleep
from threading import Timer
import digitalio
import busio
import board
import RPi.GPIO as GPIO
import adafruit_sht31d
from adafruit_epd.ssd1680 import Adafruit_SSD1680
from display import DisplayController
from state import CheeseCaveControllerMode, CheeseCaveState
from configs import CheeseCaveConfigs
import logging

logger = logging.getLogger(__name__)

class CheeseCaveController:
    def __init__(self):
        self.i2c = busio.I2C(board.SCL, board.SDA)
        self.spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
        self.ecs = digitalio.DigitalInOut(board.CE0)
        self.dc = digitalio.DigitalInOut(board.D22)
        self.rst = digitalio.DigitalInOut(board.D27)
        self.busy = digitalio.DigitalInOut(board.D17)

        logger.info('Controller is loading configs and state.')
        self.configs = CheeseCaveConfigs()
        # The state is the one that receives button events when someone presses a button. One of the actions is shutting down the board, so we need to give it a shutdown callback.
        self.state = CheeseCaveState(self.shutdown)
        logger.info('Configs and state loaded.')

        self.display = Adafruit_SSD1680(
            122,
            250,
            self.spi,
            cs_pin=self.ecs,
            dc_pin=self.dc,
            sramcs_pin=None,
            rst_pin=self.rst,
            busy_pin=self.busy,
        )
        self.display.rotation = 1
        self.display_controller = DisplayController(self.display, self.state)

        logger.info('Display controller started.')

        self.setup_sensors()
        self.setup_humidifier()

        # Up and down buttons are configured directly with RPi.GPIO so we can have threaded callbacks whenever a button press is detected. This avoids all the busy loop that we'd have to do if we used adafruit's code instead.
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.add_event_detect(5, GPIO.RISING, callback=self.button_pressed, bouncetime=50)
        GPIO.setup(6, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.add_event_detect(6, GPIO.RISING, callback=self.button_pressed, bouncetime=50)

        self._return_menu_timer = None
        self._display_update_timer = None

        self._measurement_rolling_window_size = int(self.configs.display_update_delay_seconds / \
            self.configs.measurement_delay_seconds)
        self._measurements = []

    def averaged_measures(self):
        summed_measurements = list(map(sum, zip(*self._measurements)))
        temperature = summed_measurements[0] / len(self._measurements)
        humidity = summed_measurements[1] / len(self._measurements)

        return (temperature, humidity)

    def start(self):
        self.heater_cycle()
        self.measure()
        self.make_humidifier_decision()
        self.update_display()

    def shutdown(self):
        pass

    def setup_sensors(self):
        if self.configs.sensors == 0:
            logger.warning("Controller is configured to control 0 sensors! Temperature and humidity data won't be available.")
            self._sensors = []
        else:
            logger.info(f'Controller started with {self.configs.sensors} sensors.')
            self._sensors = [adafruit_sht31d.SHT31D(self.i2c)]

            if self.configs.sensors == 2:
                self._sensors.append(adafruit_sht31d.SHT31D(self.i2c, address=0x45))

        for sensor in self._sensors:
            sensor.repeatability = adafruit_sht31d.REP_HIGH

    def setup_humidifier(self):
        if not self.configs.humidifier_connected:
            logger.warning(
                "Controller is configured without a humidifer connected! The controller won't be able to control humidity.")
            self.humidifier_control = None
        else:
            logger.info('Humidifier control configured.')
            self.humidifier_control = digitalio.DigitalInOut(board.D24)
            self.humidifier_control.switch_to_output()

    def button_pressed(self, channel):
        if self._return_menu_timer is not None:
            self._return_menu_timer.cancel()
            self._return_menu_timer = None

        if channel == 6:
            self.state.top_button_pressed()
        elif channel == 5:
            self.state.bottom_button_pressed()

        self._return_menu_timer = Timer(
            self.configs.menu_return_delay_seconds, self.return_to_general_menu)
        self._return_menu_timer.start()
        self.update_display(delay=True)

    def return_to_general_menu(self):
        self.state.mode = CheeseCaveControllerMode.GENERAL_INFO
        self.update_display()
        self._return_menu_timer = None

    def heater_cycle(self):
        new_timer = None

        if self.state.heater_on:
            for sensor in self._sensors:
                sensor.heater = False
            self.state.heater_on = False
            new_timer = Timer(
                self.configs.heater_delay_seconds, self.heater_cycle)
        else:
            for sensor in self._sensors:
                sensor.heater = True
            self.state.heater_on = True
            new_timer = Timer(self.configs.heater_on_seconds, self.heater_cycle)

        new_timer.start()

    def update_display(self, delay=False):
        if self._display_update_timer is not None:
            self._display_update_timer.cancel()

        if not delay:
            self.display_controller.update_display()

        next_update_in = self.configs.display_update_delay_seconds
        if delay:
            next_update_in = self.configs.display_update_input_delay_seconds

        self._display_update_timer = Timer(next_update_in, self.update_display)
        self._display_update_timer.start()

    def measure(self):
        temperature = []
        humidity = []

        for sensor in self._sensors:
            temperature.append(sensor.temperature)
            humidity.append(sensor.relative_humidity)

        # Denominator has a max() to handle case when any of the lists is empty.
        temperature = sum(temperature) / max(1, len(temperature))
        humidity = sum(humidity) / max(1, len(humidity))

        self._measurements.append((temperature, humidity))

        exceeded_measurements = len(self._measurements) - self._measurement_rolling_window_size
        if exceeded_measurements > 0:
            # Getting rid of the oldest measurements that exceed the capacity.
            self._measurements = self._measurements[exceeded_measurements:]

        avg_measures = self.averaged_measures()
        self.state.temperature = avg_measures[0]
        self.state.humidity = avg_measures[1]

        new_timer = Timer(self.configs.measurement_delay_seconds, self.measure)
        new_timer.start()

    def turn_off_humidifier(self):
        if self.humidifier_control is None or not self.state.humidifier_state:
            return

        logger.debug('Turning humidifier off.')

        self.humidifier_control.value = True
        sleep(0.05)
        self.humidifier_control.value = False
        self.state.humidifier_state = False

    def turn_on_humidifier(self):
        if self.humidifier_control is None or (self.state.humidifier_state or not self.state.has_water):
            return

        logger.debug('Turning humidifier on.')

        self.humidifier_control.value = True
        sleep(0.05)
        self.humidifier_control.value = False
        sleep(0.1)
        self.humidifier_control.value = True
        sleep(0.05)
        self.humidifier_control.value = False
        self.state.humidifier_state = True

    def make_humidifier_decision(self):
        if self.state.humidity >= self.state.desired_humidity:
            self.turn_off_humidifier()
        else:
            self.turn_on_humidifier()

        new_timer = Timer(
            self.configs.humidifier_decision_delay_seconds, self.make_humidifier_decision)
        new_timer.start()

if __name__ == "__main__":
    logging.basicConfig(
        format='%(asctime)s [%(levelname)s] %(module)s: %(message)s', level=logging.DEBUG)
    logger.info('Initializing controller.')
    controller = CheeseCaveController()
    logger.info('Controller initialized. Starting.')
    controller.start()
    logger.info('Controller started. Will now enter an infinite sleep loop.')
    while True:
        sleep(3600)


#!/usr/bin/env python3

dom_ids=open('t.ls').read().split()

seqs={}
ifile=open('index/cath_s35.seq')
for line in ifile:
    dom_id=line.strip()[1:]
    seq=ifile.readline().strip()
    if dom_id in dom_ids: seqs[dom_id]=seq
ifile.close()

stride_ss={}
ifile=open('index/cath_s35.stride')
for line in ifile:
    dom_id=line.strip()[1:]
    ss=ifile.readline().strip()
    if dom_id in dom_ids: stride_ss[dom_id]=ss
ifile.close()

stride_acc={}
ifile=open('index/cath_s35.stride.acc')
for line in ifile:
    dom_id=line.strip()[1:]
    accs=ifile.readline().strip().split()
    if dom_id in dom_ids: stride_acc[dom_id]=accs
ifile.close()

#######################################
# read the DSSP file

for dom_id in dom_ids:
    seq=seqs[dom_id]
    acc=stride_acc[dom_id]
    ss=list(stride_ss[dom_id])

    ifile=open('dssp_ss/'+dom_id)
    for line in ifile:
        if line.startswith('  #  RESIDUE') :
            break;

    for line in ifile:
        if line[13]=='!':
            continue
        seq_index=int(line[5:10])-1
        aa=line[13]
        if aa != seq[seq_index]:
            print('error readling ',dom_id, seq_index)

        res_ss=line[16]
        if res_ss==' ' : res_ss='C'
        ss[seq_index]=res_ss

        res_acc=line[34:38].strip()
        acc[seq_index]=res_acc

    ifile.close()

    print('>'+dom_id)
    # print(''.join(ss))
    # print(' '.join(acc))


def is_triangle(a, b, c):
    if a + b > c and a + c > b and b + c > a:
        return True
    else:
        return False

# P bool
# R bool if 3 given integers could make a triangle
# E [1, 2, 4] -> False [2, 2, 3 ]-> True
# P test for triangle is any 2 sides must be greater than the 3rd side. Could sort and add the 2 smaller or write out the 3 combos as comparrisons


from datetime import datetime, timedelta

import pandas as pd
import pytest
from elasticsearch.helpers import BulkIndexError

from eland import DataFrame, pandas_to_eland
from tests.common import (
    ES_TEST_CLIENT,
    assert_frame_equal,
    assert_pandas_eland_frame_equal,
)

dt = datetime.utcnow()
pd_df = pd.DataFrame(
    {
        "a": [1, 2, 3],
        "b": [1.0, 2.0, 3.0],
        "c": ["A", "B", "C"],
        "d": [dt, dt + timedelta(1), dt + timedelta(2)],
    },
    index=["0", "1", "2"],
)

pd_df2 = pd.DataFrame({"Z": [3, 2, 1], "a": ["C", "D", "E"]}, index=["0", "1", "2"])

@pytest.fixture(scope="function", autouse=True)
def delete_test_index():
    ES_TEST_CLIENT.indices.delete(index="test-index", ignore=404)
    yield
    ES_TEST_CLIENT.indices.delete(index="test-index", ignore=404)

class TestPandasToEland:
    def test_returns_eland_dataframe(self):
        df = pandas_to_eland(
            pd_df, es_client=ES_TEST_CLIENT, es_dest_index="test-index"
        )

        assert isinstance(df, DataFrame)
        assert "es_index_pattern: test-index" in df.es_info()

    def test_es_if_exists_fail(self):
        pandas_to_eland(pd_df, es_client=ES_TEST_CLIENT, es_dest_index="test-index")

        with pytest.raises(ValueError) as e:
            pandas_to_eland(pd_df, es_client=ES_TEST_CLIENT, es_dest_index="test-index")

        assert str(e.value) == (
            "Could not create the index [test-index] because it "
            "already exists. Change the 'es_if_exists' parameter "
            "to 'append' or 'replace' data."
        )

    def test_es_if_exists_replace(self):
        # Assert that 'replace' allows for creation
        df1 = pandas_to_eland(
            pd_df2,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="replace",
            es_refresh=True,
        ).to_pandas()
        assert_frame_equal(pd_df2, df1)

        # Assert that 'replace' will replace existing mapping and entries
        df2 = pandas_to_eland(
            pd_df,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="replace",
            es_refresh=True,
        )
        assert_pandas_eland_frame_equal(pd_df, df2)

        df3 = pandas_to_eland(
            pd_df2,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="replace",
            es_refresh=True,
        ).to_pandas()
        assert_frame_equal(df1, df3)

    def test_es_if_exists_append(self):
        df1 = pandas_to_eland(
            pd_df,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="append",
            es_refresh=True,
            # We use 'short' here specifically so that the
            # assumed type of 'long' is coerced into a 'short'
            # by append mode.
            es_type_overrides={"a": "short"},
        )
        assert_pandas_eland_frame_equal(pd_df, df1)
        assert df1.shape == (3, 4)

        pd_df2 = pd.DataFrame(
            {
                "a": [4, 5, 6],
                "b": [-1.0, -2.0, -3.0],
                "c": ["A", "B", "C"],
                "d": [dt, dt - timedelta(1), dt - timedelta(2)],
            },
            index=["3", "4", "5"],
        )
        df2 = pandas_to_eland(
            pd_df2,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="append",
            es_refresh=True,
        )

        # Assert that the second pandas dataframe is actually appended
        assert df2.shape == (6, 4)
        # use the "private" append method that's still available in pandas 2.0
        pd_df3 = pd_df._append(pd_df2)
        assert_pandas_eland_frame_equal(pd_df3, df2)

    def test_es_if_exists_append_mapping_mismatch_schema_enforcement(self):
        df1 = pandas_to_eland(
            pd_df,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="append",
            es_refresh=True,
        )

        with pytest.raises(ValueError) as e:
            pandas_to_eland(
                pd_df2,
                es_client=ES_TEST_CLIENT,
                es_dest_index="test-index",
                es_if_exists="append",
            )

        assert str(e.value) == (
            "DataFrame dtypes and Elasticsearch index mapping aren't compatible:\n"
            "- 'b' is missing from DataFrame columns\n"
            "- 'c' is missing from DataFrame columns\n"
            "- 'd' is missing from DataFrame columns\n"
            "- 'Z' is missing from ES index mapping\n"
            "- 'a' column type ('keyword') not compatible with ES index mapping type ('long')"
        )

        # Assert that the index isn't modified
        assert_pandas_eland_frame_equal(pd_df, df1)

    def test_es_if_exists_append_mapping_mismatch_no_schema_enforcement(self):
        pandas_to_eland(
            pd_df,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="append",
            es_refresh=True,
        )

        pd_df2 = pd.DataFrame(
            {
                "a": [4, 5, 6],
                "b": [-1.0, -2.0, -3.0],
                "d": [dt, dt - timedelta(1), dt - timedelta(2)],
                "e": ["A", "B", "C"],
            },
            index=["3", "4", "5"],
        )

        pandas_to_eland(
            pd_df2,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="append",
            es_refresh=True,
            es_verify_mapping_compatibility=False,
        )

        final_df = pd.DataFrame(
            {
                "a": [1, 2, 3, 4, 5, 6],
                "b": [1.0, 2.0, 3.0, -1.0, -2.0, -3.0],
                "c": ["A", "B", "C", None, None, None],
                "d": [
                    dt,
                    dt + timedelta(1),
                    dt + timedelta(2),
                    dt,
                    dt - timedelta(1),
                    dt - timedelta(2),
                ],
                "e": [None, None, None, "A", "B", "C"],
            },
            index=["0", "1", "2", "3", "4", "5"],
        )

        eland_df = DataFrame(ES_TEST_CLIENT, "test-index")
        # Assert that the index isn't modified
        assert_pandas_eland_frame_equal(final_df, eland_df)

    def test_es_if_exists_append_es_type_coerce_error(self):
        df1 = pandas_to_eland(
            pd_df,
            es_client=ES_TEST_CLIENT,
            es_dest_index="test-index",
            es_if_exists="append",
            es_refresh=True,
            es_type_overrides={"a": "byte"},
        )
        assert_pandas_eland_frame_equal(pd_df, df1)

        pd_df_short = pd.DataFrame(
            {
                "a": [128],  # This value is too large for 'byte'
                "b": [-1.0],
                "c": ["A"],
                "d": [dt],
            },
            index=["3"],
        )

        with pytest.raises(BulkIndexError) as e:
            pandas_to_eland(
                pd_df_short,
                es_client=ES_TEST_CLIENT,
                es_dest_index="test-index",
                es_if_exists="append",
            )

        # Assert that the value 128 caused the index error
        assert "Value [128] is out of range for a byte" in str(e.value.errors)

    def test_pandas_to_eland_text_inserts_keyword(self):
        es = ES_TEST_CLIENT
        df1 = pandas_to_eland(
            pd_df,
            es_client=es,
            es_dest_index="test-index",
            es_if_exists="append",
            es_refresh=True,
            es_type_overrides={
                "c": "text",
                "b": {"type": "float"},
                "d": {"type": "text"},
            },
        )
        assert es.indices.get_mapping(index="test-index") == {
            "test-index": {
                "mappings": {
                    "properties": {
                        "a": {"type": "long"},
                        "b": {"type": "float"},
                        "c": {
                            "fields": {"keyword": {"type": "keyword"}},
                            "type": "text",
                        },
                        "d": {"type": "text"},
                    }
                }
            }
        }

        # 'c' is aggregatable on 'keyword'
        assert df1.groupby("c").mean().to_dict() == {
            "a": {"A": 1.0, "B": 2.0, "C": 3.0},
            "b": {"A": 1.0, "B": 2.0, "C": 3.0},
        }

        # 'd' isn't aggregatable because it's missing the 'keyword'
        with pytest.raises(ValueError) as e:
            df1.groupby("d").mean()
        assert str(e.value) == (
            "Cannot use 'd' with groupby() because it has "
            "no aggregatable fields in Elasticsearch"
        )


# https://leetcode.com/problems/add-binary/
def addBinary(a,b):
	totalLen = len(a) + len(b)
	a = a.zfill(totalLen)
	b = b.zfill(totalLen)
	listA = list(a)
	listB = list(b)
	#  we need to reverse
	carry = 0
	i = totalLen - 1
	addList = [0] * (totalLen+1)

	while(i >= 0):
		addition = 0
		addition = int(listA[i]) + int(listB[i]) + carry

		if(addition == 0):
			# we cant do a thing
			carry = 0

		elif(addition == 1):
			carry = 0

		elif(addition == 2):
			carry = 1
			addition = 0

		else:
			# its addition = 3
			carry = 1
			addition = 1

		# insert the value to the array
		addList[i+1] = addition

		i -= 1

	# print(list(a))
	# print(' + ')
	# print(list(b))
	# print(' = ')
	# print(addList)

	s = int(''.join(str(e) for e in addList))
	return (str(s))

print(addBinary("1010","1011"))


# -*- coding:ascii -*-
from mako import runtime, filters, cache
UNDEFINED = runtime.UNDEFINED
__M_dict_builtin = dict
__M_locals_builtin = locals
_magic_number = 10
_modified_time = 1421282545.317255
_enable_loop = True
_template_filename = '/Users/jeffreymccraney/test_dmp/homepage/templates/contact.html'
_template_uri = 'contact.html'
_source_encoding = 'ascii'
import os, os.path, re
_exports = ['content']

def _mako_get_namespace(context, name):
    try:
        return context.namespaces[(__name__, name)]
    except KeyError:
        _mako_generate_namespaces(context)
        return context.namespaces[(__name__, name)]
def _mako_generate_namespaces(context):
    pass
def _mako_inherit(template, context):
    _mako_generate_namespaces(context)
    return runtime._inherit_from(context, 'base.htm', _template_uri)
def render_body(context,**pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        __M_locals = __M_dict_builtin(pageargs=pageargs)
        def content():
            return render_content(context._locals(__M_locals))
        __M_writer = context.writer()
        __M_writer('\n\n')
        if 'parent' not in context._data or not hasattr(context._data['parent'], 'content'):
            context['self'].content(**pageargs)

        return ''
    finally:
        context.caller_stack._pop_frame()

def render_content(context,**pageargs):
    __M_caller = context.caller_stack._push_frame()
    try:
        def content():
            return render_content(context)
        __M_writer = context.writer()
        __M_writer('\n
\n    \t
 Email: mccraney.j@gmail.com
\n\t\t
\n\t\t\t
\n\t\t\t
\n\t\t\t      <input type="text" class="form-control" placeholder="Enter Email...">\n\t\t\t      \n\t\t\t        <button class="btn btn-primary" type="button">Primary</button>\n\t\t\t      \n\t\t\t
\n\t\t\t
\n\t\t
\n
\n
\n
\n        <button class="btn btn-success" type="button">Success!</button>\n')
        return ''
    finally:
        context.caller_stack._pop_frame()

"""
__M_BEGIN_METADATA
{"filename": "/Users/jeffreymccraney/test_dmp/homepage/templates/contact.html", "uri": "contact.html", "line_map": {"56": 50, "34": 1, "27": 0, "44": 3, "50": 3}, "source_encoding": "ascii"}
__M_END_METADATA
"""


import pandas as pd # library for data analysis
import requests # library to handle requests
from bs4 import BeautifulSoup # library to parse HTML documents
import re # library for regular expressions
import plotly # library for plotting
import plotly.express as px # library for plotting
import pycountry_convert as pc # library to convert country names into codes for mapping
from plotly import graph_objs as go # library for plotting
import numpy as np # library for math
from flask import Flask, render_template # library for website
from flask import request
import json # library for dealing with JSON files

app = Flask(__name__)

@app.route("/")
def home():
    return render_template("home.html")

@app.route("/graph",methods=["GET","POST"])
def graph():
    question=request.form['Question']
    search = question + 'wikipedia'
    url = 'https://www.google.com/search?q='

    headers = {
        'Accept' : '*/*',
        'Accept-Language': 'en-US,en;q=0.5',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82',
    }

    parameters = {'q': search}

    content = requests.get(url, headers = headers, params = parameters).text
    soup = BeautifulSoup(content, 'html.parser')

    search = soup.find(id = 'search')
    first_link = search.find('a')

    wikiurl=(first_link['href'])
    table_class="wikitable sortable jquery-tablesorter"
    response=requests.get(wikiurl)

    soup = BeautifulSoup(response.text, 'html.parser')
    table=soup.find('table',{'class':"wikitable"})

    df=pd.read_html(str(table))
    df=pd.DataFrame(df[0])

    if df.columns[0]=="Rank" or df[df.columns[0]].iloc[0]==1 or df[df.columns[0]].iloc[0]=="1." or df[df.columns[0]].iloc[0]=="—":
        df=df.drop(df.columns[0], axis=1)

    if type(df[df.columns[1]].iloc[0])==str:
        if any(chr.isdigit() for chr in df[df.columns[1]].iloc[0])==False:
            df=df.drop(df.columns[1], axis=1)

    a=(df.columns[0])
    b=(df.columns[1])

    if df[a][0]=="World":
        df=df.drop(index=0)

    try:
        df[b]=df[b].str.replace(r'\[.*\]','')
        df[b] = df[b].str.replace(r'\D+', '')
    except:
        pass

    try:
        df[a]=df[a].str.replace(r'\[.*\]','')
        df[a]=df[a].str.replace(r'\(.*\)','')
    except:
        pass

    df[b] = df[b].replace(r'^\s*$', np.nan, regex=True)

    df[b]= df[b].astype(float)

    first=(df[b].iloc[0])
    last=(df[b].iloc[len(df[b])-1])
    secondlast=(df[b].iloc[len(df[b])-2])

    if (last/first)>1:
        df = df[:-1]
    if (secondlast/first)>1:
        df = df[:-2]

    fig=px.bar(df,x=a,y=b)

    graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)

    if (df[a].eq('China')).any() == True or (df[a].eq('Brazil')).any() == True:
        # creating a function to convert the country names to alpha3 codes that plotly can process into a map
        df.rename(columns={ df.columns[0]: "Country" }, inplace = True)
        def convert(row):
            try: cn_code = pc.country_name_to_country_alpha3(row.Country, cn_name_format = "default")
            except: cn_code="VAT"

            return(cn_code)
        df["Alpha3"]= df.apply(convert,axis=1)

        # maping the data using plotly
        fig=go.Figure(data = go.Choropleth(locations=df["Alpha3"],z=df[b]))
        fig.update_layout(autosize=False,width=1200,height=600,)

        graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)

    return render_template('home.html', graphJSON=graphJSON)


from abc import ABC, abstractmethod
from typing import Any, List, Tuple

import numpy as np
from collections import Counter

from game.utils import Card, GamePhase

class Agent(ABC):
    @abstractmethod
    def play(self, observation: dict, actions: List[Any]) -> Any:
        pass

    def parallel_play(self, observations: List[dict],
                      action_list: List[List[Any]]) -> List[Any]:
        actions_to_play = []
        for observation, actions in zip(observations, action_list):
            actions_to_play.append(self.play(observation, actions))
        return actions_to_play

class RandomPlayer(Agent):
    def play(self, observation: dict, actions: List[Any]) -> Any:
        if observation['phase'] == GamePhase.DURCH:
            if np.random.rand() < 0.985:
                return False
            else:
                return True

        if observation['phase'] == GamePhase.DECLARATION:
            if np.random.rand() < 0.5:
                return ()

        idx = np.random.randint(len(actions))
        return actions[idx]

class PartialRandomPlayer(Agent):
    def play(self, observation: dict, actions: List[Any]) -> Any:
        phase = observation['phase']
        if phase == GamePhase.PLAY:
            idx = np.random.randint(len(actions))
            return actions[idx]
        elif phase == GamePhase.MOVING:
            return self._move_cards(observation['hand'])
        elif phase == GamePhase.DURCH:
            return False
        elif phase == GamePhase.DECLARATION:
            return ()

    def _move_cards(self, hand: List[Card]) -> List[Card]:
        values = [x.value for x in hand]
        idx = np.argsort(values)[-2:]
        return [hand[idx[0]], hand[idx[1]]]

class LowPlayer(Agent):
    def play(self, observation: dict, actions: List[Any]) -> Any:
        phase = observation['phase']
        if phase == GamePhase.PLAY:
            return self._play_phase(observation)
        elif phase == GamePhase.MOVING:
            return self._move_cards(observation['hand'], actions)
        elif phase == GamePhase.DURCH:
            return False
        elif phase == GamePhase.DECLARATION:
            return ()

    def _move_cards(self, hand: List[Card], actions: List[Any]) -> Tuple[Card, Card]:
        values = [x.value for x in hand]
        idx = np.argsort(values)[-2:]
        if (hand[idx[0]], hand[idx[1]]) in actions:
            return hand[idx[0]], hand[idx[1]]
        else:
            return hand[idx[1]], hand[idx[0]]

    def _play_phase(self, features: dict) -> Card:
        pot = features['pot']
        hand = features['hand']

        if pot.is_empty():
            smallest_colour = get_smallest_colour(hand)
            return get_smallest_card(hand, smallest_colour)
        else:
            choices = get_sorted_cards_of_colour(hand, pot.get_pot_colour())
            if len(choices) == 0:
                card, point = get_highest_points_card(hand, return_value=True)
                if point >= 2:
                    return card
                return get_largest_card(hand)
            else:
                if choices[0].is_higher_value(pot.get_highest_card()):
                    vals = [c.value for c in choices]
                    pos = np.searchsorted(vals, pot.get_highest_card().value)
                    under = choices[:pos]
                    points = [c.get_point_value() for c in under]
                    idx = np.argmax(points)
                    if points[idx] >= 2:
                        return under[idx]
                    else:
                        return under[-1]
                else:
                    return choices[-1]

def get_smallest_card(hand, colour=None):
    if colour is not None:
        return get_sorted_cards_of_colour(hand, colour)[0]
    else:
        idx = np.argmin([c.value for c in hand])
        return hand[idx]

def get_largest_card(hand, colour=None):
    if colour is not None:
        return get_sorted_cards_of_colour(hand, colour)[-1]
    else:
        idx = np.argmax([c.value for c in hand])
        return hand[idx]

def get_highest_points_card(hand, return_value=False):
    vals = [c.get_point_value() for c in hand]
    idx = np.argmax(vals)
    if return_value:
        return hand[idx], vals[idx]
    else:
        return hand[idx]

def get_smallest_colour(hand):
    c = get_colour_counts(hand)
    return c.most_common()[-1][0]

def get_colour_counts(hand):
    c = Counter()
    for card in hand:
        c[card.colour] += 1
    return c

def get_sorted_cards_of_colour(hand, colour):
    return np.sort([c for c in hand if c.colour == colour])


# -*- coding:utf-8 -*-
import os, argparse, sys, re
import numpy as np
import pandas as pd
import scipy.io as sio

parser = argparse.ArgumentParser(description='Step 7: Construct AllDat Matrix in .mat format for each chromosome')
parser.add_argument('-data_dir', type=str, default="../data/", help='The data directory where merged 0h, 1h, 4h, 16h bed files for each chromosomes stored')
parser.add_argument('-out_dir', type=str, default="../data/AllDat", help='The output directory to store the AllDat_chrx.mat files')

def mkdir(dir_path):
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)

def construct_allDat_matrix(data_dir, out_dir, sep="\t"):
    TIME_POINTS = ['0h', '1h', '4h', '16h']
    CHROMOSOMES = [str(i) for i in range(1, 23)]
    for chromosome in CHROMOSOMES:
        data_dict = {} # the dict to temperatorily store reads information
        for t_idx, time_point in enumerate(TIME_POINTS):
            repli_name = time_point + '_' + 'rep0'
            input_fp = os.path.join(data_dir, repli_name, 'chr' + chromosome + '.bed')
            with open(input_fp, "r") as input_file:
                print("Processing Chr %s, Time %s" % (chromosome, time_point))
                lines = input_file.readlines()
                for lid, line in enumerate(lines):
                    if lid and (lid + 1) % 100000 == 0:
                        print("%.1f%% for Chr %s, Time %s" % ((lid + 1.0) * 100.0 / len(lines), chromosome, time_point))
                    line_contents = re.split(sep, line.strip("\n"))
                    try:
                        chr_i, start, end, methy_reads, unmethy_reads = line_contents
                        methy_reads = int(methy_reads)
                        unmethy_reads = int(unmethy_reads)
                        site = int(start)
                        if site not in data_dict.keys():
                            data_dict[site] = np.zeros((len(TIME_POINTS), 2))
                        data_dict[site][t_idx][0] = methy_reads
                        data_dict[site][t_idx][1] = unmethy_reads
                    except ValueError as e:
                        print("ValueError in Chr %s, Time %s, Line %d :%s" % (chromosome, time_point, lid + 1, line))
        sorted_site_data = sorted(data_dict.items())
        sites = []
        mat_data = []
        for site, reads in sorted_site_data:
            sites.append(site)
            mat_data.append(reads)
        mat_data = np.array(mat_data)
        MAT_DICT = {'AllDat': mat_data, 'sites': sites}
        mkdir(out_dir)
        sio.savemat(os.path.join(out_dir, "AllDat_chr%s.mat" % chromosome), MAT_DICT)
        print("**!!FINISHED Chr %s PROCESSING!!**" % chromosome)

def construct_allDat_bed_file(data_dir, out_dir, sep="\t"):

    TIME_POINTS = ['0h', '1h', '4h', '16h']

    CHROMOSOMES = [str(i) for i in range(1, 23)]

    ltws = []

    for chromosome in CHROMOSOMES:
        data_dict = {} # the dict to temperatorily store reads information
        for t_idx, time_point in enumerate(TIME_POINTS):
            repli_name = time_point + '_' + 'rep0'
            input_fp = os.path.join(data_dir, repli_name, 'chr' + chromosome + '.bed')
            with open(input_fp, "r") as input_file:
                print("Processing Chr %s, Time %s" % (chromosome, time_point))
                lines = input_file.readlines()
                for lid, line in enumerate(lines):
                    if lid and (lid + 1) % 100000 == 0:
                        print("%.1f%% for Chr %s, Time %s" % ((lid + 1.0) * 100.0 / len(lines), chromosome, time_point))
                    line_contents = re.split(sep, line.strip("\n"))
                    try:
                        chr_i, start, end, methy_reads, unmethy_reads = line_contents
                        methy_reads = int(methy_reads)
                        unmethy_reads = int(unmethy_reads)
                        site = int(start)
                        if site not in data_dict.keys():
                            data_dict[site] = np.zeros((len(TIME_POINTS), 2))
                        data_dict[site][t_idx][0] = methy_reads
                        data_dict[site][t_idx][1] = unmethy_reads
                    except ValueError as e:
                        print("ValueError in Chr %s, Time %s, Line %d :%s" % (chromosome, time_point, lid + 1, line))

        for site, dct in data_dict.items():
            vals = ["chr%s" % chromosome, str(site), str(site + 1)]
            for meth in range(2):
                for t_idx, time_point in enumerate(TIME_POINTS):
                    vals.append(str(dct[t_idx][meth]))
            ltw = "\t".join(vals) + "\n"
            ltws.append(ltw)

    mkdir(out_dir)
    outfp = os.path.join(out_dir, "AllDat.bed")
    with open(outfp, "w") as alldata_f:
        alldata_f.writelines(ltws)
    print("**!!FINISHED WRITING into %s !!**" % outfp)

def get_chrom_start_locis():
    chr_offset_sz = 1000000000
    chromosomes = ["chr%d" % j for j in range(1, 23)] + ["chrX", "chrY"]
    chrom_start_loci = {chrm: (i + 1) * chr_offset_sz for i, chrm in enumerate(chromosomes)}
    return chrom_start_loci

def convert_allDat_bed_to_mat(data_fp, out_fp):
    print("**!!START %s PROCESSING!!**" % data_fp)
    data_df = pd.read_csv(data_fp, sep="\t", header=None).values
    TIME_POINTS = ['0h', '1h', '4h', '16h']
    chrom_start_loci_dict = get_chrom_start_locis()
    data_dict = {}# the dict to temperatorily store reads information
    for item in data_df:
        chrom, start, end = item[0], item[1], item[2]
        site = chrom_start_loci_dict[chrom] + int(start)
        offset = 0
        if site not in data_dict.keys():
            data_dict[site] = np.zeros((len(TIME_POINTS), 2))
        for meth in range(2):
            for t_idx, time_point in enumerate(TIME_POINTS):
                data_dict[site][t_idx][meth] = int(item[3+offset])
                offset += 1
    sorted_site_data = sorted(data_dict.items())
    sites = []
    mat_data = []
    for site, reads in sorted_site_data:
        sites.append(site)
        mat_data.append(reads)
    mat_data = np.array(mat_data)
    MAT_DICT = {'AllDat': mat_data, 'sites': sites}
    sio.savemat(out_fp, MAT_DICT)
    print("**!!FINISHED %s PROCESSING!!**" % data_fp)
if __name__ == "__main__":
    args = parser.parse_args()
    # if len(sys.argv) <= 1:
    #     parser.print_help()
    # else:
    # data_dir = args.data_dir
    # out_dir = args.out_dir
    # construct_allDat_bed_file(data_dir, out_dir)
    regions = ["CGI", "Promoter",
                                "TFBR", "Exons", "Introns", "Intergenic", "5UTR", "3UTR",
                                "H2AZ", "LINE", "SINE", "LTR", "DNase", "Enhancer"]
    input_dir = "../data/AllDat/AllDat_Region_Intersect"
    output_dir = "../data/AllDat/AllDat_Region_Intersect_mat"
    mkdir(output_dir)
    for region in regions:
        input_fp = os.path.join(input_dir, "AllDat_%s.bed" % (region))
        output_fp = os.path.join(output_dir, "AllDat_%s.mat" % (region))
        convert_allDat_bed_to_mat(input_fp, output_fp)


from project.client import Client
from project.meals.dessert import Dessert
from project.meals.main_dish import MainDish
from project.meals.meal import Meal
from project.meals.starter import Starter

class FoodOrdersApp:
    RECEIPT_ID = 0
    VALID_MEALS = {"Starter": Starter, "MainDish": MainDish, "Dessert": Dessert}

    def __init__(self):
        self.menu: list = []
        self.clients_list: list = []

    @staticmethod
    def find_object(item: str, attribute: str, collection: list):
        for obj in collection:
            if getattr(obj, attribute) == item:
                return obj

    def register_client(self, client_phone_number: str):
        if client_phone_number in [client.phone_number for client in self.clients_list]:
            raise Exception("The client has already been registered!")

        self.clients_list.append(Client(client_phone_number))

        return f"Client {client_phone_number} registered successfully."

    def add_meals_to_menu(self, *meals: Meal):
        for meal in meals:
            if isinstance(meal, Meal):
                self.menu.append(meal)

    def show_menu(self):
        if len(self.menu) < 5:
            raise Exception("The menu is not ready!")

        menu = [meal.details() for meal in self.menu]

        return "\n".join(menu)

    def add_meals_to_shopping_cart(self, client_phone_number: str, **meal_names_and_quantities):
        cart = []
        bill = 0

        if len(self.menu) < 5:
            raise Exception("The menu is not ready!")

        if client_phone_number not in [client.phone_number for client in self.clients_list]:
            self.register_client(client_phone_number)

        client = self.find_object(client_phone_number, "phone_number", self.clients_list)

        for meal_name, quantity in meal_names_and_quantities.items():
            if meal_name not in [x.name for x in self.menu]:
                raise Exception(f"{meal_name} is not on the menu!")

            meal = [m for m in self.menu if m.name == meal_name][0]

            if meal.quantity < quantity:
                raise Exception(f"Not enough quantity of {meal.__class__.__name__}: {meal_name}!")

            meal.quantity -= quantity

            bought_meal = FoodOrdersApp.VALID_MEALS[meal.__class__.__name__](meal_name, meal.price, quantity)
            cart.append(bought_meal)
            bill += quantity * meal.price

        client.shopping_cart.extend(cart)
        client.bill += bill

        return f"Client {client_phone_number} successfully ordered " \
               f"{', '.join(x.name for x in client.shopping_cart)} for {client.bill:.2f}lv."

    def cancel_order(self, client_phone_number: str):
        client = self.find_object(client_phone_number, "phone_number", self.clients_list)

        if len(client.shopping_cart) == 0:
            raise Exception("There are no ordered meals!")

        for meal in client.shopping_cart:
            for menu_item in self.menu:
                if meal.name == menu_item.name:
                    menu_item.quantity += meal.quantity

        client.bill = 0
        client.shopping_cart.clear()

        return f"Client {client_phone_number} successfully canceled his order."

    def finish_order(self, client_phone_number: str):
        client = next(filter(lambda x: x.phone_number == client_phone_number, self.clients_list))

        if len(client.shopping_cart) == 0:
            raise Exception("There are no ordered meals!")

        total_paid_money = client.bill
        client.bill = 0
        client.shopping_cart.clear()
        FoodOrdersApp.RECEIPT_ID += 1

        return f"Receipt #{FoodOrdersApp.RECEIPT_ID} with total amount of {total_paid_money:.2f} " \
               f"was successfully paid for {client_phone_number}."

    def __str__(self):
        return f"Food Orders App has {len(self.menu)} meals on the menu and {len(self.clients_list)} clients."

16 Past Exams/03 Python OOP Retake Exam - 22 August 2022/01. Structure_Skeleton/project/food_orders_app.py


# -*- encoding: utf-8 -*-
import datetime
import subprocess as sp
import logging

from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.db import transaction
from django.db.models import Q
from celery import task
from opps.utils.text import split_tags

from .models import MediaHost
from .mediaapi import MediaAPIError

# Get an instance of a logger
logger = logging.getLogger(__name__)

BLACKLIST = getattr(settings, 'OPPS_MULTIMEDIAS_BLACKLIST', [])
LOCAL_MAX_PARALLEL = getattr(
    settings, 'OPPS_MULTIMEDIAS_LOCAL_MAX_PARALLEL', 1)
UPLOAD_MEDIA_INTERVAL = getattr(
    settings, 'OPPS_MULTIMEDIAS_UPLOAD_MEDIA_INTERVAL', 5)
UPDATE_MEDIAHOST_INTERVAL = getattr(
    settings, 'OPPS_MULTIMEDIAS_UPDATE_MEDIAHOST_INTERVAL', 2)

@task.periodic_task(run_every=timezone.timedelta(
    minutes=UPLOAD_MEDIA_INTERVAL))
def upload_media():
    mediahosts = MediaHost.objects.filter(
        status=MediaHost.STATUS_NOT_UPLOADED
    ).exclude(pk__in=BLACKLIST)

    if 'local' in settings.OPPS_MULTIMEDIAS_ENGINES:
        ffmpeg_active = False

        try:
            output = sp.check_output(
                "ps aux | grep -v grep | grep {0}".format(
                    settings.OPPS_MULTIMEDIAS_FFMPEG),
                shell=True)
            if not output:
                raise Exception("FFMPEG doesn't run!")
        except:
            MediaHost.objects.filter(
                host=MediaHost.HOST_LOCAL,
                status=MediaHost.STATUS_PROCESSING).update(
                    status=MediaHost.STATUS_NOT_UPLOADED)

    for mediahost in mediahosts:
        try:
            media = mediahost.media
        except:
            mediahost.to_delete()
            continue

        tags = split_tags(media.tags)

        if mediahost.host != MediaHost.HOST_LOCAL:
            if mediahost.host == MediaHost.HOST_VIMEO:
                mediahost.api.upload()
                continue

            mediahost.status = MediaHost.STATUS_SENDING
            mediahost.save()
            media = mediahost.media

            try:
                media_info = mediahost.api.upload(
                    media.TYPE,
                    media.media_file.path,
                    media.title,
                    media.headline,
                    tags
                )
            except Exception as e:
                logger.error(u'Error on upload {}: {}'.format(
                    unicode(mediahost.media), unicode(e)
                ))
                if mediahost.retries < 3:
                    mediahost.retries += 1
                    mediahost.status = MediaHost.STATUS_NOT_UPLOADED
                else:
                    mediahost.status = MediaHost.STATUS_ERROR
                    mediahost.status_message = _('Error on upload')
            else:
                logger.info(u'Uploaded {} - Data returned: {}'.format(
                    unicode(mediahost.media),
                    unicode(media_info)
                ))
                mediahost.host_id = media_info['id']
                mediahost.status = MediaHost.STATUS_PROCESSING

            with transaction.commit_on_success():
                mediahost.save()
        else:
            local_in_process = MediaHost.objects.filter(
                host=MediaHost.HOST_LOCAL,
                status=MediaHost.STATUS_PROCESSING).count()

            if LOCAL_MAX_PARALLEL and local_in_process >= LOCAL_MAX_PARALLEL:
                continue

            media_info = mediahost.api.upload(
                mediahost,
                tags
            )

@task.periodic_task(run_every=timezone.timedelta(minutes=2))
def update_mediahost():
    mediahosts = MediaHost.objects.filter(status=MediaHost.STATUS_PROCESSING)
    mediahosts = mediahosts.exclude(
        Q(host_id__isnull=True) | Q(host_id=''),  # Empty host_id
        host=MediaHost.HOST_LOCAL,                # Exclude local host
        pk__in=BLACKLIST,                         # exclude blacklist
        host_id='NONE')                           # Exclude NONE host_id

    for mediahost in mediahosts:
        try:
            if not mediahost.media:
                mediahost.to_delete()
                continue
        except Exception as e:
            logger.exception(e.message)
            continue

        try:
            mediahost.update()
            continue
        except Exception as e:
            logger.exception(e.message)

@task.periodic_task(run_every=timezone.timedelta(minutes=60))
def delete_mediahost():
    mediahosts = MediaHost.objects.filter(status=MediaHost.STATUS_DELETED)
    for mediahost in mediahosts:
        api = mediahost.api
        if hasattr(api, 'delete'):
            try:
                api.delete()
            except NotImplementedError:
                pass
            except MediaAPIError as e:
                logger.exception(e.message)
            else:
                mediahost.delete()


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

import sonnet as snt

from ..short_board.black_piece import  select_black_short_pieces
from ..naive_effect import ShortEffectLayer

__author__ = 'Yasuhiro'
__date__ = '2018/3/15'

class BlackNaiveShortEffectLayer(snt.AbstractModule):
    def __init__(self, direction, data_format, use_cudnn=True,
                 name='black_naive_short_effect'):
        super().__init__(name=name)
        self.direction = direction
        self.data_format = data_format
        self.use_cudnn = use_cudnn

    def _build(self, board):
        """
        非手番側の王の利きを求めるためにピンや自殺手を考慮しない手番側の利きを求める
        非手番側の王の利きを求めるレイヤー内で1度だけ使用される

        :param board:
        :return:
        """
        # 方向directionへ動ける駒が1、他は全て0
        selected_pieces = select_black_short_pieces(board=board,
                                                    direction=self.direction)
        effect = ShortEffectLayer(
            direction=self.direction, data_format=self.data_format,
            use_cudnn=self.use_cudnn,
            name='black_naive_short_effect_{}'.format(self.direction.name)
        )(selected_pieces)

        return effect


import gevent, gevent.event, gevent.greenlet, gevent.queue, greenlet
import random, pickle, logging, weakref
from types import SimpleNamespace
from function_pattern_matching import MultiFunc
import inspect
from functools import partial
import better_exceptions
import sys

from gevent import GreenletExit

class ActorStoppedError(Exception):
	__str__ = lambda x: "ActorStoppedError"

class ActorMaxIdleError(Exception):
    __str__ = lambda x: "ActorMaxIdleError"

class ActorTTLError(Exception):
    __str__ = lambda x: "ActorTTLError"

class TaskCanceledError(Exception):
    __str__ = lambda x: "TaskCanceledError"

class Task(gevent.event.AsyncResult):
	def __init__(self, msg, payload=None, sender=None):
		super().__init__()
		self.msg = msg
		self._payload = payload # pickle.dumps(payload, protocol=pickle.HIGHEST_PROTOCOL)
		self.sender = sender
		self.canceled = False

	def cancel(self):
		self.canceled = True

	@property
	def payload(self):
		return self._payload
		#return pickle.loads(self._payload)

	def set(self, value=None):
		if self.canceled:
			return TaskCanceledError
		return super().set(value)

	def get(self, *args, **kwargs):
		if self.canceled:
			return TaskCanceledError
		return super().get(*args, **kwargs)

	def __str__(self):
		return ("<Task, sender={sender}, message={msg}>"
		).format(sender=self.sender, msg=self.msg)

class Actor(object):
	def __init__(self, name=None, max_idle=None, ttl=None, loop=None, context=None, *args, **kwargs):
		self.context = context if context else SimpleNamespace()
		self._logger = logging.getLogger('root')
		self._mailbox = gevent.queue.Queue()
		self._stopped = False
		self._poisoned_pill = object()
		self._ping_pill = object()
		self._max_idle = max_idle
		self._ttl = ttl
		self._loop = gevent.spawn(loop) if loop else gevent.spawn(self._dequeue, weakref.proxy(self))
		self.name=name if name else "actor-{0}".format(self._loop.minimal_ident)

	@classmethod
	def prepare(cls, *args, **kwargs):
		return partial(cls, *args, **kwargs)

	def __str__(self):
		return "<{type} \"{name}\">".format(type=type(self).__name__, name=self.name)

	def _handle(self, task):
		try:
			self._logger.debug("{me} starts handling {task}".format(me=self, task=task))
			if isinstance(self.handle, MultiFunc):
				task.set(self.handle(self, task.msg, task.payload, task.sender))
			else:
				task.set(self.handle(task.msg, task.payload, task.sender))
			return task
		except Exception as e:
			task.set_exception(e)
			raise

	# def suspend_idle(self):
	# 	if hasattr(self, "_max_idle_timeout"):
	# 		print(f">>>--->>> {self} SUSPEND MAX IDLE {gevent.getcurrent()}")
	# 		self._max_idle_timeout.cancel()
	# 		if hasattr(self, "_parent"):
	# 			if hasattr(self._parent, "_max_idle_timeout"):
	# 				self._parent.suspend_idle()
	# 		print(f">>>--->>> {self} STATUS MAX IDLE {gevent.getcurrent()}: {self._max_idle_timeout.pending}")

	# def resume_idle(self):
	# 	if hasattr(self, "_max_idle_timeout"):
	# 		print(f">>>--->>> {self} RESUME MAX IDLE {gevent.getcurrent()}")
	# 		self._max_idle_timeout.start()
	# 		if hasattr(self, "_parent"):
	# 			if hasattr(self._parent, "_max_idle_timeout"):
	# 				self._parent.resume_idle()
	# 		print(f">>>--->>> {self} STATUS MAX IDLE {gevent.getcurrent()}: {self._max_idle_timeout.pending}")

	def _dequeue(self, parent):
		self._ttl_timeout = gevent.Timeout.start_new(timeout=self._ttl, exception=ActorTTLError)
		self._max_idle_timeout = gevent.Timeout.start_new(timeout=self._max_idle, exception=ActorMaxIdleError)
		self._stopped = False
		self._crashed = False
		try:
			for task in self._mailbox:
				gevent.idle()
				self._max_idle_timeout.close()
				if self._max_idle:
					self._logger.debug("{me} has canceled timeout of {max_idle} seconds".format(me=self, max_idle=self._max_idle))
				if isinstance(task, Task) and not task.canceled:
					self._logger.debug("{me} took {task} from mailbox".format(me=self, task=task))
					self._handle(task)
				elif task is self._poisoned_pill:
					self._logger.debug("{me} is processing the poisoned pill.".format(me=self))
					raise ActorStoppedError
				elif task is self._ping_pill:
					self._logger.debug("{me} is processing a ping.".format(me=self))
				elif isinstance(task, Task) and task.canceled:
					self._logger.debug("{me} took canceled {task} from mailbox, dismissing".format(me=self, task=task))
					continue
				self._max_idle_timeout = gevent.Timeout.start_new(timeout=self._max_idle, exception=ActorMaxIdleError)
		except ActorMaxIdleError as e:
			self._logger.debug("{me} has reached max_idle timeout of {sec} seconds.".format(me=self, sec=self._max_idle))
			self.stop()  # FIXME!!!!
		except ActorTTLError as e:
			self._logger.debug("{me} has reached ttl timeout of {sec} seconds.".format(me=self, sec=self._ttl))
			self.stop()  # FIXME!!!!
		except ActorStoppedError as e:
			self._stopped = True
		except Exception as e:
			self._stopped = True
			self._crashed = True
			formatted_exc = better_exceptions.format_exception(*sys.exc_info())
			self._logger.error(("{me} crashed with:\n{exc}").format(me=self, exc=formatted_exc))
		finally:
			self._ttl_timeout.close()
			self._max_idle_timeout.close()
			if hasattr(self, "_parent"):
				self._parent._handle_child(self, "crashed" if self._crashed else "stopped")

	def handle(self, message, payload=None, sender=None):
		"""Override in your own Actor subclass"""
		raise NotImplementedError('Please subclass Actor and implement the handle() method')

	def _receive(self, msg, payload=None, sender=None):
		gevent.idle() # UGLY: Find a better place for this
		sending_greenlet = gevent.getcurrent()
		if sender:
			sender = sender
		elif isinstance(getattr(sending_greenlet, '_actor', None), Actor):
			sender = sending_greenlet._actor
		elif isinstance(sending_greenlet, Actor):
			sender = sending_greenlet
		else:
			l = inspect.stack()[1][0].f_locals
			if "self" in l:
				sender = l["self"]
			else:
				sender = None
		task = Task(msg, payload, sender)
		return self._enqueue(task)

	def _enqueue(self, task):
		if self._stopped:
			self._logger.warn("{me} is stopped and rejects {task}".format(me=self, task=task))
			raise ActorStoppedError
		else:
			self._mailbox.put(task)
			self._logger.debug("{me} received {task}".format(me=self, task=task))
		return task

	def _kill(self):
		self._stopped = True
		self._logger.debug("{me} received order to stop immediately.".format(me=self))
		try:
			self._loop.kill()
		except GreenletExit:
			pass
		self.clear()
		self._parent._handle_child(self, "stopped")

	def tell(self, msg, payload=None, sender=None):
		"""Send a message, get nothing (fire-and-forget)."""
		self._receive(msg, payload=payload, sender=sender)

	def ask(self, msg, payload=None, sender=None):
		"""Send a message, get a future."""
		return self._receive(msg, payload=payload, sender=sender)

	def wait_for(self, msg, payload=None, sender=None, timeout=None, retry=1):
		"""Send a message, get a result"""
		for it in range(retry):
			try:
				return self._receive(msg, payload=payload, sender=sender).get(timeout=timeout)
			except (ActorStoppedError, gevent.Timeout) as exc:
				last_exc = exc
				continue
		raise last_exc

	def start(self):
		if self._stopped:
			self._loop = gevent.spawn(self._dequeue, weakref.proxy(self))
			self._stopped = False
			self._logger.debug("{me} has resumed operation.".format(me=self))
		else:
			self._logger.debug("{me} is already started.".format(me=self))

	def stop(self):
		if not self._stopped:
			self._stopped = True
			self._logger.debug("{me} received order to stop.".format(me=self))
			self._mailbox.put(self._poisoned_pill)
		else:
			self._logger.debug("{me} is already stopped.".format(me=self))

	def ping(self):
		if not self._stopped:
			self._logger.debug("{me} received ping message.".format(me=self))
			self._mailbox.put(self._ping_pill)
		else:
			self._logger.debug("{me} is stopped.".format(me=self))

	def clear(self):
		self.context = SimpleNamespace()
		while len(self._mailbox) > 0:
			task = self._mailbox.get()
			if isinstance(task, Task):
				self._logger.debug("{me} is rejecting {task}".format(me=self, task=task))
				task.set_exception(ActorStoppedError)

	def resume(self):
		self.start()

	def restart(self):
		self.stop()
		self.clear()
		self.start()

	def __del__(self):
		try:
			self._loop.kill()
		except GreenletExit:
			pass
		self.clear()

	def register_parent(self, parent):
		self._parent = weakref.proxy(parent)
		self._logger.debug("{me} registered {par} as its parent.".format(me=self, par=parent))

	def wait_idle(self):
		self._mailbox.join()

	def join(self):
		self._loop.join()


from pymoo.core.sampling import Sampling
import numpy as np
from boolcryptogp.nsgp.structure.WalshTransform import WalshTransform
from boolcryptogp.nsgp.structure.ANFBooleanFunction import ANFBooleanFunction
from boolcryptogp.nsgp.structure.TreeStructure import TreeStructure

class ANFBooleanFunctionSampling(Sampling):

    def __init__(self,
                 structure: TreeStructure,
                 walsh: WalshTransform,
                 n_trees: int = None,
                 n_trees_min: int = 2,
                 n_trees_max: int = 10,
                 tree_prob: float = 0.70):
        super().__init__()
        self.__walsh: WalshTransform = walsh
        self.__structure: TreeStructure = structure
        self.__n_trees: int = n_trees
        self.__n_trees_min: int = n_trees_min
        self.__n_trees_max: int = n_trees_max
        self.__tree_prob: float = tree_prob

    def _do(self, problem, n_samples, **kwargs):
        x = np.empty((n_samples, 1), dtype=object)

        for i in range(n_samples):
            x[i, 0] = ANFBooleanFunction(self.__walsh, self.__structure.generate_forest(
                                         n_trees=self.__n_trees,
                                         n_trees_min=self.__n_trees_min,
                                         n_trees_max=self.__n_trees_max,
                                         tree_prob=self.__tree_prob)
                                         )

        return x


#
#   Gestion articles et réceptions
#
import os
import csv
import json
'''
Exercice 4.1
Créer une application qui offre les fonctions suivantes
Gestion Article, Réception Encodage, Reception Validation
- Encodage des articles
    Code article, intitulé, prix, inventaire
    Ajout-Modification-suppression
    Sauvegarde dans un fichier articles.csv (dico1)
- Encodage des receptions d'inventaire de la journée
    Ajout reception
        article quantité
    Modification
    Suppression
    Sauvegarde dans un fichier reception.csv ( dico2 )
- Validation reception
    Mettre à jour l'inventaire avec les receptions du jour

'''

from menu import Menu
def valide(msg, choice):
    """ Fonction d'affichage de message et de confirmation """
    c = ''
    #  saisie caractère autorisé
    while c not in choice:
        c = input(msg)
    return c
def ecritureC ( fichier, dico):
    """ Ecriture fichier """
    with open(fichier, 'w') as f:
        for k, v in dico.items():
            f.write('{},{}\n'.format(k, v))
    return
def ecriture( fichier, dico):
    """ Ecriture JSON"""
    with open( fichier, 'w') as f:
        json.dump(f, dico)

def lecture (fichier):
    """ Lecture ficheir JSON """
    dict = {}
    # nested dico
    if os.path.exists(fichier):
        with open(fichier, 'r') as f:
            dict = json.load(f)
    else:
        print('Fichier:', fichier, ' inexistant')
    return dict

# Fonctions de gestion des articles

# Fonctions de gestion receptions

# Effectuer la réceptions des articles
def effectuerReception(articles, receptions):
    """ reception des arciles : mise à jour des qty"""
    for r, q in receptions.items():
        if r in articles:
            articles[r]['qty'] += q # increment de la quantité
            print('Add q', q, '->', articles[r])
        else:
            print('Article ', r, ' inexistant, reception impossible')
            if valide("Ajouter article", ('o','n')) =='o':
                print('Ajout articles', r) #  ajoute un article ...
menu = Menu()
# article, clé, nom, prix, qté
articles ={'art1':{'nom':'Ecran','prix':200, 'qty':12},
           'art2':{'nom':'Clavier','prix': 23, 'qty':9}}
fileArticles = 'article.csv'
receptions = {'art1':4,
            'art2':7,
            'art3':10}
fileRecept ='receptions.csv'
#ecriture(fileArticles, articles)
#art = lecture(fileArticles)
#print(art)

if valide('Msg a afficher <o,n>:', ('o','O','n','N')) == 'o':
    print('Ok')
else:
    print('not ok')

if valide('Réception des articles ?<o n>', ('o','n')) == 'o':
    effectuerReception(articles, receptions)
print(menu)


# encoding: utf-8

"""
给定一个链表，两两交换其中相邻的节点，并返回交换后的链表。
你不能只是单纯的改变节点内部的值，而是需要实际的进行节点交换。
"""
import os
import sys
PROJECT_ROOT = os.path.realpath(os.path.dirname(__file__))
sys.path.insert(0, os.path.join(PROJECT_ROOT, os.pardir))

from linked_list.base import get_link, Node, scan

def mergeKLists_heap(lists):
    """使用最小堆，每次pop出堆顶元素加入链表"""
    import heapq
    dummy = Node()
    p = dummy
    head = []
    # 初次将每个链表头结点加入最小堆
    for i in range(len(lists)):
        if lists[i] :
            heapq.heappush(head, (lists[i].val, i))
            lists[i] = lists[i].next
    while head:
        val, idx = heapq.heappop(head)  # 取出最小元素
        p.next = Node(val)  # 将最小元素加入链表
        p = p.next  # 将链表后移
        if lists[idx]:  # 如果该链表还有数据将下一个数据加入最小堆
            heapq.heappush(head, (lists[idx].val, idx))
            lists[idx] = lists[idx].next
    return dummy.next

class Solution(object):
    def mergeKLists(self, lists):
        if not lists:return
        n = len(lists)
        return self.merge(lists, 0, n-1)

    def merge(self,lists, left, right):
        """分治法将链表分为两组合并"""
        if left == right:
            return lists[left]
        mid = left + (right - left) // 2
        l1 = self.merge(lists, left, mid)
        l2 = self.merge(lists, mid+1, right)
        return self.mergeTwoLists(l1, l2)

    def mergeTwoLists(self,l1, l2):
        """合并两个有序链表"""
        if not l1:return l2
        if not l2:return l1
        if l1.val < l2.val:
            l1.next = self.mergeTwoLists(l1.next, l2)
            return l1
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2

if __name__ == '__main__':
    pass


import os
from colorama import Fore,Style
import requests
import time
import urllib3
import sys

def parse_args():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--domain', type=str, required=True, help='Target Domain.')
    parser.add_argument('-o', '--output', type=str, required=False, help='Output to file.')
    return parser.parse_args()

def banner():
    global version
    print(' ')

    time.sleep(1)

def parse_url(url):
    try:
        host = urllib3.util.url.parse_url(url).host
    except Exception as e:
        print(f'{Fore.RED}[*] Invalid domain, try again..')
    return host

def write_subs_to_file(subdomain, output_file):
    with open(output_file, 'a') as fp:
        fp.write(subdomain + '\n')

def main():
    banner()
    subdomains = []

    args = parse_args()
    target = parse_url(args.domain)
    output = args.output

    req = requests.get(f'https://crt.sh/?q=%.{target}&output=json')

    if req.status_code != 200:
        print(f'{Fore.RED}[*] Information Not Available!')

    for (key,value) in enumerate(req.json()):
        subdomains.append(value['name_value'])

    subs = sorted(set(subdomains))

    for s in subs:
        print(f'{s}\n')
        if output is not None:
            write_subs_to_file(s, output)

if __name__=='__main__':
    main()


import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
import os
from flask import render_template
import pdfkit

def file_path(filelocation):
    root = os.path.dirname(os.path.abspath(__file__))
    file_path = os.path.join(root, filelocation)
    return file_path

css_file = file_path('static/styles.css')
css = [css_file]

signature = file_path('static/thomas-signature.png')

def create_pdf(filelocation, filename):
    pdf_path = file_path(filelocation)
    pdf = MIMEApplication(open(pdf_path, "rb").read())
    pdf.add_header('Content-Disposition', 'attachment', filename=filename)
    return pdf

def generate_options(program):
    options = {
        "enable-local-file-access": None,
        "--header-html": file_path('static/'+ program + '/Pdf/Header.html'),
        "--footer-html": file_path('static/'+ program + '/Pdf/Footer.html'),
        "--margin-left": "20mm",
        "--margin-right": "20mm",
        "--margin-top": "40mm",
        "--margin-bottom": "40mm",
        }
    return options

def shared_send_email(config_email, dps_email, dps_password, email, documents):
    msg = MIMEMultipart()
    msg_template = config_email
    msg['Subject'] = msg_template["subject"]
    msg['From'] = f"DPS Applications{dps_email}"
    msg['To'] = email
    body = MIMEText(msg_template["body"], 'html')
    msg.attach(body)
    for document in documents:
         msg.attach(document)
    with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
        smtp.login(dps_email, dps_password)
        smtp.send_message(msg)


import numpy as np
import sys

sys.path.insert(1, '../')
from constants import *
import random

def normalize_keypoints(keypoints, center_location):
    keypoints[np.isnan(keypoints)] = 0.

    # re-center
    keypoints -= center_location

    # std
    std = np.std(keypoints, axis=1)
    keypoints /= np.expand_dims(std, 1)

    keypoints[np.isnan(keypoints)] = 0.

    return keypoints

# ─── AUGMENTS ───────────────────────────────────────────────────────────────────

def augment(pose_frames, face_frames, left_hand_frames, right_hand_frames):
    # select augmentations.
    is_rotate = np.random.random() < 0.5
    is_random_aspec_ratio = np.random.random() < 0.5

    if is_rotate:
        rotate_degrees = random.randint(-20, 20)

        pose_frames = rotate_kp(pose_frames, rotate_degrees)
        face_frames = rotate_kp(face_frames, rotate_degrees)
        left_hand_frames = rotate_kp(left_hand_frames, rotate_degrees)
        right_hand_frames = rotate_kp(right_hand_frames, rotate_degrees)

    if is_random_aspec_ratio:
        ratio_x = 0.75+np.random.random()/2
        ratio_y = 0.75+np.random.random()/2
        pose_frames *= [ratio_x, ratio_y]
        face_frames *= [ratio_x, ratio_y]
        left_hand_frames *= [ratio_x, ratio_y]
        right_hand_frames *= [ratio_x, ratio_y]

    return pose_frames, face_frames, left_hand_frames, right_hand_frames

def rotate_kp(keypoints_xy_frames, rotate_degrees=10):
    """
    Random rotate keypoint coordinates by given angle.
    :param keypoints_xy_frames: keypoints coordinates.
    :param max_rotate: max rotation angle in degrees.
    :return:rotated keypoints coordinates
    """
    num_samples, num_kp, num_kp_dim = keypoints_xy_frames.shape

    keypoints_xy = keypoints_xy_frames.reshape(num_samples * num_kp, num_kp_dim)

    rotation_theta = np.radians(rotate_degrees)

    assert num_kp_dim == 2
    M_rotation = np.array([[np.cos(rotation_theta), -np.sin(rotation_theta)],
                           [np.sin(rotation_theta), np.cos(rotation_theta)]])

    keypoints_xyt = keypoints_xy.transpose()
    keypoints_out = M_rotation @ keypoints_xyt
    keypoints_out = keypoints_out.transpose()

    return keypoints_out.reshape(num_samples, num_kp, num_kp_dim)

# ─── SAMPLING METHODS ───────────────────────────────────────────────────────────

def uniform_sampling_indicies(total_frames, num_pick):
    tick = (total_frames - 2) / float(num_pick)
    offsets = np.array([int(tick / 2.0 + tick * x) for x in range(num_pick)])
    return offsets + 1

def uniform_sampling(pose_frames, faces, left_hand, right_hand):
    """
    sampling frames by uniform selection.
    """
    indicies = uniform_sampling_indicies(total_frames=len(pose_frames), num_pick=NUM_FRAME_SAMPLES)

    return pose_frames[indicies], faces[indicies], left_hand[indicies], right_hand[indicies]

def random_sampling(pose_frames, faces, left_hand, right_hand):
    """
    sampling frames by random pick selection.
    """

    total_range = np.arange(len(pose_frames))
    np.random.shuffle(total_range)
    indicies = total_range[:NUM_FRAME_SAMPLES]
    indicies.sort()

    if len(indicies) < NUM_FRAME_SAMPLES:
        diff = NUM_FRAME_SAMPLES - len(indicies)
        pad = np.ones(diff) * indicies[-1]
        indicies = np.append(indicies, pad.astype('int'))

    return pose_frames[indicies], faces[indicies], left_hand[indicies], right_hand[indicies]