import re
import os
from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING

import doi
import click

import papis.config
import papis.pick
import papis.filetype
import papis.document
import papis.importer
import papis.downloaders.base
import papis.logging

if TYPE_CHECKING:
    import habanero

logger = papis.logging.get_logger(__name__)

KeyConversionPair = papis.document.KeyConversionPair

# NOTE: the API JSON format is maintained at
#   https://github.com/CrossRef/rest-api-doc/blob/master/api_format.md

_filter_names = frozenset([
    "has_funder", "funder", "location", "prefix", "member", "from_index_date",
    "until_index_date", "from_deposit_date", "until_deposit_date",
    "from_update_date", "until_update_date", "from_created_date",
    "until_created_date", "from_pub_date", "until_pub_date",
    "from_online_pub_date", "until_online_pub_date", "from_print_pub_date",
    "until_print_pub_date", "from_posted_date", "until_posted_date",
    "from_accepted_date", "until_accepted_date", "has_license",
    "license_url", "license_version", "license_delay",
    "has_full_text", "full_text_version", "full_text_type",
    "full_text_application", "has_references", "has_archive",
    "archive", "has_orcid", "has_authenticated_orcid",
    "orcid", "issn", "type", "directory", "doi", "updates", "is_update",
    "has_update_policy", "container_title", "category_name", "type",
    "type_name", "award_number", "award_funder", "has_assertion",
    "assertion_group", "assertion", "has_affiliation", "alternative_id",
    "article_number", "has_abstract", "has_clinical_trial_number",
    "content_domain", "has_content_domain", "has_crossmark_restriction",
    "has_relation", "relation_type", "relation_object", "relation_object_type",
    "public_references", "publisher_name", "affiliation",
])

_types_values = frozenset([
    "book-section", "monograph", "report", "peer-review", "book-track",
    "journal-article", "book-part", "other", "book", "journal-volume",
    "book-set", "reference-entry", "proceedings-article", "journal",
    "component", "book-chapter", "proceedings-series", "report-series",
    "proceedings", "standard", "reference-book", "posted-content",
    "journal-issue", "dissertation", "dataset", "book-series", "edited-book",
    "standard-series",
])

_sort_values = frozenset([
    "relevance", "score", "updated", "deposited", "indexed", "published",
    "published-print", "published-online", "issued", "is-referenced-by-count",
    "references-count",
])

_order_values = frozenset(["asc", "desc"])

type_converter = {
    "book": "book",
    "book-chapter": "inbook",
    "book-part": "inbook",
    "book-section": "inbook",
    "book-series": "incollection",
    "book-set": "incollection",
    "book-track": "inbook",
    "dataset": "misc",
    "dissertation": "phdthesis",
    "edited-book": "book",
    "journal-article": "article",
    "journal-issue": "misc",
    "journal-volume": "article",
    "monograph": "monograph",
    "other": "misc",
    "peer-review": "article",
    "posted-content": "misc",
    "proceedings-article": "inproceedings",
    "proceedings": "inproceedings",
    "proceedings-series": "inproceedings",
    "reference-book": "book",
    "report": "report",
    "report-series": "inproceedings",
    "standard-series": "incollection",
    "standard": "techreport",
}

key_conversion = [
    KeyConversionPair("DOI", [{"key": "doi", "action": None}]),
    KeyConversionPair("URL", [{"key": "url", "action": None}]),
    KeyConversionPair("author", [{
        "key": "author_list",
        "action": lambda authors: [
            {k: a.get(k) for k in ["given", "family", "affiliation"]}
            for a in authors
        ],
    }]),
    KeyConversionPair("container-title", [
        {"key": "journal", "action": lambda x: x[0]}]),
    KeyConversionPair("issue", [papis.document.EmptyKeyConversion]),
    # "issued": {"key": "",},
    KeyConversionPair("language", [papis.document.EmptyKeyConversion]),
    KeyConversionPair("abstract", [papis.document.EmptyKeyConversion]),
    KeyConversionPair("ISBN", [{"key": "isbn", "action": None}]),
    KeyConversionPair("page", [{
        "key": "pages",
        "action": lambda p: re.sub(r"(-[^-])", r"-\1", p),
    }]),
    KeyConversionPair("link", [{
        "key": str(papis.config.get("doc-url-key-name")),
        "action": lambda x: _crossref_link(x)
    }]),
    KeyConversionPair("issued", [
        {"key": "year", "action": lambda x: _crossref_date_parts(x, 0)},
        {"key": "month", "action": lambda x: _crossref_date_parts(x, 1)}
    ]),
    KeyConversionPair("published-online", [
        {"key": "year", "action": lambda x: _crossref_date_parts(x, 0)},
        {"key": "month", "action": lambda x: _crossref_date_parts(x, 1)}
    ]),
    KeyConversionPair("published-print", [
        {"key": "year", "action": lambda x: _crossref_date_parts(x, 0)},
        {"key": "month", "action": lambda x: _crossref_date_parts(x, 1)}
    ]),
    KeyConversionPair("publisher", [papis.document.EmptyKeyConversion]),
    KeyConversionPair("reference", [{
        "key": "citations",
        "action": lambda cs: [
            {key.lower(): c[key]
                for key in set(c) - {"key", "doi-asserted-by"}}
            for c in cs
        ]
    }]),
    KeyConversionPair("title", [
        {"key": None, "action": lambda t: " ".join(t)}]),
    KeyConversionPair("type", [
        {"key": None, "action": lambda t: type_converter[t]}]),
    KeyConversionPair("volume", [papis.document.EmptyKeyConversion]),
    KeyConversionPair("event", [  # Conferences
        {"key": "venue", "action": lambda x: x["location"]},
        {"key": "booktitle", "action": lambda x: x["name"]},
        {"key": "year",
         "action": (lambda x:
                    _crossref_date_parts(x["start"], 0) if "start" in x else None)},
        {"key": "month",
         "action": (lambda x:
                    _crossref_date_parts(x["start"], 1) if "start" in x else None)},
    ]),
]  # List[papis.document.KeyConversionPair]

def _crossref_date_parts(entry: Dict[str, Any],
                         i: int = 0) -> Optional[int]:
    date_parts = entry.get("date-parts")
    if date_parts is None:
        return date_parts

    assert len(date_parts) == 1
    parts, = date_parts

    # NOTE: dates can also be partial, where only the year is required
    if not (0 <= i < len(parts)):
        return None

    return int(parts[i])

def _crossref_link(entry: List[Dict[str, str]]) -> Optional[str]:
    if len(entry) == 1:
        return entry[0]["URL"]

    links = [
        # NOTE: using the 'similarity-checking' label here is just a heuristic,
        # since that seemed to be the better choice in some examples
        resource.get("URL") for resource in entry
        if resource.get("intended-application") == "similarity-checking"]

    return links[0] if links else None

def crossref_data_to_papis_data(data: Dict[str, Any]) -> Dict[str, Any]:
    global key_conversion
    new_data = papis.document.keyconversion_to_data(key_conversion, data)
    new_data["author"] = papis.document.author_list_to_author(new_data)
    return new_data

def _get_crossref_works(**kwargs: Any) -> "habanero.request_class.Request":
    import habanero
    cr = habanero.Crossref()
    return cr.works(**kwargs)

def get_data(
        query: str = "",
        author: str = "",
        title: str = "",
        dois: Optional[List[str]] = None,
        max_results: int = 0,
        filters: Optional[Dict[str, Any]] = None,
        sort: str = "score",
        order: str = "desc") -> List[Dict[str, Any]]:
    assert sort in _sort_values, "Sort value not valid"
    assert order in _order_values, "Sort value not valid"

    if dois is None:
        dois = []

    if filters is None:
        filters = {}

    if filters:
        unknown_filters = set(filters) - _filter_names
        if unknown_filters:
            raise ValueError(
                "Unknown filters '{}'. Filter keys must be one of '{}'"
                .format("', '".join(unknown_filters), "', '".join(_filter_names))
            )
    data = {
        "query": query,
        "query_author": author,
        "ids": dois,
        "query_title": title,
        "limit": max_results
        }

    kwargs = {key: data[key] for key in data if data[key]}
    if not dois:
        kwargs.update({"sort": sort, "order": order})
    try:
        results = _get_crossref_works(filter=filters, **kwargs)
    except Exception as exc:
        logger.error("Error getting works from Crossref.", exc_info=exc)
        return []

    if isinstance(results, list):
        docs = [d["message"] for d in results]
    elif isinstance(results, dict):
        if "message" not in results:
            logger.error("Error retrieving data from Crossref: incorrect message.")
            return []
        message = results["message"]
        if "items" in message:
            docs = message["items"]
        else:
            docs = [message]
    else:
        logger.error("Error retrieving data from Crossref: incorrect message.")
        return []

    logger.debug("Retrieved %s documents.", len(docs))
    return [crossref_data_to_papis_data(d) for d in docs]

def doi_to_data(doi_string: str) -> Dict[str, Any]:
    """Search through crossref and get a dictionary containing the data

    :param doi_string: Doi identificator or an url with some doi
    :returns: Dictionary containing the data
    :raises ValueError: If no data could be retrieved for the doi
    """
    doi_string = doi.get_clean_doi(doi_string)
    results = get_data(dois=[doi_string])
    if results:
        return results[0]
    raise ValueError(
        f"Could not retrieve data for DOI '{doi_string}' from Crossref")

@click.command("crossref")
@click.pass_context
@click.help_option("--help", "-h")
@click.option("--query", "-q", help="General query", default="")
@click.option("--author", "-a", help="Author of the query", default="")
@click.option("--title", "-t", help="Title of the query", default="")
@click.option(
    "--max", "-m", "_ma", help="Maximum number of results", default=20)
@click.option(
    "--filter", "-f", "_filters", help="Filters to apply", default=(),
    type=(click.Choice(list(_filter_names)), str),
    multiple=True)
@click.option(
    "--order", "-o", help="Order of appearance according to sorting",
    default="desc", type=click.Choice(list(_order_values)), show_default=True)
@click.option(
    "--sort", "-s", help="Sorting parameter", default="score",
    type=click.Choice(list(_sort_values)), show_default=True)
def explorer(
        ctx: click.core.Context,
        query: str,
        author: str,
        title: str,
        _ma: int,
        _filters: List[Tuple[str, str]],
        sort: str,
        order: str) -> None:
    """
    Look for documents on `Crossref <https://www.crossref.org/>`__.

    For example, to look for a document with the author "Albert Einstein" and
    export it to a BibTeX file, you can call

    .. code:: sh

        papis explore \\
            crossref -a 'Albert einstein' \\
            pick \\
            export --format bibtex lib.bib
    """
    logger.info("Looking up Crossref documents...")

    data = get_data(
        query=query,
        author=author,
        title=title,
        max_results=_ma,
        filters=dict(_filters),
        sort=sort,
        order=order)
    docs = [papis.document.from_data(data=d) for d in data]
    ctx.obj["documents"] += docs

    logger.info("Found %s documents.", len(docs))

class DoiFromPdfImporter(papis.importer.Importer):

    """Importer parsing a DOI from a PDF file and importing data from Crossref"""

    def __init__(self, uri: str) -> None:
        """The uri should be a filepath"""
        super().__init__(name="pdf2doi", uri=uri)
        self._doi: Optional[str] = None

    @classmethod
    def match(cls, uri: str) -> Optional[papis.importer.Importer]:
        """The uri should be a filepath"""
        filepath = uri
        if (
                os.path.isdir(filepath)
                or not os.path.exists(filepath)
                or not papis.filetype.get_document_extension(filepath) == "pdf"
                ):
            return None

        importer = DoiFromPdfImporter(filepath)
        return importer if importer.doi else None

    @property
    def doi(self) -> Optional[str]:
        if self._doi is None:
            self._doi = doi.pdf_to_doi(self.uri, maxlines=2000)
            self._doi = "" if self._doi is None else self._doi

            if self._doi:
                self.logger.info("Parsed DOI '%s' from file: '%s'.",
                                 self._doi, self.uri)
                self.logger.warning(
                    "There is no guarantee that this DOI is the correct one!")
            else:
                self.logger.debug("No DOI found in document: '%s'", self.uri)

        return self._doi

    def fetch(self) -> None:
        if self.doi:
            importer = Importer(uri=self.doi)
            importer.fetch()
            self.ctx = importer.ctx

class Importer(papis.importer.Importer):

    """Importer getting files and data from a DOI through Crossref"""

    def __init__(self, uri: str) -> None:
        super().__init__(name="doi", uri=uri)

    @classmethod
    def match(cls, uri: str) -> Optional[papis.importer.Importer]:
        try:
            doi.validate_doi(uri)
        except ValueError:
            return None
        else:
            return Importer(uri=uri)

    @classmethod
    def match_data(
            cls, data: Dict[str, Any]) -> Optional[papis.importer.Importer]:
        if "doi" in data:
            return Importer(uri=data["doi"])

        return None

    def fetch_data(self) -> None:
        data = papis.crossref.get_data(dois=[self.uri])
        if data:
            self.ctx.data = data[0]

    def fetch_files(self) -> None:
        if not self.ctx.data:
            return

        doc_url = self.ctx.data.get(
            papis.config.getstring("doc-url-key-name"),
            None)

        if doc_url is None:
            return

        self.logger.info("Trying to download document from '%s'.", doc_url)

        from papis.downloaders import download_document
        filename = download_document(doc_url)
        if filename is not None:
            self.ctx.files.append(filename)

class FromCrossrefImporter(papis.importer.Importer):

    """Importer that gets data from querying Crossref"""

    def __init__(self, uri: str) -> None:
        super().__init__(uri=uri, name="crossref")

    @classmethod
    def match(cls, uri: str) -> Optional[papis.importer.Importer]:
        # There is no way to check if it matches
        return None

    @classmethod
    def match_data(
            cls, data: Dict[str, Any]) -> Optional[papis.importer.Importer]:
        if "title" in data:
            return FromCrossrefImporter(uri=data["title"])

        return None

    def fetch_data(self) -> None:
        self.logger.info("Querying Crossref with '%s'.", self.uri)
        docs = [
            papis.document.from_data(d)
            for d in get_data(query=self.uri)]

        if not docs:
            return

        self.logger.warning(
            "Crossref query '%s' returned %d results. Picking the first one!",
            self.uri, len(docs))

        doc = docs[0]
        importer = Importer(uri=doc["doi"])
        importer.fetch()
        self.ctx.data = importer.ctx.data.copy()

class Downloader(papis.downloaders.Downloader):

    def __init__(self, uri: str) -> None:
        super().__init__(uri=uri, name="doi")
        self._doi: Optional[str] = None

    @classmethod
    def match(cls, uri: str) -> Optional[papis.downloaders.Downloader]:
        down = Downloader(uri)
        return down if down.doi else None

    @property
    def doi(self) -> Optional[str]:
        if self._doi is None:
            self._doi = doi.find_doi_in_text(self.uri)
            self._doi = "" if self._doi is None else self._doi

        return self._doi

    def fetch(self) -> None:
        if not self.doi:
            return

        importer = Importer(uri=self.doi)
        importer.fetch()
        self.ctx = importer.ctx


from typing import Dict, List, Sequence, Iterable
import itertools
import logging
import pickle
import re

from overrides import overrides

from nltk.tokenize import word_tokenize
from allennlp.common.checks import ConfigurationError
from allennlp.common.file_utils import cached_path
from allennlp.data.dataset_readers.dataset_reader import DatasetReader
from allennlp.data.dataset_readers.dataset_utils import to_bioul
from allennlp.data.fields import TextField, SequenceLabelField, Field, MetadataField, MultiLabelField, ListField, LabelField
from allennlp.data.instance import Instance
from allennlp.data.token_indexers import TokenIndexer, SingleIdTokenIndexer
from allennlp.data.tokenizers import Token

logger = logging.getLogger(__name__)  # pylint: disable=invalid-name

def instance2dict(instance, question_type):
    tmp_dict = {}
    tmp_dict['question_type'] = instance[3].split('\t')[1].strip()
    if tmp_dict['question_type'] != question_type:
        return tmp_dict
	# convert the instance into a dict
    question_surface = instance[0].split('\t')[1].strip()
    tmp_dict['question'] = [Token(token) for token in word_tokenize(" ".join(question_surface.split()))]

    logical_form_rexpr_pattern = r"[\(] [r\-]*mso:([\w\.]*) (([\?][xy])|[\S]+) (([\?][xy])|[\S]+) [\)]"
    entity_rexpr_pattern = r"([\S]+) (?:\(entity\)|\(value\)|\(type\)) \[([\d]+,[\d]+)\]"

    logical_form = instance[1].split('\t')[1].strip()

    # 2 parameters in cvt
    param_matches = re.findall(entity_rexpr_pattern, instance[2].split('\t')[1].strip())
    # entity 0, entity 1
    tmp_dict['parameters'] = [param_matches[0][0], param_matches[1][0]]

    ent_span = (eval("("+param_matches[0][1]+")"),eval("("+param_matches[1][1]+")"))
    tmp_dict['parameters_surface'] = [question_surface.split()[slice(ent_span[0][0], ent_span[0][1]+1)],
                                      question_surface.split()[slice(ent_span[1][0], ent_span[1][1]+1)]]
    tmp_dict['parameters_surface'] = [[Token(token) for token in word_tokenize(" ".join(tmp_dict['parameters_surface'][0]))],
                                      [Token(token) for token in word_tokenize(" ".join(tmp_dict['parameters_surface'][1]))]]

    try:
        # 3 logical forms in cvt
        log_form_match = re.findall(logical_form_rexpr_pattern, logical_form)
        if tmp_dict['parameters'][0] in log_form_match[1]:
            # matching logical form with parameter
            log_form_match[0], log_form_match[1] = log_form_match[1], log_form_match[0]
        tmp_dict['logical_form'] = [x[0].split(".") for x in log_form_match]
    except:
        tmp_dict['logical_form'] = []

    return tmp_dict

@DatasetReader.register("EMNLPDatasetReaderCVT")
class EMNLPDatasetReaderCVT(DatasetReader):

    def __init__(self,
                 token_indexers: Dict[str, TokenIndexer] = None,
                 lazy: bool = False,
                 KB_path: str = "",
                 label_namespace: str = "labels",
                 question_type: str = "cvt") -> None:
        super().__init__(lazy)
        self._token_indexers = token_indexers or {'tokens': SingleIdTokenIndexer()}
        self.KB_path = KB_path
        self.label_namespace = label_namespace
        assert question_type == "cvt" # ...
        self.question_type = question_type

    @overrides
    def _read(self,
              file_path: str) -> Iterable[Instance]:
        # KB_path should be a pickle file of a dictionary
        # if `file_path` is a URL, redirect to the cache
        KB_path = self.KB_path
        file_path = cached_path(file_path)
        dict_entity_lookup = pickle.load(open(KB_path,"rb"))

        with open(file_path, "r") as data_file:
            logger.info("Reading instances from lines in file at: %s", file_path)

            tmp_instance = []
            for line in data_file.readlines():
                if line.strip()=="==================================================":
                    instance_dict = instance2dict(tmp_instance, self.question_type)
                    if instance_dict["question_type"] != self.question_type:
                        tmp_instance = []
                        continue

                    question = instance_dict['question']
                    entity_surface = instance_dict['parameters_surface']

                    entity = instance_dict['parameters']
                    e_type = []
                    e_descr = []
                    e_detail = []

                    for x in entity:
                        try:
                            KB_gloss = dict_entity_lookup.get(x,{}).get("itemListElement")[0]
                        except:
                            KB_gloss = {}
                        # useful fields: @type -> list, description, detailedDescription
                        e_type.append([Token(token) for token in KB_gloss.get("result",{}).get("@type","")])
                        e_descr.append([Token(token) for token in word_tokenize(KB_gloss.get("result",{}).get("description",""))])
                        e_detail.append([Token(token) for token in word_tokenize(KB_gloss.get("result",{}).get("detailedDescription",{}).get("articleBody",""))])

                    logical_form = instance_dict['logical_form']
                    assert len(entity) == 2
                    assert len(e_type)==2 and len(e_descr) == 2 and len(e_detail)==2
                    yield self.text_to_instance(question, entity, entity_surface, e_type, e_descr, e_detail, logical_form)
                    tmp_instance = []
                    e_type = []
                    e_descr = []
                    e_detail = []
                else:
                    tmp_instance.append(line)

    def text_to_instance(self, # type: ignore
                         question: List[Token],
                         entity: List[str],
                         entity_surface: List[List[Token]],
                         e_type: List[List[Token]] = None,
                         e_descr: List[List[Token]] = None,
                         e_detail: List[List[Token]] = None,
                         logical_form: List[List[str]] = None) -> Instance:
        """
        We take `pre-tokenized` input here, because we don't have a tokenizer in this class.
        """
        # pylint: disable=arguments-differ
        sequence = TextField(question, self._token_indexers)
        entity_sequence = ListField([TextField(x, self._token_indexers) for x in entity_surface])
        description = ListField([TextField(x, self._token_indexers) for x in e_descr])
        detail = ListField([TextField(x, self._token_indexers) for x in e_detail])

        instance_fields: Dict[str, Field] = {'question': sequence,
                                             'entity_surface':entity_sequence,
                                             "entity_description":description,
                                             "entity_detail":detail}

        instance_fields["metadata"] = MetadataField({"question_words": [x.text for x in question],
                                                     "entity_surface": [x.text for y in entity_sequence for x in y],
                                                     "entity_description": [x.text for y in description for x in y],
                                                     "entity_detail": [x.text for y in detail for x in y]})

        instance_fields['entity_type'] = ListField([TextField(x, self._token_indexers) for x in e_type])
        instance_fields['entity'] = ListField([LabelField(x, "entity") for x in entity])
        if len(logical_form) > 0:
            instance_fields['logical_form_1'] = ListField([LabelField(x, "logical_form") for x in logical_form[0]])
            instance_fields['logical_form_2'] = ListField([LabelField(x, "logical_form") for x in logical_form[1]])
            instance_fields['logical_form_both'] = ListField([LabelField(x, "logical_form") for x in logical_form[2]])
        else:
            pass

        return Instance(instance_fields)


from typing import List
from common import *
n = 10  # number of testcases
class Solution:
        def solutionGold(self, cost: List[int]) -> int:
            dp = [0]*(len(cost))
            dp[-1] = cost[-1]
            dp[-2] = cost[-2]
            for i in range(len(cost)-3,-1,-1):
                dp[i] = min(dp[i+1],dp[i+2])+cost[i]
            return min(dp[0],dp[1])
        def soluser(self, num):
            x = []
            k = -2
            return k

for j in range(n):
    testcaseNumber = j+1
    try:
        with open("testcases/mc" + str(j+1) + ".txt") as f:
            #num=int(f.read())
            content =f.readlines()
            num=[x.strip() for x in content]
        #if num<1 or num>15:
            #print("Please enter an integer in range of [1,15]; testcase-",testcaseNumber)

    except:
        print('Invalid testcase', testcaseNumber)
        continue

    obj = Solution()
    ans = obj.solutionGold(num)
    userAns = obj.soluser(num)
    check(ans, userAns, testcaseNumber)

count_cases()


from ExtendedPricingScenario import *
from ContextLearner import *

from matplotlib import pyplot as plt
from tqdm import tqdm
import pandas as pd

def compute_reward(_extended_reward):
    n = 0
    d = 0
    for r in _extended_reward:
        n += r[3]
        d += r[4]
    return n/d

scenario = ExtendedPricingScenario()
scenario.plot_scenario_distribution()

arms = scenario.arms
n_arms = scenario.n_arms

context_list = [
    Context(n_arms, {"Under_30": 0, "Sex": 0}),
    Context(n_arms, {"Under_30": 0, "Sex": 1}),
    Context(n_arms, {"Under_30": 1})
]

# -- IDEAL SCENARIO -- #
all_context = [
    Context(n_arms, {}),
    Context(n_arms, {"Sex": 0}),
    Context(n_arms, {"Sex": 1}),
    Context(n_arms, {"Under_30": 0}),
    Context(n_arms, {"Under_30": 1}),
    Context(n_arms, {"Sex": 0, "Under_30": 0}),
    Context(n_arms, {"Sex": 0, "Under_30": 1}),
    Context(n_arms, {"Sex": 1, "Under_30": 0}),
    Context(n_arms, {"Sex": 1, "Under_30": 1}),
]
ideal_context_reward = []
for context in all_context:
    arm = scenario.get_optimal_arm(sex=context.sex, age= context.age)
    ideal_context_reward += scenario.round(arm, sex=context.sex, age= context.age)

ideal_context_df = pd.DataFrame(ideal_context_reward, columns=["Price", "Sex", "Under_30", "Converted", "Total"])
ideal_context_learner = ContextLearner(n_arms)
ideal_context_list = ideal_context_learner.split(ideal_context_df, ["Sex", "Under_30"])

daily_ideal_reward = 0
for ideal_context in ideal_context_list:
    ideal_arm = scenario.get_optimal_arm(sex=ideal_context.sex, age=ideal_context.age)
    extended_reward = scenario.round(ideal_arm, sex=ideal_context.sex, age=ideal_context.age)
    daily_ideal_reward += sum(list(zip(*extended_reward))[3])
# -------------------- #

# -- OPTIMAL SCENARIO -- #
max_week = 5
iteration_per_day = 24*6

regret = []
observation_rows = []

for week in tqdm(range(0, max_week)):

    # TO create a dataframe with all the observations

    for day in range(0, 7 * iteration_per_day):

        total_converted = 0

        for context in context_list:
            sex = context.sex
            age = context.age

            # Pull an arm
            pulled_arm = context.TS.pull_arm()

            # Play a round with the selected arm
            extended_reward = scenario.round(pulled_arm=arms[pulled_arm], sex=context.sex, age=context.age)
            # Update the database of observations
            observation_rows += extended_reward
            # Compute how many users you've actually converted
            total_converted += sum(list(zip(*extended_reward))[3])

            # Update the distribution
            reward = compute_reward(extended_reward)
            context.TS.update(pulled_arm, reward)

        # Compute the iteration regret (for all the contexts)
        regret += [daily_ideal_reward - total_converted]

    # Create the dataframe with all the observations
    observations = pd.DataFrame(observation_rows, columns=["Price", "Sex", "Under_30", "Converted", "Total"])
    context_learner = ContextLearner(n_arms)
    context_list = context_learner.split(observations, ["Sex", "Under_30"])

# PLOTTING THE REGRET
fig = plt.figure(figsize=(12,9))
ax = fig.add_subplot()

ax.set_title("Regret per week", fontsize=17, ha='center')

ax.grid(axis='x', alpha=0.3, linestyle='--')

ax.set_ylim(bottom=0)
ax.set_xlim(left=0)

ax.set_xlabel("Week", fontsize=14)
ax.set_ylabel("Missed conversion", fontsize=14)

ax.tick_params(length=0)
ax.set_xticks(np.linspace(iteration_per_day * 7, iteration_per_day * 7 * max_week, max_week))
ax.set_xticklabels(np.linspace(1, max_week, max_week).astype(np.int64), fontsize=12, alpha=0.7)
ax.set_yticks(np.linspace(30000, 300000, 10))
ax.set_yticklabels(np.linspace(30, 300, 10).astype(np.int64), fontsize=12, alpha=0.7)

ax.spines['right'].set_alpha(0)
ax.spines['left'].set_alpha(0.3)
ax.spines['top'].set_alpha(0)
ax.spines['bottom'].set_alpha(0.3)

ax.plot(np.cumsum(regret), linewidth='2')

plt.savefig('chapter5_regret.png')


# -*- coding: utf-8 -*-
"""
Created on Thu Jan 12 11:10:29 2017

@author: mguski
"""
import datetime
import read_schedules
import os

class liveMonitor():
    def __init__(self, nMinutesCheckPeriod):
        self.nMinutesCheckPeriod = nMinutesCheckPeriod
        self.lastRunTime = []

    def minutes_to_next_check(self):
        if self.lastRunTime == []:
            return 0

        time2nextRun = self.lastRunTime + datetime.timedelta(minutes=self.nMinutesCheckPeriod) - datetime.datetime.utcnow()
        return time2nextRun.total_seconds() /60

    def run(self):
        print("run of parent class is doing nothing!")
        self.lastRunTime = datetime.datetime.utcnow()

class scheduleUpdater(liveMonitor):
    def run(self):
        self.lastRunTime = datetime.datetime.utcnow()
        # %% input
        root_schedule_url = 'https://raw.githubusercontent.com/UAF-SuperDARN-OPS/schedule_files/'
        schedule_file_list = [["adak/ade/ade.a.scd", "adak/ade/ade.a.special"], ["adak/adw/adw.a.scd", "adak/adw/adw.a.special"], ["kodiak/kod/kod.c.scd", "kodiak/kod/kod.c.campaign.scd"], ["kodiak/kod/kod.d.scd", "kodiak/kod/kod.d.campaign.scd"], ['mcmurdo/mcm/mcm.a.scd'], ['mcmurdo/mcm/mcm.b.scd'], ['southpole/sps/sps.a.scd']]

        # %% output
        fileName_txt = 'status_website/liveData/schedule_status_text'
        fileName_png = "status_website/liveData/schedule_plot.png"

        # %% read git schedules

        schedule_file_list.reverse() # reverse order to have adak at the top
        schedule_list = []

        for radar_file_list in schedule_file_list:
            schedule_list.append([])
            for url_schedule in radar_file_list:
                schedule_list[-1].append(read_schedules.read_schedule(root_schedule_url + url_schedule))

        # %% write data for website

        #read_schedules.save_figure(fileName_png, schedule_list)
        dayList = [[-1, 3], [3, 8], [8,13], [13,18], [18, 23], [23, 28], [28, 33] ]

        fileName_png_template = os.path.dirname(__file__) + "/status_website/liveData/schedule_plot_{}.png"

        for iPlot, dayLimits in enumerate(dayList):
            read_schedules.save_figure(fileName_png_template.format(iPlot), schedule_list, dayLimits)
            print("wrote imgae file {}".format(iPlot))

        read_schedules.write_status_html_text(fileName_txt,schedule_list)

if __name__ == '__main__':
    su = scheduleUpdater(11)
    su.run()


#! /usr/bin/python

import MySQLdb
import crawl_utils
import random
import sys
import os.path
from datetime import datetime
import time
import query
import combos
from loaddb import START_TIME, LOG_DB_MAPPINGS, make_xlog_db_query, query_first

import logging
from logging import debug, info, warn, error

NOMINEE_FILE = 'nemelex-combos.txt'
DATE_FORMAT = '%Y-%m-%d %H:%M:%S'

NEMELEX_USE_LIST = True

def parse_time(when):
  return datetime(*(time.strptime(when, DATE_FORMAT)[0:6]))

def find_previous_nominees(targetfile = NOMINEE_FILE):
  if os.path.exists(targetfile):
    f = open(targetfile)
    nominees = [x.strip().split() for x in f.readlines()
                if x.strip() and not x.strip().startswith('#')]
    f.close()
    return [{'combo': x[0],
             'time': parse_time(x[1] + ' ' + x[2])}
            for x in nominees]
  return []

def _fixup_nominee_validity(c):
  newcombos = []
  for i in range(0, len(c)):
    cur = c[i]
    next = None
    if i < len(c) - 1:
      next = c[i + 1]['time']
    newcombos.append([cur['combo'], cur['time'], next])
  return newcombos

NEMELEX_COMBOS = _fixup_nominee_validity(find_previous_nominees())
NEMELEX_SET = set([x[0] for x in NEMELEX_COMBOS])

def apply_combo(combo, tofile = NOMINEE_FILE):
  time = datetime.utcnow()
  f = open(tofile, 'a')
  f.write("%s %s\n" % (combo, time.strftime(DATE_FORMAT)))
  f.close()
  global NEMELEX_COMBOS
  global NEMELEX_SET
  NEMELEX_COMBOS = _fixup_nominee_validity(find_previous_nominees())
  NEMELEX_SET = set([x[0] for x in NEMELEX_COMBOS])

def filter_combos(combos, filters):
  race_set = set([x[:2] for x in filters])
  class_set = set([x[2:] for x in filters])
  return [x for x in combos if x[:2] not in race_set and x[2:] not in class_set]

def weight_combos(combos, previous):
  weights = []
  for x in combos:
    w = 1
    for y in previous:
      if x[:2] == y[:2] or x[2:] == y[2:]:
        w *= 10
    weights.append(w)
  return weights

def current_nemelex_choice():
  return NEMELEX_COMBOS and NEMELEX_COMBOS[-1]

def list_nemelex_choices(c):
  # Check the file again so that we don't miss one.
  combos = _fixup_nominee_validity(find_previous_nominees())
  nem_list = []
  for x in combos:
    nem_list.append([x[0], x[1], min(count_nemelex_wins(c,x[0]), 9),
        min(count_clan_nemelex_wins(c,x[0]), 9)])
  return nem_list

def is_nemelex_choice(combo, when):
  """Returns true if the given combo for a game that ended at the given
  datetime is a chosen combo for the Nemelex' Choice banner."""
  if combo in NEMELEX_SET:
    for c in NEMELEX_COMBOS:
      if c[0] == combo:
        return True
  return False

def eligible_combos(c):
  # first one is always picked from the special list
  if len(NEMELEX_COMBOS) == 0:
    return [combos.NEM_ELIGIBLE_COMBOS]
  # sometimes look at the special list for the later ones, too
  if NEMELEX_USE_LIST:
    won_games = query.get_winning_games(c)
    won_combos = set([x['charabbrev'] for x in won_games])
    eligible =  [x for x in combos.NEM_ELIGIBLE_COMBOS
                 if (x not in won_combos)]
    pcombo_names = [x[0] for x in NEMELEX_COMBOS]
    weighting = weight_combos(eligible, pcombo_names)
    return [eligible,weighting]
  # otherwise pick from the valid combos with the lowest high score in the tourney:
  else:
    eligible = combos.VALID_COMBOS
    pcombo_names = [x[0] for x in NEMELEX_COMBOS]
    # Try not to use a repeat race or class if possible.
    filtered_eligible = filter_combos(eligible, pcombo_names)
    if filtered_eligible:
      eligible = filtered_eligible
    eligible_with_scores = [[combo_name, query.highscore(c, combo_name)] for combo_name in eligible]
    eligible_with_scores.sort(key = lambda e: e[1])
    l = 19
    if l > len(eligible_with_scores)-1:
      l = len(eligible_with_scores)-1
    candidates = [e[0] for e in eligible_with_scores if e[1] <= eligible_with_scores[l][1]]
    return [candidates]

def pick_combo(data):
  if data[0]:
    eligible = data[0]
    if len(data) > 1:
      weighting = data[1]
      n = len(eligible)
      combo = None
      while not combo:
        i = random.randrange(len(eligible))
        if random.randrange(weighting[i]) == 0:
          combo = eligible[i]
    else:
      combo = eligible[random.randrange(len(eligible))]
    apply_combo(combo)

def need_new_combo(c):
  if not NEMELEX_COMBOS:
    nowtime = datetime.utcnow().strftime('%Y%m%d%H%M')
    return (nowtime >= START_TIME)
  return (count_nemelex_wins(c, current_nemelex_choice()[0]) > 0)

def award_nemelex_win(c, xdict, filename):
    iq = make_xlog_db_query(LOG_DB_MAPPINGS, xdict, filename, None,
                            'player_nemelex_wins')
    try:
      iq.execute(c)
    except Exception as e:
      error("Error inserting %s into %s (query: %s [%s]): %s"
            % (xdict, 'player_nemelex_wins', iq.query, iq.values, e))
      raise

def player_has_nemelex_win(c, player, char):
    return (query_first(c, '''SELECT COUNT(*) FROM player_nemelex_wins
                              WHERE player = %s AND charabbrev = %s''',
                              player, char) > 0)

def count_clan_nemelex_wins(c, char):
    return query_first(c, '''SELECT COUNT(*) FROM clan_nemelex_wins
                             WHERE clan_finish = 1 AND charabbrev = %s''',
                             char)

def count_nemelex_wins(c, char):
    return query_first(c, '''SELECT COUNT(*) FROM player_nemelex_wins
                             WHERE charabbrev = %s''', char)


from modules.aweremplugin import AweRemPlugin, AweRemHandler
import subprocess
from twisted.internet import reactor
import platform
import re

class LinuxHandler(AweRemHandler):
    """
    AweRem Handler for Linux Remote
    """
    def __init__(self, linux):
        AweRemHandler.__init__(self)
        self.linux = linux

    def out_shutdown(self, mode="power-off", seconds=0, minutes=0, hours=0):
        """
        Shutdown the computer at the given time
        mode -- The action to do: "power-off", "reboot"
        seconds -- The number of seconds to wait
        minutes -- The number of minutes to wait
        hours -- the number of hours to wait
        """
        try:
            s = int(seconds)
        except:
            s = 0
        try:
            m = int(minutes)
        except:
            m = 0
        try:
            h = int(hours)
        except:
            h = 0
        if mode != "power-off" and mode != "reboot":
            mode = "power-off"
        if s >= 0 and m >= 0 and h >= 0:
            return self.linux.shutdown(mode, s, m, h)
        else:
            raise ValueError("date must be positive")

    def out_updateVolume(self, volume, beep=False):
        """
        Update the volume of the system at the given percentage
        volume - the percentage of the volume to be set
        """
        print(repr(beep))
        vol = int(volume)
        beep = bool(beep)
        if vol > 100:
            vol = 100
        elif vol < 0:
            vol = 0
        return self.linux.updateVolume(vol, beep)

    def out_getCurrentVolume(self):
        return self.linux.getCurrentVolume()

    def out_beep(self):
        return self.linux.beep()

class LinuxRemote(AweRemPlugin):
    """
    Some controls for Linux systems.
    """

    def activate(self):
        if platform.system().lower() == "linux":
            self.shutTimer = None
            self.priority = 2
            self.isLinux = True
        else:
            self.priority = -1
        self.handler = LinuxHandler(self)

    def getHandler(self):
        return self.handler

    def getInfo(self):
        return {"title": self.getName(), "category": "contextual",
                "priority": self.priority}

    def getName(self):
        if not self.isLinux:
            return "Not linux"
        else:
            if platform.linux_distribution() != "":
                return platform.linux_distribution()[0]
            else:
                return "Linux"

    def shutdown(self, mode, s, m, h):
        print(mode)
        shutTime = h * 3600 + m * 60 + s
        try:
            self.shutTimer.cancel()
        except:
            pass
        if mode == "power-off" or mode == "reboot":
            mode = "--" + mode
            self.shutTimer = reactor.callLater(
                shutTime, lambda: subprocess.call(["gnome-session-quit",
                                                   mode]))
        return True

    def getCurrentVolume(self):
        try:
            sinks_info = subprocess.check_output(["pacmd", "list-sinks"])
            sinks_info.lower()
        except subprocess.CalledProcessError:
            print("pulseaudio is not used")
        else:
            return int(re.search(r"\*.*?volume.*?(\d+)%", sinks_info,
                                 re.DOTALL).group(1))

    def updateVolume(self, volume, beep):
        succeeded_once = False
        try:
            sinks_list = subprocess.check_output(
                ["pacmd", "list-sinks"]).lower()
        except subprocess.CalledProcessError:
            print("pulseaudio is not used")
        else:
            for match in re.finditer(r"\*.*index.*(\d+)", sinks_list,
                                     re.MULTILINE):
                sink = match.group(1)
                volume_str = str(volume) + "%"
                try:
                    subprocess.call(["pactl", "set-sink-volume", sink,
                                     volume_str])
                except:
                    pass
                else:
                    succeeded_once = True
            if succeeded_once and beep:
                self.beep()
        return self.getCurrentVolume()

    def beep(self):
        try:
            subprocess.Popen(["canberra-gtk-play",
                              "--id=audio-volume-change"])
        except:
            pass
        return True


# Desafio 95 - Aprimorando os dicionarios

"""
Aprimore o DESAFIO 93 para que ele funcione com vários jogadores,
incluindo um sistema de visualização de DETALHES DO APROVEITAMENTO de cada jogador.
"""

from emoji import emojize

print('=' * 30)
print(f'\033[32m{"== TRANSFERMARKET 2.0 ==":^30}\033[m')
print('=' * 30)

jogador = dict()  # dicionario
partidas = []  # lista
time = list()  # lista

while True:  # laço infinito
    jogador.clear()  # Limpa o dicionario
    jogador['Nome'] = str(input(f'Nome do jogador {emojize(":trophy:")}: '))
    tot = int(input(f'Quantas partidas {jogador["Nome"]} jogou?: '))
    partidas.clear()  # lista limpada
    for c in range(0, tot):  # para contador in range 0 ate total de jogos
        partidas.append(int((input(f'-> Quantos gols{emojize(":soccer_ball:")} na {c + 1}ª partida? '))))
        # adiciona na lista partidas
    jogador['Gols'] = partidas[:]  # cria key gols com copia da lista partidas
    jogador['Total'] = sum(partidas)  # key total, soma de partidas
    time.append(jogador.copy())  # lista time adiciona copia do dicionario
    continuar = str(input('\033[34mQuer continuar [S/N]? \033[m')).upper().strip()[0]
    while continuar not in 'SN':
        continuar = str(input('\033[31mResposta invalida! Quer continuar [S/N]? \033[m')).upper().strip()[0]
    print('-' * 30)
    if continuar == 'N':
        break

print('No. ', end='')  # cabeçalho
for i in jogador.keys():  # indice na chave do dicionario
    print(f'{i:<15}', end='')
print()  # quebra linha
print('-=' * 30)
for k, v in enumerate(time):  # k = key, v = value, numerando a lista time
    print(f'{k:<5}', end='')
    for d in v.values():  # d = dado, valores da lista enumarada
        print(f'{str(d):<15}', end='')
    print()
print('-=' * 30)
while True:  # laço infinito
    busca = int(input('Buscar dados de qual jogador? (999 interrompe) '))  # variavel busca
    if busca == 999:
        break
    if busca >= len(time):  # se a variavel for maior que lenght(comprimento) da lista time
        print(f'ERRO! Não existe jogador com codigo {busca}!')
    else:
        print(f' -- Levantamento do jogador {time[busca]["Nome"]}')
        for i, g in enumerate(time[busca]['Gols']):   # i = indice, g = gols, enumerado lista times -> variavel -> gols
            print(f' No jogo {i + 1} fez {g} {"gol" if g == 1 else "gols"}')
    print('-' * 40)
print('<<< VOLTE SEMPRE >>>')


# type: ignore
import time
from collections import defaultdict

from pydavinci import davinci

resolve = davinci.Resolve()

project = resolve.project
project_manager = resolve.project_manager
media_pool = resolve.media_pool
media_storage = resolve.media_storage
ocf_folder = media_pool.add_subfolder("OCF", media_pool.root_folder)
media_pool.set_current_folder(ocf_folder)

def generate_premiere_proxies(input_dir, output_dir, proxyfactor):

    media_pool.import_media(input_dir)

    clips_res = defaultdict(list)

    for media in ocf_folder.clips:
        clips_res[media.properties["Resolution"]].append(media)

    project.set_preset("Proxy_Preset")

    render_ids = []

    for key in clips_res.keys():

        res_x, res_y = key.split("x")

        res_folder = media_pool.add_subfolder(key, ocf_folder)
        clips = clips_res[key]

        media_pool.move_clips(clips, res_folder)
        media_pool.create_timeline_from_clips(res_folder.name, res_folder.clips)

        timeline = project.timeline
        timeline.set_setting(
            "useCustomSettings", "1"
        )  # enable custom timeline size != project settings
        timeline.set_setting("timelineResolutionWidth", res_x)
        timeline.set_setting("timelineResolutionHeight", res_y)

        project.set_render_format_and_codec("mp4", "H264")
        render_settings = {
            "FormatWidth": (int(res_x) // proxyfactor),
            "FormatHeight": (int(res_y) // proxyfactor),
            "TargetDir": output_dir,
        }

        # Set Render Resolution
        project.set_render_settings(render_settings)

        render_id = project.add_renderjob()
        render_ids.append(render_id)
    return render_ids

job_ids = generate_premiere_proxies(
    "A:/path/to/my/media",
    "A:/path/to/output",
    proxyfactor=2,
)

project.render(job_ids)

for i in len(job_ids):

    render_status = project.render_status(job_ids[i])["JobStatus"]

    while render_status != "Complete":
        time.sleep(3)
        status = project.render_status(job_ids[i])
        try:
            percentage = status["CompletionPercentage"]
            time_left = status["EstimatedTimeRemainingInMs"] / 1000

        except KeyError:
            time.sleep(2)
            break

        print(
            f"Job ID {job_ids[i]} | Rendering time left: {time_left} | Percentage completed: {percentage}%\r",
            end="",
            flush=True,
        )

        render_status = status["JobStatus"]

    time_to_render = project.render_status(job_ids[i])["TimeTakenToRenderInMs"] / 1000
    print("\n")
    print(f"Job ID {job_ids[i]} | Rendering complete. | Total render time: {time_to_render}")


import constraints
from domain_store import DomainStore
from typing import Callable
import random
from copy import deepcopy

def min_varname_selection(unassigned_variables, domain_map):
    return min(unassigned_variables)

def random_value_assignment(unassigned_variables, domain_map, variable, possible_values):
    return random.sample(possible_values, k = 1)[0]

def extract_element_helper(d: dict):
    return {k : next(iter(s)) for k, s in d.items()}

def search(
        domain_store: DomainStore,
        selection_policy: Callable,
        value_assignment_policy: Callable,
        find_all: bool = False,
    ):
    all_solutions = []
    search_history = []
    transaction_history = []
    unassigned_variables, domain_map = domain_store.get_state()
    next_var = selection_policy(unassigned_variables, domain_map)
    next_possible_values = deepcopy(domain_map[next_var])
    search_history.append((next_var, next_possible_values))
    while True:
        if len(search_history) == 0:
            break
        var, possible_values = search_history[-1]
        if len(search_history) == len(transaction_history):
            domain_store.revert_transaction(transaction_history.pop())

        while len(possible_values) > 0:
            val = value_assignment_policy(
                unassigned_variables,
                domain_map,
                var,
                possible_values
            )
            possible_values.remove(val)
            is_valid_assignment, domain_transaction = domain_store.assign_value(var, val)
            if is_valid_assignment:
                transaction_history.append(domain_transaction)
                break
        else:
            search_history.pop()
            continue
        unassigned_variables, domain_map = domain_store.get_state()
        if len(unassigned_variables) == 0:
            # Solution_found
            sln = extract_element_helper(domain_map)
            all_solutions.append(sln)
            if not find_all:
                break
        else:
            # Assign a variable to an unassigned.
            next_var = selection_policy(unassigned_variables, domain_map)
            next_possible_values = deepcopy(domain_map[next_var])
            search_history.append((next_var, next_possible_values))
    return all_solutions


import os
import numpy as np
from PIL import Image

class NoiseDel():
    #去除干扰噪声
    def noise_del(self,img):
        height = img.shape[0]
        width = img.shape[1]
        channels = img.shape[2]

        # 清除四周噪点
        for row in [0,height-1]:
            for column in range(0, width):
                if img[row, column, 0] == 0 and img[row, column, 1] == 0:
                    img[row, column, 0] = 255
                    img[row, column, 1] = 255
        for column in [0,width-1]:
            for row in range(0, height):
                if img[row, column, 0] == 0 and img[row, column, 1] == 0:
                    img[row, column, 0] = 255
                    img[row, column, 1] = 255

        # 清除中间区域噪点
        for row in range(1,height-1):
            for column in range(1,width-1):
                if img[row, column, 0] == 0 and img[row, column, 1] == 0:
                    a = img[row - 1, column]  # 上
                    b = img[row + 1, column]  # 下
                    c = img[row, column - 1]  # 左
                    d = img[row, column + 1]  # 右
                    ps = [p for p in [a, b, c, d] if 1 < p[1] < 255]
                    # 如果上下or左右为白色,设置白色
                    if  (a[1]== 255 and b[1]== 255) or (c[1]== 255 and d[1]== 255):
                        img[row, column, 0] = 255
                        img[row, column, 1] = 255
                    # 设置灰色

                    elif len(ps)>1:
                        kk = np.array(ps).mean(axis=0)
                        img[row, column, 0] = kk[0]
                        img[row, column, 1] = kk[1]
                        img[row, column, 2] = kk[2]
                    else:
                        img[row, column, 0] = 255
                        img[row, column, 1] = 255
        return img

    # 灰度化
    def convert2gray(self,img):
        if len(img.shape) > 2:
            gray = np.mean(img, -1)
            # 上面的转法较快，正规转法如下
            # r, g, b = img[:,:,0], img[:,:,1], img[:,:,2]
            # gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
            return gray
        else:
            return img

    # 二值化
    def binarizing(self,img,threshold, cov=False):
        w, h = img.shape
        if cov:
            for y in range(h):
                for x in range(w):
                    if img[x, y] > threshold:
                        img[x, y] = 0
                    else:
                        img[x, y] = 255
        else:
            for y in range(h):
                for x in range(w):
                    if img[x, y] < threshold:
                        img[x, y] = 0
                    else:
                        img[x, y] = 255
        return img

if __name__=="__main__":

    filepath = 'data/png'
    savepath = 'data/png_a2'
    if not os.path.exists(savepath):
        os.mkdir(savepath)

    filenames = os.listdir(filepath)
    nd = NoiseDel()
    for file in filenames:
        openname = os.path.join(filepath,file)
        image = Image.open(openname)
        image = np.array(image)

        # 去噪、灰度、二值化处理
        image = nd.noise_del(image)
        image = nd.convert2gray(image)
        image = nd.binarizing(image,threshold=190, cov=True)

        #
        image = Image.fromarray(image).convert('L')  # Image.fromarray(image)默认转换到‘F’模式，即浮点型，‘L’是整形

        savename = os.path.join(savepath,file)
        image.save(savename)


# code based on my original, modified by Mike Stucka (thus fml) and me
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urlparse
import os
from bs4 import BeautifulSoup
import urllib2
import csv

for i in os.listdir(os.getcwd()):
    if i.startswith('ChargesInter'):
        url = i
        ids = urlparse.parse_qs(url)
        idbo = ids.get('bo')
        #print idbo
        soup = BeautifulSoup(open(url))
        #above works
        f = open('charges.csv', 'ab')
        writer = csv.writer(f)

        table2 = soup.find('table', attrs={'id':"DataList2"})
        try:
            for fmltable in table2.findAll('table'): # Inside our DataList2 table is an table holding the table contents for each charge.
                for chargetable in fmltable.findAll('table'):   # Now we're looking at the actual charge table
                    list_of_fields = [idbo[0]]  # Pull out booking number thingy from list, just as a string.
                    #print list_of_fields
                    for field in chargetable.findAll('td'):
                        text = field.text.split("  ")[-1]       # Let's look for everything after a couple spaces. This seems to work.
                        list_of_fields.append(text)
                        #print list_of_fields

                    writer.writerow(list_of_fields)     # Write it to CSV.

        except:
            continue

         # You still need to close out your csvwriter
        f.close()


from django.shortcuts import render, redirect
from django.views.generic import View
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages
from autenticacion.forms import UserRegisterForm, UserUpdateForm
from autenticacion.models import Profile
# Create your views here.
# def autenticacion(request):

# 	return render(request, "autenticacion/login.html")

class VRegister(View):
	def get(self,request):
		form=UserRegisterForm()
		return render(request, "autenticacion/register.html",{"form":form})
	def post(self,request):
		form=UserRegisterForm(request.POST)
		if form.is_valid():
			form.save(commit=False)
			form.instance.is_active=False
			username = form.cleaned_data['username']
			messages.success(request, f'Usuario {username} creado. Próximamente recibirás un correo informando la aprobación de tu cuenta.')
			form.save()
			return redirect('Inicio')
		else:
			messages.success(request, f'El título ya existía'+str(form.errors))
			return render(request,"autenticacion/register.html",{"form":form})
		context= {'form': form}
		return render(request,"autenticacion/register.html", context)
class actualizarperfil(View):
	def get(self,request):
		if request.user.is_authenticated:
			current_user = request.user
			insta=Profile.objects.get(user_id=current_user.id)
			form=UserUpdateForm(instance=insta)
			usuario=current_user.username
			return render(request, "autenticacion/actualizarperfil.html",{
				"form":form,
				"usuario":usuario,
				"nombre":current_user.first_name,
				"apellido":current_user.last_name
				})
		else:
			messages.success(request, f'Debes estar registrado para acceder')
			return redirect("/")
	def post(self,request):
		if request.user.is_authenticated:
			current_user = request.user
			insta=Profile.objects.get(user_id=current_user.id)
			form=UserUpdateForm(request.POST or None, instance=insta)
			if form.is_valid():
				form.save(commit=False)
				form.instance.user_id=request.user.id
				messages.success(request, f'Usuario modificado')
				form.save()
				return redirect('Colaboradores')
			else:
				form = UserRegisterForm(request.POST or None, instance=current_user.id)
			context= {'form': form}
			return render(request,"autenticacion/actualizarperfil.html", context)
		else:
			messages.success(request, f'Debes estar registrado para acceder')
			return redirect("/")


import logging

from odoo.exceptions import UserError
from odoo.tools.translate import _

from odoo.addons.base_rest import restapi
from odoo.addons.base_rest.components.service import skip_secure_response, to_int
from odoo.addons.component.core import Component

_logger = logging.getLogger(__name__)

class CartService(Component):
    _inherit = "shopinvader.cart.service"

    def set_carrier(self, **params):
        """
            This service will set the given delivery method to the current
            cart
        :param params: The carrier_id to set
        :return:
        """
        cart = self._get()
        if not cart:
            raise UserError(_("There is not cart"))
        else:
            self._set_carrier(cart, params["carrier_id"])
            return self._to_json(cart)

    # DEPRECATED METHODS #
    @restapi.method(
        routes=[(["/get_delivery_methods"], "GET")],
        output_param=restapi.CerberusValidator(
            "_validator_get_delivery_methods",
        ),
    )
    @skip_secure_response
    def get_delivery_methods(self):
        """
            !!!!DEPRECATED!!!!! Uses delivery_carrier.search

            This service will return all possible delivery methods for the
            current cart

        :return:
        """
        _logger.warning(
            "DEPRECATED: You should use %s in service %s",
            "search",
            "delivery_carrier",
        )
        return self.component("delivery_carrier").search(target="current_cart")["rows"]

    def apply_delivery_method(self, **params):
        """
            !!!!DEPRECATED!!!!! Uses set_carrier

            This service will apply the given delivery method to the current
            cart
        :param params: Dict containing delivery method to apply
        :return:
        """
        return self.set_carrier(carrier_id=params["carrier"]["id"])

    # Validator
    def _validator_apply_delivery_method(self):
        return {
            "carrier": {
                "type": "dict",
                "schema": {
                    "id": {
                        "coerce": int,
                        "nullable": True,
                        "required": True,
                        "type": "integer",
                    }
                },
            }
        }

    def _validator_get_delivery_methods(self):
        return {
            "country_id": {
                "coerce": to_int,
                "required": False,
                "type": "integer",
            },
            "zip_code": {"required": False, "type": "string"},
        }

    def _validator_set_carrier(self):
        return {
            "carrier_id": {
                "coerce": int,
                "nullable": True,
                "required": True,
                "type": "integer",
            }
        }

    # internal methods

    def _add_item(self, cart, params):
        res = super()._add_item(cart, params)
        self._unset_carrier(cart)
        return res

    def _update_item(self, cart, params, item=False):
        res = super()._update_item(cart, params, item)
        self._unset_carrier(cart)
        return res

    def _delete_item(self, cart, params):
        res = super()._delete_item(cart, params)
        self._unset_carrier(cart)
        return res

    def _set_carrier(self, cart, carrier_id):
        if carrier_id not in cart.shopinvader_available_carrier_ids.ids:
            raise UserError(_("This delivery method is not available for you order"))
        cart._set_carrier_and_price(carrier_id)

    def _unset_carrier(self, cart):
        cart._remove_delivery_line()

    def _get_lines_to_copy(self, cart):
        # Override. Don't copy delivery lines.
        res = super()._get_lines_to_copy(cart)
        return res.filtered(lambda l: not l.is_delivery)


# importing all needed modules
import pygame
from walker import Walker

# initializing pygame
pygame.init()

# Permanent variables: Scale, each block size, width, height, dimensions
WIDTH = 800
HEIGHT = 600
DIMENSIONS = (WIDTH, HEIGHT)

BLACK = (0, 0, 0)

# Setting up pygame
screen = pygame.display.set_mode(DIMENSIONS)
pygame.display.set_caption('Natural Random Walker')

FRAMES = int(1000/60)

# -----------------------------------------------------------------------
walkers = []

def create_random_walker(pos):
    walkers.append(Walker([pos[0], pos[1]]))

# Game loop
while True:
    pygame.time.delay(FRAMES)
    screen.fill(BLACK)

    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            pygame.quit()
        elif event.type == pygame.MOUSEBUTTONUP:
            create_random_walker(pygame.mouse.get_pos())

    for walker in walkers:
        walker.render(pygame, screen)
        walker.update(screen)

    pygame.display.update()


import os
import json

name = input("name:")

root = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))

result = []

for _file in os.listdir(root + "/" + name):
	full_name = root + "/" + name + "/" + _file

	with open(full_name, "r") as f:
		s = f.read()

	result.append(json.loads(s))

with open("result.json", "w") as f:
	f.write(json.dumps(result))


import os
from pprint import pprint

import numpy
from PIL import Image

# Синтетически иметирует работу камеры микроскопа, создавая изображения со сдвигом
from numpy import array

def image_cutter(path, n_x, n_y, bias_x, bias_y,  # Симулирует фотографии микроскопа
                 is_digit=True):  # Путь, кол-во кусков по х, кол-во кусков по у, смещение по х, смещение по у, формат выведения результата
    try:
        img = Image.open(path)
        img_x, img_y = img.size
        img = img.crop((0, 0, img_x // n_x * n_x, img_y // n_y * n_y))
        if is_digit:
            images = []
        else:
            os.mkdir(path.split('/')[-1])
        count_x, count_y = 0, 0
        for i in range(0, img.size[1], img_y // n_y):
            if is_digit:
                images.append([])
            for j in range(0, img.size[0], img_x // n_x):
                new_image = img.crop((j, i, j + img_x // n_x + bias_x, i + img_y // n_y + bias_y))
                if is_digit:
                    images[-1].append(img_to_pixels(new_image))
                else:
                    new_image.save(f'{path.split("/")[-1]}/{count_x} {count_y}.jpeg')
                count_x += 1
            count_x = 0
            count_y += 1
        if is_digit:
            return images
        else:
            return f'Photo directory "{path.split("/")[-1]}" created'
    except Exception as ex:
        print('EXCEPTION!')
        print(ex)

def rgb_to_grid(images):  # Преобразует массив фотографий из RGB в L
    grid_imgs = images.copy()
    for i in range(len(images)):
        # print('i')
        for j in range(len(images[i])):
            # print('j')
            for y in range(len(images[i][j])):
                # print('y')
                for x in range(len(images[i][j][y])):
                    r, g, b = grid_imgs[i][j][y][x]
                    grid_imgs[i][j][y][x] = round(r * 299 / 1000 + g * 587 / 1000 + b * 114 / 1000)
    return grid_imgs

def img_to_pixels(img):  # Преобразует фотографию в цифру
    pixels_arr = []
    pixels = img.load()
    for a in range(img.size[1]):
        pixels_arr.append([])
        for b in range(img.size[0]):
            pixels_arr[-1].append(pixels[b, a])
    return pixels_arr

def photos_to_digits(directory):  # Преобразует фотографии из директории в цифру
    images = []
    # for i in range(len(os.listdir(directory))):
    for i in range(0, 3):
        line_images = []
        if i % 2 == 0:
            for j in range(len(os.listdir(f'{directory}/{i}'))):
                print(j)
                file_extention = os.listdir(f'{directory}/{i}')[0].split('.')[1]
                img = Image.open(f'{directory}/{i}/{i}_{j}.{file_extention}')
                line_images.append(img_to_pixels(img))
            print('dir', i)
            images.append(line_images)
        else:
            for j in range(12, -1, -1):
                print(j)
                file_extention = os.listdir(f'{directory}/{i}')[0].split('.')[1]
                img = Image.open(f'{directory}/{i}/{i}_{j}.{file_extention}')
                # img.show()
                line_images.append(img_to_pixels(img))
            print('dir', i)
            images.append(line_images)
    print(numpy.array(images).shape)
    return images


from pywinauto.application import Application
from pywinauto import Desktop
from pywinauto.keyboard import send_keys
import time
import pyuac
def main():
    path = "\\Path\\"
    app = Application().start(r'msiexec /i ' + path)

if __name__=="__main__":
    if not pyuac.isUserAdmin():
        pyuac.runAsAdmin()
    else:
        main()

#example of key sents
time.sleep(1)
send_keys("{ENTER}")
time.sleep(1)
send_keys("{SPACE}")
time.sleep(1)
send_keys("{ENTER}")
time.sleep(1)
send_keys("{ENTER}")
time.sleep(180)
send_keys("{ENTER}")


#http://www.deanclatworthy.com/imdb/

from xml.dom.minidom import parse
#import xml.dom
from urllib import request
from urllib.parse import quote
from ast import literal_eval
from time import sleep

dom = parse('episodelist-in.xml')
domEpisodeList = dom.getElementsByTagName('episode')

apiNetloc = 'http://www.deanclatworthy.com/imdb/'
keys = ['imdbid', 'country']

for node in domEpisodeList:

   titleStr = node.getElementsByTagName('movie')[0].firstChild.data
   ttID = node.getElementsByTagName('id')[0].firstChild.nodeValue
   year = node.getElementsByTagName('year')[0].firstChild.nodeValue
   titleUrl = quote(titleStr)

   url = apiNetloc + '?q=' + titleUrl + '&year=' + year

   get = request.urlopen(url)
   byteResult = get.read()
   strResult = byteResult.decode()
   dictResult = literal_eval(strResult)

   print(titleStr)
   try:
     dictResult['year']
   except KeyError:
     print('^- key error')
     sleep(120)
     continue

   for key in keys:

     items = dictResult[key].split(',')

     if key == 'imdbid':

       if ''.join(items) != ttID:
          flag = dom.createElement('unconfirmed')
          node.appendChild(flag)

     else:

        for item in items:
          element = dom.createElement(key.lower())
          data = dom.createTextNode(str(item))
          element.appendChild(data)
          insertPoint = node.getElementsByTagName('genre')[0]
          node.insertBefore(element, insertPoint)

   sleep(120)

with open('episodelist-out.xml', 'w', encoding='utf-8') as f:
  f.write(dom.toxml('utf-8').decode('utf-8'))


from .. import models, schemas, utils
from fastapi import FastAPI, HTTPException, Response, status, Depends,APIRouter
from ..database import get_db
from sqlalchemy.orm import Session
from typing import List, Optional
from .. import oauth2

router = APIRouter(
     prefix="/receptionist",
     tags=['Receptionist']

)

""" RECEPTIONIST """
# Create receptionist

@router.post("/", status_code=status.HTTP_201_CREATED)
def create_receptionist(receptionist: schemas.ReceptionistCreate, db: Session = Depends(get_db),
                         current_user: int = Depends(oauth2.get_current_user)):
    receptionist = models.Receptionist(user_id= current_user.id, **receptionist.dict())
    db.add(receptionist)
    db.commit()
    db.refresh(receptionist)
    return receptionist

# Read single receptionist

@router.get("/{id}", response_model=schemas.ReceptionistResponse)
def get_receptionist(id: str, db: Session = Depends(get_db),
                     current_user: int = Depends(oauth2.get_current_user)):
    receptionist = db.query(models.Receptionist).filter(
        models.Receptionist.id == id).first()

    if not receptionist:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"Receptionist with id: {id} was not found")
    return receptionist

# Read All receptionists

@router.get("/", response_model=List[schemas.ReceptionistResponse])
def get_receptionist(db: Session = Depends(get_db),
                     current_user: int = Depends(oauth2.get_current_user), limit: int = 10, skip: int = 0, search: Optional[str] = ""):
    receptionist = db.query(models.Receptionist)\
    .filter(models.Receptionist.user_id == current_user.id)\
    .filter(models.Receptionist.firstname.ilike(f'%{search}%'))\
    .limit(limit)\
    .offset(skip)\
    .all()
    return receptionist

# Update receptionist

@router.put("/{id}", response_model=schemas.ReceptionistResponse)
def update_receptionist(id: str, updated_receptionist: schemas.ReceptionistCreate, db: Session = Depends(get_db),
                        current_user: int = Depends(oauth2.get_current_user)):

    receptionist_query = db.query(models.Receptionist).filter(
        models.Receptionist.id == id)

    receptionist = receptionist_query.first()

    if receptionist == None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"Receptionist with id: {id} does not exist")

    if receptionist.user_id != current_user.id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
                            detail=f"Not authorized to perform requested action")

    receptionist_query.update(
        updated_receptionist.dict(), synchronize_session=False)
    db.commit()
    return receptionist_query.first()

# Delete receptionist
@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_receptionist(id: str, db: Session = Depends(get_db),
                        current_user: int = Depends(oauth2.get_current_user)):

    receptionist_query = db.query(models.Receptionist).filter(
        models.Receptionist.id == id)

    receptionist = receptionist_query.first()

    if receptionist == None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"Receptionist with id: {id} does not exist")

    if receptionist.user_id != current_user.id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN,
                            detail=f"Not authorized to perform requested action")

    receptionist_query.delete(synchronize_session=False)
    db.commit()
    return Response(status_code=status.HTTP_204_NO_CONTENT)


import redis
import json
import time

redis_handle = redis.StrictRedis("127.0.0.1", 6379 ,0,decode_responses = True )

while True:

   data = {"a":1,"b":2 }
   data_json = json.dumps(data)
   redis_handle.lpush("work_queue",data_json)
   redis_handle.ltrim("work_queue",0, 100)
   print("pushing data")
   time.sleep(2)


# ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt

# データの読み込み
data = np.genfromtxt("output/outputKobe.txt")

# 新しいウィンドウにグラフを作成
plt.figure(1)

# グラフにデータをプロット
plt.plot(data[:,0] * 0.02 , data[:,1], label="responseAcc(m/s/s)", color="red", linestyle="solid", linewidth=1.0)
plt.plot(data[:,0] * 0.02 , data[:,2], label="inputWave(m/s/s)", color="blue", linestyle="solid", linewidth=0.5)

# 最大値／最小値を表示
num = 17996
valuelistAcc = [] #数値を格納する配列
valuelistInput = [] #数値を格納する配列

for i in range(num):
    valueAcc   = data[i,1]
    valueInput = data[i,2]
    valuelistAcc.append(valueAcc)
    valuelistInput.append(valueInput)

print("maxValueAcc=")
print(max(valuelistAcc))
print("minValueAcc=")
print(min(valuelistAcc))
print("maxValueInput=")
print(max(valuelistInput))
print("minValueInput=")
print(min(valuelistInput))

# 軸の調整
plt.xlim([0, 200])  # X軸の範囲を指定
plt.ylim([-20, 20])  # Y軸の範囲を指定

# グラフに情報を表示
plt.title("JMA_KobeWave_NS")
plt.xlabel("time(s)")  # x軸のラベル
plt.ylabel("acc(m/s/s)")  # y軸のラベル
plt.legend(loc="lower right")  # 汎例
plt.grid(True)  # グリッド線

# グラフの描画を実行
plt.savefig("output/equationOfMotion.png")
plt.show()


# -*- coding: utf-8 -*-
"""
Created on Mon Feb 12 02:11:47 2018

@author: soumi
"""

from Utils import Util
from Utils import XmlUtil
from xml.etree.ElementTree import Element, SubElement, Comment, tostring, parse
from Utils import Constants
import zipfile
import os
debugMode = True

TEMPLATE_FOLDER = r"templates\\"

def clearContent(projectPath):
    Util.run("rm -rf"+ projectPath+ "*")

def createProject(projectInfo):
    Util.run("mkdir " +projectInfo.mPath)
    Util.run("Xcopy /E /I " +TEMPLATE_FOLDER +"templateProject "+ projectInfo.mPath)
    Util.run("templates\\fart.exe -i -r " +projectInfo.mPath + "\\* templateProject "+ projectInfo.mBaseName)
    Util.run("templates\\fart.exe -i -r " +projectInfo.mPath + "\\* TEMPLATEPROJECT "+ projectInfo.mBaseName.upper())
    Util.run("rename " +projectInfo.mPath +"\\templateProject.iml "+ projectInfo.mBaseName + ".iml")
    Util.run("rename " +projectInfo.mPath +"\\app\\src\\test\\java\\com\\example\\remaui\\templateproject "+projectInfo.mBaseName )
    Util.run("rename " +projectInfo.mPath +"\\app\\src\\main\\java\\com\\example\\remaui\\templateproject "+projectInfo.mBaseName )
    Util.run("rename " +projectInfo.mPath +"\\app\\src\\androidTest\\java\\com\\example\\remaui\\templateproject "+projectInfo.mBaseName )

def setup(projectInfo):
    if(os.path.exists(projectInfo.mPath)):
        Util.run("rmdir /s /q " + projectInfo.mPath)
    createProject(projectInfo)

def projectCompile(projectInfo):

    Util.run(projectInfo.mPath +"//gradlew assembleDebug" )

def prepareProject(projectInfo):

    zipFileName = "templates\\uploads\\"+projectInfo.mName + ".zip"
    projectCompile(projectInfo)

    zipdirectory(projectInfo.mPath,zipFileName )

def zipdirectory(basedir, archivename):
    zf = zipfile.ZipFile(archivename, "w", zipfile.ZIP_DEFLATED)
    for root, dirs, files in os.walk(basedir):
           #NOTE: ignore empty directories
           for fn in files:
               absfn = os.path.join(root, fn)
               zfn = absfn[len(basedir)+len(os.sep):] #XXX: relative path
               zf.write(absfn,zfn)
    zf.close()


import torch
import torch.nn as nn

class SiameseConvNet2(nn.Module):
    def __init__(self):
        super(SiameseConvNet2, self).__init__()
        self.length = 14
        self.input_size = 1 * 14 * 14
        # we need an intermediate output,
        # because we are using a siamese network
        intermediate_output_size = 10
        self.n_outputs = 10
        # two digit output, probability of being 1 or 0:
        final_output_size = 2

        # flatten images to 1D input:
        self.flatten = nn.Flatten()
        # convolutional layers
        kernel_size = 3
        n_channel = 5
        self.conv_layer = nn.Sequential(nn.Conv2d(1, n_channel, kernel_size),
                                        nn.ReLU(),
                                        nn.Conv2d(n_channel, 2 *
                                                  n_channel, kernel_size),
                                        nn.ReLU(),
                                        nn.Conv2d(2 * n_channel, 4 *
                                                  n_channel, kernel_size),
                                        nn.BatchNorm2d(4 * n_channel),
                                        nn.ReLU(),
                                        nn.Dropout2d(p=0.3),
                                        nn.Conv2d(4 * n_channel, 8 *
                                                  n_channel, kernel_size),
                                        nn.ReLU(),
                                        nn.Dropout2d(p=0.4),
                                        nn.Conv2d(8 * n_channel, 16 *
                                                  n_channel, kernel_size),
                                        nn.ReLU(),
                                        nn.Dropout2d(p=0.5),
                                        nn.Conv2d(16 * n_channel,
                                                  32 * n_channel, kernel_size),
                                        nn.ReLU(),
                                        nn.Dropout2d(p=0.6)
                                        )

        def compute_conv2d_size(length):
            return length - (kernel_size - 1) - 1 + 1

        length_out = self.length
        depth = 4

        for i in range(depth):
            length_out = compute_conv2d_size(length_out)

        # For 10 digits:
        concat_size = 640
        self.fcout1 = nn.Linear(concat_size, intermediate_output_size)

        # For 0-1 output:
        self.fcout2 = nn.Linear(2 * intermediate_output_size,
                                final_output_size,
                                bias=False)

    def forward(self, x):
        x1 = x[:, 0].view(-1, 1, self.length, self.length)
        x2 = x[:, 1].view(-1, 1, self.length, self.length)
        # x1.shape = torch.Size([64, 1, 14, 14])

        x1 = self.conv_layer(x1)
        # x1.shape = torch.Size([64, 160, 2, 2])
        x1 = x1.view(-1, 640)
        # x1.shape = torch.Size([64, 640])

        # Size batch x 10 (cipher predictions on image)
        out1 = self.fcout1(x1)
        # out1.shape = torch.Size([64, 10])

        x2 = self.conv_layer(x2)
        x2 = x2.view(-1, 640)
        # Size batch x 10 (cipher predictions on image)
        out2 = self.fcout1(x2)

        # ------------------------------------------------------------------
        # 0-1 Prediction
        # Predict if first image bigger than second
        # ------------------------------------------------------------------

        # concatenate into size (batch x 20)
        output = torch.cat((out1, out2), 1)
        # predict probabilities:
        logits = self.fcout2(output)

        return out1.view(-1, self.n_outputs), out2.view(-1,
                                                        self.n_outputs), logits


from fastapi import FastAPI
import json
import requests
import time

# Load the llm config from the json file provided on command line
with open("model.json", 'r') as file:
    model = json.load(file)

# Whip the llama into gear
DEFAULT_SYSTEM = "You are a helpful assistant who will always answer the question with only the data provided"
DEFAULT_PROMPT = "Entity:\n{%D}\nDescribe the {%E} in a single paragraph, without saying it's a JSON object or including any URLs or images:"
DEFAULT_TOKENS = 512 # many words
DEFAULT_TEMP = 0.7 # very mild temp for more boring results

# Fast API init
app = FastAPI(
        title="SumBot",
        description="Send me a JSON record and say what kind of entity it is (movie, transaction, person) and I'll summarize it with an LLM",
        version="1.1",
        contact={
            "name": "Pat Wendorf",
            "email": "pat.wendorf@mongodb.com",
    },
    license_info={
        "name": "MIT License",
        "url": "https://opensource.org/license/mit/",
    }
)

def remove_extra_formatting(text):
    cleaned_text = text.replace("\n", " ") # remove newline
    cleaned_text = cleaned_text.replace("\t", " ") # remove tabs
    cleaned_text = cleaned_text.replace("  ", " ") # remove double spaces
    return cleaned_text

# Endpoint to compare 2 images by URL and show similarity
@app.post("/summarize")
async def summarize_json_data(entity_type: str, input_json: str):

    # Build the prompt
    prompt = model["prompt_format"].replace("{%S}", DEFAULT_SYSTEM)
    prompt = prompt.replace("{%P}", DEFAULT_PROMPT)
    prompt = prompt.replace("{%D}", input_json)
    prompt = prompt.replace("{%E}", entity_type)

    api_data = {
        "prompt": prompt,
        "n_predict": DEFAULT_TOKENS,
        "temperature": DEFAULT_TEMP,
        "stop": model["stop_tokens"],
        "tokens_cached": 0
    }

    # Time the process
    start_time = time.time()
    try:
        # Call the model API
        response = requests.post(model["llama_endpoint"], headers={"Content-Type": "application/json"}, json=api_data)
        json_output = response.json()
        end_time = time.time()
        milliseconds_elapsed = (end_time - start_time) * 1000
        output = {"summary": remove_extra_formatting(json_output['content']), "ms": round(milliseconds_elapsed)}
    except:
        output = {"error": "My AI model is not responding try again in a moment 🔥🐳"}

    # remove annoying formatting in output
    return output


import torch
import numpy as np

def create_fashion_inference():
    device = 'cuda' if torch.cuda.is_available() else 'cpu'
    use_gpu = True if torch.cuda.is_available() else False
    fashion = torch.hub.load('facebookresearch/pytorch_GAN_zoo:hub', 'DCGAN', pretrained=True, useGPU=use_gpu)
    fashion_noise, _ = fashion.buildNoiseData(1)
    @torch.inference_mode()
    def fashion_generator(latents):
        latents = [torch.from_numpy(latent).float().to(device) for latent in latents]
        latents = torch.stack(latents)
        out = fashion.test(latents)
        outs = []
        for out_i in out:
            out_i = ((out_i.permute(1,2,0) + 1) * 127.5).clamp(0,255).cpu().numpy()
            out_i = np.uint8(out_i)
            outs.append(out_i)
        return outs

    return {
        'name': 'Fashion',
        'generator': fashion_generator,
        'latent_dim': fashion_noise.shape[1],
        'fps': 15,
        'batch_size': 8,
        'strength': 0.6,
        'max_duration': 30,
        'use_peak': True
    }


import sys
import collections
import csv

import click
import vcf
from Bio import SeqIO
from BitVector import BitVector

def reflen(ref_file, region=None):
    """Get the length of reference genome sequence length.

    Args:
        ref_file : file-like object or str
            The reference genome file or file path.
        region : str
            The region in the reference genome. If it is not provided, the first
            region will be used.
    """
    parser = SeqIO.parse(ref_file, 'fasta')
    if region is None:
        return len(next(parser).seq)
    for r in parser:
        if r.name == region:
            return len(r.seq)
    raise RuntimeError("region not found")

def compute_snpbv(vcf_reader, length):
    """Compute SNP bitvector. The SNP bitvector is a bitvector of the length of
    the reference genome where SNP loci are set.

    Args:
        vcf_reader : vcf.Reader
            VCF reader.
        length : int
            The length of reference genome.

    Return:
        A BitVector.BitVector instance of size `length` where all SNP loci are
        set.
    """
    cnt = BitVector(size=length)
    for record in vcf_reader:
        cnt[record.POS-1] = 1
    return cnt

def ksnpcounts(snpbv, k):
    """Generate number of SNPs in all k-mers in the reference genome.

    Args:
        snpbv : BitVector.BitVector
            The SNP bitvector.
        k : int
            The length of the k-mer.

    Return:
        The number of SNPs in a k-mer. It yields this for all k-mers in the
        reference genome.
    """
    kcount = 0
    for i in range(k):
        kcount += snpbv[i]
    yield kcount
    for i in range(k, len(snpbv)):
        kcount += snpbv[i]
        kcount -= snpbv[i-k]
        yield kcount

def write_csv(output, vcf_file, ref_file, k, region=None, dialect='unix',
              compressed=None, frequency=False):
    """Write CSV file.

    Args:
        output : file-like object
            The output CSV file.
        vcf_file : file-like object or str
            The input VCF file or file path.
        ref_file : file-like object or str
            The input reference genome. If it is set to `None`, the reference
            genome path will be inferred from VCF metadata (header).
        k : int
            The length of the k-mer.
        region : str
            The region in the reference genome.
        dialect : str
            This string specifies the dialect of the output CSV file.
        compressed : bool
            Whether input VCF is compressed or not. It is determined by file
            extension if it is not specified.
        frequency : bool
            If set, instead of reporting SNPs counts of each k-mer, it reports
            the frequency of each counts.
    """
    fieldnames = ['k', 'count', 'freq'] if frequency else ['k', 'count']
    csv_writer = csv.DictWriter(output,
                                fieldnames=fieldnames,
                                dialect=dialect,
                                quoting=csv.QUOTE_NONE)
    csv_writer.writeheader()

    if isinstance(vcf_file, str):
        vcf_reader = vcf.Reader(filename=vcf_file, compressed=compressed)
    else:
        vcf_reader = vcf.Reader(vcf_file, compressed=compressed)
    if ref_file is None:
        ref_file = open(vcf_reader.metadata['reference'], 'r')
    bv = compute_snpbv(vcf_reader, reflen(ref_file, region))
    freqs = collections.defaultdict(int)
    for count in ksnpcounts(bv, k):
        if frequency:
            freqs[count] += 1
        else:
            csv_writer.writerow(dict(k=k, count=count))
    if not frequency:
        return
    for key, value in sorted(freqs.items()):
        csv_writer.writerow(dict(k=k, count=key, freq=value))

@click.command()
@click.argument('vcf', type=str, default="-")
@click.option('-o', '--output', type=click.File('w'), default="-",
              help="Write to this file instead of standard output.")
@click.option('-r', '--reference', type=click.File('r'), default=None,
              help=("Reference genome FASTA file. It will be inferred from VCF "
                    "header, if not specified."))
@click.option('-R', '--region', type=str, default=None,
              help="Use this region from reference genome.")
@click.option('-k', type=int, required=True, help="The value of k.")
@click.option('-c', is_flag=True, default=None,
              help="Set if the input VCF is compressed.")
@click.option('-d', '--dialect', type=click.Choice(csv.list_dialects()),
              default='unix', show_default=True,
              help="Use this CSV dialect.")
@click.option('-f', '--frequency', is_flag=True, default=False,
              help="Report frequency instead of reporting count in each k-mer.")
def cli(**kwargs):
    """Report the number of SNPs in all k-mers. Specify the k and the VCF file,
    it reports number of SNPS occurred in each k-mer.
    """
    stdin_fsock = sys.stdin.buffer if kwargs['c'] else sys.stdin
    write_csv(kwargs.pop('output'),
              kwargs.pop('vcf') if kwargs['vcf'] != '-' else stdin_fsock,
              kwargs.pop('reference'),
              kwargs.pop('k'),
              kwargs.pop('region'),
              kwargs.pop('dialect'),
              kwargs.pop('c'),
              kwargs.pop('frequency'))


##############################################################################
#
#   DEMO Application
#
##############################################################################
from pymongo        import MongoClient                                       #
from jinja2         import Environment,FileSystemLoader                      #
from twisted.python import log                                               #
from autobahn       import wamp                                              #
##############################################################################

class Subscriptions:
    """handle class subscriptions"""
    def __init__(self,conf=None,extra=None):
        self.conf = conf
        self.extra = extra

class Registrations:
    """handle class registrations"""
    def __init__(self,conf=None,extra=None):
        self.conf = conf
        self.extra = extra
        self.mongo = MongoClient()
        self.env = Environment(loader=FileSystemLoader('../../static/html'),extensions=["jinja2.ext.do",])
    #
    #   Ok, we need this to resolve sessions back to authid's
    #   Hopefully when we get passed authid's , this will get easier
    #
    def getSession(self,details):
        """ lookup details for the current user """
        id = getattr(details,'caller')
        if not id:
            log.msg("% ERROR - missing caller field")
            return None
        session = self.mongo.ionman.sessions.find_one({'session':id})
        if not session:
            log.msg("% ERROR - missing session record")
            return None

        user = self.mongo.ionman.users.find_one({'authid':session.get('authid','')})
        if not user:
            log.msg("% ERROR - missing user record")
            return None

        return user

    @wamp.register(u'demo.page.render')
    def app_load_preferences(self,params,details):
        """ load up a requested page """
        try:
            user = self.getSession(details)
            page = params.get('uri','welcome.html');
            tmpl = self.env.get_template(page)
            my_dict = {
                'name'      : user.get('name',''),
                'role'      : user.get('role',''),
                'authid'    : user.get('authid',''),
                'uri'       : page
            }
            return { 'html':tmpl.render(my_dict) }
        except:
            log.err()
            return { 'html':'' }


import numpy as np
import matplotlib.pyplot as pl
import networkx as nx

from BiasedRandomWalks import BiasedRandomWalk

# Create a test Graph with weighted edges where weights are distances
G = nx.Graph()
N = 4
G.add_nodes_from(range(N))
G.add_edge(0,1,weight=1)
G.add_edge(0,2,weight=1)
G.add_edge(1,2,weight=1)
G.add_edge(1,3,weight=0.1)
G.add_edge(2,3,weight=0.2)

# define sink nodes
sink_nodes = [3,]

# define bias
gamma = 1

# initial distribution on transient
p0 = np.array([1,0,0])

# initial distribution on all
p0_all = np.array([1,0,0,0])

# initial base class (choose 'exponential' or 'scale free')
RW = BiasedRandomWalk(G, gamma, sink_nodes, bias_kind = 'exponential')

print("adjacency_matrix =", RW.adjacency_matrix)
print("weight_matrix =", RW.weight_matrix)
print("transition_matrix =", RW.full_transition_matrix)
print("distance_matrix =", RW.distance_matrix)