import pandas as pd
from textslack.textslack import TextSlack
from gensim.models import doc2vec

# Architecture of the NLP Model
class NLPModel:

    # The constructor instantiates all the variables that would be used throughout the class
    def __init__(self, sp, conn, max_epochs=100, vec_size=50, alpha=0.025):
        self.sp = sp
        self.conn = conn
        self.slack = TextSlack(variety='BrE', lang='english')
        self.max_epochs = max_epochs
        self.vec_size = vec_size
        self.alpha = alpha
        self.df = pd.read_sql_table('SPOTIFY_DATA', con=self.conn)

    # Function that tags the list of words with indices
    def _create_tagged_document(self, list_of_list_of_words):
        for i, list_of_words in enumerate(list_of_list_of_words):
            yield doc2vec.TaggedDocument(list_of_words, [i])

    # Function to prepare the training data
    def _training_data(self):
        key_features = (self.df['album'] + ' ' + self.df['name'] + ' ' + self.df['artist']).tolist()
        cleaned_key_features = self.slack.transform(key_features)
        list_list_words = [sent.split() for sent in cleaned_key_features]
        return list_list_words

    # Function to build and train the model
    def build_model(self):
        list_list_words = self._training_data()
        train_data = list(self._create_tagged_document(list_list_words))
        model = doc2vec.Doc2Vec(size=self.vec_size,
                                alpha=self.alpha,
                                min_alpha=0.00025,
                                min_count=1,
                                dm=1)
        model.build_vocab(train_data)
        for epoch in range(self.max_epochs):
            print('iteration {0}'.format(epoch))
            model.train(train_data,
                        total_examples=model.corpus_count,
                        epochs=model.iter)
            # decrease the learning rate
            model.alpha -= 0.0002
            # fix the learning rate, no decay
            model.min_alpha = model.alpha
        model.save('d2v.model')
        print("Model Saved")

    # Function to predict the most similar doc in the doc2vec model
    def most_similar_doc(self, target):
        model = doc2vec.Doc2Vec.load('d2v.model')
        model.random.seed(95)
        cleaned_target = self.slack.transform(target).split()
        pred_vector = model.infer_vector(cleaned_target)
        sim_vector = model.docvecs.most_similar([pred_vector])
        pred_index = sim_vector[0][0]
        return self.df.loc[pred_index, self.df.columns[6:-1]]


import datetime
import difflib
import os
from inspect import isabstract
from typing import Any, List, Mapping, Optional, Set, Tuple, Type

import ee  # type: ignore
from requests.structures import CaseInsensitiveDict

config_path = os.path.expanduser("~/.config/taskee.ini")

def initialize_earthengine() -> None:
    """Initialize the Earth Engine API."""
    try:
        ee.Initialize()
    except ee.EEException:
        ee.Authenticate()
        ee.Initialize()

def _get_case_insensitive_close_matches(
    word: str, possibilities: List[str], n: int = 3, cutoff: float = 0.6
) -> List[str]:
    """A case-insensitive wrapper around difflib.get_close_matches.
    Parameters
    ----------
    word : str
        A string for which close matches are desired.
    possibilites : List[str]
        A list of strings against which to match word.
    n : int, default 3
        The maximum number of close matches to return. n must be > 0.
    cutoff : float, default 0.6
        Possibilities that don't score at least that similar to word are ignored.

    Returns
    -------
    List[str] : The best (no more than n) matches among the possibilities are returned in
        a list, sorted by similarity score, most similar first.
    """
    lower_matches = difflib.get_close_matches(
        word.lower(), [p.lower() for p in possibilities], n, cutoff
    )
    return [p for p in possibilities if p.lower() in lower_matches]

def _all_subclasses(cls: Type[Any]) -> Set[Type[Any]]:
    """Recursively find all subclasses of a given class."""
    return set(cls.__subclasses__()).union(
        [s for c in cls.__subclasses__() for s in _all_subclasses(c)]
    )

def _list_subclasses(superclass: Type[Any]) -> Mapping[str, Type[Any]]:
    """List all non-abstract subclasses of a given superclass. Return as a dictionary mapping the
    subclass name to the class. This is recursive, so sub-subclasses will also be returned.

    Parameters
    ----------
    superclass : Type[Any]
        The superclass to list subclasses of.

    Returns
    -------
    Dict[str, Type[Any]]
        A dictionary mapping the subclass name to the class.
    """
    return CaseInsensitiveDict(
        {
            cls.__name__: cls
            for cls in _all_subclasses(superclass)
            if not isabstract(cls)
        }
    )

def _get_subclasses(names: Tuple[str, ...], superclass: Type[Any]) -> Set[Type[Any]]:
    """Retrieve a set of subclasses of a given superclass.

    Parameters
    ----------
    names : Tuple[str, ...]
        A tuple of subclass names to retrieve from the superclass.
    superclass : Type[Any]
        The superclass to retrieve subclasses of.

    Returns
    -------
    Set[Type[Any]]
        A set of subclasses of the superclass.
    """
    options = _list_subclasses(superclass)
    keys = list(options.keys())

    if "all" in [name.lower() for name in names if isinstance(name, str)]:
        return set(options.values())

    selected = []

    for name in names:
        try:
            selected.append(options[name])
        except KeyError:
            close_matches = _get_case_insensitive_close_matches(name, keys, n=3)
            hint = " Close matches: {}.".format(close_matches) if close_matches else ""

            raise AttributeError(
                f'"{name}" is not a supported {superclass.__name__} type. Choose from {keys}.{hint}'
            )

    return set(selected)

def _millis_to_datetime(
    millis: str, tz: Optional[datetime.timezone] = None
) -> datetime.datetime:
    """Convert a timestamp in milliseconds (e.g. from Earth Engine) to a datetime object."""
    return datetime.datetime.fromtimestamp(int(millis) / 1000.0, tz=tz)

def _datetime_to_millis(dt: datetime.datetime) -> int:
    """Convert a datetime to a timestamp in milliseconds"""
    return int(dt.timestamp() * 1000)


from django.urls import path
from proyecto.views import index_proyecto, ProyectoCreate, ProyectoList, ProyectoUpdate, ProyectoDelete, proyecto_list_total

app_name = 'proyecto'

urlpatterns = [
    path("", index_proyecto, name="index_proyecto"),
    path("registrar/", ProyectoCreate.as_view(), name="registrar_proyecto"),
    path("listar/<int:id>", ProyectoList.as_view(), name="proyecto_listar"),
    path('listaDeProyecto/', proyecto_list_total, name= 'lista_total'),
    path("editar/<int:pk>", ProyectoUpdate.as_view(), name="editar_proyecto"),
    path("eliminar/<int:pk>", ProyectoDelete.as_view(), name="eliminar_proyecto"),
]


from pathlib import Path

from .CUBEparser import parse_files

# yapf: disable
SHORTHAND_FUNCTIONALS = [
    'svwn3',
    'svwn5',
    'pbe',
    'pbe0',
    'bpw91',
    'bp86',
    'b3p86',
    'b3p86-g',
    'blyp',
    'b3lyp',
    'b3lyp-g',
    'olyp',
    'kt1',
    'kt2',
    'kt3'
]
# yapf: enable
"""List of recognized shorthands for functionals"""

def write_scf_fock(user_dict, wf_dict, origin):
    fock_dict = {}

    # ZORA
    if user_dict["WaveFunction"]["relativity"].lower() == "zora":
        fock_dict["zora_operator"] = {
            "include_nuclear": user_dict["ZORA"]["include_nuclear"],
            "include_coulomb": user_dict["ZORA"]["include_coulomb"],
            "include_xc": user_dict["ZORA"]["include_xc"],
        }

    # Kinetic
    fock_dict["kinetic_operator"] = {"derivative": user_dict["Derivatives"]["kinetic"]}

    # Nuclear
    fock_dict["nuclear_operator"] = {
        "proj_prec": user_dict["Precisions"]["nuclear_prec"],
        "smooth_prec": user_dict["Precisions"]["nuclear_prec"],
        "nuclear_model": user_dict["WaveFunction"]["nuclear_model"],
        "shared_memory": user_dict["MPI"]["share_nuclear_potential"],
    }

    # Reaction
    if user_dict["WaveFunction"]["environment"].lower() == "pcm":
        fock_dict["reaction_operator"] = {
            "poisson_prec": user_dict["world_prec"],
            "kain": user_dict["PCM"]["SCRF"]["kain"],
            "max_iter": user_dict["PCM"]["SCRF"]["max_iter"],
            "optimizer": user_dict["PCM"]["SCRF"]["optimizer"],
            "dynamic_thrs": user_dict["PCM"]["SCRF"]["dynamic_thrs"],
            "density_type": user_dict["PCM"]["SCRF"]["density_type"],
            "epsilon_in": user_dict["PCM"]["Permittivity"]["epsilon_in"],
            "epsilon_out": user_dict["PCM"]["Permittivity"]["epsilon_out"],
            "formulation": user_dict["PCM"]["Permittivity"]["formulation"],
        }

    # Coulomb
    if wf_dict["method_type"] in ["hartree", "hf", "dft"]:
        fock_dict["coulomb_operator"] = {
            "poisson_prec": user_dict["Precisions"]["poisson_prec"],
            "shared_memory": user_dict["MPI"]["share_coulomb_potential"],
        }

    # Exchange
    if wf_dict["method_type"] in ["hf", "dft"]:
        fock_dict["exchange_operator"] = {
            "poisson_prec": user_dict["Precisions"]["poisson_prec"],
            "exchange_prec": user_dict["Precisions"]["exchange_prec"],
        }

    # Exchange-Correlation
    if wf_dict["method_type"] in ["dft"]:
        func_dict = []
        for line in wf_dict["dft_funcs"].split("\n"):
            sp = line.split()
            if len(sp) > 0:
                func = sp[0].lower()
                coef = [1.0]
                if len(sp) > 1:
                    coef = list(map(float, sp[1:]))
                func_dict.append({"name": func, "coef": coef[0]})
        fock_dict["xc_operator"] = {
            "shared_memory": user_dict["MPI"]["share_xc_potential"],
            "xc_functional": {
                "spin": user_dict["DFT"]["spin"],
                "cutoff": user_dict["DFT"]["density_cutoff"],
                "functionals": func_dict,
            },
        }

    # External electric field
    if len(user_dict["ExternalFields"]["electric_field"]) > 0:
        fock_dict["external_operator"] = {
            "electric_field": user_dict["ExternalFields"]["electric_field"],
            "r_O": origin,
        }

    return fock_dict

def write_scf_guess(user_dict, wf_dict):
    guess_str = user_dict["SCF"]["guess_type"].lower()
    guess_type = guess_str.split("_")[0]
    zeta = 0

    scf_dict = user_dict["SCF"]

    guess_prec = scf_dict["guess_prec"]

    if guess_type == "chk":
        # At least one orbital must be present in the checkpoint folder
        chk_Phi = Path(f"{scf_dict['path_checkpoint']}/phi_scf_idx_0.meta")
        if not chk_Phi.is_file():
            print(
                f"No checkpoint guess found in {scf_dict['path_checkpoint']}, falling back to 'sad_gto' initial guess"
            )
            guess_type = "sad_gto"
        else:
            # adjust guess precision if checkpoint files are present
            guess_prec = user_dict["world_prec"]

    if guess_type in ["core", "sad"]:
        zeta_str = guess_str.split("_")[1]
        if zeta_str == "sz":
            zeta = 1
        elif zeta_str == "dz":
            zeta = 2
        elif zeta_str == "tz":
            zeta = 3
        elif zeta_str == "qz":
            zeta = 4
        elif zeta_str == "gto":
            guess_type = guess_str
        else:
            print("Invalid zeta:" + zeta_str)

    file_dict = user_dict["Files"]

    if guess_type == "cube":
        found = parse_files(user_dict)
        if not found:
            print(
                f"No CUBE guess found in any of the 'initial_guess' sub-folders, falling back to 'sad_gto' initial guess"
            )
            guess_type = "sad_gto"

    vector_dir = file_dict["cube_vectors"]
    guess_dict = {
        "zeta": zeta,
        "prec": guess_prec,
        "type": guess_type,
        "method": wf_dict["method_name"],
        "relativity": wf_dict["relativity_name"],
        "environment": wf_dict["environment_name"],
        "external_field": wf_dict["external_name"],
        "screen": scf_dict["guess_screen"],
        "localize": scf_dict["localize"],
        "restricted": user_dict["WaveFunction"]["restricted"],
        "file_chk": f"{scf_dict['path_checkpoint']}/phi_scf",
        "file_basis": file_dict["guess_basis"],
        "file_gto_p": file_dict["guess_gto_p"],
        "file_gto_a": file_dict["guess_gto_a"],
        "file_gto_b": file_dict["guess_gto_b"],
        "file_phi_p": file_dict["guess_phi_p"] + "_scf",
        "file_phi_a": file_dict["guess_phi_a"] + "_scf",
        "file_phi_b": file_dict["guess_phi_b"] + "_scf",
        "file_CUBE_p": f"{vector_dir}CUBE_p_vector.json",
        "file_CUBE_a": f"{vector_dir}CUBE_a_vector.json",
        "file_CUBE_b": f"{vector_dir}CUBE_b_vector.json",
    }
    return guess_dict

def write_scf_solver(user_dict, wf_dict):
    # SCF precisions and thresholds
    start_prec = user_dict["SCF"]["start_prec"]
    final_prec = user_dict["SCF"]["final_prec"]
    if final_prec < 0.0:
        final_prec = user_dict["world_prec"]
    if start_prec < 0.0:
        start_prec = final_prec

    scf_dict = user_dict["SCF"]
    solver_dict = {
        "method": wf_dict["method_name"],
        "relativity": wf_dict["relativity_name"],
        "environment": wf_dict["environment_name"],
        "external_field": wf_dict["external_name"],
        "kain": scf_dict["kain"],
        "max_iter": scf_dict["max_iter"],
        "rotation": scf_dict["rotation"],
        "localize": scf_dict["localize"],
        "file_chk": scf_dict["path_checkpoint"] + "/phi_scf",
        "checkpoint": scf_dict["write_checkpoint"],
        "start_prec": start_prec,
        "final_prec": final_prec,
        "energy_thrs": scf_dict["energy_thrs"],
        "orbital_thrs": scf_dict["orbital_thrs"],
        "helmholtz_prec": user_dict["Precisions"]["helmholtz_prec"],
    }

    return solver_dict

def write_scf_properties(user_dict, origin):
    prop_dict = {}
    if user_dict["Properties"]["dipole_moment"]:
        prop_dict["dipole_moment"] = {}
        prop_dict["dipole_moment"]["dip-1"] = {
            "operator": "h_e_dip",
            "precision": user_dict["world_prec"],
            "r_O": origin,
        }
    if user_dict["Properties"]["quadrupole_moment"]:
        prop_dict["quadrupole_moment"] = {}
        prop_dict["quadrupole_moment"]["quad-1"] = {
            "operator": "h_e_quad",
            "precision": user_dict["world_prec"],
            "r_O": origin,
        }
    if user_dict["Properties"]["geometric_derivative"]:
        prop_dict["geometric_derivative"] = {}
        prop_dict["geometric_derivative"]["geom-1"] = {
            "operator": "h_nuc_grad",
            "precision": user_dict["world_prec"],
            "smoothing": user_dict["Precisions"]["nuclear_prec"],
        }
    return prop_dict

def write_scf_plot(user_dict):
    plot_dict = {}
    if user_dict["Properties"]["plot_density"] or len(
        user_dict["Properties"]["plot_orbitals"]
    ):
        plot_dict["orbitals"] = user_dict["Properties"]["plot_orbitals"]
        plot_dict["density"] = user_dict["Properties"]["plot_density"]
        plot_dict["plotter"] = user_dict["Plotter"]
        if user_dict["world_unit"] == "angstrom":
            plot_dict["plotter"] = {
                k: [
                    user_dict["Constants"]["angstrom2bohrs"] * r
                    for r in plot_dict["plotter"][k]
                ]
                for k in plot_dict["plotter"].keys()
            }
    return plot_dict

def write_rsp_calc(omega, user_dict, origin):
    wf_dict = parse_wf_method(user_dict)
    if not wf_dict["relativity_name"] in ["None", "Off"]:
        raise RuntimeError(
            "Linear response not available: " + wf_dict["relativity_name"]
        )

    rsp_dict = user_dict["Response"]
    file_dict = user_dict["Files"]

    rsp_calc = {}
    rsp_calc["frequency"] = omega
    rsp_calc["dynamic"] = omega > 1.0e-12
    rsp_calc["fock_operator"] = write_rsp_fock(user_dict, wf_dict)
    rsp_calc["unperturbed"] = {
        "precision": user_dict["world_prec"],
        "localize": rsp_dict["localize"],
        "fock_operator": write_scf_fock(user_dict, wf_dict, origin),
    }

    guess_str = rsp_dict["guess_type"].lower()
    user_guess_type = guess_str.split("_")[0]
    user_guess_prec = rsp_dict["guess_prec"]

    vector_dir = file_dict["cube_vectors"]

    rsp_calc["components"] = []
    for dir in [0, 1, 2]:

        rsp_comp = {}

        program_guess_type = user_guess_type
        program_guess_prec = user_guess_prec

        # check that initial guess files exist
        if user_guess_type == "chk":
            chk_X = Path(f"{rsp_dict['path_checkpoint']}/X_rsp_{dir:d}")
            chk_Y = Path(f"{rsp_dict['path_checkpoint']}/Y_rsp_{dir:d}")
            if not (chk_X.is_file() and chk_Y.is_file()):
                print(
                    f"No checkpoint guess found in {rsp_dict['path_checkpoint']} for direction {dir:d}, falling back to zero initial guess"
                )
                program_guess_type = "none"
            else:
                # adjust guess precision if checkpoint files are present
                program_guess_prec = user_dict["world_prec"]
        elif user_guess_type == "cube":
            found = parse_files(user_dict, dir)
            if not found:
                print(
                    f"No CUBE guess found in any of the 'initial_guess' sub-folders for direction {dir:d}, falling back to zero initial guess"
                )
                program_guess_type = "none"
        else:
            # do no checks on other types of guess
            pass

        rsp_comp["initial_guess"] = {
            "prec": program_guess_prec,
            "type": program_guess_type,
            "file_chk_x": f"{rsp_dict['path_checkpoint']}/X_rsp_{dir:d}",
            "file_chk_y": f"{rsp_dict['path_checkpoint']}/Y_rsp_{dir:d}",
            "file_x_p": f"{file_dict['guess_x_p']}_rsp_{dir:d}",
            "file_x_a": f"{file_dict['guess_x_a']}_rsp_{dir:d}",
            "file_x_b": f"{file_dict['guess_x_b']}_rsp_{dir:d}",
            "file_y_p": f"{file_dict['guess_y_p']}_rsp_{dir:d}",
            "file_y_a": f"{file_dict['guess_y_a']}_rsp_{dir:d}",
            "file_y_b": f"{file_dict['guess_y_b']}_rsp_{dir:d}",
            "file_CUBE_x_p": f"{vector_dir}CUBE_x_p_{dir:d}_vector.json",
            "file_CUBE_x_a": f"{vector_dir}CUBE_x_a_{dir:d}_vector.json",
            "file_CUBE_x_b": f"{vector_dir}CUBE_x_b_{dir:d}_vector.json",
            "file_CUBE_y_p": f"{vector_dir}CUBE_y_p_{dir:d}_vector.json",
            "file_CUBE_y_a": f"{vector_dir}CUBE_y_a_{dir:d}_vector.json",
            "file_CUBE_y_b": f"{vector_dir}CUBE_y_b_{dir:d}_vector.json",
        }
        if rsp_dict["write_orbitals"]:
            path_orbitals = rsp_dict["path_orbitals"]
            rsp_comp["write_orbitals"] = {
                "file_x_p": f"{path_orbitals}/X_p_rsp_{dir:d}",
                "file_x_a": f"{path_orbitals}/X_a_rsp_{dir:d}",
                "file_x_b": f"{path_orbitals}/X_b_rsp_{dir:d}",
                "file_y_p": f"{path_orbitals}/Y_p_rsp_{dir:d}",
                "file_y_a": f"{path_orbitals}/Y_a_rsp_{dir:d}",
                "file_y_b": f"{path_orbitals}/Y_b_rsp_{dir:d}",
            }
        if rsp_dict["run"][dir]:
            rsp_comp["rsp_solver"] = write_rsp_solver(user_dict, wf_dict, dir)
        rsp_calc["components"].append(rsp_comp)
    return rsp_calc

def write_rsp_fock(user_dict, wf_dict):
    fock_dict = {}

    # Coulomb
    if wf_dict["method_type"] in ["hartree", "hf", "dft"]:
        fock_dict["coulomb_operator"] = {
            "poisson_prec": user_dict["Precisions"]["poisson_prec"],
            "shared_memory": user_dict["MPI"]["share_coulomb_potential"],
        }

    # Exchange
    if wf_dict["method_type"] in ["hf", "dft"]:
        fock_dict["exchange_operator"] = {
            "poisson_prec": user_dict["Precisions"]["poisson_prec"],
            "exchange_prec": user_dict["Precisions"]["exchange_prec"],
        }

    # Exchange-Correlation
    if wf_dict["method_type"] in ["dft"]:
        func_dict = []
        for line in wf_dict["dft_funcs"].split("\n"):
            sp = line.split()
            if len(sp) > 0:
                func = sp[0].lower()
                coef = [1.0]
                if len(sp) > 1:
                    coef = list(map(float, sp[1:]))
                func_dict.append({"name": func, "coef": coef[0]})
        fock_dict["xc_operator"] = {
            "shared_memory": user_dict["MPI"]["share_xc_potential"],
            "xc_functional": {
                "spin": user_dict["DFT"]["spin"],
                "cutoff": user_dict["DFT"]["density_cutoff"],
                "functionals": func_dict,
            },
        }

    return fock_dict

def write_rsp_solver(user_dict, wf_dict, d):
    # Response precisions and thresholds
    start_prec = user_dict["Response"]["start_prec"]
    final_prec = user_dict["Response"]["final_prec"]
    if final_prec < 0.0:
        final_prec = user_dict["world_prec"]
    if start_prec < 0.0:
        start_prec = final_prec

    rsp_dict = user_dict["Response"]
    solver_dict = {
        "method": wf_dict["method_name"],
        "kain": rsp_dict["kain"],
        "max_iter": rsp_dict["max_iter"],
        "file_chk_x": rsp_dict["path_checkpoint"] + "/X_rsp_" + str(d),
        "file_chk_y": rsp_dict["path_checkpoint"] + "/Y_rsp_" + str(d),
        "checkpoint": rsp_dict["write_checkpoint"],
        "start_prec": start_prec,
        "final_prec": final_prec,
        "orbital_thrs": user_dict["Response"]["orbital_thrs"],
        "property_thrs": user_dict["Response"]["property_thrs"],
        "helmholtz_prec": user_dict["Precisions"]["helmholtz_prec"],
        "orth_prec": 1.0e-14,
    }
    return solver_dict

def parse_wf_method(user_dict):
    method_name = ""
    restricted = user_dict["WaveFunction"]["restricted"]
    method_type = user_dict["WaveFunction"]["method"].lower()
    dft_funcs = user_dict["DFT"]["functionals"].lower()
    if method_type in ["core"]:
        method_name = "Core Hamiltonian"
    elif method_type in ["hartree"]:
        method_name = "Hartree"
    elif method_type in ["hf", "hartree-fock", "hartreefock"]:
        method_name = "Hartree-Fock"
        method_type = "hf"
    elif method_type in ["dft"]:
        method_name = "DFT"
    elif method_type in ["lda"]:
        method_name = "DFT (SVWN5)"
        dft_funcs = "svwn5"
        method_type = "dft"
    elif method_type in SHORTHAND_FUNCTIONALS:
        method_name = "DFT (" + method_type.upper() + ")"
        dft_funcs = method_type
        method_type = "dft"
    else:
        raise RuntimeError(
            f"Invalid wavefunction method {user_dict['WaveFunction']['method']}"
        )

    # Determine relativity name label for print outs to the output file
    relativity_name = "None"
    if user_dict["WaveFunction"]["relativity"].lower() in ["none"]:
        user_dict["WaveFunction"]["relativity"] = "off"
        user_dict["ZORA"]["include_nuclear"] = False
        user_dict["ZORA"]["include_coulomb"] = False
        user_dict["ZORA"]["include_xc"] = False

    if user_dict["WaveFunction"]["relativity"].lower() in ["nzora"]:
        user_dict["WaveFunction"]["relativity"] = "zora"
        user_dict["ZORA"]["include_nuclear"] = True
        user_dict["ZORA"]["include_coulomb"] = False
        user_dict["ZORA"]["include_xc"] = False

    if user_dict["WaveFunction"]["relativity"].lower() in ["zora"]:
        components = [
            user_dict["ZORA"]["include_nuclear"],
            user_dict["ZORA"]["include_coulomb"],
            user_dict["ZORA"]["include_xc"],
        ]
        names = ["V_nuc", "J", "V_xc"]

        if any(components):
            zora_terms = " + ".join(
                [name for name, comp in zip(names, components) if comp]
            )
            relativity_name = "ZORA (" + zora_terms + ")"
        else:
            raise RuntimeError("ZORA selected, but no ZORA potential included")

        if user_dict["ZORA"]["include_xc"] and not restricted:
            raise RuntimeError(
                "ZORA (V_xc) not available for unrestricted wavefunctions"
            )

    # Determine environment name label for print outs to the output file
    environment_name = "None"
    if user_dict["WaveFunction"]["environment"].lower() == "pcm":
        environment_name = "PCM"

    # Determine external name label for print outs to the output file
    ext_dict = user_dict["ExternalFields"]
    has_external_fields = len(ext_dict["electric_field"]) > 0

    external_name = "None"
    if has_external_fields:
        # If no external fields, then the list will be empty
        # Need to catch the exception and store placeholders
        try:
            x, y, z = ext_dict["electric_field"]
        except ValueError:
            x, y, z = None, None, None  # Useless placeholders

        # Labels to aggregate
        external_name = f"Electric field ({x}, {y}, {z})"

    wf_dict = {
        "relativity_name": relativity_name,
        "environment_name": environment_name,
        "external_name": external_name,
        "method_name": method_name,
        "method_type": method_type,
        "dft_funcs": dft_funcs,
    }
    return wf_dict


"""The URL configuration of the application
When the particular URL is hit it feeds the request to the corresponding view.
"""
from django.urls import path
from django.views.generic import RedirectView

from .views import base, add_to_registry, validate_url, issue_registry, dashboard

urlpatterns = [
    path('base/', base),
    path('add/', add_to_registry),
    path('api/validate_url', validate_url),
    path('issue_registry/', issue_registry),
    path('dashboard/', dashboard, name='dashboard'),
    path('', RedirectView.as_view(pattern_name='dashboard', permanent=False)),
]


"""
This module contains functions to check whether a schedule is:

    1. view-serializable
    2. conflict-serializable
    3. recoverable
    4. avoids cascading aborts
    5. strict

It also contains some nice functions to tabularize schedules into tex and draw
a conflict graph using matplotlib.
"""

from action import *
from collections import defaultdict
import itertools
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np

################################################################################
# helper functions
################################################################################
def flatten(ls):
    """
    >>> flatten([[], [1], [2,3], [4]])
    [1, 2, 3, 4]
    """
    return [x for l in ls for x in l]

def graphs_eq(g1, g2):
    """
    Returns if two networkx graphs are 100% identical.

    >>> G1 = nx.DiGraph()
    >>> G1.add_nodes_from([1, 2, 3])
    >>> G1.add_edges_from([(1, 2), (2, 3), (3, 1)])
    >>> G2 = nx.DiGraph()
    >>> G2.add_nodes_from([3, 2, 1])
    >>> G2.add_edges_from([(3, 1), (2, 3), (1, 2)])
    >>> G3 = nx.DiGraph()
    >>> G3.add_nodes_from([1, 2, 3, 4])
    >>> G3.add_edges_from([(1, 2), (2, 3), (3, 1)])
    >>> G4 = nx.DiGraph()
    >>> G4.add_nodes_from([1, 2, 3])
    >>> G4.add_edges_from([(1, 2), (2, 3), (3, 1), (1, 4)])
    >>> graphs_eq(G1, G2)
    True
    >>> graphs_eq(G2, G1)
    True
    >>> graphs_eq(G1, G3)
    False
    >>> graphs_eq(G1, G4)
    False
    """
    return (set(g1.nodes()) == set(g2.nodes()) and
            set(g1.edges()) == set(g2.edges()))

def transaction_ids(schedule):
    """
    Return a list of the _unique_ transaction ids in the schedule in the order
    that they appear.

    >>> transaction_ids([r(1, "A"), r(2, "A"), w(1, "A"), r(3, "A")])
    [1, 2, 3]
    """
    js = []
    for a in schedule:
        if a.i not in js:
            js.append(a.i)
    return js

def transactions(schedule):
    """
    Partitions a schedule into the list of transactions that compose it.
    Transactions are returned in the order in which an operation of the
    transaction first appears.

    >>> transactions([
    ...     r(1, "A"),
    ...     w(2, "A"),
    ...     commit(2),
    ...     w(1, "A"),
    ...     commit(1),
    ...     w(3, "A"),
    ...     commit(3),
    ... ])
    [[R_1(A), W_1(A), Commit_1], [W_2(A), Commit_2], [W_3(A), Commit_3]]
    >>> transactions([
    ...     w(2, "A"),
    ...     r(1, "A"),
    ...     commit(2),
    ...     w(1, "A"),
    ...     commit(1),
    ...     w(3, "A"),
    ...     commit(3),
    ... ])
    [[W_2(A), Commit_2], [R_1(A), W_1(A), Commit_1], [W_3(A), Commit_3]]
    """
    js = transaction_ids(schedule)
    partitions = [[] for _ in range(len(js))]
    index = {js: i for (i, js) in enumerate(js)}
    for a in schedule:
        partitions[index[a.i]].append(a)
    return partitions

def drop_aborts(schedule):
    """
    Remove all transactions that abort.
    >>> drop_aborts([r(1, "A"), r(2, "A"), r(3, "A"), abort(1), commit(2), abort(3)])
    [R_2(A), Commit_2]
    """
    aborteds = {a.i for a in schedule if a.op == ABORT}
    return [a for a in schedule if a.i not in aborteds]

def add_commits(schedule):
    """
    Add a commit for every transaction that doesn't end in a commit or abort.
    Commits are added in the order of the first action of the transaction.

    >>> add_commits([r(1, "A"), r(2, "A"), r(3, "A"), r(4, "A"), commit(2), abort(4)])
    [R_1(A), R_2(A), R_3(A), R_4(A), Commit_2, Abort_4, Commit_1, Commit_3]
    """
    ends = {a.i for a in schedule if a.op == COMMIT or a.op == ABORT}
    no_ends = [i for i in transaction_ids(schedule) if i not in ends]
    return schedule + [commit(i) for i in no_ends]

def first_read(schedule):
    """
    Returns a mapping from each object to the transaction ids that initially
    read it. If an object is never read, it is not included in the return.

    >>> first_read([w(1, "A"), w(2, "B")])
    {}
    >>> first_read([r(1, "A"), r(2, "B"), r(2, "A")])
    {'A': [1, 2], 'B': [2]}
    """
    fr = defaultdict(list)
    written = set()
    for a in schedule:
        if a.op == READ and a.obj not in written:
            fr[a.obj].append(a.i)
        elif a.op == WRITE:
            written.add(a.obj)
    return dict(fr)

def number(schedule):
    """
    Enumerates each action according to its appearance within its transaction.
    The enumeration begins at 0.

    >>> number([r(1, "A"), r(1, "B"), r(2, "A"), w(3, "A"), commit(2)])
    [(0, R_1(A)), (1, R_1(B)), (0, R_2(A)), (0, W_3(A)), (1, Commit_2)]
    """
    ns = {i: 0 for i in transaction_ids(schedule)}
    s = []
    for a in schedule:
        s.append((ns[a.i], a))
        ns[a.i] += 1
    return s

def view_graph(schedule):
    """
    First, the schedule is numbered using the number function. Then, an edge is
    added from each read of an object to the most recent write to the same
    object.

    >>> view_graph([w(1, "A"), r(2, "A"), r(1, "A")]) #doctest: +SKIP
    +------------+     +------------+
    | (0, W_1(A) |<----| (0, R_2(A) |
    +------------+     +------------+
           ^
           |
    +------------+
    | (1, R_1(A) |
    +------------+
    """
    G = nx.DiGraph()
    last_written = {}
    for (i, a) in number(schedule):
        if a.op == WRITE:
            last_written[a.obj] = (i, a)
        elif a.op == READ:
            if a.obj in last_written:
                G.add_edge((i, a), last_written[a.obj])
        else: # a.op == COMMIT or a.op == ABORT
            pass
    return G

def last_written(schedule):
    """
    Returns a mapping from each object to the transaction id that last writes
    it. If an object is never written, it is not included in the return.

    >>> last_written([r(1, "A"), r(2, "B")])
    {}
    >>> last_written([w(1, "A"), w(2, "B"), w(2, "A")])
    {'A': 2, 'B': 2}
    """
    lw = {}
    for a in schedule:
        if a.op == WRITE:
            lw[a.obj] = a.i
    return lw

def view_equivalent(s1, s2):
    """
    Two schedules s1 and s2 are view equivalent if

        1. If Ti reads the initial value of object A in s1, it must also read
           the initial value of A in s2.
        2. If Ti reads a value of A written by Tj in s1, it must also read the
           value of A written by Tj in s2.
        3. For each data object A, the transaction (if any) that performs the
           final write on A in s1 must also perform the final write on A in s2.
    """
    assert set(transaction_ids(s1)) == set(transaction_ids(s2))

    # condition 1
    if not (first_read(s1) == first_read(s2)):
        return False

    # condition 2
    if not graphs_eq(view_graph(s1), view_graph(s2)):
        return False

    # condition 3
    if not (last_written(s1) == last_written(s2)):
        return False

    return True

################################################################################
# predicates
################################################################################
def view_serializable(schedule):
    """
    A schedule is view serializable if it is view equivalent to a some serial
    schedule over the same transactions. Aborted transactions are ignored.
    """
    schedule = drop_aborts(schedule)

    # conflict serializability implies view serializability
    if conflict_serializable(schedule):
        return True

    # if a schedule is not conflict serializable but doesn't have blind writes,
    # then it isn't view serializabile
    partitions = transactions(schedule)
    blind_write = False
    for t in partitions:
        objects_read = set()
        for a in t:
            if a.op == WRITE and a.obj not in objects_read:
                blind_write = True
            elif a.op == READ:
                objects_read.add(a.obj)
            else: # a.op == COMMIT or a.op == ABORT
                pass
    if not blind_write:
        return False

    # brute force check over all serializations to see if the schedule is view
    # equivalent to any serial schedule over the same set of transactions
    for s in itertools.permutations(transactions(schedule)):
        s = flatten(list(s))
        if view_equivalent(s, schedule):
            return True
    return False

def conflict_serializable(schedule):
    """
    A schedule is conflict serializable if its conflict graph is acyclic.
    Aborted transactions are ignored.
    """
    return len(list(nx.simple_cycles(conflict_graph(schedule)))) == 0

def recoverable(schedule):
    """
    A schedule is recoverable if all the transactions whose changes it read
    commit and the schedule commits after them.
    """
    schedule = add_commits(schedule)

    written_by = defaultdict(list) # object -> ids
    read_from  = defaultdict(set)  # id -> ids
    committed  = set()             # ids
    for a in schedule:
        if a.op == WRITE:
            written_by[a.obj].append(a.i)
        elif a.op == READ:
            if a.obj in written_by and  \
                   len(written_by[a.obj]) > 0 and \
                   written_by[a.obj][-1] != a.i:
               read_from[a.i].add(written_by[a.obj][-1])
        elif a.op == COMMIT:
            if not all(i in committed for i in read_from[a.i]):
                return False
            committed.add(a.i)
        elif a.op == ABORT:
            for (o, ids) in written_by.iteritems():
                written_by[o] = [i for i in ids if i != a.i]

    return True

def aca(schedule):
    """A schedule avoids cascading aborts if it only reads commited changes."""
    schedule = add_commits(schedule)

    last_write = defaultdict(list) # object -> ids
    committed  = set()             # ids
    for a in schedule:
        if a.op == WRITE:
            last_write[a.obj].append(a.i)
        elif a.op == READ:
            if a.obj in last_write and \
                    len(last_write[a.obj]) > 0 and \
                    last_write[a.obj][-1] not in committed \
                    and last_write[a.obj][-1] != a.i:
                return False
        elif a.op == COMMIT:
            committed.add(a.i)
        elif a.op == ABORT:
            for (o, ids) in last_write.iteritems():
                last_write[o] = [i for i in ids if i != a.i]

    return True

def strict(schedule):
    """
    A schedule is strict if never reads or writes to an uncommited changed
    variable.
    """
    schedule = add_commits(schedule)

    last_write = defaultdict(list) # object -> id
    committed  = set()             # ids
    for a in schedule:
        if a.op == WRITE or a.op == READ:
            if a.obj in last_write and \
                    len(last_write[a.obj]) > 0 and \
                    last_write[a.obj][-1] not in committed and \
                    last_write[a.obj][-1] != a.i:
                return False
            if a.op == WRITE:
                last_write[a.obj].append(a.i)
        elif a.op == COMMIT:
            committed.add(a.i)
        elif a.op == ABORT:
            for (o, ids) in last_write.iteritems():
                last_write[o] = [i for i in ids if i != a.i]

    return True

################################################################################
# misc
################################################################################
def tex(schedule):
    """
    Return a texed tabular representation of a schedule.

    >>> tex([r(1,"A"), r(1,"B"), r(2,"B"), r(3,"B"), r(1,"A"), r(2,"B")]) #doctest: +SKIP
    +--------+--------+--------+
    | T_1    | T_2    | T_3    |
    +--------+--------+--------+
    | R_1(A) |        |        |
    | R_1(B) |        |        |
    |        | R_2(B) |        |
    |        |        | R_3(B) |
    | R_1(A) |        |        |
    |        | R_2(B) |        |
    +--------+--------+--------+
    """
    transactions = sorted(transaction_ids(schedule))
    s = r"\begin{tabular}{" + ("|" + "|".join("c" for _ in transactions) + "|" )+ "}\n"
    s += r"\hline" + "\n"
    s += "&".join("$T_{}$".format(t) for t in transactions) + r"\\\hline" + "\n"
    for a in schedule:
        index = transactions.index(a.i)
        s += ("&" * index) + a.tex() + ("&" * (len(transactions) - 1 - index))
        s += r"\\\hline" + "\n"
    s += r"\end{tabular}" + "\n"
    return s

def conflict_graph(schedule):
    """
    A graph with an edge from a to b for each pair of actions (a, b) from
    different transactions on the same object where at least one of the actions
    is a write and a precedes b.
    """
    schedule = drop_aborts(schedule)
    G = nx.DiGraph()
    G.add_nodes_from(transaction_ids(schedule))

    for (i, a) in enumerate(schedule):
        for b in schedule[i+1:]:
            same_obj = a.obj == b.obj
            diff_txn = a.i != b.i
            conflict = a.op == WRITE or b.op == WRITE
            if same_obj and diff_txn and conflict:
                G.add_edge(a.i, b.i)
    return G

def draw(G):
    """Prettily draw a networkx graph G."""
    plt.figure()
    color_range = np.linspace(0, 1, len(G.nodes()))
    labels = {n: "$T_{{{}}}$".format(n) for n in G}
    pos = nx.spectral_layout(G)
    kwargs = {
        "alpha": 1.0,
        "cmap": plt.get_cmap("Dark2"), # http://bit.ly/1ItQDgE
        "font_color": "w",
        "font_size": 40,
        "labels": labels,
        "node_color": color_range,
        "node_size": 10000,
        "pos": pos,                    # http://bit.ly/1DAnT4y
        "width": 4.0,
        "with_labels": True,
    }
    nx.draw(G, **kwargs)

if __name__ == "__main__":
    import doctest
    doctest.testmod()


from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

from widgets.mixins import TextColorMixin
from utils.encoders import EncodeMethod, create_encoder
from strings import _

class EncodePage(QWidget, TextColorMixin):
    def __init__(self, parent=None):
        super(EncodePage, self).__init__(parent)
        self.setupUi()

    def setupUi(self):
        self.method_base64 = self.create_method_radio('BASE64', EncodeMethod.base64)
        self.method_md5 = self.create_method_radio('MD5', EncodeMethod.md5)
        self.method_url = self.create_method_radio('URL', EncodeMethod.url)
        self.method_html = self.create_method_radio('HTML', EncodeMethod.html)

        btnEncode = QPushButton('&Encode')
        btnDecode = QPushButton('&Decode')

        self.src_edit = QTextEdit()
        self.src_edit.setFixedHeight(300)

        self.dest_edit = QTextEdit()
        self.dest_edit.setFixedHeight(300)

        method_box = QHBoxLayout()
        method_box.addWidget(QLabel(_('method')))
        method_box.addWidget(self.method_base64)
        method_box.addWidget(self.method_md5)
        method_box.addWidget(self.method_url)
        method_box.addWidget(self.method_html)
        method_box.addStretch()

        btnBox = QVBoxLayout()
        btnBox.addStretch()
        btnBox.addWidget(btnEncode)
        btnBox.addWidget(btnDecode)
        btnBox.addStretch()

        center_box = QHBoxLayout()
        center_box.addWidget(self.src_edit, 1)
        center_box.addLayout(btnBox)
        center_box.addWidget(self.dest_edit, 1)

        vbox = QVBoxLayout()
        vbox.addLayout(method_box)
        vbox.addLayout(center_box)
        vbox.addStretch()
        self.setLayout(vbox)

        btnEncode.clicked.connect(self.on_encode)
        btnDecode.clicked.connect(self.on_decode)
        self.src_edit.textChanged.connect(self.on_srcEdit_textChanged)
        self.dest_edit.textChanged.connect(self.on_destEdit_textChanged)

    def create_method_radio(self, text, value):
        radio = QRadioButton(text)
        radio.setProperty('value', value)
        return radio

    def on_initialized(self):
        self.method_base64.setChecked(True)

    def get_encoder(self):
        method = EncodeMethod.base64
        if self.method_md5.isChecked():
            method = EncodeMethod.md5
        elif self.method_url.isChecked():
            method = EncodeMethod.url
        elif self.method_html.isChecked():
            method = EncodeMethod.html
        return create_encoder(method)

    @pyqtSlot()
    def on_encode(self):
        try:
            src = self.src_edit.toPlainText().strip()
            encoder = self.get_encoder()
            result = encoder.encode(src)
            self.setColoredText(self.dest_edit, result, True)
        except Exception as e:
            self.setColoredText(self.dest_edit, str(e), False)

    @pyqtSlot()
    def on_decode(self):
        try:
            src = self.dest_edit.toPlainText().strip()
            encoder = self.get_encoder()
            result = encoder.decode(src)
            self.setColoredText(self.src_edit, result, True)
        except Exception as e:
            self.setColoredText(self.src_edit, str(e), False)

    @pyqtSlot()
    def on_srcEdit_textChanged(self):
        if self.src_edit.hasFocus():
            self.on_encode()

    @pyqtSlot()
    def on_destEdit_textChanged(self):
        if self.dest_edit.hasFocus():
            self.on_decode()


import argparse
from experiment import Experiment
import Limited_GP

parser = argparse.ArgumentParser()
parser.add_argument('--number-of-batches', type=int, default=1)
parser.add_argument('--current-batch', type=int, default=1)
parser.add_argument('--budget', type=int, default=10000)
parser.add_argument('--suite-name', default='bbob')
args = parser.parse_args()

e = Experiment(suite_name=args.suite_name, solver=Limited_GP.solve, algorithm_name='Limited-GP')
e.run(budget=args.budget, current_batch=args.current_batch, number_of_batches=args.number_of_batches)


import math
import numpy as np
import pandas as pd

def distance(point1,point2):
    return math.sqrt(pow(point1[0] - point2[0], 2) + pow(point1[1] - point2[1], 2))

points = []
center_points = []
K = 0
file="D:\\experiment\\第三次豆瓣\\测试3\\train\\douban_train_zuobiao.csv"
data=pd.read_csv(file)
train_data = np.array(data)#np.ndarray()每个姓名转换为一个list[]
#print(type(train_data))
all_list=train_data.tolist()#转换list
#print(all_list)

for item in all_list:
    print(item[1])
    print(item[2])
    print("-----------------------")
    point = [item[1], item[2]]
    points.append(point)

#print(type(points))#每个点存入列表
points = np.array(points)#转化为数组形式
#print(points)

T = 0
for item in points:
    avg = 0
    for other in points:
        if all(other == item):
            continue
        avg += distance(item,other)
    avg /= 181
    print("当前点的平均距离为：",avg)
    T += avg
T /= 182
print("T值为：",T)


def semantic_validity_factory(value, semantic_name, null_values=set(['Unspecified', 'N/A', '', 0, None]), **kwargs) :

    if value in null_values:
        return (None, None)

    elif all(f(value) for name, f in kwargs.items() if 'semantic' in name):
        if all(f(value) for name, f in kwargs.items() if 'valid' in name):
            return (semantic_name, 'valid')
        else:
            return (semantic_name, 'invalid')

    else:
        # only checking for semantic type!
        return (None, None)


#from ast import If
#from pprint import pp
#from typing import final
from genericpath import exists
from multiprocessing.reduction import duplicate
import re
import string
from unittest import result
from tokens import tokens
from tkinter import *
from tkinter import messagebox as MessageBox
from tkinter import messagebox

#from Interfaz import datos
#resultReservadas = []
#resultCaracteresEspeciales = []
#resultDelimitadores = []

class analizador:
    tokens = tokens()
    def inicio_analizador(self, palabras):
        resultReservadas = []
        resultCaracteresEspeciales = []
        resultDelimitadores = []
        resultIndefinidas = []
        resultErrores = []
        resultDigitos = []
        listResultados = []
        print("--- Lexico ---")
        for i in palabras:
            if(i in tokens.reservadas):
                resultReservadas.append(i)
                palabras.remove(i)
            if(i in tokens.caracteres_especiales):
                resultCaracteresEspeciales.append(i)
                palabras.remove(i)
            if(i in tokens.delimitadores):
                resultDelimitadores.append(i)
                palabras.remove(i)
        for g in range (len(palabras)):
            dato = re.search("[a-zA-Z][a-zA-Z0-9_]*", palabras[g])
            if dato:
                resultIndefinidas.append(palabras[g])
            else:
                dato1 = re.search("^[0-9]+$", palabras[g])
                if dato1:
                    resultIndefinidas.append(palabras[g])
                else:
                    resultErrores.append(palabras[g])

        print("Token Reservadas: ",resultReservadas)
        print("Token Caracteres Especiales: ",resultCaracteresEspeciales)
        print("Token Delimitadores: ",resultDelimitadores)
        print("Token Indefinidas: ",resultIndefinidas)
        print("Errores: ",resultErrores)
        listResultados.append(resultReservadas)
        listResultados.append(resultCaracteresEspeciales)
        listResultados.append(resultDelimitadores)
        listResultados.append(resultIndefinidas)
        listResultados.append(resultDigitos)
        listResultados.append(resultErrores)
        return listResultados


# features - word cnt, character cnt, sentence cnt, word freq
import sys
import time
import json
import string
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem.porter import PorterStemmer
import numpy as np
import pandas as pd

porter = PorterStemmer()
stop_words = set(stopwords.words('english'))

train_file = "/Users/aparahuja/Desktop/IITD/ML/Assignment 2/Q1/reviews_Digital_Music_5.json/Music_Review_train.json"
test_file = "/Users/aparahuja/Desktop/IITD/ML/Assignment 2/Q1/reviews_Digital_Music_5.json/Music_Review_test.json"

if len(sys.argv) > 1:
    train_file = sys.argv[1]
    test_file = sys.argv[2]

train_data = pd.read_json(train_file, lines=True)
test_data = pd.read_json(test_file, lines=True)

vocabulary = set()
theta = {}
phi = {}
cnt = {}
m = len(train_data)

def F1_Confusion(y_true, y_predict):
    confusion = np.zeros((5, 5))
    n = len(y_true)
    for i in range(n):
        confusion[int(y_true[i]) - 1][int(y_predict[i]) - 1] += 1
    # print("Confusion Matrix: ")
    # print(confusion)
    print("F1 scores:")
    f1_avg = 0
    for i in range(5):
        tp = confusion[i][i]
        fn = sum([confusion[j][i] if i != j else 0 for j in range(5)])
        fp = sum([confusion[i][j] if i != j else 0 for j in range(5)])
        f1_score = tp/(tp+(fp+fn)/2)
        f1_avg += f1_score/5
        print("\tClass " + str(i+1) + " = " + "{:.5f}".format(f1_score))
    print("Macro F1 score = " + "{:.5f}".format(f1_avg))

def tokenize(review):
    tokens = [w.lower() for w in word_tokenize(review)]
    table = str.maketrans('', '', string.punctuation)
    stripped = [w.translate(table) for w in tokens]
    words = [porter.stem(word) for word in stripped if word.isalpha()]
    return [word for word in words if word not in stop_words]

def findcharClass(n):
    if n < 400:
        return "$A$"
    if n < 800:
        return "$B$"
    if n < 1200:
        return "$C$"
    if n < 1600:
        return "$D$"
    return "$E$"

def findwordClass(n):
    if n < 100:
        return "$A$"
    if n < 200:
        return "$B$"
    if n < 300:
        return "$C$"
    if n < 400:
        return "$D$"
    return "$E$"

def findDenseClass(n):
    if n < 4:
        return "$A$"
    if n < 8:
        return "$B$"
    if n < 12:
        return "$C$"
    if n < 16:
        return "$D$"
    return "$E$"

TokenizedReviews = []

def initializeModel(fcnt):
    global vocabulary, theta, phi, cnt, TokenizedReviews
    vocabulary = set()
    theta = {}
    phi = {}
    cnt = {}
    TokenizedReviews = []

    for index, data in train_data.iterrows():
        review = data['reviewText']
        label = data['overall']
        theta[label] = {}
        cnt[label] = 0
        phi[label] = 0
        words = tokenize(review)
        # convert to bigrams
        bigrams = [words[i] + words[i+1] for i in range(len(words) - 1)]
        if fcnt == 0:
            TokenizedReviews.append(words + bigrams)
            for word in words + bigrams:
                vocabulary.add(word)
        else:
            TokenizedReviews.append(words)
            for word in words:
                vocabulary.add(word)
    if fcnt > 0:
        vocabulary.add("$A$")
        vocabulary.add("$B$")
        vocabulary.add("$C$")
        vocabulary.add("$D$")
        vocabulary.add("$E$")
    vocabulary.add("UNK")
    file = open("vocabulary_e.txt", "w")
    file.write(json.dumps(list(vocabulary)))
    file.close()

    for label in theta:
        for word in vocabulary:
            theta[label][word] = 0

def learnParameters(fcnt):
    for index, data in train_data.iterrows():
        review = data['reviewText']
        label = data['overall']
        words = TokenizedReviews[index]
        phi[label] += 1
        for word in words:
            theta[label][word] += 1
            cnt[label] += 1
        if fcnt == 1:
            theta[label][findcharClass(len(review))] += 1
        if fcnt == 2:
            theta[label][findwordClass(len(words))] += 1
        # avg word length
        # theta[label][findDenseClass(len(review) / len(words))] += 1
    for label in theta:
        for word in vocabulary:
            theta[label][word] = (theta[label][word] + 1) / \
                (cnt[label] + len(vocabulary) + 1)
        phi[label] /= m

def predict(words, label):
    ans = np.log(phi[label])
    for word in words:
        if word in vocabulary:
            ans += np.log(theta[label][word])
        else:
            ans += np.log(theta[label]["UNK"])
    return ans

def findModelAccuracy(input_data, fcnt, datatype):
    print("Running model on " + datatype + " data.")
    correct = 0
    total = len(input_data)
    y_true = []
    y_predict = []
    for index, data in input_data.iterrows():
        review = data['reviewText']
        words = tokenize(review)
        bigrams = [words[i] + words[i+1] for i in range(len(words) - 1)]
        ans_label = data['overall']
        ans, logProbab = "", - sys.maxsize
        for label in phi:
            if fcnt == 0:
                prediction = predict(words + bigrams, label)
            if fcnt == 1:
                prediction = predict(
                    words, label) + 5*np.log(theta[label][findcharClass(len(review))])
            if fcnt == 2:
                prediction = predict(
                    words, label) + 5*np.log(theta[label][findwordClass(len(words))])
            # avg word length
            # prediction = predict(words, label) + 5 * np.log(theta[label][findDenseClass(len(review) / len(words))])
            if logProbab <= prediction:
                ans = label
                logProbab = prediction
        if ans_label == ans:
            correct += 1
        y_true.append(ans_label)
        y_predict.append(ans)
    F1_Confusion(y_true, y_predict)
    print("Model " + datatype + " accuracy:",
          "{:.2f}".format(correct/total*100) + "%")

features = ['single words + bigrams',
            'single words + charcter count', 'single words + word count']
fcnt = 0
for feature in features:
    print("\nTesting with feature - " + feature)
    st = time.time()
    initializeModel(fcnt)
    learnParameters(fcnt)
    en = time.time()
    print("Training Time = " + "{:.2f}".format(en - st) + " sec")

    # findModelAccuracy(train_data, "Training")
    findModelAccuracy(test_data, fcnt, "Testing")
    fcnt += 1


def adde():
    id = "id"
    name = input('Employee Name : ')
    lname = input('Employee Last Name')
    email = input('Employee Email')
    phone = input('Employee Phone Number :')
    address = input('Employee Address :')
    salary = input('Employee salary')
    c_det = (id, name, lname, email, phone, address, salary)
    qry = "INSERT INTO user  Values (%s,%s,%s,%s,%s,%s,%s)"

    # value of the fields to be entered with the query
    val = c_det
    db_cursor.execute(qry, val)
    db.commit()
    print('Customer details entered')
#adds a member to the sql server
def ved():
    qry = """select * from user where id = %s"""
    n = input("Write id")
    cursor.execute(qry, (n,))
    record = cursor.fetchall()
    print(record)
#shows details of a member from the sql server
def ep():
    qry = """UPDATE user SET salary = %s WHERE id = %s"""
    j = int(input("Write id of Employee you want to change the salary"))
    n = input("Write the new salary")
    cursor.execute(qry, (n, j))
    record = cursor.fetchall()
    db.commit()
#allows to the user to change the salary of the employee
def re():
    qry = "DELETE FROM user WHERE id = %s"
    n = input("Write id")
    y = input("Are you sure?(Y/N)")
    if y == "Y" or y == "YES" or y == "Yes" or y == "yes" or y == "y":
        cursor.execute(qry, (n,))
        db.commit()
        print("Employee deleted successfully")
    else:
        exit()
#Removes a employee from the sql
def es():
    if k == 1:
        cursor = db.cursor()
        qry = """select * from user where id = %s"""
        h = input("Write id")
        cursor.execute(qry, (h,))
        record = cursor.fetchall()
        print(record)
    elif k == 2:
        cursor = db.cursor()
        qry = """select * from user where name = %s"""
        n = str(input("Write name"))
        cursor.execute(qry, (n,))
        record = cursor.fetchall()
        print(record)
    elif k == 3:
        cursor = db.cursor()
        qry = """select * from user where lname = %s"""
        n = str(input("Write laste name"))
        cursor.execute(qry, (n,))
        record = cursor.fetchall()
        print(record)
    elif k == 4:
        cursor = db.cursor()
        qry = """select * from user where email = %s"""
        n = str(input("Write email"))
        cursor.execute(qry, (n,))
        record = cursor.fetchall()
        print(record)
    elif k == 5:
        cursor = db.cursor()
        qry = """select * from user where phone = %s"""
        n = str(input("Enter phone number"))
        cursor.execute(qry, (n,))
        record = cursor.fetchall()
        print(record)
    else:
        exit()
#searching in the sql a member by the data that the owner has
def em():
    if k == 1:
        all()
        qry = """UPDATE user SET id = %s WHERE id = %s"""
        j = int(input("Write id of Employee you want to change the id"))
        n = input("Write the new id")
        cursor.execute(qry, (n, j))
        record = cursor.fetchall()
        db.commit()
        print("Data change Successfully")
    elif k == 2:
        all()
        qry = """UPDATE user SET name = %s WHERE id = %s"""
        j = int(input("Write id of Employee you want to change the name"))
        n = str(input("Write the new name"))
        cursor.execute(qry, (n, j))
        record = cursor.fetchall()
        db.commit()
        print("Data change Successfully")
    elif k == 3:
        all()
        qry = """UPDATE user SET lname = %s WHERE id = %s"""
        j = int(input("Write id of Employee you want to change the last name"))
        n = str(input("Write the new last name"))
        cursor.execute(qry, (n, j))
        record = cursor.fetchall()
        db.commit()
        print("Data change Successfully")
    elif k == 4:
        all()
        qry = """UPDATE user SET email = %s WHERE id = %s"""
        j = int(input("Write id of Employee you want to change the email"))
        n = str(input("Write the new email"))
        cursor.execute(qry, (n, j))
        record = cursor.fetchall()
        db.commit()
        print("Data change Successfully")
    elif k == 5:
        all()
        qry = """UPDATE user SET phone = %s WHERE id = %s"""
        j = int(input("Write id of Employee you want to change the phone"))
        n = str(input("Write the new phone"))
        cursor.execute(qry, (n, j))
        record = cursor.fetchall()
        db.commit()
        print("Data change Successfully")
    elif k==6:
        all()
        qry = """UPDATE user SET email = %s WHERE id = %s"""
        j = int(input("Write id of Employee you want to change the salary"))
        n = str(input("Write the new salary"))
        cursor.execute(qry, (n, j))
        record = cursor.fetchall()
        db.commit()
        print("Data change Successfully")
    else:
        exit()
#allows to edit employees data
def inl():
    myresult = "SELECT id,name , lname FROM user;"
    cursor.execute(myresult)
    myresult = cursor.fetchall()
    print(myresult)
#prints id,name,last name from sql
def all():
    myresult = "SELECT * FROM user;"
    cursor.execute(myresult)
    myresult = cursor.fetchall()
    print(myresult)
#prints all the data from the database

import mysql.connector as mysql
db = mysql.connect(
  host="localhost",
  user="root",
  password="",
  database="project"
)
db_cursor = db.cursor()
cursor = db.cursor()
print ("1) Add Employee.")
print ("2) View Employee Details.")
print ("3) Employee Promotion(Relates to salary increase).")
print ("4) Remove Employee.")                                     #gives the user the choice of what he wants to do
print ("5) Employee Search.")
print ("6) Edit Employee.")
print("7) Exit.")
x =int(input("Choose"))
if x == 1:
    adde()
elif x == 2:
    inl()
    ved()
elif x == 3:
    inl()
    ep()
elif x == 4:  # using the functions
    inl()
    re()
elif x == 5:
    k = int(input("1)id \n2)name\n3)lname\n4)email\n5)phone number\n"))
    es()
elif x == 6:
    k = int(input("1)id \n2)name\n3)lname\n4)email\n5)phone number\n6)address\n7)Salary"))
    em()


import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

def read_file(file_name):
    with open(file_name, "r") as f:
        return f.read()

setuptools.setup(
    name="influx-line-protocol",
    description="Implementation of influxdata line protocol format in python",
    long_description=long_description,
    long_description_content_type="text/markdown",
    version="0.1.5",
    url="https://github.com/SebastianCzoch/influx-line-protocol",
    author="Sebastian Czoch",
    author_email="sebastian@czoch.pl",
    license="MIT",
    classifiers=[
        "Development Status :: 4 - Beta",
        "Intended Audience :: System Administrators",
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 2",
        "Operating System :: OS Independent",
    ],
    packages=setuptools.find_packages(),
)


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

import enum
import logging
from logging import StreamHandler

handler = StreamHandler()
logger = logging.getLogger(__name__)

class Level(enum.Enum):
    FATAL = logging.FATAL
    ERROR = logging.ERROR
    WARN = logging.WARN
    INFO = logging.INFO
    DEBUG = logging.DEBUG

class ColoredFormatter(logging.Formatter):
    RESET_SEQ = "\033[0m"
    COLOR_SEQ = "\033[1;%dm"
    COLOR_START = "COLOR_START"
    COLOR_END = "COLOR_END"
    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
    COLORS = {
        'ERROR':   RED,
        'WARNING': YELLOW,
        'INFO':    WHITE,
        'DEBUG':   CYAN,
    }

    def __init__(self, fmt):
        """
        :param str fmt: Format string.
        """
        logging.Formatter.__init__(self, fmt)
        self.fmt = fmt.replace(ColoredFormatter.COLOR_END, ColoredFormatter.RESET_SEQ)

    def format(self, record):
        """
        Output colored log
        :param logging.LogRecord record:
        :return: Format result.
        :rtype str
        """
        levelname = record.levelname
        if levelname in ColoredFormatter.COLORS:
            cs = ColoredFormatter.COLOR_SEQ % (30 + ColoredFormatter.COLORS[levelname])
            fmt = self.fmt.replace(ColoredFormatter.COLOR_START, cs)
            # update color of format
            self._style._fmt = fmt

        return logging.Formatter.format(self, record)

def init():
    """
    Initialize log module.
    """
    handler.setLevel(logging.INFO)
    logger.setLevel(logging.INFO)
    logger.addHandler(handler)
    logger.propagate = False
    f = ColoredFormatter("COLOR_START%(message)sCOLOR_END")
    handler.setFormatter(f)

def set_level(level: Level):
    """
    Set logging level
    :param Level level: Log level
    """
    logger.setLevel(level.value)
    handler.setLevel(level.value)
    if level == Level.DEBUG:
        f = ColoredFormatter("COLOR_START%(asctime)s %(levelname)-7sCOLOR_END %(message)s")
        f.default_time_format = '%H:%M:%S'
        f.default_msec_format = '%s.%03d'
        handler.setFormatter(f)

def d(msg):
    """
    Debug log
    :param str | bytes msg: Message string.
    """
    if isinstance(msg, str):
        logger.debug(msg)
    elif isinstance(msg, bytes):
        logger.debug(msg.decode("utf-8"))

def i(msg):
    """
    Info log
    :param str msg: Message string.
    """
    logger.info(msg)

def w(msg):
    """
    Warning log
    :param str msg: Message string.
    """
    logger.warning(msg)

def e(msg):
    """
    Error log
    :param str msg: Message string.
    """
    logger.error(msg)


import numpy as np
from plotfit import plotLineReg, plotPoints

def approxD2(f, x_0, h):
    return (f(x_0+h) - 2*f(x_0) + f(x_0-h))/(h*h)

def approxD2iter(f, x_0, h, tol, maxiters):
    iters = 0
    err = 10*tol
    a = x_0
    appxList = []
    while(err>tol and iters<maxiters):
        b = approxD2(f, x_0, h)
        err = np.abs(a-b)
        iters += 1
        h *= 0.5
        a = b
        appxList.append([h,a])
    return appxList

def testf(x):
    return ((x-np.pi/2)*(np.tan(x)**2))/(x**2+65)

if __name__=='__main__':
    # test func
    approxList = approxD2iter(testf, np.pi/4, .125, .0001, 200)
    print("h, approx")
    xlist = []
    ylist = []
    for i in range(len(approxList)):
        print(approxList[i])
        xlist.append(approxList[i][0])
        ylist.append(approxList[i][0])

    plotPoints(xlist, ylist)


from __future__ import division, print_function, absolute_import

import os

import pytest

import hypothesis
from hypothesis.errors import InvalidArgument
from hypothesis.database import ExampleDatabase
from hypothesis._settings import settings, Verbosity

def test_has_docstrings():
    assert settings.verbosity.__doc__

original_default = settings.get_profile('default').max_examples

def setup_function(fn):
    settings.load_profile('default')
    settings.register_profile('test_settings', settings())
    settings.load_profile('test_settings')

def test_cannot_set_non_settings():
    s = settings()
    with pytest.raises(AttributeError):
        s.databas_file = u'some_file'

def test_settings_uses_defaults():
    s = settings()
    assert s.max_examples == settings.default.max_examples

def test_raises_attribute_error():
    with pytest.raises(AttributeError):
        settings().kittens

def test_respects_none_database():
    assert settings(database=None).database is None

def test_settings_can_be_used_as_context_manager_to_change_defaults():
    with settings(max_examples=12):
        assert settings.default.max_examples == 12
    assert settings.default.max_examples == original_default

def test_can_repeatedly_push_the_same_thing():
    s = settings(max_examples=12)
    t = settings(max_examples=17)
    assert settings().max_examples == original_default
    with s:
        assert settings().max_examples == 12
        with t:
            assert settings().max_examples == 17
            with s:
                assert settings().max_examples == 12
                with t:
                    assert settings().max_examples == 17
                assert settings().max_examples == 12
            assert settings().max_examples == 17
        assert settings().max_examples == 12
    assert settings().max_examples == original_default

def test_cannot_create_settings_with_invalid_options():
    with pytest.raises(InvalidArgument):
        settings(a_setting_with_limited_options=u'spoon')

def test_can_set_verbosity():
    settings(verbosity=Verbosity.quiet)
    settings(verbosity=Verbosity.normal)
    settings(verbosity=Verbosity.verbose)

def test_can_not_set_verbosity_to_non_verbosity():
    with pytest.raises(InvalidArgument):
        settings(verbosity='kittens')

@pytest.mark.parametrize('db', [None, ExampleDatabase()])
def test_inherits_an_empty_database(db):
    assert settings.default.database is not None
    s = settings(database=db)
    assert s.database is db
    with s:
        t = settings()
    assert t.database is db

@pytest.mark.parametrize('db', [None, ExampleDatabase()])
def test_can_assign_database(db):
    x = settings(database=db)
    assert x.database is db

def test_load_profile():
    settings.load_profile('default')
    assert settings.default.max_examples == 200
    assert settings.default.max_shrinks == 500
    assert settings.default.min_satisfying_examples == 5

    settings.register_profile(
        'test',
        settings(
            max_examples=10,
            max_shrinks=5
        )
    )

    settings.load_profile('test')

    assert settings.default.max_examples == 10
    assert settings.default.max_shrinks == 5
    assert settings.default.min_satisfying_examples == 5

    settings.load_profile('default')

    assert settings.default.max_examples == 200
    assert settings.default.max_shrinks == 500
    assert settings.default.min_satisfying_examples == 5

def test_loading_profile_keeps_expected_behaviour():
    settings.register_profile('ci', settings(max_examples=10000))
    settings.load_profile('ci')
    assert settings().max_examples == 10000
    with settings(max_examples=5):
        assert settings().max_examples == 5
    assert settings().max_examples == 10000

def test_load_non_existent_profile():
    with pytest.raises(hypothesis.errors.InvalidArgument):
        settings.get_profile('nonsense')

@pytest.mark.skipif(
    os.getenv('HYPOTHESIS_PROFILE') not in (None, 'default'),
    reason='Defaults have been overridden')
def test_runs_tests_with_defaults_from_conftest():
    assert settings.default.strict
    assert settings.default.timeout == -1


"""
Сравнивает два списка.
Возвращает в виде списка результаты сравнения элементов:
1 - если l1[n] и l1[n] - буквы одного регистра;
0 - если l1[n] и l1[n] - буквы разных регистра;
-1 - если l1[n] или l1[n] - не бунвы
"""

def same(l1, l2):
    li = []
    for i in range(0, len(l1)):
        if l1[i].isalpha() and l2[i].isalpha():
            if  l1[i].isupper() and l2[i].isupper() or l1[i].islower() and l2[i].islower():
                li.append(1)
            else:
                li.append(0)
        else:
            li.append(-1)
    return li

l1 = 'QedhgrtRt'
l2 = 'JKLl;l9kj'

print(same(l1, l2))


from django.urls import reverse

def reverse_querystring(view, urlconf=None, args=None, kwargs=None, current_app=None, query_kwargs=None):
    """Custom reverse to handle query strings.
    Usage:
        reverse_querystring('app.views.my_view', kwargs={'pk': 123}, query_kwargs={'search': 'Bob'})

        for multivalue query string
        reverse_querystring('app.views.my_view', kwargs={'pk': 123}, query_kwargs={'search': ['Bob', 'Jack']})
    """
    base_url = reverse(view, urlconf=urlconf, args=args, kwargs=kwargs, current_app=current_app)

    if query_kwargs:
        lst = []
        for k, v in query_kwargs.items():
            if isinstance(v, (list, tuple)):
                for ret in v:
                    lst.append("%s=%s" % (k, ret))
            else:
                lst.append("%s=%s" % (k, v))

        query_string = "&".join(lst)
        return "%s?%s" % (base_url, query_string)
    return base_url


N = int(input())
arr = [list(map(int, input().split())) for _ in range(N)]
Max = 0

def dfs(day,total):
    global Max

    if day == N:
        Max = max(Max, total)
        return

    if day+arr[day][0]<=N:
        dfs(day+arr[day][0],total+arr[day][1])
    dfs(day+1,total)

for i in range(N):
    dfs(i,0)
print(Max)


"""Function which calculates how positive a website's content is. Scores usually range between -10 and +10"""
import requests
from bs4 import BeautifulSoup as bs
from afinn import Afinn
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer

def sentiment_analyze(url):
    """calculates a website's positivity"""

    # add https if not in there at start
    if url[0:8] != "https://":
        url = "https://" + url

    try:
        my_session = requests.session()
        for_cookies = requests.get(url).cookies
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"
        }

        response = my_session.get(url, headers=headers, cookies=for_cookies)

        req_text = response.text

        # checking request html output
        # with open("testing.html", "w") as file:
        #    file.write(req_text)

        # remove unicode characters
        decoded_text = req_text.encode("ascii", "ignore").decode("unicode_escape")

        # get the individual text pieces inside the web page as separate list elements
        soup_li = bs(decoded_text, "lxml").body.getText(separator="||").split("||")

        # list which will hold the pieces of text together with their scores
        text_li = []

        # Initialise the 2 sentiment analysis libraries used
        afinn = Afinn()
        analyzer = SentimentIntensityAnalyzer()

        # sum of non-0 scores
        sum_text = 0

        # count of non-0 scores
        count_text = 0

        # max/min text scores holders
        max_score = 0
        max_text = ""
        min_score = 0
        min_text = ""

        for text in soup_li:

            # only look at pieces of text with 5+ sentences
            if len(text.split()) >= 5:

                afinn_score = afinn.score(text)  # usually from -5 to +5
                vader_score = analyzer.polarity_scores(text)[
                    "compound"
                ]  # from -1 to +1

                combined_score = 0

                if afinn_score != 0 or vader_score != 0:
                    count_text += 1

                    if afinn_score == 0:
                        combined_score = vader_score
                    elif vader_score == 0:
                        combined_score = afinn_score
                    else:
                        combined_score = (afinn_score * 2 + vader_score * 10) / 2

                    sum_text += 10 if combined_score > 0 else -10

                    if combined_score > max_score:
                        max_score = combined_score
                        max_text = text

                    elif combined_score < min_score:
                        min_score = combined_score
                        min_text = text

                text_li.append(
                    {
                        "text": text,
                        "combined_score": combined_score,
                        "vader_score": vader_score,
                        "afinn_score": afinn_score,
                    }
                )

        if count_text == 0:
            return {
                "success": False,
                "message": "Unable to calculate any scores.",
                "raw_data": text_li,
            }

        else:

            return {
                "success": True,
                "avg_score": round(sum_text / count_text * 2),
                "max_score": max_score,
                "max_text": max_text,
                "min_score": min_score,
                "min_text": min_text,
                "raw_data": text_li,
            }

    # catch errors in requests.get statement
    except requests.exceptions.ConnectionError as error:
        return {
            "success": False,
            "message": f"An error occurred when trying to access the '{url}' URL. Error message: '{error}'",
        }
    except Exception as error:
        return {
            "success": False,
            "message": f"Something went wrong when processing the '{url}' URL.Error message: '{error}'",
        }


print("BMI calculator:-")
h = input("What is your height in m : ")
w = input("What is  your weight in kg : ")
h1 = float(h)
w1 = float(w)
bmi1 = w1/ h1**2
bmi2 = float(bmi1)
bmi= round(bmi2, 2)
if bmi <= 18 :
    print("you are under waeight",bmi)
elif bmi <= 24:
    print("you are normal weight",bmi)
elif bmi <= 30:
    print("You are over weight",bmi)
elif bmi <= 35:
    print("You are obssess weight",bmi)
else:
    print("You dont enter the correct data")


import argparse
import datetime
import os
import socket
import sys

from time import sleep

# espa-processing imports
import config
import parameters
import processor
import settings
import sensor
import utilities

from api_interface import APIServer
from logging_tools import (EspaLogging, get_base_logger, get_stdout_handler,
                           get_stderr_handler, archive_log_files)

base_logger = get_base_logger()

def work(cfg, params, developer_sleep_mode=False):
    """
    Take the environment configuration, order parameters and initiate order processing.
    Note: Much of this code was taken from the ondemand_mapper.py script in espa-processing.

    Args:
        cfg (dict): Configuration params given by config.config() and by the worker environment
        params (dict): JSON response from the API for a single granule or scene

    Returns:
        None, Products are generated, packaged, and distributed if processing was successful

    """
    # This will be the Mesos node hostname
    processing_location = socket.gethostname()

    # Use the base_logger initially, if an exception occurs before the processing logger is configured
    # the base_logger will handle log it
    logger = base_logger

    if not parameters.test_for_parameter(params, 'options'):
        raise ValueError('Error missing JSON [options] record')

    start_time = datetime.datetime.now()

    # Initialize so that we don't sleep
    dont_sleep = True

    # Note that the API response "scene" value is what we use for product_id
    try:
        (order_id, product_id, product_type, options) = \
            (params['orderid'], params['scene'], params['product_type'],
             params['options'])

        if product_id != 'plot':
            # Developer mode is always false unless you are a developer
            # so sleeping will always occur for non-plotting requests
            # Override with the developer mode
            dont_sleep = developer_sleep_mode

        # Fix the orderid in-case it contains any single quotes
        # The processors can not handle single quotes in the email
        # portion due to usage in command lines.
        params['orderid'] = order_id.replace("'", '')

        # product_id is not part of the API response - we add it here
        if not parameters.test_for_parameter(params, 'product_id'):
            params['product_id'] = product_id

        # Figure out if debug level logging was requested
        debug = False
        if parameters.test_for_parameter(options, 'debug'):
            debug = options['debug']

        # Configure and get the logger for this order request
        EspaLogging.configure(settings.PROCESSING_LOGGER, order=order_id,
                              product=product_id, debug=debug)

        # Replace the base_logger with the processing_logger
        logger = EspaLogging.get_logger(settings.PROCESSING_LOGGER)

        # add our stdout/stderr log streams
        logger.addHandler(get_stdout_handler())
        logger.addHandler(get_stderr_handler())

        logger.info('Processing {}:{}'.format(order_id, product_id))
        logger.info('Attempting connection to {0}'.format(cfg['espa_api']))

        # will throw an exception on init if unable to get a 200 response
        server = APIServer(cfg['espa_api'])

        # will throw an exception if does not receive a 200 response
        status = server.update_status(product_id, order_id, processing_location, 'processing')

        if product_id != 'plot':
            # Make sure we can process the sensor
            tmp_info = sensor.info(product_id)
            del tmp_info

            # Make sure we have a valid output format
            if not parameters.test_for_parameter(options, 'output_format'):
                logger.warning('[output_format] parameter missing defaulting to envi')

                options['output_format'] = 'envi'

            if (options['output_format'] not in parameters.VALID_OUTPUT_FORMATS):
                raise ValueError('Invalid Output format {}'.format(options['output_format']))

                # ----------------------------------------------------------------
                # NOTE: The first thing the product processor does during
                #       initialization is validate the input parameters.
                # ----------------------------------------------------------------

        destination_product_file = 'ERROR'
        destination_cksum_file = 'ERROR'

        pp = None

        try:
            # All processors are implemented in the processor module
            pp = processor.get_instance(cfg, params)

            (destination_product_file, destination_cksum_file) = pp.process()

        finally:
            # Free disk space to be nice to the whole system.
            if pp is not None:
                pp.remove_product_directory()

        # Sleep the number of seconds for minimum request duration
        sleep(utilities.get_sleep_duration(cfg, start_time, dont_sleep))

        log_items = archive_log_files(order_id, product_id)
        for item in log_items:
            utilities.change_ownership(item, cfg.get('espa_user'), cfg.get('espa_group'))

        # Everything was successful so mark the scene complete
        server.mark_scene_complete(product_id, order_id,
                                   processing_location,
                                   destination_product_file,
                                   destination_cksum_file,
                                   '') # sets log_file_contents to empty string ''
        return True

    except Exception as e:
        # First log the exception
        logger.exception('Exception encountered in processing.main.work:\nexception: {}'.format(e))

        try:
            # Sleep the number of seconds for minimum request duration
            logger.debug('Attempting to archive log files for order_id: {}\nproduct_id: {}'.format(order_id, product_id))
            sleep(utilities.get_sleep_duration(cfg, start_time, dont_sleep))
            log_items = archive_log_files(order_id, product_id)
            for item in log_items:
                utilities.change_ownership(item, cfg.get('espa_user'), cfg.get('espa_group'))

        except Exception as e2:
            logger.exception('Problem archiving log files. error: {}'.format(e2))

        try:
            logger.debug('Attempting to set product error, order_id: {}\nproduct_id: {}'.format(order_id, product_id))
            logged_contents = EspaLogging.read_logger_file(settings.PROCESSING_LOGGER)
            error_log = "Processing Log: {}\n\nException: {}".format(logged_contents, e)
            server.set_scene_error(product_id, order_id, processing_location, error_log)
        except Exception as e3:
            logger.exception('Unable to reach ESPA API and set product error for order_id: {}\nproduct_id: {}\nerror: {}'.format(order_id, product_id, e3))
            raise e3

        return False

def main(data=None):
    try:
        # retrieve a dict containing processing environment configuration values
        cfg = config.config()
        sleep_for = cfg.get('init_sleep_seconds')
        base_logger.info('Holding for {} seconds'.format(sleep_for))
        sleep(sleep_for)

        # export values for the container environment
        config.export_environment_variables(cfg)

        # create the .netrc file
        utilities.build_netrc()

        base_logger.debug('OS ENV - {0}'.format(['{0}: {1}'.format(var, val) for var, val in os.environ.items()]))
        base_logger.info('configured parameters - {0}'.format(['{0}: {1}'.format(var, val) for var, val in cfg.items()]))

        if not data:
            parser = argparse.ArgumentParser()
            parser.add_argument(dest="data", action="store", metavar="JSON",
                                type=utilities.convert_json,
                                help="response from the API"
                                      "containing order information")
            args = parser.parse_args()
            data = args.data

        base_logger.info('order data - {0}'.format(data))

        for d in data:
            result = work(cfg, d)
            base_logger.info('processing.work executed for data {} successfully? {}'.format(d, result))

        # Exit normally
        sys.exit(0)

    except Exception as e:
        msg = 'ESPA Worker error, problem executing main.main\nError: {}'.format(e)
        base_logger.exception(msg)
        # Exit with 1 so Container and Task know there was a problem and report to the framework appropriately
        sys.exit(msg)

if __name__ == '__main__':
    main()