from django.utils.translation import gettext_lazy as _

missing_parameter = _('Parameter missing')

login_success = _('Logged in successfully')

login_failed = _('Incorrect username or password')

incorrect_phone_number = _('Incorrect phone number')

parameter_error = _('Parameter error')

email_exists = _('Email already registered')

username_exists = _('username already registered')

registration_success = _('Registration successful')

incorrect_uid = _('Incorrect user id')

user_not_authenticated = _('User not authenticated')

success_message = _('Successful')

inhalation_saved_message = _('Inhalation saved')

profile_pic_update = _('Profile picture updated')

device_registered = _('Device registered')

device_saved = _('Device saved')

alarm_saved = _('Alarm saved')

no_device_registered = _('No device registered to user')

device_registered_other_user = _('Device already registered to other user')

BLOOD_GROUP_CHOICES = [
    (0, 'A+'),
    (1, 'A-'),
    (2, 'B+'),
    (3, 'B-'),
    (4, 'AB+'),
    (5, 'AB-'),
    (6, 'O+'),
    (7, 'O-'),
    (8, 'Hh'),
]

MEDICINE_TYPE_CHOICES = [
    (0, 'Maintanence Dose'),
    (1, 'Rescue Dose'),
]

STATUS_CHOICES = [
    (0, 'Inactive'),
    (1, 'Active'),
]

BOOLEAN_CHOICES = [
    (0, 'False'),
    (1, 'True'),
]

ALARM_TYPE_CHOICES = [
    ('A', 'Only Buzzer'),
    ('B', 'Only Vibrator'),
    ('C', 'Both Buzzer and Vibrator'),
    ('D', 'No Buzzer No Vibrator'),
]

GENDER_CHOICES = [
    (0, 'Male'),
    (1, 'Female'),
    (2, 'Others'),
]

TIMINGS_TYPE_CHOICES = [
    (0, 'Standard timing'),
    (1, 'Railway timing'),
]

WEATHER_API_URL = 'https://api.weatherapi.com/v1/forecast.json'

ROLES = [
    (3, 'Caretaker'),
    (1, 'Doctor'),
    (2, 'Patient'),
]

USER_CONNECTION_TYPE_CHOICES = [
    (0, 'Doctor'),
    (1, 'Caretaker'),
]

USER_CONNECTION_STATUS_CHOICES = [
    (0, _('Pending')),
    (1, _('Accepted')),
    (2, _('Rejected')),
]

VIEW_STATUS_CHOICES = [
    (0, 'Not Viewed'),
    (1, 'Viewed'),
    (2, 'Deleted'),
]
NOTIFICATION_TYPE_CHOICES = [
    (0, 'Doctor add request'),
    (1, 'Caretaker add request'),
]


from sklearn.datasets import make_blobs
import pandas as pd
import random as rd
import numpy as np
import matplotlib.pyplot as plt

class Kmeans:
    def __init__(self,n_clusters ):
        self.n_clusters = n_clusters
        self.centers = []
        self.clusters = {}
        self.distortion = []

    def initialize_centers(self, n_clusters:int, data:list ):
        centers = []
        indices = []
        while len(centers)< n_clusters:
            rand_point = rd.randint(0, len(data)-1)
            if rand_point not in indices:
                indices.append(rand_point)
                center = data[rand_point]
                centers.append(center)

        return centers

    def calc_distance(self, center, point):
        dis = np.subtract(center, point)
        dis = dis**2
        dis = np.sum(dis)
        return dis

    def make_clusters(self, centers, data):
        clusters = {}
        clusters_distances_sum = 0
        for j in range(self.n_clusters):
            clusters[j] = []

        for idx, point in enumerate(data):
            distances = []
            for  center in centers:
                dis = self.calc_distance(center , point)
                distances.append(dis)
            c = np.argmin(distances)
            clusters[c].append(idx)
            clusters_distances_sum+= distances[c]
        return clusters , clusters_distances_sum

    def update_centers(self, clusters, data):
        new_centers = []
        for _, samples in clusters.items():
            new_center = np.sum([x for i, x in enumerate(data) if i in samples], axis=0) / len(samples)
            new_centers.append(new_center)
        return new_centers

    def fit(self , n_clusters,data) :
        centers = self.initialize_centers(n_clusters, data)
        clusters, distances = self.make_clusters(centers , data )
        self.distortion.append(distances)
        while True :

            new_centers  = self.update_centers(clusters ,data )
            new_clusters,distances = self.make_clusters(new_centers , data)
            if distances >= self.distortion[-1]:
                print(distances )
                break
            centers = new_centers
            clusters = new_clusters
            self.distortion.append(distances)
        self.centers = centers

    def predict(self,point):
        distances = []
        for center in self.centers :
            dis = self.calc_distance(center , point)
            distances.append(dis)
        return np.argmin(distances)

dataset, _ = make_blobs(n_samples=200 , n_features=3 , centers=3 , cluster_std=0.5 , random_state=42)

# pd.DataFrame(dataset).to_csv('./dataset.csv')
# plt.xlabel('Iterations',fontsize = 12, color= 'b', fontweight = 'bold' )
# plt.ylabel('Distortion Values',fontsize = 12, color= 'b', fontweight = 'bold' )
# plt.title('The Distortion Function of Clusters',fontsize = 16, color= 'r', fontweight = 'bold')
# colors = ['r','g','b','y']
# for i in range(4):
#     model = Kmeans(3)
#     model.fit(3, dataset)
#     plt.plot(np.array(model.distortion)/1000, marker = 'x', color = colors[i], linewidth = 3.0, markersize = 10, markeredgewidth =4)
# plt.savefig('./results.png')
# plt.show()


from typing import List, Tuple, Dict, Set, Iterable
from random import choice, choices, randint, random, Random
from math import exp, log
from string import ascii_lowercase
from itertools import chain
from more_itertools import bucket

def _scoreit(state: Dict[Tuple[str, ...], str],
             horizontal: List[int]) -> float:

    degree = 2 * len(horizontal) - 1
    keys = [tuple((word[_] for _ in range(0, degree, 2)))
        for word in horizontal]
    addend = len(horizontal) - len(set(horizontal))
    return sum((_ not in state for _ in keys)) + addend

def _word_buckets(wordlist: List[str]) -> Dict[Tuple[str, ...], str]:

    degree = len(wordlist[0])

    buckets = bucket(wordlist,
                     lambda _: (_[idx] for idx in range(0, degree, 2)))

    # buckets has value of an iterable, make it a list
    return {key: list(buckets[key]) for key in buckets}

def metropolis(wordlist: List[str],
               temperature: float,
               distribute: bool = False,
               trace: int = 0,
               burnin: int = 1000) -> List[str]:
    """
    Use the Metropolis algorithm to sample.
    """
    degree = len(wordlist[0])
    print(f"degree = {degree}")
    rows = (degree + 1) // 2
    state = _word_buckets(wordlist)
    # Initial population
    horizontal = choices(wordlist, k=rows)
    addend = len(horizontal) - len(set(horizontal))
    keys = [tuple((word[_] for _ in range(0, degree, 2)))
        for word in horizontal]
    score = sum((_ not in state for _ in keys)) + addend

    tries = 0
    taken = 0
    while True:
        tries += 1
        if trace > 0 and tries % trace == 0:
            print(f"Step {tries}, taken = {taken}, score = {score}")
        if tries > burnin and score == 0:
            vertical = [choice(state[_]) for _ in keys]
            print(f"Final tries = {tries}")
            return vertical + horizontal
        # modify horizontal
        new_horizontal = horizontal.copy()
        new_horizontal[randint(0, rows - 1)] = choice(wordlist)
        new_keys = [tuple((word[_] for _ in range(0, degree, 2)))
            for word in new_horizontal]
        new_addend = len(new_horizontal) - len(set(new_horizontal))
        new_score = sum((_ not in state for _ in new_keys)) + new_addend
        delta_score = new_score - score
        if (delta_score <= 0
            or exp(-delta_score/temperature) >= random()):
            # Accept this move
            score = new_score
            horizontal = new_horizontal
            taken += 1

def waffle_sample(wordlist: List[str]) -> List[str]:
    """
    Use rejection sampling and conditional probability
    to uniformly sample all valid word placements
    """

    # Now rejection sampling
    # Unfortunately random.choices uses replacement
    # we reject duplicates

    # Find horizontal
    degree = len(wordlist[0])
    rows = (degree + 1) // 2
    state = _word_buckets(wordlist)
    # Now choose columns
    tries = 0
    while True:
        tries += 1
        while True:
            horizontal = choices(wordlist, k=rows)
            if len(set(horizontal)) == rows:
                break
        keys = [tuple((word[idx] for idx in range(0, degree, 2)))
                for word in horizontal]
        if all((_ in state for _ in keys)):
            vertical = [state[_] for _ in keys]
            # We have a winner!
            print(f"Succeeded in {tries} tries.")
            return horizontal + [choice(_) for _ in vertical]


from typing import Dict, Optional
from fastapi import FastAPI,Path,UploadFile,File
from pydantic import BaseModel
import json, graph, fire,os
from fastapi.middleware.cors import CORSMiddleware

description = """
## REST API для нахождения оптимального пути и нахождения пожара 🚀

Описание функционала
"""

class Items(BaseModel):
    title: str=Path(title="Название базы данных",default="Name")
    items: list =Path(default=[])

    def __str__(self) -> str:
        return json.dumps({
            "title":self.title,
            "items":self.items
        },indent=4)

app = FastAPI(
    title="REST API ФАТХИ",
    description=description,
    version="0.0.5",
    contact={
        "name": "Дмитрий Владимирович Фатхи",
        "url": "https://ff.xox.su"
    },

    docs_url="/api/rest",
    openapi_url="/api/openapi.json"
)

origins = ["*"]
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
try:
    with open("data.json") as f:
        item_data = json.loads(f.read())
except:
    item_data  ={}

@app.post("/api/upload/")
async def upload_file(uploaded_file: Optional[UploadFile] = File(default="",title="Картинка с пожаром")):
    file_location = f"files/{uploaded_file.filename}"
    with open(file_location, "wb+") as file_object:
        file_object.write(uploaded_file.file.read())

    ff = fire.Fire(file_location)
    ff.add([18, 50, 50],[35, 255, 255] )
    result = []
    for i in ff.find():
        result.append(i)
    try:
        os.remove(file_location)
    except:
        pass
    return {"result": result}

@app.post("/api/math_graph")
def math_graph(_from:str, _to:str, _block:list):
    global item_data
    nodes = []
    init_graph = {}
    for i in item_data["items"]:

        if i["from"] not in nodes and i["from"] not in _block:
            nodes.append(i["from"])
        if i["to"] not in nodes and i["to"] not in _block:
            nodes.append(i["to"])
    for node in nodes:
        init_graph[node] = {}
    for i in item_data["items"]:
        if i["from"] not in nodes or i["to"] not in nodes:
            continue
        init_graph[i["from"]][i["to"]] = i["value"]
    _graph = graph.Graph(nodes, init_graph)
    previous_nodes, shortest_path = graph.dijkstra_algorithm(graph=_graph, start_node=_from)
    result = graph.print_result(previous_nodes, shortest_path, start_node=_from, target_node=_to)
    return {
        "result":result
    }

@app.post("/api/update")
def update_data(items:Items):
    global item_data
    item_data =json.loads(str(items))
    with open("data.json","w") as f:
        f.write(str(items))
    return {
        "state":1
    }

@app.post("/api/get",response_model=Items)
def get_data():
    return item_data


# Start to the pygame file/window

import sys
import pygame
from settings import Settings
from alien import Alien

class AlienInvasion:
    """Overall class to manage game assets and behavior"""

    def __init__(self):
        """Initialize the game, and create game resources."""
        # (1)
        pygame.init()
        self.settings = Settings()

        # (2)
        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height
        pygame.display.set_caption("Raindrops")

        self.aliens = pygame.sprite.Group()
        self._create_aliens()

    def run_game(self):
        """Start the main loop for the game."""
        # (3)
        while True:
            # Watch the keyboard and mouse events.
            # (4)
            self._check_events()

            self._update_aliens()
            self._update_screen()

    def _check_events(self):
        """Respond to key presses and mouse events."""
        for event in pygame.event.get():
            # (5)
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)

    def _check_keydown_events(self, event):
        """Respond to keypresses."""
        if event.key == pygame.K_q:
            sys.exit()

    def _create_aliens(self):
        # create an alien and place it in the row.
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        available_space_x = self.settings.screen_width - alien_width

        self.number_aliens_x = available_space_x // (2* alien_width)

        available_space_y = self.settings.screen_height
        number_rows = available_space_y // (2 * alien_height)
        for row_number in range(number_rows):
            self._create_row(row_number)

    def _create_row(self, row_number):
        for alien_number in range(self.number_aliens_x):
            self._create_alien(alien_number, row_number)

    def _create_alien(self, alien_number, row_number):
        alien = Alien(self)
        alien_width, alien_height = alien.rect.size
        alien.rect.x = alien_width + 2 * alien_width * alien_number
        alien.y = 2 * alien.rect.height * row_number
        alien.rect.y = alien.y
        self.aliens.add(alien)

    def _update_aliens(self):
        self.aliens.update()

        make_new_aliens = False
        for alien in self.aliens.copy():
            if alien.check_disappeared():
                self.aliens.remove(alien)
                make_new_aliens = True

        if make_new_aliens:
            self._create_row(0)

    def _update_screen(self):
        """Update images on te screen, and flip to the new screen."""
        # Redraw the screen during each pass through the loop.
        self.screen.fill(self.settings.bg_color)
        self.aliens.draw(self.screen)

        # Make the most recently drawn screen visible.
        pygame.display.flip()

if __name__ == '__main__':
    # make a game instance and run the game.
    ai = AlienInvasion()
    ai.run_game()


import csv

import numpy as np
from sklearn import metrics
from sklearn.cluster import KMeans
from sklearn.metrics import f1_score
from sklearn.metrics.cluster import adjusted_mutual_info_score
from sklearn.metrics.cluster import normalized_mutual_info_score
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import PredefinedSplit
from sklearn.model_selection import train_test_split
from sklearn.multiclass import OneVsOneClassifier
from sklearn.neural_network import MLPRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.svm import LinearSVC
import argparse

def read_embeddings_avg(filein):
    rb = open(filein, 'r')
    emb = dict()
    #rb.readline()
    for line in rb.readlines():
        elem = line.strip().split(' ')
        e = np.fromstring(' '.join(elem[1:]), dtype=np.float, sep=' ')
        emb[int(elem[0])] = e
    rb.close()
    a = []
    for i in range(0, len(emb)):
        if i in emb:
            a.append(emb[i])
        #else:
        #    a.append(np.zeros(128))
    return a

def read_embeddings_line(filein):
    rb = open(filein, 'r')
    emb = dict()
    a = []
    for line in rb.readlines():
        elem = line.strip().split(' ')
        e = np.fromstring(' '.join(elem[0:]), dtype=np.float, sep=' ')
        a.append(e)
    rb.close()
    return a

def read_embeddings_sub2vec(filein, n):
    rb = open(filein, 'r')
    emb = dict()
    for line in rb.readlines():
        elem = line.strip().split(' ')
        e = np.fromstring(' '.join(elem[1:]), dtype=np.float, sep=' ')
        emb[int(elem[0])] = e
    rb.close()
    a = []
    for i in range(0, n):
        if i in emb:
            a.append(emb[i])
        else:
            a.append(np.zeros(128))
    return a

def clustering(label_file, embedding_file, embedding_dim, clusters):
    print('performing kmeans clustering -------------------------------------------')

    embeddings = np.fromfile(embedding_file, np.float32).reshape(-1, embedding_dim)
    #embeddings = read_embeddings_avg(embedding_file)
    kmeans = KMeans(n_clusters=clusters, random_state=0).fit(embeddings)
    node_labels = kmeans.labels_

    with open(label_file, 'r') as f:
        reader = csv.reader(f, delimiter=' ')
        label_list = list(reader)

    labels = []
    for item in label_list:
        labels.append(int(item[1]))

    nmi_score = normalized_mutual_info_score(node_labels, labels)
    adj_score = adjusted_mutual_info_score(node_labels, labels)

    print(nmi_score)
    print(adj_score)

    return nmi_score

def node_classification(label_file, embedding_file, embedding_dim, percentage_train):
    print("running node_classification ---------------------------------------")

    embeddings = np.fromfile(embedding_file, np.float32).reshape(-1, embedding_dim)
    #embeddings = read_embeddings_avg(embedding_file)

    scaler = StandardScaler()
    scaler.fit(embeddings)
    x_data = scaler.transform(embeddings)
    with open(label_file, 'r') as f:
        reader = csv.reader(f, delimiter=' ')
        label_list = list(reader)

    y_labels = []
    for item in label_list:
        y_labels.append(int(item[1]))

    y_labels = np.array(y_labels)
    parameter_space = {'estimator__kernel':['rbf', 'linear','sigmoid','poly'],
                        'estimator__gamma':[1e-3, 1e-4],
                        'estimator__probability':[True],
                       'estimator__C': [1, 10, 100, 1000],
                       'estimator__max_iter': [1000, 5000]
                       }

    x_train, x_test, y_train, y_test = train_test_split(x_data, y_labels, test_size= 1 - percentage_train, random_state=42,
                                                        stratify=y_labels)

    model = OneVsOneClassifier(SVC())
    clf = GridSearchCV(model, parameter_space, n_jobs=10, cv=5, scoring='f1_micro')
    clf.fit(x_train, y_train)
    '''
    clf = OneVsOneClassifier(LinearSVC(random_state=0))
    clf.fit(x_train, y_train)
    '''
    y_pred = clf.predict(x_test)
    macro_score = f1_score(y_test, y_pred, average='macro', labels=np.unique(y_pred))
    micro_score = f1_score(y_test, y_pred, average='micro', labels=np.unique(y_pred))
    print('F1-micro / F1-macro scores')
    print(micro_score)
    print(macro_score)

    return micro_score, macro_score

def cascade_prediction(train_file, test_file, val_file, embedding_file, embedding_dim):
    embeddings = np.fromfile(embedding_file, np.float32).reshape(-1, embedding_dim)
    #embeddings = read_embeddings_avg(embedding_file)
    label = 0

    x_test = []
    y_test = []
    index = 0
    rb = open(test_file, 'r')
    for line in rb.readlines():
        elems = line.strip().split('\t')
        x_test.append(embeddings[index])
        index += 1
        value = int(elems[-1].split(' ')[label])
        value = np.log(value + 1.0) / np.log(2.0)
        y_test.append(value)
    rb.close()

    x_train = []
    y_train = []
    rb = open(train_file, 'r')
    for line in rb.readlines():
        elems = line.strip().split('\t')
        x_train.append(embeddings[index])
        index += 1
        value = int(elems[-1].split(' ')[label])
        value = np.log(value + 1) / np.log(2.0)
        y_train.append(value)
        rb.close()

    x_val = []
    y_val = []
    rb = open(val_file, 'r')
    for line in rb.readlines():
        elems = line.strip().split('\t')
        x_val.append(embeddings[index])
        index += 1
        value = int(elems[-1].split(' ')[label])
        value = np.log(value + 1) / np.log(2.0)
        y_val.append(value)
    rb.close()

    parameter_space = {
        'hidden_layer_sizes': [(64, 32, 16), (64, 32, 64), (64,)],
        'activation': ['tanh', 'relu', 'logistic'],
        'solver': ['sgd', 'adam'],
        'alpha': [0.0001, 0.001, 0.05, 0.01, 0.5, 1],
        'learning_rate': ['constant', 'adaptive'],
        'shuffle': [False], 'random_state': [0],
        'max_iter': [200]}
    x = x_train + x_val
    y = y_train + y_val
    fold = [-1 for i in x_train]
    fold.extend([0 for i in x_val])
    '''
    model = MLPRegressor()
    ps = PredefinedSplit(test_fold=fold)
    clf = GridSearchCV(model, parameter_space, n_jobs=10, cv=ps)
    clf.fit(x, y)
    '''
    clf = MLPRegressor(hidden_layer_sizes=(64,32), activation=relu, solver=adam,shuffle=False, random_state=0)
    clf.fit(x,y)
    print(clf.get_params())
    y_pred = clf.predict(x_test)
    print('Mean Squared Error:', metrics.mean_squared_error(y_test, y_pred))

if __name__ == '__main__':
    my_parser = argparse.ArgumentParser(prog='embedding_evaluation',
                                        usage='embedding_evaluation application(kmeans/node_class/cascade_pred) embedding_file (needed for clustering: number_clusters and label_file, needed for node classification/edge prediction: label_file, needed cascade prediction: train/test/val label files) ',
                                        description='This program takes embeddings and evaluates them on different downstream applications: clustering, node clasification, link prediction and for cascade prediction. ')

    my_parser.add_argument("-e", "--embeddings", required=True,
                           help="path to embedding file")
    my_parser.add_argument("-a", "--application", required=True,
                           help="Application: kmeans/node_class/link_pred/cascade_pred")
    my_parser.add_argument("-k", "--clusters", required=False,
                           help="number of clusters for k means")
    my_parser.add_argument("-l", "--label", required=False,
                           help="label file for clustering/node classification")
    my_parser.add_argument("-pr", "--percentage_train", required = False,
                          help = "percentage of training data for the node classification")
    my_parser.add_argument("-tr", "--train_label", required=False,
                           help="train label file for cascade prediction")
    my_parser.add_argument("-te", "--test_label", required=False,
                           help="test label file for cascade prediction")
    my_parser.add_argument("-v", "--val_label", required=False,
                           help="val label file for cascade prediction")
    args = vars(my_parser.parse_args())
    print(args)
    if args.get('application') == "kmeans":
        clustering(args.get("label"), args.get("embeddings"), 128, int(args.get("clusters")))
    elif args.get('application') == "node_class":
        node_classification(args.get("label"), args.get("embeddings"), 128, float(args.get("percentage_train")))
    elif args.get('application') == "cascade_pred":
        cascade_prediction(args.get("train_label"), args.get("test_label"), args.get("val_label"), args.get("embeddings"), 128)
    else:
        print("no application found")


from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import logging

if __name__ == '__main__':
    logging.basicConfig(filename='test_1.log',
                        level=logging.INFO,
                        format='%(asctime)s %(message)s')
    logger = logging.getLogger('testing_task')
    logger.setLevel(logging.INFO)
    stream_handler = logging.StreamHandler()
    stream_handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    stream_handler.setFormatter(formatter)
    logger.addHandler(stream_handler)
    options = webdriver.ChromeOptions()
    options.add_argument("--start-maximized")
    options.add_argument('--log-level=3')
    driver = webdriver.Chrome(executable_path="chromedriver",
                              chrome_options=options)
    driver.set_window_size(1420, 900)

    logger.info("Test akceptacji cookies, wyszukania produktu na stronie ceneo.pl i uzycia sortowania")
    driver.get('https://www.ceneo.pl')
    time.sleep(3)
    driver.find_element(By.CLASS_NAME, 'btn.btn-info.btn-origin.js_cookie-monster-agree.js_gtm_button').click()
    driver.switch_to.default_content()
    logger.info("Kliknieto 'Akceptuj cookies'")
    time.sleep(2)
    logger.info("Zakceptowano polityke cookies")
    driver.find_element(By.NAME, 'search-query').click()
    logger.info("Znaleziono wyszukiwarke")
    input_1 = driver.find_element(By.ID, 'form-head-search-q')
    input_1.send_keys("xbox")
    logger.info("Wpisano fraze do wyszukiwarki")
    time.sleep(2)
    driver.find_element(By.CLASS_NAME, 'header-search__button__text').click()
    logger.info("Kliknieto 'Szukaj'")
    time.sleep(3)
    driver.find_element(By.XPATH, "//a[@title='Microsoft Xbox Series X']").click()
    logger.info("Znaleziono szukany element po atrybucie title")
    time.sleep(2)
    driver.find_element(By.XPATH, '/html/body/div[1]/div[3]/div[2]/div/div/div[1]/div[5]/div[2]/div[1]/div/div/div[1]/a/b').click()
    logger.info("Kliknieto 'Sortuj od'")
    time.sleep(2)
    driver.find_element(By.XPATH, '/html/body/div[1]/div[3]/div[2]/div/div/div[1]/div[5]/div[2]/div[1]/div/div/div[1]/div/a[3]').click()
    logger.info("Wybrano sortowanie wedlug 'najnizszej ceny z dostawa'")
    logger.info("Test zaliczony!")
    time.sleep(10)
    driver.quit()
    print("Done")


# coding: utf-8

"""
    openapi 3.1.0 sample spec
    sample spec for testing openapi functionality, built from json schema tests for draft2020-12  # noqa: E501
    The version of the OpenAPI document: 0.0.1
    Generated by: https://github.com/openapi-json-schema-tools/openapi-json-schema-generator
"""

import unittest

import unit_test_api
from unit_test_api.components.schema.additionalproperties_does_not_look_in_applicators import AdditionalpropertiesDoesNotLookInApplicators
from unit_test_api.configurations import schema_configuration

class TestAdditionalpropertiesDoesNotLookInApplicators(unittest.TestCase):
    """AdditionalpropertiesDoesNotLookInApplicators unit test stubs"""
    configuration = schema_configuration.SchemaConfiguration(
        disabled_json_schema_keywords={'format'}
    )

    def test_properties_defined_in_allof_are_not_examined_fails(self):
        # properties defined in allOf are not examined
        with self.assertRaises((unit_test_api.ApiValueError, unit_test_api.ApiTypeError)):
            AdditionalpropertiesDoesNotLookInApplicators.validate(
                {
                    "foo":
                        1,
                    "bar":
                        True,
                },
                configuration=self.configuration
            )

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


from __future__ import annotations

from typing import Final
from urllib.parse import urljoin

from flexget.utils.soup import get_soup

from ..base.entry import SignInEntry
from ..base.request import NetworkState, check_network_state
from ..base.sign_in import SignState
from ..base.sign_in import check_final_state
from ..base.work import Work
from ..schema.gazelle import Gazelle
from ..utils import net_utils
from ..utils.net_utils import get_module_name
from ..utils.value_handler import handle_infinite

class MainClass(Gazelle):
    URL: Final = 'https://gazellegames.net/'
    API_URL: Final = urljoin(URL, '/api.php')
    MESSAGE_URL: Final = urljoin(URL, '/inbox.php?action=viewconv&id={conv_id}')
    USER_CLASSES: Final = {
        'points': [1200, 6000],
    }

    @classmethod
    def sign_in_build_schema(cls) -> dict:
        return {
            get_module_name(cls): {
                'type': 'object',
                'properties': {
                    'cookie': {'type': 'string'},
                    'key': {'type': 'string'},
                    'name': {'type': 'string'}
                },
                'additionalProperties': False
            }
        }

    def sign_in_build_workflow(self, entry: SignInEntry, config: dict) -> list[Work]:
        return [
            Work(
                url='/',
                method=self.sign_in_by_get,
                succeed_regex=['Welcome, <a.+?</a>'],
                assert_state=(check_final_state, SignState.SUCCEED),
                is_base_content=True
            )
        ]

    @property
    def details_selector(self) -> dict:
        selector = super().details_selector
        net_utils.dict_merge(selector, {
            'detail_sources': {
                'default': {
                    'do_not_strip': True,
                    'elements': {
                        'bar': '#community_stats > ul:nth-child(3)',
                        'table': '#content > div > div.sidebar > div.box_main_info',
                        'join_date': '.nobullet span.time'
                    }
                },
                'achievements': {
                    'link': '/user.php?action=achievements',
                    'elements': {
                        'total_point': '#content > div[class=linkbox]'
                    }
                }
            },
            'details': {
                'points': {
                    'regex': 'Total Points: (\\d+)'
                },
                'hr': {
                    'regex': 'Hit \'n\' Runs">(\\d+)'
                },
            }
        })
        return selector

    def get_details(self, entry: SignInEntry, config: dict) -> None:
        site_config = entry['site_config']
        key = site_config.get('key')
        name = site_config.get('name')
        if not (key and name):
            entry.fail_with_prefix('key or name not found')
            return
        params = {
            'request': 'user',
            'key': key,
            'name': name
        }
        details_response_json = self.get_api_response_json(entry, params)
        if not details_response_json:
            return
        entry['details'] = {
            'uploaded': f'{details_response_json.get("response").get("stats").get("uploaded") or 0} B'.replace(',', ''),
            'downloaded': f'{details_response_json.get("response").get("stats").get("downloaded") or 0} B'.replace(',',
                                                                                ''),
            'share_ratio': handle_infinite(
                str(details_response_json.get('response').get('stats').get('ratio') or 0).replace(',', '')),
            'points': str(details_response_json.get('response').get('achievements').get('totalPoints') or 0).replace(
                ',', ''),
            'seeding': str(details_response_json.get('response').get('community').get('seeding') or 0).replace(',', ''),
            'leeching': str(details_response_json.get('response').get('community').get('leeching') or 0).replace(',',
                                                                                ''),
            'hr': str(details_response_json.get('response').get('personal').get('hnrs') or 0).replace(',', '')
        }

    def get_messages(self, entry: SignInEntry, config: dict) -> None:
        site_config = entry['site_config']
        key = site_config.get('key')
        if not key:
            entry.fail_with_prefix('key not found')
            return
        params = {
            'request': 'inbox',
            'sort': 'unread',
            'key': key
        }

        messages_response_json = self.get_api_response_json(entry, params)
        if not messages_response_json:
            return
        unread_messages = filter(lambda m: m.get('unread'),
                                 messages_response_json.get('response').get('messages'))
        failed = False
        for message in unread_messages:
            title = message.get('subject')
            conv_id = message.get('convId')
            message_url = MainClass.MESSAGE_URL.format(conv_id=conv_id)
            message_response = self.request(entry, 'get', message_url)
            network_state = check_network_state(entry, message_url, message_response)
            message_body = 'Can not read message body!'
            if network_state != NetworkState.SUCCEED:
                failed = True
            else:
                body_element = get_soup(
                    net_utils.decode(message_response)).select_one('.body')
                if body_element:
                    message_body = body_element.text.strip()
            entry['messages'] = entry['messages'] + (
                f'\nTitle: {title}\nLink: {message_url}\n{message_body}')
        if failed:
            entry.fail_with_prefix('Can not read message body!')

    def get_api_response_json(self, entry: SignInEntry, params: dict) -> dict | None:
        api_response = self.request(entry, 'get', MainClass.API_URL, params=params)
        network_state = check_network_state(entry, api_response.request.url, api_response)
        if network_state != NetworkState.SUCCEED:
            return None
        api_response_json = api_response.json()
        if not api_response_json.get('status') == 'success':
            entry.fail_with_prefix(api_response_json)
            return None
        return api_response_json


#All sorted lowercase letters are ahead of uppercase letters.
#All sorted uppercase letters are ahead of digits.
#All sorted odd digits are ahead of sorted even digits.
import re
word = "Sorting1243"
low = []
high = []
num = []
for c in word:
    if c.islower():
        low.append(c)
    elif c.isupper():
        high.append(c)
    elif c.isalnum():
        num.append(int(c))

num.sort(key=lambda x: (-(x % 2), x))

word = [*sorted(low), *sorted(high), *str(''.join(map(str, num)))]

print(''.join(word))


def extractNorvaBlog(item):
	"""
	'Norva Blog'
	"""
	vol, chp, frag, postfix = extractVolChapterFragmentPostfix(item['title'])
	if not (chp or vol or frag) or 'preview' in item['title'].lower():
		return None

	if item['tags'] == ['Uncategorized'] and item['title'].startswith("Episode "):
		return buildReleaseMessageWithType(item, 'Sairin Yuusha no Fukushuu Hanashi', vol, chp, frag=frag, postfix=postfix, tl_type='translated')

	return False


import clover
import data
import numpy as np
import definitions as defs
def log(string):
    if data.parallel['boss']:
        data.file_out.write(string)
        data.file_out.write("\n")
        print(string)

def init_chunk(chunk):
    from definitions import chunks, grid
    dx=np.array((grid.xmax-grid.xmin)/float(grid.x_cells))
    dy=(grid.ymax-grid.ymin)/float(grid.y_cells)

    xmin=grid.xmin+dx*float(chunks[chunk].field.left-1)
    ymin=grid.ymin+dy*float(chunks[chunk].field.bottom-1)
    from CloverLeafCuda import init_chunks
    init_chunks(xmin,ymin,dx,dy)

def ideal_gas(chunk, predict):
    from definitions import chunks
    if chunks[chunk].task is data.parallel["task"]:
        import CloverLeafCuda
        CloverLeafCuda.ideal_gas(predict)

def generate_chunk(chunks):
    from definitions import states
    density = np.zeros(data.number_of_states)
    energy  = np.zeros(data.number_of_states)
    xvel    = np.zeros(data.number_of_states)
    yvel    = np.zeros(data.number_of_states)
    xmin    = np.zeros(data.number_of_states)
    xmax    = np.zeros(data.number_of_states)
    ymin    = np.zeros(data.number_of_states)
    ymax    = np.zeros(data.number_of_states)
    radius    = np.zeros(data.number_of_states)
    geometry = np.zeros(data.number_of_states, np.int32)

    for state in range(0,data.number_of_states):
        density[state]=states[state].density
        energy[state]=states[state].energy
        xvel[state]=states[state].xvel
        yvel[state]=states[state].yvel
        xmin[state]=states[state].xmin
        xmax[state]=states[state].xmax
        ymin[state]=states[state].ymin
        ymax[state]=states[state].ymax
        radius[state]=states[state].radius
        geometry[state]=states[state].geometry
    import CloverLeafCuda
    CloverLeafCuda.generate_chunks(data.number_of_states, density, energy, xvel, yvel, xmin, xmax, ymin, ymax, radius, geometry, data.g_rect, data.g_circ, data.g_point)

def update_halos(fields, depth):
    from CloverLeafCuda import exchange_halo, update_halo
    for c in range(0,defs.number_of_chunks):
        if defs.chunks[c].task == data.parallel["task"]:
            exchange_halo(depth, fields,defs.chunks[c].chunk_neighbours,c)
            update_halo(depth, fields,  defs.chunks[c].chunk_neighbours)

def start():
    log('Setting up initial geometry')

    defs.time  = 0.0
    defs.step  = 0
    defs.dtold = defs.dtinit
    defs.dt    = defs.dtinit

    clover.clover_barrier()

    defs.number_of_chunks=clover.clover_get_num_chunks()
    for i in range(defs.number_of_chunks):
        defs.chunks.append(defs.chunk_type())

    left = np.zeros(defs.number_of_chunks)
    right = np.zeros(defs.number_of_chunks)
    bottom = np.zeros(defs.number_of_chunks)
    top = np.zeros(defs.number_of_chunks)

    clover.clover_decompose(defs.grid.x_cells, defs.grid.y_cells, left, right, bottom, top)
    for c in range(0,defs.number_of_chunks):

        from definitions import chunks
    #Needs changing so there can be more than 1 chunk per task
        chunks[c].task = c
        x_cells = right[c] -left[c]  +1
        y_cells = top[c]   -bottom[c]+1

        if chunks[c].task == data.parallel["task"]:
            from build_field import build_field
            build_field(c,x_cells,y_cells)

        chunks[c].field.left    = left[c]
        chunks[c].field.bottom  = bottom[c]
        chunks[c].field.right   = right[c]
        chunks[c].field.top     = top[c]
        chunks[c].field.left_boundary   = 1
        chunks[c].field.bottom_boundary = 1
        chunks[c].field.right_boundary  = defs.grid.x_cells
        chunks[c].field.top_boundary    = defs.grid.y_cells
        chunks[c].field.x_min = np.array(1, np.int)
        chunks[c].field.y_min = np.array(1, np.int)
        chunks[c].field.x_max = np.array(right[c]-left[c]+1, np.int)
        chunks[c].field.y_max = np.array(top[c]-bottom[c]+1, np.int)

    clover.clover_barrier()

    for c in range(0,defs.number_of_chunks):
        if chunks[c].task == data.parallel["task"]:
            init_chunk(c)
    for c in range(0,defs.number_of_chunks):
        if chunks[c].task == data.parallel["task"]:
            generate_chunk(c)

    defs.advect_x=True
    clover.clover_barrier()

    for c in range(0,defs.number_of_chunks):
        ideal_gas(c, False)

    fields = np.zeros(data.NUM_FIELDS, np.int32)
    fields[data.FIELD_DENSITY0]=1
    fields[data.FIELD_ENERGY0]=1
    fields[data.FIELD_PRESSURE]=1
    fields[data.FIELD_VISCOSITY]=1
    fields[data.FIELD_DENSITY1]=1
    fields[data.FIELD_ENERGY1]=1
    fields[data.FIELD_XVEL0]=1
    fields[data.FIELD_YVEL0]=1
    fields[data.FIELD_XVEL1]=1
    fields[data.FIELD_YVEL1]=1

    update_halos(fields,2)
    if data.parallel['boss']:
        print('Problem initialised and generated')
    from CloverLeafCuda import field_summary
    field_summary()

    if(defs.visit_frequency!= 0):
        import visist
        visit.visit()


import numpy as np
from inputNumber import inputNumber

# Viser en menu, beder brugeren om at vælge en af mulighederne ret og returnerer den valgte mulighed
def displayMenu(options):

    # Viser menuen
    for i in range(len(options)):
        print("{:d}. {:s}".format(i+1, options[i]))

    # For at sikre at den valgte mulighed er gyldig.
    choice = 0
    while not(np.any(choice == np.arange(len(options))+1)):
        choice = inputNumber("Vælg venligst en handling: ")
    return choice


import re
import os
import shutil
from datetime import datetime

from py4j.java_gateway import JavaGateway, GatewayParameters
from py4j.java_gateway import java_import
from py4j.protocol import Py4JNetworkError

from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import FSMContext

from unpack import get_date
from markups import button_names, get_kbd
from xml_parcing import check_cession, get_cad_num
from user_settings_handler import get_globals_from_disk, write_globals_to_disk
from config import TG_KEY, TASKS_ROOT, WHITELIST
import globals

telegram_bot = Bot(token=TG_KEY)
dp = Dispatcher(telegram_bot, storage=MemoryStorage())

def extract_cad_nums(text: str) -> list:
    """Возвращает все найденные в тексте кадастровые номера"""
    user_cad_nums = re.findall(r"\d{2}:\d{2}:\d{7}:\d{1,5}", text)
    return sorted(set(user_cad_nums))

def extract_cad_raion(text: str) -> list:
    """Возвращает все найденые в тексте кадастровые районы (район должен быть прописан отдельно, не в составе номера)"""
    found_cad_raions = re.findall(r"\d{2}:\d{2}:", text.strip())
    return sorted(set(found_cad_raions))

def get_type2_files_set() -> set:
    """Возвращает полные имена файлов для всех выписок 2го типа в индексе"""
    type2_v1_dataset = docfetcher_search(
        f'"Выписка из Единого государственного реестра недвижимости о переходе прав на объект недвижимости"')
    type2_v2_dataset = docfetcher_search('<extract_transfer_rights_property>')
    full_dataset = type2_v1_dataset + type2_v2_dataset
    result = {r.getPathStr() for r in full_dataset if r.getType() == 'xml'}
    return result

def check_whitelist(func):
    async def wrapper(*args, **kwargs):
        for arg in args:
            if isinstance(arg, types.Message) and arg.from_user.id in WHITELIST:
                await func(*args, **kwargs)
    return wrapper

class TaskCreation(StatesGroup):
    task_naming = State()
    input_cad_nums = State()

async def send_multipart_msg(user_id, text):
    parts = []
    current_part = []
    for line in text.splitlines():
        if len('\n'.join(current_part) + line) < 4000:
            current_part.append(line)
        else:
            parts.append(current_part)
            current_part = [line]
    if current_part:
        parts.append(current_part)
    parts = ['\n'.join(p) for p in parts]
    for i, part in enumerate(parts):
        if part.count('') > part.count(''):
            parts[i] = part + ''
        if part.count('') < part.count(''):
            parts[i] = '' + part
    for part in parts:
        await telegram_bot.send_message(user_id, part, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(endswith=button_names['verbose_on'][2:]))
@check_whitelist
async def toggle_verbose(message: types.Message, *args, **kwargs):
    globals.VERBOSE = not globals.VERBOSE
    write_globals_to_disk()
    text = button_names['verbose_on'][2:] + (' ВКЛ' if globals.VERBOSE else ' ВЫКЛ')
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(endswith=button_names['prohibitions_on'][2:]))
@check_whitelist
async def toggle_prohibitons(message: types.Message, *args, **kwargs):
    globals.PROHIBITIONS = not globals.PROHIBITIONS
    if globals.PROHIBITIONS and globals.CESSION:
        globals.CESSION = False
    write_globals_to_disk()
    text = button_names['prohibitions_on'][2:] + (' ВКЛ' if globals.PROHIBITIONS else ' ВЫКЛ')
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(endswith=button_names['cession_on'][2:]))
@check_whitelist
async def toggle_cession(message: types.Message, *args, **kwargs):
    globals.CESSION = not globals.CESSION
    if globals.CESSION and globals.PROHIBITIONS:
        globals.PROHIBITIONS = False
    write_globals_to_disk()
    text = button_names['cession_on'][2:] + (' ВКЛ' if globals.CESSION else ' ВЫКЛ')
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(endswith=button_names['type_1_only_on'][2:]))
@check_whitelist
async def toggle_type1_only(message: types.Message, *args, **kwargs):
    globals.TYPE_1_ONLY = not globals.TYPE_1_ONLY
    if globals.TYPE_1_ONLY:
        globals.TYPE_2_ONLY = False
    write_globals_to_disk()
    text = button_names['type_1_only_on'][2:] + (' ВКЛ' if globals.TYPE_1_ONLY else ' ВЫКЛ')
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(endswith=button_names['type_2_only_on'][2:]))
@check_whitelist
async def toggle_type2_only(message: types.Message, *args, **kwargs):
    globals.TYPE_2_ONLY = not globals.TYPE_2_ONLY
    if globals.TYPE_2_ONLY:
        globals.TYPE_1_ONLY = False
    write_globals_to_disk()
    text = button_names['type_2_only_on'][2:] + (' ВКЛ' if globals.TYPE_2_ONLY else ' ВЫКЛ')
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(endswith=button_names['check_cn_on'][2:]))
@check_whitelist
async def toggle_check_cn(message: types.Message, *args, **kwargs):
    globals.CAD_NUM_CHECK = not globals.CAD_NUM_CHECK
    write_globals_to_disk()
    text = button_names['check_cn_on'][2:] + (' ВКЛ' if globals.CAD_NUM_CHECK else ' ВЫКЛ')
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(endswith=button_names['last_only_on'][2:]))
@check_whitelist
async def toggle_last_only(message: types.Message, *args, **kwargs):
    globals.LAST_ONLY = not globals.LAST_ONLY
    write_globals_to_disk()
    text = button_names['last_only_on'][2:] + (' ВКЛ' if globals.LAST_ONLY else ' ВЫКЛ')
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(endswith=button_names['date_dirs_on'][2:]))
@check_whitelist
async def toggle_date_dirs(message: types.Message, *args, **kwargs):
    globals.DATE_DIRS = not globals.DATE_DIRS
    write_globals_to_disk()
    if globals.DATE_DIRS:
        text = 'В заданиях будут создавться каталоги для каждой отдельной даты'
    else:
        text = 'В заданиях будут создаваться каталоги по годам'
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(Text(equals=button_names['create_task']))
@check_whitelist
async def create_task(message: types.Message, *args, **kwargs):
    """Создание простого задания, стадия 1: Предлагаем ввести имя каталога"""
    text = f"ЗАДАНИЕ{' (Запреты и аресты)' if globals.PROHIBITIONS else ''}{' (Передача собственности)' if globals.CESSION else ''}: Введите название каталога"
    await TaskCreation.task_naming.set()
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(state=TaskCreation.task_naming)
@check_whitelist
async def input_task_name(message: types.Message, state: FSMContext,  *args, **kwargs):
    """Создание простого задания, стадия 2: Проверяем валидность имени и предлагаем ввести кадастровые номера"""
    dirname = message.text.strip()

    # проверяем что в имени папки нет недопустимых символов
    forbidden_chars = '/\:*?«<>|'
    if any([ch in dirname for ch in forbidden_chars]):
        chars = [ch for ch in forbidden_chars if ch in dirname]
        text = f"Данные символы нельзя использовать в имени каталога:\n{' '.join(chars)}\nЗадание отменено."
        await state.finish()
    else:
        await state.update_data(dirname=dirname)
        await TaskCreation.input_cad_nums.set()
        text = f"ЗАДАНИЕ{' (Запреты и аресты)' if globals.PROHIBITIONS else ''}{' (Передача собственности)' if globals.CESSION else ''}: Введите кадастровые номера"
    await telegram_bot.send_message(message.from_user.id, text, reply_markup=get_kbd(), parse_mode="HTML")

@dp.message_handler(state=TaskCreation.input_cad_nums)
@check_whitelist
async def input_cad_nums(message: types.Message, state: FSMContext,  *args, **kwargs):
    """Создание простого задания, стадия 3: Для каждого из найденных номеров копируем файлы в созданную папку и отправляем отчет"""
    user_cad_nums = extract_cad_nums(message.text)
    # если кадастровых номеров не найдено - ищем кадастровые районы
    use_cadaster_kvartals = False
    if not user_cad_nums:
        use_cadaster_kvartals = True
        user_cad_nums = extract_cad_raion(message.text)
    try:
        if user_cad_nums:
            found, years_count = {}, {}
            not_found, n_copied, cn_dates_and_sizes = [], 0, []
            text = 'ЗАПРЕТЫ И АРЕСТЫ\n' if globals.PROHIBITIONS else ''
            if globals.CESSION:
                text += 'ПЕРЕДАЧА СОБСТВЕННОСТИ\n'
            type2_files = get_type2_files_set()  # получаем множество полных имен файлов для всех выписок 2го типа в индексе
            for cad_num in user_cad_nums:
                results = [r for r in docfetcher_search(f'"{cad_num}"') if r.getType() == 'xml']
                if globals.CAD_NUM_CHECK:  # провереям, что кадастровый номер найденный док-фечером - именно номер данного участка, а не просто упоминается в документе
                    results = [r for r in results if get_cad_num(r.getPathStr()) == cad_num]
                if results:
                    """Если поставлены флаги Только 1го типа, Только 2го типа или Передача собственности -
                    оставляем в найденных только нужные файлы"""
                    files = []
                    if globals.TYPE_1_ONLY:
                        files = [r for r in results if r.getPathStr() not in type2_files]
                        print(files)
                        if not files:
                            not_found.append(cad_num)
                    elif globals.TYPE_2_ONLY:
                        files = [r for r in results if r.getPathStr() in type2_files]
                        if not files:
                            not_found.append(cad_num)
                    elif globals.CESSION:
                        files = [r for r in results if check_cession(r.getPathStr())]
                        if not files:
                            not_found.append(cad_num)
                    else:
                        files = results

                    if globals.LAST_ONLY:
                        files = sorted(files, key=lambda x: get_date(x.getPathStr()))[-1:]

                    if files:
                        found[cad_num] = files
                else:
                    not_found.append(cad_num)

            if not_found:  # tесли есть кадастровые номера(районы), по которым результаты поиска нулевые
                text += 'Не найдены в базе:\n'
                for cad_num in not_found:
                    text += f'{cad_num}\n'
                text += '\n'
            else:
                if not globals.PROHIBITIONS:  # в режиме Запеты и аресты данная информация излишня
                    text += 'Все номера найдены в базe\n'

            if globals.CESSION:
                found = {k: v for k, v in found.items() if v}
                if not found:
                    text += 'Повторяющихся дат регистрации не обнаружено\n'

            if found:
                prohibitions = {f.getPathStr() for f in docfetcher_search(f'запрет арест')} if globals.PROHIBITIONS else {}
                state_data = await state.get_data()
                task_path = os.path.join(TASKS_ROOT, state_data['dirname'])
                if not os.path.exists(task_path):
                    os.makedirs(task_path)
                    text += f'Создан каталог:\n{task_path}\n'
                else:
                    text += f'Каталог уже существует:\n{task_path}\n'

                for cad_num in found:
                    DEBUGTEXT = f">>>> DEBUG <<<<\n{cad_num}---Найдено файлов: {len(found[cad_num])}\n"
                    print(f"{cad_num} Найдено файлов: {len(found[cad_num])}"+"-"*50)
                    for file in found[cad_num]:
                        DEBUGTEXT += f"🔵{file.getPathStr()}\n"
                        if globals.PROHIBITIONS and file.getPathStr() not in prohibitions:  # если включен режим "Запреты и аресты", то пропускаем все файлы, где нет запретов/арестов
                            continue
                        print('  -Файл', file.getPathStr())
                        try:
                            ext_date = get_date(file.getPathStr())
                            if not globals.DATE_DIRS:  # если пользователь не выбрал опцию Каталоги по Датам, то дата сокращаестся до года (и, соответственно выписки кладутся в подпапки по годам, а не по отдельным датам)
                                ext_date = ext_date[:4]
                            file_size = os.path.getsize(file.getPathStr())
                            ext_type = 2 if file.getPathStr() in type2_files else 1
                            if (cad_num, ext_date, file_size) not in cn_dates_and_sizes:  # обрабатываем файл только если файлов с тем же номером, датой и размером за эту сессию не обрабатывалось.
                                if not use_cadaster_kvartals or not globals.DATE_DIRS:  # если ищем не уникальные кадастровые номера, а кадастровые кварталы - проверку на уникльность выписок пропускаем
                                    cn_dates_and_sizes.append((cad_num, ext_date, file_size))
                                # каталог с датой/годом для выписки
                                ext_dir_path = os.path.join(task_path, ext_date)
                                if not os.path.exists(ext_dir_path):
                                    os.makedirs(ext_dir_path)
                                # конечное расположение файла выписки
                                target_filename = os.path.join(ext_dir_path, file.getFilename())
                                if not os.path.exists(target_filename):
                                    shutil.copy(file.getPathStr(), ext_dir_path)
                                    print('\tСкопировано. Новое расположение:', ext_dir_path)
                                    n_copied += 1
                                    year = ext_date[:4]
                                    if year in years_count:
                                        years_count[year].append((cad_num, ext_type))
                                    else:
                                        years_count[year] = [(cad_num, ext_type)]
                                else:
                                    print('\tКопирование пропущено, файл c таким именем уже существует:', target_filename)
                                    DEBUGTEXT += f"🞉имя: {target_filename}\n"
                            else:
                                print('\tОбработка пропущена, файл с таким содерижмым уже существует')
                                DEBUGTEXT += f"🞉содержимое: {cad_num}, {ext_date}, {file_size}\n"
                        except FileNotFoundError as ex:
                            print('\tФайл не доступен:', ex)
                    # await telegram_bot.send_message(message.from_user.id, text=DEBUGTEXT)
                text += f'Скопирован{"ы" if n_copied != 1 else ""} {n_copied} файл{"а" if n_copied%10 in (2,3,4) else ""}{"ов" if n_copied%10 in (5,6,7,8,9,0) else ""}\n'
                if years_count:
                    text += f'По годам:\n'
                    for year in sorted(years_count):
                        text += f'{"⯈ " if globals.VERBOSE else ""}{year}: {len(years_count[year])}\n'
                        if globals.VERBOSE:
                            for cn, et in years_count[year]:
                                text += f"{cn}{' ❷' if et == 2 else ''}\n"
                    text += '\n'
        else:
            text = "Кадастровых номеров не найдено. Задание отменено."
    except Py4JNetworkError as ex:
        print(ex)
        text = 'DocFetcher не запущен'
    await send_multipart_msg(message.from_user.id, text)
    # await telegram_bot.send_message(message.from_user.id, text, parse_mode="HTML", reply_markup=get_kbd(),)
    await state.finish()

@dp.message_handler()
@check_whitelist
async def default_input(message: types.Message, **kwargs):
    """Стандартный обработчик сообщений - ищет в сообщении кадастровые номера и сообщает есть ли в индексе файлы с таким номером в теле"""
    user_cad_nums = extract_cad_nums(message.text)
    text = ''
    try:
        if user_cad_nums:
            type2_files = get_type2_files_set()
            found, not_found, files_excluded = [], [], 0
            for cad_num in user_cad_nums:
                results_dataset = docfetcher_search(f'"{cad_num}"')
                if globals.CAD_NUM_CHECK:
                    results_dataset = [r for r in results_dataset if get_cad_num(r.getPathStr()) == cad_num]  # провереям, что кадастровый номер найденный док-фечером - именно номер данного участка, а не просто упоминается в документе

                if not results_dataset:
                    not_found.append(cad_num)
                else:
                    result_files = [r.getPathStr() for r in results_dataset if r.getType() == 'xml']
                    initial_len = len(result_files)

                    if globals.TYPE_1_ONLY:
                        result_files = [r for r in result_files if r not in type2_files]
                    elif globals.TYPE_2_ONLY:
                        result_files = [r for r in result_files if r in type2_files]
                    if len(result_files) != initial_len:
                        files_excluded += (initial_len-len(result_files))

                    types_count = {1: 0, 2: 0}

                    for r_file in result_files:
                        if r_file in type2_files:
                            types_count[2] += 1
                        else:
                            types_count[1] += 1
                    if types_count[1]:
                        found.append((cad_num, 1, types_count[1]))
                    if types_count[2]:
                        found.append((cad_num, 2, types_count[2]))
            if files_excluded:
                text += f'Файлов исключено из поиска: {files_excluded}\n'

            if not_found:
                text += 'Не найдены в базе:\n'
                for x in not_found:
                    text += f'{x}\n'
                text += ''
            if found:
                if text:
                    text += '\n'
                text += 'Найдены:\n'
                for x in found:
                    text += f"{x[0]} {'❷ ' if x[1] == 2 else ''}{str(x[2]) + 'шт.' if x[2]>1 else ''}\n"
                text += ''
        else:
            text = "Введите один или несколько кадастровых номеров."
    except Py4JNetworkError:
        text = 'DocFetcher не запущен'
    await send_multipart_msg(message.from_user.id, text)

def docfetcher_search(query, port=28834):
    """Sends the given query string to the running DocFetcher instance at the
    given port and returns a list of result objects.

    The result objects provide the following getter methods for accessing their
    attributes:
    - getAuthors
    - getDateStr - e-mail send date
    - getFilename
    - getLastModifiedStr - last-modified date on files
    - getPathStr - file path
    - getScore - result score as int
    - getSender - e-mail sender
    - getSizeInKB - file size as int
    - getTitle
    - getType
    - isEmail - boolean indicating whether result object is e-mail or file

    This method will throw an error if communication with the DocFetcher
    instance fails.
    """
    gateway = JavaGateway(gateway_parameters=GatewayParameters(port=port))
    java_import(gateway.jvm, "net.sourceforge.docfetcher.gui.Application")
    application = gateway.jvm.net.sourceforge.docfetcher.gui.Application

    indexRegistry = application.getIndexRegistry()
    searcher = indexRegistry.getSearcher()
    results = searcher.search(query)
    return results

if __name__ == '__main__':
    get_globals_from_disk()
    executor.start_polling(dp, skip_updates=True)


#6번
import numpy as np
from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Input, Dense, Flatten, Reshape, Conv2D, Conv2DTranspose
from tensorflow.keras.models import Model
import matplotlib.pyplot as plt

# MNIST 데이터를 읽고 신경망에 입력할 준비
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 2와 7에 해당하는 데이터만 선택
selected_classes = [2, 7]
selected_indices = np.where(np.isin(y_train, selected_classes))[0]
x_train = x_train[selected_indices]
y_train = y_train[selected_indices]

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))

zdim = 32  # 잠복 공간의 차원

# 오토인코더의 인코더 부분 설계
encoder_input = Input(shape=(28, 28, 1))
x = Conv2D(32, (3, 3), activation='relu', padding='same', strides=(1, 1))(encoder_input)
x = Conv2D(64, (3, 3), activation='relu', padding='same', strides=(2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same', strides=(2, 2))(x)
x = Conv2D(64, (3, 3), activation='relu', padding='same', strides=(1, 1))(x)
x = Flatten()(x)
encoder_output = Dense(zdim)(x)
model_encoder = Model(encoder_input, encoder_output)

# 오토인코더의 디코더 부분 설계
decoder_input = Input(shape=(zdim,))
x = Dense(3136)(decoder_input)
x = Reshape((7, 7, 64))(x)
x = Conv2DTranspose(64, (3, 3), activation='relu', padding='same', strides=(1, 1))(x)
x = Conv2DTranspose(64, (3, 3), activation='relu', padding='same', strides=(2, 2))(x)
x = Conv2DTranspose(32, (3, 3), activation='relu', padding='same', strides=(2, 2))(x)
x = Conv2DTranspose(1, (3, 3), activation='relu', padding='same', strides=(1, 1))(x)
decoder_output = x
model_decoder = Model(decoder_input, decoder_output)

# 인코더와 디코더를 결합하여 오토인코더 모델 구축
model_input = encoder_input
model_output = model_decoder(encoder_output)
model = Model(model_input, model_output)

# 오토인코더 학습
model.compile(optimizer='Adam', loss='mse')
history = model.fit(x_train, x_train, epochs=5, batch_size=128, shuffle=True, validation_data=(x_test, x_test))

# 마지막 epoch에서의 validation 데이터셋의 mse loss 값
last_loss = history.history['val_loss'][-1]
print("마지막 epoch에서의 validation 데이터셋의 MSE loss 값:", last_loss)

# x_test 원본 이미지와 생성된 이미지 10개씩 출력
n = 10
plt.figure(figsize=(20, 4))
for i in range(n):
    # 원본 이미지 출력
    plt.subplot(2, n, i + 1)
    plt.imshow(x_test[i].reshape(28, 28), cmap='gray')
    plt.xticks([])
    plt.yticks([])

    # 생성된 이미지 출력
    plt.subplot(2, n, i + n + 1)
    decoded_img = model.predict(np.expand_dims(x_test[i], axis=0))
    plt.imshow(decoded_img.reshape(28, 28), cmap='gray')
    plt.xticks([])
    plt.yticks([])

plt.show()


from View.fighter_view import FighterView
from Model.fighter import Fighter
import random
from DAO.fighters_dao import FightersDAO

class FighterController():
    def __init__(self, game_controller):
        self.__fighter_view = FighterView()
        self.__game_controller = game_controller
        self.__fighters_DAO = FightersDAO()

    @property
    def fighters(self):
        return self.__fighters_DAO.get_all()

    def show_all_fighters_from_player(self, fighters_list):
        for counter,fighter in enumerate(fighters_list):
            fighter_data = {'fighter_number': counter+1,
                            'fighter_name':fighter.name,
                            'attack_name':fighter.attack.name,
                            'attack_power':fighter.attack.power,
                            'defense_name':fighter.defense.name,
                            'defense_power':fighter.defense.power,
                            'life':fighter.life}
            self.__fighter_view.show_fighter_data(fighter_data)

    def see_all_fighters(self):
        fighters_data_list = []
        for counter,fighter in enumerate(self.__fighters_DAO.get_all()):
            fighter_data = {'fighter_number': counter+1,
                            'fighter_name':fighter.name,
                            'attack_name':fighter.attack.name,
                            'attack_power':fighter.attack.power,
                            'defense_name':fighter.defense.name,
                            'defense_power':fighter.defense.power,
                            'life':fighter.life}
            fighters_data_list.append(fighter_data)

        self.__fighter_view.see_all_fighters(fighters_data_list)
        self.fighter_menu()

    def select_fighters_to_battle(self):
        possible_fighters = list(self.__fighters_DAO.get_all()).copy()
        selected_fighters = []

        for i in range(3):
            fighter_selected = self.select_fighter(possible_fighters)

            selected_fighters.append(fighter_selected)
            possible_fighters.remove(fighter_selected)

        return selected_fighters

    def select_fighter(self, fighters):
        fighters_list = []
        for fighter in fighters:
            fighters_list.append(fighter.name+'\n'+'Attack - '+str(fighter.attack.power)+' power \n'+'Defense - '+str(fighter.defense.power)+' power \n Life '+str(fighter.life)+'/100')

        number_selected = self.__fighter_view.screen_select_fighter(fighters_list)

        if number_selected == -1:
            self.fighter_menu()

        fighter_selected = list(fighters)[number_selected]

        return fighter_selected

    def edit_fighter(self):
        fighter = self.select_fighter(self.__fighters_DAO.get_all())
        new_name = self.__fighter_view.edit_name_fighter(fighter.name)
        self.__game_controller.append_to_history(fighter.name + ' has changed their name to ' + new_name + '.')
        fighter.name = new_name

        self.__fighters_DAO.update(fighter)

        fighter_data = {'fighter_number': 'Stats',
                            'fighter_name':fighter.name,
                            'attack_name':fighter.attack.name,
                            'attack_power':fighter.attack.power,
                            'defense_name':fighter.defense.name,
                            'defense_power':fighter.defense.power,
                            'life':fighter.life}

        self.__fighter_view.show_fighter_data(fighter_data)
        self.fighter_menu()

    def sell_fighter(self):
        if len(self.__fighters_DAO.get_all()) > 3:
            fighter = self.select_fighter(self.__fighters_DAO.get_all())
            self.__game_controller.append_to_history(fighter.name + ' was sold.')

            self.__fighters_DAO.remove(fighter.id)
            self.__game_controller.player.add_coins(15)
            self.fighter_menu()
        else:
            self.__fighter_view.show_message('you must have at least 3 fighters on your account!')
            self.fighter_menu()

    def buy_new_fighter(self):
        if self.__game_controller.player.coin_balance >= 20:

            fighter_data = self.__fighter_view.buy_new_fighter()
            fighter_skills = self.random_fighter_skills()

            fighter = Fighter(fighter_data['fighter_name'],
                              fighter_data['attack_name'],
                              fighter_skills['attack'],
                              fighter_data['defense_name'],
                              fighter_skills['defense'],
                              100)

            self.__game_controller.player.remove_coins(20)

            self.__fighters_DAO.add(fighter)

            fighter_data = {'fighter_number': 'Stats',
                            'fighter_name':fighter.name,
                            'attack_name':fighter.attack.name,
                            'attack_power':fighter.attack.power,
                            'defense_name':fighter.defense.name,
                            'defense_power':fighter.defense.power,
                            'life':fighter.life}

            self.__game_controller.append_to_history(fighter.name + ' was bought.')
            self.__fighter_view.show_fighter_data(fighter_data)
            self.fighter_menu()
        else:
            self.__fighter_view.show_message('you dont have enough coins!')
            self.fighter_menu()

    def improve_fighter_skill(self):
        if self.__game_controller.player.coin_balance >= 5:
            fighter = self.select_fighter(self.__fighters_DAO.get_all())
            option = self.__fighter_view.show_improve_skill_menu()

            self.__game_controller.append_to_history('5 coins spent.')
            if option == 1:
                fighter.attack.increase_power()
                text = fighter.name + '\'s ' + fighter.attack.name + ' increased by 3 points.'
            else:
                fighter.defense.increase_power()
                text = fighter.name + '\'s ' + fighter.defense.name + ' increased by 3 points.'
            self.__game_controller.append_to_history(text)

            self.__fighters_DAO.update(fighter)

            self.__game_controller.player.remove_coins(5)

            fighter_data = {'fighter_number': 'Stats',
                            'fighter_name':fighter.name,
                            'attack_name':fighter.attack.name,
                            'attack_power':fighter.attack.power,
                            'defense_name':fighter.defense.name,
                            'defense_power':fighter.defense.power,
                            'life':fighter.life}

            self.__fighter_view.show_fighter_data(fighter_data)
            self.fighter_menu()
        else:
            self.__fighter_view.show_message('you dont have enough coins!')
            self.fighter_menu()

    def complete_fighter_life(self):
        if self.__game_controller.player.coin_balance >= 10:
            fighter = self.select_fighter(self.__fighters_DAO.get_all())
            fighter.complete_life()

            self.__fighters_DAO.update(fighter)

            self.__game_controller.player.remove_coins(10)

            fighter_data = {'fighter_number': 'Stats',
                            'fighter_name':fighter.name,
                            'attack_name':fighter.attack.name,
                            'attack_power':fighter.attack.power,
                            'defense_name':fighter.defense.name,
                            'defense_power':fighter.defense.power,
                            'life':fighter.life}

            self.__fighter_view.show_fighter_data(fighter_data)

            self.__game_controller.append_to_history('10 coins spent.')
            self.__game_controller.append_to_history(fighter.name + '\'s life completely recovered!')
            self.fighter_menu()
        else:
            self.__fighter_view.show_message('you dont have enough coins!')
            self.fighter_menu()

    def return_to_main_menu(self):
        self.__game_controller.open_screen()

    def generate_starting_fighters(self):
        generated_fighters = []

        for num in range(1,4):
            random_skills = self.random_fighter_skills()
            attack_power = random_skills['attack']
            defense_power = random_skills['defense']
            fighter = Fighter('Fighter '+str(num), 'Attack', attack_power, 'Defense', defense_power, 100)
            generated_fighters.append(fighter)
            self.__fighters_DAO.add(fighter)

            self.__fighters = generated_fighters.copy()

        return generated_fighters

    def random_fighter_skills(self):
        skill_range = random.randint(1, 100)
        random_attack = 0
        random_defense = 0
        if skill_range <= 60:
            random_attack = random.randint(10, 40)
            random_defense = random.randint(10, 40)
        elif skill_range <= 85:
            random_attack = random.randint(41, 50)
            random_defense = random.randint(41, 50)
        elif skill_range <= 95:
            random_attack = random.randint(51, 80)
            random_defense = random.randint(51, 80)
        else :
            random_attack = random.randint(81, 100)
            random_defense = random.randint(81, 100)

        return {'attack':random_attack,'defense': random_defense}

    def fighter_menu(self):
        options_list = {1: self.see_all_fighters, 2: self.edit_fighter, 3: self.sell_fighter,
                        4: self.buy_new_fighter, 5: self.improve_fighter_skill, 6: self.complete_fighter_life,
                        7: self.return_to_main_menu}
        chosen_option = self.__fighter_view.show_fighter_menu()
        chosen_function = options_list[chosen_option]
        chosen_function()

    def save_multiples(self, fighters):
        for fighter in fighters:
            self.__fighters_DAO.update(fighter)


from django.contrib import admin
from django.urls import path

from control_estudios.views import listar_estudiantes,listar_cursos,listar_profesores,\
    crear_curso,añadir_estudiante,añadir_profesor,buscar_cursos,buscar_estudiante,buscar_profesor,eliminar_curso,\
    eliminar_profesor, eliminar_estudiante,editar_curso, editar_profesor,editar_estudiante, ver_estudiante, ver_profesor, ver_curso

urlpatterns = [
    path("estudiantes/", listar_estudiantes, name="lista_estudiantes"),
    path("nuevo-estudiante/", añadir_estudiante, name="nuevo_estudiante"),
    path("buscar-estudiante/", buscar_estudiante, name="buscar_estudiante"),
    path("eliminar-estudiante/<int:id>/", eliminar_estudiante, name="eliminar_estudiante"),
    path("editar-estudiante/<int:id>/", editar_estudiante, name="editar_estudiante"),
    path("estudiantes/<int:id>/", ver_estudiante, name="ver_estudiante"),

    path("profesores/", listar_profesores, name="lista_profesores"),
    path("nuevo-profesor/", añadir_profesor, name="nuevo_profesor"),
    path("buscar-profesor/", buscar_profesor, name="buscar_profesor"),
    path("eliminar-profesor/<int:id>/", eliminar_profesor, name="eliminar_profesor"),
    path('editar-profesor/<int:id>/', editar_profesor, name="editar_profesor"),
    path("profesores/<int:id>/", ver_profesor, name="ver_profesor"),

    path("cursos/", listar_cursos, name="lista_cursos"),
    path("crear-curso/", crear_curso, name="crear_curso"),
    path("buscar-cursos/", buscar_cursos, name="buscar_cursos"),
    path("eliminar-curso/<int:id>/", eliminar_curso, name="eliminar_curso"),
    path('editar-curso/<int:id>/', editar_curso, name="editar_curso"),
    path("cursos/<int:id>/", ver_curso, name="ver_curso"),

]


import random

#part c
def aveScore(list):
    sum = 0
    for item in list:
        sum += item[2]
    avgScore = sum/len(list)
    return avgScore

#part d
def sortLst(list):
    ascSort=sorted(list,key = lambda x: (x[0],-x[1],x[2]))
    return ascSort

def main():
    #initialize list
    nameLst = ['Kevin', 'Ada', 'Jenny', 'Ada', 'Betty', 'Sam', 'Kevin', 'Betty', 'Ada', 'Terry', 'Nathan', 'Jenny']
    scores = [80, 75, 68, 95, 85, 76, 78, 88, 92, 84, 82, 86]

    #part a
    ageLst = [random.randint(18,25) for x in range(len(nameLst))]
    list1 = list(zip(nameLst,ageLst))
    print("Part A :",list1)
    #part b
    profile = list(zip(nameLst,ageLst,scores))
    print("Part B:",profile)
    #run part c
    print("Average score:",aveScore(profile))
    #run part d
    print("Part D:",sortLst(profile))
main()
'''Output
Part A : [('Kevin', 25), ('Ada', 21), ('Jenny', 23), ('Ada', 23), ('Betty', 22), ('Sam', 24), ('Kevin', 23), ('Betty', 21), ('Ada', 23), ('Terry', 23), ('Nathan', 19), ('Jenny', 18)]
Part B: [('Kevin', 25, 80), ('Ada', 21, 75), ('Jenny', 23, 68), ('Ada', 23, 95), ('Betty', 22, 85), ('Sam', 24, 76), ('Kevin', 23, 78), ('Betty', 21, 88), ('Ada', 23, 92), ('Terry', 23, 84), ('Nathan', 19, 82), ('Jenny', 18, 86)]
Average score: 22.083333333333332
Part D: [('Ada', 23, 92), ('Ada', 23, 95), ('Ada', 21, 75), ('Betty', 22, 85), ('Betty', 21, 88), ('Jenny', 23, 68), ('Jenny', 18, 86), ('Kevin', 25, 80), ('Kevin', 23, 78), ('Nathan', 19, 82), ('Sam', 24, 76), ('Terry', 23, 84)]'''


#https://docs.opencv.org/4.5.3/d6/d00/tutorial_py_root.html
#https://docs.opencv.org/4.5.3/dd/d43/tutorial_py_video_display.html "Playing Video from file "

from __future__ import print_function

import argparse
import numpy as np
import cv2

import matplotlib.pyplot as plt

def computeMSE(prev, curr):
    assert(curr.shape == prev.shape)
    h, w = curr.shape[:2]
    return np.sum(np.square(curr.astype(np.int32) - prev.astype(np.int32))) / (h * w)

def computeMSE_test():
    black = np.zeros([10, 10])
    white = np.ones([10, 10]) * 255

    assert(computeMSE(black, black) == 0.0)
    assert(computeMSE(white, white) == 0.0)
    assert(computeMSE(white, black) == np.square(255))
    print("MSE test passed!")

def computePSNR(mse):
    if mse <= 0 :
        return 0
    return 10 * np.log10(np.square(255) / mse)

def computePSNR_test(): # assumes that computeMSE works correctly
    black = np.zeros([10, 10])
    white = np.ones([10, 10]) * 255
    assert(computePSNR(computeMSE(white, black)) == 0.0)
    print("PSNR test passed!")

def computeEntropy(img):
    hist, _ = np.histogram(img, 256, [0, 255])
    p = hist / img.size # probability histogram
    return -np.sum(p * np.log2(p, where=p!= 0))

def computeEntropy_test():
    assert(computeEntropy(np.zeros([10, 10])) == 0.0)
    img = np.concatenate((np.zeros([5, 5]), np.ones([5, 5])))
    assert(computeEntropy(img) == 1.0)
    print("Entropy test passed!")

def computeErrorImage(im1, im2):
    return np.minimum(255, np.maximum(0, im1 - im2 + 128))
    # return im1

def computeOpticalFlow1(prev, curr):
    flow = cv2.calcOpticalFlowFarneback(curr, prev, flow=None, pyr_scale=0.5, levels=3, winsize=20, iterations=15, poly_n=5, poly_sigma=1.2, flags=cv2.OPTFLOW_FARNEBACK_GAUSSIAN)
    return flow

def computeCompensatedFrame(prev, flow):
    h, w = flow.shape[:2]
    map = flow.copy()
    map[:,:,0] += np.arange(w)
    map[:,:,1] += np.arange(h)[:,np.newaxis]
    res = cv2.remap(prev, map, None, cv2.INTER_LINEAR)
    return res

def computeGME(flow): #flow = vecteurs de déplacement
    src = np.zeros_like(flow)
    h, w = flow.shape[:2]
    c = np.array([w/2, h/2])
    src[:,:,0] += np.arange(w)
    src[:,:,1] += np.arange(h)[:,np.newaxis]
    src -= c;
    srcPts = src.reshape((h*w, 2))

    dst = src + flow
    dstPts = dst.reshape((h*w, 2))
    H, mask = cv2.findHomography(srcPts, dstPts, cv2.RANSAC)
    gme = cv2.perspectiveTransform(src, H) - src
    return gme

def computeGMEError(flow, gme):
    h, w = flow.shape[:2]
    flowX, flowY = np.dsplit(flow, 2)
    gmeX, gmeY = np.dsplit(gme, 2)

    err = np.sqrt(np.square(flowX - gmeX) +
                  np.square(flowY - gmeY))

    return err / np.max(err)

def draw_flow(img, flow, step=16):
    h, w = img.shape[:2]
    y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)
    fx, fy = flow[y,x].T
    lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
    lines = np.int32(lines + 0.5)
    vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    cv2.polylines(vis, lines, 0, (0, 255, 0))
    for (x1, y1), (_x2, _y2) in lines:
        cv2.circle(vis, (x1, y1), 1, (0, 255, 0), -1)
    return vis

if __name__=='__main__':

    # computeMSE_test()
    # computePSNR_test()
    # computeEntropy_test()
    # assert False

    parser = argparse.ArgumentParser(description='Read video file')
    parser.add_argument('video', help='input video filename')
    parser.add_argument('deltaT', help='input deltaT between frames', type=int)

    args = parser.parse_args()

    cap = cv2.VideoCapture(args.video)

    if (cap.isOpened() == False):
        print("ERROR: unable to open video: "+args.video)
        quit()

    deltaT=args.deltaT

    previousFrames=[]
    frameNumbers = []
    mses = []
    psnrs = []
    mse0s = []
    psnr0s = []
    ents = []
    entEs = []

    i=0
    while(cap.isOpened()):
        ret, frame = cap.read()

        if (ret==False):
            break

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        if (len(previousFrames) >= deltaT):
            prev = previousFrames.pop(0)

            flow = computeOpticalFlow1(prev, gray)

            compensatedFrame = computeCompensatedFrame(prev, flow)

            #cv2.imshow('compensated', compensatedFrame)

            imErr0 = computeErrorImage(prev, gray)
            imErr = computeErrorImage(compensatedFrame, gray)

            # cv2.imshow('imErr0', imErr0)
            # cv2.imshow('imErr', imErr)

            mse0 = computeMSE(prev, gray)
            psnr0 = computePSNR(mse0)
            mse = computeMSE(compensatedFrame, gray)
            psnr = computePSNR(mse)
            ent = computeEntropy(gray)
            entE = computeEntropy(imErr)

            frameNumbers.append(i)
            mses.append(mse)
            psnrs.append(psnr)
            mse0s.append(mse0)
            psnr0s.append(psnr0)
            ents.append(ent)
            entEs.append(entE)

            gme = computeGME(flow)

            gmeError = computeGMEError(flow, gme)

            # cv2.imshow('flow', draw_flow(gray, flow))
            # cv2.imshow('gme', draw_flow(gray, gme))
            # cv2.imshow('gmeError', gmeError)

        previousFrames.append(gray.copy())
        i+=1

        # cv2.imshow('frame', gray)

        cv2.waitKey(1)

    plt.plot(frameNumbers, mse0s, label='MSE0')
    plt.plot(frameNumbers, mses, label='MSE')
    plt.xlabel('frames')
    plt.ylabel('MSE')
    plt.legend()
    plt.title('MSE0 vs MSE')
    plt.savefig("mse.png")
    # plt.show()
    plt.cla()

    plt.plot(frameNumbers, ents, label='Entropy)')
    plt.plot(frameNumbers, entEs, label='EntropyE')
    plt.xlabel('frames')
    plt.ylabel('Entropy')
    plt.legend()
    plt.title('Entropy vs EntropyE')
    plt.savefig("entropy.png")
    # plt.show()
    plt.cla()

    plt.plot(frameNumbers, psnr0s, label='PSNR0')
    plt.plot(frameNumbers, psnrs, label='PSNR')
    plt.xlabel('frames')
    plt.ylabel('PSNR')
    plt.legend()
    plt.title('PSNR0 vs PSNR')
    plt.savefig("psnr.png")
    # plt.show()
    plt.cla()

    cap.release()
    cv2.destroyAllWindows()


# -*- coding: utf-8 -*-
"""
Created on Mon Oct 18 18:09:38 2021

@author: Oscar
"""
i1 = input("Enter the scores file: ")
print (i1)
i2 = input("Enter the output file: ")
print (i2)

ls = []
j = 0

f = open ("{}".format(i1))
f1 = (f.read().split('\n'))

for i in f1:
    if i != "":
        ls.append(int(i))

ls.sort()

f.close()
f = open ("{}".format(i2),"w")
for i in ls:
    f.write("{0:>2}: {1:>3}\n".format(j, i))
    j += 1


punct = ",!?"

fd = open("text.txt")

for line in fd:

    for char in punct:

        if char in line:

            line = line.replace(char, "")

    word = line.split()

    longest = ""

    for words in word:

        if len(word)> len(longest):
            longest = words

print(longest)


""" Travel Inspiration - CSSE1001 - Assignment 1

A travel recommendation program. The user will be given a questionaire that
matches their travel preferences to the 'destination' database to return the
best match for the user.
"""

__author__ = "Tean-louise McGrath (42637460)"
__date__ = "29.03.19"

from destinations import Destinations

def get_user_preference(question, valid_range):
    """ Ask the user a question about their travel preference and return the
    input as a string. Also, check if input is valid.

    Paramaters:
        question (str): Question to print for travel preference paramater
        valid_range (list): List of strings that are valid inputs. Each
        preference has unique range.

    Variables:
        user_input (str): Input from user in response to question

    Return:
        str: Return of input()
    """

    print(question)
    user_input = input("> ")
    print ("")
    while user_input not in valid_range:
        print ("I'm sorry, but ", user_input, " is not a valid choice."
               " Please try again.\n", sep="")
        print (question)
        user_input = input("> ")
        print ("")

    return user_input

def get_user_interest(database_list, user_list):
    """ Ask user a question about how much they like an interest from -5 to 5.
    Loop through lists of interests and store use inputs in new list.

    Paramaters:
        database_list (list): List of interests.
        user_input (list): User inputs stored as int in order of interest list.
    """

    for interest in database_list:
        print ("How much do you like ", interest,"? (-5 to 5)", sep = "")
        user_input = int(input("> "))
        print ("")
        while user_input not in range(-5,6):
            print ("I'm sorry, but ", user_input, " is not a valid choice."
                   " Please try again.\n", sep="")
            print ("How much do you like ", interest,"? (-5 to 5)", sep = "")
            user_input = int(input("> "))
            print ("")
        user_list.append (user_input)

def match_continent(user_input, database_value):
    """ Matches the user's input for 'Continent' with the data from destinations.

    Paramaters:
        user_input (int): User's input when prompted for 'continent' preference.
        database_value (str): Continent name stored in destinations database.

    Variables:
        destination_continent (str): Name of the continent according to the
        user's input to match to database.

    Return:
        bool: Destination is match (True), if and only if, the destination of
        the continent is an exact match for user.
    """

    if user_input==1:
        destination_continent = "asia"
    elif user_input==2:
        destination_continent = "africa"
    elif user_input==3:
        destination_continent = "north america"
    elif user_input==4:
        destination_continent = "south america"
    elif user_input==5:
        destination_continent = "europe"
    elif user_input==6:
        destination_continent = "oceania"
    elif user_input==7:
        destination_continent = "antarctica"

    # Return True if user input matches database value, else False
    return (database_value == destination_continent)

def match_cost(user_input, database_value):
    """ Match the user's input for 'cost' with the data from the database.
    Convert string inputs of user and database to integers to compare.

    Paramaters:
        user_input (str): User's input when prompted for 'cost' preference.
        database_value (str): Cost of destination stored in database.

    Variables:
        user_cost_int (int): Converts the users string input to int.
        destination_cost_int (int): Converts the database string values to int.

    Return:
        bool: Destination is match (True) if the 'cost' of the destination in
        the database is less than or equal to the user's input.
    """

    if user_input=="$$$":
        user_cost_int = 3
    elif user_input=="$$":
        user_cost_int = 2
    elif user_input=="$":
        user_cost_int = 1

    if database_value =="$$$":
        destination_cost_int = 3
    elif database_value =="$$":
        destination_cost_int = 2
    elif database_value =="$":
        destination_cost_int = 1

    # Return True if user input is >= the database value, else False
    return (user_cost_int >= destination_cost_int)

def match_children(user_input, database_value):
    """ Match the user's input for 'kid friendly' with the database.

    Paramaters:
        user_input (int): User's input when prompted for 'kid friendly'
        database_value (bool): Stored in database as True (Yes) or False (No)

    Return:
        bool: True, if the user selects kid friendly (user input 1) and the
        destination is True. Or if user selects no preference (user input 2).
    """

    # User requires kid friendly. Return True if kid friendly, else False
    if user_input == 1:
        return database_value
    # User has no preference. So all countries match, always return True
    else:
        return True

def match_crime(user_input, database_value):
    """ Match the user's input for 'crime' with database.

    Paramaters:
        user_input (int): User's input when prompted for 'crime' preference.
        database_value (str): String value of crime level in database.
    Variables:
        destination_crime (int): Converts the database string values to int.

    Return:
        bool: Return True if 'crime' value of user input >= database value.
    """

    if database_value == "low":
        destination_crime = 1
    elif database_value == "average":
        destination_crime = 2
    elif database_value == "high":
        destination_crime = 3

    # Return True if user input >= database value, else False
    return user_input >= destination_crime

def match_climate (user_input,database_value):
    """ Match the user's input for 'climate' with the database.

    Paramaters:
        user_input (int): User's input when prompted for 'climate' preference.
        database_value (str): Climate description name stored in database.

    Variables:
        destination_climate (int): Converts the database string values to int.

    Return:
        bool: Return True if 'climate' value in database matches the user input.
    """

    if database_value == "cold":
        destination_climate = 1
    elif database_value== "cool":
        destination_climate = 2
    elif database_value == "moderate":
        destination_climate = 3
    elif database_value == "warm":
        destination_climate = 4
    elif database_value == "hot":
        destination_climate = 5

    # Return True if user input matches database value, else False
    return user_input == destination_climate

def match_season (user_input):
    """ Match the user's input for 'season' with the corresponding string name.

    Paramaters:
        user_input (int): User's input when prompted for 'season' preference.

    Variables:
        destination_season (str): Store season name according to user input.

    Return:
        str: The season name corresponding to user input.
    """

    if user_input == 1:
        destination_season = "spring"
    elif user_input == 2:
        destination_season = "summer"
    elif user_input == 3:
        destination_season = "autumn"
    elif user_input == 4:
        destination_season = "winter"

    # Return string name of season
    return destination_season

def match_interest (user_input, dest):
    """ Match the user's input for 'interest' with the destination value.

    Paramaters:
        user_input (list): List of user's input according to each interest.
        Each interest value in list stored as float in order.
        dest (Destination): Destination being checked from database.

    Variables:
        sports_score (float): user input for 'sports' * database score
        [same for wildlife, nature, historical, cuisine, adventure, beach]

    Return:
        float: The sum of all of the interests scores.
    """

    # Get the value of each interest from the database.
    # Interest score = user input * database value
    sports_score = user_input[0] * dest.get_interest_score("sports")
    wildlife_score = user_input[1] * dest.get_interest_score("wildlife")
    nature_score = user_input[2] * dest.get_interest_score("nature")
    historical_score = user_input[3] * dest.get_interest_score("historical")
    cuisine_score = user_input[4] * dest.get_interest_score("cuisine")
    adventure_score = user_input[5] * dest.get_interest_score("adventure")
    beach_score = user_input[6] * dest.get_interest_score("beach")

    # Return sum of all the interest scores
    return (sports_score + wildlife_score + nature_score + historical_score +
            cuisine_score + adventure_score + beach_score)

def main():
    """ Logic for Travel program. The user will be asked a number of questions
    and an exact match (or None) will be returned based on parameters.

    Variables:
        final_match (bool): Exact match based on parameters. Start as FALSE.
        greatest_score (int): Value start at -200 (min score for any destination)
        user_xxx (misc): User input for each question.
        interest_score (int): Sum of all interest scores for destination.
        season_factor (float): Season factor of destination based on user input.
        destination_score (float): Total score is interest score * season factor.

    Return:
        Destination name:  if match for continent, kid friendly, cost, crime and
        climate. The destination will have the greatest destination score.
        OR "None" if no match.
    """

    #INTRODUCTION - Welcome and name
    print ("Welcome to Travel Inspiration!\n")
    user_name = input("What is your name? ")
    print ("\nHi, ", user_name, "!\n", sep="")

    #TRAVEL PREFERENCE INPUTS - Continent, Money, Children, Season, Climate
    user_continent = int(get_user_preference("Which continent would you like to travel to?\n"
        "  1) Asia\n  2) Africa\n  3) North America\n  4) South America\n  5) Europe\n"
        "  6) Oceania\n  7) Antarctica", ["1","2","3","4","5","6","7"]))
    user_cost = get_user_preference("What is money to you?\n"
        "  $$$) No object\n  $$) Spendable, so long as I get value from doing so\n"
        "  $) Extremely important; I want to spend as little as possible", ["$$$", "$$","$"])
    user_crime = int(get_user_preference("How much crime is acceptable when you travel?\n"
        "  1) Low\n  2) Average\n  3) High", ["1","2","3"]))
    user_children = int(get_user_preference("Will you be travelling with children?\n"
        "  1) Yes\n  2) No", ["1","2"]))
    user_season = float(get_user_preference("Which season do you plan to travel in?\n"
        "  1) Spring\n  2) Summer\n  3) Autumn\n  4) Winter", ["1","2","3","4"]))
    user_climate = int(get_user_preference("What climate do you prefer?\n"
        "  1) Cold\n  2) Cool\n  3) Moderate\n  4) Warm\n  5) Hot", ["1","2","3","4","5"]))

    # INTEREST INPUTS - Sports, wildlife, nature, historical, cuisine, adventure, beach
    print ("Now we would like to ask you some questions about your interests,"
        " on a scale of -5 to 5. -5 indicates strong dislike, whereas 5 indicates"
        " strong interest, and 0 indicates indifference.\n")
    destination_interests = ["sports", "wildlife", "nature", "historical sites",
                            "fine dining", "adventure activities", "the beach"]
    user_interests = []
    get_user_interest(destination_interests, user_interests)

    # CHECK PARAMETERS
    greatest_score = -200 # Any matching destination will have a higher score.
    final_match = False # Set default to false

    for destination in Destinations().get_all():
        # For each destination run through parameters based on user inputs.
        if match_continent(user_continent, destination.get_continent()):
            if match_children(user_children, destination.is_kid_friendly()):
                if match_cost (user_cost, destination.get_cost()):
                    if match_crime (user_crime, destination.get_crime()):
                        if match_climate (user_climate,destination.get_climate()):
                            # All the user inputs match the current destination.
                            # At least one final match will be returned.
                            # Now calculate destination score.
                            # Determine season factor and interest score.
                            season_factor = destination.get_season_factor(match_season(user_season))
                            interest_score = match_interest(user_interests, destination)
                            destination_score = interest_score * season_factor

                            # Name and greatest destination score will be stored.
                            if destination_score > greatest_score:
                                greatest_score = destination_score
                                final_match_name = destination.get_name()
                                final_match = True

    #FINAL OUTPUT:
    print("Thank you for answering all our questions."
          " Your next travel destination is:", sep="\n")
    if final_match == True:
        print (final_match_name)
    else:
        print ("None")

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

""" Constants for module"""

FRAME_DIR = '/media/nina/Seagate Backup Plus Drive/hockey/frames'
MASK_DIR = '/media/nina/Seagate Backup Plus Drive/hockey/masks'
TEMPLATE_FRAME = '{:d}.png'
TEMPLATE_MASK = 'mask{:d}.png'
TEMPLATE_IMAGE = '{}.png'
VIDEO_DIR = '/media/nina/Seagate Backup Plus Drive/hockey/processed_video/'
TEMPLATE_VIDEO = "cska_akbars_cam_3_{:d}_{:d}.avi"
VIDEO_FRAME_SIZE = 1200

CLASSIFY_PATH = './classifying'
""" PATH WITH PRETRAINED player_clf.pkl, buckets.pkl """
CLASSIFY_DATA_PATH = '../data/classify'
CLASSIFIER_H, CLASSIFIER_W = (64, 32)

""" Constants for filtering blobs """

BLOB_MIN_HEIGHT = 70
BLOB_MAX_HEIGHT = 190
BLOB_MIN_WIDTH = 40
BLOB_MAX_WIDTH = 120

FIELD_X = 0
FIELD_Y = 0
FIELD_H = 820
FIELD_W = 5700


from sys import stdin
def num_flies(i, j):
	s = 0
	for k in range(i+1, i+racket-1):
		s += window[k][j+1:j+racket-1].count("*")
	return s

def draw_racket(mx, my):
	window[mx][my] = "+"
	window[mx][my+racket-1] = "+"
	window[mx+racket-1][my] = "+"
	window[mx+racket-1][my+racket-1] = "+"
	for i in range(my+1, my+racket-1):
		window[mx][i] = "-"
		window[mx+racket-1][i] = "-"
	for i in range(mx+1, mx+racket-1):
		window[i][my] ="|"
		window[i][my+racket-1] = "|"

x, y, racket = [int(x) for x in stdin.readline().split()]
window = [0]*x
for i in range(0, x):
	window[i] = list(stdin.readline().strip())

m, mx, my = 0, 0, 0
i = 0
while i <= x - racket:
	j = 0
	while j <= y - racket:
		tmp = num_flies(i, j)
		if tmp > m:
			m, mx, my = tmp, i, j
		j += 1
	i += 1

print(m)
draw_racket(mx, my)
for line in window:
	print("".join(list(map(str, line))))