"""Download Anime"""

# For USERGE-X
# (C) 2021 All Rights Reserved
# Idea by: [TG: @Lostb053]
# Author: (github.com/code-rgb) [TG: @DeletedUser420]

import asyncio
from urllib.parse import quote

from bs4 import BeautifulSoup as soup
from pyrogram import filters
from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup

from userge import Config, Message, userge
from userge.utils import check_owner, get_response, rand_key

GOGO = "https://gogoanime.so"
GOGO_DB = {}

@userge.on_cmd("gogo", about={"header": "Gogo Plugin Help"})
async def gogo_h(message: Message):
    if not userge.has_bot:
        await message.err("You Need to create a bot via Bot Father", del_in=5)
        return
    link_ = "https://t.me/{}?start=inline".format((await userge.bot.get_me()).username)
    if message.client.is_bot:
        await userge.bot.send_message(
            message.chat.id,
            text="To know how to use this plugin,\nClick the button below",
            reply_markup=InlineKeyboardMarkup(
                [[InlineKeyboardButton("See Help for Anime", url=link_)]]
            ),
        )
        await message.delete()
    else:
        await message.edit(
            "[**See Help for Anime**]({})".format(link_), disable_web_page_preview=True
        )

class Anime:
    @staticmethod
    async def _get_html(link: str, add_pre: bool = True):
        if add_pre:
            link = GOGO + link
        content = await get_response.text(link)
        return soup(content, "lxml")

    @staticmethod
    async def search(query: str):
        page = await Anime._get_html("/search.html?keyword=" + quote(query))
        out = []
        for i in page.find("ul", {"class": "items"}).findAll("li"):
            result_ = i.find("p", {"class": "name"})
            title = result_.a.text.strip()
            release = i.find("p", {"class": "released"}).text.strip()
            result_url = GOGO + result_.a.get("href")
            image = i.div.a.img.get("src")
            k_ = image.rsplit("/", 1)
            if len(k_) == 2:
                k_[1] = quote(k_[1])
            key_ = rand_key()
            body_ = f"[\u200c]({'/'.join(k_)})**{title}**\n{release}"
            GOGO_DB[key_] = {"url": result_url, "body": body_}
            out.append(
                {
                    "key": key_,
                    "title": title,
                    "release": release,
                    "image": "/".join(k_),
                }
            )
        return out

    @staticmethod
    async def get_eps(link: str):
        page = await Anime._get_html(link, add_pre=False)
        end_ = page.find("ul", {"id": "episode_page"}).findAll("li")[-1].a.get("ep_end")
        return end_

    @staticmethod
    def _get_name(link: str):
        name_ = "/" + (link.rsplit("/", 1))[1]
        return name_

    @staticmethod
    async def get_quality(url: str, episode: int, key_: str):
        endpoint = f"{Anime._get_name(url)}-episode-{episode}"
        page_ = await Anime._get_html(endpoint)
        link_ = page_.find("li", {"class": "dowloads"}).a.get("href")
        # get qualities from download page
        page = await Anime._get_html(link_, add_pre=False)
        btn_, row_ = [], []
        for i in page.findAll("div", {"class": "dowload"}):
            qual = i.a
            if qual.get("target") != "_blank":
                name = qual.text.replace("Download", "").strip()
                btn_.append(InlineKeyboardButton(name, url=qual.get("href")))
                if len(btn_) == 2:
                    row_.append(btn_)
                    btn_ = []
        if len(btn_) != 0:
            row_.append(btn_)
        row_.append(
            [InlineKeyboardButton("Back", callback_data=f"get_currentpg{key_}")]
        )
        return InlineKeyboardMarkup(row_)

if userge.has_bot:

    @userge.bot.on_callback_query(filters.regex(pattern="get_eps(.*)"))
    @check_owner
    async def get_eps_from_key(c_q: CallbackQuery):
        key_ = c_q.matches[0].group(1)
        url_ = GOGO_DB.get(key_)
        if not url_:
            return await c_q.answer("Not Found")
        url_ = url_.get("url")
        await c_q.answer()
        res = await Anime.get_eps(url_)
        btn_, row_, paginate = [], [], []
        for i in range(1, int(res) + 1):
            btn_.append(
                InlineKeyboardButton(
                    "EP " + str(i), callback_data=f"gogo_get_qual{key_}_{i}"
                )
            )
            if len(btn_) == 4:
                row_.append(btn_)
                btn_ = []
            if len(row_) == 7:
                paginate.append(row_)
                row_ = []
        if len(btn_) != 0:
            row_.append(btn_)
        if len(row_) != 0:
            paginate.append(row_)
        GOGO_DB[key_]["page"] = paginate
        p_len = len(paginate)
        if p_len > 1:
            paginate[0].append(
                [
                    InlineKeyboardButton(
                        "1 / " + str(p_len), callback_data=f"gogo_page{key_}_0"
                    ),
                    InlineKeyboardButton("Next", callback_data=f"gogo_next{key_}_0"),
                ]
            )
        GOGO_DB[key_]["current_pg"] = paginate[0]
        await c_q.edit_message_reply_markup(
            reply_markup=InlineKeyboardMarkup(paginate[0])
        )

    @userge.bot.on_callback_query(
        filters.regex(pattern=r"gogo_get_qual([a-z0-9]+)_([\d]+)")
    )
    @check_owner
    async def get_qual_from_eps(c_q: CallbackQuery):
        key_ = c_q.matches[0].group(1)
        episode = int(c_q.matches[0].group(2))
        key_data = GOGO_DB.get(key_)
        if not key_data:
            return await c_q.answer("Not Found")
        url_ = key_data.get("url")
        await c_q.answer()
        await c_q.edit_message_text(
            text=f"{key_data.get('body')}\n**[  Episode: {episode}  ]**\n\n📹 __Choose the desired video quality from below.__\n**Note:** for uploading to TG:\n`{Config.CMD_TRIGGER}upload [link] | [filename].mp4`",
            reply_markup=(
                await Anime.get_quality(url=url_, episode=episode, key_=key_)
            ),
        )

    @userge.bot.on_callback_query(
        filters.regex(pattern=r"gogo_(page|next|back)([a-z0-9]+)_([\d]+)")
    )
    @check_owner
    async def gogo_paginate(c_q: CallbackQuery):
        direction = c_q.matches[0].group(1)
        key_ = c_q.matches[0].group(2)
        pos = int(c_q.matches[0].group(3))
        key_data = GOGO_DB.get(key_)
        if not key_data:
            return await c_q.answer("Not Found")
        await c_q.answer()
        pages = key_data.get("page")
        p_len = len(pages)
        del_back, del_next = False, False
        if direction == "next":
            page = pos + 1
            del_next = (page + 1) == p_len
        elif direction == "back":
            del_back = pos == 1
            page = pos - 1
        else:
            return
        button_base = [
            InlineKeyboardButton("❮  Back", callback_data=f"gogo_back{key_}_{page}"),
            InlineKeyboardButton(
                f"{page + 1} / {p_len}",
                callback_data=f"gogo_page{key_}_{page}",
            ),
            InlineKeyboardButton("Next  ❯", callback_data=f"gogo_next{key_}_{page}"),
        ]
        if del_back:
            button_base.pop(0)
        if del_next:
            button_base.pop()
        # Work Around for multiple nav buttons
        # idk why "pages" is acting as a global variable
        # So safe to check if nav buttons already exists
        if "gogo_get_qual" in pages[page][-1][-1].callback_data:
            pages[page].append(button_base)
        else:
            pages[page][-1] = button_base
        GOGO_DB[key_]["current_pg"] = pages[page]
        await c_q.edit_message_reply_markup(
            reply_markup=InlineKeyboardMarkup(pages[page])
        )
        await asyncio.sleep(0.3)

    @userge.bot.on_callback_query(filters.regex(pattern=r"get_currentpg(.*)"))
    @check_owner
    async def get_current_pg(c_q: CallbackQuery):
        key_ = c_q.matches[0].group(1)
        data_ = GOGO_DB.get(key_)
        if not data_:
            return await c_q.answer("Not Found")
        await c_q.answer()
        mrkp = data_.get("current_pg")
        body_ = data_.get("body")
        await c_q.edit_message_text(text=body_, reply_markup=InlineKeyboardMarkup(mrkp))


#!/usr/bin/env python

# This work is licensed under the terms of the MIT license.
# For a copy, see <https://opensource.org/licenses/MIT>.

"""
Module used to parse all the route and scenario configuration parameters.
"""

import json
import math
import xml.etree.ElementTree as ET
import sys

import carla
from agents.navigation.local_planner import RoadOption
from srunner.scenarioconfigs.route_scenario_configuration import RouteScenarioConfiguration

# TODO  check this threshold, it could be a bit larger but not so large that we cluster scenarios.
TRIGGER_THRESHOLD = 2.0  # Threshold to say if a trigger position is new or repeated, works for matching positions
TRIGGER_ANGLE_THRESHOLD = 10  # Threshold to say if two angles can be considering matching when matching transforms.

class RouteParser(object):

    """
    Pure static class used to parse all the route and scenario configuration parameters.
    """

    @staticmethod
    def parse_annotations_file(annotation_filename):  # world_annotations = RouteParser.parse_annotations_file(config.scenario_file)  # scenario file is the JSON file # return final_dict  # the file has a current maps name that is an one element vec
        """
        Return the annotations of which positions where the scenarios are going to happen.
        :param annotation_filename: the filename for the anotations file
        :return:
        """

        with open(annotation_filename, 'r') as f:  # The JSON file -> scenario_file -> srunner/data/all_towns_traffic_scenarios1_3_4.json
            annotation_dict = json.loads(f.read())
            #print(annotation_filename)  # srunner/data/all_towns_traffic_scenarios1_3_4.json

        final_dict = {}

        for town_dict in annotation_dict['available_scenarios']:
            final_dict.update(town_dict)

        #print(final_dict)

        #print(next(iter(final_dict)))  # prints Town01

        #for keys in final_dict.keys():
            #print(keys)
            '''
            prints
            Town01
            Town02
            Town03
            Town04
            Town05
            Town06
            '''
        '''
        for key, value in final_dict.items():
            print(key)  # All town numbers printed before all the array values of each town were printed.
            print(f"{key}-value are as {value}")  #Town01-value are as, then all the values of that object array, i.e., te available event configurations, transforms, other vehicle transforms, left right front transforms.
        '''

        return final_dict  # the file has a current maps name that is an one element vec

    @staticmethod
    def parse_routes_file(route_filename, scenario_file, single_route=None):
        """
        Returns a list of route elements.
        :param route_filename: the path to a set of routes.
        :param single_route: If set, only this route shall be returned
        :return: List of dicts containing the waypoints, id and town of the routes
        """

        list_route_descriptions = []
        tree = ET.parse(route_filename)  # srunner/data/routes_debug.xml
        for route in tree.iter("route"):  # <route id="0" town="Town02">

            route_id = route.attrib['id']  # <route id="0" town="Town02">
            if single_route and route_id != single_route:  #  single_route = 0, route_id = 0.
                continue

            # For route id = 0 we doing this below: <route id="0" town="Town02">

            new_config = RouteScenarioConfiguration()  # RouteScenarioConfiguration/scenario config object
            new_config.town = route.attrib['town']  # s/o ScenarioConfiguration
            new_config.name = "RouteScenario_{}".format(route_id)  # RouteScenario_0
            new_config.weather = RouteParser.parse_weather(route)  # route -> <route id="0" town="Town02">
            new_config.scenario_file = scenario_file  # The JSON file -> scenario_file -> srunner/data/all_towns_traffic_scenarios1_3_4.json

            waypoint_list = []  # the list of waypoints that can be found on this route  # NAAAAAAAAICCCCCCCCCCCCEEEEEEEEEE
             # For route id = 0 we doing this below: <route id="0" town="Town02">
            for waypoint in route.iter('waypoint'):   # For route id = 0 we doing this below: <route id="0" town="Town02"> ,
            # and now iterating through the route for waypoints!!! and adding them in the order they come, I can even draw them here :3
            # go through all the points in the route!!!!!!!!!!

                waypoint_list.append(carla.Location(x=float(waypoint.attrib['x']),  # converting the waypoints to a valid cala location here and appending that carla location to the waypoint list variable!
                                                    y=float(waypoint.attrib['y']),
                                                    z=float(waypoint.attrib['z'])))

            new_config.trajectory = waypoint_list  # added them (all the waypoint carla locations) to the trajectory variable of the scenario/route configuration object!

            list_route_descriptions.append(new_config)  # only one route cx of one route ID. This list has only one object hence.

        return list_route_descriptions

    @staticmethod
    def parse_weather(route):  # set weather, might NEED it later!
        """
        Returns a carla.WeatherParameters with the corresponding weather for that route. If the route
        has no weather attribute, the default one is triggered.
        """

        route_weather = route.find("weather")
        if route_weather is None:

            weather = carla.WeatherParameters(sun_altitude_angle=70)

        else:
            weather = carla.WeatherParameters()
            for weather_attrib in route.iter("weather"):

                if 'cloudiness' in weather_attrib.attrib:  # child.tag, child.attrib
                    weather.cloudiness = float(weather_attrib.attrib['cloudiness'])  # pass those decimal values
                if 'precipitation' in weather_attrib.attrib:
                    weather.precipitation = float(weather_attrib.attrib['precipitation'])
                if 'precipitation_deposits' in weather_attrib.attrib:
                    weather.precipitation_deposits = float(weather_attrib.attrib['precipitation_deposits'])
                if 'wind_intensity' in weather_attrib.attrib:
                    weather.wind_intensity = float(weather_attrib.attrib['wind_intensity'])
                if 'sun_azimuth_angle' in weather_attrib.attrib:
                    weather.sun_azimuth_angle = float(weather_attrib.attrib['sun_azimuth_angle'])
                if 'sun_altitude_angle' in weather_attrib.attrib:
                    weather.sun_altitude_angle = float(weather_attrib.attrib['sun_altitude_angle'])
                if 'wetness' in weather_attrib.attrib:
                    weather.wetness = float(weather_attrib.attrib['wetness'])
                if 'fog_distance' in weather_attrib.attrib:
                    weather.fog_distance = float(weather_attrib.attrib['fog_distance'])
                if 'fog_density' in weather_attrib.attrib:
                    weather.fog_density = float(weather_attrib.attrib['fog_density'])

                    '''
                    <route id="0" town="Town01">
                       <weather
                          cloudiness="0"
                          precipitation="0"
                          precipitation_deposits="0"
                          wind_intensity="0"
                          sun_azimuth_angle="0"
                          sun_altitude_angle="70"
                          fog_density="0"
                          fog_distance="0"
                          wetness="0"
                       />

                    '''

        return weather

    @staticmethod
    def check_trigger_position(new_trigger, existing_triggers):  # trigger_id = RouteParser.check_trigger_position(waypoint, existent_triggers)  # waypoint is the trigger transform  that has matched with a waypoint inside our route traj  # existent_triggers is empty for our first iteration
        """
        Check if this trigger position already exists or if it is a new one.
        :param new_trigger:
        :param existing_triggers:
        :return:
        """

        for trigger_id in existing_triggers.keys():
            trigger = existing_triggers[trigger_id]
            dx = trigger['x'] - new_trigger['x']
            dy = trigger['y'] - new_trigger['y']
            distance = math.sqrt(dx * dx + dy * dy)

            dyaw = (trigger['yaw'] - new_trigger['yaw']) % 360

            # TRIGGER_THRESHOLD = 2.0
            # TRIGGER_ANGLE_THRESHOLD = 10

            if distance < TRIGGER_THRESHOLD \
                    and (dyaw < TRIGGER_ANGLE_THRESHOLD or dyaw > (360 - TRIGGER_ANGLE_THRESHOLD)):
                return trigger_id  # if the triger is already in the existing_triggers, it will return the trigger_id else it will return none i.e., implying that there are none matches xP

        return None

    @staticmethod
    def convert_waypoint_float(waypoint):
        """
        Convert waypoint values to float
        """
        waypoint['x'] = float(waypoint['x'])
        waypoint['y'] = float(waypoint['y'])
        waypoint['z'] = float(waypoint['z'])
        waypoint['yaw'] = float(waypoint['yaw'])

    @staticmethod
    def match_world_location_to_route(world_location, route_description):  # (waypoint, trajectory)  # waypoint is the trigger transform and traj is our route
        """
        We match this location to a given route.
            world_location:
            route_description:
        """
        def match_waypoints(waypoint1, wtransform):
            """
            Check if waypoint1 and wtransform are similar
            """

            #print("shiz")  # shiz
            #sys.exit("off")

            dx = float(waypoint1['x']) - wtransform.location.x  # transform x - route x
            dy = float(waypoint1['y']) - wtransform.location.y
            dz = float(waypoint1['z']) - wtransform.location.z
            dpos = math.sqrt(dx * dx + dy * dy + dz * dz)

            dyaw = (float(waypoint1['yaw']) - wtransform.rotation.yaw) % 360

            # TRIGGER_THRESHOLD = 2.0
            # TRIGGER_ANGLE_THRESHOLD = 10

            return dpos < TRIGGER_THRESHOLD \
                and (dyaw < TRIGGER_ANGLE_THRESHOLD or dyaw > (360 - TRIGGER_ANGLE_THRESHOLD))

        # *********** outer function starts here merroooo ***************

        match_position = 0
        # TODO this function can be optimized to run on Log(N) time
        for route_waypoint in route_description:  # in route
            if match_waypoints(world_location, route_waypoint[0]):  # trigger point and route waypoint

                # If above statement is true, it means our trigger point is on a certain waypoint inside our defined densly populated route
                # and the trigger yaw is the same as that particular waypoint's yaw within certain thresholds

                return match_position  # this match position is the index of the waypoint inside our route array for which our particular transform has matched with.
            match_position += 1

        return None

    @staticmethod
    def get_scenario_type(scenario, match_position, trajectory):  #scenario_subtype = RouteParser.get_scenario_type(scenario_name, match_position, trajectory)  # # "scenario_type": "Scenario1", i.e., all scenarios  # this match position is the index of the waypoint inside our route array  # traj is our densly populated route

        """
        Some scenarios have different types depending on the route.
        :param scenario: the scenario name
        :param match_position: the matching position for the scenarion
        :param trajectory: the route trajectory the ego is following
        :return: tag representing this subtype

        Also used to check which are not viable (Such as an scenario
        that triggers when turning but the route doesnt')
        WARNING: These tags are used at:
            - VehicleTurningRoute
            - SignalJunctionCrossingRoute
        and changes to these tags will affect them
        """

        def check_this_waypoint(tuple_wp_turn):
            """
            Decides whether or not the waypoint will define the scenario behavior
            """
            if RoadOption.LANEFOLLOW == tuple_wp_turn[1]:
                return False
            elif RoadOption.CHANGELANELEFT == tuple_wp_turn[1]:
                return False
            elif RoadOption.CHANGELANERIGHT == tuple_wp_turn[1]:
                return False
            return True

        '''

        VOID = -1
        LEFT = 1
        RIGHT = 2
        STRAIGHT = 3
        LANEFOLLOW = 4
        CHANGELANELEFT = 5
        CHANGELANERIGHT = 6

        '''

        # Unused tag for the rest of scenarios,
        # can't be None as they are still valid scenarios
        subtype = 'valid'

        # We have till "scenario_type": "Scenario4" in Town02 in the all towns 1 3 4 JSON file and other actors only in scenario 4 and I guess after scenario 4
        # and I noticed we have scenario 1, 3, 4 in all towns 1 3 4 JSON file, go figure.

        if scenario == 'Scenario4':
            for tuple_wp_turn in trajectory[match_position:]:  # the trigger point that matched with our route at the match position
                if check_this_waypoint(tuple_wp_turn):  # check if the RoadOption of that matched waypoint is a left or right, tag them as S4left, S4right, if neither then tag them as none.
                    if RoadOption.LEFT == tuple_wp_turn[1]:
                        subtype = 'S4left'
                    elif RoadOption.RIGHT == tuple_wp_turn[1]:
                        subtype = 'S4right'
                    else:
                        subtype = None
                    break  # Avoid checking all of them
                subtype = None

        if scenario == 'Scenario7':  # for scenario 7 we have the RoadOption STRAIGHT also available. Tag it as S7opposite
            for tuple_wp_turn in trajectory[match_position:]:
                if check_this_waypoint(tuple_wp_turn):
                    if RoadOption.LEFT == tuple_wp_turn[1]:
                        subtype = 'S7left'
                    elif RoadOption.RIGHT == tuple_wp_turn[1]:
                        subtype = 'S7right'
                    elif RoadOption.STRAIGHT == tuple_wp_turn[1]:
                        subtype = 'S7opposite'
                    else:
                        subtype = None
                    break  # Avoid checking all of them
                subtype = None

        if scenario == 'Scenario8':  # for S8 we only have left
            for tuple_wp_turn in trajectory[match_position:]:
                if check_this_waypoint(tuple_wp_turn):
                    if RoadOption.LEFT == tuple_wp_turn[1]:
                        subtype = 'S8left'
                    else:
                        subtype = None
                    break  # Avoid checking all of them
                subtype = None

        if scenario == 'Scenario9':  # for S9 we only have right
            for tuple_wp_turn in trajectory[match_position:]:
                if check_this_waypoint(tuple_wp_turn):
                    if RoadOption.RIGHT == tuple_wp_turn[1]:
                        subtype = 'S9right'
                    else:
                        subtype = None
                    break  # Avoid checking all of them
                subtype = None

        return subtype

    @staticmethod
    def scan_route_for_scenarios(route_name, trajectory, world_annotations):  # potential_scenarios_definitions, _ = RouteParser.scan_route_for_scenarios(config.town, route, world_annotations)  # Town02  # route as defined in the method above  # world_annotations is the dictionary of the JSON file with town names as keys for each scenario and each key returns the annotations of which positions where the scenarios are going to happen.
        """
        Just returns a plain list of possible scenarios that can happen in this route by matching
        the locations from the scenario into the route description

        :return:  A list of scenario definitions with their correspondent parameters
        """

        # the triggers dictionaries:
        existent_triggers = {}
        # We have a table of IDs and trigger positions associated  # ID meaning -> "scenario_type": "Scenario1"??
        possible_scenarios = {}

        # Keep track of the trigger ids being added
        latest_trigger_id = 0

        for town_name in world_annotations.keys():
            if town_name != route_name:
                continue
                # for the selected town

            scenarios = world_annotations[town_name]  # many possible scenarios mentioned like "scenario_type": "Scenario1"??

            #print(scenarios)  # all scenarios with all their transforms and everything was printed. The Dynamic Language.
            #sys.exit("heff")

            for scenario in scenarios:  # For each existent scenario
                if "scenario_type" not in scenario:  # if a block of code does not have "scenario_type": "Scenario1 or X"
                # if the JSON file does not have a scenario_type object key I guess
                    break  # heff this loop then
                scenario_name = scenario["scenario_type"]  # "scenario_type": "Scenario1"

                #print(scenario_name)  # Scenario1
                #sys.exit("heff")

                for event in scenario["available_event_configurations"]:  # for each scenario there is "available_event_configurations": [ in which there are numerous transforms and other vehicles and front and side and back transforms etc
                    waypoint = event['transform']  # trigger point of this scenario  # just noticed in some JSON available_event_configurations we have other vehicles with left or right sub fields which have front left &/or right locs and a transform underneath them as a trigger point I presume
                    RouteParser.convert_waypoint_float(waypoint)
                    # We match trigger point to the  route, now we need to check if the route affects
                    match_position = RouteParser.match_world_location_to_route(
                        waypoint, trajectory)  # waypoint is the trigger transform and traj is our route

                    # return match_position  # this match position is the index of the waypoint inside our route array for which our particular transform has matched with.

                    if match_position is not None:
                        # We match a location for this scenario, create a scenario object so this scenario
                        # can be instantiated later

                        if 'other_actors' in event:
                            other_vehicles = event['other_actors']  # all the other_actors with front, left, right locations in this
                        else:
                            other_vehicles = None
                        scenario_subtype = RouteParser.get_scenario_type(scenario_name, match_position,  # # "scenario_type": "Scenario1"  # this match position is the index of the waypoint inside our route array  # traj is our densly populated route
                                                                         trajectory)

                        # return subtype i.e., S4left, S4right, S8left, S9right, S7opposite (RoadOption = straight) etc

                        if scenario_subtype is None:
                            continue  # heff it
                        scenario_description = {
                            'name': scenario_name,  # all the scenarios we are parsing
                            'other_actors': other_vehicles,  # all the transforms inside the other vehicles i.e., left right front
                            'trigger_position': waypoint,  # waypoint is the trigger transform  that has matched with a waypoint inside our route traj
                            'scenario_type': scenario_subtype,  # scenario_name = scenario["scenario_type"]  # "scenario_type": "Scenario1"  # some scenarios have route dependent configs, S4left, etc
                        }

                        trigger_id = RouteParser.check_trigger_position(waypoint, existent_triggers)  # waypoint is the trigger transform  that has matched with a waypoint inside our route traj  # existent_triggers is empty for our first iteration

                        #return trigger_id  # if the triger is already in the existing_triggers, it will return the trigger_id else it will return none i.e., implying that there are none matches xP

                        if trigger_id is None:
                            # This trigger does not exist create a new reference on existent triggers
                            existent_triggers.update({latest_trigger_id: waypoint})  # latest_trigger_id = 0 initially
                            # Update a reference for this trigger on the possible scenarios

                            possible_scenarios.update({latest_trigger_id: []})  # latest_trigger_id = 0 initially

                            trigger_id = latest_trigger_id  # so for first trigger that was not already in the dictionary existent_triggers, is initially give an id of 0 for the initial very first one

                            # Increment the latest trigger
                            latest_trigger_id += 1  # until we catch the next trigger id cx it is not included in our existent_triggers dictionary yet

                        possible_scenarios[trigger_id].append(scenario_description)  # so we have a whole scenario for that particular trigger location as defined above and we do these for all the trigger points defined to create all these scenarios

                        # so now for the trigger id on which we caught the trigger not being matched, we append the possible scenarios dictionary on that particular id wiht the whole scenario description dictionary

                        '''
                        scenario_description = {
                            'name': scenario_name,  # all the scenarios we are parsing
                            'other_actors': other_vehicles,  # all the transforms inside the other vehicles i.e., left right front
                            'trigger_position': waypoint,  # waypoint is the trigger transform  that has matched with a waypoint inside our route traj
                            'scenario_type': scenario_subtype,  # scenario_name = scenario["scenario_type"]  # "scenario_type": "Scenario1"  # some scenarios have route dependent configs, S4left, etc
                        }
                        '''

        return possible_scenarios, existent_triggers  # existent_triggers have all the trigger points inside the, and possible scenarios have the complete description of those scenarios from all towns 1 3 4 JSOn file compared to our route


import sys
from collections import deque
input = sys.stdin.readline
dr = [-1, 1, 0, 0]
dc = [0, 0, -1, 1]

R, C = map(int, input().split())
MAP = [list(map(int, input().split())) for _ in range(R)]

air = deque([[0, 0]])
q = deque()

visited = [[0] * C for _ in range(R)]
visited[0][0] = 1

# 처음부터 공기에 노출된 치즈 표면 저장
while air:
    ar, ac = air.popleft()
    for d in range(4):
        nar, nac = ar + dr[d], ac + dc[d]
        # 범위를 벗어나는 경우
        if nar < 0 or nar >= R or nac < 0 or nac >= C:
            continue
        # 방문한 적이 있는 경우
        if visited[nar][nac]:
            continue
        visited[nar][nac] = 1
        # 공기에 노출된 치즈 표면
        if MAP[nar][nac]:
            q.append([nar, nac])
        # 공기
        else:
            air.append([nar, nac])

t = 1
cheese = len(q)
nq = deque()
# 치즈가 녹는 과정
while q:
    r, c = q.popleft()
    for d in range(4):
        nr, nc = r + dr[d], c + dc[d]
        # 범위를 벗어나는 경우
        if nr < 0 or nr >= R or nc < 0 or nc >= C:
            continue
        # 방문한 적이 있는 경우
        if visited[nr][nc]:
            continue
        visited[nr][nc] = 1
        # 다음에 녹을 치즈
        if MAP[nr][nc]:
            nq.append([nr, nc])
        # 구멍에 의한 추가 공기
        else:
            q.append([nr, nc])
    # 다음에 더 녹을 치즈 존재여부 확인
    if len(q) == 0 and len(nq):
        t += 1
        q = nq
        cheese = len(q)
        nq = deque()

print('{}\n{}'.format(t, cheese))


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

# In[ ]:

import pandas as pd
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import GradientBoostingClassifier, AdaBoostClassifier
from sklearn.metrics import recall_score

# In[ ]:

df = pd.read_csv('./datasets/data_all.csv')

# In[ ]:

X = df['content']
y = df['subreddit']

# In[ ]:

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

# In[ ]:

vects = [CountVectorizer(), TfidfVectorizer()]
models = [LogisticRegression(), KNeighborsClassifier(),
          MultinomialNB(), RandomForestClassifier(random_state=42),
          AdaBoostClassifier(random_state=42),
          GradientBoostingClassifier(random_state=42),
          SVC(random_state=42)]

# In[ ]:

pipes = []
for vect in vects:
    for model in models:
        pipe = Pipeline([
        ('vect', vect),
        ('model', model)])
        pipes.append(pipe)

# In[ ]:

params_vect = {'CountVectorizer': {'vect__stop_words': [None, 'english'],
                                   'vect__ngram_range': [(1,1), (1,2)]},
               'TfidfVectorizer': {'vect__stop_words': [None, 'english'],
                                   'vect__ngram_range': [(1,1), (1,2)]}}

# In[ ]:

params_model = {'LogisticRegression': {'model__penalty': ['l1', 'l2'],
                                       'model__C': np.logspace(-3, 3, 10)},
                'KNeighborsClassifier': {'model__n_neighbors': [5, 7, 15],
                                         'model__weights': ['uniform', 'distance']},
                'MultinomialNB': {},
                'RandomForestClassifier': {'model__n_estimators': [100, 150, 200],
                                           'model__max_depth': [None, 2, 4]},
                'AdaBoostClassifier': {'model__n_estimators': [100, 150, 200]},
                'GradientBoostingClassifier': {'model__n_estimators': [100, 150, 200]},
                'SVC': {'model__C': np.logspace(-2, 2, 5),
                        'model__gamma': np.logspace(-4, 0, 5)}
               }

# In[ ]:

df = pd.DataFrame(columns=['Vectorizer', 'Classifier',
                           'best_params', 'train_recall', 'test_recall',
                           'train_accuracy', 'test_accuracy'])

# In[ ]:

for pipe in pipes:
    Vectorizer = str(pipe.steps[0][1]).split('(')[0]
    Classifier = str(pipe.steps[1][1]).split('(')[0]

    print('\nGrid search using {} and {} ...\n'.format(Vectorizer, Classifier))

    params = {**params_vect[Vectorizer], **params_model[Classifier]}

    grid = GridSearchCV(pipe,
                    param_grid=params,
                    cv = 5,
                    scoring = 'accuracy',
                    verbose = 1,
                    n_jobs = -1,
                    return_train_score = True)

    grid.fit(X_train, y_train);

    output = {}
    output['Vectorizer'] = Vectorizer
    output['Classifier'] = Classifier
    output['best_params'] = grid.best_params_
    output['train_accuracy'] = grid.best_score_
    output['test_accuracy'] = grid.score(X_test, y_test)
    output['train_recall'] = recall_score(y_train, grid.predict(X_train))
    output['test_recall'] = recall_score(y_test, grid.predict(X_test))

    df = df.append(output, ignore_index=True)

    df.to_csv('./datasets/results.csv', index=False)


import datetime
import database as d
def sumafecha(fecha,dias_repeticion):

	fecha      = fecha
	Date       = datetime.datetime.strptime(fecha, "%Y-%m-%d")
	EndDate    = str(Date + datetime.timedelta(days=dias_repeticion))[0:10]
	a          = datetime.datetime.strptime(EndDate, "%Y-%m-%d").date()
	fechaactual= datetime.datetime.strptime(str(datetime.datetime.today())[0:10], "%Y-%m-%d").date()
	return int((a-fechaactual).days)

def plan_mantto(tipo_medicion,nivel_medicion,fecha,id_usuario):

	where_mantto  = " where medicion="+tipo_medicion+" and evaluacion="+ str(nivel_medicion) + ""
	mantto        = d.Database('plan_mantto_general','','dias_repeticion')
	row_mantto    = mantto.get(where_mantto)
	if(row_mantto==True):
		dias= mantto.rows[0]['dias_repeticion']

		atrasoMedicion='0'
		sumfec=sumafecha(fecha,dias)
		if(sumfec<0):
			atrasoMedicion='1'

		#print str(id_usuario)+'*'+str(atrasoMedicion)
		return  atrasoMedicion
	else:
		return false;


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import glob
import itertools
import tempfile
from collections import Counter

import numpy as np
import tensorflow as tf
from pathlib import Path

from tensorflow.lite.python.op_hint import convert_op_hints_to_stubs
from tensorflow.python.framework import test_util
from tensorflow.python.platform import test
from tensorflow.python.tools import optimize_for_inference_lib

# Number of steps to train model.
TRAIN_STEPS = 100
TEST_SAMPLES = 5

CONFIG = tf.ConfigProto(device_count={"GPU": 0})

UNK_ID = 0
EOS_ID = 2
UNK = "<unk>"
SOS = "<s>"
EOS = '</s>'
DIR = "data/"

max_seq_len = 150
EMBED_SIZE = 64
DICT_SIZE = 10000

class BatchInput:
    """"""

    def __init__(self, data: np.array, batch_size: int, shuffle: bool):
        """Constructor for BatchInput"""
        self.data = data
        self.batch_cursor = 0
        self.batch_size = batch_size

        if shuffle:
            np.random.shuffle(data)

    def next_batch(self):
        self.batch_cursor += self.batch_size
        return self.data[self.batch_cursor - self.batch_size:self.batch_cursor]

class UnidirectionalSequenceLstmTest(test_util.TensorFlowTestCase):

    def setUp(self):
        tf.reset_default_graph()

        self.train_data = load_data_matrix(DIR + "data.csv")

        self.vocab_len = np.max(self.train_data)+1

        # Define constants
        # Unrolled through 100 time steps
        self.time_steps = 100
        # Learning rate for Adam optimizer
        self.learning_rate = 0.001
        # MNIST is meant to be classified in 10 classes(0-9).
        self.n_classes = 3
        # Batch size
        self.batch_size = 64
        # Lstm Units.
        self.num_units = 128

    def buildLstmLayer(self):
        return tf.keras.layers.StackedRNNCells([
            tf.lite.experimental.nn.TFLiteLSTMCell(
                self.num_units, use_peepholes=True, forget_bias=1.0, name="rnn1"),
            tf.lite.experimental.nn.TFLiteLSTMCell(
                self.num_units, num_proj=8, forget_bias=1.0, name="rnn2"),
            tf.lite.experimental.nn.TFLiteLSTMCell(
                self.num_units // 2,
                use_peepholes=True,
                num_proj=8,
                forget_bias=0,
                name="rnn3"),
            tf.lite.experimental.nn.TFLiteLSTMCell(
                self.num_units, forget_bias=1.0, name="rnn4")
        ])

    def buildModel(self, lstm_layer, is_dynamic_rnn):
        enc_embedding = tf.get_variable("emb", [self.vocab_len, EMBED_SIZE], tf.float32)

        # Weights and biases for output softmax layer.
        out_weights = tf.Variable(
            tf.random_normal([self.num_units, self.n_classes]))
        out_bias = tf.Variable(tf.random_normal([self.n_classes]))

        # input text placeholder
        sentences = tf.placeholder(
            tf.int32, [None, self.time_steps], name="INPUT_TEXT")

        lengths2 = tf.placeholder(tf.int32, [None], name="INPUT_LENGTH")

        encoder_emb_inp = tf.nn.embedding_lookup(enc_embedding, sentences)

        # x is shaped [batch_size,time_steps,num_inputs]
        if is_dynamic_rnn:
            lstm_input = tf.transpose(encoder_emb_inp, perm=[1, 0, 2])
            # outputs, _ = tf.lite.experimental.nn.dynamic_rnn(
            #     lstm_layer, lstm_input, sequence_length=lengths, dtype="float32")
            outputs, _ = tf.lite.experimental.nn.dynamic_rnn(
                lstm_layer, lstm_input, dtype="float32")

            batch_size = tf.shape(outputs)[1]
            # lengths = tf.minimum(lengths, tf.tile([self.time_steps],[batch_size]))
            # lengths = tf.minimum(lengths, tf.constant([self.time_steps], dtype=tf.int32))
            # lengths2 = tf.maximum(lengths, tf.constant([200], dtype=tf.int32))
            lengths = tf.minimum(lengths2, self.time_steps)
            # lengths = tf.reduce_min(tf.stack([lengths, tf.tile([self.time_steps], [batch_size])]), axis=0)
            outputs = tf.gather_nd(outputs, tf.transpose(tf.stack([lengths-1, tf.range(batch_size)])))
            # outputs = tf.transpose(outputs, perm=[1, 0, 2])

        # outputs = tf.unstack(outputs, axis=0)
        else:
            lstm_input = tf.unstack(encoder_emb_inp, self.time_steps, 1)
            outputs, _ = tf.nn.static_rnn(lstm_layer, lstm_input,  dtype="float32")
            outputs = outputs[-1]
            # outputs, _ = tf.nn.static_rnn(lstm_layer, lstm_input, sequence_length=lengths,  dtype="float32")

        # outputs = tf.transpose(outputs, [1, 0, 2])
        #
        # # outputs is [batch_size, L, N] where L is the maximal sequence length and N
        # # the number of nodes in the last layer.
        # mask = tf.tile(
        #     tf.expand_dims(tf.sequence_mask(lengths, tf.shape(outputs)[1]), 2),
        #     [1, 1, tf.shape(outputs)[2]])
        # zero_outside = tf.where(mask, outputs, tf.zeros_like(outputs))
        #
        # lstm_out = tf.reduce_sum(zero_outside, axis=1)

    # Compute logits by multiplying outputs[-1] of shape [batch_size,num_units]
        # by the softmax layer's out_weight of shape [num_units,n_classes]
        # plus out_bias
        # TODO: change to last_encoder_state !!
        prediction = tf.matmul(outputs, out_weights) + out_bias
        output_class = tf.nn.softmax(prediction, name="OUTPUT_CLASS")

        return sentences, lengths2, prediction, output_class

    def trainModel(self, sentences, lengths, prediction, output_class, sess):
        batch_input = BatchInput(self.train_data, self.batch_size, True)

        # input label placeholder
        labels = tf.placeholder(tf.int32, [None])

        y = tf.one_hot(labels, 3)

        # Loss function
        loss = tf.reduce_mean(
            tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y))
        # Optimization
        opt = tf.train.AdamOptimizer(
            learning_rate=self.learning_rate).minimize(loss)

        # Initialize variables
        init = tf.global_variables_initializer()
        sess.run(init)
        for _ in range(TRAIN_STEPS):
            batch = batch_input.next_batch()

            batch_lengths = batch[:, 0]
            batch_sentences = batch[:, 1:self.time_steps + 1]
            batch_labels = batch[:, max_seq_len + 1]

            sess.run(opt, feed_dict={sentences: batch_sentences, lengths: batch_lengths, labels: batch_labels})

    def saveAndRestoreModel(self, lstm_layer, sess, saver, is_dynamic_rnn):
        model_dir = tempfile.mkdtemp()
        saver.save(sess, model_dir)

        # Reset the graph.
        tf.reset_default_graph()
        sentences, lengths, prediction, output_class = self.buildModel(
            lstm_layer, is_dynamic_rnn)

        new_sess = tf.Session(config=CONFIG)
        saver = tf.train.Saver()
        saver.restore(new_sess, model_dir)
        return sentences, lengths, prediction, output_class, new_sess

    def getInferenceResult(self, sentences, lengths, output_class, sess):
        # TODO: change to eval (may be)
        batch = BatchInput(self.train_data, self.batch_size, True).next_batch()

        batch_lengths = batch[0:TEST_SAMPLES, 0]
        batch_sentences = batch[0:TEST_SAMPLES, 1:self.time_steps + 1]

        expected_output = sess.run(output_class, feed_dict={sentences: batch_sentences, lengths: batch_lengths})
        frozen_graph = tf.graph_util.convert_variables_to_constants(
            sess, sess.graph_def, [output_class.op.name])
        return [batch_sentences, batch_lengths], expected_output, frozen_graph

    def tfliteInvoke(self, graph, test_inputs, outputs):
        tf.reset_default_graph()

        # input text placeholder
        sentences = tf.placeholder(
            tf.int32, [TEST_SAMPLES, self.time_steps], name="INPUT_TEXT_LITE")

        lengths = tf.placeholder(tf.int32, [TEST_SAMPLES], name="INPUT_LENGTH_LITE")

        tf.import_graph_def(graph, name="", input_map={"INPUT_TEXT": sentences, "INPUT_LENGTH": lengths})
        with tf.Session() as sess:
            curr = sess.graph_def
            curr = convert_op_hints_to_stubs(graph_def=curr)

        curr = optimize_for_inference_lib.optimize_for_inference(
            curr, ["INPUT_TEXT_LITE", "INPUT_LENGTH_LITE"], ["OUTPUT_CLASS"],
            [tf.int32.as_datatype_enum, tf.int32.as_datatype_enum])

        converter = tf.lite.TFLiteConverter(curr, [sentences, lengths], [outputs])
        tflite = converter.convert()
        interpreter = tf.lite.Interpreter(model_content=tflite)

        try:
            interpreter.allocate_tensors()
        except ValueError:
            assert False

        # first input (sentences)
        input_index = (interpreter.get_input_details()[0]["index"])
        interpreter.set_tensor(input_index, test_inputs[0])

        # second input (lengths)
        input_index = (interpreter.get_input_details()[1]["index"])
        interpreter.set_tensor(input_index, test_inputs[1])

        interpreter.invoke()
        output_index = (interpreter.get_output_details()[0]["index"])
        result = interpreter.get_tensor(output_index)
        # Reset all variables so it will not pollute other inferences.
        interpreter.reset_all_variables()
        return result

    def testStaticRnnMultiRnnCell(self):
        sess = tf.Session(config=CONFIG)

        sentences, lengths, prediction, output_class = self.buildModel(
            self.buildLstmLayer(), is_dynamic_rnn=False)
        self.trainModel(sentences, lengths, prediction, output_class, sess)

        saver = tf.train.Saver()
        sentences, lengths, prediction, output_class, new_sess = self.saveAndRestoreModel(
            self.buildLstmLayer(), sess, saver, is_dynamic_rnn=False)

        test_inputs, expected_output, frozen_graph = self.getInferenceResult(
            sentences, lengths, output_class, new_sess)

        result = self.tfliteInvoke(frozen_graph, test_inputs, output_class)
        self.assertTrue(np.allclose(expected_output, result, rtol=1e-6, atol=1e-2))

    @test_util.enable_control_flow_v2
    def testDynamicRnnMultiRnnCell(self):
        sess = tf.Session(config=CONFIG)

        sentences, lengths, prediction, output_class = self.buildModel(
            self.buildLstmLayer(), is_dynamic_rnn=True)
        self.trainModel(sentences, lengths, prediction, output_class, sess)

        saver = tf.train.Saver()

        sentences, lengths, prediction, output_class, new_sess = self.saveAndRestoreModel(
            self.buildLstmLayer(), sess, saver, is_dynamic_rnn=True)

        test_inputs, expected_output, frozen_graph = self.getInferenceResult(
            sentences, lengths, output_class, new_sess)

        result = self.tfliteInvoke(frozen_graph, test_inputs, output_class)
        print(expected_output, result)
        self.assertTrue(np.allclose(expected_output, result, rtol=1e-6, atol=1e-2))

def load_data_matrix(file_name: str) -> np.array:
    return np.loadtxt(file_name, dtype=np.int32, delimiter=",")

if __name__ == "__main__":
    test.main()


import os
import json
import uuid
import boto3
from porper.controllers.auth_controller import AuthController

class CognitoAuthController(AuthController):

    def __init__(self, permission_connection=None, loglevel="INFO"):

        AuthController.__init__(self, permission_connection, loglevel)

        self.client = boto3.client('cognito-idp')

    def authenticate(self, params):

        cognito_access_token = params['cognito_access_token']

        # get the tokens to see if the given code is valid
        self.logger.debug("cognito_access_token [{}]".format(cognito_access_token))
        response = self.client.get_user(AccessToken=cognito_access_token)
        self.logger.debug(response)
        """{
                'Username': '4de37a8c-c2c0-4cc4-9fbb-c578139fb861',
                'UserAttributes': [
                    {'Name': 'sub', 'Value': '4de37a8c-c2c0-4cc4-9fbb-c578139fb861'},
                    {'Name': 'given_name', 'Value': 'TestA'},
                    {'Name': 'family_name', 'Value': 'TestB'},
                    {'Name': 'email', 'Value': 'abay.radhakrishnan@sungardas.com'}
                ],
                'ResponseMetadata': {
                    'RequestId': '06ecec11-6187-11e9-aad6-45ac547975c8',
                    'HTTPStatusCode': 200,
                    'HTTPHeaders': {
                        'date': 'Thu, 18 Apr 2019 03:06:57 GMT',
                        'content-type': 'application/x-amz-json-1.1',
                        'content-length': '269',
                        'connection': 'keep-alive',
                        'x-amzn-requestid': '06ecec11-6187-11e9-aad6-45ac547975c8'
                    },
                    'RetryAttempts': 0
                }
            }
        """
        if not response.get('Username'):
            raise Exception("unauthorized")

        # now save the user info & tokens
        user_id = response.get('Username')
        email = [attr for attr in response.get('UserAttributes') if attr['Name'] == 'email'][0]['Value']
        family_name = [attr for attr in response.get('UserAttributes') if attr['Name'] == 'family_name'][0]['Value']
        given_name = [attr for attr in response.get('UserAttributes') if attr['Name'] == 'given_name'][0]['Value']
        customer_id = [attr for attr in response.get('UserAttributes') if attr['Name'] == 'custom:customer_id'][0]['Value']

        auth_params = {
            'user_id': user_id,
            'email': email,
            'family_name': family_name,
            'given_name': given_name,
            'customer_id': customer_id,
            'auth_type': 'cognito',
            'access_token': cognito_access_token,
            'refresh_token': cognito_access_token
        }
        auth_params['name'] = "{} {}".format(given_name, family_name)
        user_info = AuthController.authenticate(self, auth_params)

        # return the cognito_access_token if all completed successfully
        # user_info = {
        #     'user_id': user_id,
        #     'email': email,
        #     'family_name': family_name,
        #     'given_name': given_name,
        #     'customer_id': customer_id,
        #     'access_token': cognito_access_token,
        # }
        # user_info['groups'] = AuthController.find_groups(self, user_id)
        return user_info


from django.urls import path
from . import views

urlpatterns = [
    path('api-item/', views.Home.as_view()),
    path('api-item/<str:pk>/', views.Detail.as_view()),
    path('<str:pk>/add_to_cart/', views.add_to_cart),
    path('api-cart/', views.cart_view),
    path('<str:pk>/rmone_from_cart/', views.remove_one_item_from_cart),
    path('<str:pk>/rm_from_cart/', views.remove_from_cart),
    path('api-search/', views.PostSearch.as_view()),
    path('wish/', views.WishList().as_view()),
    path('<str:pk>/wish/', views.add_wish),
]


import pygame
import sys
from pygame.sprite import Group
from rain_function import create_rains
from rain_function import update_rains

class Screen_setting():
    screen_width = 1000
    screen_height = 800
    screen_bg_color = (52, 52, 52)

# class Rain(Sprite):
#     def __init__(self, screen):
#         super().__init__()
#         self.screen = screen
#         self.image = pygame.image.load('image/rain.png')
#         self.rect = self.image.get_rect()
#         self.rect.x = self.rect.width
#         self.rect.y = self.rect.height
#
#     def blitme(self):
#         self.screen.blit(self.image, self.rect)

# def get_number_rain_x(screen_width, rain_width):
#     available_space_x = screen_width - 2 * rain_width
#     number_rain_x = int(available_space_x / 2 * rain_width)
#     return number_rain_x
#
#
# def get_number_rain_y(screen_height, rain_height):
#     available_space_y = screen_height - 2 * rain_height
#     number_rain_y = int(available_space_y / 2 * rain_height)
#     return number_rain_y
#
#
# def create_rain(screen, rains, rain_list_numger, rain_row_number):
#     rain = Rain(screen)
#     rain_width = rain.rect.width
#     rain_height = rain.rect.height
#     rain.x = rain_width + 2 * rain_width * rain_row_number
#     rain.y = rain_height + 2 * rain_height * rain_list_numger
#     rain.rect.x = rain.x
#     rain.rect.y = rain.y
#     rains.add(rain)
#
#
# def create_rains(screen, screen_width, screen_height, rains):
#     rain = Rain(screen)
#     number_rain_x = get_number_rain_x(screen_width, rain.rect.width)
#     number_rain_y = get_number_rain_y(screen_height, rain.rect.height)
#     for number_y_rain in range(number_rain_y):
#         for number_x_rain in range(number_rain_x):
#             create_rain(screen, rains, number_y_rain,number_x_rain)

def rain_run():
    pygame.init()
    screen = pygame.display.set_mode(
        (Screen_setting.screen_width, Screen_setting.screen_height))
    pygame.display.set_caption('Rain')

    rains = Group()
    create_rains(screen, Screen_setting.screen_width,Screen_setting.screen_height, rains)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

        screen.fill(Screen_setting.screen_bg_color)
        rains.draw(screen)
        update_rains(screen, rains)

        pygame.display.flip()

rain_run()


import csv
import os
from django.core.management.base import BaseCommand
from reviews.models import Review
import sqlite3
# from django.db import connection
from django.conf import settings

class Command(BaseCommand):
    help = 'The Zen of Python'

    def handle(self, *args, **options):
        list_files = {
            'users': 'reviews_user',
            'category': 'reviews_categorie', 'genre': 'reviews_genre',
            'titles': 'reviews_title', 'genre_title': 'reviews_title_genre',
            'review': 'reviews', 'comments': 'reviews_comment'
        }
        dir_files = os.path.join(settings.STATICFILES_DIRS[0], "data")
        print(dir_files)
        # for file_name in list_files:
        file_name = list(list_files.keys())[6] + '.csv'
        file_name = os.path.join(dir_files, file_name)
        one_file = open(file_name)
        reader = csv.reader(one_file)
        conn = sqlite3.connect('db.sqlite3')
        cursor = conn.cursor()
        for row in reader:
            if row[0].isnumeric():
                row[2] = row[2].replace("'", ".")
                title_id = Review.objects.get(id=row[1]).title.id
                query = f"INSERT into {list_files['comments']} values ({row[0]}, '{row[2]}', '{row[4]}', {row[3]}, {row[1]}, {title_id})"
                cursor.execute(query)
            else:
                print(row)
        conn.commit()
        conn.close()
        one_file.close()


import pyrealsense2
from cv2 import cv2
import numpy as np
ImageNumber = 82

#change the following three lines for testing
image = cv2.imread(f".\\{ImageNumber}.jpg", cv2.IMREAD_UNCHANGED ) #path to rgb image
depthimg = np.array(cv2.imread(f".\\d{ImageNumber}.png", cv2.IMREAD_UNCHANGED )) #path to depth image
label_txt = "82.txt" # path to labeled txt

#depthimg = cv2.medianBlur(depthimg,5)
print("Image Reolution: ", image.shape[0], " ", image.shape[1]," ", image.shape[2])
print("Depth Reolution: ", depthimg.shape)

def get_pix(shape, li):
    xw = shape[1]
    yh = shape[0]
    x_cen = int(li[1]* xw)
    y_cen = int(li[2]* yh)
    return [x_cen, y_cen]

f=open(label_txt, "r")
l = f.readlines()
red_list = []
blue_list = []
for line in l:
    t = line.split(" ")
    t[4] = t[4].strip("\n")
    tp = [float(a) for a in t]
    if tp[0] == 0.0:
        red_list.append(tp)
    elif tp[0] == 1.0:
        blue_list.append(tp)
f.close()

def draw_dist(l):
    for i in l:
        coord = get_pix(depthimg.shape, i)
        cv2.putText(image,f'{depthimg[coord[1]][coord[0]]/10}cm', (coord[0],coord[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,255,0), 1)
        cv2.circle(image, (coord[0],coord[1]), radius=1, color=(0,0,255), thickness=-1)

        print(f"blue cone center coord is: {coord}")
        print("printing depthimg[coord[1]-5:coord[1]+5,coord[0]-5:coord[0]+5]: ")
        print(depthimg[coord[1]-5:coord[1]+5,coord[0]-5:coord[0]+5])
draw_dist(red_list)
#draw_dist(blue_list)

while True:
    cv2.imshow("image",image)
    key = cv2.waitKey(1)
    if key & 0xFF == ord('q') or key == 27:
        cv2.destroyAllWindows()
        break


import re
import json

file = 'class.txt'

# Dst-Site-Prefix: 10.225.76.164/32    DSCP: default [0] Traffic class id:59827542
p1 = re.compile(r'Dst-Site-Prefix:\s*(?P<dst_site_prefix>\S+)\s*DSCP:\s*(?P<dscp>\S*)')

#  Clock Time:                 14:16:10 (CDT) 08/05/2019
p2 = re.compile(r'\S*Clock\s*Time:\s*(?P<clock_time>.*)')

#  TC Learned:                 4w2d ago
p3 = re.compile(r'\S*TC\s*Learned:\s*(?P<tc_learned>.*)')

#  Present State:              CONTROLLED
p4 = re.compile(r'\S*Present\s*State:\s*(?P<present_state>.*)')

#  Current Performance Status: in-policy
p5 = re.compile(r'\S*Current\s*Performance\s*Status:\s*(?P<current_performance_status>.*)')

#  Current Service Provider:   ISP2 since 09:39:28
p6 =   re.compile(r'\S*Current\s*Service\s*Provider:\s*(?P<current_service_provider>.*)')

#  Previous Service Provider:  ISP1 pfr-label: 0:0 | 0:0 [0x0] for 180 sec
p7 = re.compile(r'\S*Previous\s*Service\s*Provider:\s*(?P<previous_service_provider>.*)')

#  BW Used:                    0 Kbps
p8 = re.compile(r'\S*BW\s*Used:\s*(?P<bw_used>.*)')

#  Present WAN interface:      Tunnel200 in Border 10.1.0.104
p9 = re.compile(r'\S*Present\s*WAN\s*interface:\s*(?P<present_wan_interface>\S*)\s*in\sBorder\s(?P<border>.*)')

#  Present Channel (primary):  12488652 ISP2 pfr-label:0:0 | 0:0 [0x0]
p10 = re.compile(r'\S*Present\s*Channel\s*\(primary\):\s*(?P<present_channel>\d+)')

#  Backup Channel:             12488653 ISP1 pfr-label:0:0 | 0:0 [0x0]
p11 = re.compile(r'\S*Backup\s*Channel:\s*(?P<backup_channel>\d+)')

#  Destination Site ID bitmap: 0
p12 = re.compile(r'\S*Destination\s*Site\s*ID\s*bitmap:\s*(?P<dst_site_id_bit>.*)')

#  Destination Site ID:        10.50.0.84
p13 = re.compile(r'\S*Destination\s*Site\s*ID:\s*(?P<dst_site_id>.*)')

#  Class-Sequence in use:      20
p14 = re.compile(r'\S*Class-Sequence\s*in\s*use:\s*(?P<class_sequence_in_use>.*)')

#  Class Name:                 BEST_EFFORT using policy User-defined
p15 = re.compile(r'.*\S*Class\s*Name:\s*(?P<class_name>\S*)')
    #priority 2 packet-loss-rate threshold 40.0 percent
    #priority 2 byte-loss-rate threshold 40.0 percent
p16 = re.compile(r'(?P<priority>priority\s[1-9])\s*(?P<detail>\S*)\s*(?P<type>\S*)\s*(?P<value>.*)')

#  BW Updated:                 00:00:26 ago
p17 = re.compile(r'\S*BW\s*Updated:\s*(?P<bw_updated>.*)')

#  Reason for Latest Route Change:    Backup to Primary path preference transition

#  Route Change History:
p18 = re.compile(r'Date and Time')

#  1:  04:36:42 (CDT) 08/05/19   ISP1(0:0|0:0)/10.1.0.101/Tu100 (Ch:12488653)       ISP2(0:0|0:0)/10.1.0.104/Tu200 (Ch:12488652)       Backup to Primary path preference transition
#  2:  04:33:42 (CDT) 08/05/19   ISP2(0:0|0:0)/10.1.0.104/Tu200 (Ch:12488652)       ISP1(0:0|0:0)/10.1.0.101/Tu100 (Ch:12488653)       Unreachable
#  3:  02:23:41 (CDT) 08/05/19   ISP1(0:0|0:0)/10.1.0.101/Tu100 (Ch:12488653)       ISP2(0:0|0:0)/10.1.0.104/Tu200 (Ch:12488652)       Backup to Primary path preference transition
#  4:  02:20:39 (CDT) 08/05/19   ISP2(0:0|0:0)/10.1.0.104/Tu200 (Ch:12488652)       ISP1(0:0|0:0)/10.1.0.101/Tu100 (Ch:12488653)       Unreachable
#  5:  02:10:21 (CDT) 08/03/19   ISP1(0:0|0:0)/10.1.0.101/Tu100 (Ch:12488653)       ISP2(0:0|0:0)/10.1.0.104/Tu200 (Ch:12488652)       Backup to Primary path preference transition
p19 = re.compile(r'\s*(\d:)\s*(?P<date>\S*\s*\S*\s*\S*)\s*(?P<previous_exit>\S*\s*\S*)\s*(?P<current_exit>\S*\s*\S*)\s*(?P<reason>.*)')

# 0 or 1 flags
route_change_flag = 0

# Init vars
parsed_dict = {}
class_name = ''

out = open(file, "r")

for line in out:
    if len(line.strip()) == 0: continue

    line = line.strip()

    # Dst-Site-Prefix: 10.225.76.164/32    DSCP: default [0] Traffic class id:59827542
    m = p1.match(line)
    if m:
        dst_site_prefix = m.group('dst_site_prefix')
        dst_site_dscp = m.group('dscp')

        if dst_site_prefix not in parsed_dict:
            parsed_dict[dst_site_prefix] = {}

        if dst_site_dscp not in parsed_dict[dst_site_prefix]:
            parsed_dict[dst_site_prefix][dst_site_dscp] = {}
            traffic_classes_dict = parsed_dict[dst_site_prefix][dst_site_dscp]

        # Init keys
        traffic_classes_dict['clock_time'] = ''
        traffic_classes_dict['tc_learned'] = ''
        traffic_classes_dict['present_state'] = ''
        traffic_classes_dict['current_performance_status'] = ''
        traffic_classes_dict['current_service_provider'] = ''
        traffic_classes_dict['previous_service_provider'] = ''
        traffic_classes_dict['bandwidth'] = {}
        traffic_classes_dict['present_wan_interface'] = {}
        traffic_classes_dict['channel'] = {}
        traffic_classes_dict['dst_site_id_bit'] = ''
        traffic_classes_dict['dst_site_id'] = ''
        traffic_classes_dict['class_sequence_in_use'] = ''
        traffic_classes_dict['class_name'] = {}
        traffic_classes_dict['route_change_history'] = []
        route_change_flag = 0
        class_name = ''
        continue

    #  Clock Time:                 14:16:10 (CDT) 08/05/2019
    m = p2.match(line)
    if m:
        traffic_classes_dict['clock_time'] = m.group('clock_time')
        continue

    #  TC Learned:                 4w2d ago
    m = p3.match(line)
    if m:
        traffic_classes_dict['tc_learned'] = m.group('tc_learned')
        continue
    #  Present State:              CONTROLLED
    m = p4.match(line)

    if m:
        traffic_classes_dict['present_state'] = m.group('present_state')
        continue
    #  Current Performance Status: in-policy
    m = p5.match(line)

    if m:
        traffic_classes_dict['current_performance_status'] = m.group('current_performance_status')
        continue
    #  Current Service Provider:   ISP2 since 09:39:28
    m = p6.match(line)

    if m:
        traffic_classes_dict['current_service_provider'] = m.group('current_service_provider')
        continue
    #  Previous Service Provider:  ISP1 pfr-label: 0:0 | 0:0 [0x0] for 180 sec
    m = p7.match(line)

    if m:
        traffic_classes_dict['previous_service_provider'] = m.group('previous_service_provider')
        continue
    #  BW Used:                    0 Kbps
    m = p8.match(line)

    if m:
        traffic_classes_dict['bandwidth']['used'] = m.group('bw_used')
        continue

    #  BW Updated:                 00:00:26 ago
    m = p17.match(line)
    if m:
        traffic_classes_dict['bandwidth']['updated'] = m.group('bw_updated')
        continue

    #  Present WAN interface:      Tunnel200 in Border 10.1.0.104
    m = p9.match(line)
    if m:
        traffic_classes_dict['present_wan_interface']['tunnel'] = m.group('present_wan_interface')
        traffic_classes_dict['present_wan_interface']['border'] = m.group('border')
        continue

    #  Present Channel (primary):  12488652 ISP2 pfr-label:0:0 | 0:0 [0x0]
    m = p10.match(line)
    if m:
        traffic_classes_dict['channel']['present'] = m.group('present_channel')
        #traffic_classes_dict['channel']['present'] = channel_data[m.group('present_channel')]
        continue

    #  Backup Channel:             12488653 ISP1 pfr-label:0:0 | 0:0 [0x0]
    m = p11.match(line)
    if m:
        traffic_classes_dict['channel']['backup'] = m.group('backup_channel')
        #  traffic_classes_dict['channel']['backup'] = channel_data[m.group('backup_channel')]
        continue

    #  Destination Site ID bitmap: 0
    m = p12.match(line)
    if m:
        traffic_classes_dict['dst_site_id_bit'] = m.group('dst_site_id_bit')
        continue

    #  Destination Site ID:        10.50.0.84
    m = p13.match(line)
    if m:
        traffic_classes_dict['dst_site_id'] = m.group('dst_site_id')
        continue

    #  Class-Sequence in use:      20
    m = p14.match(line)
    if m:
        traffic_classes_dict['class_sequence_in_use'] = m.group('class_sequence_in_use')
        continue

    #  Class Name:                 BEST_EFFORT using policy User-defined
    m = p15.match(line)
    if m:
        class_name = m.group('class_name')
        traffic_classes_dict['class_name'][class_name] = {}
        continue
    #  priority 2 packet-loss-rate threshold 40.0 percent
    m = p16.match(line)
    if m:
        traffic_classes_dict['class_name'][class_name]['priority'] = m.group('priority')
        traffic_classes_dict['class_name'][class_name]['detail'] = m.group('detail')
        traffic_classes_dict['class_name'][class_name]['type'] = m.group('type')
        traffic_classes_dict['class_name'][class_name]['value'] = m.group('value')
        continue

    #  Route Change History:
    m = p18.match(line)
    if m:
        route_change_flag = 1
        continue

    if route_change_flag:
        #  1:  04:36:42 (CDT) 08/05/19   ISP1(0:0|0:0)/10.1.0.101/Tu100 (Ch:12488653)       ISP2(0:0|0:0)/10.1.0.104/Tu200 (Ch:12488652)       Backup to Primary path preference transition
        m = p19.match(line)
        if m:
            route_change_dict = {}
            route_change_dict['date'] = m.group('date')
            route_change_dict['previous_exit'] = m.group('previous_exit')
            route_change_dict['current_exit'] = m.group('current_exit')
            route_change_dict['reason'] = m.group('reason')
            traffic_classes_dict['route_change_history'].append(route_change_dict)
            continue

print(json.dumps(parsed_dict))


import os
import io
import sys
import pickle
import random
import argparse
import subprocess
import numpy as np
import torch
import pandas as pd
from logging import getLogger
from itertools import permutations

from .logger import create_logger

MAIN_DUMP_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'dumped')

logger = getLogger()

# load Faiss if available (dramatically accelerates the nearest neighbor search)
try:
    import faiss
    FAISS_AVAILABLE = True
    if not hasattr(faiss, 'StandardGpuResources'):
        sys.stderr.write("Impossible to import Faiss-GPU. "
                         "Switching to FAISS-CPU, "
                         "this will be slower.\n\n")

except ImportError:
    sys.stderr.write("Impossible to import Faiss library!! "
                     "Switching to standard nearest neighbors search implementation, "
                     "this will be significantly slower.\n\n")
    FAISS_AVAILABLE = False

def initialize_exp(params):
    """
    Initialize experiment.
    """
    # initialization
    if getattr(params, 'seed', -1) == -1:
        params.seed = np.random.randint(1e8)
    random.seed(params.seed)
    np.random.seed(params.seed)
    torch.manual_seed(params.seed)
    if params.cuda:
        torch.cuda.manual_seed(params.seed)

    # dump parameters
    params.exp_path = get_exp_path(params)
    with io.open(os.path.join(params.exp_path, 'params.pkl'), 'wb') as f:
        pickle.dump(params, f)

    # create logger
    logger = create_logger(os.path.join(params.exp_path, 'train.log'), vb=params.verbose)
    logger.info('============ Initialized logger ============')
    logger.info('\n'.join('%s: %s' % (k, str(v)) for k, v in sorted(dict(vars(params)).items())))
    logger.info('The experiment will be stored in %s' % params.exp_path)
    return logger

def get_nn_avg_dist(emb, query, knn):
    """
    Compute the average distance of the `knn` nearest neighbors
    for a given set of embeddings and queries.
    Use Faiss if available.
    """
    if FAISS_AVAILABLE:
        emb = emb.cpu().numpy()
        query = query.cpu().numpy()
        if hasattr(faiss, 'StandardGpuResources'):
            # gpu mode
            res = faiss.StandardGpuResources()
            config = faiss.GpuIndexFlatConfig()
            config.device = 0
            index = faiss.GpuIndexFlatIP(res, emb.shape[1], config)
        else:
            # cpu mode
            index = faiss.IndexFlatIP(emb.shape[1])
        index.add(emb)
        distances, _ = index.search(query, knn)
        return distances.mean(1)
    else:
        bs = 1024
        all_distances = []
        emb = emb.transpose(0, 1).contiguous()
        for i in range(0, query.shape[0], bs):
            distances = query[i:i + bs].mm(emb)
            best_distances, _ = distances.topk(knn, dim=1, largest=True, sorted=True)
            all_distances.append(best_distances.mean(1).cpu())
        all_distances = torch.cat(all_distances)
        return all_distances.numpy()

def bool_flag(s):
    """
    Parse boolean arguments from the command line.
    """
    if s.lower() in ['off', 'false', '0']:
        return False
    if s.lower() in ['on', 'true', '1']:
        return True
    raise argparse.ArgumentTypeError("invalid value for a boolean flag (0 or 1)")

def get_exp_path(params):
    """
    Create a directory to store the experiment.
    """
    # create the main dump path if it does not exist
    exp_folder = MAIN_DUMP_PATH if params.exp_path == '' else params.exp_path
    if not os.path.exists(exp_folder):
        subprocess.Popen("mkdir %s" % exp_folder, shell=True).wait()
    assert params.exp_name != ''
    exp_folder = os.path.join(exp_folder, params.exp_name)
    if not os.path.exists(exp_folder):
        subprocess.Popen("mkdir %s" % exp_folder, shell=True).wait()
    if params.exp_id == '':
        chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
        while True:
            exp_id = ''.join(random.choice(chars) for _ in range(10))
            exp_path = os.path.join(exp_folder, exp_id)
            if not os.path.isdir(exp_path):
                break
    else:
        exp_path = os.path.join(exp_folder, params.exp_id)
        assert not os.path.isdir(exp_path), exp_path
    # create the dump folder
    if not os.path.isdir(exp_path):
        subprocess.Popen("mkdir %s" % exp_path, shell=True).wait()
    return exp_path

def normalize_embeddings(emb, types, mean=None):
    """
    Normalize embeddings by their norms / recenter them.
    """
    for t in types.split(','):
        if t == '':
            continue
        if t == 'center':
            if mean is None:
                mean = emb.mean(0, keepdim=True)
            emb.sub_(mean.expand_as(emb))
        elif t == 'renorm':
            emb.div_(emb.norm(2, 1, keepdim=True).expand_as(emb))
        else:
            raise Exception('Unknown normalization type: "%s"' % t)
    return mean.cpu() if mean is not None else None

def apply_mapping(map,input,device=None):
    if device is None:
        device = map.weight.device
    map = map.to(device)
    return map(input.to(device))

def save_results(params,results_by_inf_met, methods):
    columns_order = ['{}-{}'.format(src, tgt) for src, tgt in permutations(params.langs, 2)
                     if 'en' in [src, tgt] or
                     len(set(['en','de','fr','es','it','pt']).intersection(set([src, tgt])))==2]
    df = pd.DataFrame()
    # aggregate results
    for (src, tgt), pair_res in results_by_inf_met.items():
        for inf_met, p_at_1 in pair_res.items():
            df = df.append({'task':'{}-{}'.format(src,tgt),'inf-met':inf_met,'p@1':p_at_1}, ignore_index=True)
    # re-arrange results in more convenience way
    df = df.pivot(index='inf-met',columns='task',values='p@1')
    df = df.loc[methods]
    df = df[columns_order]
    df['avg'] = df.mean(1)
    # print and save results
    logger.info(df)
    df.to_csv(os.path.join(params.exp_path, 'results.csv'))


from config.bd import app,bd,ma

class ProfesorPrograma(bd.Model):
    __tablename__ = 'tblProfesorPrograma'
    idProfesorPrograma = bd.Column(bd.Integer, primary_key=True)
    profesorId = bd.Column(bd.Integer, bd.ForeignKey("tblProfesor.codigoProfesor"))
    programaId = bd.Column(bd.Integer, bd.ForeignKey("tblPrograma.codigoPrograma"))

    def __init__(self, profesorId, programaId):
        self.profesorId = profesorId
        self.programaId = programaId

# Creación de la tabla
with app.app_context():
    bd.create_all()

# Descerialización
class GProfesorPrograma_Schema(ma.Schema):
    class Meta:
        fields = ("profesorId", "programaId")


from unittest import TestCase

from hyperlink import URL

from minion import traversal
from minion.request import Request, Response

def path_view(request):
    """
    A renderer (view) that returns a response with the request path.

    Optionally adds a prefix to the front.

    """

    path = b"/" + b"/".join(each.encode("ascii") for each in request.url.path)
    return Response(content=path)

class TestTreeResource(TestCase):
    def test_it_renders_what_its_told(self):
        resource = traversal.TreeResource(render=path_view)
        request = Request(url=URL(path=[u"bar"]))
        self.assertEqual(resource.render(request), Response(content=b"/bar"))

    def test_it_supports_adding_children(self):
        resource = traversal.TreeResource(render=path_view)
        child = traversal.LeafResource(render=path_view)
        resource.set_child(b"foo", child)
        request = Request(url=URL(path=[u"bar"]))
        self.assertEqual(resource.get_child(b"foo", request=request), child)

    def test_it_returns_404s_for_unknown_children(self):
        resource = traversal.TreeResource(render=path_view)
        request = Request(url=URL(path=[u"foo"]))
        child = resource.get_child(b"foo", request=request)
        self.assertEqual(child.render(request), Response(code=404))

    def test_it_returns_404s_by_default(self):
        resource = traversal.TreeResource()
        request = Request(url=URL(path=[]))
        self.assertEqual(resource.render(request), Response(code=404))

class TestLeafResource(TestCase):
    def test_it_renders_what_its_told(self):
        resource = traversal.LeafResource(render=path_view)
        request = Request(url=URL(path=[u"foo"]))
        self.assertEqual(resource.render(request), Response(content=b"/foo"))

    def test_it_is_a_leaf_resource(self):
        self.assertTrue(
            traversal.LeafResource(render=lambda request: Response()).is_leaf,
        )

class TestMethodDelegate(TestCase):
    def test_known_HTTP_methods_use_associated_renderer(self):
        render = traversal.method_delegate(
            GET=lambda request: b"foo",
            put=lambda request: request.method,
        )
        get = Request(url=URL(path=[u""]), method=b"GET")
        self.assertEqual(render(get), b"foo")

        put = Request(url=URL(path=[u""]), method=b"PUT")
        self.assertEqual(render(put), b"PUT")

    def test_unknown_HTTP_methods_return_405s(self):
        render = traversal.method_delegate(get=lambda _: b"foo")
        request = Request(url=URL(path=[u""]), method=b"PUT")
        self.assertEqual(render(request).code, 405)

class LineDelimiterResource(object):
    """
    A resource where traversal returns a child resource that renders the
    ultimate path as a line delimited bytestring.

    """

    def __init__(self, path=()):
        self.path = list(path)

    def get_child(self, name, request):
        return self.__class__(path=self.path + [name])

    def render(self, request):
        return b"\n".join(self.path)

class TestTraverse(TestCase):
    def test_it_traverses_resources(self):
        root = LineDelimiterResource()
        request = Request(url=URL(path=[u"foo", u"bar", u"baz"]))
        renderer = traversal.traverse(
            path=b"/foo/bar/baz", resource=root, request=request,
        )
        self.assertEqual(renderer.render(request), b"foo\nbar\nbaz")

    def test_single_level(self):
        root = LineDelimiterResource()
        request = Request(url=URL(path=[u"foo"]))
        renderer = traversal.traverse(
            path=b"/foo", resource=root, request=request,
        )
        self.assertEqual(renderer.render(request), b"foo")

    def test_zero_levels(self):
        root = LineDelimiterResource()
        request = Request(url=URL(path=[u""]))
        renderer = traversal.traverse(
            path=b"/", resource=root, request=request,
        )
        self.assertIs(renderer, root)

    def test_leaf_resources_are_not_traversed(self):
        class Resource(object):
            def __init__(self, name=b""):
                self.name = name

            def get_child(self, name, request):
                resource = Resource(name=name)
                if name == b"2":
                    resource.is_leaf = True
                return resource

            def render(self, name):
                return self.name

        root = Resource()
        request = Request(url=URL(path=[u"0", u"1", u"2", u"3", u"4", u"5"]))
        renderer = traversal.traverse(
            path=b"/0/1/2/3/4/5", resource=root, request=request,
        )
        self.assertEqual(renderer.render(request), b"2")


import numpy as np
import pickle
import time
import torch
from my_io import Vocabulary
import io
import argparse

def load_vectors(fname):
    fin = io.open(fname, 'r', encoding='utf-8', newline='\n', errors='ignore')
    n, d = map(int, fin.readline().split())
    data = {}
    for line in fin:
        tokens = line.rstrip().split(' ')
        data[tokens[0]] = map(float, tokens[1:])
    return data

def load_fasttext_emb_for_vocab(fasttext_fn, vocab_pt_fn, trg_emb_fn, emb_size=300):
    src_vocab = torch.load(vocab_pt_fn, 'rb')[0]  # (src_vocab, trg_vocab)
    vocab_size = len(src_vocab)
    weights = np.random.normal(0, scale=0.1, size=[vocab_size, emb_size]).astype(np.float32)
    hit_cnt = 0
    t0 = time.time()
    # data = load_vectors(fasttext_fn)
    fin = io.open(fasttext_fn, 'r', encoding='utf-8', newline='\n', errors='ignore')
    n, d = map(int, fin.readline().split())
    print('The size of embedding is %d * %d' % (n, d))
    for idx, line in enumerate(fin):
        line = line.rstrip().split(' ')
        word = line[0]
        if word in src_vocab.word2idx:
            id = src_vocab(word)
            try:
                weights[id] = np.array(line[1:], dtype=np.float32)
            except:
                print('word: %s (id: %d) has errors\n' % (word, id))
            hit_cnt += 1
        if idx % 100000 == 0:
            print('Processing %d lines' % idx)
    print('Find %d / %d from glove embedding, takes %.2f seconds' % (hit_cnt, vocab_size, time.time() - t0))
    with open(trg_emb_fn, 'wb') as f:
        pickle.dump(weights, f)
    print('Saving embedding into %s' % trg_emb_fn)

def load_emb_for_vocab(glove_fn, vocab_pt_fn, trg_emb_fn, emb_size=200):
    src_vocab = torch.load(vocab_pt_fn, 'rb')[0]  # (src_vocab, trg_vocab)
    vocab_size = len(src_vocab)
    weights = np.random.normal(0, scale=0.1, size=[vocab_size, emb_size]).astype(np.float32)
    hit_cnt = 0
    t0 = time.time()
    with open(glove_fn, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.split()
            word = line[0]
            if word in src_vocab.word2idx:
                id = src_vocab(word)
                try:
                    weights[id] = np.array(line[1:], dtype=np.float32)
                except:
                    print('word: %s (id: %d) has errors:\nLine length:%d\n' % (word, id, len(line)), line)
                hit_cnt += 1
    print('Find %d/%d from glove embedding, takes %.2f seconds' % (hit_cnt, vocab_size, time.time() - t0))
    with open(trg_emb_fn, 'wb') as f:
        pickle.dump(weights, f)
    print('Saving embedding into %s' % trg_emb_fn)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    # Data and path parameters
    parser.add_argument('-data_tag', type=str, default='tw_mm_s1')
    opt = parser.parse_args()
    vocab_pt_fn = '../processed_data/{}/vocab.pt'.format(opt.data_tag)

    glove_fn = '/research/lyu1/yuewang/workspace/embeddings/glove.twitter.27B.200d.txt'
    # glove_fn = '/research/lyu1/yuewang/workspace/embeddings/glove.6B.200d.txt'
    # glove_fn = '/research/lyu1/yuewang/workspace/embeddings/crawl-300d-2M-subword.vec'
    trg_emb_fn = '../processed_data/{}/glove_emb.pkl'.format(opt.data_tag)
    print('Start loading embedding for vocab: %s' % vocab_pt_fn)

    load_emb_for_vocab(glove_fn, vocab_pt_fn, trg_emb_fn, 200)
    # load_fasttext_emb_for_vocab(glove_fn, vocab_pt_fn, trg_emb_fn, 300)

# Start loading embedding for vocab: ../processed_data/tw_mm_s1/vocab.pt
# Find 36941/45006 from glove embedding, takes 32.77 seconds
# Saving embedding into ../processed_data/tw_mm_s1/glove_emb.pkl


#!/usr/bin/env python

import argparse
import hashlib
import json

from flask import Flask, jsonify, abort
import yaml

app = Flask(__name__)

wines = []
supplier_name = ''

@app.route('/api/wines/<string:wine_id>', methods=['GET'])
def get_wine(wine_id):
    for wine in wines:
        if wine.get('id') == wine_id:
            return jsonify({'wine': wine})
    abort(404)

@app.route('/api/wines/', methods=['GET'])
def get_wines():
    return jsonify({
        'wines': [
            {wine.get('id'): wine.get('name')} for wine in wines
        ]
    })

@app.route('/api/', methods=['GET'])
def index():
    return jsonify({'supplier': supplier_name,
                    'user': 'anon'})

def get_hash(d):
    '''Return a deterministic hash of a dictionary'''
    hash_object = hashlib.sha1(json.dumps(d))
    return hash_object.hexdigest()

def get_args():
    '''Parse command line arguments'''
    parser = argparse.ArgumentParser()
    parser.add_argument('wines', help='wine yaml file')
    return parser.parse_args()

def get_wine_data(raw_wine_data):
    '''Return a dict containing data loaded from config file'''
    return raw_wine_data.get('wines', [])

def get_wine_supplier(raw_wine_data):
    '''Return a string containing the supplier name set in the config file'''
    return raw_wine_data.get('supplier', 'No supplier name set')

def main():
    args = get_args()

    with open(args.wines) as f:
        raw_wine_data = yaml.load(f)

    wines_data = get_wine_data(raw_wine_data)

    global supplier_name
    supplier_name = get_wine_supplier(raw_wine_data)

    for wine in wines_data:
        sha1 = get_hash(wine)
        wine['id'] = sha1[0:16]
        wines.append(wine)

    app.run(host='0.0.0.0',
            port=8080,
            debug=True)

if __name__ == '__main__':
    main()