#!/usr/bin/env python
#
# lib.py
#
# Helper code for CLI for interacting with switches via console device
#

try:
    import click
    import re
    import swsssdk
    import subprocess
    import sys
except ImportError as e:
    raise ImportError("%s - required module not found" % str(e))

DEVICE_PREFIX = "/dev/ttyUSB"

ERR_CMD = 1
ERR_DEV = 2

CONSOLE_PORT_TABLE = "CONSOLE_PORT"
BAUD_KEY = "baud_rate"
DEVICE_KEY = "remote_device"
FLOW_KEY = "flow_control"
DEFAULT_BAUD = "9600"

# QUIET == True => picocom will not output any messages, and pexpect will wait for console
#                  switch login or command line to let user interact with shell
#        Downside: if console switch output ever does not match DEV_READY_MSG, program will think connection failed
# QUIET == False => picocom will output messages - welcome message is caught by pexpect, so successful
#                   connection will always lead to user interacting with shell
#         Downside: at end of session, picocom will print exit message, exposing picocom to user
QUIET = False
DEV_READY_MSG = r"([Ll]ogin:|[Pp]assword:|[$>#])" # login prompt or command line prompt
TIMEOUT_SEC = 0.2

# runs command, exit if stderr is written to, returns stdout otherwise
# input: cmd (str), output: output of cmd (str)
def run_command(cmd):
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    output = proc.stdout.read()
    error = proc.stderr.read()
    if error != "":
        click.echo("Command resulted in error: {}".format(error))
        sys.exit(ERR_CMD)
    return output

# returns a sorted list of all devices (whose name matches DEVICE_PREFIX)
def getAllDevices():
    cmd = "ls " + DEVICE_PREFIX + "*"
    output = run_command(cmd)

    devices = output.split('\n')
    devices = list(filter(lambda dev: re.match(DEVICE_PREFIX + r"\d+", dev) != None, devices))
    devices.sort(key=lambda dev: int(dev[len(DEVICE_PREFIX):]))

    return devices

# exits if inputted line number does not correspond to a device
# input: linenum
def checkDevice(linenum):
    devices = getAllDevices()
    if DEVICE_PREFIX + str(linenum) not in devices:
        click.echo("Line number {} does not exist".format(linenum))
        sys.exit(ERR_DEV)

# returns a dictionary of busy devices and their info
#     maps line number to (pid, process start time)
def getBusyDevices():
    cmd = 'ps -eo pid,lstart,cmd | grep -E "(mini|pico)com"'
    output = run_command(cmd)
    processes = output.split('\n')

    # matches any number of spaces then any number of digits
    regexPid = r" *(\d+)"
    # matches anything of form: Xxx Xxx ( 0)or(00) 00:00:00 0000
    regexDate = r"([A-Z][a-z]{2} [A-Z][a-z]{2} [\d ]\d \d{2}:\d{2}:\d{2} \d{4})"
    # matches any non-whitespace characters ending in minicom or picocom,
    # then a space and any chars followed by /dev/ttyUSB<any digits>,
    # then a space and any chars
    regexCmd = r"\S*(?:(?:mini)|(?:pico))com .*" + DEVICE_PREFIX + r"(\d+)(?: .*)?"
    regexProcess = re.compile(r"^"+regexPid+r" "+regexDate+r" "+regexCmd+r"$")

    busyDevices = {}
    for process in processes:
        match = regexProcess.match(process)
        if match != None:
            pid = match.group(1)
            date = match.group(2)
            linenum_key = match.group(3)
            busyDevices[linenum_key] = (pid, date)
    return busyDevices

# returns actual baud rate, configured baud rate,
# and flow control settings of device corresponding to line number
# input: linenum (str), output: (actual baud (str), configured baud (str), flow control (bool))
def getConnectionInfo(linenum):
    config_db = ConfigDBConnector()
    config_db.connect()
    entry = config_db.get_entry(CONSOLE_PORT_TABLE, str(linenum))

    conf_baud = "-" if BAUD_KEY not in entry else entry[BAUD_KEY]
    act_baud = DEFAULT_BAUD if conf_baud == "-" else conf_baud
    flow_control = False
    if FLOW_KEY in entry and entry[FLOW_KEY] == "1":
        flow_control = True

    return (act_baud, conf_baud, flow_control)

# returns the line number corresponding to target, or exits if line number cannot be found
# if deviceBool, interprets target as device name
# otherwise interprets target as line number
# input: target (str), deviceBool (bool), output: linenum (str)
def getLineNumber(target, deviceBool):
    if not deviceBool:
        return target

    config_db = ConfigDBConnector()
    config_db.connect()

    devices = getAllDevices()
    linenums = list(map(lambda dev: dev[len(DEVICE_PREFIX):], devices))

    for linenum in linenums:
        entry = config_db.get_entry(CONSOLE_PORT_TABLE, linenum)
        if DEVICE_KEY in entry and entry[DEVICE_KEY] == target:
            return linenum

    click.echo("Device {} does not exist".format(target))
    sys.exit(ERR_DEV)
    return ""


from .models import Event, Slot, SignUp
from groups.methods import get_user_group_membership, group_to_json
from authentication.methods import user_to_json
from common.parsers import parse_datetime_to_epoch_time

# Constants
from common.constants import (
    EVENT_ID,
    TITLE,
    DESCRIPTION,
    START_DATE_TIME,
    END_DATE_TIME,
    LOCATION,
    IS_PUBLIC,
    GROUP,
    IMAGE_URL,
)
from common.constants import TAG, TAG_NAME, TAG_ID
from common.constants import (
    SLOT,
    SLOT_ID,
    SIGNUP_ID,
    CONFIRMED_SIGNUP_COUNT,
    PENDING_SIGNUP_COUNT,
    AVAILABLE_SLOT_COUNT,
    SIGNUP_DATE,
    IS_CONFIRMED,
    IS_ELIGIBLE,
    IS_SIGNED_UP,
    GENERAL_GROUP_TAG_NAME,
    SIGNUPS,
    CONFIRMED_SIGNUPS,
    PENDING_SIGNUPS,
    USER,
    HAS_ATTENDED
)

def get_events(*args, **kwargs):
    return Event.objects.filter(*args, **kwargs)

def get_slots(*args, **kwargs):
    return Slot.objects.filter(*args, **kwargs)

def get_signups(*args, **kwargs):
    return SignUp.objects.filter(*args, **kwargs)

def event_to_json(event, include_group=True):
    data = {
        EVENT_ID: event.id,
        TITLE: event.title,
        DESCRIPTION: event.description,
        START_DATE_TIME: parse_datetime_to_epoch_time(event.start_date_time),
        END_DATE_TIME: parse_datetime_to_epoch_time(event.end_date_time),
        LOCATION: event.location,
        IS_PUBLIC: event.is_public,
    }
    if event.image_url:
        data[IMAGE_URL] = f"https://api.slotify.club{event.image_url.url}"

    if include_group:
        data[GROUP] = group_to_json(event.group)
    return data

def signup_to_json(signup, include_slot=True, include_user=True):
    data = {
        SIGNUP_ID: signup.id,
        SIGNUP_DATE: parse_datetime_to_epoch_time(signup.created_at),
        IS_CONFIRMED: signup.is_confirmed,
        HAS_ATTENDED: signup.has_attended,
    }

    if include_slot:
        data[SLOT] = slot_to_json(signup.slot, include_availability=False)

    if include_user:
        data[USER] = user_to_json(signup.user)

    return data

def get_slot_availability_data(slot):
    confirmed_signups = len(get_signups(slot=slot, is_confirmed=True))
    pending_signups = len(get_signups(slot=slot, is_confirmed=False))
    available_slots = slot.limit - confirmed_signups

    return confirmed_signups, pending_signups, available_slots

def get_existing_signup_for_slot(slot, user):
    try:
        return get_signups(slot=slot, user=user).get()
    except SignUp.DoesNotExist:
        return None

def get_existing_signup_for_any_event_slot(event, user):
    try:
        return get_signups(slot__event=event, user=user).get()
    except SignUp.DoesNotExist:
        return None

def slot_to_json(slot, include_availability=True, user=None, include_signups=False):
    data = {TAG: {TAG_NAME: slot.tag.name, TAG_ID: slot.tag.id}, SLOT_ID: slot.id}

    if include_availability:
        confirmed, pending, available = get_slot_availability_data(slot)

        data[CONFIRMED_SIGNUP_COUNT] = confirmed
        data[PENDING_SIGNUP_COUNT] = pending
        data[AVAILABLE_SLOT_COUNT] = available

    if include_signups:
        confirmed_signups = get_signups(slot=slot, is_confirmed=True)
        pending_signups = get_signups(slot=slot, is_confirmed=False)

        signup_data = {
            CONFIRMED_SIGNUPS: [
                signup_to_json(signup, include_slot=False)
                for signup in confirmed_signups
            ],
            PENDING_SIGNUPS: [
                signup_to_json(signup, include_slot=False) for signup in pending_signups
            ],
        }

        data[SIGNUPS] = signup_data

    # If user is specified, return user-specific data for the slot
    if not user:
        return data

    existing_signup = get_existing_signup_for_slot(slot, user)
    data[IS_SIGNED_UP] = existing_signup is not None
    data[IS_CONFIRMED] = existing_signup is not None and existing_signup.is_confirmed

    is_eligible = True

    if slot.tag.is_exclusive_to_groups:
        group = slot.event.group
        membership = get_user_group_membership(user=user, group=group)
        if membership is None or not membership.is_approved:
            is_eligible = False

        # Check if this is a general slot (any group members can join this slot regardless of tag)
        # If not general slot, check if member has a matching slot tag
        if (
            not is_general_group_slot(slot)
            and membership
            and slot.tag != membership.tag
        ):
            is_eligible = False

    data[IS_ELIGIBLE] = is_eligible

    return data

def is_general_group_slot(slot):
    return slot.tag.name == GENERAL_GROUP_TAG_NAME


from rest_framework import permissions
from rest_framework.views import Request, View, status
from championships.models import Championship
from teams.models import Team
from datetime import datetime

class IsChampionshipOwner(permissions.BasePermission):
    def has_object_permission(
        self, request: Request, view: View, champs: Championship
    ) -> bool:
        self.message = "You're not the championship owner to perform this action"
        return request.user.is_authenticated and request.user == champs.staff_owner

class IsATeamOwner(permissions.BasePermission):
    def has_object_permission(self, request: Request, view: View, team: Team) -> bool:
        self.message = "You're not a team owner to perform this action"
        check_owner = False

        for user in team.users.all():
            if user.id == request.user.id and user.is_team_owner:
                check_owner = True

        return check_owner

class HaveFivePlayers(permissions.BasePermission):
    def has_object_permission(self, request: Request, view: View, team: Team) -> bool:
        self.message = "Your team must have at least 5 players"

        team_players_length = team.users.count()

        return team_players_length >= 5

class IsTeamEsportCorrectly(permissions.BasePermission):
    def has_object_permission(self, request: Request, view: View, team: Team) -> bool:
        self.message = "Your team do not have same e_sport"

        cs_id = view.kwargs["cs_id"]
        champ = Championship.objects.get(id=cs_id)

        return team.e_sport == champ.e_sport

class IsChampionshipFull(permissions.BasePermission):
    def has_object_permission(self, request: Request, view: View, team: Team) -> bool:
        self.message = "The championship is full"

        cs_id = view.kwargs["cs_id"]
        champ = Championship.objects.get(id=cs_id)

        number_teams = champ.teams.count()

        return number_teams < 8

class HasAnotherChampionshipAroundSevenDays(permissions.BasePermission):
    def has_object_permission(self, request: Request, view: View, team: Team) -> bool:
        self.message = "You've other championship around this championship date"

        day_7_in_seconds = 604800

        if team.championship.count() == 0:
            return True

        championship_id = view.kwargs["cs_id"]
        championship = Championship.objects.get(id=championship_id)
        champ_date = datetime(
            championship.initial_date.year,
            championship.initial_date.month,
            championship.initial_date.day,
        )
        championship_date_in_seconds = champ_date.timestamp()

        team_championships_date = team.championship.values("initial_date")
        for initial_date in team_championships_date:
            initial_datetime = datetime(
                initial_date["initial_date"].year,
                initial_date["initial_date"].month,
                initial_date["initial_date"].day,
            )
            initial_datetime_seconds = initial_datetime.timestamp()
            diference_date = abs(
                championship_date_in_seconds - initial_datetime_seconds
            )

            if diference_date < day_7_in_seconds:
                return False

        return True

class InitialDateProvidedIsAtLeastSevenDaysAfter(permissions.BasePermission):
    def has_permission(self, request: Request, view: View) -> bool:
        self.message = "Only initial dates after 7 days by now"
        day_7_in_seconds = 604800
        initial_date_list = request.data["initial_date"].split("-")
        date_now = datetime.now().timestamp()
        champ_date = datetime(
            int(initial_date_list[0]),
            int(initial_date_list[1]),
            int(initial_date_list[2]),
        )
        championship_date_in_seconds = champ_date.timestamp()
        sub = championship_date_in_seconds - date_now
        return sub > day_7_in_seconds

class IsChampOwnerTryngToEnterInIt(permissions.BasePermission):
    def has_object_permission(self, request: Request, view: View, team: Team) -> bool:
        self.message = "Championship owner can't play it"
        cs_id = view.kwargs["cs_id"]
        champ = Championship.objects.get(id=cs_id)
        champ_owner_id = champ.staff_owner.id

        for user in team.users.all():
            if user.id == champ_owner_id:
                return False

        return True

class TeamOwnerHasBalanceToEnterInChampionship(permissions.BasePermission):
    def has_object_permission(self, request: Request, view: View, team: Team) -> bool:
        self.message = "Don't have enough money"

        user_balance = request.user.history.balance

        cs_id = view.kwargs["cs_id"]
        champ = Championship.objects.get(id=cs_id)

        champ_entry_amount = champ.entry_amount

        return user_balance >= champ_entry_amount


import requests
import lxml.etree
import re

session = requests.Session()
response = session.get('http://www.baidu.com')
content = response.content.decode()
# print(content)

# -------------解析

doc = lxml.etree.HTML(content)
tree = doc.getroottree()
nodes = tree.xpath('//title/text()')
for i in nodes:
    print(i)


import os
from . import utils
import ipywidgets as widgets
from IPython.display import display, clear_output, Javascript

class FileBrowser(object):
    def __init__(self, funcName):
        self.path = os.getcwd()
        self._update_files()
        self._chosenFileName = None
        self.funcName = funcName

    @property
    def chosenFileName(self):
        assert self._chosenFileName is not None, "File was not chosen"
        return self._chosenFileName

    def _update_files(self):
        self.files = list()
        self.dirs = list()
        if(os.path.isdir(self.path)):
            content = os.listdir(self.path)
            content.sort()
            for f in content:
                ff = self.path + "/" + f
                if os.path.isdir(ff):
                    self.dirs.append(f)
                else:
                    self.files.append(f)

    def widget(self):
        box = widgets.VBox()
        self._update(box)
        return box

    def _update(self, box):
        clear_output()
        def on_click(b):
            if b.description == '..':
                self.path = os.path.split(self.path)[0]
            else:
                self.path = os.path.join(self.path, b.description)
            self._update_files()
            self._update(box)

        buttons = []
        if self.files or self.dirs:
            button = widgets.Button(description='..')
            button.add_class('folder')
            button.add_class('parentFolder')
            button.on_click(on_click)
            buttons.append(button)
        for f in self.dirs:
            button = widgets.Button(description=f)
            button.add_class('folder')
            button.on_click(on_click)
            buttons.append(button)
        for f in self.files:
            button = widgets.Button(description=f)
            button.add_class('file')
            button.on_click(on_click)
            buttons.append(button)
        if len(buttons) == 0:
            buttons.append(widgets.HTML("Replace "+self.funcName+"() by the following expression to save chosen path:
"+self.funcName+"('"+self.path+"',...)"))
        box.children = tuple([widgets.HTML("
%s
" % (self.path,))] + buttons)
        box.add_class('fileBrowser')
        display(box)
        if len(buttons) == 0: self._chosenFileName = self.path

def openFile(funcName, *p):
    if len(p)>0 :
        display(widgets.HTML("Delete path argument to choose file interactively: "+funcName+'()'))
        return type('obj', (object,), {'chosenFileName' : p[0]})
    assert utils.isJupyterNotebook()
    f = FileBrowser(funcName)
    f.widget()
    return f


# This exports all networks and their base attributes from an organization to a file
#  and then imports them to another organization.
#
# You need to have Python 3 and the Requests module installed. You
#  can download the module here: https://github.com/kennethreitz/requests
#  or install it using pip.
#
# To run the script, enter:
#  python copynetworks.py -k <API key> [-s <source org name>] [-d <destination org name>] [-f <file path>]
#
# Parameters '-s', '-d' and '-f' are optional, but at least two of them must be given.
#
# ** If '-s' and '-d' are given, data will be copied from src org to dst org
# ** If '-s' and '-f' are given, data will be dumped from src org to file
# ** If '-d' and '-f' are given, data will be imported from file to dst org
#
# To make script chaining easier, all lines containing informational messages to the user
#  start with the character @

import sys, getopt, requests, json

def printusertext(p_message):
	#prints a line of text that is meant for the user to read
	#do not process these lines when chaining scripts
	print('@ %s' % p_message)

def printhelp():
	#prints help text

	printusertext('This is a script that copies networks and their base attributes from a source organization')
	printusertext('to another, called the destination organization. Both source, destination org and file ')
	printusertext('parameters are optional, but at least two of them must be given.')
	printusertext('')
	printusertext('Usage:')
	printusertext('python copynetworks.py -k <API key> [-s <source org name>] [-d <dest org name>] [-f <file path>]')
	printusertext('')
	printusertext(" ** If '-s' and '-d' are given, data will be copied from src org to dst org")
	printusertext(" ** If '-s' and '-f' are given, data will be dumped from src org to file")
	printusertext(" ** If '-d' and '-f' are given, data will be imported from file to dst org")
	printusertext('')
	printusertext('Use double quotes ("") in Windows to pass arguments containing spaces. Names are case-sensitive.')

def getorgid(p_apikey, p_orgname):
	#looks up org id for a specific org name
	#on failure returns 'null'

	r = requests.get('https://dashboard.meraki.com/api/v0/organizations', headers={'X-Cisco-Meraki-API-Key': p_apikey, 'Content-Type': 'application/json'})

	if r.status_code != requests.codes.ok:
		return 'null'

	rjson = r.json()

	for record in rjson:
		if record['name'] == p_orgname:
			return record['id']
	return('null')

def getshardurl(p_apikey, p_orgid):
	#quick-n-dirty patch
	return("api.meraki.com")

def getnwlist(p_apikey, p_shardurl, p_orgid):
	#returns a list of all networks in an organization
	#on failure returns a single record with 'null' name and id

	r = requests.get('https://%s/api/v0/organizations/%s/networks' % (p_shardurl, p_orgid), headers={'X-Cisco-Meraki-API-Key': p_apikey, 'Content-Type': 'application/json'})

	returnvalue = []
	if r.status_code != requests.codes.ok:
		returnvalue.append({'name': 'null', 'id': 'null'})
		return(returnvalue)

	return(r.json())

def getnwid(p_apikey, p_shardurl, p_orgid, p_nwname):
	#looks up network id for a network name
	#on failure returns 'null'

	r = requests.get('https://%s/api/v0/organizations/%s/networks' % (p_shardurl, p_orgid), headers={'X-Cisco-Meraki-API-Key': p_apikey, 'Content-Type': 'application/json'})

	if r.status_code != requests.codes.ok:
		return 'null'

	rjson = r.json()

	for record in rjson:
		if record['name'] == p_nwname:
			return record['id']
	return('null')

def createnw (p_apikey, p_shardurl, p_dstorg, p_nwdata):
	#creates network if one does not already exist with the same name

	#check if network exists
	getnwresult = getnwid(p_apikey, p_shardurl, p_dstorg, p_nwdata['name'])
	if getnwresult != 'null':
		printusertext('WARNING: Skipping network "%s" (Already exists)' % p_nwdata['name'])
		return('null')

	if p_nwdata['type'] == 'combined':
		#find actual device types
		nwtype = 'wireless switch appliance'
	else:
		nwtype = p_nwdata['type']
	if nwtype != 'systems manager':
		r = requests.post('https://%s/api/v0/organizations/%s/networks' % (p_shardurl, p_dstorg), data=json.dumps({'timeZone': p_nwdata['timeZone'], 'tags': p_nwdata['tags'], 'name': p_nwdata['name'], 'organizationId': p_dstorg, 'type': nwtype}), headers={'X-Cisco-Meraki-API-Key': p_apikey, 'Content-Type': 'application/json'})
	else:
		printusertext('WARNING: Skipping network "%s" (Cannot create SM networks)' % p_nwdata['name'])

	return('ok')

def main(argv):
	#get command line arguments
	arg_apikey = 'null'
	arg_srcorg = 'null'
	arg_dstorg = 'null'
	arg_filepath = 'null'

	try:
		opts, args = getopt.getopt(argv, 'hk:s:d:f:')
	except getopt.GetoptError:
		printhelp()
		sys.exit(2)

	for opt, arg in opts:
		if opt == '-h':
			printhelp()
			sys.exit()
		elif opt == '-k':
			arg_apikey = arg
		elif opt == '-s':
			arg_srcorg = arg
		elif opt == '-d':
			arg_dstorg = arg
		elif opt == '-f':
			arg_filepath = arg

	#count how many optional parameters have been given
	optionscounter = 0
	if arg_srcorg != 'null':
		optionscounter += 1
	if arg_dstorg != 'null':
		optionscounter += 1
	if arg_filepath != 'null':
		optionscounter += 1

	if arg_apikey == 'null' or optionscounter < 2:
		printhelp()
		sys.exit(2)

	#get source organization id corresponding to org name provided by user
	mode_gotsource = True
	if arg_srcorg == 'null':
		mode_gotsource = False
	else:
		srcorgid = getorgid(arg_apikey, arg_srcorg)
		if srcorgid == 'null':
			printusertext('ERROR: Fetching source organization failed')
			sys.exit(2)
		#get shard URL where Org is stored
		srcshardurl = getshardurl(arg_apikey, srcorgid)
		if srcshardurl == 'null':
			printusertext('ERROR: Fetching Meraki cloud shard URL for source org failed')
			printusertext('       Does it have API access enabled?')
			sys.exit(2)

	#get destination organization id corresponding to org name provided by user
	mode_gotdestination = True
	if arg_dstorg == 'null':
		mode_gotdestination = False
	else:
		dstorgid = getorgid(arg_apikey, arg_dstorg)
		if dstorgid == 'null':
			printusertext('ERROR: Fetching destination organization failed')
			sys.exit(2)
		#get shard URL where Org is stored
		dstshardurl = getshardurl(arg_apikey, dstorgid)
		if dstshardurl == 'null':
			printusertext('ERROR: Fetching Meraki cloud shard URL for destination org failed')
			printusertext('       Does it have API access enabled?')
			sys.exit(2)

	#if user gave a source, fetch networks and their attributes from src org
	if mode_gotsource:
		nwlist = getnwlist(arg_apikey, srcshardurl, srcorgid)

		if nwlist[0]['id'] == 'null':
			printusertext('ERROR: Fetching network list from source org failed')
			sys.exit(2)

	#open buffer file for writing
	mode_gotfile = True
	if arg_filepath == 'null':
		mode_gotfile = False
	if mode_gotfile:
		#if source given, open file for writing (output)
		if mode_gotsource:
			try:
				f = open(arg_filepath, 'w')
			except:
				printusertext('ERROR: Unable to open file for writing')
				sys.exit(2)
		#if source omitted, open file for reading (input)
		else:
			try:
				f = open(arg_filepath, 'r')
			except:
				printusertext('ERROR: Unable to open file for reading')
				sys.exit(2)

	#if user gave a source and a file, dump source org networks to file
	if mode_gotsource and mode_gotfile:
		try:
			json.dump(nwlist, f)
		except:
				printusertext('ERROR: Writing to output file failed')
				sys.exit(2)

	#if user did not give source, but gave file, load networks list from file
	if not(mode_gotsource) and mode_gotfile:
		try:
			nwlist = json.load(f)
		except:
				printusertext('ERROR: Reading from input file failed')
				sys.exit(2)

	#if user gave destination org, create networks according to nwlist content
	if mode_gotdestination:
		i = 0
		for i in range (0, len(nwlist)):
			createnw (arg_apikey, dstshardurl, dstorgid, nwlist[i])

	#reached end of script
	printusertext('End of script.')

if __name__ == '__main__':
	main(sys.argv[1:])


import torch
import torch.nn as nn
import torch.nn.functional as F

from timm.models.layers import DropPath, trunc_normal_
import math
import numpy as np
from models.head import *

up_kwargs = {'mode': 'bilinear', 'align_corners': False}

def load_state_dict(module, state_dict, strict=False):
    """Load state_dict to a module.
    This method is modified from :meth:`torch.nn.Module.load_state_dict`.
    Default value for ``strict`` is set to ``False`` and the message for
    param mismatch will be shown even if strict is False.
    Args:
        module (Module): Module that receives the state_dict.
        state_dict (OrderedDict): Weights.
        strict (bool): whether to strictly enforce that the keys
            in :attr:`state_dict` match the keys returned by this module's
            :meth:`~torch.nn.Module.state_dict` function. Default: ``False``.
        logger (:obj:`logging.Logger`, optional): Logger to log the error
            message. If not specified, print function will be used.
    """
    unexpected_keys = []
    all_missing_keys = []
    err_msg = []

    metadata = getattr(state_dict, '_metadata', None)
    state_dict = state_dict.copy()
    if metadata is not None:
        state_dict._metadata = metadata

    # use _load_from_state_dict to enable checkpoint version control
    def load(module, prefix=''):
        # recursively check parallel module in case that the model has a
        # complicated structure, e.g., nn.Module(nn.Module(DDP))
        local_metadata = {} if metadata is None else metadata.get(
            prefix[:-1], {})
        module._load_from_state_dict(state_dict, prefix, local_metadata, True,
                                     all_missing_keys, unexpected_keys,
                                     err_msg)
        for name, child in module._modules.items():
            if child is not None:
                load(child, prefix + name + '.')

    load(module)
    load = None  # break load->load reference cycle
    # ignore "num_batches_tracked" of BN layers
    missing_keys = [
        key for key in all_missing_keys if 'num_batches_tracked' not in key
    ]

    if unexpected_keys:
        err_msg.append('unexpected key in source '
                       f'state_dict: {", ".join(unexpected_keys)}\n')
    if missing_keys:
        err_msg.append(
            f'missing keys in source state_dict: {", ".join(missing_keys)}\n')

    if len(err_msg) > 0:
        err_msg.insert(
            0, 'The model and loaded state dict do not match exactly\n')
        err_msg = '\n'.join(err_msg)
        if strict:
            raise RuntimeError(err_msg)
        else:
            print(err_msg)

def resize_pos_embed_4d(posemb, posemb_new):
    '''return new position embedding'''
    # Rescale the grid of position embeddings when loading from state_dict. Adapted from
    # https://github.com/google-research/vision_transformer/blob/00883dd691c63a6830751563748663526e811cee/vit_jax/checkpoint.py#L224
    gs_old = posemb.shape[1]  # 14
    gs_new = posemb_new.shape[1]  # 24
    posemb_grid = posemb
    posemb_grid = posemb_grid.permute(0, 3, 1,
                                      2)  # [1, 14, 14, dim]->[1, dim, 14, 14]
    posemb_grid = F.interpolate(posemb_grid, size=(gs_new, gs_new), mode='bicubic')  # [1, dim, 14, 14] -> [1, dim, 24, 24]
    posemb_grid = posemb_grid.permute(0, 2, 3, 1)  # [1, dim, 24, 24]->[1, 24, 24, dim]
    return posemb_grid

def load_checkpoint(model,
                    filename,
                    map_location='cpu',
                    strict=False,
                    ):
    """Load checkpoint from a file or URI.
    Args:
        model (Module): Module to load checkpoint.
        filename (str): Accept local filepath, URL, ``torchvision://xxx``,
            ``open-mmlab://xxx``. Please refer to ``docs/model_zoo.md`` for
            details.
        map_location (str): Same as :func:`torch.load`.
        strict (bool): Whether to allow different params for the model and
            checkpoint.
        logger (:mod:`logging.Logger` or None): The logger for error message.
    Returns:
        dict or OrderedDict: The loaded checkpoint.
    """
    checkpoint = torch.load(filename, map_location=map_location)
    # OrderedDict is a subclass of dict
    if not isinstance(checkpoint, dict):
        raise RuntimeError(
            f'No state_dict found in checkpoint file {filename}')
    # get state_dict from checkpoint
    if 'state_dict' in checkpoint:
        state_dict = checkpoint['state_dict']
    elif 'model' in checkpoint:
        state_dict = checkpoint['model']
    else:
        state_dict = checkpoint
    # strip prefix of state_dict
    if list(state_dict.keys())[0].startswith('module.'):
        state_dict = {k[7:]: v for k, v in state_dict.items()}

    # for MoBY, load model of online branch
    if sorted(list(state_dict.keys()))[0].startswith('encoder'):
        state_dict = {k.replace('encoder.', ''): v for k, v in state_dict.items() if k.startswith('encoder.')}

    old_posemb = state_dict['pos_embed']
    if model.pos_embed.shape != old_posemb.shape:  # need resize the position embedding by interpolate
        new_posemb = resize_pos_embed_4d(old_posemb, model.pos_embed)
        state_dict['pos_embed'] = new_posemb

    # load state_dict
    load_state_dict(model, state_dict, strict)
    print('load pretrained weight strct={}'.format(strict))
    return checkpoint

class OutlookAttention(nn.Module):
    """
    Implementation of outlook attention
    --dim: hidden dim
    --num_heads: number of heads
    --kernel_size: kernel size in each window for outlook attention
    return: token features after outlook attention
    """

    def __init__(self, dim, num_heads, kernel_size=3, padding=1, stride=1,
                 qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):
        super().__init__()
        head_dim = dim // num_heads
        self.num_heads = num_heads
        self.kernel_size = kernel_size
        self.padding = padding
        self.stride = stride
        self.scale = qk_scale or head_dim**-0.5

        self.v = nn.Linear(dim, dim, bias=qkv_bias)
        self.attn = nn.Linear(dim, kernel_size**4 * num_heads)

        self.attn_drop = nn.Dropout(attn_drop)
        self.proj = nn.Linear(dim, dim)
        self.proj_drop = nn.Dropout(proj_drop)

        self.unfold = nn.Unfold(kernel_size=kernel_size, padding=padding, stride=stride)
        self.pool = nn.AvgPool2d(kernel_size=stride, stride=stride, ceil_mode=True)

    def forward(self, x):
        B, H, W, C = x.shape

        v = self.v(x).permute(0, 3, 1, 2)  # B, C, H, W

        h, w = math.ceil(torch.true_divide(H, self.stride)), math.ceil(torch.true_divide(W, self.stride))
        v = self.unfold(v).reshape(B, self.num_heads, C // self.num_heads,
                                   self.kernel_size * self.kernel_size,
                                   h * w).permute(0, 1, 4, 3, 2)  # B,H,N,kxk,C/H

        attn = self.pool(x.permute(0, 3, 1, 2)).permute(0, 2, 3, 1)
        attn = self.attn(attn).reshape(
            B, h * w, self.num_heads, self.kernel_size * self.kernel_size,
            self.kernel_size * self.kernel_size).permute(0, 2, 1, 3, 4)  # B,H,N,kxk,kxk
        attn = attn * self.scale
        attn = attn.softmax(dim=-1)
        attn = self.attn_drop(attn)

        x = (attn @ v).permute(0, 1, 4, 3, 2).reshape(
            B, C * self.kernel_size * self.kernel_size, h * w)
        x = F.fold(x, output_size=(H, W), kernel_size=self.kernel_size,
                   padding=self.padding, stride=self.stride)

        x = self.proj(x.permute(0, 2, 3, 1))
        x = self.proj_drop(x)

        return x

class Outlooker(nn.Module):
    """
    Implementation of outlooker layer: which includes outlook attention + MLP
    Outlooker is the first stage in our VOLO
    --dim: hidden dim
    --num_heads: number of heads
    --mlp_ratio: mlp ratio
    --kernel_size: kernel size in each window for outlook attention
    return: outlooker layer
    """
    def __init__(self, dim, kernel_size, padding, stride=1,
                 num_heads=1,mlp_ratio=3., attn_drop=0.,
                 drop_path=0., act_layer=nn.GELU,
                 norm_layer=nn.LayerNorm, qkv_bias=False,
                 qk_scale=None):
        super().__init__()
        self.norm1 = norm_layer(dim)
        self.attn = OutlookAttention(dim, num_heads, kernel_size=kernel_size,
                                     padding=padding, stride=stride,
                                     qkv_bias=qkv_bias, qk_scale=qk_scale,
                                     attn_drop=attn_drop)

        self.drop_path = DropPath(
            drop_path) if drop_path > 0. else nn.Identity()

        self.norm2 = norm_layer(dim)
        mlp_hidden_dim = int(dim * mlp_ratio)
        self.mlp = Mlp(in_features=dim,
                       hidden_features=mlp_hidden_dim,
                       act_layer=act_layer)

    def forward(self, x):
        x = x + self.drop_path(self.attn(self.norm1(x)))
        x = x + self.drop_path(self.mlp(self.norm2(x)))
        return x

class Mlp(nn.Module):
    "Implementation of MLP"

    def __init__(self, in_features, hidden_features=None,
                 out_features=None, act_layer=nn.GELU,
                 drop=0.):
        super().__init__()
        out_features = out_features or in_features
        hidden_features = hidden_features or in_features
        self.fc1 = nn.Linear(in_features, hidden_features)
        self.act = act_layer()
        self.fc2 = nn.Linear(hidden_features, out_features)
        self.drop = nn.Dropout(drop)

    def forward(self, x):
        x = self.fc1(x)
        x = self.act(x)
        x = self.drop(x)
        x = self.fc2(x)
        x = self.drop(x)
        return x

class Attention(nn.Module):
    "Implementation of self-attention"

    def __init__(self, dim,  num_heads=8, qkv_bias=False,
                 qk_scale=None, attn_drop=0., proj_drop=0.):
        super().__init__()
        self.num_heads = num_heads
        head_dim = dim // num_heads
        self.scale = qk_scale or head_dim**-0.5

        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
        self.attn_drop = nn.Dropout(attn_drop)
        self.proj = nn.Linear(dim, dim)
        self.proj_drop = nn.Dropout(proj_drop)

    def forward(self, x):
        B, H, W, C = x.shape

        qkv = self.qkv(x).reshape(B, H * W, 3, self.num_heads,
                                  C // self.num_heads).permute(2, 0, 3, 1, 4)
        q, k, v = qkv[0], qkv[1], qkv[
            2]  # make torchscript happy (cannot use tensor as tuple)

        attn = (q @ k.transpose(-2, -1)) * self.scale
        attn = attn.softmax(dim=-1)
        attn = self.attn_drop(attn)

        x = (attn @ v).transpose(1, 2).reshape(B, H, W, C)
        x = self.proj(x)
        x = self.proj_drop(x)

        return x

class Transformer(nn.Module):
    """
    Implementation of Transformer,
    Transformer is the second stage in our VOLO
    """
    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False,
                 qk_scale=None, attn_drop=0., drop_path=0.,
                 act_layer=nn.GELU, norm_layer=nn.LayerNorm):
        super().__init__()
        self.norm1 = norm_layer(dim)
        self.attn = Attention(dim, num_heads=num_heads, qkv_bias=qkv_bias,
                              qk_scale=qk_scale, attn_drop=attn_drop)

        # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
        self.drop_path = DropPath(
            drop_path) if drop_path > 0. else nn.Identity()

        self.norm2 = norm_layer(dim)
        mlp_hidden_dim = int(dim * mlp_ratio)
        self.mlp = Mlp(in_features=dim,
                       hidden_features=mlp_hidden_dim,
                       act_layer=act_layer)

    def forward(self, x):
        x = x + self.drop_path(self.attn(self.norm1(x)))
        x = x + self.drop_path(self.mlp(self.norm2(x)))
        return x

class ClassAttention(nn.Module):
    """
    Class attention layer from CaiT, see details in CaiT
    Class attention is the post stage in our VOLO, which is optional.
    """
    def __init__(self, dim, num_heads=8, head_dim=None, qkv_bias=False,
                 qk_scale=None, attn_drop=0., proj_drop=0.):
        super().__init__()
        self.num_heads = num_heads
        if head_dim is not None:
            self.head_dim = head_dim
        else:
            head_dim = dim // num_heads
            self.head_dim = head_dim
        self.scale = qk_scale or head_dim**-0.5

        self.kv = nn.Linear(dim,
                            self.head_dim * self.num_heads * 2,
                            bias=qkv_bias)
        self.q = nn.Linear(dim, self.head_dim * self.num_heads, bias=qkv_bias)
        self.attn_drop = nn.Dropout(attn_drop)
        self.proj = nn.Linear(self.head_dim * self.num_heads, dim)
        self.proj_drop = nn.Dropout(proj_drop)

    def forward(self, x):
        B, N, C = x.shape

        kv = self.kv(x).reshape(B, N, 2, self.num_heads,
                                self.head_dim).permute(2, 0, 3, 1, 4)
        k, v = kv[0], kv[
            1]  # make torchscript happy (cannot use tensor as tuple)
        q = self.q(x[:, :1, :]).reshape(B, self.num_heads, 1, self.head_dim)
        attn = ((q * self.scale) @ k.transpose(-2, -1))
        attn = attn.softmax(dim=-1)
        attn = self.attn_drop(attn)

        cls_embed = (attn @ v).transpose(1, 2).reshape(
            B, 1, self.head_dim * self.num_heads)
        cls_embed = self.proj(cls_embed)
        cls_embed = self.proj_drop(cls_embed)
        return cls_embed

class ClassBlock(nn.Module):
    """
    Class attention block from CaiT, see details in CaiT
    We use two-layers class attention in our VOLO, which is optional.
    """

    def __init__(self, dim, num_heads, head_dim=None, mlp_ratio=4.,
                 qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,
                 drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm):
        super().__init__()
        self.norm1 = norm_layer(dim)
        self.attn = ClassAttention(
            dim, num_heads=num_heads, head_dim=head_dim, qkv_bias=qkv_bias,
            qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
        # NOTE: drop path for stochastic depth
        self.drop_path = DropPath(
            drop_path) if drop_path > 0. else nn.Identity()
        self.norm2 = norm_layer(dim)
        mlp_hidden_dim = int(dim * mlp_ratio)
        self.mlp = Mlp(in_features=dim,
                       hidden_features=mlp_hidden_dim,
                       act_layer=act_layer,
                       drop=drop)

    def forward(self, x):
        cls_embed = x[:, :1]
        cls_embed = cls_embed + self.drop_path(self.attn(self.norm1(x)))
        cls_embed = cls_embed + self.drop_path(self.mlp(self.norm2(cls_embed)))
        return torch.cat([cls_embed, x[:, 1:]], dim=1)

def get_block(block_type, **kargs):
    """
    get block by name, specifically for class attention block in here
    """
    if block_type == 'ca':
        return ClassBlock(**kargs)

def rand_bbox(size, lam, scale=1):
    """
    get bounding box as token labeling (https://github.com/zihangJiang/TokenLabeling)
    return: bounding box
    """
    W = size[1] // scale
    H = size[2] // scale
    cut_rat = np.sqrt(1. - lam)
    cut_w = np.int(W * cut_rat)
    cut_h = np.int(H * cut_rat)

    # uniform
    cx = np.random.randint(W)
    cy = np.random.randint(H)

    bbx1 = np.clip(cx - cut_w // 2, 0, W)
    bby1 = np.clip(cy - cut_h // 2, 0, H)
    bbx2 = np.clip(cx + cut_w // 2, 0, W)
    bby2 = np.clip(cy + cut_h // 2, 0, H)

    return bbx1, bby1, bbx2, bby2

class PatchEmbed(nn.Module):
    """
    Image to Patch Embedding.
    Different with ViT use 1 conv layer, we use 4 conv layers to do patch embedding
    """

    def __init__(self, img_size=224, stem_conv=False, stem_stride=1,
                 patch_size=8, in_chans=3, hidden_dim=64, embed_dim=384):
        super().__init__()
        assert patch_size in [4, 8, 16]

        self.stem_conv = stem_conv
        if stem_conv:
            self.conv = nn.Sequential(
                nn.Conv2d(in_chans, hidden_dim, kernel_size=7, stride=stem_stride,
                          padding=3, bias=False),  # 112x112
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU(inplace=True),
                nn.Conv2d(hidden_dim, hidden_dim, kernel_size=3, stride=1,
                          padding=1, bias=False),  # 112x112
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU(inplace=True),
                nn.Conv2d(hidden_dim, hidden_dim, kernel_size=3, stride=1,
                          padding=1, bias=False),  # 112x112
                nn.BatchNorm2d(hidden_dim),
                nn.ReLU(inplace=True),
            )

        self.proj = nn.Conv2d(hidden_dim,
                              embed_dim,
                              kernel_size=patch_size // stem_stride,
                              stride=patch_size // stem_stride)
        self.num_patches = (img_size // patch_size) * (img_size // patch_size)

    def forward(self, x):
        if self.stem_conv:
            x = self.conv(x)
        x = self.proj(x)  # B, C, H, W
        return x

class Downsample(nn.Module):
    """
    Image to Patch Embedding, downsampling between stage1 and stage2
    """
    def __init__(self, in_embed_dim, out_embed_dim, patch_size):
        super().__init__()
        self.proj = nn.Conv2d(in_embed_dim, out_embed_dim,
                              kernel_size=patch_size, stride=patch_size)

    def forward(self, x):
        x = x.permute(0, 3, 1, 2)
        x = self.proj(x)  # B, C, H, W
        x = x.permute(0, 2, 3, 1)
        return x

def outlooker_blocks(block_fn, index, dim, layers, num_heads=1, kernel_size=3,
                     padding=1,stride=1, mlp_ratio=3., qkv_bias=False, qk_scale=None,
                     attn_drop=0, drop_path_rate=0., **kwargs):
    """
    generate outlooker layer in stage1
    return: outlooker layers
    """
    blocks = []
    for block_idx in range(layers[index]):
        block_dpr = drop_path_rate * (block_idx +
                                      sum(layers[:index])) / (sum(layers) - 1)
        blocks.append(block_fn(dim, kernel_size=kernel_size, padding=padding,
                               stride=stride, num_heads=num_heads, mlp_ratio=mlp_ratio,
                               qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop,
                               drop_path=block_dpr))

    blocks = nn.Sequential(*blocks)

    return blocks

def transformer_blocks(block_fn, index, dim, layers, num_heads, mlp_ratio=3.,
                       qkv_bias=False, qk_scale=None, attn_drop=0,
                       drop_path_rate=0., **kwargs):
    """
    generate transformer layers in stage2
    return: transformer layers
    """
    blocks = []
    for block_idx in range(layers[index]):
        block_dpr = drop_path_rate * (block_idx +
                                      sum(layers[:index])) / (sum(layers) - 1)
        blocks.append(
            block_fn(dim, num_heads,
                     mlp_ratio=mlp_ratio,
                     qkv_bias=qkv_bias,
                     qk_scale=qk_scale,
                     attn_drop=attn_drop,
                     drop_path=block_dpr))

    blocks = nn.Sequential(*blocks)

    return blocks

class VOLO_backbone(nn.Module):
    """
    Vision Outlooker, the main class of our model
    --layers: [x,x,x,x], four blocks in two stages, the first block is outlooker, the
              other three are transformer, we set four blocks, which are easily
              applied to downstream tasks
    --img_size, --in_chans, --num_classes: these three are very easy to understand
    --patch_size: patch_size in outlook attention
    --stem_hidden_dim: hidden dim of patch embedding, d1-d4 is 64, d5 is 128
    --embed_dims, --num_heads: embedding dim, number of heads in each block
    --downsamples: flags to apply downsampling or not
    --outlook_attention: flags to apply outlook attention or not
    --mlp_ratios, --qkv_bias, --qk_scale, --drop_rate: easy to undertand
    --attn_drop_rate, --drop_path_rate, --norm_layer: easy to undertand
    --post_layers: post layers like two class attention layers using [ca, ca],
                  if yes, return_mean=False
    --return_mean: use mean of all feature tokens for classification, if yes, no class token
    --return_dense: use token labeling, details are here:
                    https://github.com/zihangJiang/TokenLabeling
    --mix_token: mixing tokens as token labeling, details are here:
                    https://github.com/zihangJiang/TokenLabeling
    --pooling_scale: pooling_scale=2 means we downsample 2x
    --out_kernel, --out_stride, --out_padding: kerner size,
                                               stride, and padding for outlook attention
    """
    def __init__(self, layers, img_size=512, in_chans=3, patch_size=8,
                 stem_hidden_dim=64, embed_dims=None, num_heads=None, downsamples=None,
                 outlook_attention=None, mlp_ratios=None, qkv_bias=False, qk_scale=None,
                 drop_rate=0., attn_drop_rate=0., drop_path_rate=0., norm_layer=nn.LayerNorm,
                 pooling_scale=2, out_kernel=3, out_stride=2, out_padding=1):

        super().__init__()
        self.patch_embed = PatchEmbed(stem_conv=True, stem_stride=2, patch_size=patch_size,
                                      in_chans=in_chans, hidden_dim=stem_hidden_dim,
                                      embed_dim=embed_dims[0])

        # inital positional encoding, we add positional encoding after outlooker blocks
        self.pos_embed = nn.Parameter(
            torch.zeros(1, img_size // patch_size // pooling_scale,
                        img_size // patch_size // pooling_scale,
                        embed_dims[-1]))

        self.pos_drop = nn.Dropout(p=drop_rate)

        # set the main block in network
        network = []
        for i in range(len(layers)):
            if outlook_attention[i]:
                # stage 1
                stage = outlooker_blocks(Outlooker, i, embed_dims[i], layers,
                                         downsample=downsamples[i], num_heads=num_heads[i],
                                         kernel_size=out_kernel, stride=out_stride,
                                         padding=out_padding, mlp_ratio=mlp_ratios[i],
                                         qkv_bias=qkv_bias, qk_scale=qk_scale,
                                         attn_drop=attn_drop_rate, norm_layer=norm_layer)
                network.append(stage)
            else:
                # stage 2
                stage = transformer_blocks(Transformer, i, embed_dims[i], layers,
                                           num_heads[i], mlp_ratio=mlp_ratios[i],
                                           qkv_bias=qkv_bias, qk_scale=qk_scale,
                                           drop_path_rate=drop_path_rate,
                                           attn_drop=attn_drop_rate,
                                           norm_layer=norm_layer)
                network.append(stage)

            if downsamples[i]:
                # downsampling between two stages
                network.append(Downsample(embed_dims[i], embed_dims[i + 1], 2))

        self.network = nn.ModuleList(network)
        trunc_normal_(self.pos_embed, std=.02)

    def init_weights(self, pretrained=None, strict=False):
        """Initialize the weights in backbone.
        Args:
            pretrained (str, optional): Path to pre-trained weights.
                Defaults to None.
        """
        def _init_weights(m):
            if isinstance(m, nn.Linear):
                trunc_normal_(m.weight, std=.02)
                if isinstance(m, nn.Linear) and m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.LayerNorm):
                nn.init.constant_(m.bias, 0)
                nn.init.constant_(m.weight, 1.0)
        if isinstance(pretrained, str):
            self.apply(_init_weights)
            load_checkpoint(self, pretrained, strict=strict)
            print('load pretained weight strict={}'.format(strict))
        elif pretrained is None:
            self.apply(_init_weights)
        else:
            raise TypeError('pretrained must be a str or None')

    def forward_embeddings(self, x):
        # patch embedding
        x = self.patch_embed(x)
        # B,C,H,W-> B,H,W,C
        x = x.permute(0, 2, 3, 1)
        return x

    def forward_tokens(self, x):
        out = []
        for idx, block in enumerate(self.network):
            if idx == 2:  # add positional encoding after outlooker blocks
                x = x + self.pos_embed
                x = self.pos_drop(x)
            x = block(x)
            out.append(x.permute(0, 3, 1, 2).contiguous())
        return out

    def forward(self, x):
        # step1: patch embedding
        x = self.forward_embeddings(x)

        # step2: tokens learning in the two stages
        out = self.forward_tokens(x)

        return tuple(out)

class VOLO(nn.Module):

    def __init__(self, nclass, embed_dim, layers, num_heads, mlp_ratios, downsamples, outlook_attention,
                 aux=False, pretrained_root=None, head='seghead', edge_aux=False, stem_hidden_dim=None):
        super(VOLO, self).__init__()
        self.aux = aux
        self.edge_aux = edge_aux
        self.head_name = head
        self.backbone = VOLO_backbone(layers=layers,
                                      embed_dims=embed_dim,
                                      num_heads=num_heads,
                                      mlp_ratios=mlp_ratios,
                                      downsamples=downsamples,
                                      outlook_attention=outlook_attention,
                                      stem_hidden_dim=stem_hidden_dim or 64,
                                      img_size=512
                                      )

        if self.head_name == 'apchead':
            self.decode_head = APCHead(in_channels=embed_dim[3], num_classes=nclass, in_index=3, channels=512)

        if self.head_name == 'aspphead':
            self.decode_head = ASPPHead(in_channels=embed_dim[3], num_classes=nclass, in_index=3)

        if self.head_name == 'asppplushead':
            self.decode_head = ASPPPlusHead(in_channels=embed_dim[3], num_classes=nclass, in_index=[0, 3])

        if self.head_name == 'dahead':
            self.decode_head = DAHead(in_channels=embed_dim[3], num_classes=nclass, in_index=3)

        if self.head_name == 'dnlhead':
            self.decode_head = DNLHead(in_channels=embed_dim[3], num_classes=nclass, in_index=3, channels=512)

        if self.head_name == 'fcfpnhead':
            self.decode_head = FCFPNHead(in_channels=embed_dim, num_classes=nclass, in_index=[0, 1, 2, 3], channels=256)

        if self.head_name == 'cefpnhead':
            self.decode_head = CEFPNHead(in_channels=embed_dim, num_classes=nclass, in_index=[0, 1, 2, 3], channels=256)

        if self.head_name == 'fcnhead':
            self.decode_head = FCNHead(in_channels=embed_dim[3], num_classes=nclass, in_index=3, channels=512)

        if self.head_name == 'gchead':
            self.decode_head = GCHead(in_channels=embed_dim[3], num_classes=nclass, in_index=3, channels=512)

        if self.head_name == 'psahead':
            self.decode_head = PSAHead(in_channels=embed_dim[3], num_classes=nclass, in_index=3)

        if self.head_name == 'psphead':
            self.decode_head = PSPHead(in_channels=embed_dim[3], num_classes=nclass, in_index=3)

        if self.head_name == 'seghead':
            self.decode_head = SegHead(in_channels=embed_dim, num_classes=nclass, in_index=[0, 1, 2, 3])

        if self.head_name == 'unethead':
            self.decode_head = UNetHead(in_channels=embed_dim, num_classes=nclass, in_index=[0, 1, 2, 3])

        if self.head_name == 'uperhead':
            self.decode_head = UPerHead(in_channels=embed_dim, num_classes=nclass)

        if self.head_name == 'annhead':
            self.decode_head = ANNHead(in_channels=embed_dim[2:], num_classes=nclass, in_index=[2, 3], channels=512)

        if self.head_name == 'mlphead':
            self.decode_head = MLPHead(in_channels=embed_dim, num_classes=nclass, in_index=[0, 1, 2, 3], channels=256)

        if self.aux:
            self.auxiliary_head = FCNHead(num_convs=1, in_channels=embed_dim[2], num_classes=nclass, in_index=2, channels=256)

        if self.edge_aux:
            self.edge_head = EdgeHead(in_channels=embed_dim[0:2], in_index=[0, 1], channels=embed_dim[0])

        if pretrained_root is None:
            self.backbone.init_weights()
        else:
            if 'upernet' in pretrained_root:
                load_checkpoint(self, filename=pretrained_root, strict=False)
            else:
                self.backbone.init_weights(pretrained=pretrained_root, strict=False)

    def forward(self, x):
        size = x.size()[2:]
        outputs = []

        out_backbone = self.backbone(x)
        x0 = self.decode_head(out_backbone)
        if isinstance(x0, (list, tuple)):
            for out in x0:
                out = F.interpolate(out, size, **up_kwargs)
                outputs.append(out)
        else:
            x0 = F.interpolate(x0, size, **up_kwargs)
            outputs.append(x0)

        if self.aux:
            x1 = self.auxiliary_head(out_backbone)
            x1 = F.interpolate(x1, size, **up_kwargs)
            outputs.append(x1)

        if self.edge_aux:
            edge = self.edge_head(out_backbone)
            edge = F.interpolate(edge, size, **up_kwargs)
            outputs.append(edge)

        return outputs

def volo_d1(nclass, pretrained=False, aux=False, head='uperhead', edge_aux=False):
    if pretrained:
        pretrained_root = './pretrained_weights/d1_224_84.2.pth.tar'
    else:
        pretrained_root = None

    layers = [4, 4, 8, 2]  # num of layers in the four blocks
    embed_dims = [192, 384, 384, 384]
    num_heads = [6, 12, 12, 12]
    mlp_ratios = [3, 3, 3, 3]
    downsamples = [True, False, False, False] # do downsampling after first block
    outlook_attention = [True, False, False, False ]
    # first block is outlooker (stage1), the other three are transformer (stage2)
    model = VOLO(layers=layers,
                 embed_dim=embed_dims,
                 num_heads=num_heads,
                 mlp_ratios=mlp_ratios,
                 downsamples=downsamples,
                 outlook_attention=outlook_attention,
                 nclass=nclass, aux=aux, head=head, edge_aux=edge_aux, pretrained_root=pretrained_root
                 )
    return model

def volo_d2(nclass, pretrained=False, aux=False, head='uperhead', edge_aux=False):
    if pretrained:
        pretrained_root = './pretrained_weights/rest_lite.pth'
    else:
        pretrained_root = None

    layers = [6, 4, 10, 4]
    embed_dims = [256, 512, 512, 512]
    num_heads = [8, 16, 16, 16]
    mlp_ratios = [3, 3, 3, 3]
    downsamples = [True, False, False, False]
    outlook_attention = [True, False, False, False]
    # first block is outlooker (stage1), the other three are transformer (stage2)
    model = VOLO(layers=layers,
                 embed_dim=embed_dims,
                 num_heads=num_heads,
                 mlp_ratios=mlp_ratios,
                 downsamples=downsamples,
                 outlook_attention=outlook_attention,
                 nclass=nclass, aux=aux, head=head, edge_aux=edge_aux, pretrained_root=pretrained_root
                 )
    return model

def volo_d3(nclass, pretrained=False, aux=False, head='uperhead', edge_aux=False):
    if pretrained:
        pretrained_root = './pretrained_weights/rest_lite.pth'
    else:
        pretrained_root = None

    layers = [8, 8, 16, 4]
    embed_dims = [256, 512, 512, 512]
    num_heads = [8, 16, 16, 16]
    mlp_ratios = [3, 3, 3, 3]
    downsamples = [True, False, False, False]
    outlook_attention = [True, False, False, False]
    # first block is outlooker (stage1), the other three are transformer (stage2)
    model = VOLO(layers=layers,
                 embed_dim=embed_dims,
                 num_heads=num_heads,
                 mlp_ratios=mlp_ratios,
                 downsamples=downsamples,
                 outlook_attention=outlook_attention,
                 nclass=nclass, aux=aux, head=head, edge_aux=edge_aux, pretrained_root=pretrained_root
                 )
    return model

def volo_d4(nclass, pretrained=False, aux=False, head='uperhead', edge_aux=False):
    if pretrained:
        pretrained_root = './pretrained_weights/rest_lite.pth'
    else:
        pretrained_root = None

    layers = [8, 8, 16, 4]
    embed_dims = [384, 768, 768, 768]
    num_heads = [12, 16, 16, 16]
    mlp_ratios = [3, 3, 3, 3]
    downsamples = [True, False, False, False]
    outlook_attention = [True, False, False, False]
    # first block is outlooker (stage1), the other three are transformer (stage2)
    model = VOLO(layers=layers,
                 embed_dim=embed_dims,
                 num_heads=num_heads,
                 mlp_ratios=mlp_ratios,
                 downsamples=downsamples,
                 outlook_attention=outlook_attention,
                 nclass=nclass, aux=aux, head=head, edge_aux=edge_aux, pretrained_root=pretrained_root
                 )
    return model

def volo_d5(nclass, pretrained=False, aux=False, head='uperhead', edge_aux=False):
    if pretrained:
        pretrained_root = './pretrained_weights/d5_512_87.07.pth.tar'
    else:
        pretrained_root = None

    layers = [12, 12, 20, 4]
    embed_dims = [384, 768, 768, 768]
    num_heads = [12, 16, 16, 16]
    mlp_ratios = [4, 4, 4, 4]
    downsamples = [True, False, False, False]
    outlook_attention = [True, False, False, False]
    # first block is outlooker (stage1), the other three are transformer (stage2)
    model = VOLO(layers=layers,
                 embed_dim=embed_dims,
                 num_heads=num_heads,
                 mlp_ratios=mlp_ratios,
                 downsamples=downsamples,
                 outlook_attention=outlook_attention,
                 stem_hidden_dim=128,
                 nclass=nclass, aux=aux, head=head, edge_aux=edge_aux, pretrained_root=pretrained_root
                 )
    return model

if __name__ == '__main__':
    """Notice if torch1.6, try to replace a / b with torch.true_divide(a, b)"""
    from tools.flops_params_fps_count import flops_params_fps

    model_base = volo_d1(nclass=6, aux=True, edge_aux=True, head='mlphead', pretrained=True)

    flops_params_fps(model_base)


from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
import uuid

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///employees.db'
db = SQLAlchemy(app)
ma = Marshmallow(app)

# Модель данных для сотрудника
class Employee(db.Model):
    id = db.Column(db.String(36), primary_key=True)
    last_name = db.Column(db.String(50))
    first_name = db.Column(db.String(50))
    middle_name = db.Column(db.String(50))
    position = db.Column(db.String(50))

    def __init__(self, last_name, first_name, middle_name, position):
        self.id = str(uuid.uuid4())
        self.last_name = last_name
        self.first_name = first_name
        self.middle_name = middle_name
        self.position = position

# Схема сериализации/десериализации для сотрудника
class EmployeeSchema(ma.Schema):
    class Meta:
        fields = ('id', 'last_name', 'first_name', 'middle_name', 'position')

employee_schema = EmployeeSchema()
employees_schema = EmployeeSchema(many=True)

# Создание нового сотрудника
@app.route('/employees', methods=['POST'])
def create_employee():
    last_name = request.json['last_name']
    first_name = request.json['first_name']
    middle_name = request.json['middle_name']
    position = request.json['position']

    with app.app_context():
        new_employee = Employee(last_name, first_name, middle_name, position)
        db.session.add(new_employee)
        db.session.commit()

    return employee_schema.jsonify(new_employee)

# Получение всех сотрудников
@app.route('/employees', methods=['GET'])
def get_employees():
    with app.app_context():
        all_employees = Employee.query.all()
        result = employees_schema.dump(all_employees)
        return jsonify(result)

# Получение информации о конкретном сотруднике по его идентификатору
@app.route('/employees/<id>', methods=['GET'])
def get_employee(id):
    with app.app_context():
        employee = Employee.query.get(id)
        return employee_schema.jsonify(employee)

# Обновление информации о сотруднике
@app.route('/employees/<id>', methods=['PUT'])
def update_employee(id):
    with app.app_context():
        employee = Employee.query.get(id)

        last_name = request.json['last_name']
        first_name = request.json['first_name']
        middle_name = request.json['middle_name']
        position = request.json['position']

        employee.last_name = last_name
        employee.first_name = first_name
        employee.middle_name = middle_name
        employee.position = position

        db.session.commit()

    return employee_schema.jsonify(employee)

# Удаление сотрудника
@app.route('/employees/<id>', methods=['DELETE'])
def delete_employee(id):
    with app.app_context():
        employee = Employee.query.get(id)
        db.session.delete(employee)
        db.session.commit()
        return employee_schema.jsonify(employee)

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run()


import pandas as pd
import datetime as dt
from sodapy import Socrata
from airflow.hooks.base_hook import BaseHook

class Extract:
    chicago_crime_portal = "https://data.cityofchicago.org/resource/ijzp-q8t2.json"

    def __init__(self, start_time , end_time ) -> None:
        self.start_time = start_time
        self.end_time = end_time
        self.client = Socrata("data.cityofchicago.org", app_token=BaseHook.get_connection("CITY_OF_CHICAGO_APP_TOKEN").password)

        # Get all the updates in the last week.
        self.updated_on_filter = "updated_on >= '"+ start_time  +"' and updated_on < '"+ end_time +"'"

    def execute_extraction(self) -> pd.DataFrame:

        crimes = self.client.get_all("ijzp-q8t2",where = self.updated_on_filter)
        crime_df = pd.DataFrame.from_records(crimes)
        print(crime_df.head(5))
        print(crime_df.columns)
        return crime_df

if __name__=="__main__":
    extract = Extract(dt.datetime.now()+dt.timedelta(days=-3))
    data = extract.execute_extraction()
    print(data)


import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="diss-iamhectorotero",
    version="0.0.1",
    author="Hector Otero",
    author_email="7hector2@gmail.com",
    description="A package to train RNN in physical microworlds in a supervised or RL manner",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/iamhectorotero/diss",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.5.6',
)


from __future__ import annotations

import math
import os

import pygame

from pgbot import emotion

EMOTIONS_PER_ROW = 2
NEGATIVE_EMOTIONS = {"bored": "exhausted", "happy": "sad"}
EMOTION_COLORS = {
    "happy": (230, 28, 226),
    "sad": (28, 28, 230),
    "anger": (230, 36, 18),
    "bored": (230, 181, 18),
    "exhausted": (235, 127, 19),
    "confused": (19, 235, 228),
}

def get_emotion_desc_dict(emotions: dict[str, int]):
    """
    Get emotion description dict from emotion dict
    """
    return {
        "happy": {
            "msg": "I feel... happi!\n"
            "While I am happi, I'll make more dad jokes (Spot the dad joke in there?)\n"
            "However, don't bonk me or say 'ded chat', as that would make me sad.\n"
            f"*The snek's happiness level is `{emotions.get('happy', '0')}`, "
            "don't let it go to zero!*",
            "emoji_link": "https://cdn.discordapp.com/emojis/837389387024957440.png?v=1",
        },
        "sad": {
            "msg": "I'm sad...\n"
            "I don't feel like making any jokes. This is your fault, "
            "**don't make me sad.**\nPet me pls :3\n"
            f"*The snek's sadness level is `{-emotions.get('happy', 0)}`, play with "
            "it to cheer it up*",
            "emoji_link": "https://cdn.discordapp.com/emojis/824721451735056394.png?v=1",
        },
        "exhausted": {
            "msg": "I'm exhausted. \nI ran too many commands, "
            "so I'll be resting for a while..\n"
            "Don't try to make me run commands for now, I'll most likely "
            "just ignore it..\n"
            f"*The snek's exhaustion level is `{-emotions.get('bored', 0)}`. "
            "To make its exhaustion go down, let it rest for a bit.*",
            "emoji_link": None,
        },
        "bored": {
            "msg": "I'm booooooooored...\nNo one is spending time with me, "
            "and I feel lonely :pg_depressed:\n"
            f"*The snek's boredom level is `{emotions.get('bored', '0')}`, run "
            "more command(s) to improve its mood.*",
            "emoji_link": "https://cdn.discordapp.com/emojis/823502668500172811.png?v=1",
        },
        "confused": {
            "msg": "I'm confused!\nEither there were too many exceptions in my code, "
            "or too many commands were used wrongly!\n"
            f"*The snek's confusion level is `{emotions.get('confused', '0')}`, "
            "to lower its level of confusion, use proper command syntax.*",
            "emoji_link": "https://cdn.discordapp.com/emojis/837402289709907978.png?v=1",
        },
        "anger": {
            "msg": "I'm angry!\nI've been bonked too many times, you'd be "
            "angry too if someone bonked you 50+ times :unamused:\n"
            "No jokes, no quotes. :pg_angry:. Don't you dare pet me!\n"
            f"*The snek's anger level is `{emotions.get('anger', '0')}`, "
            "ask for its forgiveness to calm it down.*",
            "emoji_link": "https://cdn.discordapp.com/emojis/779775305224159232.gif?v=1",
            "override_emotion": "anger",
        },
    }

def generate_pie_slice(
    center_x: int, center_y: int, radius: int, start_angle: int, end_angle: int
):
    """
    Generate slice of the pie in the output
    """
    p = [(center_x, center_y)]

    # cover a bit more angle so that the boundaries are fully covered
    for angle in range(start_angle - 91, end_angle - 89):
        x = center_x + int(radius * math.cos(math.radians(angle)))
        y = center_y + int(radius * math.sin(math.radians(angle)))
        p.append((x, y))
    return p

def get_emotion_percentage(emotions: dict[str, int], round_by: int = 1):
    """
    Express emotions in terms of percentages, split complementary emotions into
    their own emotions
    """
    raw_emotion_percentage = {}
    for key, value in emotions.items():
        percentage = value / emotion.EMOTION_CAPS[key][1] * 100
        if percentage < 0:
            percentage = -percentage
            key = NEGATIVE_EMOTIONS[key]
        raw_emotion_percentage[key] = percentage

    sum_of_emotions = sum([i for i in raw_emotion_percentage.values()])
    emotion_percentage = {
        key: round(raw_emotion / sum_of_emotions * 100, round_by)
        if round_by != -1
        else raw_emotion / sum_of_emotions * 100
        for key, raw_emotion in sorted(
            raw_emotion_percentage.items(), key=lambda item: item[1], reverse=True
        )
    }

    return emotion_percentage

def emotion_pie_chart(emotions: dict[str, int], pie_radius: int):
    """
    Generates a pie chart, given emotions and pie radius
    Emotions must be in "raw form", like
    {"happy": 34, "bored": -35, "anger": 89, "confused": 499}
    """
    font = pygame.font.Font(os.path.join("assets", "tahoma.ttf"), 30)
    font.bold = True

    image = pygame.Surface((pie_radius * 2, pie_radius * 2 + 30 * len(emotions)))
    image.fill((0, 0, 0, 0))

    emotion_percentage = get_emotion_percentage(emotions)
    emotion_pie_angle = {
        key: percentage / 100 * 360 for key, percentage in emotion_percentage.items()
    }

    start_angle = 0
    for key, angle in emotion_pie_angle.items():
        if round(angle) != 0:
            pygame.draw.polygon(
                image,
                EMOTION_COLORS[key],
                generate_pie_slice(
                    pie_radius,
                    pie_radius,
                    pie_radius,
                    start_angle,
                    start_angle + round(angle),
                ),
            )
            start_angle += round(angle)

    pygame.draw.circle(
        image, (255, 255, 255), (pie_radius, pie_radius), pie_radius, width=10
    )

    i = 0
    txt_x = 0
    txt_y = pie_radius * 2
    for bot_emotion, percentage in emotion_percentage.items():
        txt = font.render(
            f"{bot_emotion.title()} - {percentage}%", True, EMOTION_COLORS[bot_emotion]
        )
        txt_rect = txt.get_rect(topleft=(txt_x, txt_y))
        image.blit(txt, txt_rect)

        pygame.draw.rect(
            image,
            EMOTION_COLORS[bot_emotion],
            (int(txt_x + pie_radius * 1.8 / EMOTIONS_PER_ROW), txt_y, 20, 40),
        )

        if i % EMOTIONS_PER_ROW != EMOTIONS_PER_ROW - 1:
            txt_x += pie_radius * 2 / EMOTIONS_PER_ROW
        else:
            txt_x = 0
            txt_y += 40
        i += 1

    return image


import logging
import requests
import time
import json
from cifsdk.exceptions import AuthError, TimeoutError, NotFound, SubmissionFailed, InvalidSearch, CIFBusy
from cifsdk.constants import VERSION, PYVERSION, TOKEN
from pprint import pprint
from base64 import b64decode
from cifsdk.client.plugin import Client
import os
import zlib
from time import sleep
import random

if PYVERSION == 3:
    basestring = (str, bytes)

requests.packages.urllib3.disable_warnings()

TRACE = os.environ.get('CIFSDK_CLIENT_HTTP_TRACE')
TIMEOUT = os.getenv('CIFSDK_CLIENT_HTTP_TIMEOUT', 120)
RETRIES = os.getenv('CIFSDK_CLIENT_HTTP_RETRIES', 5)
RETRIES_DELAY = os.getenv('CIFSDK_CLIENT_HTTP_RETRIES_DELAY', '30,60')

s, e = RETRIES_DELAY.split(',')
RETRIES_DELAY = random.uniform(int(s), int(e))

logger = logging.getLogger(__name__)

logger.setLevel(logging.WARNING)
logging.getLogger('requests.packages.urllib3.connectionpool').setLevel(logging.ERROR)

if TRACE:
    logger.setLevel(logging.DEBUG)
    logging.getLogger('requests.packages.urllib3.connectionpool').setLevel(logging.DEBUG)

class HTTP(Client):

    def __init__(self, remote, token=TOKEN, proxy=None, timeout=int(TIMEOUT), verify_ssl=True, **kwargs):
        super(HTTP, self).__init__(remote, token, **kwargs)

        self.proxy = proxy
        self.timeout = timeout
        self.verify_ssl = verify_ssl
        self.nowait = kwargs.get('nowait', False)

        self.session = requests.Session()
        self.session.headers["Accept"] = 'application/vnd.cif.v3+json'
        self.session.headers['User-Agent'] = 'cifsdk-py/{}'.format(VERSION)
        self.session.headers['Authorization'] = 'Token token=' + self.token
        self.session.headers['Content-Type'] = 'application/json'
        self.session.headers['Accept-Encoding'] = 'deflate'

    def _check_status(self, resp, expect=200):
        if resp.status_code == 400:
            r = json.loads(resp.text)
            raise InvalidSearch(r['message'])

        if resp.status_code == 401:
            raise AuthError('unauthorized')

        if resp.status_code == 404:
            raise NotFound('not found')

        if resp.status_code == 408:
            raise TimeoutError('timeout')

        if resp.status_code == 422:
            msg = json.loads(resp.text)
            raise SubmissionFailed(msg['message'])

        if resp.status_code == 429:
            raise CIFBusy('RateLimit exceeded')

        if resp.status_code in [500, 501, 502, 503, 504]:
            raise CIFBusy('system seems busy..')

        if resp.status_code != expect:
            msg = 'unknown: %s' % resp.content
            raise RuntimeError(msg)

    def _get(self, uri, params={}, retry=True):
        if not uri.startswith('http'):
            uri = self.remote + uri

        resp = self.session.get(uri, params=params, verify=self.verify_ssl, timeout=self.timeout)
        n = RETRIES
        try:
            self._check_status(resp, expect=200)
            n = 0
        except Exception as e:
            if resp.status_code == 429 or resp.status_code in [500, 501, 502, 503, 504]:
                logger.error(e)
            else:
                raise e

        while n != 0:
            logger.warning('setting random retry interval to spread out the load')
            logger.warning('retrying in %.00fs' % RETRIES_DELAY)
            sleep(RETRIES_DELAY)

            resp = self.session.get(uri, params=params, verify=self.verify_ssl, timeout=self.timeout)
            if resp.status_code == 200:
                break

            if n == 0:
                raise CIFBusy('system seems busy.. try again later')

        data = resp.content

        s = (int(resp.headers['Content-Length']) / 1024 / 1024)
        logger.info('processing %.2f megs' % s)

        msgs = json.loads(data.decode('utf-8'))

        if msgs.get('data') and msgs['data'] == '{}':
            msgs['data'] = []

        if msgs.get('data') and isinstance(msgs['data'], basestring) and msgs['data'].startswith('{"hits":{"hits":[{"_source":'):
            msgs['data'] = json.loads(msgs['data'])
            msgs['data'] = [r['_source'] for r in msgs['data']['hits']['hits']]

        if not msgs.get('status') and not msgs.get('message') == 'success':
            raise RuntimeError(msgs)

        if msgs.get('status') and msgs['status'] == 'failed':
            raise InvalidSearch(msgs['message'])

        if isinstance(msgs.get('data'), list):
            for m in msgs['data']:
                if m.get('message'):
                    try:
                        m['message'] = b64decode(m['message'])
                    except Exception as e:
                        pass
        return msgs

    def _post(self, uri, data):
        if type(data) == dict:
            data = json.dumps(data)

        if self.nowait:
            uri = '{}?nowait=1'.format(uri)

        if isinstance(data, str):
            data = data.encode('utf-8')

        data = zlib.compress(data)
        headers = {
            'Content-Encoding': 'deflate'
        }

        resp = self.session.post(uri, data=data, verify=self.verify_ssl, headers=headers, timeout=self.timeout)

        logger.debug(resp.content)
        n = RETRIES
        try:
            self._check_status(resp, expect=201)
            n = 0
        except Exception as e:
            if resp.status_code == 429 or resp.status_code in [500, 501, 502, 503, 504]:
                logger.error(e)
            else:
                raise e

        while n != 0:
            logger.info('setting random retry interval to spread out the load')
            logger.info('retrying in %.00fs' % RETRIES_DELAY)
            sleep(RETRIES_DELAY)

            resp = self.session.post(uri, data=data, verify=self.verify_ssl, headers=headers, timeout=self.timeout)
            if resp.status_code in [200, 201]:
                break

            if n == 0:
                raise CIFBusy('system seems busy.. try again later')

        return json.loads(resp.content.decode('utf-8'))

    def _delete(self, uri, params={}):
        params = {f: params[f] for f in params if params.get(f)}
        if params.get('nolog'):
            del params['nolog']

        if params.get('limit'):
            del params['limit']

        resp = self.session.delete(uri, data=json.dumps(params), verify=self.verify_ssl, timeout=self.timeout)
        self._check_status(resp)
        return json.loads(resp.content.decode('utf-8'))

    def _patch(self, uri, data):
        resp = self.session.patch(uri, data=json.dumps(data), verify=self.verify_ssl, timeout=self.timeout)
        self._check_status(resp)
        return json.loads(resp.content.decode('utf-8'))

    def indicators_search(self, filters):
        rv = self._get('/search', params=filters)
        return rv['data']

    def indicators_create(self, data):
        data = str(data).encode('utf-8')

        uri = "{0}/indicators".format(self.remote)
        logger.debug(uri)
        rv = self._post(uri, data)
        return rv["data"]

    def indicators_delete(self, filters):
        uri = "{0}/indicators".format(self.remote)
        logger.debug(uri)
        rv = self._delete(uri, params=filters)
        return rv["data"]

    def feed(self, filters):
        rv = self._get('/feed', params=filters)
        return rv['data']

    def ping(self, write=False):
        t0 = time.time()

        uri = '/ping'
        if write:
            uri = '/ping?write=1'

        rv = self._get(uri)

        if rv:
            rv = (time.time() - t0)
            logger.debug('return time: %.15f' % rv)

        return rv

    def tokens_search(self, filters):
        rv = self._get('{}/tokens'.format(self.remote), params=filters)
        return rv['data']

    def tokens_delete(self, data):
        rv = self._delete('{}/tokens'.format(self.remote), data)
        return rv['data']

    def tokens_create(self, data):
        logger.debug(data)
        rv = self._post('{}/tokens'.format(self.remote), data)
        return rv['data']

    def tokens_edit(self, data):
        rv = self._patch('{}/tokens'.format(self.remote), data)
        return rv['data']

Plugin = HTTP


import pygame
pygame.init()
screen = pygame.display.set_mode((720, 480))
clock = pygame.time.Clock()
FPS = 60

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

ballsurface = pygame.Surface((50,50))
ballsurface.set_colorkey((0,0,0))
pygame.draw.circle(ballsurface, (255,0,0), (25,25),25)
ballsurface = ballsurface.convert_alpha()
ballrect = ballsurface.get_rect()
while True:
    clock.tick(FPS)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if ballrect.y >= 20:
                    ballrect.move_ip(0, -20)
            elif event.key == pygame.K_DOWN:
                if ballrect.y <= screen.get_size()[1] - 80:
                    ballrect.move_ip(0, 20)
            elif event.key == pygame.K_LEFT:
                if ballrect.x >= 20 :
                    ballrect.move_ip(-20, 0)
            elif event.key == pygame.K_RIGHT:
                if ballrect.x <= screen.get_size()[0] -80:
                    ballrect.move_ip(20, 0)
    screen.fill((255,255,255))
    screen.blit(ballsurface,ballrect)
    pygame.display.update()  # Or pygame.display.flip()


try:
  from grove import grove_temperature_humidity_aht20
  from grove.adc import ADC
  from gpiozero import DigitalOutputDevice
  import chainable_rgb_direct
except:
  grove_temperature_humidity_aht20 = None
  ADC = None
  DigitalOutputDevice = None
  chainable_rgb_direct = None
import random

class Plant:
  def __init__(self):
    if grove_temperature_humidity_aht20 != None and DigitalOutputDevice != None and ADC != None and chainable_rgb_direct != None:
      self.i2c = grove_temperature_humidity_aht20.GroveTemperatureHumidityAHT20(
        bus=4
      )
      self.fan_device = DigitalOutputDevice(18)
      self.adc = ADC()
      self.light_device = chainable_rgb_direct.rgb_led(2)
    self.dummy_fan = False
    self.dummy_light = False

  def __str__(self):
    return 'plant'

  def temp_humi(self, *args):
    if args[1] == True:
      return {'temperature': random.uniform(10,30), 'humidity': random.uniform(0,200)}

    temp, humi = self.i2c.read()
    return {'temperature': temp, 'humidity': humi}

  def water(self, *args):
    if args[1] == True:
      return {'water': random.uniform(0,1000)}

    return {'water': self.adc.read_voltage(4)}

  def moisture(self, *args):
    if args[1] == True:
      return {'moisture': random.uniform(0,200)}

    return {'moisture': self.adc.read_voltage(2)}

  def fan(self, *args):
    if args[1] == True:
      if args[0] != None:
        self.dummy_fan = ('off', 'on')[args[0].lower()]
      return {'fan': ('off', 'on')[self.dummy_fan]}

    if args[0] != None:
      new_state = args[0].lower()
      if new_state == 'on':
        self.fan_device.on()
      elif new_state == 'off':
        self.fan_device.off()
      else:
        raise ValueError(
          f"Invalid fan state {new_state}. Must be 'on' or 'off'"
        )
    return {'fan': ('off', 'on')[self.fan_device.is_active]}

  def light(self, *args):
    if args[1] == True:
      if args[0] != None:
        self.dummy_light = ('off', 'on')[args[0].lower()]
      return {'light': ('off', 'on')[self.dummy_light]}

    if args[0] != None:
      new_state = args[0].lower()
      if new_state == 'on':
        self.light_device.setOneLED(255, 255, 255, 0)
        self.light_device.setOneLED(255, 255, 255, 1)
      elif new_state == 'off':
        self.light_device.setOneLED(0, 0, 0, 0)
        self.light_device.setOneLED(0, 0, 0, 1)
      else:
        raise ValueError(
          f"Invalid light state {new_state}. Must be 'on' or 'off'"
        )
    return {
      'light':
      ('off', 'on')[0 not in (
        self.light_device.r_all[0],
        self.light_device.r_all[1],
        self.light_device.g_all[0],
        self.light_device.g_all[1],
        self.light_device.b_all[0],
        self.light_device.b_all[1]
      )]
    }


# How to detect specific color inside python
# from cv2 import getTrackbarPos
import numpy as np
import cv2 as cv
# img=cv.imread("resources/image.png")

# Convert in HSV (Hue, Saturation, Value)
# hue_img=cv.cvtColor(img,cv.COLOR_BGR2HSV)#rang barangi sakal my chla gye ga jb show kary gye

def slider():
    pass

path = "resources/image.png"

# new img or new window bnaye gye essy
cv.namedWindow("Bars")
cv.resizeWindow("Bars", 900, 300)

# Track Bar
# cv.createTrackbar("Hue","Bars",0,179,slider) yaha sy start krna hai slider bnana
cv.createTrackbar("Hue min", "Bars", 0, 179, slider)
cv.createTrackbar("Hue max", "Bars", 179, 179, slider)
cv.createTrackbar("Sat min", "Bars", 0, 255, slider)
cv.createTrackbar("Sat max", "Bars", 255, 255, slider)
cv.createTrackbar("Val min", "Bars", 0, 255, slider)
cv.createTrackbar("Val max", "Bars", 255, 255, slider)

img = cv.imread(path)
hsv_img = cv.cvtColor(img, cv.COLOR_BGR2HSV)

# hue_min=getTrackbarPos("Hue min","Bars")
# print(hue_min)
while True:

    img = cv.imread(path)
    hsv_img = cv.cvtColor(img, cv.COLOR_BGR2HSV)
    hue_min = cv.getTrackbarPos("Hue min", "Bars")
    hue_max = cv.getTrackbarPos("Hue max", "Bars")
    sat_min = cv.getTrackbarPos("Sat min", "Bars")
    sat_max = cv.getTrackbarPos("Sat max", "Bars")
    val_min = cv.getTrackbarPos("Val min", "Bars")
    val_max = cv.getTrackbarPos("Val max", "Bars")
    print(hue_min,hue_max,sat_min,sat_max,val_min,val_max)

 # To see these changes inside an image
    lower=np.array([hue_min,sat_min,val_min])
    upper=np.array([hue_max,sat_max,val_max])

 # image mask
    mask_img=cv.inRange(hsv_img,lower,upper)
    out_img=cv.bitwise_and(img,img,mask=mask_img)

    cv.imshow("original",img)
    cv.imshow("HSV",hsv_img)
    cv.imshow("Mask",mask_img)
    cv.imshow("Final Output",out_img)

    if cv.waitKey(1) & 0xff ==ord('q'):
        break
cv.destroyAllWindows()


import pickle
import os
from bs4 import BeautifulSoup
from numpy import vectorize
import spacy
import unidecode
from word2number import w2n
import os
import pickle
#import contractions

nlp = spacy.load('en_core_web_lg')

# exclude words from spacy stopwords list
deselect_stop_words = ['no', 'not']
for w in deselect_stop_words:
    nlp.vocab[w].is_stop = False

def strip_html_tags(text):
    soup = BeautifulSoup(text, "html.parser")
    stripped_text = soup.get_text(separator=" ")
    return stripped_text

def remove_whitespace(text):
    text = text.strip()
    return " ".join(text.split())

def remove_accented_chars(text):
    text = unidecode.unidecode(text)
    return text

def expand_contractions(text):
    text = contractions.fix(text)
    return text

def text_preprocessing(text, accented_chars=True, contractions=True,
                       convert_num=True, extra_whitespace=True,
                       lemmatization=True, lowercase=True, punctuations=True,
                       remove_html=True, remove_num=True, special_chars=True,
                       stop_words=True):
    if remove_html == True:
        text = strip_html_tags(text)
    if extra_whitespace == True:
        text = remove_whitespace(text)
    if accented_chars == True:
        text = remove_accented_chars(text)
    if contractions == True:
        text = expand_contractions(text)
    if lowercase == True:
        text = text.lower()

    doc = nlp(text)

    clean_text = []

    for token in doc:
        flag = True
        edit = token.text

        if stop_words == True and token.is_stop and token.pos_ != 'NUM':
            flag = False

        if punctuations == True and token.pos_ == 'PUNCT' and flag == True:
            flag = False

        if special_chars == True and token.pos_ == 'SYM' and flag == True:
            flag = False

        if remove_num == True and (token.pos_ == 'NUM' or token.text.isnumeric()) \
        and flag == True:
            flag = False

        if convert_num == True and token.pos_ == 'NUM' and flag == True:
            edit = w2n.word_to_num(token.text)

        elif lemmatization == True and token.lemma_ != "-PRON-" and flag == True:
            edit = token.lemma_

        if edit != "" and flag == True:
            clean_text.append(edit)
    return clean_text
def fix(PickleFile):
    Path=r"C:\Users\moham\Desktop\info\abstracts"
    Path_1=r"C:\Users\moham\Desktop\info\Treated_Abstracts"
    os.makedirs(Path_1,exist_ok=True)
    file=PickleFile.replace(".pkl",".txt")
    if True :
        f=open(os.path.join(Path,file),"r",encoding="UTF-8")
        lines=f.readlines()
        text=""
        for line in lines :
            text=text+" "+line
        f_1=open(os.path.join(Path_1,file[:file.find(".txt")]+".pkl"),"wb")

        pickle.dump(text_preprocessing(text), f_1)
        f_1.close()
        f.close()

Path=r"C:\Users\moham\Desktop\info\Treated_Abstracts"
vocab_to_int=dict()
max=0
for PickleFile in os.listdir(Path) :
    with open(os.path.join(Path,PickleFile), 'rb') as f:
        try:
            loaded_text = pickle.load(f)
        except :
            fix(PickleFile)
            loaded_text = pickle.load(f)

        for mot in loaded_text :
            if ((mot in vocab_to_int)==False):
                vocab_to_int[mot]=1
            else :
                vocab_to_int[mot]+=1

T=[]
T_1=[]
s=0
for index,value in vocab_to_int.items():
    T_1.append([index,value])
    if value<10:
        print (index)
        s=s+1
    else :
        T.append([index,value])
T=sorted(T,key=lambda x:x[1],reverse=True)
print(s)
vocab_to_int=dict()
for i in range(len(T)):
      vocab_to_int[T[i][0]]=i
int_to_vocab=dict()
for index,value in vocab_to_int.items():
    int_to_vocab[value]=index
print(len(int_to_vocab),len(vocab_to_int))
with open(r"C:\Users\moham\Desktop\info\test\vocab_to_int.pkl", 'wb') as f:
    pickle.dump(vocab_to_int, f)
with open(r"C:\Users\moham\Desktop\info\test\int_to_vocab.pkl", 'wb') as f:
    pickle.dump(int_to_vocab, f)
with open(r"C:\Users\moham\Desktop\info\test\ifIchangemymind.pkl", 'wb') as f:
    pickle.dump(T_1, f)


"""
While the previous DFS approach works, it can potentially traverse long
sections of the graph without a real need. In order to improve further,
we can leverage the previously ignored properties of the similar relation: it
is an equivalence relation.

Equivalence relations bring a natural partition to the set, where in our
particular case each partition contains strings similar to each other. If we
model each partition as a disjoin-set, then we could optimize the
transitivity check: if two strings belong to same disjoint set, then they are
similar.

Knowing two strings belong to same disjoint-set, means retrieving the
representative for each one, and comparing those representatives. Retrieving
each representative, in a disjoint-set forests implementation, can be done in
O(log(n)). This should be better than the linear complexity from DFS.

The disjoint-set forest was taken from Cormen book.

NOTE: Despite theoretical advantages mentioned, this algorithm actually is
slower than the DFS one. Perhaps the paths to parent are too long (unbalanced
trees), or perhaps the path-compression is worth it only if you query more
times.

"""

from itertools import izip

class DisjointSet:
    def __init__(self, val):
        self.p = self
        self.rank = 0

def make_set(x):
    return DisjointSet(x)

def union(x, y):
    link(find_set(x), find_set(y))

def link(x, y):
    if x.rank > y.rank:
        y.p = x
    else:
        x.p = y
        if x.rank == y.rank:
            y.rank += 1

def find_set(x):
    if x != x.p:
        x.p = find_set(x.p)
    return x.p

class Solution(object):
    def create_forest(self, pairs):
        forest = dict()
        for x, y in pairs:
            if x not in forest:
                forest[x] = make_set(x)
            if y not in forest:
                forest[y] = make_set(y)
            union(forest[x], forest[y])
        return forest

    def are_similar(self, w1, w2, forest):
        # reflexivity
        if w1 == w2:
            return True
        # they can't be similar if one is not in forest
        elif w1 not in forest or w2 not in forest:
            return False
            # symmetry & transitivity
        elif find_set(forest[w1]) == find_set(forest[w2]):
            return True
        else:
            return False

    def areSentencesSimilarTwo(self, words1, words2, pairs):
        if len(words1) != len(words2):
            return False
        forest = self.create_forest(pairs)
        for w1, w2 in izip(words1, words2):
            if not self.are_similar(w1, w2, forest):
                return False
        return True