'''VPT, Vantage Point Tree'''

import math
import statistics
from datetime import timedelta
from typing import Generic, TypeVar, List, Tuple, Dict, Set, Union, Optional, Callable, Final, Iterator, Any, Counter, Sequence, Literal, Deque, Iterable
from dataclasses import dataclass, field
import numpy as np
import json
from multiprocessing import Pool, pool

from .abstract_similarity_tree import AbstractSimilarityTree, K, V
from .caches import FunctionCache, DistanceCache, MinFinder
from .. import lib
from ..lib import PriorityQueue, ProgressBar, Timing

ZERO_ELEMENT = '-'
# TOLERANCE = 0.0

@dataclass
class _MVPFork(Generic[K]):
    parent: Optional['_MVPFork[K]'] = field(repr=False)
    pivot: K
    radii: List[float] = field(default_factory=list)
    children: List['_MVPNode[K]'] = field(default_factory=list)

@dataclass
class _MVPLeaf(Generic[K]):
    parent: Optional['_MVPFork[K]'] = field(repr=False)
    elements: List[K] = field(default_factory=list)

_MVPNode = Union[_MVPFork[K], _MVPLeaf[K]]

class MVPTree(AbstractSimilarityTree[K, V]):
    _K: int  # arity
    _leaf_size: int
    # _distance_function: Callable[[V, V], float]
    _distance_cache: DistanceCache[K, V]
    _elements: Set[K]
    _home_leaves: Dict[K, _MVPLeaf[K]]
    _root: _MVPNode[K]

    def __init__(self, distance_function: Callable[[V, V], float], keys_values: Sequence[Tuple[K, V]] = (), arity: int = 4, leaf_size: int = 8,
                 n_processes: int = 1, root_element: Optional[Tuple[K, V]] = None) -> None:
        assert leaf_size >= 1
        self._K = arity
        self._leaf_size = leaf_size
        self._distance_function = distance_function
        self._distance_cache = DistanceCache(distance_function)
        self._elements = set()  # keys of elements currently present in the tree (pivot is not necessarily element)
        # self._home_leaves = {}  # mapping of elements to their accommodating leaves
        self._root = _MVPLeaf(parent=None)
        self._bulk_load(keys_values, with_progress_bar=True, n_processes=n_processes, root_element=root_element)

    def __len__(self) -> int:
        '''Return number of elements'''
        return len(self._elements)

    def __contains__(self, element) -> bool:
        '''Decide if element is present in the tree'''
        return element in self._elements

    def _bulk_load(self, keys_values: Sequence[Tuple[K, V]], with_progress_bar: bool = False, n_processes: int = 1, root_element: Optional[Tuple[K, V]] = None) -> None:
        elements = [k for k, v in keys_values]
        n = len(elements)
        assert len(self) == 0, 'Bulk-load only works on an empty tree'
        assert len(set(elements)) == n, 'Duplicate keys are not allowed'
        if n == 0:
            return
        self._elements.update(elements)
        if root_element is not None:
            self._distance_cache.insert(*root_element)
            root_pivot: Optional[K] = root_element[0]
        else:
            root_pivot = None
        for k, v in keys_values:
            self._distance_cache.insert(k, v)
        bar = ProgressBar(len(elements), title=f'Bulk-loading {n} elements into {self._K}-way MVPTree').start() if with_progress_bar else None
        if n_processes == 1:
            self._root = self._create_node_from_bulk(elements, pivot=root_pivot, progress_bar=bar)
        else:
            with Pool(n_processes) as pool:
                self._root = self._create_node_from_bulk(elements, pivot=root_pivot, progress_bar=bar, pool=pool)
        if bar is not None:
            bar.finalize()

    def _create_node_from_bulk(self, elements: List[K], pivot: Optional[K] = None, parent_pivot: Optional[K] = None, progress_bar: Optional[ProgressBar] = None, pool: Optional[pool.Pool] = None) -> _MVPNode[K]:
        if len(elements) <= self._leaf_size:
            new_leaf = _MVPLeaf(parent=None, elements=elements)
            if progress_bar is not None:
                progress_bar.step(len(elements))
            return new_leaf
        else:
            if pivot is None:
                pivot = self._select_pivot0(elements, parent_pivot)
                # pivot = self._select_pivot1(elements, parent_pivot)
                elements.remove(pivot)
            bins, rs = self._partition(pivot, elements, pool=pool)
            new_fork = _MVPFork(parent=None, pivot=pivot, radii=rs)
            for bin in bins:
                subtree = self._create_node_from_bulk(bin, parent_pivot=pivot, progress_bar=progress_bar, pool=pool)
                new_fork.children.append(subtree)
                subtree.parent = new_fork
            return new_fork

    def _select_pivot0(self, elements: List[K], parent_pivot: Optional[K]) -> K:
        return elements[0]

    def _select_pivot1(self, elements: List[K], parent_pivot: Optional[K]) -> K:
        if parent_pivot is None:
            parent_pivot = elements[0]
        d_max, pivot = max((self.get_distance(parent_pivot, k), k) for k in elements)
        return pivot

    def _partition(self, pivot: K, elements: List[K], pool: Optional[pool.Pool] = None) -> Tuple[List[List[K]], List[float]]:
        bins: list[list[K]] = [[] for i in range(self._K)]
        self._distance_cache.calculate_distances([(pivot, elem) for elem in elements], pool=pool)
        distances = [self.get_distance(pivot, elem) for elem in elements]
        rs = statistics.quantiles(distances, n=self._K)
        rs.insert(0, min(distances))
        rs.append(max(distances))
        # print('distances', sorted(distances))
        # print('rs', rs)
        for elem, dist in zip(elements, distances):
            for i_bin in range(self._K):
                if dist < rs[i_bin+1]:
                    the_bin = i_bin
                    break
                elif dist == rs[i_bin+1]:
                    if i_bin == self._K - 1:
                        # end od last bin
                        the_bin = i_bin
                        break
                    else:
                        # tie
                        if len(bins[i_bin]) <= len(bins[i_bin+1]):
                            the_bin = i_bin
                            break
                        else:
                            the_bin = i_bin+1
                            break
            else:
                raise AssertionError('No bin selected')
            bins[the_bin].append(elem)
        return bins, rs

    def _get_distance_to_value(self, key1: K, value2: V) -> float:
        # if key1 == ZERO_ELEMENT:
        #     return self._distance_from_zero(value2)
        # else:
        #     return self._distance_cache.get_distance_to_value(key1, value2)
        return self._distance_cache.get_distance_to_value(key1, value2)

    def get_distance(self, key1: K, key2: K) -> float:
        # if key1 == key2 == ZERO_ELEMENT:
        #     return 0.0
        # elif key1 == ZERO_ELEMENT:
        #     return self._distance_from_zero(self._distance_cache._elements[key2])
        # elif key2 == ZERO_ELEMENT:
        #     return self._distance_from_zero(self._distance_cache._elements[key1])
        # else:
        #     return self._distance_cache.get_distance(key1, key2)
        return self._distance_cache.get_distance(key1, key2)

    def get_statistics(self):
        n_elements = len(self._elements)
        forks, leaves = self.get_forks_and_leaves()
        n_forks = len(forks)
        n_leaves = len(leaves)
        result = f'''{self._K}-way MVPT tree statistics:
        Elements: {n_elements}, Forks: {n_forks}, Leaves: {n_leaves}
        {self._distance_cache.get_statistics()}'''
        return result

    def leaf_diameters(self, leaves: List[_MVPLeaf]) -> str:
        diameters = []
        for leaf in leaves:
            n = len(leaf.elements)
            diameter = max((self.get_distance(leaf.elements[i], leaf.elements[j]) for i in range(n) for j in range(i)), default=0.0)
            diameters.append(diameter)
        return f'leaf diameters: {min(diameters):.3f}-{max(diameters):.3f}, mean: {statistics.mean(diameters):.3f} median: {statistics.median(diameters):.3f}'

    def leaf_distances(self, leaves: List[_MVPLeaf]) -> str:
        dists: list[float] = []
        for leaf in leaves:
            n = len(leaf.elements)
            dists.extend(self.get_distance(leaf.elements[i], leaf.elements[j]) for i in range(n) for j in range(i))
        min_dist = min(dists, default=math.nan)
        max_dist = max(dists, default=math.nan)
        mean = statistics.mean(dists) if len(dists) > 0 else math.nan
        median = statistics.median(dists) if len(dists) > 0 else math.nan
        return f'in-leaf distances: {min_dist:.3f}-{max_dist:.3f}, mean: {mean:.3f} median: {median:.3f}'

    def get_forks_and_leaves(self) -> Tuple[List[_MVPFork], List[_MVPLeaf]]:
        forks: List[_MVPFork[K]] = []
        leaves: List[_MVPLeaf[K]] = []
        self._collect_nodes(self._root, forks, leaves)
        return forks, leaves

    def _collect_nodes(self, node: _MVPNode[K], out_forks: List[_MVPFork[K]], out_leaves: List[_MVPLeaf[K]]):
        if isinstance(node, _MVPLeaf):
            out_leaves.append(node)
        elif isinstance(node, _MVPFork):
            out_forks.append(node)
            for subtree in node.children:
                self._collect_nodes(subtree, out_forks, out_leaves)
        else:
            raise AssertionError

    def kNN_query_by_value(self, query_value: V, k: int, distance_low_bounds: List[Callable[[V, V], float]] = [], the_range: float = math.inf) -> List[Tuple[float, K]]:
        besties = MinFinder[K](n=k)
        query_dist = FunctionCache[K, float](lambda key: self._get_distance_to_value(key, query_value))
        queue = PriorityQueue[float, _MVPNode]()
        queue.add(0.0, self._root)
        current_range = min(besties.top_size(), the_range)
        seen = set()
        QAE = True
        n_leaves = 0
        while not queue.is_empty():
            best = queue.pop_min()
            assert best is not None
            dmin, node = best
            if dmin >= current_range:
                continue
            if isinstance(node, _MVPLeaf):
                n_leaves += 1
                ancestors = list(self._gen_ancestors_of_leaf(node))
                for elem in node.elements:
                    assert elem not in seen
                    if elem in seen:
                        continue
                    if QAE:
                        if not self._can_be_under(elem, query_dist, ancestors, current_range):
                            continue
                    elem_value = self._distance_cache._elements[elem]
                    if any(d(elem_value, query_value) >= current_range for d in distance_low_bounds):
                        continue
                    current_range = min(besties.bubble_in(query_dist[elem], elem), the_range)
                    seen.add(elem)
            elif isinstance(node, _MVPFork):
                d_p_q = query_dist[node.pivot]
                assert node.pivot not in seen
                if node.pivot != ZERO_ELEMENT and node.pivot not in seen:
                    current_range = min(besties.bubble_in(d_p_q, node.pivot), the_range)
                    seen.add(node.pivot)
                for i in range(self._K):
                    dmin_child = max(dmin, node.radii[i] - d_p_q, d_p_q - node.radii[i+1])
                    if dmin_child < current_range:
                        queue.add(dmin_child, node.children[i])
            else:
                raise AssertionError('node must be one of: _MVPFork, _MVPLeaf')
        result = besties.pop_all_not_none()
        return result

    def _gen_ancestors(self, node: _MVPFork[K], include_self: bool = False) -> Iterator[K]:
        if include_self:
            yield node.pivot
        ancestor_node = node.parent
        while ancestor_node is not None:
            yield ancestor_node.pivot
            ancestor_node = ancestor_node.parent

    def _gen_ancestors_of_leaf(self, leaf: _MVPLeaf[K]) -> Iterator[K]:
        if leaf.parent is not None:
            yield from self._gen_ancestors(leaf.parent, include_self=True)

    def _can_be_under(self, elem: K, query_distance: FunctionCache[K, float], through: Iterable[K], limit: float) -> float:
        '''Decide if the distance between elem and query can be less than limit, using elements from through as pivots.'''
        # d_p_q = query_distance[node.pivot]
        for t in through:
            if t in query_distance:
                d_e_t = self.get_distance(elem, t)
                d_t_q = query_distance[t]
                d_e_q_low = abs(d_e_t - d_t_q)
                # assert d_p_q_low <= d_p_q, f'{d_p_q_low} <= {d_p_q}'
                if d_e_q_low >= limit:
                    return False
        return True

    def _node_to_json(self, node: _MVPNode[K]) -> object:
        if isinstance(node, _MVPLeaf):
            return node.elements
        elif isinstance(node, _MVPFork):
            return {
                'pivot': node.pivot,
                'radii': node.radii,
                'children': [self._node_to_json(child) for child in node.children]
            }
        else:
            raise AssertionError

    def _node_from_json(self, js: object) -> _MVPNode[K]:
        if isinstance(js, list):
            return _MVPLeaf(parent=None, elements=js)
        elif isinstance(js, dict):
            fork = _MVPFork(parent=None, pivot=js['pivot'], radii=js['radii'], children=[])
            for c in js['children']:
                child = self._node_from_json(c)
                fork.children.append(child)
                child.parent = fork
            return fork
        else:
            raise AssertionError

    def save(self, file: str, with_cache: bool = False, **json_kwargs) -> None:
        js = {
            'TYPE': 'MVPT',
            'ARITY': self._K,
            'LEAF_SIZE': self._leaf_size,
            'root': self._node_to_json(self._root),
            'distance_cache': self._distance_cache.json() if with_cache else []
        }
        kwargs = {'indent': 1}
        kwargs.update(json_kwargs)
        with open(file, 'w') as w:
            json.dump(js, w, **kwargs)  # type: ignore

    @staticmethod
    def load(file: str, distance_function: Callable[[V, V], float], get_value: Callable[[K], V]) -> 'MVPTree[K, V]':
        with open(file) as r:
            js = json.load(r)
        assert isinstance(js, dict)
        leaf_size = js['LEAF_SIZE']
        arity = js['ARITY']
        result = MVPTree[K, V](distance_function, arity=arity, leaf_size=leaf_size)
        root = result._node_from_json(js['root'])
        result._root = root
        forks, leaves = result.get_forks_and_leaves()
        for fork in forks:
            if fork.pivot != ZERO_ELEMENT:
                result._elements.add(fork.pivot)
        for leaf in leaves:
            for elem in leaf.elements:
                result._elements.add(elem)
        for elem in result._elements:
            result._distance_cache.insert(elem, get_value(elem))
        for k1, k2, dist in js['distance_cache']:
            result._distance_cache.set_distance(k1, k2, dist)
        return result


import os
import xlrd
from airflow import DAG
from airflow.contrib.hooks.wasb_hook import WasbHook
from airflow.operators.dummy_operator import DummyOperator
from airflow.operators.python_operator import PythonOperator
from airflow.operators.mssql_operator import MsSqlOperator
from datetime import datetime, timedelta
from datetime import date
import pandas as pd
from pandas import read_excel
from variables import sql_connid,sql_connid_gomedisys
from utils import sql_2_df,open_xls_as_xlsx,load_df_to_sql,search_for_file_prefix, get_files_xlsx_contains_name, get_files_with_prefix_args,search_for_file_contains, respond, read_csv, move_to_history_for_prefix,  get_files_xlsx_with_prefix, get_files_xlsx_with_prefix_args,file_get

#  Se nombran las variables a utilizar en el dag

db_table = "factMedicalScales"
db_tmp_table = "tmp_factMedicalScales"
dag_name = 'dag_' + db_table

# Función de extracción del archivo del blob al servidor, transformación del dataframe y cargue a la base de datos mssql
def func_get_factMedicalScales ():

    now = datetime.now()
    last_week = now - timedelta(days=15)
    last_week = last_week.strftime('%Y-%m-%d %H:%M:%S')
    print(now)
    print(last_week)

    # LECTURA DE DATOS
    query = f"""
        select fms.*, EMD.idDiagnostic from (
        select
            EVE.idEHREvent,EVE.idPatient,EVE.idPractitioner, EVE.actionRecordedDate
            ,EMS.idEvaluation
            ,GA.idAction
            ,GS.idSpecialty,GS.name as specialityName
            ,CSV.[idScale],CSV.[name] as evaluationName--,CSV.minValue,CSV.maxValue
            ,sum(EMSQ.[value]) value

        from
            dbo.encounters EN
            ,dbo.encounterRecords ENR
            ,dbo.EHREvents EVE
            ,dbo.generalActions GA
            ,dbo.generalSpecialties GS
            ,dbo.EHREventMedicalScales EMS
            ,dbo.EHREventMedicalScaleQuestions EMSQ
            ,dbo.EHRConfScaleValorations CSV
        where
            EN.idEncounter = EVE.idEncounter
            and EN.dateStart > '{last_week}'
            and EN.idEncounter = ENR.idEncounter
            and EVE.idEHREvent = EMS.idEHREvent
            and EVE.idEHREvent = EMSQ.idEHREvent
            and GA.idAction = EVE.idAction
            and GS.idSpecialty = EVE.idSpeciality
            and CSV.[idScale] = 11
            and EMS.idScale = EMSQ.idScale
            and CSV.idScale = EMS.idScale
            and EMS.idEvaluation = CSV.[idRecord]
        group by
            EMS.idEvaluation
            ,EVE.idEHREvent
            ,EVE.idPatient
            ,EVE.idPractitioner
            ,EVE.actionRecordedDate
            ,GA.idAction
            ,GS.idSpecialty
            ,GS.name
            ,CSV.[idScale]
            ,CSV.[name]
            ,CSV.minValue
            ,CSV.maxValue
            ) FMS LEFT JOIN (SELECT idDiagnostic, idEHREvent FROM EHREventMedicalDiagnostics WHERE isPrincipal = 1) EMD ON FMS.idEHREvent = EMD.idEHREvent
    """
    df = sql_2_df(query, sql_conn_id=sql_connid_gomedisys)
    # print(df.columns)
    # print(df.dtypes)
    # print(df)

    # PROCESAMIENTO
    df['actionRecordedDate'] = pd.to_datetime(df['actionRecordedDate'], errors='coerce')
    df['actionRecordedDate'] = df['actionRecordedDate'].astype(str)

    # convert to int
    cols_int = ['idDiagnostic']
    for col in cols_int:
        df[col] = df[col].astype(str).str.replace('.0','')
        df[col] = df[col].replace('','nan')
        # df[col] = pd.to_numeric(df[col], errors='coerce', downcast='integer')

    df = df.drop_duplicates(subset=['idEHREvent','idPatient','idPractitioner','idEvaluation','idAction','idSpecialty','idScale'])

    print(df.columns)
    print(df.dtypes)
    print(df)

    print(df[df['idEHREvent']==2214900])

    # CARGA A BASE DE DATOS
    if ~df.empty and len(df.columns) >0:
        load_df_to_sql(df, db_tmp_table, sql_connid)

# Se declara un objeto con los parámetros del DAG
default_args = {
    'owner': 'clinicos',
    'depends_on_past': False,
    'start_date': datetime(2015, 6, 1),
}
# Se declara el DAG con sus respectivos parámetros
with DAG(dag_name,
    catchup=False,
    default_args=default_args,
    # Se establece la ejecución del dag a las 10:40 am (hora servidor) todos los Jueves
    schedule_interval= '40 10 * * 04',
    max_active_runs=1
    ) as dag:

    # Se declara la función que sirve para denotar el inicio del DAG a través de DummyOperator
    start_task = DummyOperator(task_id='dummy_start')

    #Se declara y se llama la función encargada de traer y subir los datos a la base de datos a través del "PythonOperator"
    get_factMedicalScales_python_task = PythonOperator(task_id = "get_factMedicalScales",
                                                        python_callable = func_get_factMedicalScales,
                                                        email_on_failure=True,
                                                        email='BI@clinicos.com.co',
                                                        dag=dag
                                                        )

    # Se declara la función encargada de ejecutar el "Stored Procedure"
    load_factMedicalScales = MsSqlOperator(task_id='Load_factMedicalScales',
                                            mssql_conn_id=sql_connid,
                                            autocommit=True,
                                            sql="EXECUTE sp_load_factMedicalScales",
                                            email_on_failure=True,
                                            email='BI@clinicos.com.co',
                                            dag=dag
                                       )

    # Se declara la función que sirva para denotar la Terminación del DAG, por medio del operador "DummyOperator"
    task_end = DummyOperator(task_id='task_end')

start_task >> get_factMedicalScales_python_task >> load_factMedicalScales >> task_end


'''
Created on 24 nov 2021

@author: migueltoro
'''

from us.lsi.tools.Iterable import str_iter
from us.lsi.tools.File import lineas_de_fichero,absolute_path
import sys
import calendar
from sortedcontainers.sorteddict import SortedDict # type: ignore
import random

d = {0:'a',3:'b',2:'c'}
print(list(d.values()))
r2 = "La respuesta es correcta"

def pp(file:str)->float:
    ls: list[str] = lineas_de_fichero(file)
    ls2: list[str] = ls [1:]
    n:int = 0
    s:float = 0.
    for e in ls2:
        s = s + float(e.split(',')[1])
        n = n+1
    m = s/n
    return m

def pp2(file:str)->float:
    ls: list[str] = lineas_de_fichero(file)
    ls2: list[str] = ls [1:]
    n:int = 0
    s:float = 0.
    for e in ls2:
        _,v,_ = e.split(',')
        s = s + float(v)
        n = n+1
    m = s/n
    return m

numeros = [7, 3, 5, 1, 3, 1, 7]

if __name__ == '__main__':
    print(str_iter(sys.path,sep='\n'))
    print(list(calendar.day_name))
    print(d)
    r = sorted(d.items(),reverse=True)
    random.shuffle(r)
    print(r)
    print(SortedDict(r))
    print(len(r2))
    print(r2[23])
    num = 29
    print(num % 3 == 0 or 20 <= num <= 30)
    print(4+1.)
    print(pp(absolute_path('/resources/pp.txt')))
    print(pp2(absolute_path('/resources/pp.txt')))
    print(numeros[8-2])


import PIL
from PIL import ImageGrab
from PIL import Image
from PIL import ImageOps
from PIL import ImageStat
import time
import serial
import json

arduinoSerial = serial.Serial("/dev/cu.usbmodem143301") #Create Serial port object called arduinoSerial
time.sleep(2) #wait for 2 secounds for the communication to get established

maxAngle = 40
stepsPerRev = 4096
maxSteps = stepsPerRev / 360 * maxAngle

def image2Data():
    originalImage = PIL.ImageGrab.grab((1200, 100, 2200, 1600))
    bnwImage = PIL.ImageOps.grayscale(originalImage)
    bnwImage.save("result.png")

    grads = {}
    cropHeight = round(1500 / 3 + 0.5)
    cropWidth = round(1000 / 3 + 0.5)
    tileCount = 1
    for top in range(0, 1500, cropHeight):
        for left in range(0, 1000, cropWidth):
            crop = bnwImage.crop((left, top, left + cropWidth, top + cropHeight))
            stat = PIL.ImageStat.Stat(crop)
            statAvg = stat.sum[0] / stat.count[0]
            angle = round(maxSteps - statAvg / 255 * maxSteps)
            grads[tileCount] = angle
            tileCount += 1
    #print(grads)
    return grads

isOn = True

while isOn:
    grads = image2Data()
    gradsJson = json.dumps(grads)
    arduinoSerial.write(gradsJson.encode('ascii'))
    #arduinoSerial.flush()
    time.sleep(0.5)


'''
Given folders containing runs of algorithms on a benchmark over a set of random seeds,
plots their oracle performances on the same graph (test.png)
and records their corresponding final values (output.txt).
'''

import matplotlib.pyplot as plt
import numpy as np
import argparse
import os, json

if __name__ == "__main__":

    parser = argparse.ArgumentParser()

    parser.add_argument('--output', type=str, default='test')
    parser.add_argument('--num_comps', type=int, default=6)
    parser.add_argument('--seeds', type=str, default='1,2,3,4,5')
    parser.add_argument('--iters', type=int, default=100)
    parser.add_argument('--folder0', type=str)
    parser.add_argument('--folder1', type=str)
    parser.add_argument('--folder2', type=str)
    parser.add_argument('--folder3', type=str)
    parser.add_argument('--folder4', type=str)
    parser.add_argument('--folder5', type=str)

    args = parser.parse_args()
    arg_dict = vars(args)

    outdir = arg_dict["output"]
    if not os.path.exists(outdir):
        os.makedirs(outdir)

    seeds = [int(item) for item in arg_dict["seeds"].split(',')]
    colors = ['tab:red', 'k', 'tab:orange', 'tab:blue', 'tab:purple', 'tab:brown']

    plt.rc('axes', titlesize=16)
    plt.rc('axes', labelsize=16)
    plt.rc('xtick', labelsize=16)
    plt.rc('ytick', labelsize=16)

    f1 = plt.figure()
    ax1 = f1.gca()
    f2 = plt.figure()
    ax2 = f2.gca()

    for i in range(arg_dict["num_comps"]):
        job_dir = arg_dict["folder"+str(i)]
        with open(os.path.join(outdir, 'members.txt'), 'a') as record:
            record.write(job_dir+' '+colors[i])
            record.write('\n')

        test_mean = [[] for r in range(arg_dict["iters"])]
        test_stderr = [[] for r in range(arg_dict["iters"])]
        train_mse = [[] for r in range(arg_dict["iters"])]
        for s in range(len(seeds)):
            log_dir = os.path.join(job_dir, 'seed_'+str(seeds[s]))
            training_file = os.path.join(log_dir, 'train.json')
            evaluation_file = os.path.join(log_dir, 'test.json')

            # Testing results
            results = []
            with open(evaluation_file, 'r') as test:
                for line in test:
                    results.append(json.loads(line))
            for data in results:
                r = data['round']
                test_mean[r].append(data['loss_est'])
                test_stderr[r].append(data['loss_stderr'])

            # Training results
            train_obj = []
            with open(training_file, 'r') as train:
                for line in train:
                    train_obj.append(json.loads(line))
            for data in train_obj:
                r = data['round']
                train_mse[r].append(data['mse'])

        compiled_rounds = np.arange(arg_dict["iters"])
        compiled_test_mean = np.asarray([np.mean(np.asarray(test_mean[r])) for r in range(arg_dict["iters"])])
        compiled_test_var = np.asarray([(np.var(np.asarray(test_mean[r]))
            +np.mean(np.asarray(test_stderr[r])**2))/len(test_mean[r]) for r in range(arg_dict["iters"])])
        compiled_train_mse = np.asarray([np.mean(np.asarray(train_mse[r])) for r in range(arg_dict["iters"])])
        compiled_mse_stderr = np.asarray([np.std(np.asarray(train_mse[r]))/np.sqrt(10*len(seeds)) for r in range(arg_dict["iters"])])
        with open(os.path.join(outdir, 'output.txt'), 'a') as printout:
            printout.write('For folder {}, the final test performance is {} with standard error {}'.format(i, compiled_test_mean[-1], np.sqrt(compiled_test_var[-1])))
            printout.write('\n')

        ax1.plot(compiled_rounds, compiled_test_mean, colors[i])
        ax1.fill_between(compiled_rounds, compiled_test_mean-np.sqrt(compiled_test_var),
                compiled_test_mean+np.sqrt(compiled_test_var), facecolor=colors[i], alpha=0.25)
        ax2.plot(compiled_rounds, compiled_train_mse, colors[i])
        ax2.fill_between(compiled_rounds, compiled_train_mse-compiled_mse_stderr,
                compiled_train_mse+compiled_mse_stderr, facecolor=colors[i], alpha=0.25)

    ax1.set_xlabel('Round')
    ax1.set_ylabel('Test loss')
    f1.savefig(os.path.join(outdir, 'test.png'), bbox_inches = 'tight')
    plt.close(f1)

    ax2.set_xlabel('Round')
    ax2.set_ylabel('Gradient MSE')
    f2.savefig(os.path.join(outdir, 'train_mse.png'), bbox_inches = 'tight')
    plt.close(f2)


import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from torch.distributions import Categorical

from collections import OrderedDict
from maml_rl.policies.policy import Policy, weight_init

A_DIM = 6

class CriticNet(Policy):
    """Policy network based on a multi-layer perceptron (MLP), with a
    `Categorical` distribution output. This policy network can be used on tasks
    with discrete action spaces (eg. `TabularMDPEnv`). The code is adapted from
    https://github.com/cbfinn/maml_rl/blob/9c8e2ebd741cb0c7b8bf2d040c4caeeb8e06cc95/sandbox/rocky/tf/policies/maml_minimal_categorical_mlp_policy.py
    """

    def __init__(self, input_size, output_size, learning_rate=0.001):
        super(CriticNet, self).__init__(input_size=input_size, output_size=output_size)

        # for i in range(1, self.num_layers + 1):
        #     self.add_module('layer{0}'.format(i),
        #         nn.Linear(layer_sizes[i - 1], layer_sizes[i]))
        self.add_module('layer0-fc0', nn.Linear(1, 128))
        self.add_module('layer0-fc1', nn.Linear(1, 128))
        self.add_module('layer0-cv0', nn.Conv1d(1, 128, 4))
        self.add_module('layer0-cv1', nn.Conv1d(1, 128, 4))
        self.add_module('layer0-cv2', nn.Conv1d(1, 128, 4))
        self.add_module('layer0-fc2', nn.Linear(1, 128))

        self.add_module('layer1-fc', nn.Linear(2048, 128))  # 输入维度待定~~~~~~~~~~~~~~~
        self.add_module('layer2-fc', nn.Linear(128, 1))

        self.apply(weight_init)

        self.learning_rate = learning_rate
        self.opt = torch.optim.RMSprop(self.parameters(), lr=learning_rate)

    def forward(self, input, params=None):
        if params is None:
            params = OrderedDict(self.named_parameters())
        # output = torch.tensor(input)
        output = torch.tensor(input)
        output = output.float()
        state_size0, state_size1, state_size2, state_size3 = output.size()

        state_size = state_size0 * state_size1
        output = output.reshape(state_size, state_size2, state_size3)

        # bit_rate, buffer_size, next_chunk_size, bandwidth_measurement(throughput and time), chunk_til_video_end
        # print(output[:, 0, -1].size())
        split0 = F.linear(output[:, 0, -1].view(state_size, 1),
                          weight=params['layer0-fc0.weight'],
                          bias=params['layer0-fc0.bias'])
        split0 = F.relu(split0)

        split1 = F.linear(output[:, 1, -1].view(state_size, 1),
                          weight=params['layer0-fc1.weight'],
                          bias=params['layer0-fc1.bias'])
        split1 = F.relu(split1)

        split2 = F.conv1d(output[:, 2, :].view(state_size, 1, -1),
                          weight=params['layer0-cv0.weight'],
                          bias=params['layer0-cv0.bias'])
        split2 = split2.view(state_size, -1)
        split2 = F.relu(split2)

        split3 = F.conv1d(output[:, 3, :].view(state_size, 1, -1),
                          weight=params['layer0-cv1.weight'],
                          bias=params['layer0-cv1.bias'])
        split3 = split3.view(state_size, -1)
        split3 = F.relu(split3)

        split4 = F.conv1d(output[:, 4, :A_DIM].view(state_size, 1, -1),
                          weight=params['layer0-cv2.weight'],
                          bias=params['layer0-cv2.bias'])
        split4 = split4.view(state_size, -1)
        split4 = F.relu(split4)

        split5 = F.linear(output[:, 5, -1].view(state_size, 1),
                          weight=params['layer0-fc2.weight'],
                          bias=params['layer0-fc2.bias'])
        split5 = F.relu(split5)

        merge = torch.cat([split0, split1, split2, split3, split4, split5], 1)
        merge = F.relu(merge)

        output = F.linear(merge,
                          weight=params['layer1-fc.weight'],
                          bias=params['layer1-fc.bias'])
        output = F.relu(output)

        output = F.linear(output,
            weight=params['layer2-fc.weight'],
            bias=params['layer2-fc.bias'])

        output = output.reshape(state_size0, state_size1, 1)

        return output

    def fit(self, episodes, learning_rate=0.001, isnew=False):
        if isnew:  # start a new optimizer for meta-training
            self.opt = torch.optim.RMSprop(self.parameters(), lr=learning_rate, alpha=0.9)

        returns = episodes.returns
        loss_func = torch.nn.MSELoss()

        loss_list = []
        for i in range(returns.size()[1]):
            values = self.forward(episodes.observations[:, i:i+1, :, :]).view(-1)
            loss = loss_func(values, returns[:, i])
            self.opt.zero_grad()
            loss.backward()
            self.opt.step()
            loss_list.append(float(loss))

        loss_list = np.array(loss_list)
        return loss_list.mean()


# učitavanje biblioteka i argumenata
import os
from imutils.face_utils import FaceAligner
from imutils.face_utils import rect_to_bb
import imutils
import dlib
import cv2
import sys

py_filename = sys.argv[0]
predictor_path = sys.argv[1]
save_path = sys.argv[2]
root_images = sys.argv[3]

# pozivanje detektora lica i klase FaceAligner za poravnavanje lica
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
fa = FaceAligner(predictor, desiredFaceWidth=256)

# prolaz kroz sve slike u svim mapama zadane putanje
for subdir, dirs, files in os.walk(root_images):
    for file in files:
        image = cv2.imread(os.path.join(subdir, file))
        image = imutils.resize(image, width=800)
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        rects = detector(gray, 2)

        # poravnavanje za svako lice pronađeno na slici
        i = 1
        for rect in rects:
            (x, y, w, h) = rect_to_bb(rect)
            faceAligned = fa.align(image, gray, rect)

            cv2.imwrite(save_path + file, faceAligned)
            cv2.waitKey(0)
            i += 1


from threading import Lock
from time import sleep
from time import time
from typing import Callable
from typing import List
from typing import Optional

from paho.mqtt import client as mqtt

from wolk_gateway_module.connectivity.connectivity_service import (
    ConnectivityService,
)
from wolk_gateway_module.logger_factory import logger_factory
from wolk_gateway_module.model.message import Message

class MQTTConnectivityService(ConnectivityService):
    """Responsible for exchanging data with WolkGateway through MQTT."""

    def __repr__(self) -> str:
        """
        Make string representation of MQTTConnectivityService.

        :returns: representation
        :rtype: str
        """
        return (
            f"MQTTConnectivityService(host='{self.host}', "
            f"port='{self.port}', "
            f"client_id='{self.client_id}', "
            f"topics='{self.topics}', "
            f"qos='{self.qos}', "
            f"lastwill_message='{self.lastwill_message}', "
            f"inbound_message_listener='{self.inbound_message_listener}', "
            f"connected='{self._connected}')"
        )

    def __init__(
        self,
        host: str,
        port: int,
        client_id: str,
        qos: int,
        lastwill_message: Message,
        topics: list,
    ) -> None:
        """
        Prepare MQTT connectivity service for connecting to WolkGateway.

        :param host: Address of WolkGateway
        :type host: str
        :param port: TCP/IP port of WolkGateway used for MQTT connection
        :type port: int
        :param client_id: Unique module identifier
        :type client_id: str
        :param qos: MQTT Quality of Service level (0, 1, 2)
        :type qos: int
        :param lastwill_message: Last will message
        :type lastwill_message: Message
        :param topics: List of topics to subscribe to
        :type topics: list
        """
        self.log = logger_factory.get_logger(str(self.__class__.__name__))

        self.host = host
        self.port = port
        self.client_id = client_id
        self.topics = topics
        self.qos = qos
        self.lastwill_message = lastwill_message
        self.inbound_message_listener: Callable[
            [Message], None
        ] = lambda message: print("\n\nNo inbound message listener set!\n\n")
        self._connected = False
        self.connected_rc: Optional[int] = None

        self.client = mqtt.Client(client_id=self.client_id)
        self.client.on_connect = self._on_mqtt_connect
        self.client.on_disconnect = self._on_mqtt_disconnect
        self.client.on_message = self._on_mqtt_message
        self.client.username_pw_set(self.client_id)
        self.client.will_set(
            self.lastwill_message.topic, self.lastwill_message.payload
        )

        self.mutex = Lock()

        self.log.debug(self.__repr__())

    def set_inbound_message_listener(
        self, on_inbound_message: Callable[[Message], None]
    ) -> None:
        """
        Set the callback function ot handle inbound messages.

        :param on_inbound_message: Callable that handles inbound messages
        :type on_inbound_message: Callable[[Message], None]
        """
        self.log.debug(f"Set inbound message listener to {on_inbound_message}")
        self.inbound_message_listener = on_inbound_message

    def set_lastwill_message(self, message: Message) -> None:
        """Send offline state for module devices on disconnect."""
        self.log.debug(f"Set lastwill message: {message}")
        if self._connected:
            self.log.debug("Reconnecting to set lastwill")
            self.disconnect()
            self.lastwill_message = message
            self.connect()
        else:
            self.lastwill_message = message

    def add_subscription_topics(self, topics: List[str]) -> None:
        """
        Add subscription topics.

        Adding these topics will not subscribe to them immediately,
        a new connection needs to happen to subscribe to them.

        :param topics: List of topics
        :type topics: List[str]
        """
        self.log.debug(f"Adding {topics} to {self.topics}")
        self.topics.extend(topics)

    def remove_topics_for_device(self, device_key: str) -> None:
        """
        Remove topics for device from subscription topics.

        :param device_key: Device identifier
        :type device_key: str
        """
        self.log.debug(f"Removing topics for device {device_key}")
        if len(self.topics) == 0:
            return

        for topic in self.topics:
            if device_key in topic:
                self.topics.remove(topic)

    def connected(self) -> bool:
        """
        Return if currently connected.

        :returns: connected
        :rtype: bool
        """
        return self._connected

    def connect(self) -> bool:
        """
        Establish connection with WolkGateway.

        :returns: result
        :rtype: bool
        """
        if self._connected:
            self.log.info("Already connected")
            return True

        self.mutex.acquire()

        self.client.connect(self.host, self.port)
        self.client.loop_start()

        self.log.info(f"Connecting to {self.host}:{self.port} ...")

        timeout = round(time()) + 5

        while True:

            if round(time()) > timeout:
                self.log.warning("Connection timed out!")
                self.mutex.release()
                return False

            if self._connected is not True:
                sleep(0.1)
                continue

            if self.connected_rc == 0:
                break

            elif self.connected_rc == 1:
                self.log.error(
                    "Connection refused - incorrect protocol version"
                )
                self.mutex.release()
                return False

            elif self.connected_rc == 2:
                self.log.error(
                    "Connection refused - invalid client identifier"
                )
                self.mutex.release()
                return False

            elif self.connected_rc == 3:
                self.log.error("Connection refused - server unavailable")
                self.mutex.release()
                return False

            elif self.connected_rc == 4:
                self.log.error("Connection refused - bad username or password")
                self.mutex.release()
                return False

            elif self.connected_rc == 5:
                self.log.error("Connection refused - not authorized")
                self.mutex.release()
                return False

        self.log.debug(f"Subscribing to topics: {self.topics}")
        for topic in self.topics:
            self.client.subscribe(topic, 2)

        self.mutex.release()
        self._connected = True

        return True

    def reconnect(self) -> bool:
        """
        Terminate existing and create new connection with WolkGateway.

        :returns: result
        :rtype: bool

        :raises RuntimeError: Reason for connection being refused
        """
        self.log.debug("Attempting reconnect")
        if self._connected:
            self.client.loop_stop()
            self.client.disconnect()

        return self.connect()

    def disconnect(self) -> None:
        """Terminate connection with WolkGateway."""
        self.log.debug(f"Disconnecting from {self.host} : {self.port}")
        if self._connected:
            self.client.publish(
                self.lastwill_message.topic, self.lastwill_message.payload
            )
            self.client.loop_stop()
            self.client.disconnect()

    def publish(self, message: Message) -> bool:
        """
        Publish serialized data to WolkGateway.

        :param message: Message to be published
        :type message: Message
        :returns: result
        :rtype: bool
        """
        if not self._connected:
            self.log.warning(f"Not connected, unable to publish {message}")
            return False

        self.mutex.acquire()

        info = self.client.publish(message.topic, message.payload, self.qos)

        if info.rc == mqtt.MQTT_ERR_SUCCESS:
            self.log.debug(f"Published {message}")
            self.mutex.release()
            return True
        else:
            self.mutex.release()
            return info.is_published()

    def _on_mqtt_message(
        self, client: mqtt.Client, userdata: str, message: mqtt.MQTTMessage
    ) -> None:
        """
        Parse inbound messages and pass them to message listener.

        :param client: Client that received the message
        :type client: paho.mqtt.Client
        :param userdata: Private user data set in Client()
        :type userdata: str
        :param message: Class with members: topic, payload, qos, retain.
        :type message: paho.mqtt.MQTTMessage
        """
        self.log.debug(f"Received message on topic: {message.topic}")
        self.inbound_message_listener(Message(message.topic, message.payload))

    def _on_mqtt_connect(
        self, client: mqtt.Client, userdata: str, flags: int, rc: int
    ) -> None:
        """
        Handle when the client receives a CONNACK response from the server.

        :param client: Client that received the message
        :type client: paho.mqtt.Client
        :param userdata: private user data set in Client()
        :type userdata: str
        :param flags: Response flags sent by the broker
        :type flags: int
        :param rc: Connection result
        :type rc: int
        """
        self.log.debug(f"CONNACK: {rc}")
        if rc == 0:  # Connection successful
            self.connected_rc = 0
            self._connected = True
            # Subscribing in on_mqtt_connect() means if we lose the connection
            # and reconnect then subscriptions will be renewed.
            if self.topics:
                self.mutex.acquire()
                for topic in self.topics:
                    self.client.subscribe(topic, 2)
                self.mutex.release()
        elif rc == 1:  # Connection refused - incorrect protocol version
            self.connected_rc = 1
        elif rc == 2:  # Connection refused - invalid client identifier
            self.connected_rc = 2
        elif rc == 3:  # Connection refused - server unavailable
            self.connected_rc = 3
        elif rc == 4:  # Connection refused - bad username or password
            self.connected_rc = 4
        elif rc == 5:  # Connection refused - not authorized
            self.connected_rc = 5

    def _on_mqtt_disconnect(
        self, client: mqtt.Client, userdata: str, rc: int
    ) -> None:
        """
        Handle when the client disconnects from the broker.

        :param client: Client that received the message
        :type client: paho.mqtt.Client
        :param userdata: private user data set in Client()
        :type userdata: str
        :param rc: Disconnection result
        :type rc: int
        """
        self.log.debug(f"Disconnect return code: {rc}")
        self._connected = False
        if rc != 0:
            self.log.warning(
                f"Unexpected disconnect on {self.host}:{self.port}!"
            )


import logging

import boto3
from env import BUCKET_NAME

s3 = boto3.client('s3')

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def store(data, key):
    s3.put_object(Body=data, Bucket=BUCKET_NAME, Key=key)

def load(key):
    response = s3.get_object(Bucket=BUCKET_NAME, Key=key)
    content = response['Body'].read().decode('utf8')
    return content


import time
import http.client
import flask
import sqlalchemy

from ruddock import auth_utils
from ruddock.decorators import login_required
from ruddock.modules.users import blueprint, helpers

@blueprint.route('/list', defaults={'search_type': 'all'})
@blueprint.route('/list/<search_type>')
@login_required()
def show_memberlist(search_type):
  """
  Displays the member list. Optionally filters for only current students
  or only alumni.
  """
  # If search_type is not a valid value (someone is messing with the URL),
  # abort the request.
  search_filters_all = ['all', 'current', 'alumni'] + helpers.get_all_grad_years()
  if search_type not in search_filters_all:
    flask.abort(http.client.NOT_FOUND)

  memberlist = helpers.get_memberlist(search_type)
  return flask.render_template(
      'memberlist.html',
      memberlist=memberlist,
      search_type=search_type,
      search_terms=search_filters_all)

@blueprint.route('/view/<username>')
@login_required()
def view_profile(username):
  """Procedure to show a user's profile and membership details."""
  user_info = helpers.get_user_info(username)
  offices = helpers.get_office_info(username)

  if user_info is not None:
    return flask.render_template('view_user.html',
        info=user_info,
        offices=offices,
        strftime=time.strftime)
  else:
    flask.abort(http.client.NOT_FOUND)


#!/usr/bin/env python3
"""
Experiment to stress ICQC.

This is using the Xnet test driver to benchmark ICQC performance.
"""
import dataclasses
import json
import os
import sys
import time

import gflags
from termcolor import colored

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import common.misc as misc  # noqa
from common.icpy_stress_experiment import IcPyStressExperiment  # noqa
from common.icpy_stress_experiment import get_default_stress_configuration  # noqa

FLAGS = gflags.FLAGS

GB = 1024 * 1024 * 1024
CANISTER_MEMORY = 3.8 * GB
DEFAULT_NUM_PAGES = CANISTER_MEMORY / 4096

NUM_QUERY_THREADS_PER_CANISTER = 2

gflags.DEFINE_integer("call_graph_depth", 2, "Depth of the call graph to generate")
gflags.DEFINE_integer("call_graph_fanout", 2, "Rank of the out degree in each node")
gflags.DEFINE_boolean("dry_run", False, "Just print how many canisters would be needed")
gflags.DEFINE_boolean("duplicate_subtrees", False, "Duplicate subtrees instead of building copies.")
gflags.DEFINE_boolean("debug", False, "Create a list of message exchanges. For debugging purposes.")
gflags.DEFINE_integer("num_pages", DEFAULT_NUM_PAGES, "Number of pages to touch.")

# Configuration for load
CANISTER = "call-tree-test-canister"

class CompositeQueryExperiment(IcPyStressExperiment):
    """Logic for Icqc experiment."""

    def __init__(self):
        """Construct Icqc experiment."""
        super().__init__(False)
        super().init()
        super().init_experiment()

        self.target = self.get_machine_to_instrument()

        self.graph = self.get_topology(FLAGS.call_graph_depth)
        self.root_canister_id = self.install_canister(self.target, CANISTER)
        print("Graph is: ", self.graph)

    def get_topology(self, depth):
        """
        Returns a list of dictionaries.

        The dictionary contains itself recursively (key "subtrees") and
        a canister id indicating which canister should handle this subtree.
        """
        if depth == 0:
            return []

        if FLAGS.duplicate_subtrees:
            # Build a single subtree
            subtree = {
                "canister_id": self.install_canister(self.target, CANISTER),
                "subtrees": self.get_topology(depth - 1),
            }
            return [subtree for _ in range(FLAGS.call_graph_fanout)]
        else:
            # Build call_graph_fanout subtrees
            return [
                {"canister_id": self.install_canister(self.target, CANISTER), "subtrees": self.get_topology(depth - 1)}
                for _ in range(FLAGS.call_graph_fanout)
            ]

    def plot_call_graph(self, response):
        import pydot

        graph = pydot.Dot("call_graph", graph_type="graph")

        parsed = json.loads(response)
        import itertools

        all_cids = set(itertools.chain.from_iterable([(m["sender"], m["receiver"]) for m in parsed]))
        cid_map = {cid: uid for uid, cid in enumerate(all_cids)}
        for message in parsed:
            sender = cid_map[message["sender"]]
            receiver = cid_map[message["receiver"]]
            graph.add_edge(pydot.Edge(sender, receiver, color="blue"))

        graph.write_png("callgraph.png")

    def run_experiment_internal(self, config):
        """Run a single iteration of the Icqc benchmark and return it's metrics."""
        agent = misc.get_agent(self.target)
        arguments_as_json = json.dumps(
            {
                "calltrees": self.graph,
                "debug": False,
                "num_pages": FLAGS.num_pages,
            }
        )
        print(f"Running with {config['rps']} rps - Graph JSON is: {arguments_as_json}")

        # XXX Support multiple concurrent canister call trees w/ multiple root nodes!
        machines = self.get_machines_to_target()
        stress_configuration = dataclasses.replace(
            get_default_stress_configuration(), method="start", payload=arguments_as_json, use_updates=False
        )
        self.run_all(config["rps"], FLAGS.iter_duration, machines, self.root_canister_id, stress_configuration)

        if FLAGS.debug:
            arguments_as_json = json.dumps(
                {
                    "calltrees": self.graph,
                    "debug": True,
                    "num_pages": FLAGS.num_pages,
                }
            )
            print(f"Running debug run (with graph output: {arguments_as_json}")
            t_request_start = time.time()
            response = agent.query_raw(self.root_canister_id, "start", arguments_as_json)
            duration = time.time() - t_request_start
            print(f"Debug run took: {duration}")
            print(f"Response is: {response}")
            parsed = json.loads(response)
            print(f"Total: {len(parsed)} messages (will show only in debug mode)")

            # Plot only the last response
            self.plot_call_graph(response)

if __name__ == "__main__":

    print(
        colored(
            "Note that this benchmark currently needs to run on a system subnet. Use --targets=... to specify IPv6 address of e.g. an NNS node",
            "red",
        )
    )

    exp = CompositeQueryExperiment()
    if FLAGS.dry_run:
        import math

        total = sum([math.pow(FLAGS.call_graph_fanout, d) for d in range(FLAGS.call_graph_depth + 1)])
        print(f"#canister needed for depth={FLAGS.call_graph_depth} and fanout={FLAGS.call_graph_fanout}: {total}")
        sys.exit(0)

    exp.run_experiment({"rps": 2 * NUM_QUERY_THREADS_PER_CANISTER})
    exp.end_experiment()


from enum import IntEnum
from typing import Tuple

from Controllers.HC05Controller import HC05_Controller
from Controllers.CoreController import CoreController
from Controllers.UserManager import UserManager
from Controllers.PresetManager import PresetManager

from Question.Options import OptionsContainer, StandardOptions
from Question.RestrictedQuestion import RestrictedQuestion

class CoreManager:
    class ManagementOptionsEnum(IntEnum):
        LIST_OPT: int = 0
        LIST_BLOCK : int = 1
        ADD : int = 2
        EDIT : int = 3
        REMOVE : int = 4

    def __init__(self, bluetooth_radio : HC05_Controller):
        # Options
        self.options_container = OptionsContainer(self.ManagementOptionsEnum)

        # Bluetooth Radio
        self.bluetooth_radio = bluetooth_radio

        # Controllers
        self.core_controller = CoreController(self.bluetooth_radio)

        # Managers
        self.preset_manager = PresetManager(self.core_controller)
        self.user_manager = UserManager(self.core_controller)

        # Establish Connection
        # conn_estab and error are provided for future uses. They are handled in HC05Controller.py.
        conn_estab, error, setup = self.establish_connection()

        if setup:
            self.setup()

    def establish_connection(self) -> Tuple[int, int, int]:
        # Establish link with bluetooth radio
        return self.bluetooth_radio.establish_connection()

    def end_connection(self):
        # End link with bluetooth radio
        self.bluetooth_radio.end_connection()

    def setup(self):
        print()
        print("***SMART PLUG SETUP***")
        print()
        # Create and add a new user
        self.user_manager.add_user()

    def ask_command_question(self) -> bool:
        command_question : RestrictedQuestion = RestrictedQuestion("What command would you like to run? ", OptionsContainer(self.ManagementOptionsEnum))
        # Ask the question, until a valid response is received
        command : int = command_question.ask_question()
        # Handle the option appropriately
        continuing : bool = self.handle_option(command_question, command)

        return continuing

    def handle_option(self, command_question : RestrictedQuestion, option : int) -> bool:
        if option == StandardOptions.EXIT:
            # Cleanup and exit
            self.end_connection()
            return False
        elif option == self.ManagementOptionsEnum.LIST_OPT:
            # List the available options
            command_question.valid_answers.list_options()
        elif option == self.ManagementOptionsEnum.LIST_BLOCK:
            # List presets
            self.preset_manager.get_presets()
        elif option == self.ManagementOptionsEnum.ADD:
            # Add preset
            self.preset_manager.add_preset(self.user_manager.user.prefs)
        elif option == self.ManagementOptionsEnum.EDIT:
            # Edit time block
            self.preset_manager.update_preset()
        elif option == self.ManagementOptionsEnum.REMOVE:
            self.preset_manager.remove_preset()

        return True

def intro():
    print(39 * "*")
    print(f"{5 * '*'} SMART PLUG CONTROL SOFTWARE {5 * '*'}")
    print(39 * "*")
    print()

def main():
    # Display nice intro banner
    intro()

    # Create serial connection to bluetooth radio (doesn't actually connect)
    # Let's hope no one changes the name of the HC-05
    bluetooth_radio = HC05_Controller("/dev/cu.SMARTPLUG-SPPDev", baudrate=9600, timeout=2)

    # Create a management controller
    management_controller : CoreManager = CoreManager(bluetooth_radio)

    # Check if command line arguments have been passed in
    asking_command_questions : bool = True
    while asking_command_questions:
        asking_command_questions = management_controller.ask_command_question()

if __name__ == "__main__":
    main()


import seaborn as sns
import numpy as np
import mat73
import os
import scipy.io as rd
import matplotlib.pyplot as plt
import pandas as pd

bin_folder='D:/Data/Results/decoderResults/figures/OriginalDataFigures'
fname='barchartresults.mat'
info_barplot = rd.loadmat(bin_folder + os.sep + fname)
matversion_difference=info_barplot['differencemat']
# matversion_crumble=info_barplot['matversion_crumble']
# matversion_crumble_L27=info_barplot['matversion_crumble_l27']
# matversion_eclair=info_barplot['matversion_eclair']
# matversion_eclair_l27=info_barplot['matversion_eclair_l27']
# matversion_zola=info_barplot['matversion_zola']
# matversion_zola_l27=info_barplot['matversion_zola_l27']
# tips = sns.load_dataset("tips")
#
# ax = plt.subplots()
# #zola=bar(mean(matversion_zola(:, [2,1,3])))
#
# zola_y=np.mean(matversion_zola, axis=0)
# zola_y_l27=np.mean(matversion_zola_l27, axis=0)
# zola_y_1=(zola_y[1])
# zola_y_2=(zola_y[0])
# zola_y_3=(zola_y[2])
# zola_y_l28=[zola_y_1, zola_y_2, zola_y_3]
# zola_y_l28_scatter=[matversion_zola[:,1], matversion_zola[:,0], matversion_zola[:,2]]
# zola_y_l27_bar=[zola_y_l27[0], zola_y_l27[7], zola_y_l27[2],  zola_y_l27[3],  zola_y_l27[4],  zola_y_l27[5],  zola_y_l27[6]]
# zola_y_l27_scatter=[matversion_zola_l27[:, 0], matversion_zola_l27[:, 7], matversion_zola_l27[:,2],  matversion_zola_l27[:,3],  matversion_zola_l27[:,4],  matversion_zola_l27[:,5],  matversion_zola_l27[:,6]]
#[1,8,3:7]
# plotting columns
# ax=sns.stripplot(data=zola_y_l28_scatter, jitter=0.1, color='green', alpha=0.8)
# ax=sns.stripplot(data=matversion_crumble, jitter=0.1, color='purple', alpha=0.8)
# ax=sns.stripplot(data=matversion_eclair, jitter=0.1, color='navy', alpha=0.8)
# ax = sns.barplot([1,2,3], zola_y_l28,  color='green', label='F1702',alpha=.3)
# ax = sns.barplot([1,2,3,4,5,6,7], np.mean(matversion_eclair, axis=0), color='navy', alpha=0.3, label='F1902')
# ax=sns.barplot([1,2,3,4,5,6,7], np.mean(matversion_crumble, axis=0),  color='purple',  alpha=0.3, label='F1901')
# x_vec=np.empty((24,2))
# ax=sns.boxplot( y=matversion_difference[0])
# x_vecc1=np.transpose(np.array([0] * 12))
# x_vecc2=np.transpose(np.array([1] * 12))
# np.reshape(x_vecc1, (1,12), order='C')
# x_vec[0]=np.transpose(np.concatenate((x_vecc1, x_vecc2), axis=0))
# x_vec[1]=np.concatenate((matversion_difference[:,0], matversion_difference[:, 1]), axis=0)
#
# x_vec=x_vec.tolist()
df = pd.DataFrame(matversion_difference, columns = ['Rove','Natural'])

ax=sns.boxplot(y=df["Rove"])
plt.title('Decoding score of behavioural response using \n a dynamic time warping shift model', fontsize=15)
str={'roved F0', 'control F0'}
plt.xticks([0,1], labels=str, rotation=45)
plt.xlabel('F0 Type of Target Stimulus')
plt.ylabel('Relative decoding score (score-chance)')

plt.legend(fontsize=8)
plt.ylim([-0.35, 0.4])
ax = sns.boxplot(data=df, orient="y", palette="magma")
ax=sns.stripplot(data=df, jitter=0.1, palette='husl', alpha=1)
plt.savefig(bin_folder + '\seabornboxplotmissvhit_l27.png',dpi=500, bbox_inches='tight')

plt.show()

#barchartresults_orig
fname='barchartresults_orig.mat'
info_barplot = rd.loadmat(bin_folder + os.sep + fname)
matversion_difference_orig=info_barplot['differencemat']

df_orig = pd.DataFrame(matversion_difference_orig, columns = ['Rove','Natural'])

plt.title('Decoding score of behavioural response without \n dynamic time warping', fontsize=15)
str={'roved F0', 'control F0'}
plt.xticks([0,1], labels=str, rotation=45)
plt.xlabel('F0 Type of Target Stimulus')
plt.ylabel('Relative decoding score (score-chance)')

plt.legend(fontsize=8)
plt.ylim([-0.35, 0.4])
ax = sns.boxplot(data=df_orig, orient="y", palette="magma")
ax=sns.stripplot(data=df_orig, jitter=0.1, palette='husl', alpha=1)
plt.savefig(bin_folder + '\seabornboxplothitvsmiss_origdata_l27.png',dpi=500, bbox_inches='tight')

plt.show()

#ax2 = plt.subplots()
# ax2=sns.stripplot(data=zola_y_l27_scatter, jitter=0.1, color='green', alpha=0.8)
# ax2=sns.stripplot(data=matversion_crumble_L27, jitter=0.1, color='purple', alpha=0.8)
# ax2=sns.stripplot(data=matversion_eclair_l27, jitter=0.1, color='navy', alpha=0.8)
# ax2 = sns.barplot([1,2,3,4,5,6,7], zola_y_l27_bar,  color='green', label='F1702',alpha=.3)
# ax2 = sns.barplot([1,2,3,4,5,6,7], np.mean(matversion_eclair_l27, axis=0), color='navy', alpha=0.3, label='F1902')
# ax2=sns.barplot([1,2,3,4,5,6,7], np.mean(matversion_crumble_L27, axis=0),  color='purple',  alpha=0.3, label='F1901')
# plt.xlabel('Distractor')
# str={'craft', "in contrast to", "when a", "accurate", "rev instruments", "of science", "pink noise instruments"}
# plt.xticks([0,1,2,3,4,5,6], labels=str, rotation=45)
# plt.ylabel('Change in Mean Decoding Score for All Sites')
#
# plt.title('Change in decoding score between train and test dataset, intra-trial roving',fontsize=10)
#
# plt.legend(fontsize=8)
# plt.ylim([-0.35, 0.35])
# plt.savefig(bin_folder + '\seabornbarplot_l27.png', dpi=500, bbox_inches='tight')
# plt.show()


import os
import platform

import discord
from colorama import Fore, Style
from config import prefix, token
from discord.ext import commands

bot = commands.AutoShardedBot(commands.when_mentioned_or(prefix), intents=discord.Intents.all())

bot.remove_command("help")

class AkioHelpCommand(commands.MinimalHelpCommand):
    async def send_pages(self):
        destination = self.get_destination()
        for page in self.paginator.pages:
            await destination.send(
                embed=discord.Embed(description=page, color=discord.Color.random())
            )

bot.help_command = AkioHelpCommand(no_category="Help")

loaded_cogs = 0
print(Fore.MAGENTA + "STARTING COG LOADING PROCESS", Style.RESET_ALL)
for cog in os.listdir("./cogs"):
    if cog.endswith(".py"):
        bot.load_extension(f"cogs.{cog[:-3]}")
        loaded_cogs += 1
        print(Fore.YELLOW + f"Loaded {cog}", Style.RESET_ALL)
print(Fore.MAGENTA + "DONE", Style.RESET_ALL)
print("-" * 15)

@bot.event
async def on_ready():
    print(Fore.GREEN + f"Logged in as {bot.user.name}")
    print(f"ID: {bot.user.id}")
    print(f"Running Discord.py version {discord.__version__}")
    print(f"Running on: {platform.system()} {platform.release()} ({os.name})")
    print(f"Loaded *{loaded_cogs}* cogs in total", Style.RESET_ALL)
    print("-" * 15)

bot.run(token)


try:
    import ujson as json
except:
    import json

try:
    import urequests as requests
except:
    import requests

import time

# Returns a string representing the current date and time in YYY-MM-dd format

def get_datetime():
    datetime = None
    datetime = time.localtime()
    date_str = str(datetime[0]) + "-" + \
        str(datetime[1]) + "-" + str(datetime[2])
    hour_str = str(
        datetime[4]) if datetime[4] >= 10 else "0" + str(datetime[4])
    seconds_str = str(
        datetime[5]) if datetime[5] >= 10 else "0" + str(datetime[5])
    time_str = str(datetime[3]) + ":" + hour_str + ":" + seconds_str
    return date_str + " " + time_str

class Spreadsheet:

    def __init__(self, logger=None, retry_limit=50):
        self._id = ''
        self._range = ''
        self._url_params = 'insertDataOption=INSERT_ROWS&valueInputOption=USER_ENTERED'
        self._url_template = 'https://sheets.googleapis.com/v4/spreadsheets/%s/values/%s:append?%s'
        self._sa = None
        self.logger = logger
        self.retry_limit = retry_limit

    def set_id(self, id):
        self._id = id

    def set_range(self, range):
        self._range = range

    def set_service_account(self, sa):
        self._sa = sa

    def append_values(self, values):
        print('spreadsheet: send: %s' % values)

        datetime = get_datetime()
        print("Datetime is: " + datetime)

        token = self._sa.token()

        url = self._url_template % (self._id, self._range, self._url_params)

        values.insert(0, datetime)
        data = {'values': [values]}
        headers = {}
        headers['Content-Type'] = 'application/json'
        headers['Authorization'] = 'Bearer %s' % token
        self.send_values(url, data, headers)

    def send_values(self, url, data, headers):
        counter = 0
        response = False

        while not response and counter < self.retry_limit:
            try:
                if counter == 0:
                    raise ZeroDivisionError()
                response = requests.post(url, json=data, headers=headers)
            except Exception as e:
                counter += 1
                if (counter < self.retry_limit):
                    print("Error encountered, retrying attempt " + str(counter) + "...")
                    time.sleep(1)
                    continue
                else:
                    self.logger.log_error("Error encountered while sending data")
                    raise e

            if (response):
                print('\nspreadsheet response:')
                print(response.text)
                if (self.logger is not None):
                    self.logger.log("Data successfully submitted at " + get_datetime() + " UTC")
                return
            elif (counter < self.retry_limit):
                counter += 1
                print("No spreadsheet response recieved, retrying attempt " + str(counter) + "...")
            else:
                if (self.logger is not None):
                    self.logger.log_error("No response from spreadsheet")
                return


from typing import Dict, List, Optional, Union

from power_grid_model.data_types import BatchDataset, SingleDataset
from power_grid_model.enum import CalculationType
from power_grid_model.validation.errors import ValidationError
from power_grid_model.validation.utils import errors_to_string
from power_grid_model.validation.validation import validate_batch_data, validate_input_data

class ValidationException(ValueError):
    """
    An exception storing the name of the validated data, a list/dict of errors and a convenient conversion to string
    to display a summary of all the errors when printing the exception.
    """

    def __init__(self, errors: Union[List[ValidationError], Dict[int, List[ValidationError]]], name: str = "data"):
        super().__init__(f"Invalid {name}")
        self.errors = errors
        self.name = name

    def __str__(self):
        return errors_to_string(errors=self.errors, name=self.name)

def assert_valid_input_data(
    input_data: SingleDataset, calculation_type: Optional[CalculationType] = None, symmetric: bool = True
):
    """
    Validates the entire input dataset:

        1. Is the data structure correct? (checking data types and numpy array shapes)
        2. Are all required values provided? (checking NaNs)
        3. Are all ID's unique? (checking object identifiers across all components)
        4. Are the supplied values valid? (checking limits and other logic as described in "Graph Data Model")

    Args:
        input_data: A power-grid-model input dataset
        calculation_type: Supply a calculation method, to allow missing values for unused fields
        symmetric: A boolean to state whether input data will be used for a symmetric or asymmetric calculation

    Raises:
        KeyError | TypeError | ValueError: if the data structure is invalid.
        ValidationException: if the contents are invalid.
    """
    validation_errors = validate_input_data(
        input_data=input_data, calculation_type=calculation_type, symmetric=symmetric
    )
    if validation_errors:
        raise ValidationException(validation_errors, "input_data")

def assert_valid_batch_data(
    input_data: SingleDataset,
    update_data: BatchDataset,
    calculation_type: Optional[CalculationType] = None,
    symmetric: bool = True,
):
    """
    The input dataset is validated:

        1. Is the data structure correct? (checking data types and numpy array shapes)
        2. Are all input data ID's unique? (checking object identifiers across all components)

    For each batch the update data is validated:
        3. Is the update data structure correct? (checking data types and numpy array shapes)
        4. Are all update ID's valid? (checking object identifiers across update and input data)

    Then (for each batch independently) the input dataset is updated with the batch's update data and validated:
        5. Are all required values provided? (checking NaNs)
        6. Are the supplied values valid? (checking limits and other logic as described in "Graph Data Model")

    Args:
        input_data: a power-grid-model input dataset
        update_data: a power-grid-model update dataset (one or more batches)
        calculation_type: Supply a calculation method, to allow missing values for unused fields
        symmetric: A boolean to state whether input data will be used for a symmetric or asymmetric calculation

    Raises:
        KeyError | TypeError | ValueError: if the data structure is invalid.
        ValidationException: if the contents are invalid.
    """
    validation_errors = validate_batch_data(
        input_data=input_data, update_data=update_data, calculation_type=calculation_type, symmetric=symmetric
    )
    if validation_errors:
        raise ValidationException(validation_errors, "update_data")


import logging
from odoo import api,fields, models

_logger = logging.getLogger(__name__)

class MassConfirm(models.TransientModel):

    _name = "mass.order.confirm"
    order_no = fields.Char("Order No")
    vehicle_no = fields.Char("Vehicle No")

    @api.model
    def confirm_purchase_orders(self, val_list):
        ids = [val['order_no'] for val in val_list]
        _logger.info("The ids multi in purchase confirm")
        _logger.info(ids)
        po_ids = self.env['purchase.order'].search([('name', 'in', ids),('state','=','draft')])
        if po_ids:
            po_ids.button_approve()
            d = val_list
            for l in range(len(po_ids)):
                d[l]['ids'] = po_ids[l]
            #self.confirm_inventory(d)
        else:
            _logger.info("No Purchase Inventory to Process")
            return False

    @api.model
    def confirm_sale_orders(self, val_list):
        ids = [val['order_no'] for val in val_list]
        so_ids = self.env['sale.order'].search([('name', 'in', ids),('state','=','draft')])
        if so_ids:
            for so_id in so_ids:
                so_id.action_confirm()
            d = val_list
            for l in range(len(so_ids)):
                d[l]['ids'] = so_ids[l]
            #self.confirm_inventory(d)
        else:
            _logger.info("No Sales Inventory to Process")
            return False

    @api.multi
    def confirm_inventory(self, val_list):
        _logger.info("Confirm Multi Inventory")
        for vals in val_list:
            _logger.info(vals)
            order_id = vals['ids']
            _logger.info("ORDER ID Before Processing" + str(order_id))
            vehicle_id = self.env['vehicle'].search([('ref', '=', order_id.name)])
            if not vehicle_id or not order_id:
                _logger.error("ERROR processing" + str(order_id))
                continue
            try:
                self._create_move_lines(order_id.picking_ids, vehicle_id.id)
            except Exception as ex:
                _logger.error("ERROR processing" + str(order_id))
        return True

    @api.multi
    def _create_move_lines(self, picking_ids, vehicle_id):
        if not picking_ids.move_line_ids:
            template = self._prepare_stock_move_line(picking_ids, vehicle_id)
            res = self.env['stock.move.line'].create(template)
            _logger.info(res)
        else:
            _logger.info("Move Line Exists")
            picking_ids.move_line_ids.write({'vehicle_id':vehicle_id, 'qty_done':1})
        picking_ids.action_done()

    @api.multi
    def _prepare_stock_move_line(self, picking,vehicle_id):

        move_line = picking.move_lines
        template = {'move_id':move_line.id,
                    'location_id':move_line.location_id.id,
                    'location_dest_id':move_line.location_dest_id.id,
                    'product_id':move_line.product_id.id,
                    'product_uom_id':1,'picking_id':picking.id,
                    'vehicle_id':vehicle_id,
                    'qty_done':1
                    }
        return template


from django.db import models

# Create your models here.

class tweet(models.Model):
	timestemp = models.DateTimeField('date published')
	body = models.CharField(max_length = 200)

	def __unicode__(self):
		result=self.body
		cut = 20
		if len(result) > cut:
			result = result[:cut] + "..."
		return result


import unittest
import os
import requests_mock
from parsons import VAN
from requests.exceptions import HTTPError
from test.test_van.responses_people import (
    find_people_response,
    get_person_response,
    merge_contacts_response,
    delete_person_response,
)

os.environ["VAN_API_KEY"] = "SOME_KEY"

class TestNGPVAN(unittest.TestCase):
    def setUp(self):
        self.van = VAN(os.environ["VAN_API_KEY"], db="MyVoters", raise_for_status=False)

    @requests_mock.Mocker()
    def test_find_person(self, m):
        m.post(
            self.van.connection.uri + "people/find",
            json=find_people_response,
            status_code=200,
        )

        person = self.van.find_person(
            first_name="Bob", last_name="Smith", phone=4142020792
        )

        self.assertEqual(person, find_people_response)

    @requests_mock.Mocker()
    def test_find_person_json(self, m):
        json = {
            "firstName": "Bob",
            "lastName": "Smith",
            "phones": [{"phoneNumber": 4142020792}],
        }

        m.post(
            self.van.connection.uri + "people/find",
            json=find_people_response,
            status_code=200,
        )

        person = self.van.find_person_json(match_json=json)

        self.assertEqual(person, find_people_response)

    def test_upsert_person(self):
        pass

    def test_upsert_person_json(self):
        pass

    def test_update_person(self):
        pass

    def test_update_person_json(self):
        pass

    def test_people_search(self):
        # Already tested as part of upsert and find person methods
        pass

    def test_valid_search(self):
        # Fails with FN / LN Only
        self.assertRaises(
            ValueError,
            self.van._valid_search,
            "Barack",
            "Obama",
            None,
            None,
            None,
            None,
            None,
        )

        # Fails with only Zip
        self.assertRaises(
            ValueError,
            self.van._valid_search,
            "Barack",
            "Obama",
            None,
            None,
            None,
            None,
            60622,
        )

        # Fails with no street number
        self.assertRaises(
            ValueError,
            self.van._valid_search,
            "Barack",
            "Obama",
            None,
            None,
            None,
            "Pennsylvania Ave",
            None,
        )

        # Successful with FN/LN/Email
        self.van._valid_search(
            "Barack", "Obama", "barack@email.com", None, None, None, None
        )

        # Successful with FN/LN/DOB/ZIP
        self.van._valid_search(
            "Barack", "Obama", "barack@email.com", None, "2000-01-01", None, 20009
        )

        # Successful with FN/LN/Phone
        self.van._valid_search("Barack", "Obama", None, 2024291000, None, None, None)

    @requests_mock.Mocker()
    def test_get_person(self, m):
        json = get_person_response

        # Test works with external ID
        m.get(self.van.connection.uri + "people/DWID:15406767", json=json)
        person = self.van.get_person("15406767", id_type="DWID")
        self.assertEqual(get_person_response, person)

        # Test works with vanid
        m.get(self.van.connection.uri + "people/19722445", json=json)
        person = self.van.get_person("19722445")
        self.assertEqual(get_person_response, person)

    @requests_mock.Mocker()
    def test_delete_person(self, m):
        json = delete_person_response
        # Test works with vanid
        m.delete(self.van.connection.uri + "people/19722445", json=json)
        response = self.van.delete_person("19722445")
        self.assertEqual(delete_person_response, response)

    @requests_mock.Mocker()
    def test_apply_canvass_result(self, m):
        # Test a valid attempt
        m.post(
            self.van.connection.uri + "people/2335282/canvassResponses", status_code=204
        )
        self.van.apply_canvass_result(2335282, 18)

        # Test a bad result code
        json = {
            "errors": [
                {
                    "code": "INVALID_PARAMETER",
                    "text": "'resultCodeId' must be a valid result code in the current context.",
                    "properties": ["resultCodeId"],
                }
            ]
        }
        m.post(
            self.van.connection.uri + "people/2335282/canvassResponses",
            json=json,
            status_code=400,
        )
        self.assertRaises(HTTPError, self.van.apply_canvass_result, 2335282, 0)

        # Test a bad vanid
        json = {
            "errors": [
                {
                    "code": "INTERNAL_SERVER_ERROR",
                    "text": "An unknown error occurred",
                    "referenceCode": "88A111-E2FF8",
                }
            ]
        }
        m.post(
            self.van.connection.uri + "people/0/canvassResponses",
            json=json,
            status_code=400,
        )
        self.assertRaises(HTTPError, self.van.apply_canvass_result, 0, 18)

        # Test a good dwid
        m.post(
            self.van.connection.uri + "people/DWID:2335282/canvassResponses",
            status_code=204,
        )
        self.van.apply_canvass_result(2335282, 18, id_type="DWID")

        # test canvassing via phone or sms without providing phone number
        self.assertRaises(
            Exception, self.van.apply_canvass_result, 2335282, 18, contact_type_id=37
        )

        # test canvassing via phone or sms with providing phone number
        m.post(
            self.van.connection.uri + "people/2335282/canvassResponses", status_code=204
        )
        self.van.apply_canvass_result(
            2335282, 18, contact_type_id=37, phone="(516)-555-2342"
        )

    @requests_mock.Mocker()
    def test_apply_survey_question(self, m):
        # Test valid survey question
        m.post(
            self.van.connection.uri + "people/2335282/canvassResponses", status_code=204
        )
        self.van.apply_survey_response(2335282, 351006, 1443891)

        # Test bad survey response id
        # json = {
        #     'errors': [{
        #         'code': 'INVALID_PARAMETER',
        #         'text': ("'surveyResponseId' must be a valid Response to the given "
        #                  "Survey Question."),
        #         'properties': ['responses[0].surveyResponseId']
        #     }]
        # }
        m.post(
            self.van.connection.uri + "people/2335282/canvassResponses", status_code=400
        )
        self.assertRaises(
            HTTPError, self.van.apply_survey_response, 2335282, 0, 1443891
        )

        # Test bad survey question id
        # json = {
        #     'errors': [{
        #         'code': 'INVALID_PARAMETER',
        #         'text': ("'surveyQuestionId' must be a valid Survey Question that is "
        #                 "available in the current context."),
        #         'properties': ['responses[0].surveyQuestionId']
        #     }]
        # }
        m.post(
            self.van.connection.uri + "people/2335282/canvassResponses", status_code=400
        )
        self.assertRaises(HTTPError, self.van.apply_survey_response, 2335282, 351006, 0)

    def test_toggle_volunteer_action(self):
        pass

    def test_apply_response(self):
        pass

    @requests_mock.Mocker()
    def test_create_relationship(self, m):
        relationship_id = 12
        bad_vanid_1 = 99999
        good_vanid_1 = 12345
        vanid_2 = 54321

        # Bad request
        m.post(
            self.van.connection.uri + "people/{}/relationships".format(bad_vanid_1),
            status_code=404,
        )

        # Good request
        m.post(
            self.van.connection.uri + "people/{}/relationships".format(good_vanid_1),
            status_code=204,
        )

        # Test bad input
        self.assertRaises(
            HTTPError,
            self.van.create_relationship,
            bad_vanid_1,
            vanid_2,
            relationship_id,
        )
        self.assertRaises(
            HTTPError,
            self.van.create_relationship,
            bad_vanid_1,
            vanid_2,
            relationship_id,
        )

        self.van.create_relationship(good_vanid_1, vanid_2, relationship_id)

    @requests_mock.Mocker()
    def test_apply_person_code(self, m):
        vanid = 999
        code_id = 888

        # Test good request
        m.post(self.van.connection.uri + f"people/{vanid}/codes", status_code=204)
        self.van.apply_person_code(vanid, code_id)

        # Test bad request
        m.post(self.van.connection.uri + f"people/{vanid}/codes", status_code=404)
        self.assertRaises(HTTPError, self.van.apply_person_code, vanid, code_id)

    @requests_mock.Mocker()
    def test_merge_contacts(self, m):
        source_vanid = 12345

        m.put(
            self.van.connection.uri + f"people/{source_vanid}/mergeInto",
            json=merge_contacts_response,
            status_code=200,
        )

        person = self.van.merge_contacts(source_vanid=source_vanid, primary_vanid=56789)

        self.assertEqual(person, merge_contacts_response)


"""

This module provides functions for creating, saving, and maintaining the ConfigParser object for AdaHub.

"""

# Local imports
from ada_hub.lib.constants import PROG, DEFAULT_CONF_FILE_PATH, DEFAULT_DATA_ROOT, DEFAULT_CONF_ROOT

# Standard Library imports (from)
from logging import getLogger
from pathlib import Path

# Standard Library imports (standard)
import configparser

from ada_hub.lib.config.defaults import create_new_config

def write_config(conf_obj: object, conf_path: str) -> None:
    """

    Write the provided ConfigParser object to an .ini file at the path indicated

    Args:
        conf_obj (object): A ConfigParser object that you would like written to the given path.
        conf_path (str): A string containing the path where we need to write our ConfigParser object.

    Returns:
        None

    """

    with open(conf_path, 'w') as fp:
        conf_obj.write(fp)

class AdaHubConfig(object):

    def read_from_disk(self):
        """

        Function that reads our configuration state from a file (which is assigned when AdaHubConfig is initialized)
        and loads it into memory (particularly, for the purposes of this documentation we just need to know that it's
        being stored in a variable called 'config' which is what is returned at the end of its operation.

        Returns:
            Config (object)

        """

        # Set up a logger for this function.
        log_name = f'{self.log_name}.read_from_disk'
        log = getLogger(log_name)

        # For verbose output, announce ourselves and why we're operating.
        log.debug(f'Logger started for {log_name}')
        log.debug(f'Received call to read config file from disk: {self.config_file_path}')

        # Initialize a new ConfigParser object for us to load the config file that we read into.
        config = configparser.ConfigParser()

        # Use the ConfigParser object to read the settings file, and parse it appropriately.
        config.read(self.config_file_path)

        # For debugging purposes we will announce the sections we found within the config file.
        log.debug(f'Found config file with these sections: {config.sections()}')

        # Finally, return our object to the caller
        return config

    def __init__(self, args):
        # Import directly
        import os

        # From * standard library imports
        from pathlib import Path

        if args.data_dir is None:
            self.conf_dir = DEFAULT_CONF_ROOT
        else:
            self.conf_dir = str(args.data_dir() + '/conf')

        self.config_filepath = str(self.conf_dir + '/settings.ini')

        conf_dir_exists = os.path.exists(Path(self.conf_dir))
        conf_file_exists = os.path.exists(Path(self.conf_file_path))
        conf_file_isfile = os.path.exists(Path(self.config_file_path))

        if conf_dir_exists and conf_file_exists and conf_file_isfile:
            self.config = self.read_from_disk()

        if args.data_dir:
            path_to_config = args.data_dir
        else:
            path_to_config = args.data_dir

        # Start a logger
        self.log_name = f'{PROG}.AdaHubConfig'
        log = getLogger(self.log_name)

        log.debug('Started Logger for AdaHubConfig')
        log.debug('Initializing class')

        # Determine and (if log levels permit) announce the default configuration file path
        self.default_conf_file_path = DEFAULT_CONF_FILE_PATH
        log.debug(f'The default config file location is {self.default_conf_file_path}')

        # Check to see if a value for the path_to_config parameter was provided; if so we'll use that instead of the
        # default path found in the constants file.
        log.debug('Checking for non-default path to config...')

        if path_to_config is not None:
            log.debug(f'A custom config path was provided: {path_to_config}')
            config_path = Path(path_to_config)
        else:
            log.debug(f'No custom config filepath provided, falling back on default filepath: {self.default_conf_file_path}')
            config_path = Path(self.default_conf_file_path)

        # Finally, set this path as an attribute of the AdaHubConfig class
        self.config_file_path = config_path

        self.conf_root = self.config_file_path.parent

        if not Path(self.conf_root).exists():
            log.warning(f'Config root not present on system {self.conf_root}')
            os.makedirs(Path(self.conf_root))
            log.info('Directory written!')
        else:
            if Path(self.config_file_path).exists():
                log.debug('Found config file')
                self.config = self.read_from_disk()

            else:
                log.debug('Did not find specified config file. Creating...')
                config_struct = self.build_default()
                write_config(config_struct, config_struct['RUNTIME']['conf_file_path'])
                with open(config_struct['RUNTIME']['conf_file_path'], 'w') as fp:
                    config_struct.write(fp)
                    log.debug('Written')
                self.config = config_struct

            log.debug(f'Sections in config: {self.config.sections()}')

# Author: Taylor-Jayde Blackstone <t.blackstone@inspyre.tech>
# Since: Version 1.0


# coding=utf-8
from rest_framework import viewsets, mixins
from halls.models import Hall, SubHall, ContentSubHall, SubHallTag
from halls.serializers import HallSerializer, SubHallSerializer
from django.shortcuts import get_object_or_404
from rest_framework.response import Response

class HallsViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = Hall.objects.filter()
    serializer_class = HallSerializer

    def list(self, request, *args, **kwargs):
        serializer = self.serializer_class(self.queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, *args, **kwargs):
        hall = get_object_or_404(Hall.objects.all(), name=kwargs.get('pk', ''))
        serializer = self.serializer_class(hall)
        return Response(serializer.data)

class SubHallsViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = SubHall.objects.filter()
    serializer_class = SubHallSerializer

    def list(self, request, *args, **kwargs):
        serializer = self.serializer_class(self.queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, *args, **kwargs):
        hall = get_object_or_404(SubHall.objects.all(), name=kwargs.get('pk', ''))
        serializer = self.serializer_class(hall)
        return Response(serializer.data)

class ContentSubHallViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = ContentSubHall.objects.filter()
    serializer_class = HallSerializer

    def retrieve(self, request, *args, **kwargs):
        sub_hall = get_object_or_404(SubHallTag.objects.all(), tag=kwargs.get('pk', '')).parent_hall

        contents = []

        for p in ContentSubHall.objects.filter(sub_hall=sub_hall):
            entry = {
                "media": str(p.media),
                "url": str(p.url)
            }
            contents.append(entry)

        return Response(contents)


#!/usr/bin/env python
# encoding: utf-8

import argparse

from influxdb import InfluxDBClient, client as inf_client
import readline
from datetime import datetime

client = None
readline.parse_and_bind('?: complete')
readline.set_completer_delims(" ")

series = []

tags = ["SELECT", "FROM", "GROUP BY", "COUNT(", "FILL(", "INNER JOIN", "DISTINCT(", "WHERE", "AND", "", "TIME", "VALUE", "ASC", "DESC", "DERIVATIVE(", "COUNT(", "MEAN(", "SUM(", "MIN(", "MAX(","STDDEV(", "FIRST(", "LAST(", "DIFFERENCE(", "MEDIAN(", "MODE(", "LIMIT"]

def influxdb_compete(text, state):
    utext = text.upper()
    current_line = readline.get_line_buffer().strip().upper()
    try:
        if len(current_line) >= readline.get_begidx():
            x = current_line[:readline.get_begidx()].split()
        else:
            x = current_line.split()
    except Exception as e:
        x = []
    if (len(x) > 0 and x[-1] == 'FROM'):
        for t in [i for i in series if i.lower().startswith(text.lower())]:
            if state == 0:
                return t
            else:
                state -= 1
    elif (len(x) > 0 and x[-1] == 'SELECT'):
        for t in [x for x in ['value', 'time'] if x.startswith(text.lower())]:
            if state == 0:
                return "%s " % t
            else:
                state -= 1
    else:
        for t in tags:
            if t.startswith(utext):
                if state == 0:
                    return "%s " % t
                else:
                    state -= 1
    return None

def load_series():
    global series
    res = client.query("list series")
    series = [i[1] for i in res[0]['points']]

def main():
    readline.parse_and_bind("tab: complete")
    readline.add_history("list series")
    readline.set_completer(influxdb_compete)

    load_series()

    while True:
        try:
            command = input("> ")
        except KeyboardInterrupt:
            print("\nbye!")
            break
        except EOFError:
            print("\nbye!")
            break
        if not command:
            continue
        cx = command.upper().split()
        cy = command.split()
        if 'FROM' in cx:
            table = cy[cx.index("FROM")+1]
            if not (table.startswith("/") and table.endswith("/")):
                command = ' '.join([' '.join(cy[:cx.index("FROM")+1]), "\"%s\"" % table, ' '.join(cy[cx.index("FROM")+2:])])

        try:
            for i in client.query(command):
                print(i['name'])
                print(' | '.join(i['columns']))
                for point in i['points']:
                    pointdata = point[1:]
                    print("%s, %s" % (datetime.fromtimestamp(point[0]).strftime("%d.%m.%Y %H:%M:%S"), ', '.join([str(i) for i in pointdata])))
        except inf_client.InfluxDBClientError as e:
            print(e.content.decode("utf-8"))

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="InfluxDB command line client")
    parser.add_argument('-u', '--user', help="Username", default="root")
    parser.add_argument('-p', '--password', help="Password", default="root")
    parser.add_argument('-d', '--database', help="Database", default="root")
    parser.add_argument('-s', '--server', help="Server hostname", default="localhost")
    parser.add_argument('--port', help="Port", default=8086, type=int)
    args = parser.parse_args()
    client = InfluxDBClient(args.server, args.port, args.user, args.password, args.database)
    main()


import time
import json
from gevent.pywsgi import WSGIServer
from flask import Flask, Response, render_template, stream_with_context
from gevent import monkey
monkey.patch_all()

"""
Flask server for the web interface
The data is read from lyrics.json and streamed from the server to the client
"""

app = Flask(__name__)

##############################

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

##############################

@app.route("/listen")
def listen():

    def respond_to_client():
        while True:
            with open("lyrics.json", "r") as f:
                song_info = json.load(f)["data"]
                print(song_info)

                _data = json.dumps(
                    {"title": song_info["title"],
                     "lyrics": song_info["lyrics"],
                     "id": f"https://open.spotify.com/embed/track/{song_info['id']}"
                     })

                yield f"id: 1\ndata: {_data}\nevent: online\n\n"
            time.sleep(0.5)
    return Response(respond_to_client(), mimetype='text/event-stream')

##############################
if __name__ == "__main__": #run the server
    # app.run(port=80, debug=True)
    http_server = WSGIServer(("localhost", 80), app)
    http_server.serve_forever()


from sklearn.svm import SVC
from sklearn import grid_search
from sklearn import cross_validation as cs
from sklearn.externals import  joblib
import numpy as np
import persistence
from numpy import *
import time
import warnings

def cross_validation():
    dataSet, labels = persistence.allData(persistence.openConnection())
    # dataMatrix = mat(dataSet)
    # labelMatrix = mat(labels)
    clf = SVC(kernel='rbf', C=1000)
    clf.fit(dataSet, labels)
    scores = cs.cross_val_score(clf, dataSet, labels, cv=5)
    print('Accuracy: %0.2f (+- %0.2f)' % (scores.mean(), scores.std()))
    return clf

# t0 = time.time()
# cross_validation()
# print('fit time:', round(time.time()-t0, 3), 's')

def searchBestParameter():
    parameters = {'kernel': ('linear', 'poly', 'rbf', 'sigmoid'), 'C': [1, 100]}
    dataSet, labels = persistence.allData(persistence.openConnection())
    svr = SVC()
    clf = grid_search.GridSearchCV(svr, parameters)
    clf.fit(dataSet, labels)

    print(clf.best_params_)

# searchBestParameter()
# print('fit time: %.2f s' % round(time.time()-t0, 3))

def predict(binImg1, binImg2, binImg3):
    parameters = {'kernel': ('linear', 'poly', 'rbf', 'sigmoid'), 'C': [1, 100]}
    dataSet, labels = persistence.allData(persistence.openConnection())
    svr = SVC()
    clf = grid_search.GridSearchCV(svr, parameters)
    clf.fit(dataSet, labels)

    v1 = clf.predict(binImg1)
    v2 = clf.predict(binImg2)
    v3 = clf.predict(binImg3)

    return (v1, v2, v3)


import json
import sys

import requests as req

sys.path.append("../athene")
from athene.console import console

data = json.loads(req.get("https://genius1512.github.io/athene/files/data.json").text)
# when getting profile
def get(identifier: str):
    new_data = (
        data["teachers"] if 3 <= len(identifier) <= 4 else data["students"]
    )  # teacher or student?

    if identifier in new_data:
        console.print(f"{identifier}'s profile:", style="standard")
        for attribute in new_data[identifier]:
            console.print(
                f"    {attribute}: {new_data[identifier][attribute]}", style="standard"
            )

def search(term: str):
    # search through teachers
    had_output = False
    for key in data["teachers"]:
        if (
            term in key
            or term in data["teachers"][key]["id"]
            or term in data["teachers"][key]["name"]
            or term in data["teachers"][key]["hash"]
        ):
            had_output = True
            console.print(key, style="standard")
    # search through students
    for key in data["students"]:
        if (
            term in key
            or term in data["students"][key]["id"]
            or term in data["students"][key]["name"]
            or term in data["students"][key]["hash"]
            or term in data["students"][key]["class"]
        ):
            had_output = True
            console.print(key, style="standard")

    if not had_output:
        console.print("No profiles matched your search", style="warning")