from flask import Flask,request
from flask_sqlalchemy import SQLAlchemy

import json as js

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////Users/Kapil/Desktop/Kapil_Assignment/Kapil_Assignment/organization.db' # dialect+driver://username:password@host:port/database

db = SQLAlchemy(app)

class Employees(db.Model):
    __tablename__ = 'employees'

    id = db.Column('Employee_ID',db.Integer,primary_key=True)
    first_name = db.Column('First_name',db.String)
    last_name = db.Column('Last_name',db.String)
    device_id = db.Column('Device_ID',db.Integer)

    def getById(self,id):
        emp = Employees.query.filter_by(id=id).first()
        val = {"id":emp.id, "first_name":emp.first_name,"last_name":emp.last_name,"device_id":emp.device_id}
        return js.dumps(val)

    def getAll(self):
        emp_all =  Employees.query.all()
        vals = []
        for emp in emp_all:
            val = {"id":emp.id, "first_name":emp.first_name,"last_name":emp.last_name,"device_id":emp.device_id}
            vals.append(val)
        print(vals)
        return js.dumps(vals)

    def insert(self,kwargs):
        db.session.add(Employees(**kwargs))
        db.session.commit()

    def update(self,id,kwargs):
        Employees.query.filter_by(id=id).update(kwargs)
        db.session.commit()

    def delete(self,id):
        self = Employees.query.filter_by(id=id).first()
        print(self)
        db.session.delete(self)
        db.session.commit()

@app.route('/',methods=['GET'])
def getAll():
    text = Employees().getAll()
    # emp = Employees()
    return text

@app.route('/<int:id>', methods=['GET'])
def getByID(id):
    text = Employees().getById(id)
    return text

@app.route('/',methods=['POST'])
def insert():
    data = {}
    data["id"] = request.form["id"]
    data["first_name"] = request.form["first_name"]
    data["last_name"] = request.form["last_name"]
    data["device_id"] = request.form["device_id"]
    #pprint.pprint(data)
    Employees().insert(data)
    return "Inserted"

@app.route('/<int:id>',methods=['GET','PATCH'])
def update(id):
    data = {}
    data["id"] = request.form["id"]
    data["first_name"] = request.form["first_name"]
    data["last_name"] = request.form["last_name"]
    data["device_id"] = request.form["device_id"]
    Employees().update(id,data)
    return "UPDATED"

@app.route('/<int:id>',methods=['DELETE'])
def delete(id):
    Employees().delete(id)
    return "DELETED!"


import sys
from pathlib import Path

from genicam.genapi import NodeMap
from harvesters.core import Harvester

from common import (CONNECTION_SETTINGS, console, cti_file_path,
                    enable_components, enabled_components,
                    get_component_statuses, sorted_components)

def main(device_sn: str):
    with Harvester() as h:
        h.add_file(str(cti_file_path), check_existence=True, check_validity=True)
        h.update()

        console.print(f"[bold]Connecting to: {device_sn}")
        with h.create({"serial_number": device_sn}, config=CONNECTION_SETTINGS) as ia:
            features: NodeMap = ia.remote_device.node_map

            # Enable software trigger mode
            features.TriggerSelector.value = "FrameStart"
            features.TriggerMode.value = "On"
            features.TriggerSource.value = "Software"

            if features.IsMotionCam3D_Val.value:
                features.OperationMode.value = "Camera"

            # To get Normals we need to enable this value
            features.NormalsEstimationRadius.value = 2

            enable_components(features, sorted_components(features))
            console.print(get_component_statuses(features))

            console.print("[green]Start Acquisition")
            ia.start()
            features.TriggerSoftware.execute()
            enabled_comps: list = enabled_components(features)
            with ia.fetch(timeout=10) as buff:
                # match the components based on their order
                for name, part in zip(enabled_comps, buff.payload.components):
                    console.print(
                        f"[yellow]Component {name}:[/yellow]\n"
                        f"DataFormat: {part.data_format}\n"
                        f"Width: {part.width}\n"
                        f"Height: {part.height}\n"
                    )

if __name__ == "__main__":
    try:
        device_id = sys.argv[1]
    except IndexError:
        print(
            f"Error: no device given, please run it with the device serial number as argument:"
        )
        print(f"    {Path(__file__).name} <device serial>")
        sys.exit(1)
    main(device_id)


from flask import jsonify
from flask_restful import abort, Resource, reqparse

from data import db_session
from data.aims import Aim

# Парсер
parser = reqparse.RequestParser()
parser.add_argument('name', required=True)
parser.add_argument('about', required=True)
parser.add_argument('is_finished', required=True, type=bool)
parser.add_argument('author', required=True)
parser.add_argument('finish_date', required=True)

#  Проверка существования цели
def abort_if_aim_not_found(aim_id):
    session = db_session.create_session()
    news = session.query(Aim).get(aim_id)
    if not news:
        abort(404, message=f"Aim {aim_id} not found")

# Ресурс цели
class AimsResource(Resource):
    # Получение цели
    def get(self, aim_id):
        abort_if_aim_not_found(aim_id)
        session = db_session.create_session()
        aim = session.query(Aim).get(aim_id)
        return jsonify({'aims': aim.to_dict(
            only=('name', 'about', 'is_finished', 'author', 'finish_date'))})

    # Удаление цели
    def delete(self, aim_id):
        abort_if_aim_not_found(aim_id)
        session = db_session.create_session()
        aim = session.query(Aim).get(aim_id)
        session.delete(aim)
        session.commit()
        return jsonify({'success': 'OK'})

# Ресурс целей
class AimsListResource(Resource):
    # Получение целей
    def get(self):
        session = db_session.create_session()
        aims = session.query(Aim).all()
        return jsonify({'aims': [item.to_dict(
            only=('name', 'about', 'is_finished', 'finish_date')) for item in aims]})

    def post(self):
        # Создание цели
        args = parser.parse_args()
        session = db_session.create_session()
        aim = Aim(
            name=args['name'],
            about=args['about'],
            is_finished=args['is_finished'],
            author=args['author'],
            finish_date=args['finish_date']
        )
        session.add(aim)
        session.commit()
        return jsonify({'success': 'OK'})


from typing import List

def transpose(matrix: List[List[int]]) -> List[List[int]]:
    row, column = len(matrix), len(matrix[0])
    res, temp = [], []
    for i in range(column):
        for j in range(row):
            temp.append(matrix[j][i])
        res.append(temp)
        temp = []
    return res

def main():
    matrix = [[1, 2, 3],
              [4, 5, 6],
              [7, 8, 9]]
    # target = [[1, 4, 7],
    #           [2, 5, 8],
    #           [3, 6, 9]]
    print(transpose(matrix))

if __name__ == '__main__':
    main()


from telegram import Update
from telegram.ext import ContextTypes
import parse
from my_math import calc as c

async def commands(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    result = f'Hi, {update.effective_user.full_name}!\n' \
             'The bot supports floating point numbers \n' \
             'and the following arithmetic operations: \n' \
             '(), ^, /, *, -, + \n\n' \
             'For example: \n' \
             '-1 + 0.5 / (1 + 2) \n\n' \
             'And two trigonometric operations:\n' \
             'c as cos and s as sin\n' \
             's((c90)+(s59)) \n\n' \
             'Constants:\n' \
             'p, e'
    await update.message.reply_text(f'{result}')

async def calculate(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    line = update.message.text
    formula = parse.get_formula(line)
    result = c.calc(formula)
    await update.message.reply_text(f'{result}')


from string import *
import os
import pydot

def main():
    forest = 'z(xy(tp(ui(klm)n)g(abc));w(h(q(j)o);A(BCDE(F));'
    trees = forest.split(';')[:-1]
    stack = list()

    for i, tree in enumerate(trees):
        graph = pydot.Dot(graph_type='graph')
        edges = list()

        for c in tree:
            if c == '(' or c in ascii_letters:
                stack.append(c)
            elif c == ')':
                popped = stack.pop()
                line = list()
                while popped != '(':
                    line.append(popped)
                    popped = stack.pop()

                root = stack[-1]
                for x in line:
                    edges.append(pydot.Edge(root, x))

        line = list()
        root = ''
        while stack:
            c = stack.pop()
            if c != '(':
                line.append(c)
            elif c == '(':
                root = stack.pop()
        for x in line:
            if root:
                edges.append(pydot.Edge(root, x))

        for edge in edges[::-1]:
            graph.add_edge(edge)

        graph.write_png('tree%s.png' % i)

if __name__ == '__main__':
    main()


from __future__ import unicode_literals

try:  # transition with Python 3.6+
    import collections.abc as collectionsABC
except ImportError:
    import collections as collectionsABC

from glyphs.helpers.ImmutableObject import ImmutableObject
import six

class ROGlyph(ImmutableObject):
    """
        R/O glyph designed to read data from an object (source of the data).
    """

    NAME_SPACE_SEPARATOR = '>'
    """
        Token used to separate the 'levels' for the keys-value pairs.
    """

    KEY_VALUE_SEPARATOR = ':'
    """
        Token used to separate the key and values for the key-value pairs.
    """

    def __init__(self, r_path, r_types=None, r_translation_function=None, r_default_value=None):
        """
            Initializer for a R/O glyph.

            @param r_path: The "path" pointing to the source of data.
            For multilevel keys (nest level):
            - if the path is a unicode, use L{a name space separator<glyphs.api.ROGlyph.ROGlyph.NAME_SPACE_SEPARATOR>}
            between the various level of keys.
            - if the path is a collection, each level is a unicode in the collection.
            @type r_path: six.text_type or collections.abc.Sequence
            @param r_types: (Optional) A string describing the type of data expected to be found in the
            source data. For each matching level in L{r_path}, a key-value pair may be specified, not all
            levels are required to have a type defined.
            - if L{r_types} is a unicode, use L{a name space separator<glyphs.api.ROGlyph.ROGlyph.NAME_SPACE_SEPARATOR>}
            between the various level of types. To omit a level of type, do not specify a key-value pair.
            - if L{r_types} is a collection, each level of types is a unicode in the collection. To omit a
            level of type, place C{None} at the skipped level.

            The level of types are key-value pairs. The key defines where the type information can be found at
            a given level in the source. The values specifies the type expected. The key and value separator
            <glyphs.api.ROGlyph.ROGlyph.KEY_VALUE_SEPARATOR>}.
            There is no need to specify every level of type to match L{r_path},
            as any long-tail levels that are not specified will be interpreted as having no key-value
            pairs.
            @param r_translation_function: function used to translate the data found at L{r_path}
            to any target format.
            This is meant to be a very simple function for pure translate / transtyping. No intelligence here.
            If C{None}, then no translation is needed and the data should be passed through.
            @param r_default_value: value to use as a default value. To be used when no data is found at
            L{r_path}.

            @precondition: isinstance(r_path, six.text_type) or all(isinstance(u, six.text_type) for u in r_path)
            @precondition: len(r_path) > 0
            @precondition: r_types is None or isinstance(r_types, (six.text_type, tuple))
            @precondition: r_types is None or len(r_types) > 0
            @precondition: r_types is None or isinstance(r_types, tuple) or (
                                                                                (
                                                                                isinstance(r_path, six.text_type)
                                                                                and r_types.count(ROGlyph.NAME_SPACE_SEPARATOR) <= r_path.count(ROGlyph.NAME_SPACE_SEPARATOR)
                                                                                )
                                                                                or r_types.count(ROGlyph.NAME_SPACE_SEPARATOR) <= len(r_path)
                                                                                )
            @precondition: r_types is None or isinstance(r_types, six.text_type) or (
                                                                                (
                                                                                isinstance(r_path, six.text_type)
                                                                                and len(r_types) <= r_path.count(ROGlyph.NAME_SPACE_SEPARATOR)
                                                                                )
                                                                                or len(r_types) <= len(r_path)
                                                                                )
            @precondition: r_types is None or len(r_types) > 0
            @precondition: r_translation_function is None or callable(r_translation_function)
        """
        assert r_translation_function is None or callable(r_translation_function)

        self.__dict__["__r_path_type"] = self._generate_path_type_paired_sequence(r_path, r_types,)

        self.__dict__["__r_translation_function"] = r_translation_function
        self.__dict__["__r_default_value"] = r_default_value

    def __repr__(self):
        return "{}({},)".format(self.__class__.name, self.r_path,)

    @property
    def iter_r_path_type(self):
        """
            Returns a new iterator through the configured sequence of triplet of the sub path, their matching
            types as a pair and a boolean expressing whether they are the last triplet in the sequence.

            The iterator makes up a typed path to read data out of an object.

            @rtype: collections.abc.Iterable

            @postcondition: next(return, None) is not None
            @postcondition: all(
                                (
                                    isinstance(x, tuple)
                                    and len(x) == 3
                                    and isinstance(x[0], bool)
                                    and isinstance(x[1], six.text_type) and len(x[1]) > 0
                                    and (
                                        x[2] is None
                                        or (
                                            isinstance(x[2], tuple) and len(x[2]) == 2
                                            and all(isinstance(v) for v in x[2])
                                           )
                                        )
                                )
                                for x in return
                                )
        """
        return iter(self.__dict__["__r_path_type"])

    @property
    def r_default_value(self):
        """
            Returns a value to use in case no suitable value is found in the object.
        """
        return self.__dict__["__r_default_value"]

    @property
    def r_translation_function(self):
        """
            Returns a function used to translate the value found in the object to a target
            format.

            Note: this is meant to be a very simple function for pure translate / transtyping. No
            intelligence here.

            If C{None}, then no translation is needed and the data should be passed through.

            @postcondition: return is None or callable(return)
        """
        return self.__dict__["__r_translation_function"]

    def _generate_path_type_paired_sequence(self, path, types,):
        """
            Returns a sequence of triplet of the sub path, their matching L{types} as a pair and a boolean expressing whether
            they are the last triplet in the sequence.

            @param path: The "path" to walk to reach the data.
            For multilevel keys (nest level):
            - if the path is a unicode, uses L{a name space separator<glyphs.api.ROGlyph.ROGlyph.NAME_SPACE_SEPARATOR>}
            between the various level of keys.
            - if the path is a collection, each level is a unicode in the collection.
            @type path: six.text_type or collections.abc.Sequence
            @param types: (Optional) A string describing the type of data expected to be found in the
            source data. For each matching level in L{path} (sub path), a key-value pair may be specified, not
            all levels are required to have a type defined.
            - if L{types} is a unicode, uses L{a name space separator<glyphs.api.ROGlyph.ROGlyph.NAME_SPACE_SEPARATOR>}
            between the various level of types. To omit a level of type, do not specify a key-value pair at
            that level.
            - if L{types} is a collection, each level of types is a unicode in the collection. To omit a
            level of type, place C{None} at the skipped level.

            The level of types are key-value pairs. The key defines where the type information can be found at
            a given level in the source. The values specifies the type expected. The key and value separator
            <glyphs.api.ROGlyph.ROGlyph.KEY_VALUE_SEPARATOR>}.
            There is no need to specify every level of type to match L{path},
            as any long-tail levels that are not specified will be interpreted as having no key-value
            pairs.

            e.g.
            if the separator is a period '.' as a name space separator and ':' as a key separator to express
            and object which is a series of nested dictionaries:
            path: sub_path1.sub_path2.sub_path3
            value: 1
            types: ..xsi:Entity
            object: {'sub_path1': {'sub_path2': {'sub_path3': 1, 'xsi':'Entity' } } }

            @rtype: collections.abc.Sequence

            @precondition: types is None or isinstance(types, tuple) or (
                                                                             (
                                                                             isinstance(path, six.text_type)
                                                                             and types.count(ROGlyph.NAME_SPACE_SEPARATOR) <= path.count(ROGlyph.NAME_SPACE_SEPARATOR)
                                                                             )
                                                                             or types.count(ROGlyph.NAME_SPACE_SEPARATOR) <= len(path)
                                                                        )
            @precondition: types is None or isinstance(types, six.text_type) or (
                                                                             (
                                                                             isinstance(path, six.text_type)
                                                                             and len(types) <= path.count(ROGlyph.NAME_SPACE_SEPARATOR)
                                                                             )
                                                                             or len(types) <= len(path)
                                                                          )
            @precondition: types is None or len(types) > 0

            @postcondition: len(return) > 0
            @postcondition: all(
                                    (
                                        isinstance(x, tuple)
                                        and len(x) == 3
                                        and isinstance(x[0], bool)
                                        and isinstance(x[1], six.text_type) and len(x[1]) > 0
                                        and (
                                            x[2] is None
                                            or (
                                                isinstance(x[2], tuple) and len(x[2]) == 2
                                                and all(isinstance(v) for v in x[2])
                                               )
                                            )
                                    )
                                    for x in return
                                )
        """

        if isinstance(path, six.text_type):
            path_tuple = tuple(path.split(ROGlyph.NAME_SPACE_SEPARATOR))
        else:
            assert isinstance(path, collectionsABC.Sequence)  # pre
            path_tuple = tuple(path)
            assert all(isinstance(u, six.text_type) for u in path_tuple)  # pre

        assert path_tuple

        max_index = len(path_tuple) - 1

        if types is None:
            types_tuple = tuple()
        elif isinstance(types, six.text_type):
            types_tuple = tuple(None if x == '' else x for x in types.split(ROGlyph.NAME_SPACE_SEPARATOR))
        else:
            assert isinstance(types, tuple)
            assert all(l is None or isinstance(l, six.text_type) for l in types)
            types_tuple = types

        types_tuple = tuple(None if x is None else tuple(x.split(ROGlyph.KEY_VALUE_SEPARATOR)) for x in types_tuple)

        if len(types_tuple) < len(path_tuple):
            # pad anything that has been left unspecified.
            types_tuple += (None,) * (len(path_tuple) - len(types_tuple))
        else:
            assert len(types_tuple) == len(path_tuple)  # pre

        assert len(types_tuple) == len(path_tuple)  # dev check

        return tuple(
                      (idx == max_index, sub_path, type_name,)
                      for idx, (sub_path, type_name,) in enumerate(
                                                                  six.moves.zip(
                                                                                path_tuple,
                                                                                types_tuple,
                                                                               )
                                                                  )
                      )


import datetime
import requests
import json
import time
from bs4 import BeautifulSoup
from sqlalchemy import create_engine, Column, String, Numeric, DateTime
from sqlalchemy.orm import Session
from sqlalchemy.orm import declarative_base
Base = declarative_base()

with open('config.json', 'r') as config_file:
    config = json.load(config_file)

# a in-memory cache to prevent spamming the same stories
# on startup, the last 500 stories are resent, so the topic will still have dupes
seen_stories = set()

def inflate_story(id):
    print('inflating...', id)
    return requests.get(f'https://hacker-news.firebaseio.com/v0/item/{id}.json').json()

class Story(Base):
    __tablename__ = 'stories'

    id = Column(Numeric, primary_key=True)
    by = Column(String)
    score = Column(Numeric)
    title = Column(String)
    time = Column(DateTime)
    url = Column(String)

db = create_engine(config['db']['uri'])
Base.metadata.create_all(db)

with db.connect() as conn:
    sess = Session(db)
    while True:
        print('Fetching new stories...')
        stories = requests.get(
            'https://hacker-news.firebaseio.com/v0/newstories.json').json()
        new_stories = 0

        for story_id in stories:
            if story_id in seen_stories:
                continue

            story = inflate_story(story_id)
            if story is None:
                continue
            if 'url' not in story:
                continue

            sess.merge(Story(
                by=story['by'],
                id=story['id'],
                score=story['score'],
                title=story['title'],
                time=datetime.datetime.utcfromtimestamp(story['time']),
                url=story['url']
            ))
            sess.commit()

            seen_stories.add(story_id)
            new_stories += 1

        print('Produced', new_stories, 'new stories')
        time.sleep(15)


class HashTable:
    def __init__(self, size):
        self.keyMap = [None] * size

    def _hash(self, key):
        total = 0
        WEIRD_PRIME = 53
        for i in range(0, min(len(key), 100)):
            char = key[i]
            value = ord(char) - 96
            total = (total * WEIRD_PRIME + value) % len(self.keyMap)
        return total

    def set(self, key, value):
        hash = self._hash(key)
        if self.keyMap[hash] == None:
            self.keyMap[hash] = []
        self.keyMap[hash].append([key, value])
        return self.keyMap

    def get(self, key):
        hash = self._hash(key)
        if self.keyMap[hash] == None:
            return None
        else:
            for i in range(0, len(self.keyMap[hash])):
                if self.keyMap[hash][i][0] == key:
                    return self.keyMap[hash][i][1]
        return None

    def keys(self):
        keysArr = []
        for i in range(0, len(self.keyMap)):
            if self.keyMap[i] != None:
                for j in range(0, len(self.keyMap[i])):
                    keysArr.append(self.keyMap[i][j][0])
        return keysArr

    def values(self):
        valuesArr = []
        for i in range(0, len(self.keyMap)):
            if self.keyMap[i] != None:
                for j in range(0, len(self.keyMap[i])):
                    valuesArr.append(self.keyMap[i][j][1])
        return valuesArr

map = HashTable(13)
print(map.set("pink", "#ff3092"))
print(map.set("blue", "#a03e5c"))
print(map.set("green", "#bb3092"))
print(map.set("cyan", "#ae3e5f"))
print(map.set("black", "#6fc092"))
print(map.set("white", "#a69c5v"))
print(map.set("orange", "#ffe354"))
print(map.set("yellow", "#00ff5c"))
print(map.set("maroon", "#00ff5c"))
print(map.get("green"))
print(map.get("pink"))
print(map.get("orange"))
print(map.get("cyan"))
print(map.get("blue"))
print(map.get("yellow"))
print(map.get("sky"))
print(map.keys())
print(map.values())


"""
bruteforce + DFS : 각각의 전선(연결관계)를 끊어 보고, 그떄 노드 개수의 차이가 최소인 경우 구하기
"""
from collections import defaultdict

def dfs(tree, cur, visited):
    visited.add(cur)
    for nxt in tree[cur]:
        if nxt not in visited:
            dfs(tree, nxt, visited)

    return len(visited)

# 자른 뒤에 그래프를 만든 뒤, dfs 탐색하며 노드 개수 세기, 차이 계산해서 return
def cut(idx, n, wires):
    tree = defaultdict(list)
    for i in range(len(wires)):
        if i == idx:
            continue
        v1, v2 = wires[i]
        tree[v1].append(v2)
        tree[v2].append(v1)

    visited1, visited2 = set(), set()
    cnt1 = dfs(tree, wires[idx][0], visited1)
    cnt2 = dfs(tree, wires[idx][1], visited2)

    return abs(cnt1 - cnt2)

def solution(n, wires):
    res = float('inf')
    for i in range(len(wires)):  # i는 wires에서 제거할 연결 관계의 인덱스
        res = min(cut(i, n, wires[:]), res)

    return res

전력망을둘로나누기.py


from selenium import webdriver
import unittest
import time

class WindowTest(unittest.TestCase):
    """
    Selenium test sends the browser around the screen in a clockwise motion.

    Asserts an error if the final position is not the same as the initial position.
    """
    def setUp(self):
        # Start chrome maximised
        options = webdriver.ChromeOptions()
        options.add_argument("--start-maximized")
        self.driver = webdriver.Chrome(chrome_options=options)

    def test_window_manipulation(self):
        driver = self.driver

        # Store dimensions of maximised window for calculations
        zero_pos = driver.get_window_position()
        max_size = driver.get_window_size()
        print('Initial window parameters:')
        print(zero_pos, max_size)
        print("==========")

        # Set window size for spiral manipulation
        size_x, size_y = 300, 300
        driver.set_window_size(size_x, size_y)
        step_size = 30

        # Manipulate window top-left to top-right
        for x in range(zero_pos['x'], (max_size['width'] - size_x), step_size):
            driver.set_window_position(x, zero_pos['y'])
        win_pos = driver.get_window_position()
        print(win_pos)

        # Manipulate top-right to bottom-right
        for y in range(win_pos['y'], (max_size['height'] - size_y), step_size):
            driver.set_window_position(win_pos['x'], y)
        win_pos = driver.get_window_position()
        print(win_pos)

        # Manipulate bottom-right to bottom-left
        for x in range(win_pos['x'], zero_pos['x'] - step_size, -step_size):
            driver.set_window_position(x, win_pos['y'])
        win_pos = driver.get_window_position()
        print(win_pos)

        # Manipulate bottom-right to bottom-left
        for y in range(win_pos['y'], zero_pos['y'] - step_size, -step_size):
            driver.set_window_position(win_pos['x'], y)
        win_pos = driver.get_window_position()
        print(win_pos)

        # Check the final position is the same as the starting position
        if win_pos['x'] != zero_pos['x']:
            raise AssertionError('The final position {} is not the same as the initial position {}'.format(win_pos['x'], zero_pos['x']))
        else:
            print('Final position verified. ✓')

        time.sleep(2)

    def tearDown(self):
        self.driver.close()

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


import requests
from bs4 import BeautifulSoup
import re

class Scraper:
    url : str
    meta = str
    title = str
    photo_url = str
    page_text = str

    def extract_data(url_f):
        data = requests.get(url_f)
        soup = BeautifulSoup(data.content, "html.parser")
        links = []
        page_text = []
        for link in soup.findAll('a', attrs={'href': re.compile("^http://")}):
            links.append(link)
        # getting all the paragraphs
        for para in soup.find_all("p"):
            page_text.append(para.get_text())
        data = {
            "url" : str(url_f),
            "page_meta_tag" : str(soup.find("meta")),
            "page_title" :str(soup.find("title")),
            "page_links": str(links),
            "page_text" : str(page_text)
        }
        return data


import os

from django.http import HttpResponse, JsonResponse
from django.views import View
from .utils import session_check
from .token import tokenForRtc, Role_Publisher, Role_Attendee
import time
from .screenShot import http_authenticate, acquire, start, stop
import json
import datetime
from users.models import User
import requests
import oss2
from aip import AipBodyAnalysis
from PIL import Image
import io
from backend.settings import BASE_DIR
from imageMask .u2net_test import U2Net
from imageParse .exp .inference .inference import Graphonomy
from imagePose .keypoints_from_images import openPose
from virtualTryOn .test import virtualTryOn
import cv2

class ClothShot(View):
    def post(self, request):
        response = HttpResponse()
        return_model = {"msg_code": 100, "message": None, "cloth_object_name": ''}
        try:
            sessionId = request.COOKIES['sessionid']
            meeting = request.POST.get("meeting")
            meeting = json.loads(meeting)
            session_data = request.session.load()
            sessionCheck = session_check(request, sessionId)
            if sessionCheck == "login":
                appID = meeting["appID"]
                certification = meeting["certification"]
                channel = meeting["channel"]
                uid = 9  # Record Account uid is 9
                role = Role_Attendee
                privilegeExpiredTs = 24*60*60+int(time.time())
                token = tokenForRtc(appID, certification, channel, uid, role, privilegeExpiredTs)
                if http_authenticate():
                    resourceid = acquire(appID, channel)
                    if "Error" not in resourceid:
                        sid = start(appID, channel, resourceid, token)
                        clothObjectTime = str(datetime.datetime.utcnow()).replace("-", "").replace(" ", "").replace(".", "").replace(":", "")
                        clothObjectTime = clothObjectTime[:16]
                        if "Error" not in sid:
                            time.sleep(2)
                            stop_result = stop(appID, channel, resourceid, sid)
                            if stop_result:
                                host = User.objects.filter(room_num=channel)
                                host_uid = ''
                                if len(host):
                                    host_uid = str(host[0].id)
                                else:
                                    raise RuntimeError("Error, Meeting Host Not Found!")
                                clothImgName = sid + "_" + channel + "__uid_s_" + host_uid + "__uid_e_video_" + clothObjectTime
                                print(clothImgName)
                                return_model["msg_code"] = 100
                                return_model["message"] = "截图成功!"
                                return_model["cloth_object_name"] = clothImgName
                            else:
                                return_model["msg_code"] = 1001
                                return_model["message"] = "截图失败，请联系管理员!"
                        else:
                            return_model["msg_code"] = 1001
                            return_model["message"] = sid
                    else:
                        return_model["msg_code"] = 1001
                        return_model["message"] = resourceid

                else:
                    return_model["msg_code"] = 1001
                    return_model["message"] = "HTTP基本认证未通过，截图失败！"
            elif sessionCheck == "expired":
                return_model["msg_code"] = 1001
                return_model["message"] = "sessionid失效，登录过期请重新登录！"
            elif sessionCheck == "notExist":
                return_model["msg_code"] = 1001
                return_model["message"] = "请先登录后再操作！"
        except Exception as e:
            return_model["msg_code"] = 1001
            return_model["message"] = "截图失败," + str(e)

        response.content = json.dumps(return_model, ensure_ascii=False)
        return response

class GetCutCloth(View):
    # def post(self, request):
    #     response = HttpResponse()
    #     return_model = {"msg_code": 100, "message": None}
    #
    #     cloth_object_key = request.POST.get("clothObjectKey")
    #     print(type(cloth_object_key))
    #     cloth_object_key = json.loads(cloth_object_key)
    #     print(type(cloth_object_key))
    #
    #     # 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建RAM账号。
    #     auth = oss2.Auth('*******', '******')
    #     # Endpoint以杭州为例，其它Region请按实际情况填写。
    #     bucket = oss2.Bucket(auth, 'http://oss-cn-shanghai.aliyuncs.com', 'ai-try-on')
    #
    #     # bucket.get_object的返回值是一个类文件对象（File-Like Object），同时也是一个可迭代对象（Iterable）。
    #     object_stream = bucket.get_object(cloth_object_key)
    #     image = object_stream.read()
    #     print(image)
    #
    #     # 由于get_object接口返回的是一个stream流，需要执行read()后才能计算出返回Object数据的CRC checksum，因此需要在调用该接口后做CRC校验。
    #     if object_stream.client_crc != object_stream.server_crc:
    #         print("The CRC checksum between client and server is inconsistent!")
    #
    #     APP_ID = '*******'
    #     API_KEY = '*******'
    #     SECRET_KEY = '******'
    #
    #     client = AipBodyAnalysis(APP_ID, API_KEY, SECRET_KEY)
    #
    #     """ 调用人体检测与属性识别 """
    #     bodyInfo = client.bodyAttr(image)
    #     print("1")
    #     person_num, position = 0, {}
    #     if bodyInfo:
    #         for key, value in bodyInfo.items():
    #             if key == 'person_num':
    #                 person_num = value
    #             if key == 'person_info':
    #                 obj = value[-1]
    #                 for k, v in obj.items():
    #                     if k == 'location':
    #                         for kk, vv in v.items():
    #                             position[kk] = vv
    #
    #     left, upper, right, lower, width, height = 0, 0, 0, 0, 0, 0
    #     for key, value in position.items():
    #         if key == 'top':
    #             upper = value
    #         if key == 'left':
    #             left = value
    #         if key == 'width':
    #             width = value
    #         if key == 'height':
    #             height = value
    #
    #     right = left + width
    #     lower = upper + height
    #
    #     img = Image.open(io.BytesIO(image))
    #     print(type(img))
    #
    #     print(img.size)
    #     cutCloth = io.BytesIO()
    #     cropped = img.crop((left, upper, right, lower))
    #     print(type(cropped))
    #     cropped.save(cutCloth, "JPEG")
    #     print(type(str(BASE_DIR)))
    #     cropped.save(os.path.join(str(BASE_DIR)+'/static/images/cloth/', cloth_object_key[-21:]).replace('/', '\\'))
    #     cutClothBytes = cutCloth.getvalue()
    #
    #     response.content = cutClothBytes
    #     return response
    def post(self, request):
        response = HttpResponse()
        print(BASE_DIR)
        dir_path = os.path.join(BASE_DIR, "static\\images\\cloth\\cloth.png")
        with open(dir_path, 'rb') as f:
            im = f.read()
        img = Image.open(io.BytesIO(im))
        print(type(img))

        print(img.size)
        cutCloth = io.BytesIO()
        img.save(cutCloth, "JPEG")
        cutClothBytes = cutCloth.getvalue()

        response.content = cutClothBytes
        return response

class GetCloth(View):
    def post(self, request):
        response = HttpResponse()
        cloth_object_key = request.POST.get("clothObjectKey")
        cloth_object_key = json.loads(cloth_object_key)
        print(type(cloth_object_key))

        # 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建RAM账号。
        auth = oss2.Auth('*******', '*******')
        # Endpoint以杭州为例，其它Region请按实际情况填写。
        bucket = oss2.Bucket(auth, 'http://oss-cn-shanghai.aliyuncs.com', 'ai-try-on')

        # bucket.get_object的返回值是一个类文件对象（File-Like Object），同时也是一个可迭代对象（Iterable）。
        object_stream = bucket.get_object(cloth_object_key)
        cloth_bytes = object_stream.read()
        print(type(cloth_bytes))

        # 由于get_object接口返回的是一个stream流，需要执行read()后才能计算出返回Object数据的CRC checksum，因此需要在调用该接口后做CRC校验。
        if object_stream.client_crc != object_stream.server_crc:
            print("The CRC checksum between client and server is inconsistent!")

        response.content = cloth_bytes
        return response

class GetTryOnCloth(View):
    def post(self, request):
        response = HttpResponse()
        humanImageKey = request.POST.get("humanImageName")
        clothObjectKey = request.POST.get("clothObjectKey")
        humanImageKey = json.loads(humanImageKey)
        clothObjectKey = json.loads(clothObjectKey)

        # 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建RAM账号。
        auth = oss2.Auth('******', '*******')
        # Endpoint以杭州为例，其它Region请按实际情况填写。
        bucket = oss2.Bucket(auth, 'http://oss-cn-shanghai.aliyuncs.com', 'ai-try-on')

        # bucket.get_object的返回值是一个类文件对象（File-Like Object），同时也是一个可迭代对象（Iterable）。
        object_stream = bucket.get_object(humanImageKey)
        image = object_stream.read()
        print(type(image))

        imgStream = io.BytesIO(image)
        imgPIL = Image.open(imgStream)
        imgPIL.save(os.path.join(str(BASE_DIR)+'/static/images/image/', humanImageKey).replace('/', '\\'))

        # 由于get_object接口返回的是一个stream流，需要执行read()后才能计算出返回Object数据的CRC checksum，因此需要在调用该接口后做CRC校验。
        if object_stream.client_crc != object_stream.server_crc:
            print("The CRC checksum between client and server is inconsistent!")

        images_dir = os.path.join(str(BASE_DIR) + '/static/', 'images').replace('/', '\\')

        # reshape && get cloth mask
        cloth_dir = os.path.join(images_dir, 'cloth', clothObjectKey[-21:])
        print(cloth_dir)
        clothImage = cv2.imread(cloth_dir)
        print(clothImage.shape)
        b, g, r = cv2.split(clothImage)
        clothImage = cv2.merge([r, g, b])
        clothImage = cv2.resize(clothImage, (192, 256), interpolation=cv2.INTER_AREA)
        print(clothImage.shape)
        img2 = Image.fromarray(clothImage)
        img2.save(cloth_dir)

        U2Net(os.path.join(str(BASE_DIR)+'/static/images/', 'cloth').replace('/', '\\'))

        # reshape && get human image mask
        humanImage_dir = os.path.join(images_dir, 'image', humanImageKey)
        print(humanImage_dir)
        humanImage = cv2.imread(humanImage_dir)
        print(humanImage.shape)
        b, g, r = cv2.split(humanImage)
        humanImage = cv2.merge([r, g, b])
        humanImage = cv2.resize(humanImage, (192, 256), interpolation=cv2.INTER_AREA)
        print(humanImage.shape)
        img2 = Image.fromarray(humanImage)
        img2.save(humanImage_dir)

        # get humanKeyPoints
        openPose(humanImageKey)

        U2Net(os.path.join(str(BASE_DIR)+'/static/images/', 'image').replace('/', '\\'))

        # get parse images
        Graphonomy(humanImageKey)

        # get GMM image
        # prepare .txt
        txt_dir = os.path.join(str(BASE_DIR), "static\\images\\test_pairs.txt")
        print(txt_dir)
        print(humanImageKey + ' ' + clothObjectKey)
        with open(txt_dir, 'w') as f:
            f.write(humanImageKey + ' ' + clothObjectKey[-21:])
        virtualTryOn('GMM', 'GMM')

        # get TOM image
        virtualTryOn("TOM", 'TOM')

        tryOnImage = Image.open(cloth_dir)
        tryOnImageStream = io.BytesIO()
        tryOnImage.save(tryOnImageStream, "JPEG")
        tryOnImageBytes = tryOnImageStream.getvalue()
        response.content = tryOnImageBytes

        return response

class GetAICloth(View):
    def get(self, request):
        response = HttpResponse()
        print(BASE_DIR)
        dir_path = os.path.join(BASE_DIR, "static\\images\\result_dir\\model.jpg")
        with open(dir_path, 'rb') as f:
            im = f.read()
        img = Image.open(io.BytesIO(im))
        print(type(img))

        print(img.size)
        Cloth = io.BytesIO()
        img.save(Cloth, "JPEG")
        clothBytes = Cloth.getvalue()

        time.sleep(10)
        response.content = clothBytes
        return response


import argparse
import numpy as np
import torch
import torch.nn as nn
from tqdm.auto import tqdm
import os
import logging
from sklearn.preprocessing import LabelEncoder
from scipy.special import softmax
from torch.utils.data import DataLoader
from hyperopt import STATUS_OK, Trials, fmin, hp, tpe, space_eval

from utils import dotdict, load_environment_vars, load_dict, save_dict
from eval_utils import cross_val_score, f1_macro_score
from deep_utils import (
    get_logger,
    get_inverse_class_weights,
    NormalDataset,
    EarlyStopping,
)

LOG = get_logger()

OPT_MAX_TRIALS = 100
OPT_EARLY_STOPPING = 10

DEFAULT_SSL_CONFIG = {
    "ssl": {
        "augmentation": True,
        "weighted_loss_fn": True,
        "learning_rate": 0.0001,
        "patience": 10,
        "num_epoch": 100,
    }
}

DEFAULT_PARAM_GRID = {
    "learning_rate": hp.uniform("learning_rate", 1e-6, 1e-3),
    "batch_size": hp.choice("batch_size", [100, 500, 1000]),
    "pretrained": hp.choice("pretrained", [True, False]),
}

SSL_REPO_PATH, GPU = load_environment_vars(["SSL_REPO_PATH", "GPU"])

def get_sslnet(device, cfg, ssl_weights_path=None, pretrained=False):
    """
    Load and return the SSLNet.

    :param str device: pytorch map location
    :param cfg: config object
    :param ssl_weights_path: the path of the pretrained (fine-tuned) weights.
    :param bool pretrained: Initialise the model with self-supervised pretrained weights.
    :return: pytorch SSLNet model
    :rtype: nn.Module
    """
    if cfg.ssl_repo_path:
        # use repo from disk (for offline use)
        LOG.info("Using local %s", cfg.ssl_repo_path)
        sslnet: nn.Module = torch.hub.load(
            cfg.ssl_repo_path,
            f"harnet{cfg.data.winsec}",
            source="local",
            class_num=cfg.data.output_size,
            pretrained=pretrained,
        )
    else:
        # download repo from github
        repo = "OxWearables/ssl-wearables"
        sslnet: nn.Module = torch.hub.load(
            repo,
            f"harnet{cfg.data.winsec}",
            trust_repo=True,
            class_num=cfg.data.output_size,
            pretrained=pretrained,
        )

    if ssl_weights_path:
        # load pretrained weights
        model_dict = torch.load(ssl_weights_path, map_location=device)
        sslnet.load_state_dict(model_dict)
        LOG.info("Loaded SSLNet weights from %s", ssl_weights_path)

    sslnet.to(device)

    return sslnet

def predict(model, data_loader, my_device, output_logits=False):
    """
    Iterate over the dataloader and do inference with a pytorch model.

    :param nn.Module model: pytorch Module
    :param data_loader: pytorch dataloader
    :param str my_device: pytorch map device
    :param bool output_logits: When True, output the raw outputs (logits) from the last layer (before classification).
                                When False, argmax the logits and output a classification scalar.
    :return: true labels, model predictions, pids
    :rtype: (np.ndarray, np.ndarray, np.ndarray)
    """

    predictions_list = []
    true_list = []
    pid_list = []
    model.eval()
    if my_device == "cpu":
        torch.set_flush_denormal(True)
    for i, (x, y, pid) in enumerate(
        tqdm(data_loader, mininterval=60, disable=LOG.getEffectiveLevel() > 20)
    ):
        with torch.inference_mode():
            x = x.to(my_device, dtype=torch.float)
            logits = model(x)
            true_list.append(y)
            if output_logits:
                predictions_list.append(logits.cpu())
            else:
                pred_y = torch.argmax(logits, dim=1)
                predictions_list.append(pred_y.cpu())
            pid_list.extend(pid)
    true_list = torch.cat(true_list)
    predictions_list = torch.cat(predictions_list)

    if output_logits:
        return (
            torch.flatten(true_list).numpy(),
            predictions_list.numpy(),
            np.array(pid_list),
        )
    else:
        return (
            torch.flatten(true_list).numpy(),
            torch.flatten(predictions_list).numpy(),
            np.array(pid_list),
        )

def train(model, train_loader, val_loader, cfg, my_device, weights, weights_path):
    """
    Iterate over the training dataloader and train a pytorch model.
    After each epoch, validate model and early stop when validation loss function bottoms out.

    Trained model weights will be saved to disk (cfg.ssl.weights).

    :param nn.Module model: pytorch model
    :param train_loader: training data loader
    :param val_loader: validation data loader
    :param cfg: config object.
    :param str my_device: pytorch map device.
    :param weights: training class weights
    """
    optimizer = torch.optim.Adam(
        model.parameters(), lr=cfg.ssl.learning_rate, amsgrad=True
    )

    if cfg.ssl.weighted_loss_fn:
        weights = torch.FloatTensor(weights).to(my_device)
        loss_fn = nn.CrossEntropyLoss(weight=weights)
    else:
        loss_fn = nn.CrossEntropyLoss()

    early_stopping = EarlyStopping(
        patience=cfg.ssl.patience, path=weights_path, verbose=True, trace_func=LOG.info
    )

    for epoch in range(cfg.ssl.num_epoch):
        model.train()
        train_losses = []
        train_acces = []
        for i, (x, y, _) in enumerate(
            tqdm(train_loader, disable=LOG.getEffectiveLevel() > 20)
        ):
            x.requires_grad_(True)
            x = x.to(my_device, dtype=torch.float)
            true_y = y.to(my_device, dtype=torch.long)

            optimizer.zero_grad()

            logits = model(x)
            loss = loss_fn(logits, true_y)
            loss.backward()
            optimizer.step()

            pred_y = torch.argmax(logits, dim=1)
            train_acc = torch.sum(pred_y == true_y)
            train_acc = train_acc / (pred_y.size()[0])

            train_losses.append(loss.cpu().detach())
            train_acces.append(train_acc.cpu().detach())

        val_loss, val_acc = _validate_model(model, val_loader, my_device, loss_fn)

        epoch_len = len(str(cfg.ssl.num_epoch))
        print_msg = (
            f"[{epoch:>{epoch_len}}/{cfg.ssl.num_epoch:>{epoch_len}}] | "
            + f"train_loss: {np.mean(train_losses):.3f} | "
            + f"train_acc: {np.mean(train_acces):.3f} | "
            + f"val_loss: {val_loss:.3f} | "
            + f"val_acc: {val_acc:.2f}"
        )

        early_stopping(val_loss, model)
        LOG.info(print_msg)

        if early_stopping.early_stop:
            LOG.info("Early stopping")
            LOG.info("SSLNet weights saved to %s", weights_path)
            break

    return model

def _validate_model(model, val_loader, my_device, loss_fn):
    """Iterate over a validation data loader and return mean model loss and accuracy."""
    model.eval()
    losses = []
    acces = []
    for i, (x, y, _) in enumerate(val_loader):
        with torch.inference_mode():
            x = x.to(my_device, dtype=torch.float)
            true_y = y.to(my_device, dtype=torch.long)

            logits = model(x)
            loss = loss_fn(logits, true_y)

            pred_y = torch.argmax(logits, dim=1)

            val_acc = torch.sum(pred_y == true_y)
            val_acc = val_acc / (list(pred_y.size())[0])

            losses.append(loss.cpu().detach())
            acces.append(val_acc.cpu().detach())
    losses = np.array(losses)
    acces = np.array(acces)
    return np.mean(losses), np.mean(acces)

class SSLClassifier:
    def __init__(
        self,
        class_labels,
        weights_path,
        winsec=10,
        batch_size=1000,
        pretrained=True,
        load_weights=True,
        verbose=True,
        seed=42,
        learning_rate=1e-4,
        optimisedir="",
        fold=0,
    ):
        """
        SSLClassifier is a class for training and using SSLNet-based classifiers.

        Args:
            class_labels (list): List of class labels.
            weights_path (str): Path to the SSLNet weights file.
            winsec (float): Window size in seconds.
            batch_size (int): Batch size for training and inference.
            pretrained (bool): Whether to use pretrained weights.
            load_weights (bool): When to load weights from saved weights_path.
            verbose (bool): Whether to enable verbose logging.
            seed (int): Random seed for reproducibility.
            learning_rate (float): Learning rate during training.
            optimisedir (str): Path to the optimised parameters file.
            fold (int): Integer representing the cross validation fold number.
        """
        le = LabelEncoder()
        le.fit(class_labels)

        self.le = le
        self.class_labels = class_labels

        optimised_params = (
            load_dict(optimisedir)
            if optimisedir and os.path.exists(optimisedir)
            else {}
        )

        cfg = {
            "ssl_repo_path": SSL_REPO_PATH,
            "data": {
                "output_size": len(class_labels),
                "winsec": winsec,
            },
            **DEFAULT_SSL_CONFIG,
        }

        cfg["ssl"]["learning_rate"] = (
            optimised_params["learning_rate"] if optimised_params else learning_rate
        )

        self.batch_size = (
            optimised_params["batch_size"] if optimised_params else batch_size
        )

        self.pretrained = optimised_params["pretrained"] if pretrained else pretrained

        self.verbose = verbose

        if verbose:
            LOG.setLevel(logging.DEBUG)
        else:
            LOG.setLevel(logging.CRITICAL)

        self.cfg = dotdict(cfg)

        self.my_device = f"cuda:{GPU}" if GPU != -1 else "cpu"

        self.weights_path = weights_path.format(fold)
        self.seed = seed

        if load_weights & os.path.exists(self.weights_path):
            self.model = get_sslnet(
                self.my_device, self.cfg, self.weights_path, pretrained
            )

        else:
            self.model = get_sslnet(self.my_device, self.cfg, None, pretrained)

    def __str__(self):
        return (
            f"SSLClassifier:\n"
            f"  Class Labels: {self.le.classes_}\n"
            f"  SSL Repo Path: {self.cfg.ssl_repo_path}\n"
            f"  Weights Path: {self.weights_path}\n"
            f"  Pretrained: {self.pretrained}\n"
            f"  Winsec: {self.cfg.data.winsec}\n"
            f"  Device: {self.my_device}\n"
        )

    def predict_proba(self, data):
        """
        Compute class probabilities for the given data.

        Args:
            data (str or pd.DataFrame): Input data. Either a file path or a DataFrame.
            batch_size (int): Batch size for inference.

        Returns:
            np.ndarray: Array of class probabilities with shape (n_samples, n_classes).
        """
        np.random.seed(self.seed)
        torch.manual_seed(self.seed)

        dataset = NormalDataset(data)

        dataloader = DataLoader(
            dataset,
            batch_size=self.batch_size,
            shuffle=False,
            num_workers=0,
        )

        LOG.info("SSL inference")
        _, y_logits, _ = predict(
            self.model, dataloader, self.my_device, output_logits=True
        )

        y_score = softmax(y_logits, axis=1)

        return y_score

    def predict_from_proba(self, y_score):
        """
        Predict class labels from class probabilities.

        Args:
            y_score (np.ndarray): Array of class probabilities with shape (n_samples, n_classes).

        Returns:
            np.ndarray: Array of predicted class labels.
        """
        y_pred = np.argmax(y_score, axis=1)

        return self.le.inverse_transform(y_pred)

    def predict(self, data):
        """
        Predict class labels for the given data.

        Args:
            data (str or pd.DataFrame): Input data. Either a file path or a DataFrame.

        Returns:
            np.ndarray: Array of predicted class labels.
        """
        y_score = self.predict_proba(data)

        return self.predict_from_proba(y_score)

    def fit(self, X, y, groups=None, val_split=0.125):
        """
        Fit the SSLNet model to the labeled data.

        Args:
            X (np.ndarray): Input features.
            y (np.ndarray): Target class labels.
            pids (np.ndarray or None): Patient IDs corresponding to the data samples.
            val_split (float): Fraction of data to use for validation.
        """
        np.random.seed(self.seed)
        torch.manual_seed(self.seed)

        if groups is not None:
            unique_pids = np.unique(groups)
            val_ids = np.random.choice(
                unique_pids, int(val_split * len(unique_pids)), replace=False
            )
            mask_val = np.isin(groups, val_ids)

        else:
            num_samples = len(X)
            val_ids = np.random.choice(
                num_samples, int(val_split * num_samples), replace=False
            )
            mask_val = np.zeros(num_samples, dtype=bool)
            mask_val[val_ids] = True

        mask_train = ~mask_val

        y = self.le.transform(y)

        X_train, y_train = X[mask_train], y[mask_train]
        X_val, y_val = X[mask_val], y[mask_val]

        # construct train and validation dataloaders
        train_dataset = NormalDataset(
            X_train,
            y_train,
            name="train",
            is_labelled=True,
            transform=self.cfg.ssl.augmentation,
        )
        val_dataset = NormalDataset(X_val, y_val, name="val", is_labelled=True)

        train_loader = DataLoader(
            train_dataset,
            batch_size=self.batch_size,
            shuffle=True,
            num_workers=0,
        )

        val_loader = DataLoader(
            val_dataset,
            batch_size=self.batch_size,
            shuffle=False,
            num_workers=0,
        )

        sslnet = self.model

        if not self.weights_path:
            raise Exception("No weights path provided")

        LOG.info("SSLNet training")
        train(
            sslnet,
            train_loader,
            val_loader,
            self.cfg,
            self.my_device,
            get_inverse_class_weights(y_train),
            self.weights_path,
        )
        LOG.info("SSLNet weights saved to %s", self.weights_path)

        # update model to saved best weights from training
        self.model = get_sslnet(self.my_device, self.cfg, self.weights_path, False)

    def optimise(
        self,
        X,
        y,
        groups=None,
        param_grid=DEFAULT_PARAM_GRID,
        weightsdir="model_weights/ssl_opt_{}.pt",
        outdir="optimised_params/ssl.pkl",
    ):
        def objective(space):
            models = [
                SSLClassifier(
                    self.class_labels,
                    weightsdir,
                    fold=i,
                    load_weights=False,
                    verbose=False,
                    **space,
                )
                for i in range(3)
            ]

            f1_scores = cross_val_score(
                models,
                X,
                y,
                groups=groups,
                cv=3,
                scoring=f1_macro_score,
            )
            mean_f1 = np.mean(f1_scores)

            return {"loss": -mean_f1, "status": STATUS_OK}

        best_loss = float("inf")
        no_improvement_count = 0
        trials = Trials()

        for iteration in tqdm(range(OPT_MAX_TRIALS)):
            best = fmin(
                fn=objective,
                space=param_grid,
                algo=tpe.suggest,
                max_evals=1,
                trials=trials,
                verbose=0,
                rstate=np.random.default_rng(42),
            )

            current_loss = trials.results[-1]["loss"]

            if current_loss < best_loss:
                best_loss = current_loss
                best_trial = best
                no_improvement_count = 0

            else:
                no_improvement_count += 1

            if no_improvement_count >= OPT_EARLY_STOPPING:
                print(f"Early stopping after {iteration+1} iterations.")
                break

        optimised_params = space_eval(param_grid, best_trial)

        save_dict(optimised_params, outdir)

        return optimised_params

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--datadir", "-d", default="prepared_data")
    parser.add_argument("--optimisedir", "-o", default="outputs/optimised_params")
    parser.add_argument("--weightsdir", "-w", default="outputs/model_weights")
    parser.add_argument("--smoke_test", action="store_true")
    args = parser.parse_args()

    X = np.load(os.path.join(args.datadir, "X.npy"))
    y = np.load(os.path.join(args.datadir, "Y.npy"))
    P = np.load(os.path.join(args.datadir, "P.npy"))

    if args.smoke_test:
        np.random.seed(42)
        smoke_idx = np.random.randint(len(y), size=int(0.01 * len(y)))

        X, y, P = X[smoke_idx], y[smoke_idx], P[smoke_idx]

    smoke_flag = "_smoke" if args.smoke_test else ""
    ssl = SSLClassifier(
        np.unique(y), os.path.join(args.weightsdir, f"ssl_opt{smoke_flag}_{{}}.pt")
    )
    params = ssl.optimise(
        X,
        y,
        P,
        weightsdir=f"{args.weightsdir}/ssl_opt_{{}}.pt",
        outdir=f"{args.optimisedir}/ssl{smoke_flag}.pkl",
    )

    print(f"Best params: {params}")


import logging, logging.config, logging.handlers
import asyncio
import os

from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

import structlog

import ascifight.config as config
import ascifight.routers.orders as orders
import ascifight.routers.states as states
import ascifight.routers.other as other
import ascifight.routers.computations as computations

import ascifight.util as util
import ascifight.game_loop as game_loop

try:
    os.mkdir(config.config["server"]["log_dir"])
except FileExistsError:
    pass

logging.config.dictConfig(util.log_config_dict)

structlog.configure(
    processors=[
        structlog.stdlib.add_log_level,
        structlog.stdlib.PositionalArgumentsFormatter(),
        util.time_stamper,
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
        structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
    ],
    logger_factory=structlog.stdlib.LoggerFactory(),
    wrapper_class=structlog.stdlib.BoundLogger,
    cache_logger_on_first_use=True,
)

root_logger = logging.getLogger()
logger = structlog.get_logger()

tags_metadata = [
    {
        "name": "orders",
        "description": "Operations to give orders to your actors.",
    },
    {
        "name": "states",
        "description": "Operations to get state information about the game.",
    },
    {
        "name": "logistics",
        "description": "Operations to provide quality of life support.",
    },
    {
        "name": "computations",
        "description": "Computational functions that help to create 'AI' scripts.",
    },
    {
        "name": "web-page",
        "description": "Web-pages to display various information.",
    },
]

app = FastAPI(
    openapi_tags=tags_metadata,
    title="A Social, Community Increasing - Fight",
    description=util.api_description,
    version="0.2.0",
    contact={
        "name": "Ralf Kelzenberg",
        "url": "http://vodafone.com",
        "email": "Ralf.Kelzenberg@vodafone.com",
    },
)

app.include_router(orders.router)
app.include_router(states.router)
app.include_router(other.router)
app.include_router(computations.router)
app.mount(
    "/logs", StaticFiles(directory=config.config["server"]["log_dir"]), name="logs"
)

@app.on_event("startup")
async def startup():
    logger.info("Starting server.")
    asyncio.create_task(game_loop.routine())


from pyspark import SparkConf, SparkContext
import re
import numpy as np
import nltk

# uncomment the line below to download nltk data package if you haven't already
# nltk.download('punkt')

""" This homework is using Python 3.10 """
""" The packages used in this lab are PySpark, re, NumPy, and nltk. """

def word_tokenize_and_count(content, stopwords):
    """
    Function Name: word_tokenize_and_count
    This function takes in a string, splits it into words, removes
    stopwords, and returns a list of word count.
    Input: content - a string from document content or from a sentence in a document.
           stopwords - a list containing all stopwords.
    Output: tokenized_word_count - a list of word count in the format of [(word1, count), (word2, count), ...].
    """
    tokenized_word_count = sc.parallelize(nltk.word_tokenize(content)) \
        .filter(lambda x: any(c.isalpha() for c in x)) \
        .filter(lambda x: x not in stopwords) \
        .map(lambda x: (x, 1)) \
        .reduceByKey(lambda x, y: x + y) \
        .collect()
    return tokenized_word_count

def term_freq_and_doc_freq(doc_id_to_content_rdd, stopwords):
    """
    Function Name: term_freq_and_doc_freq
    This function counts term frequencies and document frequencies for each word in each document/sentence, and returns
    term frequency as a list and document frequency as a dictionary.
    Input: data_rdd - a pair RDD with keys equal to docID and values equal to context.
           stopwords - a list containing all stopwords.
    Output: term_freq_list - a list of word count, each element is a tuple (doc_id, [(word1, count), (word2, count),..])
            doc_freq_dict - a dictionary of document frequency with keys equal to words and values equal to frequencies.
    """
    term_freq_list = [(doc_id_to_content[0], word_tokenize_and_count(doc_id_to_content[1], stopwords))
                      for doc_id_to_content in doc_id_to_content_rdd.collect()]

    doc_freq_dict = sc.parallelize(term_freq_list) \
        .flatMap(lambda x: x[1]) \
        .groupByKey() \
        .mapValues(len) \
        .collectAsMap()
    return term_freq_list, doc_freq_dict

def normalized_tf_idf(term_freq, doc_freq, n):
    """
    Function Name: normalized_tf_idf
    This function calculates TF-IDF and normalized TF-IDF, and returns normalized TF-IDF as a RDD.
    Input: term_freq - a list of word count of each document/sentence returned from function term_freq_and_doc_freq.
           doc_freq - a dictionary of document frequency returned from function term_freq_and_doc_freq.
           n - number of documents or number of sentences in a document.
    Output: norm_tf_idf_rdd - a RDD with keys equal to docID and values as lists of tuples containing
    words and corresponding normalized TF-IDFs.
    """
    tf_idf_list = sc.parallelize(term_freq) \
        .mapValues(lambda x: [(word, (1 + np.log10(tf)) * np.log10(n / doc_freq[word])) for (word, tf) in list(x)]) \
        .collect()
    sqrt_sum_of_tf_idf_dict = sc.parallelize(tf_idf_list) \
        .mapValues(lambda words_tf_idf: np.sqrt(sum(tf_idf * tf_idf for (word, tf_idf) in list(words_tf_idf)))) \
        .collectAsMap()
    norm_tf_idf_rdd = sc.parallelize(tf_idf_list) \
        .map(lambda x: (x[0], [(word, tf_idf / sqrt_sum_of_tf_idf_dict[x[0]]) for (word, tf_idf) in list(x[1])]))
    return norm_tf_idf_rdd

def relevance(norm_tf_idf_rdd, q, q_norm):
    """
    Function Name: relevance
    This function calculates relevance of each document/sentence w.r.t the query, and return the relevance as a RDD.
    Input: norm_tf_idf_rdd - a RDD of normalized TF-IDFs returned from function normalized_tf_idf.
           q - a RDD containing query vector.
           q_norm - magnitude of the query vector.
    Output: res_rdd - a pair RDD containing relevance of each document/sentence w.r.t query.
    """
    doc_norm_dict = norm_tf_idf_rdd.mapValues(
        lambda x: np.linalg.norm([norm_tf_idf for (word, norm_tf_idf) in list(x)])) \
        .collectAsMap()
    q_words = q.keys().collect()
    rel_rdd = norm_tf_idf_rdd.mapValues(lambda x: np.sum([value
                                                          if word in q_words else 0 for (word, value) in list(x)])) \
        .map(lambda x: (x[0], x[1] / (doc_norm_dict[x[0]] * q_norm)))
    return rel_rdd

def find_top_10(doc_id_to_content_rdd, stopwords, q, q_norm):
    """
    Function Name: find_top_10
    This function goes through step1-step5 in teh Lab2 description and finds top 10 relevant documents.
    Input: doc_id_to_content_rdd - a pair RDD with keys equal to docID and values equal to document contents.
           stopwords - a list containing all stopwords.
           q - a RDD containing query vector.
           q_norm - magnitude of the query vector.
    Output: top_10_res_rdd - a pair RDD with keys equal to docID and values equal to corresponding relevances w.r.t
    provided query.
    """
    n = doc_id_to_content_rdd.count()
    # step 1: compute term frequency of every word in the document.
    tf_list, df_dict = term_freq_and_doc_freq(doc_id_to_content_rdd, stopwords)
    # step 2&3&4: compute TF-IDF, normalized TF-IDF, and relevance in the function relevance.
    norm_rdd = normalized_tf_idf(tf_list, df_dict, n)
    rel_doc_q_rdd = relevance(norm_rdd, q, q_norm)
    # step 5: sort and get top 10 documents
    top_10_list = rel_doc_q_rdd.sortBy(lambda x: x[1], ascending=False).take(10)  # take top 10 relevance as a list
    top_10_res_rdd = sc.parallelize(top_10_list).map(lambda x: (x[0], x[1]))  # store docID and relevance in a RDD
    return top_10_res_rdd

def find_relevant_sentence(id_list, top_10_rdd, stopwords, q, q_norm):
    """
    Function Name: find_relevant_sentence
    This function goes through step6 in Lab2 description and finds most relevant sentence from each document.
    Input: id_list - a list of top 10 document IDs.
           top_10_rdd - a pair RDD with keys equal to docID and values equal to one sentence from the document.
           stopwords - a list containing all stopwords.
           q - a RDD containing query vector.
           q_norm - magnitude of the query vector.
    Output: res_rdd - a pair RDD with keys equal to docID and values as tuples containing relevance and the sentence.
    """
    # create an empty RDD to store most relevant sentence in each document
    res_rdd = sc.parallelize([])
    for doc_id in id_list:
        doc_rdd = top_10_rdd.filter(lambda x: x[0] == doc_id)  # take all sentences from one document
        n_sentence = doc_rdd.count()  # number of sentences in this document

        # calculate TF, TF-IDF, and normalized TF-IDF for every word, and calculate relevance for every sentence
        tf_line_list, df_line_dict = term_freq_and_doc_freq(doc_rdd, stopwords)
        norm_line_rdd = normalized_tf_idf(tf_line_list, df_line_dict, n_sentence)
        # create a new RDD to give each sentence a unique key
        uniq_key_norm_line_list = [(doc_id + '-' + str(i + 1), norm_tf_idf_list)
                                   for i, norm_tf_idf_list in enumerate(norm_line_rdd.values().collect())]
        uniq_key_norm_line_rdd = sc.parallelize(uniq_key_norm_line_list).map(lambda x: (x[0], x[1]))
        rel_line_q_rdd = relevance(uniq_key_norm_line_rdd, q, q_norm)
        # zip each sentence with its corresponding relevance, and convert list to RDD
        rel_sentence_list = list(zip(doc_rdd.values().collect(), rel_line_q_rdd.values().collect()))
        rel_sentence_rdd = sc.parallelize(rel_sentence_list)
        # find the sentence with the maximum relevance
        max_rel_sentence = rel_sentence_rdd.max(key=lambda x: x[1])
        # combine all sentences with maximum relevance from top 10 documents with docID
        res_rdd = res_rdd.union(sc.parallelize([[doc_id, max_rel_sentence]]).map(lambda x: (x[0], x[1])))
    return res_rdd

if __name__ == '__main__':
    # start = time.time()
    conf = SparkConf().setMaster("local").setAppName("My App")
    sc = SparkContext(conf=conf)

    # import datafiles, query, and stopwords as RDDs
    datafile_rdd = sc.wholeTextFiles('datafiles/*')
    datafile_rdd = datafile_rdd.map(lambda x: (re.findall(r'\d+', x[0])[-1], x[1].lower()))

    query_rdd = sc.textFile('query.txt')
    query_words_rdd = query_rdd.flatMap(lambda w: re.split(r'\W+', w))
    query_list = query_words_rdd.collect()
    query_words_rdd = query_words_rdd.map(lambda w: (w, 1))
    query_norm = np.linalg.norm(query_words_rdd.values().collect())  # calculate magnitude of the query vector

    stopwords_rdd = sc.textFile('stopwords.txt')
    stopwords_set = set(stopwords_rdd.collect())

    # STEP1-5: find top 10 relevant documents
    top_10_id_rel_rdd = find_top_10(datafile_rdd, stopwords_set, query_words_rdd, query_norm)

    doc_id_list = top_10_id_rel_rdd.keys().collect()  # docIDs of top 10 documents in a list
    top_10_doc_rdd = datafile_rdd.filter(lambda x: x[0] in doc_id_list)  # filter top 10 documents from original data
    # split sentences by every new line in the document
    top_10_doc_rdd = top_10_doc_rdd.mapValues(lambda x: x.split('\n')).mapValues(lambda x: x[:-1])
    top_10_doc_sentence_rdd = top_10_doc_rdd.flatMap(lambda x: [(x[0], v) for v in x[1]])

    # STEP6: find the most relevant sentence from each document in top 10
    max_rel_sentence_rdd = \
        find_relevant_sentence(doc_id_list, top_10_doc_sentence_rdd, stopwords_set, query_words_rdd, query_norm)

    # combine top 10 documents' ID, document relevance, most relevant sentence, and sentence relevance in one RDD
    combined_res_rdd = top_10_id_rel_rdd.join(max_rel_sentence_rdd).sortBy(lambda x: x[1][0], ascending=False)

    # STEP7: output the result from RDD
    textfile = open("output.txt", "w")
    for line in combined_res_rdd.collect():
        textfile.write('<' + str(line[0]) + '> ')  # docID
        textfile.write('<' + str(line[1][0]) + '> ')  # document relevance score
        textfile.write('<' + str(line[1][1][0]) + '> ')  # relevant sentence
        textfile.write('<' + str(line[1][1][1]) + '> ')  # sentence relevance score
        textfile.write('\n')  # add new line
    textfile.close()
    sc.stop()


from collections import deque

def isInside(y,x):
    return (0<= y <N) and (0<= x <M)

def BFS():
    while queue:
        y, x = queue.popleft()
        for i in range(4):
            ny = y + dy[i]
            nx = x + dx[i]
            if isInside(ny, nx):
                # 이웃한 토마토가 아직 익지 않았다면 해당 값은 0 일 것.
                if not tomato[ny][nx]:
                    queue.append([ny,nx])
                    tomato[ny][nx] = tomato[y][x] + 1

def Solve():
    res = 0
    for i in range(N):
        if 0 in tomato[i]:
            return -1
        res = max(res, max(tomato[i]))
    return (res - 1)

M, N = map(int, input().split())
queue = deque()
tomato = []

dx = [1,-1,0,0]
dy = [0,0,1,-1]

for i in range(N):
    tomato.append(list(map(int, input().split())))
    for j in range(M):
        if tomato[i][j] is 1:
            queue.append([i, j])

BFS()
print(Solve())


# def divide3(x, y):
#     err1 = "Error, Cannot divide by 0!"
#     try:
#         return x/y
#     except ZeroDivisionError:
#         print("Error!: Cannot divide by zero")
#
#
# divide3(2, 0)

def divide1(x, y):
    if y == 0:
        raise ValueError('Error: Cannot divide by zero!')
    return x / y

def divide2(x, y):
    print(x / y)

def power_recur(x, exp):
    if x == 0:
        return 0
    if exp < 0:
        exp = abs(exp)
        if exp == 0:
            z = 1
        else:
            z = x * power_recur(x, exp - 1)
        return 1 / z

    if exp == 0:
        return 1
    else:
        return x * power_recur(x, exp - 1)

# print(power_recur(3, -2))

def power_recur2(x, exp):
    if x == 0:
        return 0
    if exp < 0:
        return (1 / x) * power_recur2(x, exp + 1)
    if exp == 0:
        return 1
    else:
        return x * power_recur2(x, exp - 1)

# print(power_recur2(2, -2))

def power_iter(x, exp):
    if x == 0:
        return 0
    if exp < 0:
        exp = abs(exp)
        y = 1
        for i in range(exp):
            y = x * y
        return 1 / y
    y = 1
    for i in range(exp):
        y = x * y
    return y

def fib(n):
    a, b = 0, 1
    for i in range(n):
        print(a)
        a, b = b, a + n

def squarelist(list1):
    list2 = [x * x for x in list1]
    return list2

l1 = [1, 3, 4]
print(squarelist(l1))
# list1 = []
# list2 = []
# list3 = list1
#
# if list1 == list2:  # true because both lists are empty
#     print("True")
# else:
#     print("False")
#
# if list1 is list2:  #false because lists are at different memorylocations(list 1 and list 2 refer to diff ..memlocas)
#     print("True")
# else:
#     print("False")
#
# if list1 is list3:  # true because both lists are pointing to the same object
#     print("True")
# else:
#     print("False")

# def power_recur3(x, exp):
#     if exp < 0:
#         if exp == 0:
#             v = 1
#         else:
#             v = x * power_recur2(x, exp + 1)
#         return 1 / v
#
#     if exp == 0:
#         return 1
#     else:
#         return x * power_recur2(x, exp - 1)
#
#
# print(power_recur3(2, -2))


from python_to_you.extensions import configuration
from flask import Flask

##
# Init minimal_app
# This is required in tests
# @param none
# @return Flask app
# #
def minimal_app():
    app = Flask(
            __name__,
            template_folder="blueprints/templates",
            static_folder="blueprints/static"
        )
    configuration.init_app(app)
    return app

##
# This is a factory
# Create app and load all extensions
# @param none
# @return Flask app
# #
def create_app():
    app = minimal_app()
    configuration.load_extensions(app)
    return app


from .. import Provider as PersonProvider

class Provider(PersonProvider):
    formats = (
        "{{first_name}} {{last_name}}",
        "{{first_name}} {{last_name}}",
        "{{last_name}}, {{first_name}}",
    )

    first_names = (
        "Tomas",
        "Lukas",
        "Mantas",
        "Deividas",
        "Arnas",
        "Artūras",
        "Karolis",
        "Dovydas",
        "Dominykas",
        "Darius",
        "Edvinas",
        "Jonas",
        "Martynas",
        "Kajus",
        "Donatas",
        "Andrius",
        "Matas",
        "Rokas",
        "Augustas",
        "Danielius",
        "Mindaugas",
        "Paulius",
        "Marius",
        "Armandas",
        "Edgaras",
        "Jokūbas",
        "Nedas",
        "Tadas",
        "Nerijus",
        "Simonas",
        "Vytautas",
        "Artūras",
        "Robertas",
        "Eimantas",
        "Arijus",
        "Nojus",
        "Egidijus",
        "Aurimas",
        "Emilis",
        "Laurynas",
        "Edvardas",
        "Joris",
        "Pijus",
        "Erikas",
        "Domas",
        "Vilius",
        "Evaldas",
        "Justinas",
        "Aleksandras",
        "Kristupas",
        "Gabrielius",
        "Benas",
        "Gytis",
        "Arminas",
        "Vakris",
        "Tautvydas",
        "Domantas",
        "Justas",
        "Markas",
        "Antanas",
        "Arūnas",
        "Ernestas",
        "Aronas",
        "Vaidas",
        "Ąžuolas",
        "Titas",
        "Giedrius",
        "Ignas",
        "Povilas",
        "Saulius",
        "Julius",
        "Arvydas",
        "Kęstutis",
        "Rytis",
        "Aistis",
        "Gediminas",
        "Algirdas",
        "Naglis",
        "Irmantas",
        "Rolandas",
        "Aivaras",
        "Simas",
        "Faustas",
        "Ramūnas",
        "Šarūnas",
        "Gustas",
        "Tajus",
        "Dainius",
        "Arnoldas",
        "Linas",
        "Rojus",
        "Adomas",
        "Žygimantas",
        "Ričardas",
        "Orestas",
        "Kipras",
        "Juozas",
        "Audrius",
        "Romualdas",
        "Petras",
        "Eleonora",
        "Raminta",
        "Dovilė",
        "Sandra",
        "Dominyka",
        "Ana",
        "Erika",
        "Kristina",
        "Gintarė",
        "Rūta",
        "Edita",
        "Karina",
        "Živilė",
        "Jolanta",
        "Radvilė",
        "Ramunė",
        "Svetlana",
        "Ugnė",
        "Eglė",
        "Viktorija",
        "Justina",
        "Brigita",
        "Rasa",
        "Marija",
        "Giedrė",
        "Iveta",
        "Sonata",
        "Vitalija",
        "Adrija",
        "Goda",
        "Paulina",
        "Kornelija",
        "Liepa",
        "Vakarė",
        "Milda",
        "Meda",
        "Vaida",
        "Izabelė",
        "Jovita",
        "Irma",
        "Žemyna",
        "Leila",
        "Rimantė",
        "Mantė",
        "Rytė",
        "Perla",
        "Greta",
        "Monika",
        "Ieva",
        "Indrė",
        "Ema",
        "Aurelija",
        "Smiltė",
        "Ingrida",
        "Simona",
        "Amelija",
        "Sigita",
        "Olivija",
        "Laurita",
        "Jorūnė",
        "Leticija",
        "Vigilija",
        "Medėja",
        "Laura",
        "Agnė",
        "Evelina",
        "Kotryna",
        "Lėja",
        "Aušra",
        "Neringa",
        "Gerda",
        "Jurgita",
        "Rusnė",
        "Aušrinė",
        "Rita",
        "Elena",
        "Ineta",
        "Ligita",
        "Vasarė",
        "Vėjūnė",
        "Ignė",
        "Gytė",
        "Ariana",
        "Arielė",
        "Vytė",
        "Eidvilė",
        "Karolina",
        "Miglė",
        "Viltė",
        "Jolanta",
        "Enrika",
        "Aurėja",
        "Vanesa",
        "Darija",
        "Reda",
        "Milana",
        "Rugilė",
        "Diana",
    )

    last_names = (
        "Kazlauskas",
        "Jankauskas",
        "Petrauskas",
        "Pocius",
        "Stankevičius",
        "Vsiliauskas",
        "Žukauskas",
        "Butkus",
        "Paulauskas",
        "Urbonas",
        "Kavaliauskas",
        "Sakalauskas",
        "Žukauskas",
        "Akelis",
        "Ambrasas",
        "Kairys",
        "Kalvaitis",
        "Kalvelis",
        "Kalvėnas",
        "Kaupas",
        "Kiška",
        "Gagys",
        "Gailius",
        "Gailys",
        "Gaižauskas",
        "Gaičiūnas",
        "Galdikas",
        "Gintalas",
        "Ginzburgas",
        "Grinius",
        "Gronskis",
        "Nagys",
        "Naujokas",
        "Narušis",
        "Nausėda",
        "Poška",
        "Povilonis",
    )


import os
import unittest

import yaml
import astropy.units as u

from lsst.verify import Metric

class MetricTestCase(unittest.TestCase):
    """Test Metrics and metrics.yaml functionality."""

    def setUp(self):
        yaml_path = os.path.join(os.path.dirname(__file__),
                                 'data', 'metrics', 'testing.yaml')
        with open(yaml_path) as f:
            self.metric_doc = yaml.safe_load(f)

    def test_load_all_yaml_metrics(self):
        """Verify that all metrics from testing.yaml can be loaded."""
        for metric_name in self.metric_doc:
            m = Metric.deserialize(metric_name, **self.metric_doc[metric_name])
            self.assertIsInstance(m, Metric)

    def test_reference_string(self):
        """Verify reference property for different reference datasets."""
        m1 = Metric('test', 'test', '', reference_url='example.com',
                    reference_doc='Doc', reference_page=1)
        self.assertEqual(m1.reference, 'Doc, p. 1, example.com')

        m2 = Metric('test', 'test', '', reference_url='example.com')
        self.assertEqual(m2.reference, 'example.com')

        m3 = Metric('test', 'test', '', reference_url='example.com',
                    reference_doc='Doc')
        self.assertEqual(m3.reference, 'Doc, example.com')

        m4 = Metric('test', 'test', '', reference_doc='Doc', reference_page=1)
        self.assertEqual(m4.reference, 'Doc, p. 1')

        m4 = Metric('test', 'test', '', reference_doc='Doc')
        self.assertEqual(m4.reference, 'Doc')

    def test_json(self):
        """Simple test of the serialized JSON content of a metric."""
        name = 'T1'
        description = 'Test'
        unit = u.mag
        reference_doc = 'TEST-1'
        reference_page = 1
        reference_url = 'example.com'
        m = Metric(name, description, unit,
                   tags=['tagA', 'tagB'],
                   reference_doc=reference_doc,
                   reference_url=reference_url,
                   reference_page=reference_page)

        j = m.json
        self.assertEqual(j['name'], name)
        self.assertEqual(j['description'], description)
        self.assertEqual(j['unit'], unit)
        self.assertEqual(j['reference']['doc'], reference_doc)
        self.assertEqual(j['reference']['page'], reference_page)
        self.assertEqual(j['reference']['url'], reference_url)
        self.assertIn('tagA', j['tags'])
        self.assertIn('tagB', j['tags'])
        self.assertNotIn('tagC', j['tags'])

        # rebuild from json
        m2 = Metric.deserialize(**j)
        self.assertEqual(m, m2)

    def test_str(self):
        m1 = Metric('test', 'test docs', 'arcsec', reference_url='example.com',
                    reference_doc='Doc', reference_page=1)
        self.assertEqual(str(m1), 'test (arcsec): test docs')

        m2 = Metric('test2', 'some words', '')
        self.assertEqual(
            str(m2),
            'test2 (dimensionless_unscaled): some words')

    def test_check_unit(self):
        m = Metric('test', '', 'marcsec')
        self.assertTrue(m.check_unit(5. * u.arcsec))
        self.assertTrue(m.check_unit(5. * u.marcsec))
        self.assertFalse(m.check_unit(5. * u.mag))

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


import torch.nn as nn
import torch
from models.panoptic.sem_head import SemNet
from models import register_model
from models import BaseModel

@register_model("resnet-50-fpn-pan-net")
class PanNet(BaseModel):

    def __init__(self, num_classes, hard_attention=True):
        """
        :param num_classes:
        :param hard_attention:
        """
        super(PanNet, self).__init__()

        self.sem_head = SemNet(num_classes)
        self.endpoints = self.create_endpoints()
        self.use_hard_attention = hard_attention

        self.first_stuff_index = 80

    def forward(self, data, endpoints):
        """
        :param data: contains imgs: tensor of shape BxCxHxW and bboxs: tensor of shape BxNx5, includes N tuples of (ID, x, y, w, h)
        :param endpoints: the endpoints tensor
        :return: semantic and panoptic logits
        """

        if self.use_hard_attention:
            return self.forward_hard(data, endpoints)
        else:
            return self.forward_soft(data, endpoints)

    def forward_hard(self, data, endpoints):
        device = next(self.parameters()).device
        bboxs = data['gt-bboxs'].to(device, non_blocking=True)
        imgs = data['img'].to(device, non_blocking=True)

        endpoints = self.sem_head.forward(data, endpoints)

        num_batches = bboxs.size()[0]

        sem_logits = endpoints['sem-logits']
        # copy all stuff logits
        stuff_logits = sem_logits[:, self.first_stuff_index:, :, :]
        stuff_logits_size = stuff_logits.size()
        inst_logits = torch.zeros(num_batches, bboxs.size()[1], stuff_logits_size[2], stuff_logits_size[3]).to(imgs)

        # extract classes
        class_list_inst = bboxs[:, :, 0]
        class_list_stuff = torch.empty(num_batches, stuff_logits.size()[1]).to(imgs)
        for i in range(num_batches):
            class_list_stuff[i, :] = torch.arange(stuff_logits.size()[1]) + self.first_stuff_index

        class_list = torch.cat((class_list_stuff, class_list_inst), dim=1)

        # extract bbox coords
        bbox_tensor = bboxs[:, :, 1:]

        for i in range(bbox_tensor.size()[1]):
            if bbox_tensor[:, i, :].sum() == 0:
                break
            logit_slice_indices = class_list_inst[:, i].to(dtype=torch.long)
            inst_logits[:, i, :, :] = self._extract_bbox_padded(sem_logits[range(num_batches), logit_slice_indices, ...], bbox_tensor[:, i, :])

        pan_logits = torch.cat((stuff_logits, inst_logits), dim=1)
        max_indices = torch.argmax(pan_logits, dim=1)
        endpoints['inst-pred'] = max_indices
        endpoints['sem-pred'] = torch.empty_like(max_indices)
        for i in range(num_batches):
            endpoints['sem-pred'][i, ...] = class_list[i][max_indices[i]]

        return endpoints

    def _extract_bbox_padded(self, imgs, bboxes):
        imgs = torch.unsqueeze(imgs, dim=1)
        bboxes = bboxes.transpose(0, 1)

        # top left corner
        x0s = bboxes[0]
        y0s = bboxes[1]
        ws = bboxes[2]
        hs = bboxes[3]
        H = imgs.size()[2]
        W = imgs.size()[3]

        offsetx = 2*(x0s+(ws-1)/2)/W-1
        offsety = 2*(y0s+(hs-1)/2)/H-1
        scalex = ws/W
        scaley = hs/H
        zeros = torch.zeros(imgs.size()[0]).to(imgs)

        """
        ------------------------------------------------------------------
        |  bbox_width  |              |     (x0 + (bbox_width -1)/2      |
        |  ----------  |       0      | 2x  -----------------------  -1  |
        |  img_width   |              |             img_width            |
        |----------------------------------------------------------------|
        |              |  bbox_height |     (y0 + (bbox_height -1)/2     |
        |       0      |  ----------- | 2x  -----------------------  -1  |
        |              |  img_height  |             img_height           |
        |----------------------------------------------------------------|
        """

        theta = torch.stack((
                torch.stack((scalex, zeros, offsetx), dim=1),
                torch.stack((zeros, scaley, offsety), dim=1)),
                dim=1
                )
        #theta = torch.Tensor([[[w/W, 0, offsetx], [0, h/H, offsety]]])

        indices = nn.functional.affine_grid(theta, torch.Size((imgs.size()[0], 1, 256, 256)))

        output_up = nn.functional.grid_sample(imgs, indices, mode='bilinear', padding_mode='zeros')

        """
        -------------------------------------------------------------------------
        |   img_width  |              |     (img_width/2 - bbox_width/2 - x0)   |
        |  ----------  |       0      | 2x  --------------------------------    |
        |  bbox_width  |              |                 bbox_width              |
        |-----------------------------------------------------------------------|
        |              |   img_height |     (img_height/2 - bbox_height/2 - y0) |
        |       0      |  ----------- | 2x  ----------------------------------  |
        |              |  bbox_height |                 bbox_height             |
        |-----------------------------------------------------------------------|
        """

        offsetx = (W/2 - ws/2-x0s)/ws*2
        offsety = (H/2 - hs/2-y0s)/hs*2
        scalex = W/ws
        scaley = H/hs

        theta = torch.stack((
                torch.stack((scalex, zeros, offsetx), dim=1),
                torch.stack((zeros, scaley, offsety), dim=1)),
                dim=1
                )

        #theta = torch.Tensor([[[W/w, 0, offsetx], [0, H/h, offsety]]])

        indices = nn.functional.affine_grid(theta, (imgs.size()[0], 1, H, W))

        output = nn.functional.grid_sample(output_up, indices, mode='nearest', padding_mode='zeros')
        output = torch.squeeze(output, dim=1)
        return output

    def forward_soft(self, *x):
        pass

    @staticmethod
    def build(cfg):
        model = PanNet(cfg['num_classes'])
        skips = ["fc"]
        duplicates = []
        return model, skips, duplicates

    @staticmethod
    def create_endpoints():
        endpoints = {}
        endpoints['sem-pred'] = None
        endpoints['inst-pred'] = None
        endpoints.update(SemNet.create_endpoints())
        return endpoints


import io
import mimetypes
import uuid

class MultiPartForm:
    def __init__(self):
        self.fields = {}
        self.files = []

    def __setitem__(self, name, value):
        self.fields[name] = value

    def add_file(self, field, filename, data, mimetype=None):
        if mimetype is None:
            mimetype = (mimetypes.guess_type(filename)[0] or
                        'application/octet-stream')
        self.files.append((field, filename, mimetype, data))

    def _generate_bytes(self, boundary):
        buffer = io.BytesIO()
        for field, value in self.fields.items():
            buffer.write(b'--' + boundary + b'\r\n')
            buffer.write('Content-Disposition: form-data; '
                         'name="{}"\r\n'.format(field).encode('utf-8'))
            buffer.write(b'\r\n')
            buffer.write(value.encode('utf-8'))
            buffer.write(b'\r\n')
        for field, filename, f_content_type, body in self.files:
            buffer.write(b'--' + boundary + b'\r\n')
            buffer.write('Content-Disposition: file; '
                         'name="{}"; filename="{}"\r\n'.format(
                             field, filename
                         ).encode('utf-8'))
            buffer.write('Content-Type: {}\r\n'.format(
                f_content_type
            ).encode('utf-8'))
            buffer.write(b'\r\n')
            buffer.write(body)
            buffer.write(b'\r\n')
        buffer.write(b'--' + boundary + b'--\r\n')
        return buffer.getvalue()

    def encode(self):
        boundary = uuid.uuid4().hex.encode('ascii')
        while boundary in self._generate_bytes(boundary=b'NOBOUNDARY'):
            boundary = uuid.uuid4().hex.encode('ascii')

        content_type = 'multipart/form-data; boundary={}'.format(
            boundary.decode('ascii')
        )
        return content_type, self._generate_bytes(boundary)

form = MultiPartForm()
form['name'] = 'value'
form.add_file('file1', 'somefile.txt', b'Some Content', 'text/plain')
content_type, form_body = form.encode()
print(content_type, form_body.decode('ascii'))

from web_03 import http_request
_, resp = http_request('https://httpbin.org/post', method='POST',
                       data=form_body, headers={'Content-Type': content_type})
print(resp)


# views.py

from django.shortcuts import render, HttpResponse
import requests

# Create your views here.

def index(request):
    return HttpResponse('Hello World!')

def test(request):
    return HttpResponse('My second view!')

def profile(request):
    parsedData = []
    if request.method == 'POST':
        username = request.POST.get('user')
        req = requests.get('https://api.github.com/users/' + username)
        jsonList = []
        jsonList.append(req.json())
        userData = {}
        for data in jsonList:
            userData['name'] = data['name']
            userData['blog'] = data['blog']
            userData['email'] = data['email']
            userData['public_gists'] = data['public_gists']
            userData['public_repos'] = data['public_repos']
            userData['avatar_url'] = data['avatar_url']
            userData['followers'] = data['followers']
            userData['following'] = data['following']
        parsedData.append(userData)
    return render(request, 'app/profile.html', {'data': parsedData})