import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.common.exceptions import NoSuchElementException

title  = input('\nEnter the title of the form\n')
thumbnail_link  = input('\nPlease provide a thumnail url\n')
desc  = input('\nEnter a little description\n')
generes  = input('\nAdd a few categories\n')
episode_link  = input('\nEnter the webiste to be  parsed \n')

def links():
	epi = episode_link

	# eppp = 'https://vidstreaming.io'
	eppp = ('anylink prefix')

	response = requests.get(epi)

	soup = BeautifulSoup(response.text, 'html.parser')

	video_container = soup.find('ul', attrs = {'class' : 'listing items lists'})

	vid_links = video_container.find_all('li')

	browseable_links = []

	for links in vid_links:
		## parsed the a tag to get the href value by split and indexing
		cleaned_link = str(links.find('a')).split()[1]
		browseable_links.append(eppp+cleaned_link[6:(len(cleaned_link)-2)])

	urls = browseable_links[::-1]

	link_list = []

	for url in urls:
		res = requests.get(url)
		bigsoup = BeautifulSoup(res.text, 'html.parser')
		frame = bigsoup.find('iframe')
		src = str(frame).split()[6]
		cleaned_src = src[5:(len(src)-12)]
		link_list.append('https:' + cleaned_src)

	return link_list

rings = links()

def log_update(name,image_url, desc, genres):

	path = 'driver/chromedriver'

	driver = webdriver.Chrome(executable_path = path)
	driver.get('login URL')

	## LOGIN
	user_ = driver.find_element_by_xpath('//*[@id="id_username"]')
	user_.send_keys('username')
	pswd = driver.find_element_by_xpath('//*[@id="id_password"]')
	pswd.send_keys('pswd', Keys.ENTER)

	#Open a new window to fill up new form
	driver.find_element_by_xpath('//*[@id="content-main"]/div[2]/table/tbody/tr[1]/td[1]/a').click()

	##TITLE OR ANYTHING ELSE
	title = driver.find_element_by_id('id_title')
	title.send_keys(name)

	image = driver.find_element_by_xpath('//*[@id="id_thumbnail_url"]')
	image.send_keys(image_url)

	description = driver.find_element_by_xpath('//*[@id="id_description"]')
	description.send_keys(desc)

	genre = driver.find_element_by_xpath('//*[@id="id_genre"]')
	genre.send_keys(genres)

	#!! Start looping over what you want to neccesarily update (For pop ups)

	main = driver.window_handles[0]
	main
	ep_no = 0

	for update in rings:
		ep_no = ep_no + 1
		try:
			driver.find_element_by_xpath('//*[@id="add_id_episodes"]').click()

			a = driver.window_handles[-1]
			driver.switch_to.window(a)

			ep_desc = driver.find_element_by_xpath('//*[@id="id_description"]')

			ep_desc.send_keys(f'{name} Epsiode {ep_no}')

			ep_nos = driver.find_element_by_xpath('//*[@id="id_episode_no"]')
			ep_nos.send_keys(f'{ep_no}')

			ep_link = driver.find_element_by_xpath('//*[@id="id_link"]')
			ep_link.send_keys(update)

			driver.find_element_by_class_name('default').click()

			driver.switch_to.window(main)

		except NoSuchElementException as e:
			print(e)
	try:
		grand_save = driver.find_element_by_name('_save').click()
		time.sleep(10)

	except error as e:
		print(e)
log_update(title, desc, thumbnail_link, generes)


import os
import sys
import collections
import string

script_name = sys.argv[0]

res = {
    "Lines":"",
    "Characters":"",
    "Total-Words":"",
    "Unique-Words":"",
    "Repeated-Words":"",
    "Special-Characters":""
}

try:
    textfile = sys.argv[1]
    with open(textfile, "r") as f:

        line=0
        data = f.read()
        Lisst = data.split("\n")

        for i in Lisst:
            if i:
                line += 1
        res["Lines"] = line
        res["Characters"] = len(data.replace(" ","")) - res["Lines"]
        counter = collections.Counter(data.split())
        d = counter.most_common()
        res["Total-Words"] = sum([i[1] for i in d])
        res["Unique-Words"] = len([i[0] for i in d])
        res["Repeated-Words"] = sum([i[1] for i in d])-len([i[0] for i in d])
        special_chars = string.punctuation
        res["Special-Characters"] = sum(v for k, v in collections.Counter(data).items() if k in special_chars)

except IndexError:
    print('Usage: %s TEXTFILE' % script_name)
except IOError:
    print('"%s" cannot be opened.' % textfile)

print(res)


from __future__ import absolute_import, unicode_literals

import warnings

from django.core.management import call_command
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    """Verify importing dataset into clean migrated DB."""

    help = __doc__

    def run_from_argv(self, argv):
        """Migrate DB, flush and import dataset."""

        # this command is used to universally verify dataset import into sqlite
        # (development) or mysql (production) databases. Since for sqlite a
        # memory database is used a migration needs to be performed first. For
        # mysql a flush is required to ensure no previous data is present.

        # suppress pyyaml warnings (which doesn't support timezoned datetimes)
        warnings.filterwarnings(
            "ignore",
            r"DateTimeField .* received a naive datetime",
            RuntimeWarning,
            r"django\.db\.models\.fields",
        )

        print("+ Running migrations")
        # run migrate quietly as testing/debugging migrations is not priority
        # here.
        call_command("migrate", "-v0")
        print("+ Flusing old data")
        call_command("flush", "--no-input")
        print("+ Importing fixture " + argv[2])
        call_command("load_dataset", argv[2])
        print("Done")


from termcolor import colored
from random import randint, shuffle, sample

def Read_Datafile():
    datafile = open('data.txt', 'r')
    filelines = datafile.readlines()
    m, p = map(int, filelines[0].split())

    plan = [[0] * p] * m
    data = [[]] * m

    for i in range(1, m + 1):
        data[i - 1] = list(map(int, filelines[i].split()))[1:]

    for i in range(m):
        machine = [0] * p
        for j in range(len(data[i])):
            machine[data[i][j] - 1] = 1
        plan[i] = machine

    clustersnum = randint(2, min(m, p))

    clusterslist = [i + 1 for i in range(clustersnum)]
    m_clusters = sample(clusterslist, clustersnum)
    for i in range(clustersnum, m):
        m_clusters.append(randint(1, clustersnum))
    shuffle(m_clusters)

    p_clusters = sample(clusterslist, clustersnum)
    for i in range(clustersnum, p):
        p_clusters.append(randint(1, clustersnum))
    shuffle(p_clusters)

    return plan, m_clusters, p_clusters

def List_to_Str(arr):
    string = ''
    for i in range(len(arr) - 1):
        string += str(arr[i]) + ' '
    string += str(arr[len(arr) - 1])
    return string

def Find_Indexes(arr, elem):
    out = []
    if elem in arr:
        out.append(arr.index(elem))
        for i in range(arr.count(elem) - 1):
            out.append(arr.index(elem, out[-1] + 1))
    return out

def Print_Plan(plan, m_clusters, p_clusters):
    print(' ' * (len(str(max(m_clusters))) + 1), colored(List_to_Str(p_clusters), 'yellow'))
    for i in range(len(m_clusters)):
        print(colored(m_clusters[i], 'yellow'), end='')
        if m_clusters[i] < 10:
            print(' ', end='')
        for j in range(len(plan[i])):
            if p_clusters[j] > 9:
                print(end=' ')
            if plan[i][j]:
                print(' +', end='')
            else:
                print('  ', end='')
        print()

def Swap_Arr(arr, i1, i2):
    new = arr
    new[i1], new[i2] = new[i2], new[i1]
    return new

Algorithms and Data Structures/Variable Neighbourhood Search/um_funs.py


import pytesseract
import easyocr
import cv2
import matplotlib.pyplot as plt
from PIL import Image
# from all_functions import get_keyword_tiker_moex, decorator_speed
from Config import Config
from PIL import Image
import pytesseract
import io
import re

def raspoznavanie_texta_na_photo(photo):
    # читать изображение с помощью OpenCV
    image = cv2.imread(photo)
    # или вы можете использовать подушку
    # image = Image.open("test.png")

    # получаем строку
    string = pytesseract.image_to_string(image, lang='eng' )
    # string2 = pytesseract.image_to_string(image,lang='rus')
    # rezult = string2 + string
    # r = re.compile("[а-яА-Я]+")
    # words = str(string2).split()
    # russian = [w for w in filter(r.match, words)]

    # печатаем
    return string
# raspoznavanie_texta_na_photo()

# def raspoznavanie_texta_na_photo():
#     reader = easyocr.Reader(['en'])
#     rezult = reader.readtext("exempl_goodwin_signals.jpg")
#     print(rezult)
# raspoznavanie_texta_na_photo()

def fast_image_to_text(image_path):
    # Загрузка изображения
    image = cv2.imread(image_path)

    # Преобразование в оттенки серого
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Применение размытия по Гауссу
    blur = cv2.GaussianBlur(gray, (3, 3), 0)

    # Применение порогового значения Оцу
    thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

    # Применение морфологических операций для удаления шума
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)

    # Распознавание текста
    text = pytesseract.image_to_string(opening, lang='eng', config='--psm 6')

    return text

def photo_to_text(photo):
    text = pytesseract.image_to_string(photo, lang='rus+eng')
    return text

async def download_photo(event, client):
    if event.photo:
        # Скачиваем фото
        photo_bytes = await client.download_media(event.photo, bytes)
        image = Image.open(io.BytesIO(photo_bytes))
        return image

def filter_words_rus_en(lst):
    pattern = re.compile(r'^[а-яА-Яa-zA-Z]+$')
    filtered_list = [word for word in lst if pattern.match(word)]
    text = ' '.join(filtered_list)
    return f'🌿🌿🌿 Текст из фото \n{text}'


#!/usr/bin/env python3

import random

import eventlet
import socketio
import sys

from classes.house import House
from classes.player import Player

sio = socketio.Server(cors_allowed_origins='*')
app = socketio.WSGIApp(sio, static_files={
    '/': {'content_type': 'text/html', 'filename': 'index.html'}
})

house = House()

@sio.event
def connect(sid, environ):
    print('connect ', sid)
    sio.emit('event', {'response': 'my response'})

@sio.event
def my_message(sid, data):
    print('message ', data)

@sio.on("join")
def join(sid, data):
    name = data['name']
    lobby = data['lobby']

    game = house.get_game(lobby)
    disconnected_player = game.get_disconnected_player(name)

    if disconnected_player:
        sio.enter_room(sid, lobby)
        game.add_player(disconnected_player)
        game.update_sid(disconnected_player.sid, sid)
        disconnected_player.sid = sid
        sio.emit('player_join', {'name': disconnected_player.name}, lobby)
        host = game.get_player(game.host)

        players = []
        revealed = {}

        for player in [*game.players, *game.disconnected]:
            player_data = {'name': player.name, 'points': player.points }
            if player.reveal_pos or player.sid in game.placed_cards.keys(): player_data['placed'] = True
            player_data['connected'] = (player in game.players)
            players.append(player_data)

            if player.sid in game.revealed_players:
                revealed[player.reveal_pos] = game.placed_cards[player.sid]

        return {
            'players': players,
            'host': host.name,
            'points_to_win': game.points_to_win,
            'hand_size': game.hand_size,
            'card_decks': game.card_decks,
            'revealed': revealed,
            'hand': disconnected_player.hand,
            'black': game.black_card,
            'zar': game.get_zar().name,
        }

    if game.game_state != "Lobby":
        return {'error': 'Game already running.'}

    player = Player(sid, name)

    if not game.add_player(player):
        return {'error': 'Player name already exists.'}

    sio.enter_room(sid, lobby)

    sio.emit('player_join', {'name': player.name}, lobby)  # Sending new player information to other players
    host = game.get_player(game.host)

    return {
        'players': list(map(lambda p: {
            'name': p.name,
            'points': 0,
            'connected': p in game.players
        }, [*game.players, *game.disconnected])),
        'host': host.name,
        'points_to_win': game.points_to_win,
        'hand_size': game.hand_size,
        'card_decks': game.card_decks,
        'language': game.language
    }

@sio.on("start_game")
def start_game(sid):
    game = house.get_game_of_player(sid)
    if not game:
        return {'error': 'You are not in a lobby.'}

    if game.host != sid:
        return {'error': 'You are not the host.'}

    if len(game.players) < 3:
        return {'error': 'You need at least 3 players in the lobby.'}

    for player in game.players:
        player.hand = []

    game.start_game()

    for player in game.players:
        player.points = 0
        sio.emit('game_start', {'hand': player.hand, 'black': game.black_card, 'zar': game.get_zar().name}, to=player.sid)

@sio.on("place_cards")
def place_cards(sid, cards):
    game = house.get_game_of_player(sid)
    game.player_placed_cards(sid, cards)
    player = game.get_player(sid)

    sio.emit('cards_placed', player.name, room=game.name)

@sio.on("reveal")
def reveal_cards(sid, pos):
    game = house.get_game_of_player(sid)
    zar = game.get_zar()

    if zar.sid != sid:
        return {'error': 'You are not the zar.'}

    if not game.all_players_placed():
        return {'error': 'Not all players have placed their cards.'}

    players = list(filter(lambda p: p.sid != sid and not game.is_player_revealed(p.sid), game.players))

    if len(players) == 0:
        return {'error': 'All players are revealed.'}

    player = random.choice(players)

    game.player_revealed(player.sid)

    player.reveal_pos = pos

    sio.emit("cards_revealed", {'pos': pos, 'cards': game.placed_cards[player.sid]}, room=game.name)

@sio.on("winner_selected")
def winner(sid, pos):
    game = house.get_game_of_player(sid)

    if game.get_zar().sid != sid:
        return {'error': 'You are not the zar.'}

    if not game.all_cards_revealed():
        return {'error': 'Not all cards are revealed.'}

    winning_player = game.get_player_with_pos(pos)

    if not winning_player:
        return {'error': 'Player with name ' + name + ' not found.'}

    winning_player.points += 1

    if winning_player.points >= game.points_to_win:
        game.end_game()

        points = {}
        for player in game.players:
            points[player.name] = player.points
        sio.emit('game_end', points, room=game.name)
    else:
        pos = {}
        for player in game.players:
            pos[player.reveal_pos] = player.name

        game.start_round()
        for player in game.players:
            sio.emit('next_round', {
                'hand': player.hand,
                'black': game.black_card,
                'zar': game.get_zar().name,
                'winner': winning_player.name,
                'pos': pos
            }, to=player.sid)

@sio.on("change_settings")
def change_settings(sid, settings):
    game = house.get_game_of_player(sid)

    if game.get_zar().sid != sid:
        return {'error': 'You are not the zar.'}

    if game.game_state != "Lobby":
        return {'error': 'Settings can only be canged in the lobby.'}

    if settings['card_decks']:
        game.card_decks = settings['card_decks']

    if settings['points_to_win']:
        game.points_to_win = settings['points_to_win']

    if settings['hand_size']:
        game.hand_size = settings['hand_size']

    if settings['language']:
        game.language = settings['language']

    sio.emit('settings_changed', settings, room=game.name)

    return {'info': 'The settings have been changed.'}

@sio.on("delete_card")
def delete_card(sid, card):
    game = house.get_game_of_player(sid)

    if not game:
        return {'error': 'You are not in a game.'}

    player = game.get_player(sid)

    if player.deleted_card:
        return {'error': 'You already deleted a card.'}

    if card not in player.hand:
        return {'error': 'The card does not exist in your hand.'}

    player.hand.remove(card)
    player.deleted_card = True

@sio.on("games")
def games(sid, password):
    if(password != 'Umpa Lumpas'):
        return {'error': 'Wrong password.'}

    return [game.to_json() for game in house.games.values()]

@sio.on("players")
def players(sid, password):
    if(password != 'Umpa Lumpas'):
        return {'error': 'Wrong password.'}

    return [player.to_json() for game in house.games.values() for player in game.players]

@sio.on("leave")
def leave(sid):
    disconnect(sid)

@sio.event
def disconnect(sid):
    for game in house.games.values():
        if game.has_player(sid):
            sio.leave_room(sid, game.name)

            if len(game.players) == 1:
                del house.games[game.name]
                return

            zar = game.get_zar()
            player = game.remove_player(sid)
            sio.emit('host', game.get_player(game.host).name, game.name)
            sio.emit('player_leave', player.name, game.name)

            if game.game_state == "Lobby": return

            if len(game.players) < 3:
                game.end_game()
                points = {}
                for player in game.players:
                    points[player.name] = player.points
                    sio.emit('game_end', points, room=game.name)
            elif player == zar:
                game.start_round()
                for player in game.players:
                    sio.emit('next_round', {
                        'hand': player.hand,
                        'black': game.black_card,
                        'zar': game.get_zar().name,
                        'winner': ''
                    }, to=player.sid)

if __name__ == '__main__':
    if(len(sys.argv) > 1 and sys.argv[1] == 'dev'):
        eventlet.wsgi.server(eventlet.listen(('', 5000)), app)
    else:
        eventlet.wsgi.server(eventlet.wrap_ssl(eventlet.listen(('', 5000)), certfile='cert.crt', keyfile='private.key', server_side=True), app)


from bs4 import BeautifulSoup
import requests

WEBSITE = "https://www.esquire.com/entertainment/movies/g226/best-movies-ever-0609/"

response = requests.get(WEBSITE)
website_html = response.text
# print(website_html)

soup = BeautifulSoup(website_html, "html.parser")

moviename_tags = soup.findAll(name="span", class_="listicle-slide-hed-text")
movies = [span.getText() for span in moviename_tags]

# print(movies)
entries = [f"{i+1}.) {movies[i]}\n" for i in range(len(movies))]

with open("movieslist.txt", "w") as file:
    file.writelines(entries)


"""Module for working with datasets."""

from __future__ import annotations

# stdlib
from enum import Enum
from pathlib import PosixPath
import logging
import os
import re
from typing import Union, Set, Dict, Iterable, List, Optional

# external
import formulate
import uproot
from uproot.reading import ReadOnlyDirectory
from uproot.behaviors.TTree import TTree

# tdub
import tdub.config

log = logging.getLogger(__name__)

DataSource = Union[
    str, Iterable[str], os.PathLike, Iterable[os.PathLike], ReadOnlyDirectory, TTree
]

class Region(Enum):
    """A simple enum class for easily using region information.

    Attributes
    ----------
    r1j1b
        Label for our `1j1b` region.
    r2j1b
        Label for our `2j1b` region.
    r2j2b
        Label for our `2j2b` region.

    Examples
    --------
    Using this enum for grabing the ``2j2b`` region from a set of
    files:

    >>> from tdub.data import Region, selection_for
    >>> from tdub.frames import iterative_selection
    >>> df = iterative_selection(files, selection_for(Region.r2j2b))

    """

    r1j1b = 0
    r2j1b = 1
    r2j2b = 2
    rUnkn = 9

    @staticmethod
    def from_str(s: str) -> Region:
        """Get enum value for the given string.

        This function supports three ways to define a region; prefixed
        with "r", prefixed with "reg", or no prefix at all. For
        example, ``Region.r2j2b`` can be retrieved like so:

        - ``Region.from_str("r2j2b")``
        - ``Region.from_str("reg2j2b")``
        - ``Region.from_str("2j2b")``

        Parameters
        ----------
        s : str
            String representation of the desired region

        Returns
        -------
        Region
            Enum version

        Examples
        --------
        >>> from tdub.data import Region
        >>> Region.from_str("1j1b")
        <Region.r1j1b: 0>

        """
        if s.startswith("reg"):
            rsuff = s.split("reg")[-1]
            return Region.from_str(rsuff)
        elif s.startswith("r"):
            return Region[s]
        else:
            if s == "2j2b":
                return Region.r2j2b
            elif s == "2j1b":
                return Region.r2j1b
            elif s == "1j1b":
                return Region.r1j1b
            else:
                raise ValueError(f"{s} doesn't correspond to a Region")

    def __str__(self) -> str:
        """Convert to string, removing prefix 'r'."""
        return self.name[1:]

def as_region(region: str | Region) -> Region:
    """Convert input to :py:obj:`~Region`.

    Meant to be similar to :py:func:`numpy.asarray` function.

    Parameters
    ----------
    region : str or Region
        Region already as a Region or as a str

    Returns
    -------
    Region
        Region representation.

    Examples
    --------
    >>> from tdub.data import as_region, Region
    >>> as_region("r2j1b")
    <Region.r2j1b: 1>
    >>> as_region(Region.r2j2b)
    <Region.r2j2b: 2>

    """
    if isinstance(region, str):
        return Region.from_str(region)
    return region

class SampleInfo:
    """Describes a sample's attritubes given it's name.

    Parameters
    ----------
    input_file : str
        File stem containing the necessary groups to parse.

    Attributes
    ----------
    phy_process : str
        Physics process (e.g. ttbar or tW_DR or Zjets)
    dsid : int
        Dataset ID
    sim_type : str
        Simulation type, "FS" or "AFII"
    campaign : str
        Campaign, MC16{a,d,e}
    tree : str
        Original tree (e.g. "nominal" or "EG_SCALE_ALL__1up")

    Examples
    --------
    >>> from tdub.data import SampleInfo
    >>> sampinfo = SampleInfo("ttbar_410472_AFII_MC16d_nominal.root")
    >>> sampinfo.phy_process
    ttbar
    >>> sampinfo.dsid
    410472
    >>> sampinfo.sim_type
    AFII
    >>> sampinfo.campaign
    MC16d
    >>> sampinfo.tree
    nominal

    """

    _parse: re.Pattern = re.compile(
        r"""(?P<phy_process>\w+)_
        (?P<dsid>[0-9]{6})_
        (?P<sim_type>(FS|AFII))_
        (?P<campaign>MC16(a|d|e))_
        (?P<tree>\w+)
        (\.\w+|$)""",
        re.X,
    )

    def __init__(self, input_file: str) -> None:
        """Class constructor."""
        if "Data_Data" in input_file:
            self.phy_process = "Data"
            self.dsid = 0
            self.sim_type = "Data"
            self.campaign = "Data"
            self.tree = "nominal"
        else:
            m: re.Match | None = SampleInfo._parse.match(input_file)
            if not m:
                raise ValueError(f"{input_file} cannot be parsed by SampleInfo regex")
            self.phy_process = m.group("phy_process")
            if self.phy_process.startswith("MCNP"):
                self.phy_process = "MCNP"
            self.dsid = int(m.group("dsid"))
            self.sim_type = m.group("sim_type")
            self.campaign = m.group("campaign")
            self.tree = m.group("tree")

def avoids_for(region: str | Region) -> list[str]:
    """Get the features to avoid for the given region.

    See the :py:mod:`tdub.config` module for definition of the
    variables to avoid (and how to modify them).

    Parameters
    ----------
    region : str or tdub.data.Region
        Region to get the associated avoided branches.

    Returns
    -------
    list(str)
        Features to avoid for the region.

    Examples
    --------
    >>> from tdub.data import avoids_for, Region
    >>> avoids_for(Region.r2j1b)
    ['HT_jet1jet2', 'deltaR_lep1lep2_jet1jet2met', 'mass_lep2jet1', 'pT_jet2']
    >>> avoids_for("2j2b")
    ['deltaR_jet1_jet2']

    """
    region = as_region(region)
    if region == Region.r1j1b:
        return tdub.config.AVOID_IN_CLF_1j1b
    elif region == Region.r2j1b:
        return tdub.config.AVOID_IN_CLF_2j1b
    elif region == Region.r2j2b:
        return tdub.config.AVOID_IN_CLF_2j2b
    else:
        raise ValueError(f"Incompatible region: {region}")

def branches_from(
    source: DataSource,
    tree: str = "WtLoop_nominal",
    ignore_weights: bool = False,
) -> list[str]:
    """Get a list of branches from a data source.

    If the `source` is a list of files, the first file is the only
    file that is parsed.

    Parameters
    ----------
    source : str, list(str), os.PathLike, list(os.PathLike), or uproot File/Tree
        What to parse to get the branch information.
    tree : str
        Name of the tree to get branches from
    ignore_weights : bool
        Flag to ignore all branches starting with `weight_`.

    Returns
    -------
    list(str)
        Branches from the source.

    Raises
    ------
    TypeError
        If `source` can't be used to find a list of branches.

    Examples
    --------
    >>> from tdub.data import branches_from
    >>> branches_from("/path/to/file.root", ignore_weights=True)
    ["pT_lep1", "pT_lep2"]
    >>> branches_from("/path/to/file.root")
    ["pT_lep1", "pT_lep2", "weight_nominal", "weight_tptrw"]

    """
    if isinstance(source, (str, PosixPath)):
        t = uproot.open(source).get(tree)
    elif isinstance(source, list):
        t = uproot.open(source[0]).get(tree)
    elif isinstance(source, uproot.reading.ReadOnlyDirectory):
        t = source.get(tree)
    elif isinstance(source, uproot.behaviors.TTree.TTree):
        t = source
    else:
        raise TypeError("Cannot use source (it is type %s)" % str(type(source)))
    branches = t.keys()

    if ignore_weights:
        weights = set(filter(re.compile(r"(weight_\w+)").match, branches))
        branches = set(branches) ^ weights

    return list(sorted(branches, key=str.lower))

def categorize_branches(source: list[str]) -> dict[str, list[str]]:
    """Categorize branches into a separated lists.

    The categories:

    - `kinematics`: for kinematic features (used for classifiers)
    - `weights`: for any branch that starts or ends with ``weight``
    - `meta`: for meta information (final state information)

    Parameters
    ----------
    source : list(str)
        Complete list of branches to be categorized.

    Returns
    -------
    dict(str, list(str))
        Dictionary connecting categories to their associated list of
        branchess.

    Examples
    --------
    >>> from tdub.data import categorize_branches, branches_from
    >>> branches = ["pT_lep1", "pT_lep2", "weight_nominal", "weight_sys_jvt", "reg2j2b"]
    >>> cated = categorize_branches(branches)
    >>> cated["weights"]
    ['weight_sys_jvt', 'weight_nominal']
    >>> cated["meta"]
    ['reg2j2b']
    >>> cated["kinematics"]
    ['pT_lep1', 'pT_lep2']

    Using a ROOT file:

    >>> root_file = PosixPath("/path/to/file.root")
    >>> cated = categorize_branches(branches_from(root_file))

    """
    metas = {
        "reg1j1b",
        "reg2j1b",
        "reg2j2b",
        "reg1j0b",
        "reg2j0b",
        "isMC16a",
        "isMC16d",
        "isMC16e",
        "OS",
        "SS",
        "elmu",
        "elel",
        "mumu",
        "charge_lep1",
        "charge_lep2",
        "pdgId_lep1",
        "pdgId_lep2",
        "runNumber",
        "randomRunNumber",
        "eventNumber",
    }
    bset = set(source)
    weight_re = re.compile(r"(^weight_\w+)|(\w+_weight$)")
    weights = set(filter(weight_re.match, bset))
    metas = metas & set(bset)
    kinematics = (set(bset) ^ weights) ^ metas
    return {
        "kinematics": sorted(kinematics, key=str.lower),
        "weights": sorted(weights, key=str.lower),
        "meta": sorted(metas, key=str.lower),
    }

def features_for(region: str | Region) -> list[str]:
    """Get the feature list for a region.

    See the :py:mod:`tdub.config` module for the definitions of the
    feature lists (and how to modify them).

    Parameters
    ----------
    region : str or tdub.data.Region
        Region as a string or enum entry. Using ``"ALL"`` returns a
        list of unique features from all regions.

    Returns
    -------
    list(str)
        Features for that region (or all regions).

    Examples
    --------
    >>> from pprint import pprint
    >>> from tdub.data import features_for
    >>> pprint(features_for("reg2j1b"))
    ['mass_lep1jet1',
     'mass_lep1jet2',
     'mass_lep2jet1',
     'mass_lep2jet2',
     'pT_jet2',
     'pTsys_lep1lep2jet1jet2met',
     'psuedoContTagBin_jet1',
     'psuedoContTagBin_jet2']

    """
    # first allow retrieval of all features
    if region == "ALL":
        return sorted(
            set(tdub.config.FEATURESET_1j1b)
            | set(tdub.config.FEATURESET_2j1b)
            | set(tdub.config.FEATURESET_2j2b),
            key=str.lower,
        )

    region = as_region(region)
    if region == Region.r1j1b:
        return tdub.config.FEATURESET_1j1b
    if region == Region.r2j1b:
        return tdub.config.FEATURESET_2j1b
    if region == Region.r2j2b:
        return tdub.config.FEATURESET_2j2b
    else:
        raise ValueError(f"Incompatible region: {region}")

def quick_files(
    datapath: str | os.PathLike,
    campaign: str | None = None,
    tree: str = "nominal",
) -> dict[str, list[str]]:
    """Get a dictionary connecting sample processes to file lists.

    The lists of files are sorted alphabetically. These types of
    samples are currently tested:

    - `tW_DR` (410648, 410649 full sim)
    - `tW_DR_AFII` (410648, 410649 fast sim)
    - `tW_DR_PS` (411038, 411039 fast sim)
    - `tW_DR_inc` (410646, 410647 full sim)
    - `tW_DR_inc_AFII` (410646, 410647 fast sim)
    - `tW_DS` (410656, 410657 full sim)
    - `tW_DS_inc` (410654, 410655 ful sim)
    - `ttbar` (410472 full sim)
    - `ttbar_AFII` (410472 fast sim)
    - `ttbar_PS` (410558 fast sim)
    - `ttbar_PS713` (411234 fast sim)
    - `ttbar_hdamp` (410482 fast sim)
    - `ttbar_inc` (410470 full sim)
    - `ttbar_inc_AFII` (410470 fast sim)
    - `Diboson`
    - `Zjets`
    - `MCNP`
    - `Data`

    Parameters
    ----------
    datapath : str or os.PathLike
        Path where all of the ROOT files live.
    campaign : str, optional
        Enforce a single campaign ("MC16a", "MC16d", or "MC16e").
    tree : str
        Upstream AnalysisTop ntuple tree.

    Returns
    -------
    dict(str, list(str))
        The dictionary of processes and their associated files.

    Examples
    --------
    >>> from pprint import pprint
    >>> from tdub.data import quick_files
    >>> qf = quick_files("/path/to/some_files") ## has 410472 ttbar samples
    >>> pprint(qf["ttbar"])
    ['/path/to/some/files/ttbar_410472_FS_MC16a_nominal.root',
     '/path/to/some/files/ttbar_410472_FS_MC16d_nominal.root',
     '/path/to/some/files/ttbar_410472_FS_MC16e_nominal.root']
    >>> qf = quick_files("/path/to/some/files", campaign="MC16d")
    >>> pprint(qf["tW_DR"])
    ['/path/to/some/files/tW_DR_410648_FS_MC16d_nominal.root',
     '/path/to/some/files/tW_DR_410649_FS_MC16d_nominal.root']
    >>> qf = quick_files("/path/to/some/files", campaign="MC16a")
    >>> pprint(qf["Data"])
    ['/path/to/some/files/Data15_data15_Data_Data_nominal.root',
     '/path/to/some/files/Data16_data16_Data_Data_nominal.root']

    """
    if campaign is None:
        camp = ""
    else:
        if campaign not in ("MC16a", "MC16d", "MC16e"):
            raise ValueError(f"{campaign} but be either 'MC16a', 'MC16d', or 'MC16e'")
        camp = f"_{campaign}"

    path = str(PosixPath(datapath).resolve())
    files = os.listdir(path)

    patterns = {
        "tW_DR": f"tW_DR_41064(8|9)_FS_MC16(a|d|e)_{tree}.root$",
        "tW_DR_AFII": f"tW_DR_41064(8|9)_AFII_MC16(a|d|e)_{tree}.root$",
        "tW_DR_PS": f"tW_DR_41103(8|9)_AFII_MC16(a|d|e)_{tree}.root$",
        "tW_DR_inc": f"tW_DR_41064(6|7)_FS_MC16(a|d|e)_{tree}.root$",
        "tW_DR_inc_AFII": f"tW_DR_41064(6|7)_AFII_MC16(a|d|e)_{tree}.root$",
        "tW_DS": f"tW_DS_41065(6|7)_FS_MC16(a|d|e)_{tree}.root$",
        "tW_DS_inc": f"tW_DS_41065(4|5)_FS_MC16(a|d|e)_{tree}.root$",
        "ttbar": f"ttbar_410472_FS_MC16(a|d|e)_{tree}.root$",
        "ttbar_AFII": f"ttbar_410472_AFII_MC16(a|d|e)_{tree}.root$",
        "ttbar_PS": f"ttbar_410558_AFII_MC16(a|d|e)_{tree}.root$",
        "ttbar_PS713": f"ttbar_411234_AFII_MC16(a|d|e)_{tree}.root$",
        "ttbar_hdamp": f"ttbar_410482_AFII_MC16(a|d|e)_{tree}.root$",
        "ttbar_inc": f"ttbar_410470_FS_MC16(a|d|e)_{tree}.root$",
        "ttbar_inc_AFII": f"ttbar_410470_AFII_MC16(a|d|e)_{tree}.root$",
        "Diboson": f"Diboson_[0-9]{{6}}_FS_MC16(a|d|e)_{tree}.root$",
        "Zjets": f"Zjets_[0-9]{{6}}_FS_MC16(a|d|e)_{tree}.root$",
        "MCNP": f"MCNP_[0-9]{{6}}_FS_MC16(a|d|e)_{tree}.root$",
    }

    if campaign == "MC16a":
        patterns["Data"] = f"Data1(5|6)_data1(5|6)_Data_Data_{tree}.root$"
    elif campaign == "MC16d":
        patterns["Data"] = f"Data17_data17_Data_Data_{tree}.root$"
    elif campaign == "MC16e":
        patterns["Data"] = f"Data18_data18_Data_Data_{tree}.root$"
    else:
        patterns["Data"] = f"Data1(5|6|7|8)_data1(5|6|7|8)_Data_Data_{tree}.root$"

    patterns = {k: re.compile(v) for k, v in patterns.items()}
    file_lists = {}
    for k, p in patterns.items():
        file_lists[k] = [f"{path}/{entry}" for entry in sorted(filter(p.match, files))]

    if campaign is not None:
        for k, v in file_lists.items():
            if k == "Data":
                continue
            file_lists[k] = sorted(filter(lambda x: camp in PosixPath(x).name, v))

    return file_lists

def selection_as_numexpr(selection: str) -> str:
    """Get the numexpr selection string from an arbitrary selection.

    Parameters
    -----------
    selection : str
        Selection string in ROOT or numexpr

    Returns
    -------
    str
        Selection in numexpr format.

    Examples
    --------
    >>> selection = "reg1j1b == true && OS == true && mass_lep1jet1 < 155"
    >>> from tdub.data import selection_as_numexpr
    >>> selection_as_numexpr(selection)
    '(reg1j1b == True) & (OS == True) & (mass_lep1jet1 < 155)'

    """
    return formulate.from_auto(selection).to_numexpr()

def selection_as_root(selection: str) -> str:
    """Get the ROOT selection string from an arbitrary selection.

    Parameters
    -----------
    selection : str
        The selection string in ROOT or numexpr

    Returns
    -------
    str
        The same selection in ROOT format.

    Examples
    --------
    >>> selection = "(reg1j1b == True) & (OS == True) & (mass_lep1jet1 < 155)"
    >>> from tdub.data import selection_as_root
    >>> selection_as_root(selection)
    '(reg1j1b == true) && (OS == true) && (mass_lep1jet1 < 155)'

    """
    return formulate.from_auto(selection).to_root()

def selection_branches(selection: str) -> set[str]:
    """Construct the minimal set of branches required for a selection.

    Parameters
    -----------
    selection : str
        Selection string in ROOT or numexpr

    Returns
    -------
    set(str)
        Necessary branches/variables

    Examples
    --------
    >>> from tdub.data import minimal_selection_branches
    >>> selection = "(reg1j1b == True) & (OS == True) & (mass_lep1lep2 > 100)"
    >>> minimal_branches(selection)
    {'OS', 'mass_lep1lep2', 'reg1j1b'}
    >>> selection = "reg2j1b == true && OS == true && (mass_lep1jet1 < 155)"
    >>> minimal_branches(selection)
    {'OS', 'mass_lep1jet1', 'reg2j1b'}

    """
    return formulate.from_auto(selection).variables

def selection_for(region: str | Region, additional: str | None = None) -> str:
    """Get the selection for a given region.

    We have three regions with a default selection (`1j1b`, `2j1b`,
    and `2j2b`), these are the possible argument options (in str or
    Enum form). See the :py:mod:`tdub.config` module for the
    definitions of the selections (and how to modify them).

    Parameters
    ----------
    region : str or Region
        Region to get the selection for
    additional : str, optional
        Additional selection (in ROOT or numexpr form). This will
        connect the region specific selection using `and`.

    Returns
    -------
    str
        Selection string in numexpr format.

    Examples
    --------
    >>> from tdub.data import Region, selection_for
    >>> selection_for(Region.r2j1b)
    '(reg2j1b == True) & (OS == True)'
    >>> selection_for("reg1j1b")
    '(reg1j1b == True) & (OS == True)'
    >>> selection_for("2j2b")
    '(reg2j2b == True) & (OS == True)'
    >>> selection_for("2j2b", additional="minimaxmbl < 155")
    '((reg2j2b == True) & (OS == True)) & (minimaxmbl < 155)'
    >>> selection_for("2j1b", additional="mass_lep1jetb < 155 && mass_lep2jetb < 155")
    '((reg1j1b == True) & (OS == True)) & ((mass_lep1jetb < 155) & (mass_lep2jetb < 155))'

    """
    region = as_region(region)
    if region == Region.r1j1b:
        selection = "(reg1j1b == True) & (OS == True)"
    elif region == Region.r2j1b:
        selection = "(reg2j1b == True) & (OS == True)"
    elif region == Region.r2j2b:
        selection = "(reg2j2b == True) & (OS == True)"
    else:
        raise ValueError("Incompatible region used")

    if additional is not None:
        additional = selection_as_numexpr(additional)
        selection = f"({selection}) & ({additional})"

    return selection


from django.shortcuts import render
from django.views.generic.base import View
from django.http import HttpResponse
from elasticsearch import Elasticsearch
from datetime import datetime

from search.models import ArticleType

import json
import redis

redis_cli = redis.StrictRedis()
client = Elasticsearch(hosts=["127.0.0.1"])

# Create your views here.
class IndexView(View):
    def get(self, request):
        # 逆序排列热门搜索，取前5个
        hot_search = redis_cli.zrevrangebyscore("search_keywords_set", "+inf", "-inf", start=0, num=5)
        return render(request, "index.html", {"hot_search": hot_search})

class SearchView(View):
    def get(self, request):
        keyword = request.GET.get("q", "")
        page = self.__trans_page(request.GET.get("p", "1"))

        # redis关键词加1
        redis_cli.zincrby("search_keywords_set", keyword)

        hot_search = redis_cli.zrevrangebyscore("search_keywords_set", "+inf", "-inf", start=0, num=5)

        start_time = datetime.now()
        response = self.__get_search_response(keyword, page)
        end_time = datetime.now()
        last_seconds = (end_time - start_time).total_seconds()

        hit_list, total_nums = self.__parse_search_response(response)

        jobbole_count = redis_cli.get("jobbole_count")

        return render(request, "result.html",
                      {"hot_search": hot_search, "all_hits": hit_list, "total_nums": total_nums,
                       "last_seconds": last_seconds, "page_nums": self.__get_page_nums(total_nums), "keyword": keyword,
                       "jobbole_count": jobbole_count})

    @staticmethod
    def __get_search_response(keyword, page):
        response = client.search(
            index="jobbole",
            body={
                "query": {
                    "multi_match": {
                        "query": keyword,
                        "field": ["tags", "title", "content"]
                    }
                },
                "from": (page - 1) * 10,
                "size": 10,
                "highlight": {
                    "pre_tags": [''],
                    "post_tags": [''],
                    "fields": {
                        "title": {},
                        "content": {}
                    }
                }
            }
        )
        return response

    @staticmethod
    def __parse_search_response(response):
        hit_list = []
        for hit in response["hits"]["hits"]:
            hit_dict = {}
            if "title" in hit["highlight"]:
                hit_dict["title"] = "".join(hit["highlight"]["title"])
            else:
                hit_dict["title"] = hit["_source"]["title"]
            if "content" in hit["highlight"]:
                hit_dict["content"] = "".join(hit["highlight"]["content"])[:500]
            else:
                hit_dict["content"] = hit["_source"]["content"][:500]
            hit_dict["create_date"] = hit["_source"]["create_date"]
            hit_dict["url"] = hit["_source"]["url"]
            hit_dict["score"] = hit["_source"]
            hit_list.append(hit_dict)

        total_nums = response["hits"]["total"]
        return hit_list, total_nums

    @staticmethod
    def __get_page_nums(total_nums):
        if total_nums % 10 > 0:
            page_nums = int(total_nums / 10) + 1
        else:
            page_nums = int(total_nums / 10)
        return page_nums

    @staticmethod
    def __trans_page(page):
        try:
            page = int(page)
        except:
            page = 1
        return page

class SearchSuggestView(View):
    def get(self, request):
        key_words = request.GET.get("s", "")
        return_data = []
        if key_words:
            s = ArticleType.search()
            s = s.suggest("article_suggest", key_words, completion={
                "field": "suggest",
                "fuzzy": {
                    "fuzziness": 2
                },
                "size": 10
            })
            suggestions = s.execute_suggest()
            for match in suggestions.article_suggest[0].options:
                source = match._source
                return_data.append(source["title"])
        return HttpResponse(json.dumps(return_data), content_type="application/json")


import logging
import json
from datetime import datetime
import time
from resilient_circuits import ResilientComponent, function, handler, StatusMessage, FunctionResult, FunctionError
from fn_cisco_amp4ep.lib.amp_client import Ampclient
from fn_cisco_amp4ep.lib.helpers import validate_opts, validate_params
from fn_cisco_amp4ep.lib.amp_ratelimit import AmpRateLimit

RATE_LIMITER = AmpRateLimit()

class FunctionComponent(ResilientComponent):
    """Component that implements Resilient function 'fn_amp_get_groups' of package fn_cisco_amp4ep.
    The function can be used to query to get information on groups or individual group by group_guid.

    The Function takes the following parameter:
        amp_group_guid, amp_group_name, amp_limit

        An example of a set of query parameter might look like the following:
                amp_group_guid = None
                amp_group_name = None
                amp_limit      = None

    The function will execute a REST api get request against a Cisco AMP for endpoints server and returns a result in
    JSON format similar to the following.

    {
      "input_params": {"group_guid": null, "limit": null, "name": null},
      "response": {
        "version": "v1.2.0",
        "data": [
          {
            "source": null,
            "guid": "abcd1234-a123-b456-c769-abcdef123456",
            "name": "Audit",
            "links": {
              "group": "https://api.amp.cisco.com/v1/groups/abcd1234-a123-b456-c769-abcdef123456"
            },
            "description": "Test Audit Group 1"
          },
          {
            "source": null,
            "guid": "abcd1234-a123-b456-c769-abcdef123457",
            "name": "Domain Controller",
            "links": {
              "group": "https://api.amp.cisco.com/v1/groups/abcd1234-a123-b456-c769-abcdef123457"
            },
            "description": "Test Domain Controller Group 2"
          },
          {
            "source": null,
            "guid": "abcd1234-a123-b456-c769-abcdef123458",
            "name": "Protect",
            "links": {
              "group": "https://api.amp.cisco.com/v1/groups/abcd1234-a123-b456-c769-abcdef123458"
            },
            "description": "Test Protect Group 3"
          },
          ...
        ],
        "metadata": {
          "results": {
            "index": 0,
            "total": 5,
            "items_per_page": 500,
            "current_item_count": 5
          },
          "links": {
            "self": "https://api.amp.cisco.com/v1/groups"
          }
        }
      },
      "query_execution_time": "2018-10-08 12:49:38"
    }
    """
    def __init__(self, opts):
        """constructor provides access to the configuration options"""
        super(FunctionComponent, self).__init__(opts)
        self.options = opts.get("fn_cisco_amp4ep", {})
        validate_opts(self)

    @handler("reload")
    def _reload(self, event, opts):
        """Configuration options have changed, save new values"""
        self.options = opts.get("fn_cisco_amp4ep", {})
        validate_opts(self)

    @function("fn_amp_get_groups")
    def _fn_amp_get_groups_function(self, event, *args, **kwargs):
        """Function: Returns information on group or groups."""
        try:
            # Get the function parameters:
            amp_group_guid = kwargs.get("amp_group_guid")  # text
            amp_group_name = kwargs.get("amp_group_name")  # text
            amp_limit = kwargs.get("amp_limit")  # number

            log = logging.getLogger(__name__)
            log.info("amp_group_guid: %s", amp_group_guid)
            log.info("amp_group_name: %s", amp_group_name)
            log.info("amp_limit: %s", amp_limit)

            yield StatusMessage("Running Cisco AMP get groups query...")

            params = {"group_guid": amp_group_guid, "name": amp_group_name, "limit": amp_limit}

            validate_params(params)

            amp = Ampclient(self.options, RATE_LIMITER)

            rtn = amp.get_paginated_total(amp.get_groups, **params)
            query_execution_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            # Add in "query_execution_time" and "ip_address" to result to facilitate post-processing.
            results = {"response": rtn, "query_execution_time": query_execution_time, "input_params": params}
            param_name = None if params["name"] is None else params["name"].encode('utf-8')
            yield StatusMessage("Returning 'group' or 'groups' results for group guid '{}', group name '{}' and limit '{}'"
                                .format(params["group_guid"], param_name, params["limit"]))

            log.debug(json.dumps(results))
            # Produce a FunctionResult with the results
            yield FunctionResult(results)
        except Exception:
            log.exception("Exception in Resilient Function for Cisco AMP for endpoints.")
            yield FunctionError()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""测试用例"""

import io
import sys

import src.Person as sp
import src.MyClass as sclass
import Student as sd
import Teacher as t

class TestOOStep:

    def setup_class(self) -> None:
        self.klass = sclass.Klass(number=2)
        print("\n开始执行测试用例")

    @staticmethod
    def teardown_class() -> None:
        print("\n执行测试用例完毕")

    def test_should_person_have_id_name_and_age(self) -> None:
        person = sp.PersonClass(1, 'Tom', 21)
        assert person.name == 'Tom'
        assert person.age == 21

    def test_should_person_with_same_id_be_same_one(self) -> None:
        person1 = sp.PersonClass(1, 'Tom', 21)
        person2 = sp.PersonClass(1, 'Tom', 21)
        assert person1.id == person2.id and person1.name == person2.name and person1.age == person2.age

    def test_should_person_have_an_introduce_method_which_introduce_person_with_name_and_age(self) -> None:
        tom = sp.PersonClass(1, 'Tom', 21)
        intro = tom.introduce()
        assert "My name is Tom. I am 21 years old." == intro

    def test_should_class_have_a_number(self) -> None:
        assert self.klass.number == 2

    def test_should_class_get_display_name(self) -> None:
        assert self.klass.get_display_name() == "Class 2"

    def test_should_class_not_assign_a_student_as_leader_when_student_is_not_a_member(self) -> None:
        jerry = sd.StudentClass(1, "Jerry", 8, sclass.Klass(number=5))

        stdout = sys.stdout
        sys.stdout = io_obj = io.StringIO()
        self.klass.assign_leader(jerry)
        sys.stdout = stdout
        result = io_obj.getvalue()

        assert result == "It is not one of us.\n"

    def test_should_class_assign_a_member_student_as_leader(self) -> None:
        jerry = sd.StudentClass(1, "Jerry", 8, self.klass)
        self.klass.append_member(jerry)
        self.klass.assign_leader(jerry)
        assert self.klass.leader == jerry

    def test_should_student_have_name_age_and_class_number(self) -> None:
        tom = sd.StudentClass(1, "Tom", 21, self.klass)
        assert tom.name == "Tom"
        assert tom.age == 21
        assert tom.my_class == self.klass

    def test_should_student_introduce_with_class(self) -> None:
        tom = sd.StudentClass(1, "Tom", 21, self.klass)
        assert tom.introduce() == "My name is Tom. I am 21 years old. I am a Student. I am at Class 2."

    def test_should_student_introduce_itself_as_class_leader(self) -> None:
        tom = sd.StudentClass(1, "Tom", 21, self.klass)
        self.klass.append_member(tom)
        self.klass.assign_leader(tom)
        assert tom.introduce() == "My name is Tom. I am 21 years old. I am a Student. I am Leader of Class 2."

    def test_should_teacher_have_name_and_age_and_classes(self) -> None:
        class_list = [self.klass]
        tom = t.TeacherClass(1, "Tom", 21, class_list)
        assert tom.name == "Tom"
        assert tom.age == 21
        assert len(tom.classes) == 1
        assert tom.classes[0] == self.klass

    def test_should_teacher_introduce_itself_with_which_classes_it_teaches(self) -> None:
        class_list = [self.klass, sclass.Klass(number=3)]
        tom = t.TeacherClass(1, "Tom", 21, class_list)
        assert tom.introduce() == "My name is Tom. I am 21 years old. I am a Teacher. I teach Class 2, 3."

    def test_should_teacher_introduce_itself_with_no_class_teaching(self) -> None:
        tom = t.TeacherClass(1, "Tom", 21)
        assert tom.introduce() == "My name is Tom. I am 21 years old. I am a Teacher. I teach No Class."

    def test_should_teacher_isTeaching_return_true_when_the_student_is_in_any_classes_the_teacher_teaches(self) -> None:
        class_list = [self.klass, sclass.Klass(number=3)]
        tom = t.TeacherClass(1, "Tom", 21, class_list)
        jerry = sd.StudentClass(1, "Jerry", 8, self.klass)
        assert tom.is_teaching(jerry)

    def test_should_teacher_isTeaching_return_false_when_the_student_is_not_in_all_the_classes_the_teacher_teaches(self) -> None:
        class_list = [self.klass]
        tom = t.TeacherClass(1, "Tom", 21, class_list)
        jerry = sd.StudentClass(1, "Jerry", 8, sclass.Klass(number=3))
        assert not tom.is_teaching(jerry)

    def test_should_teacher_introduce_a_student_it_teaches(self) -> None:
        class_list = [self.klass]
        tom = t.TeacherClass(1, 'Tom', 21, class_list)
        jerry = sd.StudentClass(1, "Jerry", 8, self.klass)
        assert tom.introduce_with(jerry) == "My name is Tom. I am 21 years old. I am a Teacher. I teach Jerry."

    def test_should_teacher_introduce_a_student_it_does_not_teach(self) -> None:
        class_list = [sclass.Klass(number=1)]
        tom = t.TeacherClass(1, "Tom", 21, class_list)
        jerry = sd.StudentClass(1, "Jerry", 8, sclass.Klass(number=2))
        assert tom.introduce_with(jerry) == "My name is Tom. I am 21 years old. I am a Teacher. I don't teach Jerry."

    def test_should_teacher_be_notified_when_student_join_any_classes_it_teaches(self) -> None:
        class_list = [self.klass]
        tom = t.TeacherClass(1, "Tom", 21, class_list)
        jerry = sd.StudentClass(1, "Jerry", 8, sclass.Klass(number=3))

        stdout = sys.stdout
        sys.stdout = io_obj = io.StringIO()
        self.klass.append_member(jerry)
        sys.stdout = stdout
        result = io_obj.getvalue()

        assert result.endswith("I am Tom. I know Jerry has joined Class 2.\n")

    def test_should_teacher_be_notified_when_any_class_it_teaches_assigned_a_leader(self) -> None:
        class_list = [self.klass]
        tom = t.TeacherClass(1, "Tom", 21, class_list)
        jerry = sd.StudentClass(1, "Jerry", 8, sclass.Klass(number=3))

        stdout = sys.stdout
        sys.stdout = io_obj = io.StringIO()
        self.klass.append_member(jerry)
        self.klass.assign_leader(jerry)
        sys.stdout = stdout
        result = io_obj.getvalue()

        assert result.endswith("I am Tom. I know Jerry become Leader of Class 2.\n")


from setuptools import setup, find_packages

install_requires = [
    'numpy',
]

tests_require = [
    'pytest',
]

setup(name='dlutils',
      version='0.1',
      description='Deep Learning Utilities',
      author="Bruno Di Giorgi",
      author_email='bruno@brunodigiorgi.it',
      url='https://github.com/brunodigiorgi/dlutils',
      license="GPLv2",
      packages=find_packages(),
      package_data={'': ['*.html_template']},
      zip_safe=False,
      install_requires=install_requires,
      extras_require={
          'testing': tests_require,
      },
      )


import clr
clr.AddReference("RevitAPI")
from Autodesk.Revit import DB

from abc import ABCMeta
from exceptions import TypeValidationException

_app = __revit__.Application  # noqa

class RevitVersion(object):
    _rvt_version = _app.VersionNumber
    _as_integer = int(_rvt_version)

    @classmethod
    def as_integer(cls):
        return cls._as_integer

class AbstractUnitType(object):
    """
    Abstract unit types across Revit versions.
    The type of physical quantity to be measured, for example length or force.

    since 2014: `DB.UnitType`\n
    since 2021: `DB.SpecTypeId`
    """
    pass

class AbstractUnitOfMeasure(object):
    """
    Abstract units of measure across Revit versions.

    since 2014: `DB.DisplayUnitType`\n
    since 2021: `DB.UnitTypeId`
    """

class _CrossVersionRevitObject(object):
    """
    Base class for utils that help to bypass changes in methods
    across different versions of Revit API.
    """

    __metaclass__ = ABCMeta
    _rvt_ver_num = RevitVersion.as_integer()

    def _validate_type(self, obj, expected_type, err_msg=None):
        # type: (object, type, str) -> None
        if not isinstance(obj, expected_type):
            raise TypeValidationException(
                message=err_msg,
                expected_type=expected_type,
                provided_type=type(obj)
            )

class _Definition(_CrossVersionRevitObject):
    def __init__(self, definition):
        # type: (DB.Definition) -> None
        self._validate_type(definition, DB.Definition)
        self._definition = definition

    def get_unit_type(self):
        # type: () -> AbstractUnitType | DB.UnitType | DB.SpecTypeId
        if self._rvt_ver_num < 2021:
            return self._definition.UnitType

        if self._rvt_ver_num < 2022:
            return self._definition.GetSpecTypeId()

        return self._definition.GetDataType()

class _Parameter(_CrossVersionRevitObject):
    def __init__(self, parameter):
        # type: (DB.Parameter) -> None
        self._validate_type(parameter, DB.Parameter)
        self._parameter = parameter

    def get_units_of_measure(self):
        # type: () -> AbstractUnitOfMeasure
        if self._rvt_ver_num < 2021:
            return self._parameter.DisplayUnitType
        return self._parameter.GetUnitTypeId()

class _FormatOptions(_CrossVersionRevitObject):
    def __init__(self, format_opts):
        # type: (DB.FormatOptions) -> None
        self._validate_type(format_opts, DB.FormatOptions)
        self._format_opts = format_opts

    def get_units_of_measure(self):
        # type: (DB.FormatOptions) -> AbstractUnitOfMeasure
        if self._rvt_ver_num < 2021:
            return self._format_opts.DisplayUnits
        return self._format_opts.GetUnitTypeId()

class _UnitUtils(_CrossVersionRevitObject):
    def __init__(self):
        self._unit_utils = DB.UnitUtils

    def is_unit_of_measure(self, unit_of_measure):
        # type: (AbstractUnitOfMeasure) -> bool
        if self._rvt_ver_num < 2021:
            return self._unit_utils.IsValidDisplayUnit(unit_of_measure)
        return self._unit_utils.IsUnit(unit_of_measure)

    def is_valid_unit_of_measure(self, unit_type, unit_of_measure):
        # type: (AbstractUnitType, AbstractUnitOfMeasure) -> bool
        if self._rvt_ver_num < 2021:
            return self._unit_utils.IsValidDisplayUnit(
                unit_type,
                unit_of_measure
            )
        return self._unit_utils.IsValidUnit(unit_type, unit_of_measure)

def definition(definition):
    # type: (DB.Definition) -> _Definition
    return _Definition(definition)

def format_options(format_opts):
    # type: (DB.FormatOptions) -> _FormatOptions
    return _FormatOptions(format_opts)

def parameter(parameter):
    # type: (DB.Parameter) -> _Parameter
    return _Parameter(parameter)

unit_utils = _UnitUtils()


import typing as ty
from functools import reduce

def build_grid_from_list_map(list_map: ty.List[str]) -> ty.List[ty.List]:
    return [list(grid_row) for grid_row in list_map]

def encounters_multipled(encounters: ty.List):
    if len(encounters) == 1:
        return encounters[0]

    return reduce(lambda x, y: x * y, encounters)

def get_encountered_trees(
    tree_map: ty.List, move_x: int, move_y: int) -> int:
    encountered_trees = 0
    current_x = 0
    current_y = 0

    grid = build_grid_from_list_map(tree_map)
    grid_rows = len(grid) - 1
    grid_cols = len(grid[0]) - 1

    out_bound = False

    while True:
        if current_y + move_y > grid_rows:
            break

        current_y += move_y

        if current_x + move_x > grid_cols:
            current_x = (current_x + move_x - grid_cols) - 1
        else:
            current_x += move_x

        encounter = grid[current_y][current_x]

        if encounter == '#':
            encountered_trees += 1
            marker = 'X'
        else:
            marker = 'O'

        grid[current_y][current_x] = marker

    return encountered_trees

def move_by_patterns(tree_map: ty.List, movements: ty.List) -> int:
    encounters = list()
    for move in movements:
        encounters.append(
            get_encountered_trees(tree_map, *move)
        )
    return encounters_multipled(encounters)


import subprocess
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

def scan_ports(target: str) -> dict:
    # Placeholder using Nmap as an example; adjust as necessary
    command = ["nmap", "-sV", "-T4", target]
    try:
        result = subprocess.check_output(command, text=True)

        # Here we are simply returning the raw result. In reality, you'd parse this for port and service details.
        # The dictionary structure can be {port: service}. This can be further enhanced to capture more info.
        return {'raw_output': result}
    except subprocess.CalledProcessError as e:
        print(f"Error during port scan: {e}")
        return {}

class PortScanGUI(Gtk.Box):

    def __init__(self, subdomains: list):
        super().__init__(spacing=10)

        # Dropdown to select subdomain/IP
        self.subdomain_selector = Gtk.ComboBoxText()
        for subdomain in subdomains:
            self.subdomain_selector.append_text(subdomain)
        self.subdomain_selector.set_active(0)
        self.pack_start(self.subdomain_selector, True, True, 0)

        # Button
        self.button = Gtk.Button(label="Start Port Scan")
        self.button.connect("clicked", self.on_button_clicked)
        self.pack_start(self.button, True, True, 0)

        # Display
        self.text_view = Gtk.TextView()
        self.text_view.set_editable(False)
        self.pack_start(self.text_view, True, True, 0)

    def on_button_clicked(self, widget):
        target = self.subdomain_selector.get_active_text()
        if target:
            result = scan_ports(target)

            # Display raw output in the text view. You can further parse the result to show structured data.
            text_buffer = self.text_view.get_buffer()
            text_buffer.set_text(result.get('raw_output', ''))


import typing as t

from dataclasses import dataclass

G = t.TypeVar("G")
A = t.TypeVar("A")
P = t.TypeVar("P")

@dataclass
class Rules(t.Generic[G, A, P]):
    init_game: t.Callable[[], G]
    take_action_mut: t.Callable[[G, A], G]
    is_over: t.Callable[[G], t.Optional[P]]
    get_final_score: t.Callable[[G], t.Dict[str, float]]
    encode_action: t.Callable[[A], str]
    decode_action: t.Callable[[str], A]
    get_random_action: t.Callable[[G], t.Optional[A]]
    get_all_actions: t.Callable[[G], t.List[A]]
    get_players: t.Callable[[G], t.List[P]]

    format_gamestate: t.Callable[[G], str]

    encode_gamestate: t.Callable[[G], bytes]
    decode_gamestate: t.Callable[[bytes], G]

def load_rules(game_type: str):
    if game_type == "2048":
        import t2048.rules as rules
        import t2048.fmt as fmt
    elif game_type == "connect4":
        import connect4.rules as rules
        import connect4.fmt as fmt
    else:
        raise Exception(f"Unknown game type {game_type}")

    return Rules(
        init_game=rules.init_game,
        take_action_mut=rules.take_action_mut,
        is_over=rules.is_over,
        get_final_score=rules.get_final_score,
        encode_action=rules.encode_action,
        decode_action=rules.decode_action,
        get_random_action=rules.get_random_action,
        get_all_actions=rules.get_all_actions,
        get_players=rules.get_players,
        format_gamestate=fmt.format_gamestate,
        encode_gamestate=rules.encode_gamestate,
        decode_gamestate=rules.decode_gamestate,
    )


from Gauss_gen import *
from conv import *
import cv2

img = cv2.imread("Lena.jpg")
edge_size = 50
img_padding = np.zeros((img.shape[0] + 2 * edge_size, img.shape[1] + 2 * edge_size, 3))
# kernel = Gauss_gen(1.5)
# img_gauss = np.zeros((img.shape[0] - len(kernel) + 1, img.shape[1] - len(kernel) + 1, 3))
for i in range(3):
    img_padding[:, :, i] = padding(img[:, :, i], edge_size, "wrap_around")
#     img_gauss[:, :, i] = conv2d(img[:, :, i], kernel, 1)

cv2.imshow("ori", img)
cv2.imshow("zeor", img_padding.astype("uint8"))
# cv2.imshow("gauss", img_gauss.astype("uint8"))
cv2.waitKey(0)


import numpy as np
import pandas as pd
from scipy.special import comb
#from tslearn import metrics

# Given a mixture and a sorted list of genes, check if expression levels are in the same order.
# Provide a score for each gene.
def spearman_rank(set_1, set_2):
    # order the sets
    set_1_ord = sorted(set_1)
    set_2_ord = sorted(set_2)

    # append relevant rank to each value in set
    set_1_ranked = []
    set_2_ranked = []
    d = []

    for i in range(len(set_1)):
        set_1_ranked.append([set_1[i], set_1_ord.index(set_1[i]) + 1])
        set_2_ranked.append([set_2[i], set_2_ord.index(set_2[i]) + 1])
        d.append(set_1_ranked[i][1] - set_2_ranked[i][1])

    d_sq = [i**2 for i in d]
    # Indices of smallest elements.
    indices_small = np.argsort(d_sq)[0:round(0.9 * len(set_2))]
    sum_d_sq = sum(d_sq)
    # calculate n^3 - n
    n_cu_min_n = len(set_1)**3 - len(set_1)
    r = 1 - ((6.0 * sum_d_sq) / n_cu_min_n)  # Spearman rank.
    return indices_small, round(r, 2)

# Set_1 should be the pure expression values.
def kendall_rank(set_1, set_2):
    dist = np.zeros(len(set_1))
    for i in range(len(set_1)):
        for j in range(i, len(set_1)):
            if ((set_1[i] <= set_1[j]) and (set_2[i] > set_2[j])) or ((set_1[i] > set_1[j]) and (set_2[i] <= set_2[j])):
                dist[j] += 1
                dist[i] += 1
    indices_small = np.argsort(dist)[0:round(0.8 * len(set_2))]
    rank = dist.sum() / comb(len(set_1), 2, exact=True)
    return indices_small, round(rank, 2)

def dtw_rank(set_1, set_2):
    dist = np.zeros(len(set_1))
    for i in range(len(set_1)):
        set_1_temp = np.delete(set_1.values, i)
        set_2_temp = np.delete(set_2, i)
        P = np.array([set_1_temp, np.arange(0, len(set_1_temp))])
        Q = np.array([set_1_temp, np.arange(0, len(set_2_temp))])
        dist[i] = metrics.dtw(P, Q)
    indices_large = np.argsort(dist)[len(dist):-round(0.9 * len(dist)) - 1:-1]
    return indices_large, 0

# This function does a gene differentiation analysis. It finds for each cell types its majorodizing genes.
# We also get a factor of how much (strongly majordizing) each gene is.
def gene_diff(pure, mix):
    num_genes_per_cell = 80
    gene_list_per_cell = {}
    # Loop on all cells
    for cell_type in pure:
        gene_list = []
        data = pure.copy()
        for factor in range(100, 1, -1):  # 2
            data2 = data.copy()
            data2['max_val'] = data.drop(cell_type, axis=1).max(axis=1)
            data2['med_val'] = data.drop(cell_type, axis=1).median(axis=1)
            data2 = data2.loc[(data2[cell_type] > 0.5 * factor * data2.max_val) & (data2.max_val > 0)]  # Ignore cases where all other mixes are zeros.
            # data2 = data2.loc[(data2[cell_type] > 0.5 * factor * data2.max_val) & (data2.med_val > 0)]  # Ignore cases where all other mixes are zeros.
            if (len(data2) == 0):
                continue
            data2.sort_values(cell_type, inplace=True, ascending=False)
            #gene_list += list(zip(data2.index, [factor for i in range(len(data2.index))]))
            gene_list += list(data2.index)
            data.drop(data2.index, inplace=True)
            if (len(gene_list) > num_genes_per_cell):
                gene_list = gene_list[0:num_genes_per_cell]
                break

        # Select maximum correlated genes (max(mix columns) agrees with pure).
        #max_col = mix.loc[gene_list].sum().idxmax()
        #mix_column = mix[max_col].loc[gene_list]
        #indices_small, score = kendall_rank(pure[cell_type].loc[gene_list], mix_column.values)
        #gene_list = [gene_list[i] for i in indices_small]

        #print(f'{cell_type} : {gene_list}')
        if (len(gene_list) < 8):
            print(f'WARNING: {cell_type} short differential gene list, length {len(gene_list)}.')
        gene_list_per_cell[cell_type] = gene_list

    gene_list_df = pd.DataFrame(dict([(k, pd.Series([i for i in v])) for k, v in gene_list_per_cell.items()]), columns=pure.columns)
    #factor_list = pd.DataFrame(dict([(k, pd.Series([j * 0.5 for (i, j) in v])) for k, v in gene_list_per_cell.items()]), columns=pure.columns)

    #import IPython
    # IPython.embed()
    # for cell in cells:
    #  print(cell, ',', *[x for x in gene_list_df[cell].values.tolist() if str(x) != 'nan'])
    return gene_list_df


import transliterate

#Обрабатывает прежде полученые данные, и формирует из их выходной результат для передачи в AMS систему
class Dump_all:
    def __init__(self,agents,agents_numb,atribute,atribute_numb,verb,verb_numb,point,money,money_numb,data):
        self.agents = agents
        self.ag_numb = agents_numb
        self.atribute = atribute
        self.attr_numb = atribute_numb
        self.action = verb
        self.action_numb = verb_numb
        self.points = point
        self.money = money
        self.money_numb = money_numb
        self.data = data
    def dump_to_file(self):
        for i in self.ag_numb:
            tmp = '\n'+ transliterate.translit(
                str(self.agents[self.ag_numb.index(i)]).replace(
                    ' ', '_'),
                language_code='uk',
                reversed=True)+ ' - '

            for j in self.attr_numb:
                if (i<j):
                    tmp+= transliterate.translit(
                        str(self.atribute[self.attr_numb.index(j)]).replace(
                            ' ', '_'),
                        language_code='uk',
                        reversed=True) +', '
                self.atribute.pop(self.attr_numb.index(j))
                self.attr_numb.pop(self.attr_numb.index(j))
            with open('Dump.txt','a',encoding='utf-8') as f:
                f.write(str(tmp)+"\n")

        with open('Dump.txt', 'a', encoding='utf-8') as f:
            f.write(str(transliterate.translit(
                        str(self.action['faiding']).replace(
                            ' ', '_'),
                        language_code='uk',
                        reversed=True)+", "+transliterate.translit(
                        str(self.action['NonFaiding']).replace(
                            ' ', '_'),
                        language_code='uk',
                        reversed=True)+'\n' ))

        self.atribute.reverse()
        self.attr_numb.reverse()
        self.money.reverse()
        self.money_numb.reverse()
        tmp_string = ''

        tmp_string += transliterate.translit(
            str("судового збору").replace(
                 ' ', '_'),
             language_code='uk',
            reversed=True) +" = "+ transliterate.translit(
                            str(self.money[0]).replace(
                                ' ', '_'),
                            language_code='uk',
                            reversed=True) + "\n"
        self.money.pop(0)
        self.money_numb.pop(0)

        for i in self.money_numb:
            index_i = self.money_numb.index(i)
            for j in self.attr_numb:
                index_j = self.attr_numb.index(j)
                if j<i:
                    with open('Dump.txt', 'a', encoding='utf-8') as f:
                        f.write(str(transliterate.translit(
                            str(self.atribute[self.attr_numb.index(j)]).replace(
                                ' ', '_'),
                            language_code='uk',
                            reversed=True) +" = "+transliterate.translit(
                            str( self.money[self.money_numb.index(i)]).replace(
                                ' ', '_'),
                            language_code='uk',
                            reversed=True) +'\n'))
                self.atribute.pop(self.attr_numb.index(j))
                self.attr_numb.pop(self.attr_numb.index(j))
            self.money.pop(self.money_numb.index(i))
            self.money_numb.pop(self.money_numb.index(i))

        self.money.reverse()

        tmp_string +=   transliterate.translit(
                            str("штрафні санкції").replace(
                                ' ', '_'),
                            language_code='uk',
                            reversed=True)+" = "+transliterate.translit(
                            str(self.money[0]).replace(
                                ' ', '_'),
                            language_code='uk',
                            reversed=True) + "\n"
        tmp_string += transliterate.translit(
            str("штрафні санкції").replace(
                ' ', '_'),
            language_code='uk',
            reversed=True) +" = "+ transliterate.translit(
                            str(self.money[1]).replace(
                                ' ', '_'),
                            language_code='uk',
                            reversed=True) + "\n"
        #tmp_string += transliterate.translit(
          #  str("судового збору").replace(
           #     ' ', '_'),
           # language_code='uk',
            #reversed=True) + self.money[2] + "\n"

        with open('Dump.txt', 'a', encoding='utf-8') as f:
            f.write(str(tmp_string)+'\n'+transliterate.translit(
                            str(self.points).replace(
                                ' ', '_'),
                            language_code='uk',
                            reversed=True)+'\n'+transliterate.translit(
                            str(self.data).replace(
                                ' ', '_'),
                            language_code='uk',
                            reversed=True))


# coding: utf-8

from typing import Dict, List  # noqa: F401

from fastapi_cache import FastAPICache
from fastapi import (  # noqa: F401
    APIRouter,
    Body,
    Cookie,
    Depends,
    Form,
    Header,
    Path,
    Query,
    Response,
    Security,
    status,
)

from openapi_server.models.extra_models import TokenModel  # noqa: F401
from openapi_server.utils.vars import SAMPLEEXECUTION_TYPE_NAME, SAMPLEEXECUTION_TYPE_URI
from openapi_server.connector import query_manager
from fastapi_cache.decorator import cache

from openapi_server.models.sample_execution import SampleExecution
from openapi_server.security_api import get_token_BearerAuth

router = APIRouter()

@router.get(
    "/sampleexecutions",
    responses={
        200: {"model": List[SampleExecution], "description": "Successful response - returns an array with the instances of SampleExecution."},
    },
    tags=["SampleExecution"],
    summary="List all instances of SampleExecution",
    response_model_by_alias=True,
)
@cache(namespace="SampleExecution", expire=1800)
async def sampleexecutions_get(
    username: str = Query(None, description="Name of the user graph to query"),
    label: str = Query(None, description="Filter by label"),
    page: int = Query(1, description="Page number"),
    per_page: int = Query(100, description="Items per page", ge=1, le=200),
) -> List[SampleExecution]:
    """Gets a list of all instances of SampleExecution (more information in https://w3id.org/okn/o/sd#SampleExecution)"""

    return query_manager.get_resource(

        username=username,label=label,page=page,per_page=per_page,

        rdf_type_uri=SAMPLEEXECUTION_TYPE_URI,
        rdf_type_name=SAMPLEEXECUTION_TYPE_NAME,
        kls=SampleExecution
        )

@router.delete(
    "/sampleexecutions/{id}",
    responses={
        202: {"description": "Deleted"},
        404: {"description": "Not Found"},
    },
    tags=["SampleExecution"],
    summary="Delete an existing SampleExecution",
    response_model_by_alias=True,
)
async def sampleexecutions_id_delete(
    id: str = Path(None, description="The ID of the SampleExecution to be retrieved"),
    user: str = Query(None, description="Username"),
    token_BearerAuth: TokenModel = Security(
        get_token_BearerAuth
    ),
) -> None:
    """Delete an existing SampleExecution (more information in https://w3id.org/okn/o/sd#SampleExecution)"""

    await FastAPICache.clear(namespace="SampleExecution")
    return query_manager.delete_resource(
        id=id,
        user=user,

        rdf_type_uri=SAMPLEEXECUTION_TYPE_URI,
        rdf_type_name=SAMPLEEXECUTION_TYPE_NAME,
        kls=SampleExecution
        )

@router.get(
    "/sampleexecutions/{id}",
    responses={
        200: {"model": SampleExecution, "description": "Gets the details of a given SampleExecution"},
    },
    tags=["SampleExecution"],
    summary="Get a single SampleExecution by its id",
    response_model_by_alias=True,
)
@cache(namespace="SampleExecution", expire=1800)
async def sampleexecutions_id_get(
    id: str = Path(None, description="The ID of the SampleExecution to be retrieved"),
    username: str = Query(None, description="Name of the user graph to query"),
) -> SampleExecution:
    """Gets the details of a given SampleExecution (more information in https://w3id.org/okn/o/sd#SampleExecution)"""

    return query_manager.get_resource(
        id=id,
        username=username,

        rdf_type_uri=SAMPLEEXECUTION_TYPE_URI,
        rdf_type_name=SAMPLEEXECUTION_TYPE_NAME,
        kls=SampleExecution
        )

@router.put(
    "/sampleexecutions/{id}",
    responses={
        200: {"model": SampleExecution, "description": "Updated"},
        404: {"description": "Not Found"},
    },
    tags=["SampleExecution"],
    summary="Update an existing SampleExecution",
    response_model_by_alias=True,
)
async def sampleexecutions_id_put(
    id: str = Path(None, description="The ID of the SampleExecution to be retrieved"),
    user: str = Query(None, description="Username"),
    sample_execution: SampleExecution = Body(None, description="An old SampleExecutionto be updated"),
    token_BearerAuth: TokenModel = Security(
        get_token_BearerAuth
    ),
) -> SampleExecution:
    """Updates an existing SampleExecution (more information in https://w3id.org/okn/o/sd#SampleExecution)"""

    await FastAPICache.clear(namespace="SampleExecution")
    return query_manager.put_resource(
        id=id,
        user=user,
        body=sample_execution,
        rdf_type_uri=SAMPLEEXECUTION_TYPE_URI,
        rdf_type_name=SAMPLEEXECUTION_TYPE_NAME,
        kls=SampleExecution
        )

@router.post(
    "/sampleexecutions",
    responses={
        201: {"model": SampleExecution, "description": "Created"},
    },
    tags=["SampleExecution"],
    summary="Create one SampleExecution",
    response_model_by_alias=True,
)
async def sampleexecutions_post(
    user: str = Query(None, description="Username"),
    sample_execution: SampleExecution = Body(None, description="Information about the SampleExecutionto be created"),
    token_BearerAuth: TokenModel = Security(
        get_token_BearerAuth
    ),
) -> SampleExecution:
    """Create a new instance of SampleExecution (more information in https://w3id.org/okn/o/sd#SampleExecution)"""

    await FastAPICache.clear(namespace="SampleExecution")
    return query_manager.post_resource(

        user=user,
        body=sample_execution,
        rdf_type_uri=SAMPLEEXECUTION_TYPE_URI,
        rdf_type_name=SAMPLEEXECUTION_TYPE_NAME,
        kls=SampleExecution
        )


import numpy as np
from sklearn.metrics import average_precision_score, roc_auc_score
import matplotlib
from matplotlib import pyplot as plt
import os

def plotAUROC(snames, labels: np.array, preds: np.array, med_ex: np.array, binary=False):
    fig, axs = plt.subplots(len(snames), 1)
    for i, name in enumerate(snames):
        num_genes = 1000
        if not binary:
            A = (labels[name] > med_ex[name]).astype(int).reshape(-1, num_genes)
            P = (preds[name] > med_ex[name]).astype(int).reshape(-1, num_genes)
        else:
            A = labels[name].astype(float).reshape(-1, num_genes)
            P = preds[name].astype(float).reshape(-1, num_genes)
        roc_auc_scores = np.zeros(num_genes)
        count = 0
        difference = 0
        for gene in range(num_genes):
            if (np.any(A[:, gene] == 0) and np.any(A[:, gene] == 1)):
                # Has both classes
                difference += abs(np.mean(A[:, gene] - P[:, gene]))
                roc_auc_scores[gene] = roc_auc_score(A[:, gene], P[:, gene])
                count += 1
            else:
                # Put -1 if ROC curve is not defined
                roc_auc_scores[gene] = -1
        axs[i].hist(roc_auc_scores[roc_auc_scores >= 0], bins=20)
        print(f"Median AUROC - {np.median(roc_auc_scores[roc_auc_scores >= 0])}")

def plotAP(snames, labels: np.array, preds: np.array, med_ex: np.array, binary=False):
    fig, axs = plt.subplots(len(snames), 1)
    for i, name in enumerate(snames):
        num_genes = 1000
        if not binary:
            A = (labels[name] > med_ex[name]).astype(int).reshape(-1, num_genes)
            P = (preds[name] > med_ex[name]).astype(int).reshape(-1, num_genes)
        else:
            A = labels[name].astype(float).reshape(-1, num_genes)
            P = preds[name].astype(float).reshape(-1, num_genes)

        ap_scores = np.zeros(num_genes)
        for gene in range(num_genes):
            if (np.any(A[:, gene] == 0) and np.any(A[:, gene] == 1)):
                ap_scores[gene] = average_precision_score(A[:, gene], P[:, gene])
            else:
                ap_scores[gene] = -1
        axs[i].hist(ap_scores[ap_scores >= 0], bins=20)
        print(f"Median AP - {np.median(ap_scores[ap_scores >= 0])}")

def plotHeatmaps(image, index, labels: np.array, xys: np.array, binary=False):
    cmap = matplotlib.cm.get_cmap('viridis')
    if binary:
        intensities = labels[:, index]
    else:
        intensities = 1 / (1 + np.exp(-labels[:, index]));
    colors = cmap(intensities, alpha=0.5);
    heatmap = draw_heatmap(np.copy(image), 5, xys, colors, 100);
    return heatmap

def draw_heatmap(image: np.ndarray, downsample: int, xys: np.ndarray, colors: np.array, size: int):
    # Generate "true" photo
    new_image: np.ndarray = image[::downsample, ::downsample, :].copy()
    size = size // downsample
    for i, (xy, color) in enumerate(zip(xys, colors)):
        x, y = xy
        # Center around gene locations
        x = int(x) // downsample - size // 2
        y = int(y) // downsample - size // 2

        if len(color) == 3:
            alpha = 0.50
        else:
            alpha = color[3]
        new_image[y:y + size, x:x + size] = np.uint8((1 - alpha) * new_image[y:y + size, x:x + size].astype(np.float32) + 255 * alpha * color[:3])
    return new_image


import psycopg2

def delete_table(cursor):
    cursor.execute("""
        DROP TABLE email;
        DROP TABLE phone;
        DROP TABLE name;
    """)

def create_db(cursor):
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS name(
        name_id SERIAL PRIMARY KEY,
        first_name VARCHAR(40) NOT NULL,
        last_name VARCHAR(40) NOT NULL
    );
    """)
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS email(
        id SERIAL PRIMARY KEY,
        address VARCHAR(320) NOT NULL,
        name_id INTEGER NOT NULL REFERENCES name(name_id)
    );
    """)
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS phone(
        id SERIAL PRIMARY KEY,
        number INTEGER NOT NULL,
        name_id INTEGER NOT NULL REFERENCES name(name_id)
    );
    """)

def add_new_client(cursor, f_name, l_name, e_address, ph_number=None):
    cursor.execute("""
        INSERT INTO name(first_name, last_name) VALUES(%s, %s) RETURNING name_id;
    """, (f_name, l_name))
    id_new_client = cur.fetchone()

    cursor.execute("""
        SELECT * FROM name;
    """)
    print(cursor.fetchall())

    cursor.execute("""
        INSERT INTO email(address, name_id) VALUES(%s, %s);
    """, (e_address, id_new_client))

    cursor.execute("""
        SELECT * FROM email;
    """)
    print(cursor.fetchall())

    if ph_number != None:
        cursor.execute("""
            INSERT INTO phone(number, name_id) VALUES(%s, %s);
        """, (ph_number, id_new_client))

    cursor.execute("""
        SELECT * FROM phone;
    """)
    print(cursor.fetchall())

def add_phone(cursor, ph_number, cl_id):
    cursor.execute("""
        INSERT INTO phone(number, name_id) VALUES(%s, %s);
    """, (ph_number, cl_id))

    cursor.execute("""
        SELECT * FROM phone;
    """)
    print(cursor.fetchall())

def change_data(cursor, cl_id, f_name=None, l_name=None, e_address=None, ph_number=None):
    if f_name != None:
        cursor.execute("""
            UPDATE name SET first_name=%s WHERE name_id=%s;
        """, (f_name, cl_id))

    if l_name != None:
        cursor.execute("""
            UPDATE name SET last_name=%s WHERE name_id=%s;
        """, (l_name, cl_id))

    cursor.execute("""
        SELECT * FROM name;
    """)
    print(cursor.fetchall())

    if e_address != None:
        cursor.execute("""
            UPDATE email SET address=%s WHERE name_id=%s;
        """, (e_address, cl_id))

    cursor.execute("""
        SELECT * FROM email;
    """)
    print(cursor.fetchall())

    if ph_number != None:
        cursor.execute("""
            UPDATE phone SET number=%s WHERE name_id=%s;
        """, (ph_number, cl_id))

    cursor.execute("""
        SELECT * FROM phone;
    """)
    print(cursor.fetchall())

def delete_phone(cursor, ph_number, cl_id):
    cursor.execute("""
        DELETE FROM phone WHERE number=%s AND name_id=%s;
    """, (ph_number, cl_id,))

    cursor.execute("""
        SELECT * FROM phone;
    """)
    print(cursor.fetchall())

def delete_client(cursor, cl_id):
    cursor.execute("""
        DELETE FROM email WHERE name_id=%s;
    """, (cl_id,))

    cursor.execute("""
        SELECT * FROM email;
    """)
    print(cursor.fetchall())

    cursor.execute("""
        DELETE FROM phone WHERE name_id=%s;
    """, (cl_id,))

    cursor.execute("""
        SELECT * FROM phone;
    """)
    print(cursor.fetchall())

    cursor.execute("""
        DELETE FROM name WHERE name_id=%s;
    """, (cl_id,))

    cursor.execute("""
        SELECT * FROM name;
    """)
    print(cursor.fetchall())

def find_client(cursor, f_name=None, l_name=None, e_address=None, ph_number=None):
    cursor.execute("""
        SELECT n.name_id, n.first_name, n.last_name, e.address, p.number FROM email e
        join name n ON e.name_id=n.name_id
        join phone p ON n.name_id=p.name_id
        WHERE first_name=%s OR last_name=%s OR address=%s OR number=%s;
    """, (f_name, l_name, e_address, ph_number))
    print(cur.fetchall())

with psycopg2.connect(database="client", user="postgres", password="****") as conn:
    with conn.cursor() as cur:
        delete_table(cur)

        create_db(cur)

        add_new_client(cur, 'Иван', 'Иванов', 'ivanov@mail.ru', 11111)

        add_new_client(cur, 'Петр', 'Петров', 'petrov@mail.ru', 22222)

        add_phone(cur, 33333, 2)

        change_data(cur, 2, f_name='Семен', l_name='Семенов')

        delete_phone(cur, 11111, 1)

        delete_client(cur, 1)

        find_client(cur, ph_number=22222)

conn.close()


"""
This module handles:
- Getting individual loan
- Deleting and Updating Loan
- By Extension, Updating parent Loan

"""
from fastapi import APIRouter, Depends, HTTPException, status
from ..utils import get_db
from models.loan import Loan
from models.loan_profile import LoanProfile
from models.loan_out import LoanOut
from sqlalchemy.orm import Session
from schemas.loan import LoanOutUpdate

router = APIRouter(tags=['LoanOut'], prefix='/loan_out')

@router.get('/')
def get_loans(storage: Session = Depends(get_db)) -> list[dict | None]:
    """Return all [individual] loan instances as a list of dictionary from the database"""
    loans: list = []
    all_loans: dict = storage.all(LoanOut)
    if not all_loans:
        return loans
    loan = [all_loans[key].to_dict() for key in all_loans.keys()]
    return loan

@router.get('/{id}')
def get_loan(id: str, storage: Session = Depends(get_db)) -> dict:
    """Return a single loan instances as a dictionary from the database"""
    loan: dict = storage.get(LoanOut, id)
    if loan is None:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="Loan instance not found")
    loan = loan.to_dict()
    return loan

@router.delete('/{id}', status_code=status.HTTP_204_NO_CONTENT)
def delete_loan(id: str, loan_id: dict, storage: Session = Depends(get_db)) -> None:
    """Delete a loan instance and update the aggregate (parent) loan"""
    loan_id = loan_id.get('loan_id')
    loan = storage.get(Loan, loan_id)
    loan_out = storage.get(LoanOut, id)
    if loan is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail="Aggregate Loan instance not found")
    if loan_out is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail="Loan instance not found")

    loan_dict: dict = loan.to_dict()
    loanout_dict: dict = loan_out.to_dict()

    if loan_id != loanout_dict['loan_id']:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail="Couldn't link loan instance to aggregate loan")
    total_amount = loan_dict['total_amount'] - loanout_dict['amount']
    loan_dict['total_amount'] = total_amount
    loan_out.delete()

    # if parent instance of loan less or equals - we delete the loan
    # because it implies that the aggregate loan doesn't have a child
    # instance else we update
    if loan_dict['total_amount'] <= 0:
        loan.delete()
    else:
        loan.update(loan_dict)

@router.put('/{id}', status_code=status.HTTP_204_NO_CONTENT)
def update_loanout(id: str, data: dict, storage: Session = Depends(get_db)):
    """Update a loan instance"""
    if len(data) < 1:
        raise HTTPException(
            status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
            detail='request data is empty'
        )

    # data = data.model_dump()

    loanout_data: dict = data['loanout_data']
    loan_out = storage.get(LoanOut, id)

    if loan_out is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail="Loan instance not found")
    loanout_dict: dict = loan_out.to_dict()

    # I only want to update the Parent Loan if it is "amount" that's
    # been updated
    if 'amount' in loanout_data:
        parent_ids: dict = data['parent_ids']
        loan_id = parent_ids.get('loan_id')
        loan_profile_id = parent_ids.get('loan_profile_id')
        loan = storage.get(Loan, loan_id)

        if loan is None:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                                detail="Aggregate Loan instance not found")
        loan_dict: dict = loan.to_dict()

    if 'amount' in loanout_data:
        if loan_id != loanout_dict['loan_id']:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                                detail="Couldn't link loan instance to aggregate loan")
        total_amount = loan_dict['total_amount'] - loanout_dict['amount']
        total_amount += loanout_data['amount']
        loan_dict['total_amount'] = total_amount
        loan.update(loan_dict)

        # Get exiting loan_profile and update it
        loan_profile = storage.get(LoanProfile, loan_profile_id)
        if loan_profile is None:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                                detail="Loan Profile instance not found")

        if loan_dict['is_member']:  # Interest rate on loans
            RATE = 0.05
        else:
            RATE = 0.1

        loan_profile_data = {}
        loan_profile_data['principal'] = loan_dict['total_amount']
        loan_profile_data['interest'] = loan_dict['total_amount'] * RATE
        loan_profile_data['total'] = loan_dict['total_amount'] + \
            loan_profile_data['interest']

        print(loan_profile.to_dict()['loan_id'])
        print(loan_dict['id'])
        if loan_profile.to_dict()['loan_id'] != loan_dict['id']:
            raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                                detail="Cannot attach <Loan Profile Instance> to <Loan Instance>")

        loan_profile.update(loan_profile_data)
        loan_profile.save()

    loan_out.update(loanout_data)

    return {}


# Definirea clasei DataManager care va inregistra zborurile intr-un fisier Google Sheets

import requests

SHEETY_PRICES_ENDPOINT = "****************"

class DataManager:

    def __init__(self):
        self.destination_data = {}

# Functia citeste din fisierul Google Sheets datele zborurilor inregistrate

    def get_destination_data(self):
        response = requests.get(url=SHEETY_PRICES_ENDPOINT)
        data = response.json()
        self.destination_data = data["prices"]
        return self.destination_data

# Baza de date este updatata cu noile coduri iata

    def update_destination_codes(self):
        for city in self.destination_data:
            new_data = {
                "price": {
                    "iataCode": city["iataCode"]
                }
            }
            response = requests.put(
                url=f"{SHEETY_PRICES_ENDPOINT}/{city['id']}",
                json=new_data
            )