import unittest

import torch
import random

from parlai.core.metrics import AverageMetric, SumMetric, FixedMetric, Metrics

class TestMetric(unittest.TestCase):
    """
    Test individual Metric classes.
    """

    def test_sum_metric_inputs(self):

        passing_inputs_and_outputs = [
            (2, 2.0),
            (-5.0, -5.0),
            (torch.LongTensor([[-1]]), -1.0),
            (torch.DoubleTensor([34.68]), 34.68),
        ]
        for input_, output in passing_inputs_and_outputs:
            actual_output = SumMetric(input_).value()
            self.assertEqual(actual_output, output)

        failing_inputs = [
            ('4', AssertionError),
            ([6.8], AssertionError),
            (torch.Tensor([1, 3.8]), ValueError),  # Tensor has more than 1 element
        ]
        for input_, error in failing_inputs:
            with self.assertRaises(error):
                SumMetric(input_)

    def test_sum_metric_additions(self):

        input_pairs_and_outputs = [
            (1, 2, 3),
            (3, -5.0, -2.0),
            (torch.Tensor([[[4.2]]]), 3, 7.2),
            (torch.DoubleTensor([1]), torch.LongTensor([[-1]]), 0),
        ]
        for input1, input2, output in input_pairs_and_outputs:
            actual_output = (SumMetric(input1) + SumMetric(input2)).value()
            self.assertAlmostEqual(actual_output, output, places=6)

    def test_average_metric_inputs(self):

        passing_inputs_and_outputs = [
            ((2, 4), 0.5),
            ((17.0, 10.0), 1.7),
            ((torch.Tensor([2.3]), torch.LongTensor([2])), 1.15),
            ((torch.Tensor([2.3]), torch.Tensor([2.0])), 1.15),
        ]
        for input_, output in passing_inputs_and_outputs:
            actual_output = AverageMetric(input_[0], input_[1]).value()
            self.assertAlmostEqual(actual_output, output, places=6)
            self.assertIsInstance(actual_output, float)

        failing_inputs = [
            ((2, '4'), AssertionError),
            ((torch.Tensor([1, 1]), torch.Tensor([2])), ValueError),
        ]
        for input_, error in failing_inputs:
            with self.assertRaises(error):
                AverageMetric(input_[0], input_[1])

    def test_average_metric_additions(self):

        input_pairs_and_outputs = [
            ((2, 4), (1.5, 1), 0.7),
            (
                (torch.LongTensor([[[2]]]), torch.Tensor([4])),
                (torch.FloatTensor([1.5]), 1),
                0.7,
            ),
        ]
        for input1, input2, output in input_pairs_and_outputs:
            actual_output = (
                AverageMetric(input1[0], input1[1])
                + AverageMetric(input2[0], input2[1])
            ).value()
            self.assertAlmostEqual(actual_output, output, places=6)
            self.assertIsInstance(actual_output, float)

    def test_fixedmetric(self):
        assert (FixedMetric(3) + FixedMetric(3)).value() == 3
        with self.assertRaises(ValueError):
            _ = FixedMetric(3) + FixedMetric(4)

class TestMetrics(unittest.TestCase):
    """
    Test the Metrics aggregator.
    """

    def test_simpleadd(self):
        m = Metrics(threadsafe=False)
        m.add('key', SumMetric(1))
        m.add('key', SumMetric(2))
        assert m.report()['key'] == 3

        m.clear()
        assert 'key' not in m.report()

        m.add('key', SumMetric(1.5))
        m.add('key', SumMetric(2.5))
        assert m.report()['key'] == 4.0

        # shouldn't throw exception
        m.flush()

    def test_shared(self):
        m = Metrics(threadsafe=False)
        m2 = Metrics(threadsafe=False, shared=m.share())
        m3 = Metrics(threadsafe=False, shared=m.share())

        m2.add('key', SumMetric(1))
        m3.add('key', SumMetric(2))
        m2.flush()  # just make sure this doesn't throw exception, it's a no-op
        m.add('key', SumMetric(3))

        assert m.report()['key'] == 6

        # shouldn't throw exception
        m.flush()
        m2.flush()
        m3.flush()

    def test_multithreaded(self):
        m = Metrics(threadsafe=True)
        m2 = Metrics(threadsafe=True, shared=m.share())
        m3 = Metrics(threadsafe=True, shared=m.share())

        m2.add('key', SumMetric(1))
        m2.flush()
        m3.add('key', SumMetric(2))
        m3.flush()
        m.add('key', SumMetric(3))
        m.flush()
        m.report()['key'] == 6

    def test_verymultithreaded(self):
        m = Metrics(threadsafe=True)
        nt = 128
        ms = [Metrics(threadsafe=True, shared=m.share()) for _ in range(nt)]

        # intentionally just over the int overflow
        for _ in range(32768 + 1):
            ms[random.randint(0, nt - 1)].add('key', SumMetric(1))
        thread_ids = list(range(nt))
        random.shuffle(thread_ids)
        for tid in thread_ids:
            ms[tid].flush()

        assert m.report()['key'] == 32768 + 1

    def test_largebuffer(self):
        m = Metrics(threadsafe=True)
        m2 = Metrics(threadsafe=True, shared=m.share())

        # intentionally just over the int overflow
        for _ in range(32768 + 1):
            m2.add('key', SumMetric(1))
        m2.flush()

        assert m.report()['key'] == 32768 + 1

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


import cv2
import numpy as np
img = cv2.imread(r'images\messi5.jpg')
grey_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.imread(r'messi_face/.jpg', 0)

res = cv2.matchTemplate(grey_img, template, cv2.TM_CCOEFF_NORMED)
print(res)
threshold = 0.8;
loc = np.where(res >= threshold)
print(loc)
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()


"""
Original code and data by Quint
"""
import datetime
from typing import List, Tuple, Generator

from util import *

class Wiesbaden(ScraperBase):

    POOL = PoolInfo(
        id="wiesbaden",
        name="Wiesbaden",
        public_url="https://www.wiesbaden.de/leben-in-wiesbaden/verkehr/auto/parken/parkhaeuser.php",
        source_url="https://geoportal.wiesbaden.de/parkleitsystem/parkhaeuser.php",
        timezone="Europe/Berlin",
        attribution_contributor="Stadt Wiesbaden",
        attribution_license=None,
        attribution_url=None,
    )

    STATUS_MAPPING = {
        "OK": LotData.Status.open,
        # TODO: After opening times lots show all numbers but this status
        #   so i guess it means "closed"
        "Nicht OK": LotData.Status.closed,
        "Übertragungsstörung": LotData.Status.error,
    }

    def get_lot_data(self) -> List[LotData]:
        timestamp = self.now()

        lots = []
        for source_url, attributes in self.iter_lot_attributes():
            if not "name" in attributes:
                log("Error: incomplete attributes for ", source_url)
                continue

            lots.append(
                LotData(
                    timestamp=timestamp,
                    id=name_to_legacy_id("wiesbaden", attributes["name"]),
                    status=self.STATUS_MAPPING.get(attributes["status"], LotData.Status.unknown),
                    num_free=int_or_none(attributes["num_free"]),
                    capacity=int_or_none(attributes["capacity"]),
                )
            )

        return lots

    def iter_lot_attributes(self) -> Generator[Tuple[datetime.datetime, str, dict], None, None]:
        soup = self.request_soup(self.POOL.source_url)
        for row in soup.find_all("tr"):
            tds = row.find_all("td")

            if tds[0].find("h4"):
                # skip heading
                continue

            name = tds[0].text.strip()
            num_free = tds[1].text.split('/')[0].strip()
            capacity = tds[1].text.split('/')[1].strip()
            status = tds[3].text.strip()
            attributes = {
                "name": name,
                "num_free": num_free,
                "capacity": capacity,
                "status": status
            }

            yield self.POOL.source_url, attributes

    def get_lot_infos(self) -> List[LotInfo]:

        lot_map = {
            lot.id: lot
            for lot in self.get_v1_lot_infos_from_geojson("Wiesbaden")
        }

        lots = []
        for source_url, attributes in self.iter_lot_attributes():
            name = attributes["name"]
            legacy_id = self.name_to_legacy_id(name)

            kwargs = vars(lot_map[legacy_id]) if legacy_id in lot_map else {}
            kwargs.update(dict(
                name=name,
                id=legacy_id,
                has_live_capacity=True,
                source_url=source_url,
            ))

            lots.append(LotInfo(**kwargs))

        return lots

    def name_to_legacy_id(self, name):
        NEW_TO_LEGACY = {
            "Mauritius Galerie": "Mauritius-Parkhaus",
            "City 1": "City I",
            "City 2": "City II",
        }
        legacy_name = NEW_TO_LEGACY.get(name, name)
        return name_to_legacy_id(self.POOL.id, name)


import cv2

from utils.consts import *
from recognizable_object import RecognizableObject
from drone import Drone
from utils.config_utils import load_colors, save_colors
from borders import Borders
import faulthandler
from gui import Gui

def interactive_loop(borders, gui, left_cam, right_cam, cam_distance, balloon, drone_1, drone_2):
    """
    The interactive loop for receiving commands from the user.
    :param gui: the GUI.
    :param borders: the Borders.
    :param left_cam: the left Camera.
    :param right_cam: the right Camera.
    :param cam_distance: the distance between the cameras.
    :param balloon: the balloon's RecognizableObject.
    :param drone_1: the first Drone.
    :param drone_2: the second Drone.
    :return: whether to continue or not, and the distance between the cameras.
    """
    event, values = gui.window.read(timeout=1)
    str_colors_changed = "Color bounds changed"
    distance = cam_distance

    # the 'v' button is set as the detect color of recognizable_object in the left_cam cam
    if event == 'v' or event == 'Balloon color (L)':
        balloon.detect_color(True)
        print(str_colors_changed)

    # the 'n' button is set as the detect color of recognizable_object in the right_cam cam
    elif event == 'n' or event == 'Balloon color (R)':
        balloon.detect_color(False)
        print(str_colors_changed)

    # the 's' button is set as the detect color of drone_1 in the left_cam cam
    elif event == 's' or event == 'Drone 1 color (L)':
        drone_1.detect_color(True)
        print(str_colors_changed)

    # the 'f' button is set as the detect color of drone_1 in the right_cam cam
    elif event == 'f' or event == 'Drone 1 color (R)':
        drone_1.detect_color(False)
        print(str_colors_changed)

    # the 'w' button is set as the detect color of drone_2 in the left_cam cam
    elif event == 'w' or event == 'Drone 2 color (L)':
        drone_2.detect_color(True)
        print(str_colors_changed)

    # the 'e' button is set as the detect color of drone_2 in the right_cam cam
    elif event == 'e' or event == 'Drone 2 color (R)':
        drone_2.detect_color(False)
        print(str_colors_changed)

    elif event == 't' or event == 'Take Off':
        drone_1.tookoff = True
        drone_2.tookoff = True

    elif event == 'y' or event == 'Go Home':
        drone_1.start_track()
        drone_2.start_track()

    # the 'q' button is set as the quitting button
    elif event == 'q' or event == 'Quit' or event == Gui.WINDOW_CLOSED:
        return False, distance

    # the 'p' button is set as the save text_colors to file
    elif event == 'p' or event == 'Save Colors':
        save_colors(COLORS_FILENAME, [balloon, drone_1.recognizable_object, drone_2.recognizable_object])

    # the 'k' button is set as the read text_colors from file
    elif event == 'k' or event == 'Load Colors':
        load_colors(COLORS_FILENAME, [balloon, drone_1.recognizable_object, drone_2.recognizable_object])

    # the 'j' button is set as the saving the borders. can save 4 coordinates
    elif event == 'j' or event == 'Set Borders':
        borders.set_corner(balloon, left_cam)
        print("Saved the {:.0f} coordinate: ({:.0f},{:.0f})".format(borders.index, balloon.x, balloon.y))
        gui.update_borders_button(borders.index)
        if borders.index == 4:
            borders.save_borders(BORDERS_FILENAME)
            drone_1.set_home((borders.x_middle_1, borders.y_middle))
            drone_2.set_home((borders.x_middle_2, borders.y_middle))
            gui.show_homes_gui(drone_1.home, drone_2.home)
            # drone_2.default_height = drone_q.default_height + 30 # for safety we can delete this when seek middle works

    # the 'r' button is set as the read text_colors from file
    elif event == 'r' or event == 'Load Borders':
        borders.load_borders(BORDERS_FILENAME, left_cam)
        drone_1.set_home((borders.x_middle_1, borders.y_middle))
        drone_2.set_home((borders.x_middle_2, borders.y_middle))
        gui.show_homes_gui(drone_1.home, drone_2.home)

    elif event == 'z' or event == 'Start Play':
        drone_1.game_start = 1
        drone_2.game_start = 1

    elif event == 'flip_left':
        left_cam.flip = -1 if values['flip_left'] else 1
        left_cam.is_flipped = values['flip_left']

    elif event == 'flip_right':
        right_cam.flip = -1 if values['flip_right'] else 1
        right_cam.is_flipped = values['flip_right']

    elif event == 'received_input':
        distance = gui.update_val(left_cam, right_cam, drone_1, drone_2, distance, values)

    elif event == 'SLIDER_H' or event == 'SLIDER_S' or event == 'SLIDER_V' or event == 'SLIDER_T':
        recognizable_objects = [balloon] + [drone_1.recognizable_object, drone_2.recognizable_object]
        gui.update_hsv(recognizable_objects, event, values)

    return True, distance

def game_loop(drone_1, drone_2, balloon, cameras_distance, left, right):
    """
    Runs the loop of the game - capturing frames from the video cameras and controlling the drone accordingly.
    :param drone_1: the first Drone.
    :param drone_2: the second Drone.
    :param balloon: the RecognizableObject of the balloon.
    :param cameras_distance: the distance between the cameras.
    :param left: the Camera of the left camera.
    :param right: the Camera of the right camera.
    """
    continue_loop = True

    borders = Borders()
    gui = Gui()
    gui.show_gui()

    drones = [drone_1, drone_2]
    recognizable_objects = [balloon] + [drone.recognizable_object for drone in drones]
    load_colors(COLORS_FILENAME, recognizable_objects)
    borders.load_borders(BORDERS_FILENAME, left)

    drone_1.active = True
    drone_1.set_home((90, 350))
    drone_2.set_home((7, 365))
    gui.show_homes_gui(drone_1.home, drone_2.home)

    while continue_loop:
        # Capture the video frame by frame
        if not left.capture():
            continue
        if not right.capture():
            continue

        for recognizable_object in recognizable_objects:
            # Process frames
            recognizable_object.detect_and_set_coordinates(left, right, cameras_distance)

        gui.display_frames_gui(balloon, drones, left, right, borders)

        # Set Obstacle
        for drone in drones:
            if drone.start:
                drone.set_obstacle(left)

        # State Machine
        for i, drone in enumerate(drones):
            drone.state.run(drone, drones[1-i], balloon, borders)
            transition = drone.state.to_transition(drone, drones[1-i], balloon, borders)
            if transition:
                drone.state.cleanup(transition, drone, drones[1-i], balloon, borders)
                drone.state = drone.state.next(transition)
                print("drone", drone.ident, " state:", drone.state)
                drone.state.setup(drone, drones[1-i], balloon, borders)
        gui.update_states(str(drone_1.state), str(drone_2.state))

        continue_loop, distance = interactive_loop(borders, gui, left, right, cameras_distance, balloon, drone_1, drone_2)

    for i in range(3):
        for drone in drones:
            if drone.tookoff:
                drone.stop()

    for drone in drones:
        if drone.tookoff:
            try:
                drone.land()
            except:
                pass

    # After the loop release the cap object
    left.release()
    right.release()
    # Destroy all the windows
    cv2.destroyAllWindows()

def main():
    """
    A game of 2 drones playing volleyball with the balloon.
    """
    right_cam = C920_NIR_1
    left_cam = C920_NIR_2

    drone_1 = Drone(1, (0, 191, 255), iface_ip="192.168.10.10")
    drone_2 = Drone(2, (38, 38, 200), iface_ip="192.168.10.2")
    balloon = RecognizableObject((255, 54, 89), "balloon")

    distance = 111.9
    game_loop(drone_1, drone_2, balloon, distance, left_cam, right_cam)

if __name__ == "__main__":
    faulthandler.enable()
    main()


# compare healthy between two schools by drink milk or don't drink milk

# -------------------------------------- developer : abed shabahang
from statistics import mean

number_of_schools = 2
students_A = 0
students_B = 0
milk_in_class_A = None
milk_in_class_B = None
print("\n" + " This is a program that can examine two schools in terms of the impact of milk consumption on the physical health of students \t".strip() + "programmer : Abed Shabahang" .strip() + "\n")
for i in range(0, number_of_schools):
    name_of_class = "A" if i == 0 else "B"

    number_of_student = int(input("plz enter number of students in school " + str(name_of_class) + ":" + "\n "))
    milk_in_class = int(input("if use milk in school " + str(name_of_class) + " enter 1 else enter 0 :" + "\n "))
    list_age = list()
    list_height = list()
    list_weight = list()
    k = i
    if k == 0:
        students_A = number_of_student
        milk_in_class_A = milk_in_class

    else:
        students_B = number_of_student
        milk_in_class_B = milk_in_class

    print("now in school :", name_of_class, " ", "(number_of_students_A:", students_A, "", "milk_A:", milk_in_class_A, ") ",
          "(number_of_students_B:", students_B, "", "milk_B:", milk_in_class_B, ")")
    for j in range(0, 3):
        # --------------------------------------- list_A (age , height, weight)
        if k == 0 and j == 0:
            list_age_A = input(
                "plz enter ages of students in school " + str(name_of_class) + "\n" + "for example : 16 18 17" + "\n").split(" ")
            list_age_A = list(map(lambda x: int(x), list_age_A))
            mean_age_A = float(mean(list_age_A))
            # print("list_age_A:", list_age_A)

        elif k == 0 and j == 1:
            list_height_A = input("plz enter height of students in school " + str(name_of_class) + "\n" + "for example : 169 185 174" + "\n").split(" ")
            list_height_A = list(map(lambda x: int(x), list_height_A))
            mean_height_A = float(mean(list_height_A))
            # print("list_height_A:", list_height_A)

        elif k == 0 and j == 2:
            list_weight_A = input("plz enter weight of students in school " + str(name_of_class) + "\n" + "for example : 56 47 75" + "\n").split(" ")
            list_weight_A = list(map(lambda x: int(x), list_weight_A))
            mean_weight_A = float(mean(list_weight_A))
            # print("list_weight_A:", list_weight_A)
        # --------------------------------------- list_B (age , height, weight)
        if k == 1 and j == 0:
            list_age_B = input("plz enter ages of students in school " + str(name_of_class) + "\n" + "for example : 16 18 17" + "\n").split(" ")
            list_age_B = list(map(lambda x: int(x), list_age_B))
            mean_age_B = float(mean(list_age_B))
            # print("list_age_B:", "mean_age_B:", mean_age_B)

        elif k == 1 and j == 1:
            list_height_B = input("plz enter height of students in school " + str(name_of_class) + "\n" + "(for example : 165 182 173)" + "\n").split(" ")
            list_height_B = list(map(lambda x: int(x), list_height_B))
            mean_height_B = float(mean(list_height_B))
            # print("list_height_B :", list_height_B)

        elif k == 1 and j == 2:
            list_weight_B = input("plz enter weight of students in school " + str(name_of_class) + "\n" + "for example : 46 78 84" + "\n").split(" ")
            list_weight_B = list(map(lambda x: int(x), list_weight_B))
            mean_weight_B = float(mean(list_weight_B))
            # print("list_weight_B:", list_weight_B)

class Schools:
    count = 0

    def __init__(self, mean_age, mean_height, mean_weight, milk):
        self.mean_age = mean_age
        self.mean_height = mean_height
        self.mean_weight = mean_weight
        self.milk = milk

class School_A(Schools):

    def use_milk(self):
        if self.milk == 0:
            print("School A dont used milk for students")
            print("mean_age: %.1f" % self.mean_age)
            print("mean_height: %.1f" % self.mean_height)
            print("mean_weight: %.1f \n" % self.mean_weight)
        else:
            print("School A used milk for students")
            print("mean_age : %.1f" % self.mean_age)
            print("mean_height: %.1f" % self.mean_height)
            print("mean_weight: %.1f \n" % self.mean_weight)

class School_B(Schools):

    def use_milk(self):
        if self.milk == 0:
            print("School B dont used milk for students")
            print("mean_age: %.1f" % self.mean_age)
            print("mean_height: %.1f" % self.mean_height)
            print("mean_weight: %.1f" % self.mean_weight)
        else:
            print("School B used milk for students")
            print("mean_age : %.1f" % self.mean_age)
            print("mean_height: %.1f" % self.mean_height)
            print("mean_weight: %.1f" % self.mean_weight)

school_1 = School_A(mean_age_A, mean_height_A, mean_weight_A, milk_in_class_A)

school_2 = School_B(mean_age_B, mean_height_B, mean_weight_B, milk_in_class_B)
if mean_age_A == mean_age_B and mean_weight_A == mean_weight_B:
    print("Same")
elif mean_age_A == mean_age_B:
    if mean_weight_A > mean_weight_B:
        school_1.use_milk()
    else:
        school_1.use_milk()
else:
    school_1.use_milk()
    school_2.use_milk()


import copy
import glob
import re

import matplotlib
import numpy as np

import aimsprop as ai

matplotlib.use("Agg")
import matplotlib.pyplot as plt

def build_traj(
    ICs,
):

    # => Parse/Align/Weight/Clean <= #

    # Parse a series of FMS90 trajectories
    main_dir = "/home/monikaw/chem/stilbene/4-aims"

    broken_frame = {}
    trajs = []
    labels = []
    for IC in ICs:
        input_dirs = [name for name in glob.glob("%s/%04d/*-run" % (main_dir, IC))]
        trajs_IC = []
        for run in input_dirs:
            mobj = re.match("\S+(\d+)-run", run)

        restart_index = np.array(
            [int(re.match("\S+(\d+)-run", run).group(1)) for run in input_dirs]
        )
        restart_inds = np.argsort(
            np.array(
                [int(re.match("\S+(\d+)-run", run).group(1)) for run in input_dirs]
            )
        )
        for ind in restart_inds:
            run = input_dirs[ind]
            ind1 = restart_index[ind]
            print(("Reading:", run))
            if (IC, ind1) in list(broken_frame.keys()):
                traj = ai.parse_fms90_dumpfile(
                    "%s" % run, scheme="mulliken", cutoff_time=broken_frame[(IC, ind1)]
                )
            else:
                traj = ai.parse_fms90_dumpfile("%s" % run, scheme="mulliken")
            trajs_IC.append(copy.copy(traj))
        print("merging restarts")
        traj_IC = ai.Bundle.merge(trajs_IC, [1.0] * len(trajs_IC), [IC] * len(trajs_IC))

        print("removing duplicate frames")
        traj_IC = traj_IC.remove_duplicates()

        print("interpolating across IC")
        ts = np.arange(0.0, max(traj_IC.ts), 400.0)
        traj_IC = traj_IC.interpolate_linear(ts)

        # Each dat contains np.array([[dE (eV), Osc, Tx, Ty, Tz]])
        dat = np.load("/home/monikaw/chem/stilbene/4-spectra/%04d/align.npz" % IC)[
            "dat"
        ]
        # Extract the transition dipole moments for alignment purposes
        tdm = dat[0, 2:]
        # Rotate each AIMS trajectory so the transition dipole moment vector is in aligned in z at t=0
        traj_IC = ai.rotate_frames_to_z(traj_IC, tdm)

        labels += [IC] * len(traj_IC.frames)
        trajs.append(copy.copy(traj_IC))

    # Parse the oscillator strength weights and transition dipole alignments
    # from the 4-spectra dir (computed by the align.py script)
    # Each dat contains np.array([[dE (eV), Osc, Tx, Ty, Tz]])
    dats = [
        np.load("/home/monikaw/chem/stilbene/4-spectra/%04d/align.npz" % x)["dat"]
        for x in ICs
    ]
    # Compute the normalized oscillator strength weights
    ws = np.array([dat[0, 1] for dat in dats])
    ws /= np.sum(ws)
    # Merge the trajectories into one super-big Bundle with uniform weights
    print("merging ICs")
    traj = ai.Bundle.merge(trajs, ws)
    print(("nframes", len(traj.frames)))

    return traj, trajs

if __name__ == "__main__":

    time_scale = 1.0 / 41.3413745758  # au to fs

    ICs = np.arange(100, 132, 1)
    traj, trajs = build_traj(ICs)
    ts = traj.ts

    # => UED Signal <= #

    print("calculating raw UED signal")
    R = np.linspace(0.0, 6.0, 200)
    traj = ai.compute_ued_simple(traj, "UED", R=R, alpha=8.0)

    # => Bootstrap Results <= #

    print("resampling trajectories")
    resampled_trajs = ai.bootstrap(traj, 1000, ICs)

    # => Plotting Population with Standard Deviation Error Bars <= #

    # Getting population statistics
    I1 = []
    I2 = []
    for ind, retraj in enumerate(resampled_trajs):
        pop1 = ai.pop.compute_population(retraj)
        I1.append(pop1[1])
        I2.append(pop1[2])
    std1 = np.std(I1, axis=0)
    std2 = np.std(I2, axis=0)
    avg_pop1 = np.average(I1, axis=0)
    avg_pop2 = np.average(I2, axis=0)

    # Plotting population with error bars
    plt.clf()
    plt.errorbar(ts * time_scale, avg_pop1, yerr=std1, fmt="none", ecolor="r")
    plt.errorbar(ts * time_scale, avg_pop2, yerr=std2, fmt="none", ecolor="b")
    plt.plot(ts * time_scale, avg_pop1, "r", label="$S_{0}$")
    plt.plot(ts * time_scale, avg_pop2, "b", label="$S_{1}$")

    plt.xlabel("t [fs]")
    plt.ylabel("Population")
    plt.axis([time_scale * min(ts), max(ts) * time_scale, -0.1, 1.1])
    plt.legend()
    plt.tight_layout()
    plt.savefig("Population.pdf")

    # => Plotting UED stats Heatmap <= #

    print("extracting UED statistics")
    avg, std = ai.extract_stats(resampled_trajs, "UED", diff=True)

    nlevel = 65

    plt.clf()
    vmax = np.max(np.abs(std))
    levels = np.linspace(0.0, vmax, nlevel)
    cticks = [0, +int(vmax)]
    plt.contourf(ts * time_scale, R, std.T, levels=levels)
    plt.colorbar(ticks=cticks)
    plt.xlabel("t [fs]")
    plt.ylabel("R[$\AA$]")
    plt.tight_layout()
    plt.savefig("ued_std.pdf")

    plt.clf()
    vmax = np.max(np.abs(avg))
    levels = np.linspace(-vmax, +vmax, nlevel)
    cticks = [-int(vmax), 0, +int(vmax)]
    plt.contourf(ts * time_scale, R, avg.T, cmap=plt.cm.bwr, levels=levels)
    plt.colorbar(ticks=cticks)
    plt.xlabel("t [fs]")
    plt.ylabel("R[$\AA$]")
    plt.tight_layout()
    plt.savefig("ued_avg.pdf")


import requests
from Utils import url_manager

user_agent = """Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"""
headers = {
    "User-Agent": user_agent
}
cookies = {
    "Hm_lvt_1893a75fb13d3c54441162f35c31e6c2": "1684219483,1684296936",
    "Hm_lpvt_1893a75fb13d3c54441162f35c31e6c2": "1684296936"
}
root_url = "http://www.cosplay8.com/pic/Lolita/"
urls = url_manager.UrlManager()
urls.add_new_url(root_url)

while urls.has_new_url():
    curr_url = urls.get_url()
    response = requests.get(curr_url, headers=headers, cookies=cookies, timeout=3)
    if response.status_code != 200:
        print("unsuccessful" + f":{response.status_code}")
        continue
    with open("cosplay.html", "wb") as f:
        f.write(response.content)


""" Xiaomi.eu command handler """
from telethon import events

from uranus_bot.telegram_bot import DATABASE
from uranus_bot.telegram_bot.messages.error import error_message
from uranus_bot.telegram_bot.messages.xiaomi_eu import eu_message
from uranus_bot.telegram_bot.tg_bot import BOT, PROVIDER

@BOT.on(events.NewMessage(pattern=r'/eu(?: )?(\w+)?'))
async def xiaomi_eu(event):
    """Send a message when the command /eu is sent."""
    try:
        device = event.pattern_match.group(1).lower()
    except (IndexError, AttributeError):
        if event.message.message.endswith('/eu'):
            device = DATABASE.get_codename(event.chat_id)
        else:
            return
    if not device:
        return
    locale = DATABASE.get_locale(event.chat_id)
    if device not in list(PROVIDER.eu_codenames.keys()):
        await event.reply(await error_message(device, locale))
        return
    try:
        message, buttons = await eu_message(device, PROVIDER.eu_data, PROVIDER.eu_codenames, locale)
        await event.reply(message, buttons=buttons, link_preview=False)
    except TypeError:
        pass
    raise events.StopPropagation


import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import csv

lines = np.loadtxt('combine.csv',dtype=np.str,delimiter=',')
df = lines[0:,0:].astype('float')
X = PCA(n_components=128).fit_transform(df)

y = []
with open('tagsAfterCombine.csv') as dfile:
    f_csv = csv.reader(dfile)
    for line in f_csv:
        if len(line[0]) == 0:
            tags.append(" ")
        y.append(int(line[0]))

X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.4,random_state=42)

classify=LogisticRegression()

classify.fit(X_train, y_train)

accuracy=classify.score(X_test,y_test)


import time

from lib import script
from lib import states

"""
Reboots all nodes that are considered 'inactive', which means no instance
assigned to them, running
"""

class RebootUnprovisioned(script.TeethScript):
    use_ironic = True

    def __init__(self):
        super(RebootUnprovisioned, self).__init__(
            'Utility for rebooting inactive nodes.')
        self.add_argument('--sleep',
                          type=int,
                          default=10,
                          required=False,
                          help='Amount of time in seconds to sleep between '
                               'reboots. Defaults to 10.')

    def _is_inactive(self, node):
        return (
            node['instance_uuid'] is None and
            node['maintenance'] is False and
            node['provision_state'] in (states.AVAILABLE,
                                        states.MANAGEABLE)
        )

    def run(self):
        for node in self.ironic_client.list_nodes():
            if self._is_inactive(node):
                try:
                    self.ironic_client.set_target_power_state(
                        node, states.REBOOT)
                    print('Rebooted {uuid}'.format(**node))
                except Exception:
                    print('Failed to reboot {uuid}'.format(**node))
                # Artificially slow this down to avoid overloading conductors
                # or dropping capacity too fast
                time.sleep(self.get_argument('sleep'))

if __name__ == "__main__":
    RebootUnprovisioned().run()


__all__ = [
    'nothing',
    'deny',
    'drop_field',
    'item_to_list',
    'extract_from_list',
    'remove_cls_key',
    'to_manual_ref',
    'to_dbref',
    'to_dynamic_ref',
    'to_string',
    'to_int',
    'to_long',
    'to_double',
    'to_decimal',
    'to_date',
    'to_bool',
    'to_binary',
    'to_object',
    'to_object_id',
    'to_uuid_str',
    'to_uuid_bin',
    'to_url_string',
    'to_email_string',
    'to_complex_datetime',
]

import re
import uuid

import bson
from dateutil.parser import parse as dateutil_parse

from mongoengine_migrate.exceptions import MigrationError, InconsistencyError
from mongoengine_migrate.mongo import (
    check_empty_result
)
from mongoengine_migrate.updater import ByPathContext, ByDocContext, DocumentUpdater

def nothing(*args, **kwargs):
    """Converter which does nothing"""
    pass

def deny(updater: DocumentUpdater):
    """Convertion is denied"""
    raise MigrationError(f"Such type_key convertion for field "
                         f"{updater.document_type}.{updater.field_name} is forbidden")

def drop_field(updater: DocumentUpdater):
    """Drop field"""
    def by_path(ctx: ByPathContext):
        ctx.collection.update_many(
            {ctx.filter_dotpath: {'$exists': True}, **ctx.extra_filter},
            {'$unset': {ctx.update_dotpath: ''}},
            array_filters=ctx.build_array_filters()
        )

    updater.update_by_path(by_path)

def item_to_list(updater: DocumentUpdater, remove_cls_key=False):
    """Make a list with single element from every non-array value"""
    def by_doc(ctx: ByDocContext):
        if updater.field_name in ctx.document:
            f = ctx.document[updater.field_name]
            if f is not None:
                if remove_cls_key and isinstance(f, dict) and '_cls' in f:
                    del f['_cls']
                if not isinstance(f, (list, tuple)):
                    ctx.document[updater.field_name] = [f]
            else:
                ctx.document[updater.field_name] = []  # null -> []

    updater.update_by_document(by_doc)

def extract_from_list(updater: DocumentUpdater, item_type, remove_cls_key=False):
    """
    Replace every list which was met with its first element with
    checking item type. If type is other than `item_type` then
    the error will be raised
    :param updater:
    :param item_type: python type(s) to check the element
    :param remove_cls_key: if True then '_cls' keys will be removed
     from dict items if any
    :return:
    """
    def by_doc(ctx: ByDocContext):
        doc = ctx.document
        if updater.field_name not in doc or doc[updater.field_name] is None:
            return

        f = doc[updater.field_name]
        if isinstance(f, (list, tuple)):
            if f:
                f = f[0]
                if remove_cls_key and isinstance(f, dict) and '_cls' in f:
                    del f['_cls']
                if not isinstance(f, item_type) and updater.migration_policy.name == 'strict':
                    raise InconsistencyError(f"Field {updater.field_name} has wrong value {f!r} "
                                             f"(should be {item_type}) in record {doc}")
            else:
                f = None
            doc[updater.field_name] = f
        elif f is not None and updater.migration_policy.name == 'strict':
            raise MigrationError(f'Could not extract item from non-list value '
                                 f'{updater.field_name}: {doc[updater.field_name]}')

    updater.update_by_document(by_doc)

def remove_cls_key(updater: DocumentUpdater):
    """Unset '_cls' key in documents if any"""
    def by_path(ctx: ByPathContext):
        ctx.collection.update_many(
            {ctx.filter_dotpath + '._cls': {'$exists': True}, **ctx.extra_filter},
            {'$unset': {ctx.update_dotpath + '._cls': ''}},
            array_filters=ctx.build_array_filters()
        )

    updater.update_by_path(by_path)

def to_object_id(updater: DocumentUpdater):
    def by_doc(ctx: ByDocContext):
        doc = ctx.document
        if updater.field_name not in doc or doc[updater.field_name] is None:
            return

        f = doc[updater.field_name]
        is_dict = isinstance(f, dict)
        if isinstance(f, str):  # ObjectId as string
            try:
                f = bson.ObjectId(f)
            except bson.errors.BSONError:
                pass

        if isinstance(f, bson.ObjectId):
            return
        elif is_dict and isinstance(f.get('_ref'), bson.DBRef):  # Already dynamic ref
            doc[updater.field_name] = f['_ref'].id
        elif isinstance(f, bson.DBRef):
            doc[updater.field_name] = f.id
        elif is_dict and isinstance(f.get('_id'), bson.ObjectId):  # manual ref
            doc[updater.field_name] = f['_id']

        elif updater.migration_policy.name == 'strict':  # Other data type
            raise InconsistencyError(f"Field {updater.field_name} has wrong value {f!r} "
                                     f"(should be DBRef, ObjectId, manual ref, dynamic ref, "
                                     f"ObjectId string) in record {doc}")

    # TODO: precheck if field actually contains value other than ObjectId
    updater.update_by_document(by_doc)

def to_manual_ref(updater: DocumentUpdater):
    """Convert references (ObjectId, DBRef, dynamic ref) to manual ref
    """
    def by_doc(ctx: ByDocContext):
        doc = ctx.document
        if updater.field_name not in doc or doc[updater.field_name] is None:
            return

        f = doc[updater.field_name]
        if isinstance(f, str):  # ObjectId as string
            try:
                f = bson.ObjectId(f)
            except bson.errors.BSONError:
                pass

        is_dict = isinstance(f, dict)
        if is_dict and isinstance(f.get('_id'), bson.ObjectId):  # Already manual ref
            return
        elif is_dict and isinstance(f.get('_ref'), bson.DBRef):  # dynamic ref
            doc[updater.field_name] = {'_id': f['_ref'].id}
        elif isinstance(f, bson.DBRef):
            doc[updater.field_name] = {'_id': f.id}
        elif isinstance(f, bson.ObjectId):
            doc[updater.field_name] = {'_id': f}
        elif updater.migration_policy.name == 'strict':  # Other data type
            raise InconsistencyError(f"Field {updater.field_name} has wrong value {f!r} "
                                     f"(should be DBRef, ObjectId, manual ref, dynamic ref, "
                                     f"ObjectId string) in record {doc}")

    # TODO: precheck if field actually contains value other than manual ref
    updater.update_by_document(by_doc)

def to_dbref(updater: DocumentUpdater):
    """Convert references (ObjectId, manual ref, dynamic ref) to dbref
    """
    def by_doc(ctx: ByDocContext):
        doc = ctx.document
        if updater.field_name not in doc or doc[updater.field_name] is None:
            return

        f = doc[updater.field_name]
        if isinstance(f, bson.DBRef):  # Already DBRef
            return
        elif isinstance(f, str):  # ObjectId as string
            try:
                f = bson.ObjectId(f)
            except bson.errors.BSONError:
                pass

        collection_name = ctx.collection.name if ctx.collection is not None else None
        is_dict = isinstance(f, dict)
        if is_dict and isinstance(f.get('_id'), bson.ObjectId):  # manual ref
            doc[updater.field_name] = bson.DBRef(collection_name, f['_id'])
        elif is_dict and isinstance(f.get('_ref'), bson.DBRef):  # dynamic ref
            doc[updater.field_name] = f['_ref']
        elif isinstance(f, bson.ObjectId):
            doc[updater.field_name] = bson.DBRef(collection_name, f)
        elif updater.migration_policy.name == 'strict':  # Other data type
            raise InconsistencyError(f"Field {updater.field_name} has wrong value {f!r} "
                                     f"(should be DBRef, ObjectId, manual ref, dynamic ref, "
                                     f"ObjectId string) in record {doc}")

    # TODO: precheck if field actually contains value other than DBRef
    updater.update_by_document(by_doc)

def to_dynamic_ref(updater: DocumentUpdater):
    """Convert references (ObjectId, DBRef, manual ref) to dynamic ref
    """
    def by_doc(ctx: ByDocContext):
        doc = ctx.document
        if updater.field_name not in doc or doc[updater.field_name] is None:
            return

        f = doc[updater.field_name]
        is_dict = isinstance(f, dict)
        collection_name = ctx.collection.name if ctx.collection is not None else None

        if isinstance(f, str):  # ObjectId as string
            try:
                f = bson.ObjectId(f)
            except bson.errors.BSONError:
                pass

        # We cannot get dynamic ref from other types of refs because
        # of lack of '_cls' value. Mongoengine fields which use this
        # converter can keep DBRef. So return DBRef instead
        if is_dict and isinstance(f.get('_ref'), bson.DBRef):  # Already dynamic ref
            return
        elif isinstance(f, bson.DBRef):
            return
        elif is_dict and isinstance(f.get('_id'), bson.ObjectId):  # manual ref
            doc[updater.field_name] = bson.DBRef(collection_name, f['_id'])
        elif isinstance(f, bson.ObjectId):
            doc[updater.field_name] = bson.DBRef(collection_name, f)
        elif updater.migration_policy.name == 'strict':  # Other data type
            raise InconsistencyError(f"Field {updater.field_name} has wrong value {f!r} "
                                     f"(should be DBRef, ObjectId, manual ref, dynamic ref) "
                                     f"in record {doc}")

    # TODO: precheck if field actually contains value other than dynamic ref or DBRef
    updater.update_by_document(by_doc)

def to_string(updater: DocumentUpdater):
    def by_doc(ctx: ByDocContext):
        doc = ctx.document
        if updater.field_name not in doc or doc[updater.field_name] is None:
            return

        f = doc[updater.field_name]
        is_dict = isinstance(f, dict)
        if is_dict and isinstance(f.get('_ref'), bson.DBRef):  # dynamic ref
            doc[updater.field_name] = str(f['_ref'].id)
        elif is_dict and isinstance(f.get('_id'), bson.ObjectId):  # manual ref
            doc[updater.field_name] = str(f['_id'])
        elif isinstance(f, bson.DBRef):
            doc[updater.field_name] = str(f.id)
        else:
            try:
                doc[updater.field_name] = str(f)
            except (TypeError, ValueError) as e:
                if updater.migration_policy.name == 'strict':
                    raise MigrationError(f'Cannot convert value {updater.field_name}: '
                                         f'{doc[updater.field_name]} to string') from e

    # TODO: precheck if field actually contains value other than string
    updater.update_by_document(by_doc)

def to_int(updater: DocumentUpdater):
    __mongo_convert(updater, 'int')

def to_long(updater: DocumentUpdater):
    __mongo_convert(updater, 'long')

def to_double(updater: DocumentUpdater):
    __mongo_convert(updater, 'double')

def to_decimal(updater: DocumentUpdater):
    __mongo_convert(updater, 'decimal')

def to_date(updater: DocumentUpdater):
    __mongo_convert(updater, 'date')

def to_bool(updater: DocumentUpdater):
    __mongo_convert(updater, 'bool')

def to_binary(updater: DocumentUpdater):
    __mongo_convert(updater, 'binary')

def to_object(updater: DocumentUpdater):
    __mongo_convert(updater, 'object')

def to_uuid_str(updater: DocumentUpdater):
    """Convert binData with UUID to string with UUID"""
    def by_doc(ctx: ByDocContext):
        doc = ctx.document
        if updater.field_name not in doc or doc[updater.field_name] is None:
            return

        f = doc[updater.field_name]
        if isinstance(f, str) and uuid_pattern.match(f):
            return
        elif isinstance(f, uuid.UUID):
            doc[updater.field_name] = str(f)
        elif updater.migration_policy.name == 'strict':
            raise InconsistencyError(f"Field {updater.field_name} has wrong value {f!r} "
                                     f"(should be UUID string or UUID Binary data) in record {doc}")

    uuid_pattern = re.compile(r'\A[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}\Z',
                              re.IGNORECASE)
    updater.update_by_document(by_doc)

def to_uuid_bin(updater: DocumentUpdater):
    """Convert strings with UUID to binData with UUID"""
    def by_doc(ctx: ByDocContext):
        doc = ctx.document
        if updater.field_name not in doc or doc[updater.field_name] is None:
            return

        f = doc[updater.field_name]
        if isinstance(f, uuid.UUID):
            return
        elif isinstance(f, str) and uuid_pattern.match(f):
            doc[updater.field_name] = uuid.UUID(f)
        elif updater.migration_policy.name == 'strict':
            raise InconsistencyError(f"Field {updater.field_name} has wrong value {f!r} "
                                     f"(should be UUID string or UUID Binary data) in record {doc}")

    uuid_pattern = re.compile(r'\A[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}\Z',
                              re.IGNORECASE)
    updater.update_by_document(by_doc)

def to_url_string(updater: DocumentUpdater, check_only=False):
    """Cast fields to string and then verify if they contain URLs"""
    def by_path(ctx: ByPathContext):
        fltr = {ctx.filter_dotpath: {'$not': url_regex, '$ne': None}, **ctx.extra_filter}
        check_empty_result(ctx.collection, ctx.filter_dotpath, fltr)

    to_string(updater)

    url_regex = re.compile(
        r"\A[A-Z]{3,}://[A-Z0-9\-._~:/?#\[\]@!$&'()*+,;%=]\Z",
        re.IGNORECASE
    )
    if updater.migration_policy.name == 'strict':
        updater.update_by_path(by_path)

def to_email_string(updater: DocumentUpdater):
    def by_path(ctx: ByPathContext):
        email_regex = r"\A[^\W][A-Z0-9._%+-]+@[\p{L}0-9.-]+\.\p{L}+\Z"
        fltr = {ctx.filter_dotpath: {'$not': {'$regex': email_regex, '$options': 'i'}, '$ne': None}, **ctx.extra_filter}
        check_empty_result(ctx.collection, ctx.filter_dotpath, fltr)

    to_string(updater)

    if updater.migration_policy.name == 'strict':
        updater.update_by_path(by_path)

def to_complex_datetime(updater: DocumentUpdater):
    def by_path(ctx: ByPathContext):
        fltr = {ctx.filter_dotpath: {'$not': regex, '$ne': None}, **ctx.extra_filter}
        check_empty_result(ctx.collection, ctx.filter_dotpath, fltr)

    to_string(updater)

    # We should not know which separator is used, so use '.+'
    # Separator change is handled by appropriate field method
    regex = r'\A' + str('.+'.join([r"\d{4}"] + [r"\d{2}"] * 5 + [r"\d{6}"])) + r'\Z'
    if updater.migration_policy.name == 'strict':
        updater.update_by_path(by_path)

def __mongo_convert(updater: DocumentUpdater, target_type: str):
    """
    Convert field to a given type in a given collection. `target_type`
    contains MongoDB type name, such as 'string', 'decimal', etc.

    https://docs.mongodb.com/manual/reference/operator/aggregation/convert/
    :param updater: DocumentUpdater object
    :param target_type: MongoDB type name
    :return:
    """
    def by_doc(ctx: ByDocContext):
        # https://docs.mongodb.com/manual/reference/operator/aggregation/convert/
        type_map = {
            'double': float,
            'string': str,
            'objectId': bson.ObjectId,
            'bool': bool,
            'date': lambda x: dateutil_parse(str(x)),
            'int': int,
            'long': bson.Int64,
            'decimal': float,
            'binary': bson.Binary,
            'object': dict
        }
        assert target_type in type_map

        doc = ctx.document
        field_name = updater.field_name
        if field_name in doc:
            t = type_map[target_type]
            if not isinstance(doc[field_name], t) and doc[field_name] is not None:
                try:
                    doc[field_name] = type_map[target_type](doc[field_name])
                except (TypeError, ValueError) as e:
                    if updater.migration_policy.name == 'strict':
                        raise MigrationError(f'Cannot convert value '
                                             f'{field_name}: {doc[field_name]} to type {t}') from e

    updater.update_by_document(by_doc)


# -*- coding: utf-8 -*-
"""
Created on Tue Jan 14 14:19:53 2020

@author: Mercy Mueni Mwangi
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import r2_score
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

#reading the file
dataset = pd.read_csv('C:\\Users\\Mercy Mueni Mwangi\\Documents\\Data Science\\Udemy\\baseballplayer.csv')
dataset.head()

#specifying our variables
X = dataset['Angle'].values.reshape(-1,1)
Y = dataset['Distance'].values.reshape(-1,1)

#ploting/visualizing the data
plt.scatter(X,Y,color = "red")
plt.xlabel("Angle")
plt.ylabel("Distance")
plt.title("Distance covered by the ball", loc = "center")
plt.show()

#Drawing linear regression line
# here we use R-squared  value to draw a linear line through a non-linear data
x_train, x_test,y_train,y_test= train_test_split(X,Y, test_size =0.4, random_state=0)

# Regression Instance
regressor= LinearRegression()
regressor.fit(x_train,y_train)

# Plotting the linear regression line through the polinomial data
plt.scatter(X,Y,color = "red")
plt.plot(x_train,regressor.predict(x_train))
plt.xlabel("Angle")
plt.ylabel("Distance")
plt.title("Distance covered by the ball", loc = "center")
plt.show()

#r-squared score
pred_y = regressor.predict(x_test)
R_squared= r2_score(y_test,pred_y)

''' USING POLYNOMIAL REGRESSION MODEL '''
from sklearn.preprocessing import PolynomialFeatures

#transforming x features with PolynomialFeatures
poly_reg = PolynomialFeatures(degree=2)
transformed_x= poly_reg.fit_transform(X)

#splitting the data
xtrain, xtest,ytrain,ytest= train_test_split(transformed_x,Y, test_size =0.4, random_state=0)

# fitting a regression model
regressor2=LinearRegression()
regressor2.fit(xtrain,ytrain)

#r-squared score
pred_y1=regressor2.predict(xtest)
Rsquared= r2_score(ytest,pred_y1)


import inspect
import itertools
import logging
import sys
import os
import gc

from ryu import cfg
from ryu import utils
from ryu.app import wsgi
from ryu.controller.handler import register_instance, get_dependent_services
from ryu.controller.controller import Datapath
from ryu.controller import event
from ryu.controller.event import EventRequestBase, EventReplyBase
from ryu.lib import hub
from ryu.ofproto import ofproto_protocol

LOG = logging.getLogger('ryu.base.app_manager')

SERVICE_BRICKS = {}

def lookup_service_brick(name):
    return SERVICE_BRICKS.get(name)

def _lookup_service_brick_by_ev_cls(ev_cls):
    return _lookup_service_brick_by_mod_name(ev_cls.__module__)

def _lookup_service_brick_by_mod_name(mod_name):
    return lookup_service_brick(mod_name.split('.')[-1])

def register_app(app):
    assert isinstance(app, RyuApp)
    assert app.name not in SERVICE_BRICKS
    SERVICE_BRICKS[app.name] = app
    register_instance(app)

def unregister_app(app):
    SERVICE_BRICKS.pop(app.name)

def require_app(app_name, api_style=False):
    """
    Request the application to be automatically loaded.

    If this is used for "api" style modules, which is imported by a client
    application, set api_style=True.

    If this is used for client application module, set api_style=False.
    """
    iterable = (inspect.getmodule(frame[0]) for frame in inspect.stack())
    modules = [module for module in iterable if module is not None]
    if api_style:
        m = modules[2]  # skip a frame for "api" module
    else:
        m = modules[1]
    m._REQUIRED_APP = getattr(m, '_REQUIRED_APP', [])
    m._REQUIRED_APP.append(app_name)
    LOG.debug('require_app: %s is required by %s', app_name, m.__name__)

class RyuApp(object):
    """
    The base class for Ryu applications.

    RyuApp subclasses are instantiated after ryu-manager loaded
    all requested Ryu application modules.
    __init__ should call RyuApp.__init__ with the same arguments.
    It's illegal to send any events in __init__.

    The instance attribute 'name' is the name of the class used for
    message routing among Ryu applications.  (Cf. send_event)
    It's set to __class__.__name__ by RyuApp.__init__.
    It's discouraged for subclasses to override this.
    """

    _CONTEXTS = {}
    """
    A dictionary to specify contexts which this Ryu application wants to use.
    Its key is a name of context and its value is an ordinary class
    which implements the context.  The class is instantiated by app_manager
    and the instance is shared among RyuApp subclasses which has _CONTEXTS
    member with the same key.  A RyuApp subclass can obtain a reference to
    the instance via its __init__'s kwargs as the following.

    Example::

        _CONTEXTS = {
            'network': network.Network
        }

        def __init__(self, *args, *kwargs):
            self.network = kwargs['network']
    """

    _EVENTS = []
    """
    A list of event classes which this RyuApp subclass would generate.
    This should be specified if and only if event classes are defined in
    a different python module from the RyuApp subclass is.
    """

    OFP_VERSIONS = None
    """
    A list of supported OpenFlow versions for this RyuApp.
    The default is all versions supported by the framework.

    Examples::

        OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION,
                        ofproto_v1_2.OFP_VERSION]

    If multiple Ryu applications are loaded in the system,
    the intersection of their OFP_VERSIONS is used.
    """

    @classmethod
    def context_iteritems(cls):
        """
        Return iterator over the (key, contxt class) of application context
        """
        return iter(cls._CONTEXTS.items())

    def __init__(self, *_args, **_kwargs):
        super(RyuApp, self).__init__()
        self.name = self.__class__.__name__
        self.event_handlers = {}        # ev_cls -> handlers:list
        self.observers = {}     # ev_cls -> observer-name -> states:set
        self.threads = []
        self.main_thread = None
        self.events = hub.Queue(128)
        self._events_sem = hub.BoundedSemaphore(self.events.maxsize)
        if hasattr(self.__class__, 'LOGGER_NAME'):
            self.logger = logging.getLogger(self.__class__.LOGGER_NAME)
        else:
            self.logger = logging.getLogger(self.name)
        self.CONF = cfg.CONF

        # prevent accidental creation of instances of this class outside RyuApp
        class _EventThreadStop(event.EventBase):
            pass
        self._event_stop = _EventThreadStop()
        self.is_active = True

    def start(self):
        """
        Hook that is called after startup initialization is done.
        """
        self.threads.append(hub.spawn(self._event_loop))

    def stop(self):
        if self.main_thread:
            hub.kill(self.main_thread)
        self.is_active = False
        self._send_event(self._event_stop, None)
        hub.joinall(self.threads)

    def set_main_thread(self, thread):
        """
        Set self.main_thread so that stop() can terminate it.

        Only AppManager.instantiate_apps should call this function.
        """
        self.main_thread = thread

    def register_handler(self, ev_cls, handler):
        assert callable(handler)
        self.event_handlers.setdefault(ev_cls, [])
        self.event_handlers[ev_cls].append(handler)

    def unregister_handler(self, ev_cls, handler):
        assert callable(handler)
        self.event_handlers[ev_cls].remove(handler)
        if not self.event_handlers[ev_cls]:
            del self.event_handlers[ev_cls]

    def register_observer(self, ev_cls, name, states=None):
        states = states or set()
        ev_cls_observers = self.observers.setdefault(ev_cls, {})
        ev_cls_observers.setdefault(name, set()).update(states)

    def unregister_observer(self, ev_cls, name):
        observers = self.observers.get(ev_cls, {})
        observers.pop(name)

    def unregister_observer_all_event(self, name):
        for observers in self.observers.values():
            observers.pop(name, None)

    def observe_event(self, ev_cls, states=None):
        brick = _lookup_service_brick_by_ev_cls(ev_cls)
        if brick is not None:
            brick.register_observer(ev_cls, self.name, states)

    def unobserve_event(self, ev_cls):
        brick = _lookup_service_brick_by_ev_cls(ev_cls)
        if brick is not None:
            brick.unregister_observer(ev_cls, self.name)

    def get_handlers(self, ev, state=None):
        """Returns a list of handlers for the specific event.

        :param ev: The event to handle.
        :param state: The current state. ("dispatcher")
                      If None is given, returns all handlers for the event.
                      Otherwise, returns only handlers that are interested
                      in the specified state.
                      The default is None.
        """
        ev_cls = ev.__class__
        handlers = self.event_handlers.get(ev_cls, [])
        if state is None:
            return handlers

        def test(h):
            if not hasattr(h, 'callers') or ev_cls not in h.callers:
                # dynamically registered handlers does not have
                # h.callers element for the event.
                return True
            states = h.callers[ev_cls].dispatchers
            if not states:
                # empty states means all states
                return True
            return state in states

        return filter(test, handlers)

    def get_observers(self, ev, state):
        observers = []
        for k, v in self.observers.get(ev.__class__, {}).items():
            if not state or not v or state in v:
                observers.append(k)

        return observers

    def send_request(self, req):
        """
        Make a synchronous request.
        Set req.sync to True, send it to a Ryu application specified by
        req.dst, and block until receiving a reply.
        Returns the received reply.
        The argument should be an instance of EventRequestBase.
        """

        assert isinstance(req, EventRequestBase)
        req.sync = True
        req.reply_q = hub.Queue()
        self.send_event(req.dst, req)
        # going to sleep for the reply
        return req.reply_q.get()

    def _event_loop(self):
        while self.is_active or not self.events.empty():
            ev, state = self.events.get()
            self._events_sem.release()
            if ev == self._event_stop:
                continue
            handlers = self.get_handlers(ev, state)
            for handler in handlers:
                try:
                    handler(ev)
                except hub.TaskExit:
                    # Normal exit.
                    # Propagate upwards, so we leave the event loop.
                    raise
                except:
                    LOG.exception('%s: Exception occurred during handler processing. '
                                  'Backtrace from offending handler '
                                  '[%s] servicing event [%s] follows.',
                                  self.name, handler.__name__, ev.__class__.__name__)

    def _send_event(self, ev, state):
        self._events_sem.acquire()
        self.events.put((ev, state))

    def send_event(self, name, ev, state=None):
        """
        Send the specified event to the RyuApp instance specified by name.
        """

        if name in SERVICE_BRICKS:
            if isinstance(ev, EventRequestBase):
                ev.src = self.name
            LOG.debug("EVENT %s->%s %s",
                      self.name, name, ev.__class__.__name__)
            SERVICE_BRICKS[name]._send_event(ev, state)
        else:
            LOG.debug("EVENT LOST %s->%s %s",
                      self.name, name, ev.__class__.__name__)

    def send_event_to_observers(self, ev, state=None):
        """
        Send the specified event to all observers of this RyuApp.
        """

        for observer in self.get_observers(ev, state):
            self.send_event(observer, ev, state)

    def reply_to_request(self, req, rep):
        """
        Send a reply for a synchronous request sent by send_request.
        The first argument should be an instance of EventRequestBase.
        The second argument should be an instance of EventReplyBase.
        """

        assert isinstance(req, EventRequestBase)
        assert isinstance(rep, EventReplyBase)
        rep.dst = req.src
        if req.sync:
            req.reply_q.put(rep)
        else:
            self.send_event(rep.dst, rep)

    def close(self):
        """
        teardown method.
        The method name, close, is chosen for python context manager
        """
        pass

class AppManager(object):
    # singleton
    _instance = None

    @staticmethod
    def run_apps(app_lists):
        """Run a set of Ryu applications

        A convenient method to load and instantiate apps.
        This blocks until all relevant apps stop.
        """
        app_mgr = AppManager.get_instance()
        app_mgr.load_apps(app_lists)
        contexts = app_mgr.create_contexts()
        services = app_mgr.instantiate_apps(**contexts)
        webapp = wsgi.start_service(app_mgr)
        if webapp:
            services.append(hub.spawn(webapp))
        try:
            hub.joinall(services)
        finally:
            app_mgr.close()
            for t in services:
                t.kill()
            hub.joinall(services)
            gc.collect()

    @staticmethod
    def get_instance():
        if not AppManager._instance:
            AppManager._instance = AppManager()
        return AppManager._instance

    def __init__(self):
        self.applications_cls = {}
        self.applications = {}
        self.contexts_cls = {}
        self.contexts = {}
        self.close_sem = hub.Semaphore()

    def load_app(self, name):
        mod = utils.import_module(name)
        clses = inspect.getmembers(mod,
                                   lambda cls: (inspect.isclass(cls) and
                                                issubclass(cls, RyuApp) and
                                                mod.__name__ ==
                                                cls.__module__))
        if clses:
            return clses[0][1]
        return None

    def load_apps(self, app_lists):
        app_lists = [app for app
                     in itertools.chain.from_iterable(app.split(',')
                                                      for app in app_lists)]
        while len(app_lists) > 0:
            app_cls_name = app_lists.pop(0)

            context_modules = [x.__module__ for x in self.contexts_cls.values()]
            if app_cls_name in context_modules:
                continue

            LOG.info('loading app %s', app_cls_name)

            cls = self.load_app(app_cls_name)
            if cls is None:
                continue

            self.applications_cls[app_cls_name] = cls

            services = []
            for key, context_cls in cls.context_iteritems():
                v = self.contexts_cls.setdefault(key, context_cls)
                assert v == context_cls
                context_modules.append(context_cls.__module__)

                if issubclass(context_cls, RyuApp):
                    services.extend(get_dependent_services(context_cls))

            # we can't load an app that will be initiataed for
            # contexts.
            for i in get_dependent_services(cls):
                if i not in context_modules:
                    services.append(i)
            if services:
                app_lists.extend([s for s in set(services)
                                  if s not in app_lists])

    def create_contexts(self):
        for key, cls in self.contexts_cls.items():
            if issubclass(cls, RyuApp):
                # hack for dpset
                context = self._instantiate(None, cls)
            else:
                context = cls()
            LOG.info('creating context %s', key)
            assert key not in self.contexts
            self.contexts[key] = context
        return self.contexts

    def _update_bricks(self):
        for i in SERVICE_BRICKS.values():
            for _k, m in inspect.getmembers(i, inspect.ismethod):
                if not hasattr(m, 'callers'):
                    continue
                for ev_cls, c in m.callers.items():
                    if not c.ev_source:
                        continue

                    brick = _lookup_service_brick_by_mod_name(c.ev_source)
                    if brick:
                        brick.register_observer(ev_cls, i.name,
                                                c.dispatchers)

                    # allow RyuApp and Event class are in different module
                    for brick in SERVICE_BRICKS.values():
                        if ev_cls in brick._EVENTS:
                            brick.register_observer(ev_cls, i.name,
                                                    c.dispatchers)

    @staticmethod
    def _report_brick(name, app):
        LOG.debug("BRICK %s", name)
        for ev_cls, list_ in app.observers.items():
            LOG.debug("  PROVIDES %s TO %s", ev_cls.__name__, list_)
        for ev_cls in app.event_handlers.keys():
            LOG.debug("  CONSUMES %s", ev_cls.__name__)

    @staticmethod
    def report_bricks():
        for brick, i in SERVICE_BRICKS.items():
            AppManager._report_brick(brick, i)

    def _instantiate(self, app_name, cls, *args, **kwargs):
        # for now, only single instance of a given module
        # Do we need to support multiple instances?
        # Yes, maybe for slicing.
        LOG.info('instantiating app %s of %s', app_name, cls.__name__)

        if hasattr(cls, 'OFP_VERSIONS') and cls.OFP_VERSIONS is not None:
            ofproto_protocol.set_app_supported_versions(cls.OFP_VERSIONS)

        if app_name is not None:
            assert app_name not in self.applications
        app = cls(*args, **kwargs)
        register_app(app)
        assert app.name not in self.applications
        self.applications[app.name] = app
        return app

    def instantiate(self, cls, *args, **kwargs):
        app = self._instantiate(None, cls, *args, **kwargs)
        self._update_bricks()
        self._report_brick(app.name, app)
        return app

    def instantiate_apps(self, *args, **kwargs):
        for app_name, cls in self.applications_cls.items():
            self._instantiate(app_name, cls, *args, **kwargs)

        self._update_bricks()
        self.report_bricks()

        threads = []
        for app in self.applications.values():
            t = app.start()
            if t is not None:
                app.set_main_thread(t)
                threads.append(t)
        return threads

    @staticmethod
    def _close(app):
        close_method = getattr(app, 'close', None)
        if callable(close_method):
            close_method()

    def uninstantiate(self, name):
        app = self.applications.pop(name)
        unregister_app(app)
        for app_ in SERVICE_BRICKS.values():
            app_.unregister_observer_all_event(name)
        app.stop()
        self._close(app)
        events = app.events
        if not events.empty():
            app.logger.debug('%s events remains %d', app.name, events.qsize())

    def close(self):
        def close_all(close_dict):
            for app in close_dict.values():
                self._close(app)
            close_dict.clear()

        # This semaphore prevents parallel execution of this function,
        # as run_apps's finally clause starts another close() call.
        with self.close_sem:
            for app_name in list(self.applications.keys()):
                self.uninstantiate(app_name)
            assert not self.applications
            close_all(self.contexts)


import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')

def read_eval(dirs, min_episode=500, eval_freq=10):
    # the experiment should run at least 'min_episode' episodes
    all_episodes = []
    all_normal_rewards = []
    all_color_rewards = []
    all_video_easy_rewards = []
    all_video_rewards = []
    for filename in dirs:
        eval_filename = os.path.join(filename,'eval.csv')
        if os.path.exists(eval_filename):
            df = pd.read_csv(eval_filename)

            if df['episode'].values[-1] >= min_episode:
                all_episodes.append(df['episode'].values)
                all_normal_rewards.append(df['episode_reward_normal'].values)
                all_color_rewards.append(df['episode_reward_color_hard'].values)
                all_video_easy_rewards.append(df['episode_reward_video_easy'].values)
                all_video_rewards.append(df['episode_reward_video_hard'].values)
        else:
            print('{} doesn\'t exist.'.format(eval_filename))

    #print('episodes', [int(episode[-1]) for episode in all_episodes])
    return all_episodes, all_normal_rewards, all_color_rewards, all_video_easy_rewards, all_video_rewards

def compute_mean_std(data):
    data_length = [len(d) for d in data]
    mean = []
    std = []
    for i in range(max(data_length)):
        tmp = []
        for j in range(len(data)):
            if i < data_length[j]:
                tmp.append(data[j][i])
        mean.append(np.mean(tmp))
        std.append(np.std(tmp))

    return np.array(mean), np.array(std)

def plot_rewards(dirs, exp_name, color=None, eval_freq=10, eval_num=1, plot_std=True):
    all_episodes, all_normal_rewards, all_color_rewards, all_video_easy_rewards, all_video_rewards = read_eval(dirs, min_episode=50, eval_freq=eval_freq)
    plot_episodes = np.arange(max([len(_) for _ in all_episodes])) * eval_freq

    last_normal_rewards = [x for _ in all_normal_rewards for x in _[-eval_num:]]
    last_color_rewards = [x for _ in all_color_rewards for x in _[-eval_num:]]
    last_video_easy_rewards = [x for _ in all_video_easy_rewards for x in _[-eval_num:]]
    last_video_rewards = [x for _ in all_video_rewards for x in _[-eval_num:]]

    # normal eval rewards
    plt.subplot(241)
    plot_normal_rewards_mean, plot_normal_rewards_std = compute_mean_std(all_normal_rewards)
    plt.plot((plot_episodes+all_episodes[0][0])*1000, plot_normal_rewards_mean, label=exp_name)
    if plot_std:
        plt.fill_between((plot_episodes+all_episodes[0][0])*1000, plot_normal_rewards_mean-plot_normal_rewards_std, plot_normal_rewards_mean+plot_normal_rewards_std, alpha=0.4)
    print('normal bg, {}: {}; mean {:.2f} +- std {:.2f}'.format(exp_name, [len(_) for _ in all_normal_rewards], np.mean(last_normal_rewards), np.std(last_normal_rewards)))

    # color_hard eval rewards
    plt.subplot(242)
    plot_color_rewards_mean, plot_color_rewards_std = compute_mean_std(all_color_rewards)
    plt.plot((plot_episodes+all_episodes[0][0])*1000, plot_color_rewards_mean, label=exp_name)
    if plot_std:
        plt.fill_between((plot_episodes+all_episodes[0][0])*1000, plot_color_rewards_mean-plot_color_rewards_std, plot_color_rewards_mean+plot_color_rewards_std, alpha=0.4)
    print('color-hard bg, {}: {}; mean {:.2f} +- std {:.2f}'.format(exp_name, [len(_) for _ in all_normal_rewards], np.mean(last_color_rewards), np.std(last_color_rewards)))

    # video_easy eval_rewards
    plt.subplot(243)
    plot_video_easy_rewards_mean, plot_video_easy_rewards_std = compute_mean_std(all_video_easy_rewards)
    plt.plot((plot_episodes+all_episodes[0][0])*1000, plot_video_easy_rewards_mean, label=exp_name)
    if plot_std:
        plt.fill_between((plot_episodes+all_episodes[0][0])*1000, plot_video_easy_rewards_mean-plot_video_easy_rewards_std, plot_video_easy_rewards_mean+plot_video_easy_rewards_std, alpha=0.4)
    print('video-easy bg, {}: {}; mean {:.2f} +- std {:.2f}'.format(exp_name, [len(_) for _ in all_normal_rewards], np.mean(last_video_easy_rewards), np.std(last_video_easy_rewards)))

    # video_hard eval_rewards
    plt.subplot(244)
    plot_video_rewards_mean, plot_video_rewards_std = compute_mean_std(all_video_rewards)
    plt.plot((plot_episodes+all_episodes[0][0])*1000, plot_video_rewards_mean, label=exp_name)
    if plot_std:
        plt.fill_between((plot_episodes+all_episodes[0][0])*1000, plot_video_rewards_mean-plot_video_rewards_std, plot_video_rewards_mean+plot_video_rewards_std, alpha=0.4)
    print('video-hard bg, {}: {}; mean {:.2f} +- std {:.2f}'.format(exp_name, [len(_) for _ in all_normal_rewards], np.mean(last_video_rewards), np.std(last_video_rewards)))

    # ratio, color_hard / normal
    plt.subplot(246)
    color_hard_ratio = plot_color_rewards_mean / plot_normal_rewards_mean
    plt.plot((plot_episodes+all_episodes[0][0])*1000, color_hard_ratio, label=exp_name)

    # ratio, video_easy / normal
    plt.subplot(247)
    video_easy_ratio = plot_video_easy_rewards_mean / plot_normal_rewards_mean
    plt.plot((plot_episodes+all_episodes[0][0])*1000, video_easy_ratio, label=exp_name)

    # ratio, video_hard / normal
    plt.subplot(248)
    video_hard_ratio = plot_video_rewards_mean / plot_normal_rewards_mean
    plt.plot((plot_episodes+all_episodes[0][0])*1000, video_hard_ratio, label=exp_name)

    return np.mean(last_normal_rewards), np.std(last_normal_rewards), np.mean(last_color_rewards), np.std(last_color_rewards), np.mean(last_video_easy_rewards), np.std(last_video_easy_rewards), np.mean(last_video_rewards), np.std(last_video_rewards)

def plt_dir_rewards(dir_name, exp_name, color=None, eval_freq=10, eval_num=1, plot_std=True):
    # eval_freq: evaluate every n episodes

    dirs = os.listdir(dir_name)
    for i in range(len(dirs)):
        dirs[i] = os.path.join(dir_name, dirs[i])
    normal_mean, normal_std, color_mean, color_std, video_easy_mean, video_easy_std, video_mean, video_std = plot_rewards(dirs, exp_name, color, eval_freq, eval_num, plot_std)

    return normal_mean, normal_std, color_mean, color_std, video_easy_mean, video_easy_std, video_mean, video_std

if __name__ == '__main__':
    env_names = [['walker', 'walk'], ['walker', 'stand'], ['cartpole', 'swingup'], ['ball_in_cup', 'catch'], ['finger','spin']]
    plot_type = 'AU7005'

    if plot_type == 'AU7005':
        algo_names = ['svea', 'sda_quantile0.95', 'sda_quantile0.9']
        label_dicts = {}
        for algo_name in algo_names: label_dicts[algo_name] = algo_name
        latex_name = 'table_result_latex'
        csv_name = 'dmgb_table.csv'

    cols = ['env_name', 'svea(normal)', 'sgsac(normal)', 'svea(color-hard)', 'sgsac(color-hard)', 'svea(video-easy)', 'sgsac(video-easy)', 'svea(video-hard)', 'sgsac(video-hard)']
    table_result_df = pd.DataFrame(columns = cols)

    work_dir = 'results'
    if not os.path.exists(work_dir):
        os.mkdir(work_dir)
    work_dir = os.path.join(work_dir, plot_type)
    if not os.path.exists(work_dir):
        os.mkdir(work_dir)

    eval_num = 10
    plot_std = False
    for env_name in env_names:
        print(env_name)
        textbfs = ''
        plt.figure(figsize=(20,10))
        domain_name, task_name = env_name
        result_dir = '{}_{}_results_onlycsv'.format(domain_name, task_name)
        for algo_name in algo_names:
            algo_dir = os.path.join(result_dir, algo_name)
            if os.path.exists(algo_dir):
                label_name = label_dicts[algo_name]
                try:
                    normal_mean, normal_std, color_mean, color_std, video_easy_mean, video_easy_std, video_mean, video_std = plt_dir_rewards(algo_dir, label_name, eval_num=eval_num, plot_std=plot_std)
                except Exception as e:
                    normal_mean, normal_std, color_mean, color_std, video_easy_mean, video_easy_std, video_mean, video_std = 0, 0, 0, 0, 0, 0, 0, 0
                    print(e)

        exp_dict = {1:'normal',2:'color_hard',3:'video_easy',4:'video_hard',6:'color-hard/normal', 7:'video-easy/normal', 8:'video-hard/normal'}
        for i in exp_dict:
            plt.subplot(240+i)
            plt.xlabel('environment steps')
            if i <= 4:
                plt.ylabel('episode_reward (eval)')
            elif 6 <= i <= 8:
                plt.ylabel('ratio')
            #plt.ylim(0, 1000)
            plt.legend(loc='best')
            plt.grid()
            plt.title('{}_{} {} eval'.format(domain_name, task_name, exp_dict[i]))
            plt.savefig(os.path.join(work_dir,'{}_{}_gb'.format(domain_name, task_name)))
        plt.close()

    print(table_result_df)


#!/usr/bin/env python
import argparse
import os
import subprocess
import uuid
import ast

class cd:
    """Context manager for changing the current working directory"""

    def __init__(self, newPath):
        self.newPath = os.path.expanduser(newPath)

    def __enter__(self):
        self.savedPath = os.getcwd()
        os.chdir(self.newPath)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.savedPath)

class DockerPopen(subprocess.Popen):
    def __exit__(self, exc_type, exc_val, traceback):
        self.terminate()
        self.wait(5)
        return super().__exit__(exc_type, exc_val, traceback)

def create_docker(name: str) -> str:
    rand = str(uuid.uuid4())[:5]
    tag = f"{name}:{rand}"
    with cd(
        os.path.join(os.path.dirname(os.path.dirname(__file__)), "docker_images", name)
    ):
        subprocess.run(["docker", "build", ".", "-t", tag])
    return tag

def show(args):
    directory = os.path.join(os.path.dirname(os.path.dirname(__file__)), "docker_images")
    for framework in sorted(os.listdir(directory)):
        print(f"{framework}")
        local_path = os.path.join(
            os.path.dirname(os.path.dirname(__file__)), "docker_images", framework,
            "app", "main.py"
        )
        # Using ast to prevent import issues with missing dependencies.
        # and slow loads.
        with open(local_path, "r") as source:
            tree = ast.parse(source.read())
            for item in tree.body:
                if isinstance(item, ast.AnnAssign) and item.target.id == "ALLOWED_TASKS":
                    for key in item.value.keys:
                        print(" " * 4, key.value)

def start(args):
    import sys

    import uvicorn

    model_id = args.model_id
    task = args.task
    framework = args.framework

    local_path = os.path.join(
        os.path.dirname(os.path.dirname(__file__)), "docker_images", framework
    )
    sys.path.append(local_path)
    os.environ["MODEL_ID"] = model_id
    os.environ["TASK"] = task
    uvicorn.run("app.main:app", host="127.0.0.1", port=8000, log_level="info")

def docker(args):
    model_id = args.model_id
    task = args.task
    framework = args.framework

    tag = create_docker(framework)
    run_docker_command = [
        "docker",
        "run",
        "-p",
        "8000:80",
        "-e",
        f"TASK={task}",
        "-e",
        f"MODEL_ID={model_id}",
        "-v",
        "/tmp:/data",
        "-t",
        tag,
    ]

    with DockerPopen(run_docker_command) as proc:
        try:
            proc.wait()
        except KeyboardInterrupt:
            proc.terminate()

def main():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()
    parser_start = subparsers.add_parser(
        "start", help="Start a local version of a model inference"
    )
    parser_start.add_argument(
        "--model-id",
        type=str,
        required=True,
        help="Which model_id to start.",
    )
    parser_start.add_argument(
        "--task",
        type=str,
        required=True,
        help="Which task to load",
    )
    parser_start.add_argument(
        "--framework",
        type=str,
        required=True,
        help="Which framework to load",
    )
    parser_start.set_defaults(func=start)
    parser_docker = subparsers.add_parser(
        "docker", help="Start a docker version of a model inference"
    )
    parser_docker.add_argument(
        "--model-id",
        type=str,
        required=True,
        help="Which model_id to docker.",
    )
    parser_docker.add_argument(
        "--task",
        type=str,
        required=True,
        help="Which task to load",
    )
    parser_docker.add_argument(
        "--framework",
        type=str,
        required=True,
        help="Which framework to load",
    )
    parser_docker.set_defaults(func=docker)
    parser_show = subparsers.add_parser(
        "show", help="Show dockers and the various pipelines they implement"
    )
    parser_show.set_defaults(func=show)
    args = parser.parse_args()
    args.func(args)

if __name__ == "__main__":
    main()


import argparse
import sythe.fileio as fileio
from sythe.resources.ec2_resources import get_ec2_instances

def main():
    parser = argparse.ArgumentParser(description='A rule engine for resources')
    parser.add_argument('config', help='The config file containing rules')
    args = parser.parse_args()

    config_file_path = args.config
    rules = fileio.parse_rules_from_file(config_file_path)
    resources = get_ec2_instances()
    for rule in rules:
        print("Applying rule: {}".format(rule))
        for resource in resources:
            rule.execute(resource)


from flask import Flask, render_template, Response
import cv2
import face_recognition
import numpy as np

app = Flask(__name__)

video_capture = cv2.VideoCapture("video/debate_2022.mp4")

lula_image = face_recognition.load_image_file("fotos_treino/lula.png")
lula_face_encoding = face_recognition.face_encodings(lula_image)[0]

bolsonaro_image = face_recognition.load_image_file("fotos_treino/bolsonaro.jpg")
bolsonaro_face_encoding = face_recognition.face_encodings(bolsonaro_image)[0]

known_face_encodings = [
    lula_face_encoding,
    bolsonaro_face_encoding
]

known_face_names = [
    "Lula",
    "Bolsonaro"
]

face_locations = []
face_encodings = []
face_names = []
process_this_frame = True

def detect_faces(frame):
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
    rgb_small_frame = small_frame[:, :, ::-1]

    face_locations = face_recognition.face_locations(rgb_small_frame, model="CNN", number_of_times_to_upsample=1)
    face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)

    face_names = []
    for face_encoding in face_encodings:
        matches = face_recognition.compare_faces(known_face_encodings, face_encoding, tolerance=0.58)
        name = "Desconhecido"

        face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
        best_match_index = np.argmin(face_distances)
        if matches[best_match_index]:
            name = known_face_names[best_match_index]

        face_names.append(name)

    return face_locations, face_names

def gen_frames():
    while True:
        success, frame = video_capture.read()

        if not success:
            break

        face_locations, face_names = detect_faces(frame)

        for (top, right, bottom, left), name in zip(face_locations, face_names):
            top *= 4
            right *= 4
            bottom *= 4
            left *= 4

            if name == "Desconhecido":
                cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
                cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
                font = cv2.FONT_HERSHEY_DUPLEX
                cv2.putText(frame, name, (left + 6, bottom - 6), font, 0.8, (255, 255, 255), 1)
            else:
                cv2.rectangle(frame, (left, top), (right, bottom), (255, 165, 0), 2)
                cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (255, 165, 0), cv2.FILLED)
                font = cv2.FONT_HERSHEY_DUPLEX
                cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)

        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)


from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.conf import settings
from django.utils import simplejson
from django.template import Context, RequestContext
from django.template.loader import get_template
from madrona.common import default_mimetypes as mimetypes
from madrona.common.utils import kml_errors
from forms import UploadForm

def load_single_shp(request):
    """
    GET returns a form to upload a zipped shp
    POST takes the zip, validates that it is a single-feature poly shp and returns KML
    """
    user = request.user
    if user.is_anonymous() or not user.is_authenticated():
        return HttpResponse('You must be logged in', status=401)

    form = UploadForm()
    if request.method == 'POST':
        form = UploadForm(request.POST, request.FILES)

        # Override the defulat form behavior and
        # only allow single-feature polygon shps
        form.multi_feature = False
        form.supported_geomtypes = ['Polygon']

        if form.is_valid():
            layer = form.handle(request.FILES['file_obj'],user)
            g = layer[0].geom
            if g.srs:
                g.transform_to(4326)
            geoms = [g]
            t = get_template('loadshp/loadshp.kml')
            kml = t.render(Context({'username': user.username, 'geoms': geoms}))
            json = simplejson.dumps({'input_kml': kml, 'status':'success'})
            # Jquery Form plugin requires that we wrap this in a textarea
            # otherwise it mangles the kml
            return HttpResponse('<textarea>' + json + '</textarea>',mimetype="text/html")
        else:
            json = simplejson.dumps({'error_html': form.errors['file_obj'][0], 'status':'errors'})
            return HttpResponse('<textarea>' + json + '</textarea>',mimetype="text/html")

    elif request.method == 'GET':
        return render_to_response('loadshp/upload.html', RequestContext(request,{'form': form,'action':request.path}))

    else:
        raise Exception("This URL does not support %s requests" % request.method)


import os, sys
import time
import argparse
import json
import datetime, dateutil
import numpy as np

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description = "Experiment Info",
        epilog = "Record meta information on experiment.",
        add_help = "How to use",
        prog = "python experi.py <arguments>")

    parser.add_argument('-t','--type', choices=['Migration', 'Foraging', 'other'],
                        help = "General type of experiment.")
    parser.add_argument('-d', '--date', default = 'today', type = str,
                        help = "Date of experiment [DEFAULT: today]. Format Must be ISO: 'YYYY-MM-DD'.")
    parser.add_argument('-s','--species', choices=['T.rugatulus', 'T.curvispinosus', 'other'],
                        help = "Species used in experiment.")
    parser.add_argument('-r','--recording_size', type = float,
                        help = "Size of recording")

    args = vars(parser.parse_args())

    # Collect the arguments.
    exp_type = args['type']
    exp_date = args['date']
    exp_spp  = args['species']
    exp_size = args['recording_size']

    # handling date input
    if exp_date == 'today':
        date = datetime.datetime.now().strftime("%Y-%m-%d")
    else:
        date_temp = datetime.date.fromisoformat(exp_date)
        date = date_temp.strftime("%Y-%m-%d")

    meta = {
        "date": date,
        "exp_type": exp_type,
        "species": exp_spp,
        "File Size (TB)": exp_size,
        }

    # file name formatting
    fn = f"T_{exp_spp[2:5]}_{exp_type}_{exp_date}.json"
    json_object = json.dumps(meta, indent = 4)

    with open(fn, "w") as outfile:
        outfile.write(json_object)