"""
======================
Polypeptide Elongation
======================

This process models the polymerization of amino acids into polypeptides
by ribosomes using an mRNA transcript as a template. Elongation terminates
once a ribosome has reached the end of an mRNA transcript. Polymerization
occurs across all ribosomes simultaneously and resources are allocated to
maximize the progress of all ribosomes within the limits of the maximum ribosome
elongation rate, available amino acids and GTP, and the length of the transcript.
"""

import numpy as np

# wcEcoli imports
from wholecell.utils.polymerize import (buildSequences, polymerize,
    computeMassIncrease)
from wholecell.utils.random import stochasticRound
from wholecell.utils import units

# vivarium imports
from vivarium.core.composition import simulate_process
from vivarium.library.dict_utils import deep_merge
from vivarium.plots.simulation_output import plot_variables

# vivarium-ecoli imports
from ecoli.library.schema import (listener_schema, numpy_schema, counts, attrs,
    bulk_name_to_idx)
from ecoli.models.polypeptide_elongation_models import (BaseElongationModel,
    TranslationSupplyElongationModel, SteadyStateElongationModel,
    MICROMOLAR_UNITS)
from ecoli.processes.registries import topology_registry
from ecoli.processes.partition import PartitionedProcess

# Register default topology for this process, associating it with process name
NAME = 'ecoli-polypeptide-elongation'
TOPOLOGY = {
    "environment": ("environment",),
    "boundary": ("boundary",),
    "listeners": ("listeners",),
    "active_ribosome": ("unique", "active_ribosome"),
    "bulk": ("bulk",),
    "polypeptide_elongation": ("process_state", "polypeptide_elongation"),
    # Non-partitioned counts
    "bulk_total": ("bulk",),
    "timestep": ("timestep",)
}
topology_registry.register(NAME, TOPOLOGY)

DEFAULT_AA_NAMES = [
    'L-ALPHA-ALANINE[c]', 'ARG[c]', 'ASN[c]', 'L-ASPARTATE[c]', 'CYS[c]',
    'GLT[c]', 'GLN[c]', 'GLY[c]', 'HIS[c]', 'ILE[c]', 'LEU[c]', 'LYS[c]',
    'MET[c]', 'PHE[c]', 'PRO[c]', 'SER[c]', 'THR[c]', 'TRP[c]', 'TYR[c]',
    'L-SELENOCYSTEINE[c]', 'VAL[c]']

class PolypeptideElongation(PartitionedProcess):
    """ Polypeptide Elongation PartitionedProcess

    defaults:
        proteinIds: array length n of protein names
    """

    name = NAME
    topology = TOPOLOGY
    defaults = {
        'time_step': 1,
        'max_time_step': 2.0,
        'n_avogadro': 6.02214076e+23 / units.mol,
        'proteinIds': np.array([]),
        'proteinLengths': np.array([]),
        'proteinSequences': np.array([[]]),
        'aaWeightsIncorporated': np.array([]),
        'endWeight': np.array([2.99146113e-08]),
        'variable_elongation': False,
        'make_elongation_rates': (lambda random, rate, timestep, variable:
            np.array([])),
        'next_aa_pad': 1,
        'ribosomeElongationRate': 17.388824902723737,
        'translation_aa_supply': {'minimal': np.array([])},
        'import_threshold': 1e-05,
        'aa_from_trna': np.zeros(21),
        'gtpPerElongation': 4.2,
        'aa_supply_in_charging': False,
        'adjust_timestep_for_charging': False,
        'mechanistic_translation_supply': False,
        'mechanistic_aa_transport': False,
        'ppgpp_regulation': False,
        'disable_ppgpp_elongation_inhibition': False,
        'variable_elongation': False,
        'trna_charging': False,
        'translation_supply': False,
        'mechanistic_supply': False,
        'ribosome30S': 'ribosome30S',
        'ribosome50S': 'ribosome50S',
        'amino_acids': DEFAULT_AA_NAMES,
        'aa_exchange_names': DEFAULT_AA_NAMES,
        'basal_elongation_rate': 22.0,
        'ribosomeElongationRateDict': {
            'minimal': 17.388824902723737 * units.aa / units.s},
        'uncharged_trna_names': np.array([]),
        'aaNames': DEFAULT_AA_NAMES,
        'aa_enzymes': [],
        'proton': 'PROTON',
        'water': 'H2O',
        'cellDensity': 1100 * units.g / units.L,
        'elongation_max': 22 * units.aa / units.s,
        'aa_from_synthetase': np.array([[]]),
        'charging_stoich_matrix': np.array([[]]),
        'charged_trna_names': [],
        'charging_molecule_names': [],
        'synthetase_names': [],
        'ppgpp_reaction_names': [],
        'ppgpp_reaction_metabolites': [],
        'ppgpp_reaction_stoich': np.array([[]]),
        'ppgpp_synthesis_reaction': 'GDPPYPHOSKIN-RXN',
        'ppgpp_degradation_reaction': 'PPGPPSYN-RXN',
        'aa_importers': [],
        'amino_acid_export': None,
        'synthesis_index': 0,
        'aa_exporters': [],
        'get_pathway_enzyme_counts_per_aa': None,
        'import_constraint_threshold': 0,
        'unit_conversion': 0,
        'elong_rate_by_ppgpp': 0,
        'amino_acid_import': None,
        'degradation_index': 1,
        'amino_acid_synthesis': None,
        'rela': 'RELA',
        'spot': 'SPOT',
        'ppgpp': 'ppGpp',
        'kS': 100.0,
        'KMtf': 1.0,
        'KMaa': 100.0,
        'krta': 1.0,
        'krtf': 500.0,
        'KD_RelA': 0.26,
        'k_RelA': 75.0,
        'k_SpoT_syn': 2.6,
        'k_SpoT_deg': 0.23,
        'KI_SpoT': 20.0,
        'aa_supply_scaling': lambda aa_conc, aa_in_media: 0,
        'seed': 0,
        'emit_unique': False,
    }

    def __init__(self, parameters=None):
        super().__init__(parameters)

        self.max_time_step = self.parameters['max_time_step']

        # Simulation options
        self.aa_supply_in_charging = self.parameters['aa_supply_in_charging']
        self.adjust_timestep_for_charging = self.parameters[
            'adjust_timestep_for_charging']
        self.mechanistic_translation_supply = self.parameters[
            'mechanistic_translation_supply']
        self.mechanistic_aa_transport = self.parameters[
            'mechanistic_aa_transport']
        self.ppgpp_regulation = self.parameters['ppgpp_regulation']
        self.disable_ppgpp_elongation_inhibition = self.parameters[
            'disable_ppgpp_elongation_inhibition']
        self.variable_elongation = self.parameters['variable_elongation']
        self.variable_polymerize = self.ppgpp_regulation or self.variable_elongation
        translation_supply = self.parameters['translation_supply']
        trna_charging = self.parameters['trna_charging']

        # Load parameters
        self.n_avogadro = self.parameters['n_avogadro']
        self.proteinIds = self.parameters['proteinIds']
        self.protein_lengths = self.parameters['proteinLengths']
        self.proteinSequences = self.parameters['proteinSequences']
        self.aaWeightsIncorporated = self.parameters['aaWeightsIncorporated']
        self.endWeight = self.parameters['endWeight']
        self.make_elongation_rates = self.parameters['make_elongation_rates']
        self.next_aa_pad = self.parameters['next_aa_pad']

        self.ribosome30S = self.parameters['ribosome30S']
        self.ribosome50S = self.parameters['ribosome50S']
        self.amino_acids = self.parameters['amino_acids']
        self.aa_exchange_names = self.parameters['aa_exchange_names']
        self.aa_environment_names = [aa[:-3] for aa in self.aa_exchange_names]
        self.aa_enzymes = self.parameters['aa_enzymes']

        self.ribosomeElongationRate = self.parameters['ribosomeElongationRate']

        # Amino acid supply calculations
        self.translation_aa_supply = self.parameters['translation_aa_supply']
        self.import_threshold = self.parameters['import_threshold']

        # Used for figure in publication
        self.trpAIndex = np.where(self.proteinIds ==
            "TRYPSYN-APROTEIN[c]")[0][0]

        self.elngRateFactor = 1.

        # Data structures for charging
        self.aa_from_trna = self.parameters['aa_from_trna']

        # Set modeling method
        # TODO: Test that these models all work properly
        if trna_charging:
            self.elongation_model = SteadyStateElongationModel(
                self.parameters, self)
        elif translation_supply:
            self.elongation_model = TranslationSupplyElongationModel(
                self.parameters, self)
        else:
            self.elongation_model = BaseElongationModel(self.parameters, self)

        # Growth associated maintenance energy requirements for elongations
        self.gtpPerElongation = self.parameters['gtpPerElongation']
        # Need to account for ATP hydrolysis for charging that has been
        # removed from measured GAM (ATP -> AMP is 2 hydrolysis reactions)
        # if charging reactions are not explicitly modeled
        if not trna_charging:
            self.gtpPerElongation += 2

        # basic molecule names
        self.proton = self.parameters['proton']
        self.water = self.parameters['water']
        self.rela = self.parameters['rela']
        self.spot = self.parameters['spot']
        self.ppgpp = self.parameters['ppgpp']
        self.aa_importers = self.parameters['aa_importers']
        self.aa_exporters = self.parameters['aa_exporters']
        # Numpy index for bulk molecule
        self.proton_idx = None

        # Names of molecules associated with tRNA charging
        self.ppgpp_reaction_metabolites = self.parameters[
            'ppgpp_reaction_metabolites']
        self.uncharged_trna_names = self.parameters['uncharged_trna_names']
        self.charged_trna_names = self.parameters['charged_trna_names']
        self.charging_molecule_names = self.parameters[
            'charging_molecule_names']
        self.synthetase_names = self.parameters['synthetase_names']

        self.seed = self.parameters['seed']
        self.random_state = np.random.RandomState(seed = self.seed)

        self.zero_aa_exchange_rates = MICROMOLAR_UNITS / units.s * np.zeros(
            len(self.amino_acids))

    def ports_schema(self):
        return {
            'environment': {
                'media_id': {
                    '_default': '',
                    '_updater': 'set'},
                'exchange': {'*': {'_default': 0}}
            },
            'boundary': {
                'external': {
                    aa: {'_default': 0}
                    for aa in sorted(self.aa_environment_names)
                }
            },
            'listeners': {
                'mass': listener_schema({
                    'cell_mass': 0.0,
                    'dry_mass': 0.0}),

                'growth_limits': listener_schema({
                    'fraction_trna_charged': ([0] * len(self.uncharged_trna_names),
                        self.uncharged_trna_names),
                    'aa_allocated': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_pool_size': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_request_size': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'active_ribosome_allocated': 0,
                    'net_charged': ([0] * len(self.uncharged_trna_names),
                        self.uncharged_trna_names),
                    'aas_used': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_count_diff': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    # Below only if trna_charging enbaled
                    'original_aa_supply': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_in_media': ([False] * len(self.amino_acids),
                        self.amino_acids),
                    'synthetase_conc': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'uncharged_trna_conc': (
                        [0] * len(self.amino_acids), self.amino_acids),
                    'charged_trna_conc': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_conc': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'ribosome_conc': 0,
                    'fraction_aa_to_elongate': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_supply': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_synthesis': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_import': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_export': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_importers': ([0] * len(self.aa_importers),
                        self.aa_importers),
                    'aa_exporters': ([0] * len(self.aa_exporters),
                        self.aa_exporters),
                    'aa_supply_enzymes_fwd': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_supply_enzymes_rev': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_supply_aa_conc': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_supply_fraction_fwd': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_supply_fraction_rev': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'ppgpp_conc': 0,
                    'rela_conc': 0,
                    'spot_conc': 0,
                    'rela_syn': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'spot_syn': 0,
                    'spot_deg': 0,
                    'spot_deg_inhibited': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'trna_charged': ([0] * len(self.amino_acids),
                        self.amino_acids)}),

                'ribosome_data': listener_schema({
                    'translation_supply': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'effective_elongation_rate': 0,
                    'aa_count_in_sequence': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'aa_counts': ([0] * len(self.amino_acids),
                        self.amino_acids),
                    'actual_elongations': 0,
                    'actual_elongation_hist': [0] * 22,
                    'elongations_non_terminating_hist': [0] * 22,
                    'did_terminate': 0,
                    'termination_loss': 0,
                    'num_trpA_terminated': 0,
                    'process_elongation_rate': 0})},

            'bulk': numpy_schema('bulk'),
            'bulk_total': numpy_schema('bulk'),

            'active_ribosome': numpy_schema('active_ribosome',
                emit=self.parameters['emit_unique']),

            'polypeptide_elongation': {
                'aa_count_diff': {
                    '_default': {},
                    '_emit': True,
                    '_updater': 'set',
                    '_divider': 'empty_dict'},
                'gtp_to_hydrolyze': {
                    '_default': 0,
                    '_emit': True,
                    '_updater': 'set',
                    '_divider': 'zero',
                },
                'aa_exchange_rates': {
                    '_default': 0,
                    '_emit': True,
                    '_updater': 'set',
                    '_divider': 'zero'
                },
            },
            'timestep': {'_default': self.parameters['time_step']}
        }

    def calculate_request(self, timestep, states):
        """
        Set ribosome elongation rate based on simulation medium environment and elongation rate factor
        which is used to create single-cell variability in growth rate
        The maximum number of amino acids that can be elongated in a single timestep is set to 22
        intentionally as the minimum number of padding values on the protein sequence matrix is set to 22.
        If timesteps longer than 1.0s are used, this feature will lead to errors in the effective ribosome
        elongation rate.
        """

        if self.proton_idx is None:
            bulk_ids = states['bulk']['id']
            self.proton_idx = bulk_name_to_idx(self.proton, bulk_ids)
            self.water_idx = bulk_name_to_idx(self.water, bulk_ids)
            self.rela_idx = bulk_name_to_idx(self.rela, bulk_ids)
            self.spot_idx = bulk_name_to_idx(self.spot, bulk_ids)
            self.ppgpp_idx = bulk_name_to_idx(self.ppgpp, bulk_ids)
            self.monomer_idx = bulk_name_to_idx(self.proteinIds, bulk_ids)
            self.amino_acid_idx = bulk_name_to_idx(self.amino_acids, bulk_ids)
            self.aa_enzyme_idx = bulk_name_to_idx(self.aa_enzymes, bulk_ids)
            self.ppgpp_rxn_metabolites_idx = bulk_name_to_idx(
                self.ppgpp_reaction_metabolites, bulk_ids)
            self.uncharged_trna_idx = bulk_name_to_idx(
                self.uncharged_trna_names, bulk_ids)
            self.charged_trna_idx = bulk_name_to_idx(
                self.charged_trna_names, bulk_ids)
            self.charging_molecule_idx = bulk_name_to_idx(
                self.charging_molecule_names, bulk_ids)
            self.synthetase_idx = bulk_name_to_idx(
                self.synthetase_names, bulk_ids)
            self.ribosome30S_idx = bulk_name_to_idx(
                self.ribosome30S, bulk_ids)
            self.ribosome50S_idx = bulk_name_to_idx(
                self.ribosome50S, bulk_ids)
            self.aa_importer_idx = bulk_name_to_idx(
                self.aa_importers, bulk_ids)
            self.aa_exporter_idx = bulk_name_to_idx(
                self.aa_exporters, bulk_ids)

        # MODEL SPECIFIC: get ribosome elongation rate
        self.ribosomeElongationRate = self.elongation_model.elongation_rate(states)

        # If there are no active ribosomes, return immediately
        if states['active_ribosome']['_entryState'].sum() == 0:
            return {'listeners': {'ribosome_data': {}, 'growth_limits': {}}}

        # Build sequences to request appropriate amount of amino acids to
        # polymerize for next timestep
        proteinIndexes, peptideLengths, = attrs(states['active_ribosome'],
            ['protein_index', 'peptide_length'])

        self.elongation_rates = self.make_elongation_rates(
            self.random_state,
            self.ribosomeElongationRate,
            states['timestep'],
            self.variable_elongation)

        sequences = buildSequences(
            self.proteinSequences,
            proteinIndexes,
            peptideLengths,
            self.elongation_rates)

        sequenceHasAA = (sequences != polymerize.PAD_VALUE)
        aasInSequences = np.bincount(sequences[sequenceHasAA], minlength=21)

        # Calculate AA supply for expected doubling of protein
        dryMass = (states['listeners']['mass']['dry_mass'] * units.fg)
        current_media_id = states['environment']['media_id']
        translation_supply_rate = self.translation_aa_supply[current_media_id] \
            * self.elngRateFactor
        mol_aas_supplied = translation_supply_rate * dryMass * states['timestep'] * units.s
        self.aa_supply = units.strip_empty_units(mol_aas_supplied * self.n_avogadro)

        # MODEL SPECIFIC: Calculate AA request
        fraction_charged, aa_counts_for_translation, requests = \
            self.elongation_model.request(states, aasInSequences)

        # Write to listeners
        listeners = requests.setdefault('listeners', {})
        ribosome_data_listener = listeners.setdefault(
            'ribosome_data', {})
        ribosome_data_listener['translation_supply'
            ] = translation_supply_rate.asNumber()
        growth_limits_listener = requests['listeners'].setdefault(
            'growth_limits', {})
        growth_limits_listener['fraction_trna_charged'
            ] = np.dot(fraction_charged, self.aa_from_trna)
        growth_limits_listener['aa_pool_size'] = counts(states['bulk_total'],
            self.amino_acid_idx)
        growth_limits_listener['aa_request_size'] = aa_counts_for_translation

        return requests

    def evolve_state(self, timestep, states):
        """
        Set ribosome elongation rate based on simulation medium environment and elongation rate factor
        which is used to create single-cell variability in growth rate
        The maximum number of amino acids that can be elongated in a single timestep is set to 22
        intentionally as the minimum number of padding values on the protein sequence matrix is set to 22.
        If timesteps longer than 1.0s are used, this feature will lead to errors in the effective ribosome
        elongation rate.
        """

        update = {
            'listeners': {
                'ribosome_data': {},
                'growth_limits': {}},
            'polypeptide_elongation': {},
            'active_ribosome': {},
            'bulk': []
        }

        # Begin wcEcoli evolveState()
        # Set values for metabolism in case of early return
        update['polypeptide_elongation']['gtp_to_hydrolyze'] = 0
        update['polypeptide_elongation']['aa_count_diff'] = {}

        # Get number of active ribosomes
        n_active_ribosomes = states['active_ribosome']['_entryState'].sum()
        update['listeners']['growth_limits'][
            'active_ribosome_allocated'] = n_active_ribosomes
        update['listeners']['growth_limits']['aa_allocated'] = counts(
            states['bulk'], self.amino_acid_idx)

        # If there are no active ribosomes, return immediately
        if n_active_ribosomes == 0:
            return update

        # Polypeptide elongation requires counts to be updated in real-time
        # so make a writeable copy of bulk counts to do so
        states['bulk'] = counts(states['bulk'], range(len(states['bulk'])))

        # Build amino acids sequences for each ribosome to polymerize
        protein_indexes, peptide_lengths, positions_on_mRNA = attrs(
            states['active_ribosome'],
            ['protein_index', 'peptide_length', 'pos_on_mRNA'])

        all_sequences = buildSequences(
            self.proteinSequences,
            protein_indexes,
            peptide_lengths,
            self.elongation_rates + self.next_aa_pad)
        sequences = all_sequences[:, :-self.next_aa_pad].copy()

        if sequences.size == 0:
            return update

        # Calculate elongation resource capacity
        aaCountInSequence = np.bincount(sequences[
            (sequences != polymerize.PAD_VALUE)])
        total_aa_counts = counts(states['bulk'], self.amino_acid_idx)
        charged_trna_counts = counts(states['bulk'], self.charged_trna_idx)

        # MODEL SPECIFIC: Get amino acid counts
        aa_counts_for_translation = self.elongation_model.final_amino_acids(
            total_aa_counts, charged_trna_counts)

        # Using polymerization algorithm elongate each ribosome up to the limits
        # of amino acids, sequence, and GTP
        result = polymerize(
            sequences,
            aa_counts_for_translation,
            10000000,  # Set to a large number, the limit is now taken care of in metabolism
            self.random_state,
            self.elongation_rates[protein_indexes],
            variable_elongation=self.variable_polymerize)

        sequence_elongations = result.sequenceElongation
        aas_used = result.monomerUsages
        nElongations = result.nReactions

        next_amino_acid = all_sequences[np.arange(len(sequence_elongations)),
            sequence_elongations]
        next_amino_acid_count = np.bincount(next_amino_acid[
            next_amino_acid != polymerize.PAD_VALUE], minlength=21)

        # Update masses of ribosomes attached to polymerizing polypeptides
        added_protein_mass = computeMassIncrease(
            sequences,
            sequence_elongations,
            self.aaWeightsIncorporated)

        updated_lengths = peptide_lengths + sequence_elongations
        updated_positions_on_mRNA = positions_on_mRNA + 3*sequence_elongations

        didInitialize = (
            (sequence_elongations > 0) &
            (peptide_lengths == 0))

        added_protein_mass[didInitialize] += self.endWeight

        # Write current average elongation to listener
        currElongRate = (sequence_elongations.sum() /
            n_active_ribosomes) / states['timestep']

        # Ribosomes that reach the end of their sequences are terminated and
        # dissociated into 30S and 50S subunits. The polypeptide that they are
        # polymerizing is converted into a protein in BulkMolecules
        terminalLengths = self.protein_lengths[protein_indexes]

        didTerminate = (updated_lengths == terminalLengths)

        terminatedProteins = np.bincount(
            protein_indexes[didTerminate],
            minlength = self.proteinSequences.shape[0])

        protein_mass, = attrs(states['active_ribosome'], ['massDiff_protein'])
        update['active_ribosome'].update({
            'delete': np.where(didTerminate)[0],
            'set': {
                'massDiff_protein': protein_mass + added_protein_mass,
                'peptide_length': updated_lengths,
                'pos_on_mRNA': updated_positions_on_mRNA,
            }
        })

        update['bulk'].append((self.monomer_idx, terminatedProteins))
        states['bulk'][self.monomer_idx] += terminatedProteins

        nTerminated = didTerminate.sum()
        nInitialized = didInitialize.sum()

        update['bulk'].append((self.ribosome30S_idx, nTerminated))
        update['bulk'].append((self.ribosome50S_idx, nTerminated))
        states['bulk'][self.ribosome30S_idx] += nTerminated
        states['bulk'][self.ribosome50S_idx] += nTerminated

        # MODEL SPECIFIC: evolve
        net_charged, aa_count_diff, evolve_update = self.elongation_model.evolve(
            states,
            total_aa_counts,
            aas_used,
            next_amino_acid_count,
            nElongations,
            nInitialized)

        evolve_bulk_update = evolve_update.pop('bulk')
        update = deep_merge(update, evolve_update)
        update['bulk'].extend(evolve_bulk_update)

        update['polypeptide_elongation']['aa_count_diff'] = aa_count_diff
        # GTP hydrolysis is carried out in Metabolism process for growth
        # associated maintenance. This is passed to metabolism.
        update['polypeptide_elongation'][
            'gtp_to_hydrolyze'] = self.gtpPerElongation * nElongations

        # Write data to listeners
        update['listeners']['growth_limits']['net_charged'] = net_charged
        update['listeners']['growth_limits']['aas_used'] = aas_used
        update['listeners']['growth_limits']['aa_count_diff'] = [
            aa_count_diff.get(id_, 0) for id_ in self.amino_acids]

        ribosome_data_listener = update['listeners'].setdefault(
            'ribosome_data', {})
        ribosome_data_listener['effective_elongation_rate'] = currElongRate
        ribosome_data_listener['aa_count_in_sequence'] = aaCountInSequence
        ribosome_data_listener['aa_counts'] = aa_counts_for_translation
        ribosome_data_listener['actual_elongations'
            ] = sequence_elongations.sum()
        ribosome_data_listener['actual_elongation_hist'] = np.histogram(
            sequence_elongations, bins = np.arange(0,23))[0]
        ribosome_data_listener['elongations_non_terminating_hist'
            ] = np.histogram(sequence_elongations[~didTerminate],
                             bins=np.arange(0,23))[0]
        ribosome_data_listener['did_terminate'] = didTerminate.sum()
        ribosome_data_listener['termination_loss'] = (
            terminalLengths - peptide_lengths)[didTerminate].sum()
        ribosome_data_listener['num_trpA_terminated'] = terminatedProteins[
            self.trpAIndex]
        ribosome_data_listener['process_elongation_rate'] = (
            self.ribosomeElongationRate / states['timestep'])

        return update

    def isTimeStepShortEnough(self, inputTimeStep, timeStepSafetyFraction):
        model_specific = self.elongation_model.isTimeStepShortEnough(
            inputTimeStep, timeStepSafetyFraction)
        max_time_step = inputTimeStep <= self.max_time_step
        return model_specific and max_time_step

def test_polypeptide_elongation(return_data=False):
    def make_elongation_rates(random, base, time_step, variable_elongation=False):
        size = 1
        lengths = time_step * np.full(size, base, dtype=np.int64)
        lengths = stochasticRound(random, lengths) if random else np.round(lengths)
        return lengths.astype(np.int64)

    test_config = {
        'time_step': 2,
        'proteinIds': np.array(['TRYPSYN-APROTEIN[c]']),
        'ribosome30S': 'CPLX0-3953[c]',
        'ribosome50S': 'CPLX0-3962[c]',
        'make_elongation_rates': make_elongation_rates,
        'proteinLengths': np.array([245]),  # this is the length of proteins in proteinSequences
        'translation_aa_supply': {
            'minimal': (units.mol / units.fg / units.min) * np.array([
                6.73304301e-21, 3.63835219e-21, 2.89772671e-21, 3.88086822e-21,
                5.04645651e-22, 4.45295877e-21, 2.64600664e-21, 5.35711230e-21,
                1.26817689e-21, 3.81168405e-21, 5.66834531e-21, 4.30576056e-21,
                1.70428208e-21, 2.24878356e-21, 2.49335033e-21, 3.47019761e-21,
                3.83858460e-21, 6.34564026e-22, 1.86880523e-21, 1.40959498e-27,
                5.20884460e-21])},
        'proteinSequences': np.array([[
            12, 10, 18, 9, 13, 1, 10, 9, 9, 16, 20, 9, 18, 15, 9, 10, 20, 4, 20, 13, 7, 15, 9, 18, 4, 10, 13, 15, 14, 1,
            2, 14, 11, 8, 20, 0, 16, 13, 7, 8, 12, 13, 7, 1, 10, 0, 14, 10, 13, 7, 10, 11, 20, 5, 4, 1, 11, 14, 16, 3,
            0, 5, 15, 18, 7, 2, 0, 9, 18, 9, 0, 2, 8, 6, 2, 2, 18, 3, 12, 20, 16, 0, 15, 2, 9, 20, 6, 14, 14, 16, 20,
            16, 20, 7, 11, 11, 15, 10, 10, 17, 9, 14, 13, 13, 7, 6, 10, 18, 17, 10, 16, 7, 2, 10, 10, 9, 3, 1, 2, 2, 1,
            16, 11, 0, 8, 7, 16, 9, 0, 5, 20, 20, 2, 8, 13, 11, 11, 1, 1, 9, 15, 9, 17, 12, 13, 14, 5, 7, 16, 1, 15, 1,
            7, 1, 7, 10, 10, 14, 13, 11, 16, 7, 0, 13, 8, 0, 0, 9, 0, 0, 7, 20, 14, 9, 9, 14, 20, 4, 20, 15, 16, 16, 15,
            2, 11, 9, 2, 10, 2, 1, 10, 8, 2, 7, 10, 20, 9, 20, 5, 12, 10, 14, 14, 9, 3, 20, 15, 6, 18, 7, 11, 3, 6, 20,
            1, 5, 10, 0, 0, 8, 4, 1, 15, 9, 12, 5, 6, 11, 9, 0, 5, 10, 3, 11, 5, 20, 0, 5, 1, 5, 0, 0, 7, 11, 20, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]).astype(np.int8)
    }

    polypep_elong = PolypeptideElongation(test_config)

    initial_state = {
        'environment': {'media_id': 'minimal'},
        'bulk': np.array([
            ('CPLX0-3953[c]', 100),
            ('CPLX0-3962[c]', 100),
            ('TRYPSYN-APROTEIN[c]', 0),
            ('RELA', 0),
            ('SPOT', 0),
            ('H2O', 0),
            ('PROTON', 0),
            ('ppGpp', 0),
            ] + [(aa, 100) for aa in DEFAULT_AA_NAMES],
            dtype=[('id', 'U40'), ('count', int)]),
        'unique': {
            'active_ribosome': np.array([
                (1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
            ], dtype=[
                ('_entryState', np.bool_), ('unique_index', int),
                ('protein_index', int), ('peptide_length', int),
                ('pos_on_mRNA', int), ('massDiff_DNA', '<f8'),
                ('massDiff_mRNA', '<f8'), ('massDiff_metabolite', '<f8'),
                ('massDiff_miscRNA', '<f8'), ('massDiff_nonspecific_RNA',
                '<f8'), ('massDiff_protein', '<f8'), ('massDiff_rRNA',
                '<f8'), ('massDiff_tRNA', '<f8'), ('massDiff_water', '<f8')])
        },
        'listeners': {
            'mass': {
                'dry_mass': 350.0
            }
        }
    }

    settings = {
        'total_time': 200,
        'initial_state': initial_state,
        'topology': TOPOLOGY}
    data = simulate_process(polypep_elong, settings)

    if return_data:
        return data, test_config

def run_plot(data, config):

    # plot a list of variables
    bulk_ids = ['CPLX0-3953[c]', 'CPLX0-3962[c]', 'TRYPSYN-APROTEIN[c]',
        'RELA', 'SPOT', 'H2O', 'PROTON', 'ppGpp'] + [
            aa for aa in DEFAULT_AA_NAMES]
    variables = [(bulk_id,) for bulk_id in bulk_ids]

    # format data
    bulk_timeseries = np.array(data['bulk'])
    for i, bulk_id in enumerate(bulk_ids):
        data[bulk_id] = bulk_timeseries[:, i]

    plot_variables(
        data,
        variables=variables,
        out_dir='out/processes/polypeptide_elongation',
        filename='variables'
    )

def main():
    data, config = test_polypeptide_elongation(return_data=True)
    run_plot(data, config)

if __name__ == '__main__':
    main()


import pandas
import requests

# Loads URLs into a Pandas Dataframe

dataframe= pandas.read_csv('urls.csv')
counter = 0
for url in dataframe['urls']:

    try:

        response = requests.get(url, allow_redirects=False)

        status = response.status_code

    except:

        status = "0"

    dataframe.at[counter, 'Status'] = status

    counter = counter + 1

dataframe['Status'] = dataframe['Status'].astype(int)

# Prints out terminal

print(dataframe)

#Saves in CSV

dataframe.to_csv('Statuscodes.csv')


import logging
import os
import socket
import sys

def get_host_ip():
    try:
        ip = os.popen(
            "ifconfig | grep \"inet addr:10\" | awk '{print $2}' | awk -F \":\" '{print $2}'"
        ).read()
        ip = ip.strip("\n").strip(" ")
        if not ip:
            raise Exception()
    except Exception:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        try:
            s.connect(("9.0.0.0", 80))
        except socket.error:
            return None
        ip, port = s.getsockname()
        s.close()
    except Exception:
        host_name = socket.gethostname()
        ip = socket.gethostbyname(host_name)
    return ip

def log_to_stdout(level=logging.DEBUG):
    root = logging.getLogger()
    root.setLevel(level)

    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )
    handler.setFormatter(formatter)
    root.addHandler(handler)


from django.shortcuts import render
from .forms import walletForm,userForm
from .models import DataUser,walletData
from django.shortcuts import redirect

# Create your views here.
def index(request):
    uform = userForm()

    context ={
      'judul':'.demo',
      'content':'Wellcome to my web.',
      'webname': 'demo',
      'uform': uform,
    }

    if request.method == 'POST':
      nik = request.POST['nik']
      hp_number = request.POST['hp_number']
      alamat = request.POST['alamat']
      ttl = request.POST['ttl']
      pekerjaan = request.POST['pekerjaan']
      user_signature = request.POST['user_signature']

      DataUser.objects.create(
        nik = nik,
        user_name = request.user.username,
        alamat = alamat,
        ttl = ttl,
        pekerjaan = pekerjaan,
        user_signature = user_signature,
        hp_number = hp_number,
      )
      return redirect("home")

    return render(request,'userdata/index.html', context)


import os
import sys
import argparse

dirname = os.path.dirname(__file__)
path = os.path.join(dirname, './../')
sys.path.append(path)

from Prepare_Data import pickle_load, prepare_CIFAR10, prepare_CIFAR100, prepare_SVHN
from Prepare_Model import prepare_GBP_End2End, prepare_Resnet

import numpy as np
import tensorflow as tf
import keras

from cleverhans.model import CallableModelWrapper
from cleverhans.utils_tf import model_eval
from cleverhans.attacks import\
    FastGradientMethod,\
    CarliniWagnerL2,\
    DeepFool,\
    ElasticNetMethod,\
    FastFeatureAdversaries,\
    LBFGS,\
    MadryEtAl,\
    MomentumIterativeMethod,\
    VirtualAdversarialMethod,\
    SaliencyMapMethod,\
    SPSA,\
    vatm

def main(type="Resnet", dataset="CIFAR10", attack_type="FGM"):

    size = 256
    eval_params = {'batch_size': 128}

    ############################################# Prepare the Data #####################################################

    if dataset == 'CIFAR10':
        (_, _), (x_test, y_test) = prepare_CIFAR10()
        num_classes = 10
        input_dim = 32
    elif dataset == 'CIFAR100':
        (_, _), (x_test, y_test) = prepare_CIFAR100()
        num_classes = 100
        input_dim = 32
    else:
        (_, _), (x_test, y_test) = prepare_SVHN("./Data/")
        num_classes = 10
        input_dim = 32

    x_test = x_test / 255.
    y_test = keras.utils.to_categorical(y_test, num_classes)

    ############################################# Prepare the Data #####################################################

    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    with tf.Session(config=config) as sess:

        # prepare the placeholders
        x = tf.placeholder(tf.float32, [None, input_dim, input_dim, 3])
        y = tf.placeholder(tf.float32, [None, num_classes])

        input_output = []
        def modelBuilder(x, num_classes, dataset, type, sess, input_output):

            if len(input_output) == 0:

                reuse = False

                # Model/Graph
                if type == 'End2End':
                    _, tf_model = \
                        prepare_GBP_End2End(num_classes,
                                            inputT=x, sess=sess,
                                            checkpoint_dir='./{}_{}/'.format(dataset, type), reuse=reuse)
                else:

                    _, tf_model = \
                        prepare_Resnet(num_classes,
                                       inputT=x, sess=sess,
                                       checkpoint_dir='./{}_{}/'.format(dataset, type), reuse=reuse)

                input_output.append(x)
                input_output.append(tf_model.logits)

            else:

                reuse = True

                # Model/Graph
                if type == 'End2End':
                    _, tf_model = \
                        prepare_GBP_End2End(num_classes, inputT=x, reuse=reuse)
                else:
                    _, tf_model = \
                        prepare_Resnet(num_classes, inputT=x, reuse=reuse)

                input_output.append(x)
                input_output.append(tf_model.logits)

            return tf_model.logits

        # create an attackable model for the cleverhans
        model = CallableModelWrapper(lambda placeholder: modelBuilder(placeholder, num_classes, dataset, type, sess, input_output), 'logits')

        # TODO: check the configurations
        if attack_type == "FGM": # pass
            attack = FastGradientMethod(model, back='tf', sess=sess)
            params = {
                'eps' : 0.06,
                'clip_min': 0.,
                'clip_max': 1.
            }
        elif attack_type == "CWL2": # pass
            attack = CarliniWagnerL2(model, back='tf', sess=sess)
            params = {
                'confidence': 0.9,
                'batch_size': 128,
                'learning_rate': 0.005,
            }
        elif attack_type == "DF": # pass
            attack = DeepFool(model, back='tf', sess=sess)
            params = {
            }
        elif attack_type == "ENM": # configurations checked, quickly tested
            attack = ElasticNetMethod(model, back='tf', sess=sess)
            params = {
                'confidence': 0.9,
                'batch_size': 128,
                'learning_rate': 0.005,
            }
        elif attack_type == "FFA": # configuration checked
            attack = FastFeatureAdversaries(model, back='tf', sess=sess)
            params = {
                'eps': 0.06,
                'eps_iter': 0.005,
                'clip_min': 0.,
                'clip_max': 1.
            }
        elif attack_type == "LBFGS":
            attack = LBFGS(model, back='tf', sess=sess)
            params = {
                'eps': 0.06,
                'clip_min': 0.,
                'clip_max': 1.
            }
        elif attack_type == "MEA":
            attack = MadryEtAl(model, back='tf', sess=sess)
            params = {
                'eps': 0.06,
                'clip_min': 0.,
                'clip_max': 1.
            }
        elif attack_type == "MIM":
            attack = MomentumIterativeMethod(model, back='tf', sess=sess)
            params = {
                'eps': 0.06,
                'clip_min': 0.,
                'clip_max': 1.
            }
        elif attack_type == "SMM":
            attack = SaliencyMapMethod(model, back='tf', sess=sess)
            params = {
                'eps': 0.06,
                'clip_min': 0.,
                'clip_max': 1.
            }
        elif attack_type == "SPSA":
            attack = SPSA(model, back='tf', sess=sess)
            params = {
                'eps': 0.06,
                'clip_min': 0.,
                'clip_max': 1.
            }
        elif attack_type == "VATM":
            attack = vatm(model, back='tf', sess=sess)
            params = {
                'eps': 0.06,
                'clip_min': 0.,
                'clip_max': 1.
            }
        elif attack_type == "VAM":
            attack = VirtualAdversarialMethod(model, back='tf', sess=sess)
            params = {
                'eps': 0.06,
                'clip_min': 0.,
                'clip_max': 1.
            }
        else:
            raise Exception("I don't recognize {} this attack type. I will use FGM instead.".format(attack_type))

        # tf operation
        adv_x = attack.generate(x, **params)

        # generate the adversarial examples
        adv_vals = sess.run(adv_x, feed_dict={x: x_test[:size]})

        # notice that "adv_vals" may contain NANs because of the failure of the attack
        # also the input may not be perturbed at all because of the failure of the attack
        to_delete = []
        for idx, adv in enumerate(adv_vals):
            # for nan
            if np.isnan(adv).any():
                to_delete.append(idx)
            # for no perturbation
            if np.array_equiv(adv, x_test[idx]):
                to_delete.append(idx)

        # cleanings
        adv_vals_cleaned = np.delete(adv_vals, to_delete, axis=0)
        ori_cleaned = np.delete(x_test[:size], to_delete, axis=0)
        y_cleaned = np.delete(y_test[:size], to_delete, axis=0)

        if len(adv_vals_cleaned) == 0:
            print("No adversarial example is generated!")
            return

        print("{} out of {} adversarial examples are generated.".format(len(adv_vals_cleaned), size))

        print("The average L_inf distortion is {}".format(
            np.mean([np.max(np.abs(adv - ori_cleaned[idx])) for idx, adv in enumerate(adv_vals_cleaned)])))

        # TODO: visualize the adv_vals

        accuracy = model_eval(sess, input_output[0], y, tf.nn.softmax(input_output[1]), x_test[:size], y_test[:size],
                              args=eval_params)
        print('Test accuracy on normal examples: %0.4f' % accuracy)

        accuracy = model_eval(sess, input_output[0], y, tf.nn.softmax(input_output[1]), adv_vals_cleaned, y_cleaned,
                              args=eval_params)
        print('Test accuracy on adversarial examples: %0.4f' % accuracy)

if __name__ == '__main__':

    os.environ['CUDA_VISIBLE_DEVICES'] = '0'

    ap = argparse.ArgumentParser()
    ap.add_argument("-t", "--type", required=True, help="Resnet or End2End")
    ap.add_argument("-d", "--dataset", required=True, help="CIFAR10, CIFAR100 or SVHN")
    ap.add_argument("-a", "--attack", required=True, help="Attack Type")
    args = vars(ap.parse_args())

    main(type=args["type"], dataset=args["dataset"], attack_type=args["attack"])


import os
import getpass

# Cubitpy imports.
from .cubitpy_types import (
    FiniteElementObject,
    GeometryType,
    ElementType,
    CubitItems,
    BoundaryConditionType,
)

class CubitOptions(object):
    """Object for types in cubitpy."""

    def __init__(self):
        # Temporary directory for cubitpy.
        self.temp_dir = os.path.join(
            "/tmp/cubitpy_{}".format(getpass.getuser()), "pid_{}".format(os.getpid())
        )
        self.temp_log = os.path.join(self.temp_dir, "cubitpy.log")

        # Check if temp path exits, if not create it.
        os.makedirs(self.temp_dir, exist_ok=True)

        # Geometry types.
        self.geometry = GeometryType

        # Finite element types.
        self.finite_element_object = FiniteElementObject

        # Element shape types.
        self.element_type = ElementType

        # Cubit internal items.
        self.cubit_items = CubitItems

        # Boundary condition type.
        self.bc_type = BoundaryConditionType

        # Tolerance for geometry.
        self.eps_pos = 1e-10

    @staticmethod
    def get_default_paths(name, throw_error=True):
        """Look for and return a path to cubit or pre_exodus."""

        if name == "cubit":
            environment_variable = "CUBIT"
            test_function = os.path.isdir
        elif name == "pre_exodus":
            environment_variable = "BACI_PRE_EXODUS"
            test_function = os.path.isfile
        else:
            raise ValueError("Type {} not implemented!".format(name))

        # Check if he environment variable is set and the path exits.
        if environment_variable in os.environ.keys():
            if test_function(os.environ[environment_variable]):
                return os.environ[environment_variable]

        # No valid path found or given.
        if throw_error:
            raise ValueError("Path for {} not found!".format(name))
        else:
            return None

# Global object with options for cubitpy.
cupy = CubitOptions()


import torch
import torchvision
from torchvision.datasets import MNIST
from torch.utils.data import DataLoader
from torch_geometric.datasets import Planetoid
from torch_geometric.transforms import NormalizeFeatures
import dgl.data

def load_mnist_data(root='data', flatten=True, batch_size=32):
    if flatten:
        transform = torchvision.transforms.Compose(
            [torchvision.transforms.ToTensor(),
             torchvision.transforms.Lambda(lambda x: torch.flatten(x))]
        )
    else:
        transform = torchvision.transforms.ToTensor(),

    train_dataset = MNIST(root=root, download=True, transform=transform)
    test_dataset = MNIST(root=root, train=False,
                         download=True, transform=transform)

    train_dataloader = DataLoader(train_dataset, batch_size=32, shuffle=True)
    test_dataloader = DataLoader(test_dataset, batch_size=32, shuffle=False)

    return train_dataloader, test_dataloader

def load_cora():
    dataset = Planetoid(root='data/Planetoid', name='Cora', transform=NormalizeFeatures())

    print()
    print(f'Dataset: {dataset}:')
    print('======================')
    print(f'Number of graphs: {len(dataset)}')
    print(f'Number of features: {dataset.num_features}')
    print(f'Number of classes: {dataset.num_classes}')

    data = dataset[0]  # Get the first graph object.
    return data, dataset

def load_cora_dgl():
    dataset = dgl.data.CoraGraphDataset()
    g = dataset[0]
    return g, dataset


import sagemaker
import boto3

from sagemaker.huggingface.model import HuggingFaceModel

sess = sagemaker.Session()

sagemaker_session_bucket = "sentence-transformers-sagemaker-hf-150523"

try:
    role = sagemaker.get_execution_role()
except ValueError:
    iam = boto3.client("iam")
    role = iam.get_role(RoleName="AmazonSageMaker-ExecutionRole-20220224T111993")[
        "Role"
    ]["Arn"]

sess = sagemaker.Session(default_bucket=sagemaker_session_bucket)

print(f"sagemaker role arn: {role}")
print(f"sagemaker bucket: {sess.default_bucket()}")
print(f"sagemaker session region: {sess.boto_region_name}")

repository = "sentence-transformers/all-mpnet-base-v2"

model_id = repository.split("/")[-1]
s3_location = f"s3://{sess.default_bucket()}/custom_inference/{model_id}/model.tar.gz"

# create Hugging Face Model Class
huggingface_model = HuggingFaceModel(
    model_data=s3_location,
    role=role,
    transformers_version="4.28",
    pytorch_version="2.0",
    py_version="py310",
)

# deploy the endpoint endpoint
predictor = huggingface_model.deploy(
    initial_instance_count=1,
    instance_type="ml.g4dn.xlarge",
    endpoint_name="sentence-transformers-all-mpnet-base-v2",
)

# "ml.g4dn.xlarge"
# ml.g5.2xlarge


from django.db.models import BooleanField, Exists, OuterRef, Sum, Value
from django.shortcuts import get_object_or_404
from djoser.views import UserViewSet
from recipes.models import (
    Favourites,
    Ingredients,
    IngredientInRecipe,
    Recipe,
    ShopList,
    Tag,
)
from django.http import HttpResponse
from users.models import Follow, UserCustomized
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import SAFE_METHODS, IsAuthenticated

from .filters import RecipesFilter, IngredientsFilter
from .permissions import IsAdminAuthorOrReadOnly, IsAdminOrReadOnly
from .serializers import (
    AddRecipeSerializer,
    IngredientsSerializer,
    GetRecipeSerializer,
    CreateUpdateRecipeSerializer,
    TagsSerializer,
    FollowSerializer,
    CheckFollowSerializer,
    CheckFavouriteSerializer,
    CheckShopCartSerializer
)
from core.pagination import StandardResultsSetPagination

class TagViewSet(viewsets.ReadOnlyModelViewSet):
    '''Tags' viewset. Tags Model.'''

    queryset = Tag.objects.all()
    serializer_class = TagsSerializer
    permission_classes = (IsAdminOrReadOnly,)
    pagination_class = None

class RecipeViewSet(viewsets.ModelViewSet):
    '''Recipes' viewset. Recipes Model.'''

    permission_classes = (IsAdminAuthorOrReadOnly,)
    filter_class = RecipesFilter

    def get_serializer_class(self):
        '''Recipes' serialization.'''
        if self.request.method in SAFE_METHODS:
            return GetRecipeSerializer
        return CreateUpdateRecipeSerializer

    def get_queryset(self):
        '''Check if recipe in shoplist and/or favs'''
        user = self.request.user
        if user.is_authenticated:
            return Recipe.objects.annotate(
                is_favorited=Exists(
                    user.fav_adder.filter(recipe__pk=OuterRef('pk'))),
                is_in_shopping_cart=Exists(
                    user.shopper.filter(recipe__pk=OuterRef('pk')))
            )
        return Recipe.objects.annotate(
            is_favorited=Value(False, output_field=BooleanField()),
            is_in_shopping_cart=Value(False, output_field=BooleanField()),
        )

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

    @action(
        detail=True, methods=('POST', 'DELETE'),
        permission_classes=(IsAuthenticated,)
    )
    def shopping_cart(self, request, pk=None):
        '''Add/Delete a recipe to/from the shoplist.'''
        data = {
            'user': request.user.id,
            'recipe': pk,
        }
        serializer = CheckShopCartSerializer(
            data=data, context={'request': request}
        )
        serializer.is_valid(raise_exception=True)
        if request.method == 'POST':
            return self.add_object(ShopList, request.user, pk)
        return self.delete_object(ShopList, request.user, pk)

    def add_object(self, model, user, pk):
        '''Adding objects for favourites and shoplist.'''
        recipe = get_object_or_404(Recipe, id=pk)
        model.objects.create(user=user, recipe=recipe)
        serializer = AddRecipeSerializer(recipe)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def delete_object(self, model, user, pk):
        '''Deleting objects from favourites and shoplist.'''
        model.objects.filter(user=user, recipe__id=pk).delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    @action(
        methods=('GET',), detail=False, permission_classes=(IsAuthenticated,)
    )
    def download_shopping_cart(self, request):
        '''Download shoplist file in txt format'''
        ingredients = (
            IngredientInRecipe.objects.filter(
                recipe__shoplist_recipe__user=request.user
            )
            .select_related('ingredient').all()
            .prefetch_related('recipe').all()
            .values('ingredient__name', 'ingredient__measurement_unit')
            .order_by('ingredient__name')
            .annotate(total=Sum('amount'))
        )
        col1 = max(len(ingredient["ingredient__name"])
                   for ingredient in ingredients)
        col2 = max(len(str(ingredient["total"]))
                   for ingredient in ingredients)
        col3 = max(len(ingredient["ingredient__measurement_unit"])
                   for ingredient in ingredients)
        devider = (
            f'\n|{"_"*(col1+2)}|{"_"*(col2+2)}|{"_"*(col3+2)}|\n')
        output = 'The list of goods for your recipes. \n\n'
        output += f',{(len(devider)-devider.count("|"))*"_"},\n'
        output += devider.join(
            f'| {ingredient["ingredient__name"]} '
            f'{(col1-len(ingredient["ingredient__name"]))*" "}'
            f'| {ingredient["total"]}'
            f'{(col2-len(str(ingredient["total"])))*" "} '
            f'| {ingredient["ingredient__measurement_unit"]}'
            f'{(col3-len(ingredient["ingredient__measurement_unit"]))*" "} |'
            for ingredient in ingredients
        )
        output += devider
        filename = 'shoplist.txt'
        response = HttpResponse(output, content_type="text/plain")
        response['Content-Disposition'] = f'attachment; filename={filename}'
        return response

    @action(
        detail=True, methods=('POST', 'DELETE'),
        permission_classes=(IsAuthenticated,)
    )
    def favorite(self, request, pk=None):
        '''Add/Delete a recipe to/from favourites.'''
        data = {
            'user': request.user.id,
            'recipe': pk,
        }
        serializer = CheckFavouriteSerializer(
            data=data, context={'request': request}
        )
        serializer.is_valid(raise_exception=True)
        if request.method == "POST":
            return self.add_object(Favourites, request.user, pk)
        return self.delete_object(Favourites, request.user, pk)

class FollowViewSet(UserViewSet):
    '''Subscriptions viewset includes all actions.'''
    permission_classes = (IsAuthenticated,)
    pagination_class = StandardResultsSetPagination

    @action(methods=('GET',), detail=False)
    def subscriptions(self, request):
        user = request.user
        queryset = user.follower.all()
        page = self.paginate_queryset(queryset)
        serializer = FollowSerializer(page,
                                      context={'request': request},
                                      many=True)
        return self.get_paginated_response(serializer.data)

    @action(
        methods=('POST', 'DELETE'),
        detail=True)
    def subscribe(self, request, id=None):
        '''Follow the author.'''
        user = request.user
        author = get_object_or_404(UserCustomized, pk=id)
        data = {
            'user': user.id,
            'author': author.id,
        }
        serializer = CheckFollowSerializer(
            data=data,
            context={'request': request},
        )
        serializer.is_valid(raise_exception=True)
        if request.method == "POST":
            result = Follow.objects.create(user=user, author=author)
            serializer = FollowSerializer(result, context={'request': request})
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        user.follower.filter(author=author).delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

class IngredientsViewSet(viewsets.ReadOnlyModelViewSet):
    '''Ingredients' viewset. Ingredients Model. '''

    queryset = Ingredients.objects.all()
    serializer_class = IngredientsSerializer
    filter_backends = (IngredientsFilter,)
    search_fields = ('^name',)
    permission_classes = (IsAdminOrReadOnly,)
    pagination_class = None


import random
from re import I, X

import numpy as np

from Appliance import Appliance
from Appliance_Type import appliance_type
from scipy.optimize import linprog
from Household import Household
from PriceGenerators import RTP_Price

NUMBER_OF_HOUSES = 30
HOURS_IN_DAY = 24
EV_MAX_HOURLY = 3

def get_houses_with_ev(num_houses):
    houses_with_EVs = []
    for _ in range(num_houses):
        houses_with_EVs.append(random.randint(0, 1))
    return houses_with_EVs

def main():
    houses_with_EVs = get_houses_with_ev(NUMBER_OF_HOUSES)
    number_of_appliances = sum(houses_with_EVs)

    left_eq = []
    households = []
    for i in range(NUMBER_OF_HOUSES):
        house = Household("House " + str(i))
        households.append(house)
        if (houses_with_EVs[i] == 0):
            left_eq.append([0] * HOURS_IN_DAY * NUMBER_OF_HOUSES)
            continue

        ev = Appliance("EV", 9.9, 0, EV_MAX_HOURLY, appliance_type.shiftable)
        house.add_appliance(ev)
        left_eq.append(ev.set_operation_time(
            20, 8, HOURS_IN_DAY, NUMBER_OF_HOUSES))

    # Sets daily usage of household to daily usage of it's appliances
    rhs_eq = []
    for house in households:
        appliances = house.get_appliances()
        if len(appliances) == 0:
            rhs_eq.append(0)
        else:
            rhs_eq.append(appliances[0].daily_usage)

    ineq_matrix = np.identity(HOURS_IN_DAY * NUMBER_OF_HOUSES)

    rhs_ineq = [EV_MAX_HOURLY] * HOURS_IN_DAY * NUMBER_OF_HOUSES

    rtp = RTP_Price(HOURS_IN_DAY, NUMBER_OF_HOUSES)
    objective = rtp.get_rtp_prices()

    opt = linprog(c=objective, A_ub=ineq_matrix,
                  b_ub=rhs_ineq, A_eq=left_eq, b_eq=rhs_eq, method="revised simplex")

    print('Optimized consumption for the EV each hour House # 1:', np.round(opt.x[:25], 2),
          '\nOptimized consumption for the EV each hour House # 2', np.round(
              opt.x[25:49], 2),
          '\nOptimized consumption for the EV each hour House # 3', np.round(
              opt.x[48:72], 2),
          '\nTotal Optamized cost for the nebougherhood in NOK', np.round(opt.fun, 2))

if __name__ == '__main__':
    main()


def open_input():
    with open("input.txt") as fd:
        array = fd.read().splitlines()
    return array

def make_dictionary(array):
    dictionary = {"up": [], "down": [], "forward": []}
    lenght = len(array)
    for i in range(0, lenght):
        array[i] = array[i].split(' ')
        if array[i][0] == "up":
            dictionary["up"].append(int(array[i][1]))
        elif array[i][0] == "down":
            dictionary["down"].append(int(array[i][1]))
        elif array[i][0] == "forward":
            dictionary["forward"].append(int(array[i][1]))
    return dictionary

def part_one(array):
    dictionary = make_dictionary(array)
    up = sum(dictionary["up"])
    down = sum(dictionary["down"])
    forward = sum(dictionary["forward"])
    print("part one:", (down - up) * forward)

def part_two(array):
    aim = 0
    ver = 0
    hor = 0
    lenght = len(array)
    for i in range(0, lenght):
        if array[i][0] == "up":
            aim -= int(array[i][1])
        elif array[i][0] == "down":
            aim += int(array[i][1])
        elif array[i][0] == "forward":
            hor += int(array[i][1])
            ver += int(array[i][1]) * aim
    print("part two:", ver * hor)

if (__name__ == "__main__"):
    array = open_input()
    part_one(array)
    part_two(array)


#!/usr/bin/env python3
import math
import os
import sys
import csv
import tensorflow as tf
import numpy as np
import pandas as pd
import time
import argparse

np.set_printoptions(suppress=True)
np.random.seed(0)

EPOCHES = 1
BATCH_SIZE = 32
learning_rate = 0.03125
DIM_NUM = 11
ROW_NUM = 1279

file_x = ""
file_y = ""
filex_name = "cls_train_x.csv"
filey_name = "cls_train_y.csv"

file_x = "../dsets/ALL/" + filex_name
file_y = "../dsets/ALL/" + filey_name

print("file_x:", file_x)
print("file_y:", file_y)
print("DIM_NUM:", DIM_NUM)

# training dataset
dataset_x = tf.data.TextLineDataset(file_x)
dataset_y = tf.data.TextLineDataset(file_y)

# dataset decode
def decode_x(line):
    fields = tf.string_split([line], ',').values
    fields = tf.string_to_number(fields, tf.float64)
    return fields

def decode_y(line):
    fields = tf.string_split([line], ',').values
    fields = tf.string_to_number(fields, tf.float64)
    return fields

# dataset pipeline
dataset_x = dataset_x \
    .map(decode_x) \
    .batch(BATCH_SIZE)

dataset_y = dataset_y \
    .map(decode_y) \
    .batch(BATCH_SIZE)

# make iterator
iter_x = dataset_x.make_initializable_iterator()
X = iter_x.get_next()

iter_y = dataset_y.make_initializable_iterator()
Y = iter_y.get_next()

# initialize W & b
W = tf.Variable(tf.zeros([DIM_NUM, 1], dtype=tf.float64))
b = tf.Variable(tf.zeros([1], dtype=tf.float64))

# build lr model
pred_Y = tf.sigmoid(tf.matmul(X, W) + b)
dy = pred_Y - Y
dw = tf.matmul(X, dy, transpose_a=True) * (1.0 / BATCH_SIZE)
db = tf.reduce_sum(dy, axis=0) * (1.0 / BATCH_SIZE)
delta_w = dw * learning_rate
delta_b = db * learning_rate
update_w = W - delta_w
update_b = b - delta_b

# update variables
assign_update_w = tf.assign(W, update_w)
assign_update_b = tf.assign(b, update_b)

# training
init = tf.global_variables_initializer()
with tf.Session() as sess:
    # init var & iter
    sess.run(init)
    sess.run([iter_x.initializer, iter_y.initializer])

    # train
    start_time = time.time()
    BATCHES = int(ROW_NUM / BATCH_SIZE)

    for e in range(EPOCHES):
        for i in range(BATCHES):
            sess.run([assign_update_w, assign_update_b])

    training_use_time = time.time() - start_time
    print("training_use_time: {} seconds".format(training_use_time))


import inspect
import os
import pickle
import subprocess
import sys
import types
from textwrap import dedent
from typing import Optional, Iterable, Dict, Callable

import dill

from airflow.exceptions import AirflowException
from airflow.models import BaseOperator, SkipMixin
from airflow.utils.decorators import apply_defaults
from airflow.utils.file import TemporaryDirectory
from airflow.utils.operator_helpers import context_to_airflow_vars

class PythonOperator(BaseOperator):

    template_fields = ('templates_dict', 'op_args', 'op_kwargs')
    ui_color = '#ffefeb'

    # since we won't mutate the arguments, we should just do the shallow copy
    # there are some cases we can't deepcopy the objects(e.g protobuf).
    shallow_copy_attrs = ('python_callable', 'op_kwargs',)

    @apply_defaults
    def __init__(
        self,
        python_callable,
        op_args: Optional[Iterable] = None,
        op_kwargs: Optional[Dict] = None,
        provide_context: bool = False,
        templates_dict: Optional[Dict] = None,
        templates_exts: Optional[Iterable[str]] = None,
        *args,
        **kwargs
    ):
        super().__init__(*args, **kwargs)
        if not callable(python_callable):
            raise AirflowException('`python_callable` param must be callable')
        self.python_callable = python_callable
        self.op_args = op_args or []
        self.op_kwargs = op_kwargs or {}
        self.provide_context = provide_context
        self.templates_dict = templates_dict
        if templates_exts:
            self.template_ext = templates_exts

    def execute(self, context):
        # Export context to make it available for callables to use.
        airflow_context_vars = context_to_airflow_vars(context, in_env_var_format=True)
        self.log.info("Exporting the following env vars:\n%s",
                      '\n'.join(["{}={}".format(k, v)
                                 for k, v in airflow_context_vars.items()]))
        os.environ.update(airflow_context_vars)

        if self.provide_context:
            context.update(self.op_kwargs)
            context['templates_dict'] = self.templates_dict
            self.op_kwargs = context

        return_value = self.execute_callable()
        self.log.info("Done. Returned value was: %s", return_value)
        return return_value

    def execute_callable(self):
        with TemporaryDirectory(prefix='venv') as tmp_dir:
            if self.templates_dict:
                self.op_kwargs['templates_dict'] = self.templates_dict
            # generate filenames
            input_filename = os.path.join(tmp_dir, 'script.in')
            output_filename = os.path.join(tmp_dir, 'script.out')
            string_args_filename = os.path.join(tmp_dir, 'string_args.txt')
            script_filename = os.path.join(tmp_dir, 'script.py')

            # set up virtualenv
            self._execute_in_subprocess(self._generate_virtualenv_cmd(tmp_dir))
            cmd = self._generate_pip_install_cmd(tmp_dir)
            if cmd:
                self._execute_in_subprocess(cmd)

            self._write_args(input_filename)
            self._write_script(script_filename)
            self._write_string_args(string_args_filename)

            # execute command in virtualenv
            self._execute_in_subprocess(
                self._generate_python_cmd(tmp_dir,
                                          script_filename,
                                          input_filename,
                                          output_filename,
                                          string_args_filename))
            return self._read_result(output_filename)

    def _pass_op_args(self):
        # we should only pass op_args if any are given to us
        return len(self.op_args) + len(self.op_kwargs) > 0

    def _execute_in_subprocess(self, cmd):
        try:
            self.log.info("Executing cmd\n%s", cmd)
            output = subprocess.check_output(cmd,
                                             stderr=subprocess.STDOUT,
                                             close_fds=True)
            if output:
                self.log.info("Got output\n%s", output)
        except subprocess.CalledProcessError as e:
            self.log.info("Got error output\n%s", e.output)
            raise

    def _write_string_args(self, filename):
        # writes string_args to a file, which are read line by line
        with open(filename, 'w') as file:
            file.write('\n'.join(map(str, self.string_args)))

    def _write_args(self, input_filename):
        # serialize args to file
        if self._pass_op_args():
            with open(input_filename, 'wb') as file:
                arg_dict = ({'args': self.op_args, 'kwargs': self.op_kwargs})
                if self.use_dill:
                    dill.dump(arg_dict, file)
                else:
                    pickle.dump(arg_dict, file)

    def _read_result(self, output_filename):
        if os.stat(output_filename).st_size == 0:
            return None
        with open(output_filename, 'rb') as file:
            try:
                if self.use_dill:
                    return dill.load(file)
                else:
                    return pickle.load(file)
            except ValueError:
                self.log.error("Error deserializing result. "
                               "Note that result deserialization "
                               "is not supported across major Python versions.")
                raise

    def _write_script(self, script_filename):
        with open(script_filename, 'w') as file:
            python_code = self._generate_python_code()
            self.log.debug('Writing code to file\n', python_code)
            file.write(python_code)

    def _generate_virtualenv_cmd(self, tmp_dir):
        cmd = ['virtualenv', tmp_dir]
        if self.system_site_packages:
            cmd.append('--system-site-packages')
        if self.python_version is not None:
            cmd.append('--python=python{}'.format(self.python_version))
        return cmd

    def _generate_pip_install_cmd(self, tmp_dir):
        if len(self.requirements) == 0:
            return []
        else:
            # direct path alleviates need to activate
            cmd = ['{}/bin/pip'.format(tmp_dir), 'install']
            return cmd + self.requirements

    @staticmethod
    def _generate_python_cmd(tmp_dir, script_filename,
                             input_filename, output_filename, string_args_filename):
        # direct path alleviates need to activate
        return ['{}/bin/python'.format(tmp_dir), script_filename,
                input_filename, output_filename, string_args_filename]

    def _generate_python_code(self):
        if self.use_dill:
            pickling_library = 'dill'
        else:
            pickling_library = 'pickle'
        fn = self.python_callable
        # dont try to read pickle if we didnt pass anything
        if self._pass_op_args():
            load_args_line = 'with open(sys.argv[1], "rb") as file: arg_dict = {}.load(file)'\
                .format(pickling_library)
        else:
            load_args_line = 'arg_dict = {"args": [], "kwargs": {}}'

        # no indents in original code so we can accept
        # any type of indents in the original function
        # we deserialize args, call function, serialize result if necessary
        return dedent("""\
        import {pickling_library}
        import sys
        {load_args_code}
        args = arg_dict["args"]
        kwargs = arg_dict["kwargs"]
        with open(sys.argv[3], 'r') as file:
            virtualenv_string_args = list(map(lambda x: x.strip(), list(file)))
        {python_callable_lines}
        res = {python_callable_name}(*args, **kwargs)
        with open(sys.argv[2], 'wb') as file:
            res is not None and {pickling_library}.dump(res, file)
        """).format(load_args_code=load_args_line,
                    python_callable_lines=dedent(inspect.getsource(fn)),
                    python_callable_name=fn.__name__,
                    pickling_library=pickling_library)


import mongomock
import pytest
from fastapi.testclient import TestClient
from main import app, get_db

@pytest.fixture()
def mock_mongo():
    mongo_client = mongomock.MongoClient()
    db = mongo_client["government_catnip"]

    def fake_db():
        return db

    app.dependency_overrides[get_db] = fake_db

    yield db

@pytest.fixture()
def db_location(mock_mongo):
    yield mock_mongo["location_information"]

@pytest.fixture()
def mock_location(db_location):
    db_location.insert_many([
        {
            "locationID": 1,
            "location": "Amphawa",
            "population": 10000,
            "numberOfVoters": 9995
        },
        {
            "locationID": 2,
            "location": "Bang Len",
            "population": 20000,
            "numberOfVoters": 18995
        }
    ])

@pytest.fixture()
def db_population(mock_mongo):
    yield mock_mongo["personal_information"]

@pytest.fixture()
def mock_population(db_population):
    db_population.insert_many([
        {
            "citizenID": 4569871354123,
            "title": "Mr.",
            "firstName": "Anuman",
            "lastName": "Saengthong",
            "sex": "Male",
            "locationID": 557,
            "rightToVote": True,
            "blacklist": False
        },
        {
            "citizenID": 1234567898765,
            "title": "Ms.",
            "firstName": "Achara",
            "lastName": "Sukkasem",
            "sex": "Female",
            "locationID": 231,
            "rightToVote": True,
            "blacklist": False
        }])

@pytest.fixture()
def db_election_result(mock_mongo):
    yield mock_mongo["election_result"]

@pytest.fixture()
def mock_election_result(db_election_result):
    db_election_result.insert_many([
        {
            "locationID": 1,
            "location": "Amphawa",
            "numberOfVoters": 9900,
            "nameOfParliament": "Jakarin Chujan",
            "nameOfParty": "Catnip"

        },
        {
            "locationID": 2,
            "location": "Bang Len",
            "numberOfVoters": 9900,
            "nameOfParliament": "Chananya Photan",
            "nameOfParty": "Catnip"
        }
    ])

@pytest.fixture()
def db_district(mock_mongo):
    yield mock_mongo["district"]

@pytest.fixture()
def mock_district(db_district):
    db_district.insert_many([
        {
            "districtID": 1,
            "district": "Amphawa",
            "districtTH": "อัมพวา",
            "province": "Samut Songkhram",
            "provinceTH": "สมุทรสงคราม",
            "region": "Centre"
        },
        {
            "districtID": 2,
            "district": "Bang Len",
            "districtTH": "บางเลน",
            "province": "Nakhon Pathom",
            "provinceTH": "นครปฐม",
            "region": "Centre"
        }
    ])

@pytest.fixture()
def db_personal_cvv(mock_mongo):
    yield mock_mongo["personal_cvv"]

@pytest.fixture()
def mock_person_cvv(db_personal_cvv):
    db_personal_cvv.insert_many([
        {
            "citizenID": 440556794906,
            "citizenCVV": "$2b$12$xFOUTVJjht350Ik7D1eQhOB1yB0/yog4etgEbn4aDk3Jf3CT65rm."
        },
        {
            "citizenID": 173518749711,
            "citizenCVV": "$2b$12$UHsLQtJ5hit1XZyEYHo9IO.61aDeJV/rdc1/mp35OwJKcISe.hN0W"
        }
    ])

@pytest.fixture()
def client():
    yield TestClient(app)


##
# This file contains functions related to working with histograms
##

import cv2

# convert to HSV get histogram on hue
def getHueHistogram(image):
    hsvImage = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    hueHist = cv2.calcHist([hsvImage], [0], None, [180], [0,180])
    return hueHist

# convert to HSV get 2d histogram on hue and saturation
def getHueSatHistogram(image):
    hsvImage = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    hueSatHist = cv2.calcHist([hsvImage], [0,1], None, [180,256], [0,180, 0,256])

    # remove low saturation which corresponds to white
    hueSatHist[:,0:50] = 0
    return hueSatHist


from pathlib import Path
import yaml
#from ruamel.yaml import YAML as RUAMEL_YAML
#import ruamel.yaml
import src.common.processing_vars as var
def write_role_file(self, d:dict):
    yml_path = 'snowflake/account/roles/' + d['ROLE_NAME_SANS_ENV'] + '.yml'

    data = self.create_parent_load_data(yml_path)

    data['OWNER'] = self.choose_value_string(data, 'OWNER', d,'OWNER', var.EMPTY_STRING)
    data['COMMENT'] = self.choose_value_string(data, 'COMMENT', d, 'COMMENT', var.EMPTY_STRING)
    #data['PARENT_ROLES'] = self.choose_value_string(data, 'PARENT_ROLES', d, 'PARENT_ROLES', var.EMPTY_STRING)
    data['CHILD_ROLES'] = self.choose_value_list(data, 'CHILD_ROLES', d, 'CHILD_ROLES', var.EMPTY_LIST)
    #print('#### RAW ####')
    #print(d['CHILD_ROLES'])
    #print('#### MODIFIED ####')
    #print(data['CHILD_ROLES'])
    if 'TAGS' in d and d['TAGS'] != []:
        if 'TAGS' in data:
            data['TAGS'] = self.choose_list_objects(d['TAGS'], data['TAGS'])
        else:
            data['TAGS'] = d['TAGS']
    else:
        data['TAGS']=var.EMPTY_STRING

    #ryaml = ruamel.yaml.YAML(typ=['rt', 'string'])
    #ryaml = RUAMEL_YAML(typ=['rt', 'string'])
    #yaml_string = ryaml.dump_to_string(data)
    yaml_string = yaml.dump(data, sort_keys=False)
    #yaml_string_converted = self.replace_jinja_ref_string(yaml_string)
    #yaml_string_converted = yaml_string_converted.replace("'"+var.EMPTY_STRING+"'",'')
    yaml_string_converted = self.convert_special_characters_back_in_file(yaml_string)
    with open(yml_path, "w+") as f:
        f.write(yaml_string_converted)


import multiprocessing

def worker(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    with multiprocessing.Manager() as manager:
        d = manager.dict()
        l = manager.list(range(10))

        p = multiprocessing.Process(target=worker, args=(d, l))
        p.start()
        p.join()

        print(d)
        print(l)