from gevent.event import AsyncResult
from raidex import messages
from raidex.signing import Signer
from raidex.raidex_node.offer_book import OfferDeprecated
from raidex.raidex_node.order.offer import OfferType
from raidex.utils import timestamp

class Swap(object):

    def __init__(self, maker_instance):
        self._maker = maker_instance
        self._taker = None
        self._maker_executed = False
        self._taker_executed = False

    def try_take(self, cs_instance):
        if self._taker is None:
            self._taker = cs_instance
            return True
        return False

    @property
    def is_completed(self):
        # no timeout comparison
        return self._maker_executed and self._taker_executed

    @property
    def is_taken(self):
        return (self._maker is not None) and (self._taker is not None)

    def report_executed(self, cs_instance):
        if self.is_completed:
            return False
        if not self._taker:
            return False
        if cs_instance not in (self._maker, self._taker):
            return False
        if cs_instance is self._maker:
            self._maker_executed = True
            return True
        if cs_instance is self._taker:
            self._taker_executed = True
            return True

class CommitmentServiceGlobal(object):
    """
    Serves as the brain of the CS-Server, that keeps track of all the reported swaps
    """
    def __init__(self, signer=None):
        if signer is None:
            signer = Signer()
        self.signer = signer
        self.swaps = {}

    @property
    def address(self):
        return self.signer.address

    def make_offer(self, commitment_service_client, offer_id):
        if offer_id in self.swaps:
            return False
        self.swaps[offer_id] = Swap(commitment_service_client)
        return True

    def try_take_offer(self, commitment_service_client, offer_id):
        swap = self.swaps.get(offer_id)
        if swap is None:
            return False
        success = swap.try_take(commitment_service_client)
        return success

    def report_swap_executed(self, commitment_service_client, offer_id):
        swap = self.swaps.get(offer_id)
        if swap is None:
            return False
        success = swap.report_executed(commitment_service_client)
        return success

    def swap_is_completed(self, offer_id):
        swap = self.swaps.get(offer_id)
        if swap is None:
            return False
        if swap.is_completed:
            return True
        else:
            return False

class NonFailingCommitmentServiceGlobal(object):
    """
    Replacement of CommitmentServiceGlobal
    This has no inherent logic and always returns True for all methods.
    This makes sense to use, when no Taker/Maker matchmaking logic should be present
    and the CommitmentService Clients are only being used to construct and broadcast the
    correct messages, signed by the CS.
    """
    def __init__(self, signer=None):
        if signer is None:
            signer = Signer.random()
        self.signer = signer

    @property
    def address(self):
        return self.signer.address

    def make_offer(self, commitment_service_client, offer_id):
        return True

    def try_take_offer(self, commitment_service_client, offer_id):
        return True

    def report_swap_executed(self, commitment_service_client, offer_id):
        return True

    def swap_is_completed(self, offer_id):
        return True

class CommitmentServiceClientMock(object):
    """Mock for the CommitmentService
    Has the same interface as the CommitmentService client, but also includes the mocked CS-Node behaviour

    At the moment just creates the messages that you would get for a proper commitment.
    Every raidex node has its own with the same key
    """
    _commitment_service_global = NonFailingCommitmentServiceGlobal()

    def __init__(self, node_signer, token_pair, message_broker, fee_rate=0.1, commitment_service_global=None):
        if commitment_service_global is not None:
            self._commitment_service_global = commitment_service_global
        self._global_sign = self._commitment_service_global.signer.sign
        self.commitment_service_address = self._commitment_service_global.address
        self.node_address = node_signer.address
        self.token_pair = token_pair
        self._sign = node_signer.sign
        self.fee_rate = fee_rate
        self.message_broker = message_broker

    def maker_commit_async(self, offer):
        # type: (OfferDeprecated) -> AsyncResult
        result = AsyncResult()
        success = self._commitment_service_global.make_offer(self, offer.offer_id)
        if success is False:
            result.set(None)
            return result
        offer_msg = self.create_offer_msg(offer)
        commitment_msg = messages.Commitment(offer.offer_id, offer_msg.hash, offer.timeout_date, 42)
        self._sign(commitment_msg)

        commitment_proof_msg = messages.CommitmentProof(commitment_msg.signature)
        self._global_sign(commitment_proof_msg)
        proven_offer_msg = messages.ProvenOffer(offer_msg, commitment_msg, commitment_proof_msg)
        self._sign(proven_offer_msg)
        result.set(proven_offer_msg)
        return result

    def taker_commit_async(self, offer):
        # type: (OfferDeprecated) -> AsyncResult
        result = AsyncResult()
        success = self._commitment_service_global.try_take_offer(self, offer.offer_id)
        if success is False:
            result.set(None)
            return result
        offer_msg = self.create_offer_msg(offer)
        commitment_msg = messages.TakerCommitment(offer.offer_id, offer_msg.hash, offer.timeout_date, 42)
        self._sign(commitment_msg)
        commitment_proof_msg = messages.CommitmentProof(commitment_msg.signature)
        self._global_sign(commitment_proof_msg)
        proven_commitment_msg = messages.ProvenCommitment(commitment_msg, commitment_proof_msg)
        self._sign(proven_commitment_msg)
        result.set(proven_commitment_msg)
        self.message_broker.broadcast(self.create_taken(offer.offer_id))
        return result

    def create_taken(self, offer_id):
        # type: (int) -> OfferTaken
        offer_taken_msg = messages.OfferTaken(offer_id)
        self._global_sign(offer_taken_msg)
        return offer_taken_msg

    def create_swap_completed(self, offer_id):
        # type: (int) -> SwapCompleted
        swap_completed_msg = messages.SwapCompleted(offer_id, timestamp.time())
        self._global_sign(swap_completed_msg)
        return swap_completed_msg

    def create_offer_msg(self, offer):
        # type: (OfferDeprecated) -> OfferMsg
        if offer.type == OfferType.SELL:
            return messages.SwapOffer(self.token_pair.quote_token, offer.quote_amount, self.token_pair.base_token,
                                      offer.base_amount, offer.offer_id, offer.timeout_date)
        else:
            return messages.SwapOffer(self.token_pair.base_token, offer.base_amount, self.token_pair.quote_token,
                                      offer.quote_amount, offer.offer_id, offer.timeout_date)

    def report_swap_executed(self, offer_id):
        # type: (int) -> None
        success = self._commitment_service_global.received_inbound_from_swap(self, offer_id)
        if success is True and self._commitment_service_global.swap_is_completed(offer_id):
            swap_completed_msg = self.create_swap_completed(offer_id)
            self.message_broker.broadcast(swap_completed_msg)

    def start(self):
        # in order to provide the same interface as the client.CommitmentService
        # the actual tasks are not running because this is a failsafe mock without CS-interaction
        pass


#!/usr/bin/python3
from smr_calibration_wheel import *
from smr_evaluation_wheel import *
from smr_control_wheel import *
from smr_control_continuous_wheel import *
import sys
import rospy
import rospkg
import os

def get_mode(idx):
	modality={
			0:'smrCalibrationWheel',
			1:'smrEvaluationWheel',
			2:'smrControlWheel',
			3:'SmrControlContinuousWheel'
		}
	return modality.get(idx,"Unexpected protocol index")

def main():
	sys.argv = rospy.myargv(sys.argv)

	rospy.init_node('rosneuro_feedback')
	mode = get_mode(rospy.get_param('~protocol_mode'))

	if mode == 'smrEvaluationWheel':
		o = SmrEvaluationWheel()
	elif mode == 'smrCalibrationWheel':
		o = SmrCalibrationWheel()
	elif mode == 'smrControlWheel':
		o = SmrControlWheel()
	elif mode == 'SmrControlContinuousWheel':
		o = SmrControlContinuousWheel()
	else:
		print('[rosneuro_feedback] Unexpected protocol mode')
		return

	o.run()

if __name__ == '__main__':
	main()


import numpy as np
import torchpack.distributed as dist

__all__ = ['cosine_schedule_with_warmup']

def cosine_schedule_with_warmup(k, num_epochs, batch_size, dataset_size):
    batch_size *= dist.size()

    if dist.size() == 1:
        warmup_iters = 0
    else:
        warmup_iters = 1000 // dist.size()

    if k < warmup_iters:
        return (k + 1) / warmup_iters
    else:
        iter_per_epoch = (dataset_size + batch_size - 1) // batch_size
        ratio = (k - warmup_iters) / (num_epochs * iter_per_epoch)
        return 0.5 * (1 + np.cos(np.pi * ratio))


import pytest
from sqlalchemy.orm import Session

from application.data_access.entity_queries import get_entity_search
from application.db.models import EntityOrm
from application.search.enum import PeriodOption, GeometryRelation
from tests.test_data.wkt_data import handrians_wall_search

@pytest.fixture(scope="module")
def invalid_test_data(apply_migrations, db_session: Session):
    from tests.test_data import invalid_geometry

    entity_models = []
    for entity in invalid_geometry:
        e = EntityOrm(**entity)
        db_session.add(e)
        entity_models.append(e)

    db_session.commit()
    return {"entities": invalid_geometry}

@pytest.fixture(scope="module")
def raw_params():
    return {
        "theme": None,
        "typology": None,
        "dataset": None,
        "organisation": None,
        "organisation_entity": None,
        "entity": None,
        "curie": None,
        "prefix": None,
        "reference": None,
        "related_entity": None,
        "entries": PeriodOption.all,
        "start_date": None,
        "start_date_year": None,
        "start_date_month": None,
        "start_date_day": None,
        "start_date_match": None,
        "end_date": None,
        "end_date_year": None,
        "end_date_month": None,
        "end_date_day": None,
        "end_date_match": None,
        "entry_date": None,
        "entry_date_year": "",
        "entry_date_month": "",
        "entry_date_day": "",
        "entry_date_match": None,
        "longitude": None,
        "latitude": None,
        "geometry": None,
        "geometry_entity": None,
        "geometry_reference": None,
        "geometry_relation": None,
        "limit": 10,
        "offset": None,
        "suffix": None,
        "field": None,
    }

@pytest.fixture()
def params(raw_params):
    return raw_params.copy()

def test_search_geometry_reference_excludes_invalid_data(invalid_test_data, params):
    invalid = [
        int(entity["entity"])
        for entity in invalid_test_data["entities"]
        if "invalid" in entity["name"]
    ]
    valid = [
        int(entity["entity"])
        for entity in invalid_test_data["entities"]
        if "invalid" not in entity["name"]
    ]
    params["geometry_reference"] = ["E07000004"]
    result = get_entity_search(params)
    for e in result["entities"]:
        assert e.entity not in invalid
        assert e.entity in valid

def test_search_by_dataset_and_lasso_excludes_invalid_geometry(
    invalid_test_data, params
):
    params["dataset"] = ["world-heritage-site"]
    params["geometry_relation"] = GeometryRelation.intersects.name
    params["geometry"] = [handrians_wall_search]
    result = get_entity_search(params)
    assert 0 == result["count"]
    assert 0 == len(result["entities"])


from typing import Set
from typing import Union

import numpy as np

from netin.generators.undirected import UnDiGraph
from netin.utils import constants as const

class PA(UnDiGraph):
    """Creates a new PA instance. An undirected graph with preferential attachment.

    Parameters
    ----------
    n: int
        number of nodes (minimum=2)

    k: int
        minimum degree of nodes (minimum=1)

    f_m: float
        fraction of minorities (minimum=1/n, maximum=(n-1)/n)

    seed: object
        seed for random number generator

    Notes
    -----
    The initialization is an undirected graph with n nodes and no edges.
    Then, everytime a node is selected as source, it gets connected to k target nodes.
    Target nodes are selected via preferential attachment (in-degree), see [BarabasiAlbert1999]_.
    """

    ############################################################
    # Constructor
    ############################################################

    def __init__(self, n: int, k: int, f_m: float, seed: object = None):
        super().__init__(n, k, f_m, seed)

    ############################################################
    # Init
    ############################################################

    def _infer_model_name(self):
        """
        Infers the name of the model.
        """
        return self.set_model_name(const.PA_MODEL_NAME)

    ############################################################
    # Generation
    ############################################################

    def get_target_probabilities(self, source: Union[None, int], target_set: Union[None, Set[int]],
                                 special_targets: Union[None, object, iter] = None) -> tuple[np.array, set[int]]:
        """
        Returns the probabilities of the target nodes to be selected given a source node.
        This probability is proportional to the degree of the target node.

        Parameters
        ----------
        source: int
            source node (id)

        target_set: set
            set of target nodes (ids)

        special_targets: object
            special targets

        Returns
        -------
        probs: np.array
            probabilities of the target nodes to be selected

        target_set: set
            set of target nodes (ids)
        """
        probs = np.array([(self.degree(target) + const.EPSILON) for target in target_set])
        probs /= probs.sum()
        return probs, target_set

    def _makecopy(self):
        """
        Makes a copy of the current object.
        """
        return self.__class__(n=self.n,
                              k=self.k,
                              f_m=self.f_m,
                              seed=self.seed)

    @staticmethod
    def fit(g, n=None, k=None, seed=None):
        """
        It fits the PA model to the given graph.

        Parameters
        ----------
        g: netin.UnDiGraph
            graph to fit the model to

        n: int
            number of nodes to override (e.g., to generate a smaller network)

        k: int
            minimum node degree to override (e.g., to generate a denser network ``k>1``)

        seed: object
            seed for random number generator

        Returns
        -------
        netin.PA
            fitted model
        """
        n = n or g.number_of_nodes()
        k = k or g.calculate_minimum_degree()
        f_m = g.calculate_fraction_of_minority()

        new_g = PA(n=n,
                     k=k,
                     f_m=f_m,
                     seed=seed)
        new_g.generate()

        return new_g


import json
from os import environ
from urllib.parse import urlparse

import auction.wallet as wallet
import requests
from auction.auctioneer import Auctioneer
from auction.log import logger
from auction.outputs import Error, Log, Output
from auction.routing import Router
from auction.util import hex_to_str

logger.info("Auction DApp started")

rollup_server = environ["ROLLUP_HTTP_SERVER_URL"]
network = environ["NETWORK"]
logger.debug(f"Rollup server URL: {rollup_server}")
logger.info(f"Network is {network}")

# Setup contracts addresses
erc20_portal_file = open(f'./deployments/{network}/ERC20Portal.json')
erc20_portal = json.load(erc20_portal_file)

erc721_portal_file = open(f'./deployments/{network}/ERC721Portal.json')
erc721_portal = json.load(erc721_portal_file)

dapp_address_relay_file = open(f'./deployments/{network}/DAppAddressRelay.json')
dapp_address_relay = json.load(dapp_address_relay_file)

router = None

def send_request(output):
    if isinstance(output, Output):
        request_type = type(output).__name__.lower()
        endpoint = request_type
        if isinstance(output, Error):
            endpoint = "report"
            logger.warning(hex_to_str(output.payload))
        elif isinstance(output, Log):
            endpoint = "report"

        logger.debug(f"Sending {request_type}")
        response = requests.post(rollup_server + f"/{endpoint}",
                                 json=output.__dict__)
        logger.debug(f"Received {output.__dict__} status {response.status_code} "
                     f"body {response.content}")
    else:
        for item in output:
            send_request(item)

def handle_advance(data):
    logger.debug(f"Received advance request data {data}")
    try:
        msg_sender = data["metadata"]["msg_sender"]
        payload = data["payload"]

        if msg_sender.lower() == dapp_address_relay['address'].lower():
            logger.debug("Setting DApp address")
            rollup_address = payload
            router.set_rollup_address(rollup_address)
            return Log(f"DApp address set up successfully to {rollup_address}.")

        # It is an ERC20 deposit
        if msg_sender.lower() == erc20_portal['address'].lower():
            try:
                return router.process("erc20_deposit", payload)
            except Exception as error:
                error_msg = f"Failed to process ERC20 deposit '{payload}'. {error}"
                logger.debug(error_msg, exc_info=True)
                return Error(error_msg)
        elif msg_sender.lower() == erc721_portal['address'].lower():
            try:
                return router.process("erc721_deposit", payload)
            except Exception as error:
                error_msg = f"Failed to process ERC721 deposit '{payload}'. {error}"
                logger.debug(error_msg, exc_info=True)
                return Error(error_msg)
        else:
            try:
                str_payload = hex_to_str(payload)
                payload = json.loads(str_payload)
                return router.process(payload["method"], data)
            except Exception as error:
                error_msg = f"Failed to process command '{str_payload}'. {error}"
                logger.debug(error_msg, exc_info=True)
                return Error(error_msg)

    except Exception as error:
        error_msg = f"Failed to process advance_request. {error}"
        logger.debug(error_msg, exc_info=True)
        return Error(error_msg)

def handle_inspect(data):
    logger.debug(f"Received inspect request data {data}")
    try:
        url = urlparse(hex_to_str(data["payload"]))
        return router.process(url.path, data)
    except Exception as error:
        error_msg = f"Failed to process inspect request. {error}"
        logger.debug(error_msg, exc_info=True)
        return Error(error_msg)

handlers = {
    "advance_state": handle_advance,
    "inspect_state": handle_inspect,
}

finish = {"status": "accept"}

auctioneer = Auctioneer(wallet)
router = Router(wallet, auctioneer)

while True:
    logger.debug("Sending finish")
    response = requests.post(rollup_server + "/finish", json=finish)
    logger.debug(f"Received finish status {response.status_code}")
    if response.status_code == 202:
        logger.debug("No pending rollup request, trying again")
    else:
        rollup_request = response.json()
        data = rollup_request["data"]

        handler = handlers[rollup_request["request_type"]]
        output = handler(rollup_request["data"])

        finish["status"] = "accept"
        if isinstance(output, Error):
            finish["status"] = "reject"

        send_request(output)


def sort(data):

    array={}
    array2={}
    counter=0
    for x in data:
        array[counter]=x
        counter+=1

    exittheloop=False
    while exittheloop==False:
        counter=0
        for x in range(0,len(array),2):
            temp=array.get(x)
            temp2=array.get(x+1)
            if not temp2==None:
                templen=len(temp)
                temp2len=len(temp2)
            i=0
            j=0
            buffer=""
            exittheloop2=False
            while exittheloop2==False and not temp2==None:
                if i>=templen and j>=temp2len:
                    exittheloop2=True
                elif i>=templen:
                    buffer=buffer+temp2[j]
                    j+=1
                elif j>=temp2len:
                    buffer=buffer+temp[i]
                    i+=1
                elif temp[i]<temp2[j]:
                    buffer=buffer+temp[i]
                    i+=1
                else:
                    buffer=buffer+temp2[j]
                    j+=1
            array2[counter]=buffer
            counter+=1
        del array
        array=array2.copy()
        del array2
        array2={}
        if len(array)==1:
            exittheloop=True
    return array[0]

data="9876543210abccowabunga98675444444444444444444444444444444444444444444444444444444444444444444444334142314321234321342321484848"
print(sort(data))


from wok.task import task

from intogensm import so
from intogensm.config import GlobalConfig, PathsConfig
from intogensm.projects.db import ProjectDb
from intogensm.projects.results import ProjectResults
from intogensm.oncodrivefm import OncodriveFm

def increment(d, key):
	if key not in d:
		d[key] = 1
	else:
		d[key] += 1

def distrib(counts):
	d = {}
	for key, count in counts.items():
		increment(d, count)
	return [v for v in sorted(d.items(), key=lambda v: v[0])]

def quality_control(log, config, project, ofm):

	ofm.load_expression_filter()
	filter = ofm.filter if ofm.filter_enabled else None

	data = {}

	projdb = ProjectDb(project["db"])

	for csq in projdb.consequences(join_samples=True, join_ctypes=True):#,
								   #filters={ProjectDb.CSQ_CTYPES : so.ONCODRIVEFM}):

		is_selected = so.match(csq.ctypes, so.ONCODRIVEFM)

		var = csq.var
		for sample in var.samples:
			key = (sample.id, csq.gene)
			if key not in data:
				data[key] = is_selected
			else:
				data[key] = data[key] or is_selected

	projdb.close()

	source_genes = {}

	selected_genes = set()
	filter_genes = set()
	threshold_genes = set()

	selected_gene_sample_count = {} # number of samples for each selected gene
	filter_gene_sample_count = {} # number of samples per gene

	source_samples = {}
	selected_samples = set()
	filter_samples = set()
	threshold_samples = set()

	for (sample, gene), is_selected in data.items():
		if sample in source_samples:
			sample_index = source_samples[sample]
		else:
			source_samples[sample] = sample_index = len(source_samples)

		if is_selected:
			selected_samples.add(sample_index)

			increment(selected_gene_sample_count, gene)

	ofm.load_samples_thresholds(len(selected_samples))
	samples_threshold = ofm.genes_samples_threshold

	for (sample, gene), is_selected in data.items():
		if gene not in source_genes:
			source_genes[gene] = len(source_genes)

		gi = source_genes[gene]
		sample_index = source_samples[sample]

		if is_selected:
			if filter is None or filter.valid(gene):
				filter_samples.add(sample_index)

				increment(filter_gene_sample_count, gi)

				if selected_gene_sample_count[gene] >= samples_threshold:
					threshold_samples.add(sample_index)

	for gene, sample_count in selected_gene_sample_count.items():
		gi = source_genes[gene]

		selected_genes.add(gi)

		if filter is None or filter.valid(gene):
			filter_genes.add(gi)

			if sample_count >= samples_threshold:
				threshold_genes.add(gi)

	# significance of q-values

	projdb = ProjectDb(project["db"])
	sig_thresholds = [0.0, 0.001, 0.005] + [i / 100.0 for i in range(1, 11)] + [1.0]
	sig_count = [0] * len(sig_thresholds)
	for gene in projdb.genes():
		if gene.id in source_genes and source_genes[gene.id] in threshold_genes:
			i = 0
			while i < len(sig_thresholds) and gene.fm_qvalue > sig_thresholds[i]:
				i += 1

			for j in range(i, len(sig_count)):
				sig_count[j] += 1

	projdb.close()

	source_samples_count = len(source_samples)
	selected_samples_count = len(selected_samples)
	filter_samples_count = len(filter_samples)
	threshold_samples_count = len(threshold_samples)

	source_genes_count = len(source_genes)
	selected_genes_count = len(selected_genes)
	filter_genes_count = len(filter_genes)
	threshold_genes_count = len(threshold_genes)

	sorted_filter_genes = sorted(filter_genes, reverse=True, key=lambda gi: filter_gene_sample_count[gi])

	qc_data = dict(
			source=dict(
				genes=sorted(source_genes.keys(), key=lambda k: source_genes[k]),
				genes_count=source_genes_count,
				genes_lost_count=max(0, source_genes_count - threshold_genes_count),
				samples=sorted(source_samples.keys(), key=lambda k: source_samples[k]),
				samples_count=source_samples_count),
				samples_lost_count=max(0, source_samples_count - threshold_samples_count),
			selected=dict(
				genes=sorted(selected_genes),
				genes_count=selected_genes_count,
				genes_lost=sorted(set(source_genes.values()) - selected_genes),
				genes_lost_count=max(0, source_genes_count - selected_genes_count),
				samples=sorted(selected_samples),
				samples_count=selected_samples_count,
				samples_lost=sorted(set(source_samples.values()) - selected_samples),
				samples_lost_count=max(0, source_samples_count - selected_samples_count)),
			filter=dict(
				genes=sorted_filter_genes,
				genes_count=filter_genes_count,
				genes_lost=sorted(selected_genes - filter_genes),
				genes_lost_count=max(0, selected_genes_count - filter_genes_count),
				genes_sample_count=[filter_gene_sample_count[gi] for gi in sorted_filter_genes],
				samples=sorted(filter_samples),
				samples_count=filter_samples_count,
				samples_lost=sorted(selected_samples - filter_samples),
				samples_lost_count=max(0, selected_samples_count - filter_samples_count)),
			threshold=dict(
				genes=sorted(threshold_genes),
				genes_count=threshold_genes_count,
				genes_lost=sorted(filter_genes - threshold_genes),
				genes_lost_count=max(0, filter_genes_count - threshold_genes_count),
				samples=sorted(threshold_samples),
				samples_count=threshold_samples_count,
				samples_threshold=samples_threshold,
				samples_lost=sorted(filter_samples - threshold_samples),
				samples_lost_count=max(0, filter_samples_count - threshold_samples_count)),
			results=dict(
				sig_thresholds=sig_thresholds[1:],
				sig_count=sig_count[1:])
			)

	return qc_data

@task.foreach()
def oncodrivefm(project):
	log = task.logger
	conf = task.conf

	log.info("--- [{0}] --------------------------------------------".format(project["id"]))

	config = GlobalConfig(conf)
	paths = PathsConfig(config) # avoid that project conf override path configurations
	config = GlobalConfig(conf, project["conf"])

	ofm = OncodriveFm(config.oncodrivefm, paths, log)

	log.info("Calculating quality indicators for OncodriveFM ...")

	qc_data = quality_control(log, config, project, ofm)

	project_results = ProjectResults(project)
	project_results.save_quality_control("oncodrivefm", qc_data)

task.run()


import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO_Pin_Signal = 24

GPIO.setup(GPIO_Pin_Signal,GPIO.IN,pull_up_down = GPIO.PUD_DOWN)

print("Prueba de modulo [Presiona Ctrl + C para finalizar la prueba]")

def funcionSalida(null):
        print("Ha sido detectado")

GPIO.add_event_detect(GPIO_Pin_Signal,GPIO.RISING,callback = funcionSalida,bouncetime = 100)

# loop
try:
        while True:
                time.sleep(1)

except KeyboardInterrupt:
        GPIO.cleanup()


import os
from queue import Queue, Empty
from shutil import rmtree
import sys
from tempfile import gettempdir
from typing import Optional
import threading
import time
import unittest
from urllib.parse import quote

# Related third party imports
from genicam.gentl import TimeoutException
import numpy as np

# Local application/library specific imports
from harvesters.test.base_harvester import TestHarvesterCoreBase
from harvesters.test.base_harvester import get_cti_file_path
from harvesters.core import Callback
from harvesters.core import Harvester
from harvesters.core import ImageAcquirer
from harvesters.test.helper import get_package_dir
from harvesters.util.pfnc import Dictionary
from harvesters.core import Component2DImage
from harvesters.util.pfnc import Mono8, Mono10, Mono12, Mono14, Mono16
from harvesters.util.pfnc import Mono10Packed, Mono12Packed
from harvesters.util.pfnc import Mono10p, Mono12p, Mono14p

class TestHarvesterCore(TestHarvesterCoreBase):
    sleep_duration = .5  # Time to keep sleeping [s]

    def test_basic_usage_1(self):
        """
        We walk through a basic usage and manually close the image
        acquirer.

        :return: None.
        """

        # Prepare an image acquirer for device #0.
        ia = self.harvester.create_image_acquirer(0)

        # Acquire images.
        self._basic_usage(ia)

        # Discard the image acquirer.
        ia.destroy()

    def test_basic_usage_2(self):
        """
        We walk through a basic usage and omit manually closing the image
        acquirer using the with statement.

        :return: None.
        """

        # Prepare an image acquirer for device #0.
        with self.harvester.create_image_acquirer(0) as ia:

            # Acquire images.
            self._basic_usage(ia)

    def _basic_usage(self, ia: ImageAcquirer):
        # Start image acquisition.
        ia.start_acquisition()

        # Fetch a buffer that is filled with image data.
        with ia.fetch_buffer() as buffer:
            # Reshape it.
            self._logger.info('{0}'.format(buffer))

        # Stop image acquisition.
        ia.stop_acquisition()

    def test_multiple_image_acquirers(self):
        num_devices = len(self.harvester.device_info_list)
        self._test_image_acquirers(num_ias=num_devices)

    def _test_image_acquirers(self, num_ias=1):
        #
        self._logger.info('Number of devices: {0}'.format(num_ias))

        #
        ias = []  # Image Acquirers

        #
        for list_index in range(num_ias):
            ias.append(
                self.harvester.create_image_acquirer(
                    list_index=list_index
                )
                # Or you could simply do the same thing as follows:
                # self.harvester.create_image_acquirer(list_index)
            )

        #
        for i in range(3):
            #
            self._logger.info('---> Round {0}: Set up'.format(i))
            for index, ia in enumerate(ias):
                ia.start_acquisition()
                self._logger.info(
                    'Device #{0} has started image acquisition.'.format(index)
                )

            k = 0

            # Run it as fast as possible.
            frames = 10

            while k < frames:
                for ia in ias:
                    if k % 2 == 0:
                        # Option 1: This way is secure and preferred.
                        try:
                            # We know we've started image acquisition but this
                            # try-except block is demonstrating a case where
                            # a client called fetch_buffer method even though
                            # he'd forgotten to start image acquisition.
                            with ia.fetch_buffer() as buffer:
                                self._logger.info('{0}'.format(buffer))
                        except AttributeError:
                            # Harvester Core has not started image acquisition
                            # so calling fetch_buffer() raises AttributeError
                            # because None object is used for the with
                            # statement.
                            pass
                    else:
                        # Option 2: You can manually do the same job but not
                        # recommended because you might forget to queue the
                        # buffer.
                        buffer = ia.fetch_buffer()
                        self._logger.info('{0}'.format(buffer))

                #
                k += 1

            #
            self._logger.info('<--- Round {0}: Tear down'.format(i))
            for index, ia in enumerate(ias):
                ia.stop_acquisition()
                self._logger.info(
                    'Device #{0} has stopped image acquisition.'.format(index)
                )

        for ia in ias:
            ia.destroy()

    def test_controlling_a_specific_camera(self):
        if not self.is_running_with_default_target():
            return

        # The basic usage.
        ia = self.harvester.create_image_acquirer(0)
        ia.destroy()

        # The basic usage but it explicitly uses the parameter name.
        ia = self.harvester.create_image_acquirer(
            list_index=0
        )
        ia.destroy()

        # The key can't specify a unique device so it raises an exception.
        with self.assertRaises(ValueError):
            self.harvester.create_image_acquirer(
                vendor='EMVA_D'
            )

        # The key specifies a unique device.
        self._logger.info(self.harvester.device_info_list)
        ia = self.harvester.create_image_acquirer(
            serial_number='SN_InterfaceA_0'
        )
        ia.destroy()

    def test_timeout_on_fetching_buffer(self):
        if not self.is_running_with_default_target():
            return

        # Create an image acquirer:
        ia = self.harvester.create_image_acquirer(0)

        # We do not start image acquisition:
        #ia.start_acquisition()

        timeout = 3  # sec

        with self.assertRaises(TimeoutException):
            # Try to fetch a buffer but the IA will immediately raise
            # TimeoutException because it's not started image acquisition:
            _ = ia.fetch_buffer(timeout=timeout)

        # Then we setup the device for software trigger mode:
        ia.remote_device.node_map.TriggerMode.value = 'On'
        ia.remote_device.node_map.TriggerSource.value = 'Software'

        # We're ready to start image acquisition:
        ia.start_acquisition()

        with self.assertRaises(TimeoutException):
            # Try to fetch a buffer but the IA will raise TimeoutException
            # because we've not triggered the device so far:
            _ = ia.fetch_buffer(timeout=timeout)

        # We finally acquire an image triggering the device:
        buffer = None
        self.assertIsNone(buffer)

        ia.remote_device.node_map.TriggerSoftware.execute()
        buffer = ia.fetch_buffer(timeout=timeout)
        self.assertIsNotNone(buffer)
        self._logger.info('{0}'.format(buffer))
        buffer.queue()

        # Now we stop image acquisition:
        ia.stop_acquisition()
        ia.destroy()

    def test_stop_start_and_stop(self):
        # Create an image acquirer:
        ia = self.harvester.create_image_acquirer(0)

        # It's not necessary but we stop image acquisition first;
        #
        ia.stop_acquisition()

        # Then start it:
        ia.start_acquisition()

        # Fetch a buffer to make sure it's working:
        with ia.fetch_buffer() as buffer:
            self._logger.info('{0}'.format(buffer))

        # Then stop image acquisition:
        ia.stop_acquisition()

        # And destroy the ImageAcquirer:
        ia.destroy()

    def test_num_holding_filled_buffers(self):
        if not self.is_running_with_default_target():
            return

        # Connect to the first camera in the list:
        self.ia = self.harvester.create_image_acquirer(0)

        # Setup the camera before starting image acquisition:
        self.setup_camera()

        #
        tests = [
            self._test_issue_120_1
        ]
        for test in tests:
            for num_images in [1, 2, 4, 8]:
                #
                self.ia.num_filled_buffers_to_hold = num_images

                # Start image acquisition:
                self.ia.start_acquisition(run_in_background=True)

                # Run a test:
                test(num_images)

                # Stop image acquisition:
                self.ia.stop_acquisition()

    def _test_issue_120_1(self, num_images):
        # Make sure num_holding_filled_buffers is incremented every trigger:
        for i in range(num_images):
            #
            self.assertEqual(
                self.ia.num_holding_filled_buffers, i
            )

            # Trigger it:
            self.generate_software_trigger(sleep_s=self.sleep_duration)

            # It must be incremented:
            self.assertEqual(
                self.ia.num_holding_filled_buffers, i + 1
            )

        # Trigger it again, we know it's redundant compared to the
        # maximum capacity:
        self.generate_software_trigger(sleep_s=self.sleep_duration)

        # Make sure num_holding_filled_buffers does not exceed
        # num_filled_buffers_to_hold:
        self.assertEqual(
            self.ia.num_filled_buffers_to_hold,
            self.ia.num_holding_filled_buffers
        )

        # Make sure num_holding_filled_buffers is decreased every time
        # a filled buffer is fetched:
        for i in range(num_images):
            #
            self.assertEqual(
                self.ia.num_holding_filled_buffers,
                num_images - i
            )
            #
            with self.ia.fetch_buffer():
                #
                self.assertEqual(
                    self.ia.num_holding_filled_buffers,
                    num_images - (i + 1)
                )

    def setup_camera(self):
        self.ia.remote_device.node_map.AcquisitionMode.value = 'Continuous'
        self.ia.remote_device.node_map.TriggerMode.value = 'On'
        self.ia.remote_device.node_map.TriggerSource.value = 'Software'

    def generate_software_trigger(self, sleep_s=0.):
        # Trigger the camera because you have already setup your
        # equipment for the upcoming image acquisition.
        self.ia.remote_device.node_map.TriggerSoftware.execute()
        #
        if sleep_s > 0:
            time.sleep(sleep_s)

    def test_issue_59(self):
        if not self.is_running_with_default_target():
            return

        # Connect to the first camera in the list.
        self.ia = self.harvester.create_image_acquirer(0)

        #
        min = self.ia._data_streams[0].buffer_announce_min
        with self.assertRaises(ValueError):
            self.ia.num_buffers = min - 1

        #
        with self.assertRaises(ValueError):
            self.ia.num_filled_buffers_to_hold = 0

        #
        self.ia.num_filled_buffers_to_hold = min

    def test_issue_60(self):
        if not self.is_running_with_default_target():
            return

        # Connect to the first camera in the list.
        self.ia = self.harvester.create_image_acquirer(0)

        # Check the number of buffers:
        self.assertEqual(16, self.ia.num_buffers)

    @unittest.skip('It has been obsolete; see issue #141.')
    def test_issue_61(self):
        if not self.is_running_with_default_target():
            return

        # Connect to the first camera in the list.
        self.ia = self.harvester.create_image_acquirer(0)

        # Register a call back method:
        self.ia.on_new_buffer_arrival = self._callback_on_new_buffer_arrival

        # We turn software trigger on:
        self.setup_camera()

        # We have not fetched any buffer:
        self.assertEqual(0, len(self._buffers))

        # Start image acquisition:
        self.ia.start_acquisition(run_in_background=True)

        # Trigger the target device:
        num_images = self.ia.num_buffers
        self.assertTrue(num_images > 0)

        # Trigger the target device:
        for _ in range(num_images):
            self.generate_software_trigger(sleep_s=self.sleep_duration)

        # If the callback method was called, then we should have the same
        # number of buffers with num_images:
        self.assertEqual(num_images, len(self._buffers))

        # Release the buffers before stopping image acquisition:
        for buffer in self._buffers:
            buffer.queue()

        self._buffers.clear()

        # Then stop image acquisition:
        self.ia.stop_acquisition()

    def _callback_on_new_buffer_arrival(self):
        # Fetch a buffer and keep it:
        self._buffers.append(self.ia.fetch_buffer())

    def test_issue_66(self):
        if not self.is_running_with_default_target():
            return

        file_names = ['altered_plain.xml', 'altered_zip.zip']
        expected_values = ['plain', 'zip']
        for i, file_name in enumerate(file_names):
            self._test_issue_66(
                'issue_66_' + file_name, expected_values[i]
            )

    def _test_issue_66(self, file_name, expected_value):
        #
        xml_dir = self._get_xml_dir()

        # Connect to the first camera in the list.
        self.ia = self.harvester.create_image_acquirer(
            0, file_path=os.path.join(xml_dir, file_name)
        )

        # Compare DeviceModelNames:
        self.assertEqual(
            'Altered TLSimu (' + expected_value + ')',
            self.ia.remote_device.node_map.DeviceModelName.value
        )

        #
        self.ia.destroy()

    def test_issue_67(self):
        if not self.is_running_with_default_target():
            return

        file_names = ['altered_plain.xml', 'altered_zip.zip']
        for i, file_name in enumerate(file_names):
            self._test_issue_67(
                'issue_67_' + file_name
            )

    def _test_issue_67(self, expected_file_name):
        #
        xml_dir = self._get_xml_dir()

        #
        url = 'file://'
        file_path = xml_dir + '/' + expected_file_name

        # '\' -> '/'
        file_path.replace('\\', '/')

        # ':' -> '|'
        file_path.replace(':', '|')

        # ' ' -> '%20'
        file_path = quote(file_path)

        #
        url += file_path

        # Parse the URL:
        retrieved_file_path = ImageAcquirer._retrieve_file_path(url=url)

        # Compare file names:
        self.assertEqual(
            os.path.basename(retrieved_file_path),
            expected_file_name
        )

    def test_issue_121(self):
        #
        expected_file_path = '/Foo.xml'

        #
        url = 'file://' + expected_file_path
        retrieved_file_path = ImageAcquirer._retrieve_file_path(url=url)

        # Compare file names:
        self.assertEqual(
            retrieved_file_path,
            expected_file_path
        )

    @staticmethod
    def _get_xml_dir():
        return os.path.join(get_package_dir('harvesters'), 'test', 'xml')

    def test_issue_70(self):
        if not self.is_running_with_default_target():
            return

        # Connect to the first camera in the list:
        self.ia = self.harvester.create_image_acquirer(0)

        # Then check the minimum buffer number that a client can ask
        # the ImageAcquire object to prepare:
        self.assertEqual(5, self.ia.min_num_buffers)

    def test_issue_78(self):
        if not self.is_running_with_default_target():
            return

        # The device_info_list must not turn empty even if a given key
        # does not match to any candidate:
        self._logger.info(self.harvester.device_info_list)
        device_info_list = self.harvester.device_info_list.copy()
        try:
            self.harvester.create_image_acquirer(
                serial_number='abcdefghijklmnopqrstuwxyz!#$%&=~|<>'
            )
        except ValueError:
            self.assertEqual(
                device_info_list, self.harvester.device_info_list
            )

    def test_issue_130_1(self):
        #
        self.ia = self.harvester.create_image_acquirer(0)
        #
        self.ia.start_acquisition(run_in_background=False)
        #
        with self.ia.fetch_buffer() as buffer:
            self.assertIsNotNone(buffer)
        #
        self.ia.stop_acquisition()

    def test_issue_141(self):
        if not self.is_running_with_default_target():
            return

        # Connect to the first camera in the list.
        self.ia = self.harvester.create_image_acquirer(0)

        # We turn software trigger on:
        self.setup_camera()

        # Create a callback:
        self.on_new_buffer_available = _OnNewBufferAvailable(
            ia=self.ia, buffers=self._buffers
        )
        self.on_return_buffer_now = _OnReturnBufferNow(
            holder=self.on_new_buffer_available
        )

        # Trigger the target device:
        self.num_images = self.ia.num_buffers
        self.assertTrue(self.num_images > 0)

        #
        tests = [
            self._test_141_with_callback, self._test_141_without_callback
        ]
        for test in tests:
            # We have not yet fetched any buffer:
            self.assertEqual(0, len(self.on_new_buffer_available.buffers))

            # Run a sub-test:
            test()

            # Then stop image acquisition:
            self.ia.stop_acquisition()

    def _test_141_with_callback(self):
        # Add it to the image acquire so that it can get notified when the
        # event happened:
        self.ia.add_callback(
            ImageAcquirer.Events.NEW_BUFFER_AVAILABLE,
            self.on_new_buffer_available
        )
        self.ia.add_callback(
            ImageAcquirer.Events.RETURN_ALL_BORROWED_BUFFERS,
            self.on_return_buffer_now
        )

        #
        self._test_141_body()

        # If the callback method was called, then we should have the same
        # number of buffers with num_images:
        self.assertEqual(
            self.ia.num_buffers, len(self.on_new_buffer_available.buffers)
        )

    def _test_141_without_callback(self):
        # Remove all callbacks to not any callback work:
        self.ia.remove_callbacks()

        #
        self._test_141_body()

        # The list must be empty because the emit method has not been called:
        self.assertEqual(
            0, len(self.on_new_buffer_available.buffers)
        )

    def _test_141_body(self):
        # Start image acquisition:
        self.ia.start_acquisition(run_in_background=True)

        # Trigger the target device:
        for _ in range(self.num_images):
            self.generate_software_trigger(sleep_s=self.sleep_duration)

    def test_issue_150(self):
        # Create an image acquirer:
        self.ia = self.harvester.create_image_acquirer(0)

        # TLSimu does not support SingleFrame in reality:
        # modes = ["SingleFrame", "Continuous"]

        # Test only "Continuous":
        modes = ["Continuous"]
        for mode in modes:
            self.ia.remote_device.node_map.AcquisitionMode.value = mode

            for i in range(32):
                # Then start it:
                self.ia.start_acquisition()

                # Fetch a buffer to make sure it's working:
                with self.ia.fetch_buffer() as buffer:
                    self._logger.info('{0}'.format(buffer))

            # Then stop image acquisition:
            self.ia.stop_acquisition()

        # And destroy the ImageAcquirer:
        self.ia.destroy()

    def test_issue_146(self):
        #
        tests = [
            self._test_issue_146_group_packed_10,
            self._test_issue_146_group_packed_12,
            self._test_issue_146_packed_10,
            self._test_issue_146_packed_12,
            self._test_issue_146_mono_unpacked_multibytes,
        ]
        #
        for test in tests:
            test()

    def _test_issue_146_group_packed_10(self):
        _1st = 0xff
        _3rd = 0xff
        ba = bytes([_1st, 0x33, _3rd])
        packed = np.frombuffer(ba, dtype=np.uint8)
        pf = Dictionary.get_proxy('BayerRG10Packed')
        unpacked = pf.expand(packed)
        self.assertEqual(_1st * 4 + 3, unpacked[0])
        self.assertEqual(_3rd * 4 + 3, unpacked[1])

    def _test_issue_146_group_packed_12(self):
        _1st = 0xff
        _3rd = 0xff
        ba = bytes([_1st, 0xff, _3rd])
        packed = np.frombuffer(ba, dtype=np.uint8)
        pf = Dictionary.get_proxy('BayerRG12Packed')
        unpacked = pf.expand(packed)
        self.assertEqual(_1st * 16 + 0xf, unpacked[0])
        self.assertEqual(_3rd * 16 + 0xf, unpacked[1])

    def _test_issue_146_packed_10(self):
        element = 0xff
        ba = bytes([element, element, element, element])
        packed = np.frombuffer(ba, dtype=np.uint8)
        pf = Dictionary.get_proxy('Mono10p')
        unpacked = pf.expand(packed)
        self.assertEqual(0x3ff, unpacked[0])
        self.assertEqual(0x3ff, unpacked[1])
        self.assertEqual(0x7ff, unpacked[2])

    def _test_issue_146_packed_12(self):
        _1st = 0xff
        _3rd = 0xff
        ba = bytes([_1st, 0xff, _3rd])
        packed = np.frombuffer(ba, dtype=np.uint8)
        pf = Dictionary.get_proxy('Mono12p')
        unpacked = pf.expand(packed)
        self.assertEqual(0xf * 256 + _1st, unpacked[0])
        self.assertEqual(_3rd * 16 + 0xf, unpacked[1])

    def _test_issue_146_mono_unpacked_multibytes(self):
        names = ['Mono10', 'Mono12']
        maximums = [0x4, 0x10]
        for index, name in enumerate(names):
            pf = Dictionary.get_proxy(name)
            for i in range(maximums[index]):
                for j in range(0x100):
                    ba = bytes([j, i, j, i])
                    packed = np.frombuffer(ba, dtype=np.uint8)
                    unpacked = pf.expand(packed)
                    # We know it's redundant but check 10 times:
                    for l in range(10):
                        for k in range(2):
                            self.assertEqual((i << 8) + j, unpacked[k])

class _TestIssue81(threading.Thread):
    def __init__(self, message_queue=None, cti_file_path=None):
        super().__init__()
        self._message_queue = message_queue
        self._cti_file_path = cti_file_path

    def run(self):
        h = Harvester()
        h.add_file(self._cti_file_path)
        h.update()
        try:
            ia = h.create_image_acquirer(0)
        except:
            # Transfer the exception anyway:
            self._message_queue.put(sys.exc_info())
        else:
            ia.start_acquisition()
            ia.stop_acquisition()
            ia.destroy()
            h.reset()

class TestIssue81(unittest.TestCase):
    _cti_file_path = get_cti_file_path()
    sys.path.append(_cti_file_path)

    def test_issue_81(self):
        message_queue = Queue()
        t = _TestIssue81(
            message_queue=message_queue, cti_file_path=self._cti_file_path
        )
        t.start()
        t.join()
        try:
            result = message_queue.get(block=False)
        except Empty:
            # Nothing happened; everything is fine.
            pass
        else:
            exception, message, backtrace = result
            # Transfer the exception:
            raise exception(message)

class TestIssue85(unittest.TestCase):
    _cti_file_path = get_cti_file_path()
    sys.path.append(_cti_file_path)

    def setUp(self) -> None:
        #
        self.env_var = 'HARVESTERS_XML_FILE_DIR'
        self.original = None if os.environ else os.environ[self.env_var]

    def tearDown(self) -> None:
        if self.original:
            os.environ[self.env_var] = self.original

    def test_issue_85(self):
        #
        temp_dir = os.path.join(
            gettempdir(), 'harvester', self.test_issue_85.__name__
        )

        #
        if os.path.isdir(temp_dir):
            rmtree(temp_dir)
        os.makedirs(temp_dir)

        #
        os.environ[self.env_var] = temp_dir

        #
        self.assertFalse(os.listdir(temp_dir))

        #
        with Harvester() as h:
            h.add_file(self._cti_file_path)
            h.update()
            with h.create_image_acquirer(0):
                # Check if XML files have been stored in the expected
                # directory:
                self.assertTrue(os.listdir(temp_dir))

class _OnNewBufferAvailable(Callback):
    def __init__(self, ia: ImageAcquirer, buffers: list):
        super().__init__()
        self._ia = ia
        self._buffers = buffers

    def emit(self, context: Optional[object] = None) -> None:
        buffer = self._ia.fetch_buffer()
        self._buffers.append(buffer)

    @property
    def buffers(self):
        return self._buffers

class _OnReturnBufferNow(Callback):
    def __init__(self, holder: _OnNewBufferAvailable):
        super().__init__()
        self._holder = holder

    def emit(self, context: Optional[object] = None) -> None:
        # Return/Queue the buffers before stopping image acquisition:
        while len(self._holder.buffers) > 0:
            buffer = self._holder.buffers.pop(-1)
            buffer.queue()

class TestIssue181(unittest.TestCase):
    def test_issue_181_with_nonexistent_file(self):
        h = Harvester()
        with self.assertRaises(FileNotFoundError):
            h.add_file('just a string', check_existence=True)

    def test_issue_181_with_invalid_file(self):
        h = Harvester()
        with self.assertRaises(OSError):
            h.add_file(__file__, check_validity=True)

class TestIssue188(unittest.TestCase):
    _height = 1
    _range = range(0, 3, 1)

    def test_issue_188_unpacked(self):
        proxies = [Mono8, Mono10, Mono12, Mono14, Mono16]
        expected_results = [
            [1, 2, 2, 2, 2],  # 1 x 1
            [2, 4, 4, 4, 4],  # 2 x 1
            [3, 6, 6, 6, 6],  # 3 x 1
        ]
        for i in self._range:
            for j, proxy in enumerate(proxies):
                self.assertEqual(
                    expected_results[i][j],
                    Component2DImage._get_nr_bytes(
                        pf_proxy=proxy(), width=i + 1, height=self._height
                    )
                )

    def test_issue_188_packed(self):
        proxies = [Mono10Packed, Mono12Packed]
        expected_results = [
            [2, 2],  # 1 x 1
            [3, 3],  # 2 x 1
            [4, 5],  # 3 x 1
        ]
        for i in self._range:
            for j, proxy in enumerate(proxies):
                self.assertEqual(
                    expected_results[i][j],
                    Component2DImage._get_nr_bytes(
                        pf_proxy=proxy(), width=i + 1, height=self._height
                    )
                )

    def test_issue_188_p(self):
        proxies = [Mono10p, Mono12p, Mono14p]
        expected_results = [
            [2, 2, 2],  # 1 x 1
            [3, 3, 4],  # 2 x 1
            [4, 5, 6],  # 3 x 1
        ]
        for i in self._range:
            for j, proxy in enumerate(proxies):
                self.assertEqual(
                    expected_results[i][j],
                    Component2DImage._get_nr_bytes(
                        pf_proxy=proxy(), width=i + 1, height=self._height
                    )
                )

    def test_issue_188_neels_case(self):
        proxies = [Mono12]
        width = 2456
        height = 2058
        for proxy in proxies:
            self.assertEqual(
                10108896,  # = 2456 * 2058 * 2
                Component2DImage._get_nr_bytes(
                    pf_proxy=proxy(), width=width, height=height
                )
            )

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


"""sysinfo URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from .views import *
urlpatterns = [
    path('', index,name='index'),
    path('user/', user, name='user'),
    path('cpu/', cpu, name='cpu'),
    path('cpu/<str:chart>/', cpu, name='cpu'),
    path('memory/', memory, name='memory'),
    path('disk/', disk, name='disk'),
    path('network/', network, name='network'),
    path('process/', process, name='process'),
]


import requests
from datetime import datetime
from os import environ

NUTRI_ENDPOINT = "https://trackapi.nutritionix.com/v2/natural/exercise"

nutri_header = {
    "x-app-id": environ.get("NUTRIX_ID"),
    "x-app-key": environ.get("NUTRIX_KEY")
}

nutri_params = {
    "query": input("Please enter your exercise: "),
    "gender": "male",
    "weight_kg": 86.5,
    "height_cm": 176,
    "age": 26
}

response = requests.post(url=NUTRI_ENDPOINT, headers=nutri_header, json=nutri_params)
response.raise_for_status()
nutri_response = response.json()["exercises"][0]

for exercise in nutri_response:
    sheet_params = {
        "sheet1":  {
            "date": datetime.now().strftime("%d/%m/%Y"),
            "time": datetime.now().strftime("%H:%M"),
            "exercise": nutri_response["user_input"].title(),
            "duration (min)": nutri_response["duration_min"],
            "calories": nutri_response["nf_calories"],
            "id": -1
        }
    }

    GOOGLE_ENDPOINT = environ.get("WORKOUT_SHEET_ENDPOINT")
    response = requests.post(url=GOOGLE_ENDPOINT, json=sheet_params)
    response.raise_for_status()
print("workout logged!")


t = int(input())
while t > 0:
    a,n = input().split()
    a,n = [int(a), int(n)]
    soma = 0
    while n > 0:
        print(a,end=" ")
        soma += a
        a += 1
        n -= 1
    print(f"\n{soma}")
    t-=1


class Solution():
    def binaryToDec(self,no):
        sum = 0
        #base  = 1
        factor = 0
        while no != 0:
            last_digit = no % 10 # get the last digit
            #print(last_digit)
            sum = sum + (last_digit * pow(2,factor))
            #print(sum)
            no = no // 10
            factor += 1
            #base = base * 2

        return sum #int(no,2)

if __name__ == '__main__':
    no = int(input())
    obj = Solution()
    print(obj.binaryToDec(no))


from django.contrib import admin
from .models import Project, Link, Tag, Screenshot
from django_markdown.admin import AdminMarkdownWidget
from django.db import models

class LinkInline(admin.StackedInline):
    model= Link
    extra=1
class ScreenInline(admin.StackedInline):
    model= Screenshot
    extra=1
class ProjectAdmin(admin.ModelAdmin):
    formfield_overrirdes= {models.TextField:  {'widget': AdminMarkdownWidget}}
    inlines=[LinkInline,ScreenInline]

# Register your models here.

admin.site.register(Project, ProjectAdmin)
admin.site.register(Tag)


#-*- coding:utf-8 -*-

import config
import aterm
import logging

logger = logging.getLogger("j2py.fix_expressions")

assign_expressions = config.config["assign-expressions"]

@aterm.transformation
def fix_assigns(ast):
    for a in ast.findall(assign_expressions):
        parents = [ p for p in a.parents() ]
        if parents[0].name != 'ExprStm':
            logging.warning("inner assign %s %s",a, [p.name for p in parents])

run = fix_assigns


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('registrations', '0001_initial'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='category',
            options={'verbose_name_plural': 'categories'},
        ),
        migrations.AddField(
            model_name='participant',
            name='college',
            field=models.ForeignKey(default=None, to='registrations.College'),
            preserve_default=False,
        ),
        migrations.AlterField(
            model_name='category',
            name='model',
            field=models.CharField(max_length=8, choices=[(b'Project', b'Project'), (b'Paper', b'Paper'), (b'Both', b'Both')]),
        ),
    ]


import json
import logging
from datetime import datetime
from http import HTTPStatus
import polling2
from polling2 import TimeoutException
import requests

from adobe.pdfservices.operation.internal.http.response_util import ResponseUtil
from adobe.pdfservices.operation.internal.api.dto.response.job_status import JobStatus
from adobe.pdfservices.operation.internal.constants.request_key import RequestKey
from adobe.pdfservices.operation.internal.http.response_util import ResponseUtil
from adobe.pdfservices.operation.exception.exceptions import ServiceApiException
from adobe.pdfservices.operation.internal.api.dto.response.platform.platform_api_response import PlatformApiResponse
from adobe.pdfservices.operation.internal.exceptions import OperationException
from adobe.pdfservices.operation.internal.extension_media_type_mapping import ExtensionMediaTypeMapping
from adobe.pdfservices.operation.internal.http.http_request import HttpRequest
from adobe.pdfservices.operation.internal.http.http_method import HttpMethod
from adobe.pdfservices.operation.internal.http.request_header_const import DefaultHeaders
from adobe.pdfservices.operation.internal.http import http_client
from adobe.pdfservices.operation.internal.internal_execution_context import InternalExecutionContext
from adobe.pdfservices.operation.internal.api.dto.request.platform.platform_api_request import PlatformApiRequest

class PlatformApi:
    operation = '/operation/'
    POLLING_TIMEOUT_STATUS_CODE = 0

    @staticmethod
    def submit_job(context: InternalExecutionContext, platform_api_request: PlatformApiRequest, operation_endpoint: str,
                   x_request_id: str, operation_header_info: str):
        http_request = HttpRequest(http_method=HttpMethod.POST,
                                   request_key=RequestKey.PLATFORM,
                                   url=context.client_config.get_pdf_services_uri() + PlatformApi.operation +
                                       operation_endpoint, data=platform_api_request.to_json(),
                                   headers={DefaultHeaders.DC_REQUEST_ID_HEADER_KEY: x_request_id,
                                            DefaultHeaders.X_DCSDK_OPS_INFO_HEADER_NAME: operation_header_info,
                                            DefaultHeaders.CONTENT_TYPE_HEADER_NAME: ExtensionMediaTypeMapping.JSON.mime_type},

                                   authenticator=context.authenticator,
                                   connect_timeout=context.client_config.get_connect_timeout(),
                                   read_timeout=context.client_config.get_read_timeout())
        response = http_client.process_request(http_request=http_request,
                                               success_status_codes=[HTTPStatus.CREATED],
                                               error_response_handler=PlatformApi.handle_error_response)
        return response.headers.get('location')

    @staticmethod
    def status_poll(context: InternalExecutionContext, location: str, x_request_id: str):
        def is_correct_response(response):
            content = json.loads(response.content)
            status = content.get('status')
            if status == JobStatus.FAILED:
                job_error_response = PlatformApiResponse(status,content.get('error')).get_error_response()
                raise ServiceApiException(job_error_response.get('message'), ResponseUtil.
                                          get_request_tracking_id_from_response(response, False), job_error_response
                                          .get('status'), job_error_response.get('code'))
            return status == JobStatus.DONE

        start_time = datetime.now()
        http_request = HttpRequest(http_method=HttpMethod.GET,
                                   request_key=RequestKey.STATUS,
                                   url=location,
                                   headers={DefaultHeaders.DC_REQUEST_ID_HEADER_KEY: x_request_id},
                                   authenticator=context.authenticator,
                                   connect_timeout=context.client_config.get_connect_timeout(),
                                   read_timeout=context.client_config.get_read_timeout(),
                                   retryable=True)

        try:
            response = polling2.poll(
                lambda: http_client.process_request(http_request=http_request,
                                                    success_status_codes=[HTTPStatus.OK, HTTPStatus.ACCEPTED],
                                                    error_response_handler=PlatformApi.handle_error_response),
                check_success=is_correct_response,
                step=0.5,
                timeout=10 * 60
            )
            logging.debug(f'Total polling time, Latency(ms): {(datetime.now() - start_time).microseconds / 1000}')
            return response
        except TimeoutException:
            logging.error("Polling Timeout reached. Something's wrong, file operation took too long")
            raise OperationException(message="Operation execution has timed out!", error_message="Polling Timeout reached", request_tracking_id=ResponseUtil.get_request_tracking_id_from_response(response, True)
                                     ,status_code=PlatformApi.POLLING_TIMEOUT_STATUS_CODE)

    @staticmethod
    def handle_error_response(response: requests.Response):
        pass


#Node class implementation for Singly Linked List
class SNode:

    def __init__(self):
       self.data=None
       self.next=None

    def setData(self, data):
        self.data=data

    def setNext(self, next):
        self.next=next

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

#Singly Linked List Implementation
class SLinkedList:

    def __init__(self):
        self.head=self.tail=None

    def insertAtHead(self, data):
        temp = SNode()
        temp.setData(data)

        if self.head==None:
            temp.setNext(None)
            self.head=self.tail=temp

        else:
            temp.setNext(self.head)
            self.head=temp

    def insertAtTail(self, data):
        temp=SNode()
        temp.setData(data)

        if self.tail==None:
            temp.setNext(None)
            self.head=self.tail=temp

        else:
            self.tail.setNext(temp)
            self.tail=temp

    def print(self):
        curr=self.head

        while curr!=None:
            print(curr.getData())
            curr=curr.getNext()

    def deleteFromHead(self):
        if self.head==None:
            return

        if self.head is self.tail:
            self.head=self.tail=None
            return

        self.head=self.head.getNext()

    def deleteFromTail(self):
        if self.tail==None:
            return

        if self.head is self.tail:
            self.head=self.tail=None
            return

        curr=self.head

        while curr.getNext() is not self.tail:
            curr=curr.getNext()

        curr.setNext(None)
        self.tail=curr


from django.shortcuts import render

from . import Pool
import uuid
import os
def AddSubCategory(request):
    try:
        result = request.session['ADMIN']
        return render(request,'SubCategory.html')
    except Exception as e:
        return render(request, 'AdminLogin.html')

def SubCategorySubmit(request):
    try:
      subcategoryname=request.POST['subcategoryname']
      categoryid = request.POST['categoryid']
      description = request.POST['description']
      picture = request.FILES['picture']
      filename=str(uuid.uuid4())+picture.name[picture.name.rfind('.'):]
      q="insert into subcategory(categoryid,subcategoryname,description,subcategorypic)values({},'{}','{}','{}')".format(categoryid,subcategoryname,description,filename)
      db,cmd=Pool.ConnectionPool()
      cmd.execute(q)
      F = open("D:/MM/assets/SubCategoryImages/"+filename, "wb")
      for chunk in picture.chunks():
          F.write(chunk)
      F.close
      db.commit()
      db.close()
      return render(request,'SubCategory.html',{'msg':'Sub-Category Added Successfully'})

    except Exception as e:
        print("Error:",e)
        return render(request,'SubCategory.html',{'msg':'Fail To Add Sub-Category'})

def ShowAllSubCategory(request):
    try:
        result = request.session['ADMIN']
        db,cmd=Pool.ConnectionPool()
        q="select * from subcategory"
        cmd.execute(q)
        rows=cmd.fetchall()
        db.close()
        return render(request,"ShowAllSubCategory.html",{'rows':rows})

    except Exception as e:
        return render(request, 'AdminLogin.html')

def DisplaySubCategoryById(request):
    scid=request.GET['scid']
    try:
            db,cmd = Pool.ConnectionPool()
            q = "select SC.*,(select C.categoryname from category C where C.categoryid=SC.categoryid)from subcategory SC where subcategoryid={}".format(scid)
            cmd.execute(q)
            row = cmd.fetchone()
            db.close()
            return render(request, "DisplaySubCategoryById.html", {'row': row})

    except Exception as e:
       print("Error:", e)
       return render(request,"DisplaySubCategoryById.html", {'row': []})

def UpdateDeleteSubCategory(request):
    scid=request.GET['scid']
    btn=request.GET['btn']
    oldpic = request.GET['oldpic']
    if(btn=='Edit'):
        try:
          categoryid=request.GET['categoryid']
          subcategoryname=request.GET['subcategoryname']
          description=request.GET['description']

          db,cmd = Pool.ConnectionPool()
          q="update subcategory set categoryid={},subcategoryname='{}', description='{}' where subcategoryid={}".format(categoryid,subcategoryname,description,scid)
          cmd.execute(q)
          db.commit()
          db.close()
          return ShowAllSubCategory(request)

        except Exception as e:
            print("Error:", e)
            return ShowAllSubCategory(request)

    elif(btn=='Delete'):
        try:
            db, cmd = Pool.ConnectionPool()
            q = "delete from subcategory where subcategoryid={}".format(scid)
            cmd.execute(q)
            db.commit()
            db.close()
            os.remove("D:/MM/assets/SubCategoryImages/" + oldpic)
            return ShowAllSubCategory(request)

        except Exception as e:
            print("Error:", e)
            return ShowAllSubCategory(request)

def EditSubCategoryImage(request):
    try:
        scid=request.GET['scid']
        subcategoryname = request.GET['subcategoryname']
        subcategorypic = request.GET['subcategorypic']
        row=[scid,subcategoryname,subcategorypic]

        return render(request,"EditSubCategoryImage.html",{'row':row})
    except Exception as e:
        print("Error:",e)
        return render(request, "EditSubCategoryImage.html", {'row': row})

def SaveSubCategoryImage(request):
    try:
      scid = request.POST['scid']
      oldpic=request.POST['oldpic']
      picture = request.FILES['picture']
      filename=str(uuid.uuid4())+picture.name[picture.name.rfind('.'):]

      q="update subcategory set subcategorypic='{}' where subcategoryid={}".format(filename,scid)
      db,cmd=Pool.ConnectionPool()
      cmd.execute(q)
      F = open("D:/MM/assets/SubCategoryImages/"+filename, "wb")
      for chunk in picture.chunks():
          F.write(chunk)
      F.close
      db.commit()
      db.close()
      os.remove("D:/MM/assets/SubCategoryImages/"+oldpic)
      return ShowAllSubCategory(request)

    except Exception as e:
        print("Error:", e)
        return ShowAllSubCategory(request)


# -*- coding: utf-8 -*-
# Needs environmental variable PAGES_TEMPLATE to be set as the absolute path
# to the html template file.

import os
# External import
import bs4

def main(originalFilePath, newDirPath=""):
    """Applies the template to the html file. Keeps the content of the div with
    the id "contenu".

    Arguments:
        originalFilePath {rString} -- absolute path to the html file.
        newDirPath {rString} -- directory of the output file.

    Returns the absolute path  of the created file."""
    fileName = originalFilePath[originalFilePath.rfind("\\")+1:]
    # Checks if it's a "special-pages" page
    prevRep = originalFilePath[originalFilePath[:originalFilePath.rfind(fileName)-1].rfind("\\")+1:originalFilePath.rfind(fileName)-1]
    if prevRep == "special-pages":
        fileName = "special-pages\\" + fileName
        os.makedirs(os.path.dirname(newDirPath + "\\" + fileName), exist_ok=True)

    # Gets Pages template
    PAGES_TEMPLATE = os.getenv("PAGES_TEMPLATE")
    with open(PAGES_TEMPLATE, mode="r", encoding="utf-8") as f:
        template = bs4.BeautifulSoup(f, "html.parser")

    with open(originalFilePath, mode="r+", encoding="utf-8") as f:
        soup = bs4.BeautifulSoup(f, "html.parser")
        content = soup.find(id="contenu")
        template.find(id="contenu").clear()
        template.find(id="contenu").append(content)
        title = template.find(id="pageName").string
        template.title.append(title)
        template.find(id="pageName").string = title

    # Applies changes
    with open(newDirPath + "\\" + fileName, mode="w", encoding="utf-8") as f:
        f.seek(0 , 0)
        f.truncate()
        f.write(str(template))

    return newDirPath + "\\" + fileName

##main(r"D:\transform_github\original_repos\404.html", r"D:\transform_github\a_upload")


import threading
import itertools
import time

# this will later be used to add a loading '...' to some text
done_dot=False

def dotdotdot(text):
    for c in itertools.cycle(['.', '..', '...','']):
        if done_dot:
            break
        sys.stdout.write('\r'+text+c)
        sys.stdout.flush()
        time.sleep(0.3)
    sys.stdout.write('\nDone!')

# needed for the next function
import subprocess
import importlib

# function that imports a library if it is installed, else installs it and then imports it
def getpack(package):
    try:
        return importlib.import_module(package)
        # import package
    except ImportError:
        subprocess.call([sys.executable, "-m", "pip", "install", package],
                        stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        return importlib.import_module(package)
        # import package

# import necessary packages
from eff_fron import *
pd = getpack("pandas")
yf = getpack("yfinance")
bs = getpack("bs4")
requests = getpack("requests")
plt = getpack("matplotlib.pyplot")
import random

# get the tickers of all stocks in the SP500
def sp500_tickers():
    resp = requests.get('http://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
    soup = bs.BeautifulSoup(resp.text, 'lxml')
    table = soup.find('table', {'class': 'wikitable sortable'})
    tickers = []
    for row in table.findAll('tr')[1:]:
        ticker = row.findAll('td')[0].text
        ticker = ticker.replace("\n", "")
        tickers.append(ticker)

    return tickers

# get the returns for a given list of tickers
def get_returns(tickers):
    returns = []

    # keep track of number of requests
    n_requests = 0
    # for tickers with insufficient return data
    insufficient = []
    print("Downloading return-information, this might takes some time.", end='\r')
    for i in tickers:
        # get data
        data_tick = yf.Ticker(i)
        # daily changes of past 1-years in percent
        ret = data_tick.history(period="1y").Close
        ret = [ret1 / ret2 - 1 for ret1, ret2 in zip(ret[1:], ret)]
        if len(ret) == 250:
            returns.append(ret)
        else:
            insufficient.append(i)
        del ret

        n_requests += 1
        print(f"Downloading return-information, this might takes some time. ({n_requests}/{len(tickers)})", end='\r')

    print("\nReturns downloaded.")
    if len(insufficient) > 0:
        print(f"The following tickers will be omitted because of insufficient data: {', '.join(insufficient)}.\n"
              f"This could be due to the company going public within the last year or no information being available on"
              f" Yahoo finance.")
    print("\n")

    return returns

# generate random portfolio weights for the random portfolios in the visualization
def random_weights(n, k):
    return np.random.dirichlet(np.ones(n), size=k)

def main():
    # for dotdotdot function
    global done_dot

    print("Welcome, this is a cmd-line interface tool to calculate minimum risk portfolio weights for a given set of "
          "stocks and a selected expected return  (daily).")
    print("In other words, this script calculated the portfolio weights and standard deviation for a portfolio at point"
          " mu_p of the efficient frontier.")
    print("If you are unfamiliar with Moskowitz's Efficient Frontier please read the README.md file.\n")

    while True:
        done_dot = False
        sel = input("\nIf you want to run a simulation for a custom group of (U.S.) stocks enter '0'.\n"
                    "If you want to run a simulation for all stocks within the SP500 "
                    "enter '1'. Disclaimer: depending on your hardware this might take very long or not work at all.\n"
                    "If you want to run a simulation for a random sample of stocks within the SP500 enter '2'\n\n"
                    "To end the program enter 'q'\n")

        # end program/loop if q is entered
        if sel == 'q':
            break

        # if custom portfolio get ticker input
        elif sel == '0':
            tickers = [x for x in input("Please enter the tickers of the stocks you want to include in your portfolio."
                                        " Seperate them by a space: ").split()]

        # if not custom either draw a sample of SP500 or use all (depending on selection)
        elif sel == '1' or sel == '2':
            tickers = sp500_tickers()
            if sel == '2':
                tickers = random.sample(tickers, int(input("How many securities should be in your random sample: ")))

        else:
            print("invalid selection")

        # get returns and whether short-selling should be incorporated
        returns = get_returns(tickers)
        option = int(input("If you want to incorporate short selling enter '1' else enter '0': "))

        # expected returns and covariance matrix
        mus = [np.mean(i) for i in returns]
        cov_m = np.cov(returns)

        # load weights result into df
        results = pd.DataFrame(list(zip(tickers, mus, [np.std(i) for i in returns])),
                               columns=["Ticker", "expected return", "standard dev"])
        pd.set_option('display.max_rows', results.shape[0] + 1)
        print(results)

        # get target return
        mu_target = float(input(f"Please enter your target return (e.g.: 5% as 0.05):"))

        # prepare a loading message
        t = threading.Thread(target=dotdotdot, args=("Calculating optimal portfolio, this may take some time",))
        # starting loading... thread
        t.start()

        # get risk-free rate e.g. 3-month t-bill
        # rf = yf.Ticker("^IRX").history(period="1y").Close[-1] / 100
        # rf = (1 + rf) ** (1 / 60) - 1
        rf = 0.0

        # risk minimizing portfolio for target return (or max possible return)
        res = optimal_portfolio(mus, cov_m, mu_target, rf, option)

        # minimum variance portfolio
        min_var = min_var_portfolio(mus, cov_m, rf)

        # calculate some portfolios on the frontier for visualization
        r_range = np.linspace(min_var.mu, max(mus), 75)
        efficient_fron = efficient_frontier(mus, cov_m, rf, r_range)
        del r_range

        # The code below could be used to calculate the tangency portfolio. Since this programm works with daily
        # returns, and I could not find a satisfactory solution for a daily risk free rate, it is not implemented.
        # tang_port = tangency_portfolio(mus, cov_m,rf)

        # end loading '...'
        done_dot = True
        time.sleep(0.3)
        print("\n")

        # display results and additional information
        print(f"The risk-minimizing portfolio for your selection has a standard deviation of {round(res.std,5)}, "
              f"an expected return of {round(res.mu,5)} and the following weights on the securities:")

        # make sure all rows will be displayed

        results["weights"] = [round(i, 5) for i in res.weights]
        pd.set_option('display.max_rows', results.shape[0] + 1)
        print(results)

        # if target mu and real mu differ more than 1 percent
        if abs(mu_target - res.mu) >= mu_target*0.01:
            print(f"\nYour target return of {mu_target} could not be reached. Try to integrate shortselling.")

        if min_var.mu > res.mu:
            print(f"\nAttention: though this portfolio minimizes the risk for your chosen return, the minimal risk "
                  f"portfolio achieves a higher mean return ({round(min_var.mu,5)}) with a standard deviation of "
                  f"{round(min_var.std,5)}. The weights on the minimal risk portfolio are: {min_var.weights}\n")

        # visualization option
        if 'y' in input("Would you like to see this result on the efficient frontier? (y/n)   "):
            # random portfolios for scatter plot
            rand_mus = []
            rand_std = []
            rand_sr = []

            for i in random_weights(len(tickers), len(tickers)*4000):
                r_mu = sum([i[j] * mus[j] for j in range(len(tickers))])
                rand_mus.append(r_mu)
                r_sig = sigma_p(i, cov_m)
                rand_std.append(r_sig)
                rand_sr.append((r_mu-rf)/r_sig)

            plt.scatter(rand_std, rand_mus, c=rand_sr, cmap='YlGnBu', marker='o', s=10, alpha=0.2)
            plt.title('Portfolio Optimization based on Efficient Frontier')
            plt.xlabel('Standard deviation')
            plt.ylabel('Expected return')
            plt.colorbar().set_label('Sharpe ratio')

            # chosen portfolio, minimum variance portfolio, tangency portfolio and efficient frontier
            plt.scatter(res.std, res.mu, marker='*', s=25, c='red', label="Your portfolio")
            plt.scatter(min_var.std, min_var.mu, marker='D', s=25, c='darkgreen', label="Minimum variance")
            # plt.scatter(tang_port.std, tang_port.mu, marker='^', s=25, c='gold', label="Tangency portfolio")
            plt.plot([p.std for p in efficient_fron], [p.mu for p in efficient_fron], linestyle='-.', color='black',
                     label='efficient frontier')

            plt.legend()

            plt.show()

            del rand_mus, rand_std

        if 'n' in input("Do you want to run another simulation? (y/n)   "):
            break

    print("Thank you.\nGoodbye.")

main()