import pydantic
from pydantic import Field
from typing import Optional, Any, Literal, Union, List
from .dataid import DataID

prefix = "mupif."
type_ids = []
type_ids.extend(prefix+s for s in list(map(str, DataID)))

class PhysicsMeta(pydantic.BaseModel):
    Type: Literal['Electronic', 'Atomistic', 'Molecular', 'Mesoscopic', 'Continuum', 'Other']
    Entity: Literal['Atom', 'Electron', 'Grains', 'Finite volume', 'Other']
    Entity_description: str = ''
    Equation: List[str] = []
    Equation_quantities: List[str] = []
    Relation_description: List[str] = []

class SolverMeta(pydantic.BaseModel):
    Software: str
    Language: str
    License: str
    Creator: str
    Version_date: str
    Solver_additional_params: str = ''
    Documentation: str
    Estim_time_step_s: float
    Estim_comp_time_s: float
    Estim_execution_cost_EUR: float
    Estim_personnel_cost_EUR: float
    Required_expertise:  Literal["None", "User", "Expert"]
    Accuracy:  Literal["Low", "Medium", "High", "Unknown"]
    Sensitivity:  Literal["Low", "Medium", "High", "Unknown"]
    Complexity:  Literal["Low", "Medium", "High", "Unknown"]
    Robustness:  Literal["Low", "Medium", "High", "Unknown"]

# See https://docs.pydantic.dev/1.10/usage/schema/ for possible Field(...) arguments
# the first positional argument is the default value, doc translates to JSON Schema description field
class ExecutionMeta(pydantic.BaseModel):
    '''Execution metadata, for use by the MuPIF infrastructure.'''
    ID: str = ''
    Use_case_ID: Union[str, int] = ''
    Task_ID: str = ''
    Log_URI: str = Field('',description='Internal use only: Pyro URI of the remote logger object, valid only when the workflow is running.')
    Status: Literal["Instantiated", "Initialized", "Running", "Finished", "Failed"] = Field(default='Instantiated',description='Set by the workflow scheduler automatically')
    Progress: float = Field(-1,description='Floating progress in range 0…1; may be set by the workflow, but is not mandatory. Ignored if negative.')
    Date_time_start: str = Field('',description='Automatically set in Workflow')
    Date_time_end: str = Field('',description='Automatically set in Workflow')
    Timeout: int = Field(0,description='Maximum runtime in seconds; unlimited if non-positive')
    Username: str = Field('',description='Automatically set in Model and Workflow')
    Hostname: str = Field('',description='Automatically set in Model and Workflow')

class IOMeta(pydantic.BaseModel):
    Type: Literal[
        'mupif.Property',
        'mupif.TemporalProperty',
        'mupif.Field',
        'mupif.TemporalField',
        'mupif.HeavyStruct',
        'mupif.PyroFile',
        'mupif.String',
        'mupif.ParticleSet',
        'mupif.GrainState',
        'mupif.PiecewiseLinFunction',
        'mupif.DataList[mupif.Property]',
        'mupif.DataList[mupif.TemporalProperty]',
        'mupif.DataList[mupif.Field]',
        'mupif.DataList[mupif.TemporalField]',
        'mupif.DataList[mupif.HeavyStruct]',
        'mupif.DataList[mupif.String]',
        'mupif.DataList[mupif.ParticleSet]',
        'mupif.DataList[mupif.GrainState]',
        'mupif.DataList[mupif.PiecewiseLinFunction]'
    ]
    Type_ID: DataID
    Obj_ID: Optional[Union[str, List[str]]] = None
    Name: str
    ValueType: Literal['Scalar', 'Vector', 'Tensor', 'ScalarArray', 'VectorArray', 'TensorArray', ''] = ''
    Description: str = ''
    Units: str
    Required: bool = False

    @pydantic.root_validator(pre=False)
    def _require_valueType_unless_property(cls, values):
        if values['Type'] != 'mupif.Property' and values['Type'] != 'mupif.TemporalProperty':
            assert 'ValueType' != ''
        return values

    @pydantic.root_validator(pre=True)
    def _convert_type_id_to_value(cls, values):
        tid = values['Type_ID']
        if isinstance(tid, str):
            prefix = 'mupif.DataID.'
            if tid.startswith(prefix):
                tid = tid[len(prefix):]
            values['Type_ID'] = DataID[tid]
        return values

class InputMeta(IOMeta):
    Set_at: Literal['initialization', 'timestep']

class OutputMeta(IOMeta):
    pass

class ModelInWorkflowMeta(pydantic.BaseModel):
    'Metadata for Model as part of a workflow'
    Name: str
    Module: str = ''
    Class: str = ''
    Jobmanager: str = ''

    @pydantic.root_validator(pre=False)
    def _moduleClass_or_jobmanager(cls, values):
        if values['Jobmanager'] == '':
            assert values['Module'] != '' and values['Name'] != ''
        return values

class ModelWorkflowCommonMeta(pydantic.BaseModel):
    'Metadata common for both Model and Workflow'
    Name: str
    ID: Union[str, int]
    Description: str
    Execution: ExecutionMeta
    Inputs: List[InputMeta] = []
    Outputs: List[OutputMeta] = []

class ModelMeta(ModelWorkflowCommonMeta):
    pass
    Physics: PhysicsMeta
    Solver: SolverMeta

class WorkflowMeta(ModelWorkflowCommonMeta):
    Models: List[ModelInWorkflowMeta] = []

#ModelMeta_JSONSchema=ModelMeta.schema_json()
#WorkflowMeta_JSONSchema=WorkflowMeta.schema_json()

##
## OLD, transfer comments and delete
##

if 0:
    import copy
    # Schema for metadata for Model and further passed to Workflow
    ModelSchema = {
        "type": "object",  # Object supplies a dictionary
        "properties": {
            # Name: e.g. Non-stationary thermal problem, obtained automatically from getApplicationSignature()
            # Name of the model (or workflow), e.g. "stationary thermal model", "steel buckling workflow"
            "Name": {"type": "string"},
            # ID: Unique ID of model (workflow), e.g. "Lammps", "CalculiX", "MFEM", "Buckling workflow 1"
            "ID": {"type": ["string", "integer"]},
            "Description": {"type": "string"},
            "Version_date": {"type": "string"},
            "Material": {"type": "string"},  # What material is simulated
            "Manuf_process": {"type": "string"},  # Manufacturing process or in-service conditions
            "Geometry": {"type": "string"},  # e.g. nanometers, 3D periodic box
            "Physics": {  # Corresponds to MODA Generic Physics
                "type": "object",
                "properties": {
                    # Type: MODA model type
                    "Type": {"type": "string", "enum": ["Electronic", "Atomistic", "Molecular", "Mesoscopic", "Continuum", "Other"]},
                    "Entity": {"type": "string", "enum": ["Atom", "Electron", "Grains", "Finite volume", "Other"]},
                    # Entity_description: E.g. Atoms are treated as spherical entities in space with the radius and mass
                    # determined by the element type
                    "Entity_description": {"type": "string"},
                    # Equation: List of equations' description such as Equation of motion, heat balance, mass conservation.
                    # MODA PHYSICS EQUATIONS
                    "Equation": {"type": "array"},
                    # Equation_quantities: e.g. Force, mass, potential, energy, stress, heat, temperature.
                    "Equation_quantities": {"type": "array"},
                    # Relation_description: Describes equilibrium of forces on an infinitesimal element, etc.
                    "Relation_description": {"type": "array"},
                    # Relation_formulation: Constitutive equation (material relation), e.g. force field, stress-strain,
                    # flow-gradient. MODA MATERIAL RELATIONS
                    "Relation_formulation": {"type": "array"}
                },
                "required": ["Type", "Entity"]
            },
            "Solver": {
                "properties": {
                    # Software: Name of the software (e.g.openFOAM). Corresponds to MODA SOFTWARE TOOL
                    "Software": {"type": "string"},
                    "Language": {"type": "string"},
                    "License": {"type": "string"},
                    "Creator": {"type": "string"},
                    "Version_date": {"type": "string"},
                    # Type: Type e.g. finite difference method for Ordinary Differential Equations (ODEs)
                    # Corresponds to MODA Solver Specification NUMERICAL SOLVER attribute.
                    "Type": {"type": "string"},
                    # Solver_additional_params: Additional parameters of numerical solver, e.g. time integration scheme
                    "Solver_additional_params": {"type": "string"},
                    "Documentation": {"type": "string"},  # Where published/documented
                    "Estim_time_step_s": {"type": "number"},  # Seconds
                    "Estim_comp_time_s": {"type": "number"},  # Seconds
                    "Estim_execution_cost_EUR": {"type": "number"},  # EUR
                    "Estim_personnel_cost_EUR": {"type": "number"},  # EUR
                    "Required_expertise": {"type": "string", "enum": ["None", "User", "Expert"]},
                    "Accuracy": {"type": "string", "enum": ["Low", "Medium", "High", "Unknown"]},
                    "Sensitivity": {"type": "string", "enum": ["Low", "Medium", "High", "Unknown"]},
                    "Complexity": {"type": "string", "enum": ["Low", "Medium", "High", "Unknown"]},
                    "Robustness": {"type": "string", "enum": ["Low", "Medium", "High", "Unknown"]}
                },
                "required": [
                    "Software", "Language", "License", "Creator", "Version_date", "Type", "Documentation",
                    "Estim_time_step_s", "Estim_comp_time_s", "Estim_execution_cost_EUR", "Estim_personnel_cost_EUR",
                    "Required_expertise", "Accuracy", "Sensitivity", "Complexity", "Robustness"
                ]
            },
            "Execution": {
                "properties": {
                    "ID": {"type": ["string", "integer"]},  # Optional application execution ID (typically set by workflow)
                    # Use_case_ID: user case ID (e.g. thermo-mechanical simulation coded as 1_1)
                    "Use_case_ID": {"type": ["string", "integer"]},
                    # Task_ID: user task ID (e.g. variant of user case ID such as model with higher accuracy)
                    "Task_ID": {"type": "string"},
                    "Log_URI": {"type": "string"},
                    "Status": {"type": "string", "enum": ["Instantiated", "Initialized", "Running", "Finished", "Failed"]},
                    "Progress": {"type": "number"},  # Progress in %
                    "Date_time_start": {"type": "string"},  # automatically set in Workflow
                    "Date_time_end": {"type": "string"},  # automatically set in Workflow
                    "Timeout": {"type": "integer"},  # maximum runtime in seconds
                    "Username": {"type": "string"},  # automatically set in Model and Workflow
                    "Hostname": {"type": "string"}  # automatically set in Model and Workflow
                },
                "required": ["ID"]
            },
            "Inputs": {
                "type": "array",  # List
                "items": {
                    "type": "object",  # Object supplies a dictionary
                    "properties": {
                        "Type": {"type": "string", "enum": [
                            "mupif.Property",
                            "mupif.TemporalProperty",
                            "mupif.Field",
                            "mupif.TemporalField",
                            "mupif.HeavyStruct",
                            "mupif.PyroFile",
                            "mupif.String",
                            "mupif.ParticleSet",
                            "mupif.GrainState",
                            "mupif.PiecewiseLinFunction",
                            "mupif.DataList[mupif.Property]",
                            "mupif.DataList[mupif.TemporalProperty]",
                            "mupif.DataList[mupif.Field]",
                            "mupif.DataList[mupif.TemporalField]",
                            "mupif.DataList[mupif.HeavyStruct]",
                            "mupif.DataList[mupif.String]",
                            "mupif.DataList[mupif.ParticleSet]",
                            "mupif.DataList[mupif.GrainState]",
                            "mupif.DataList[mupif.PiecewiseLinFunction]"
                        ]},
                        "Type_ID": {"type": "string", "enum": type_ids},  # e.g. PID_Concentration
                        "Obj_ID": {  # optional parameter for additional info, string or list of string
                            "anyof": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}]
                        },
                        "Name": {"type": "string"},
                        "ValueType": {"type": "string", "enum": ["Scalar", "Vector", "Tensor", "ScalarArray", "VectorArray", "TensorArray"]},
                        "Description": {"type": "string"},
                        "Units": {"type": "string"},
                        "Required": {"type": "boolean"},
                        "Set_at": {"type": "string", "enum": ["initialization", "timestep"]},
                        "EDMPath": {"type": "string"},
                        "EDMList": {"type": "boolean"}
                    },
                    "required": ["Type", "Type_ID", "Name", "Units", "Required", "Set_at"],
                    "allOf": [
                        {
                            "anyOf": [
                                {"required": ["ValueType"]},
                                {"allOf": [
                                    {"not": {
                                        "properties": {
                                            "Type": {"const": "mupif.Property"}
                                        }
                                    }},
                                    {"not": {
                                        "properties": {
                                            "Type": {"const": "mupif.TemporalProperty"}
                                        }
                                    }}
                                ]}

                            ]
                        }
                    ]
                }
            },
            "Outputs": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "Type": {"type": "string", "enum": [
                            "mupif.Property",
                            "mupif.TemporalProperty",
                            "mupif.Field",
                            "mupif.TemporalField",
                            "mupif.HeavyStruct",
                            "mupif.PyroFile",
                            "mupif.String",
                            "mupif.ParticleSet",
                            "mupif.GrainState",
                            "mupif.PiecewiseLinFunction",
                            "mupif.DataList[mupif.Property]",
                            "mupif.DataList[mupif.TemporalProperty]",
                            "mupif.DataList[mupif.Field]",
                            "mupif.DataList[mupif.TemporalField]",
                            "mupif.DataList[mupif.HeavyStruct]",
                            "mupif.DataList[mupif.String]",
                            "mupif.DataList[mupif.ParticleSet]",
                            "mupif.DataList[mupif.GrainState]",
                            "mupif.DataList[mupif.PiecewiseLinFunction]"
                        ]},
                        "Type_ID": {"type": "string", "enum": type_ids},  # e.g. mupif.DataID.FID_Temperature
                        "Obj_ID": {  # optional parameter for additional info, string or list of string
                            "anyof": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}]
                        },
                        "Name": {"type": "string"},
                        "ValueType": {"type": "string", "enum": ["Scalar", "Vector", "Tensor", "ScalarArray", "VectorArray", "TensorArray"]},
                        "Description": {"type": "string"},
                        "Units": {"type": "string"},
                        "EDMPath": {"type": "string"},
                        "EDMList": {"type": "boolean"}
                    },
                    "required": ["Type", "Type_ID", "Name", "Units"],
                    "allOf": [
                        {
                            "anyOf": [
                                {"required": ["ValueType"]},
                                {"allOf": [
                                    {"not": {
                                        "properties": {
                                            "Type": {"const": "mupif.Property"}
                                        }
                                    }},
                                    {"not": {
                                        "properties": {
                                            "Type": {"const": "mupif.TemporalProperty"}
                                        }
                                    }}
                                ]}

                            ]
                        }
                    ]
                }
            }
        },
        "required": [
            "Name", "ID", "Description", "Physics", "Solver", "Execution", "Inputs", "Outputs"
        ]
    }

    # reduced
    WorkflowSchema = {}
    WorkflowSchema["properties"].update({
        "Dependencies": {  # This i automatically generated according to self._models List.
            "type": "array",  # List of contained models/workflows
            "items": {
                "type": "object",  # Object supplies a dictionary
                "properties": {
                    "Label": {"type": "string"},  # Explicit label, given to the model/workflow by its parent workflow.
                    "Name": {"type": "string"},  # Obtained automatically from Model metadata.
                    "ID": {"type": ["string", "integer"]},  # Obtained automatically from Model metadata.
                    "Version_date": {"type": "string"},  # Obtained automatically from Model metadata.
                    "Type": {"type": "string", "enum": ["Model", "Workflow"]},  # Filled automatically.
                    "Dependencies": {"type": "array"}  # Object supplies a dictionary
                },
                "required": ["Name", "ID", "Version_date", "Type"]
            }
        },
        "Models": {
            "type": "array",  # List of contained models/workflows definition
            "items": {
                "type": "object",  # Object supplies a dictionary
                "properties": {
                    "Name": {"type": "string"},  # specifies access to the model using self.getModel('Name')
                    "Module": {"type": "string"},
                    "Class": {"type": "string"},
                    "Jobmanager": {"type": "string"},
                    "Instantiate": {"type": "boolean"},
                },
                "required": ["Name"],
                "anyOf": [
                    {"required": ["Module", "Class"]},  # local module with the workflow class
                    {"required": ["Jobmanager"]}  # remote model
                ]
            }
        },
        "EDMMapping": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "Name": {"type": "string"},
                    "EDMEntity": {"type": "string"},
                    "DBName": {"type": "string"},
                    "createFrom": {"type": "string"},
                    "createNew": {"type": "object"},
                    "EDMList": {"type": "boolean"}
                },
                "required": ["Name", "EDMEntity", "DBName"]
            }
        },
    })
    WorkflowSchema["required"] = ["Name", "ID", "Description", "Execution", "Inputs", "Outputs", "Models"]


import cv2

img=cv2.imread('4018995.jpg',-1)
print(img)
cv2.imshow("image",img)
key=cv2.waitKey(0)
if key==27:
    cv2.destroyAllWindows()
elif key==ord('s'):
    cv2.imwrite("demonslayer.png",img)


# For simple dajax(ice) functionalities
from django.utils import simplejson
from dajaxice.decorators import dajaxice_register
from dajax.core import Dajax
from dajaxice.utils import deserialize_form
# For rendering templates
from django.template import RequestContext
from django.template.loader import render_to_string
# Decorators
from django.contrib.auth.decorators import login_required
from scripts.utility import show_alert
from post_office import mail
import json, datetime
from models import Badge

@dajaxice_register
def check_barcode(request, barcode):
    dajax=Dajax()
    try:
        badge = Badge.objects.get(barcode=barcode)
        if badge:
            if datetime.datetime.today().date().day is 11:
                if badge.rockshow == True:
                    return_message = badge.name + ' already entered'
                    return_type = 'error'
                else:
                    badge.rockshow = True
                    return_message = badge.name
                    return_type = 'success'
                    badge.save()
            elif datetime.datetime.today().date().day is 12:
                if badge.popular_night == True:
                    return_message = badge.name + ' already entered'
                    return_type = 'error'
                else:
                    badge.popular_night = True
                    return_message = badge.name
                    return_type = 'success'
                    badge.save()
            else:
                return_message = 'No show today'
                return_type = 'success'
        else:
            return_message = 'Barcode not found'
            return_type = 'error'
    except:
        return_message = 'Barcode not found'
        return_type = 'error'
    dajax.assign('#div_alert', 'innerHTML', "
"+return_message+"
")
    dajax.remove_css_class('#div_alert', 'error' if return_type is 'success' else 'success')
    dajax.add_css_class('#div_alert', return_type)
    dajax.script('reset_page();')
    return dajax.json()


from mlxtend.frequent_patterns import apriori, association_rules
from datetime import date
import pandas as pd
import json
import string
import mongoengine as me
import numpy as np
from datetime import datetime
from schema import Users
from schema import Preprocessed_Products

def encode_u(x):
    if x < 1:
        return 0
    else:
        return 1

def get_associated_products(frozen_list):
    associated_products = []

    for i in range(len(frozen_list)):
        if len(frozen_list[i]) == 1:
            value1, = frozen_list[i]
            associated_products.append(value1)

        if len(frozen_list[i]) == 2:
            (value1,value2) = frozen_list[i]
            associated_products.append(value1)
            associated_products.append(value2)

        if len(frozen_list[i]) == 3:
            (value1,value2,value3) = frozen_list[i]
            associated_products.append(value1)
            associated_products.append(value2)
            associated_products.append(value3)

        if len(frozen_list[i]) == 4:
            (value1,value2,value3,value4) = frozen_list[i]
            associated_products.append(value1)
            associated_products.append(value2)
            associated_products.append(value3)
            associated_products.append(value4)

        if len(frozen_list[i]) == 5:
            (value1,value2,value3,value4,value5) = frozen_list[i]
            associated_products.append(value1)
            associated_products.append(value2)
            associated_products.append(value3)
            associated_products.append(value4)
            associated_products.append(value5)

    x = np.array(associated_products)
    x_unique = np.unique(x)
    return list(x_unique)

def association_rule_mining():
    # load existing data
    basket = pd.read_csv('basket.csv')
    basket = basket.applymap(encode_u)
    basket['Id'] = ''

    for i in range(len(basket)):
        basket['Id'][i] = f'{i}'

    # load new data
    users = Users.objects[1:]
    users = json.loads(users.to_json())

    for i in range(len(users)):
        id = users[i]['_id']['$oid']

        if id not in basket['Id'].values:
            basket = basket.append(pd.Series(0, index=basket.columns), ignore_index=True)
            last_index = len(basket)-1
            basket['Id'][last_index] = id

            for j in range(len(users[i]['viewed'])):
                product = users[i]['viewed'][j]['name']
                basket[product][last_index] = 1

        else:
            for j in range(len(basket)):
                if basket["Id"][j] == id:
                    for k in range(len(users[i]['viewed'])):
                        product = users[i]['viewed'][k]['name']
                        basket[product][j] = 1

    # generate new rules
    bas = basket.loc[:, basket.columns!='Id']
    frequent_itemsets = apriori(bas, min_support=0.05, use_colnames=True)
    rules = association_rules(frequent_itemsets, metric="lift", min_threshold=1)
    new_rules = rules.sort_values(['lift','support'],ascending=False).reset_index(drop=True)

    ## Update Database
    # 1. empty associated_products
    for i in range(Preprocessed_Products.objects.count()):

        product = Preprocessed_Products.objects[i]
        count = len(product.associated_products)

        for j in range(count):
            product.associated_products.pop()
            product.save()

    # 2. insert new associated_products
    for i in range(Preprocessed_Products.objects.count()):
        product = Preprocessed_Products.objects[i]
        name = product.name

        frozen_list = []
        for i in range(len(rules)):
            if rules["antecedents"][i] == frozenset({name}):
                frozen_list.append(rules["consequents"][i])

        associated_products = get_associated_products(frozen_list)

        for j in range(len(associated_products)):
            product.associated_products.append(associated_products[j])
            product.save()

    # output to csv files
    bas.to_csv(f"basket.csv")

    # output to csv files for recording purpose
    today = date.today()
    bas.to_csv(f"Basket/basket_{today}.csv")
    new_rules.to_csv(f"Rules/rules_{today}.csv")


import pickle  # Сериализует любой python объект в строку
import numpy as np
from PIL import Image

# Сериализуем изображение
with open('picleExample.pkl', 'wb') as f:
    pickle.dump(np.array(Image.open('1.jpg')), f)
    pickle.dump(np.array(Image.open('3.jpg')), f)
    # f.close()

# Десериализуем
with open('picleExample.pkl', 'rb') as f:
    image1 = pickle.load(f)
    image2 = pickle.load(f)
    # f.close()

Image.fromarray(image1).show()
Image.fromarray(image2).show()

Book Python CV/src/1. Основы обработки изображений/1.3_pickle.py


from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QComboBox, QMenu
from dwarf.ui.widgets.list_view import DwarfListView

class Explorer(QWidget):

    def __init__(self, plugin):
        super().__init__()

        self.plugin = plugin
        self.adb = plugin.adb

        self.current_path = ''

        self.path_input = QComboBox(self)
        self.path_input.activated[str].connect(self.set_path)

        self.explorer = DwarfListView()
        self.explorer_model = QStandardItemModel(0, 6)
        self.explorer_model.setHeaderData(0, Qt.Horizontal, 'permissions')
        self.explorer_model.setHeaderData(1, Qt.Horizontal, 'uid')
        self.explorer_model.setHeaderData(2, Qt.Horizontal, 'gid')
        self.explorer_model.setHeaderData(3, Qt.Horizontal, 'size')
        self.explorer_model.setHeaderData(4, Qt.Horizontal, 'modified')
        self.explorer_model.setHeaderData(5, Qt.Horizontal, 'name')
        self.explorer.setModel(self.explorer_model)
        self.explorer.doubleClicked.connect(self._item_double_clicked)
        self.explorer.setContextMenuPolicy(Qt.CustomContextMenu)
        self.explorer.customContextMenuRequested.connect(self._on_context_menu)

        box = QVBoxLayout()
        box.addWidget(self.path_input)
        box.addWidget(self.explorer)
        self.setLayout(box)

    def set_path(self, path):
        if self.current_path == path:
            return

        self.current_path = path

        ls = self.adb.su_cmd('ls -al %s' % path)
        if ls and ls[:2] != 'ls':
            ls = ls.split('\n')[1:]

            self.path_input.clear()
            self.explorer_model.setRowCount(0)

            split = path.split('/')
            self.path_input.addItem(path)
            for i in range(1, len(split)):
                path = '/'.join(split[:-i])
                if path:
                    self.path_input.addItem(path)

            for line in ls:
                if line:
                    parts = line.split()
                    self.explorer_model.appendRow([
                        QStandardItem(parts[0]),
                        QStandardItem(parts[2]),
                        QStandardItem(parts[3]),
                        QStandardItem(parts[4]),
                        QStandardItem('%s %s' % (parts[5], parts[6])),
                        QStandardItem(parts[7]),
                    ])

    def _item_double_clicked(self, model_index):
        row = self.explorer_model.itemFromIndex(model_index).row()
        if row != -1:
            name = self.explorer_model.item(row, 5).text()
            if name == '..':
                path = '/'.join(self.current_path.split('/')[:-1])
            else:
                path = self.current_path + '/' + name

            ret = self.adb.su_cmd('cd %s' % path)
            if not ret:
                self.set_path(path)

    def _on_context_menu(self, pos):
        row = self.explorer.indexAt(pos).row()
        glbl_pt = self.explorer.mapToGlobal(pos)
        if row != -1:
            context_menu = QMenu(self)
            name = self.explorer_model.item(row, 5).text()
            context_menu.addAction('pull file', lambda: self._on_pull_file(name))
            context_menu.exec_(glbl_pt)

    def _on_pull_file(self, name):
        from PyQt5.QtWidgets import QFileDialog
        _file = QFileDialog.getSaveFileName(self.plugin.app, '', name)
        if _file[0]:
            path = self.current_path + '/' + name if self.current_path != '/' else self.current_path + name
            dwarf_temp = '/sdcard/.dwarf_temp'
            self.adb.su_cmd('cp -r %s %s' % (path, dwarf_temp))
            self.adb.pull(dwarf_temp, _file[0])
            self.adb.su_cmd('rm -rf %s' % dwarf_temp)


"""Based on Daniel Holden code from:
   A Deep Learning Framework for Character Motion Synthesis and Editing
   (http://www.ipab.inf.ed.ac.uk/cgvu/motionsynthesis.pdf)"""

import numpy as np
import os
import torch
import torch.nn as nn
import json
import my_tools
class ForwardKinematicsLayer(torch.nn.Module):
    """ Forward Kinematics Layer Class """
    def __init__(self, device=torch.device("cuda"), parents=None, positions=None):
        super().__init__()
        self.b_idxs = None

        if parents is None and positions is None:
            parents_json = "/viscam/u/jiamanli/github/hm-vae/utils/data/joint24_parents.json"
            pos_npy = "/viscam/u/jiamanli/github/hm-vae/utils/data/skeleton_offsets.npy"

            ori_parents_list = json.load(open(parents_json, 'r'))
            self.parents = []
            for p in ori_parents_list:
                self.parents.append(torch.LongTensor([p])[0].to(device))
            self.parents = torch.stack(self.parents).to(device) # K
            self.positions = torch.from_numpy(np.load(pos_npy)).float()[None, :, :].to(device) # 1 X 24 X 3
        else:
            self.parents = []
            for p in parents:
                self.parents.append(torch.LongTensor([p])[0].to(device))
            self.parents = torch.stack(self.parents).to(device) # K
            self.positions = torch.from_numpy(positions).float()[None, :, :].to(device)

        self.device = device

    def rotate(self, t0s, t1s):
        return torch.matmul(t0s, t1s)

    def identity_rotation(self, rotations):
        # rotations: bs X n_joints X rot_dim(3,4,6)
        diagonal = torch.diag(torch.tensor([1.0, 1.0, 1.0, 1.0])).to(self.device) # 4 X 4
        diagonal = torch.reshape(
            diagonal, torch.Size([1] * len(rotations.shape[:-1]) + [4, 4])) # 1 X 1 X 4 X 4
        ts = diagonal.repeat(rotations.shape[:-1] + torch.Size([1, 1]))
        return ts # bs X n_joints X 4 X 4

    def make_fast_rotation_matrices(self, positions, rotations):
        # positions: bs X n_joints X 3
        # rotations: bs X n_joints X rot_dim(6, 3 X 3)
        if rotations.size()[-1] == 3 and rotations.size()[-2] == 3:
            rot_matrices = rotations # bs X n_joints X 3 X 3
        elif rotations.size()[-1] == 6:
            rot_matrices = my_tools.rotation_matrix_from_ortho6d(rotations) # bs X n_joints X 3 X 3

        rot_matrices = torch.cat([rot_matrices, positions[..., None]], dim=-1) # bs X n_joints X 3 X 4
        zeros = torch.zeros(rot_matrices.shape[:-2] + torch.Size([1, 3])).to(self.device) # bs X n_joints X 1 X 3
        ones = torch.ones(rot_matrices.shape[:-2] + torch.Size([1, 1])).to(self.device) # bs X n_joints X 1 X 1
        zerosones = torch.cat([zeros, ones], dim=-1) # bs X n_joints X 1 X 4
        rot_matrices = torch.cat([rot_matrices, zerosones], dim=-2) # bs X n_joints X 4 X 4

        return rot_matrices # bs X n_joints X 4 X 4

    def rotate_global(self, parents, positions, rotations):
        locals = self.make_fast_rotation_matrices(positions, rotations) # bs X n_joints X 4 X 4
        if rotations.shape[-1] == 3 and rotations.shape[-2] == 3:
            rotations = rotations.view(rotations.shape[0], rotations.shape[1], -1) # bs X n_joints X 9
        globals = self.identity_rotation(rotations) # bs X n_joints X 4 X 4

        globals = torch.cat([locals[:, 0:1], globals[:, 1:]], dim=1) # bs X 1 X 4 X 4 cat with bs X (n_joints-1) X 4 X 4 --> bs X n_joints X 4 X 4
        b_size = positions.shape[0]
        if self.b_idxs is None:
            self.b_idxs = torch.LongTensor(np.arange(b_size)).to(self.device)
        elif self.b_idxs.shape[-1] != b_size:
            self.b_idxs = torch.LongTensor(np.arange(b_size)).to(self.device)

        for i in range(1, positions.shape[1]): # iterate n_joints
            globals[:, i] = self.rotate(
            globals[self.b_idxs, parents[i]], locals[:, i])

        return globals # bs X n_joints X 4 X 4

    def forward(self, rotations, positions=None, return_rot=False):
        # parents: a list, each element represent each joint's parent idx
        # positions: bs X n_joints X 3
        # rotations: bs X n_joints X rot_dim(6, 3 X 3)
        # Get the full transform with rotations for skinning
        bs = rotations.size()[0]
        if positions is None:
            positions = self.positions.repeat(bs, 1, 1)
        transforms = self.rotate_global(self.parents, positions, rotations) # bs X n_joints X 4 X 4
        coordinates = transforms[:, :, :3, 3] # bs X n_joints X 3

        if return_rot:
            return coordinates, transforms[:, :, :3, :3] # B X n_joint X 3 X 3
        else:
            return coordinates


import tensorflow as tf
import time
import numpy as np
from typing import Tuple
import wandb

class TrainLogger(tf.keras.callbacks.Callback):

    def __init__(self, checkpoint_manager: tf.train.CheckpointManager, image_log, save_every: int = 5, cycle_gan: bool = True):
        super(TrainLogger, self).__init__()
        self.is_cyclegan = cycle_gan
        self.train_start_time = 0
        self.train_end_time = 0
        self.current_epoch_start_time = 0
        self.epoch_times = []
        self.epoch = 0
        self.last_save_epoch = 0
        self.checkpoint_manager = checkpoint_manager
        self.save_interval = save_every
        self.image_data = image_log

    def on_epoch_begin(self, epoch, logs=None):
        self.current_epoch_start_time = time.time()
        self.epoch = epoch + 1

    def on_epoch_end(self, epoch, logs=None):
        epoch_time = time.time() - self.current_epoch_start_time
        self.epoch_times.append(epoch_time)

        if self.is_cyclegan:

            i2t_images = [((self.model.i2t_generator.predict(image[tf.newaxis], verbose=0).reshape((256, 256, 3)) + 1) * 127.5).astype(int) for image in self.image_data[0]]
            t2i_images = [((self.model.t2i_generator.predict(image[tf.newaxis], verbose=0).reshape((256, 256, 3)) + 1) * 127.5).astype(int) for image in self.image_data[1]]

            wandb.log({
                "input_domain_gt": [wandb.Image(image) for image in self.image_data[0]],
                "target_domain_generated": [wandb.Image(i2t_image) for i2t_image in i2t_images],
                "target_domain_gt": [wandb.Image(image) for image in self.image_data[1]],
                "input_domain_generated": [wandb.Image(t2i_image) for t2i_image in t2i_images],
                "i2t_learning_rate": tf.keras.backend.get_value(self.model.i2t_generator_optimizer.lr),
                "t2i_learning_rate": tf.keras.backend.get_value(self.model.t2i_generator_optimizer.lr),
                "input_discr_learning_rate": tf.keras.backend.get_value(self.model.input_domain_discriminator_optimizer.lr),
                "target_discr_learning_rate": tf.keras.backend.get_value(self.model.target_domain_discriminator_optimizer.lr),
                **logs
            })

        else:
            t_images = [((self.model.generator.predict(image[tf.newaxis], verbose=0).reshape((256, 256, 3)) + 1) * 127.5).astype(int) for image in self.image_data[0]]

            wandb.log({
                "input_gt": [wandb.Image(image) for image in self.image_data[0]],
                "target_domain_generated": [wandb.Image(t_image) for t_image in t_images],
                **logs
            })

        if (epoch + 1) % self.save_interval == 0:
            self.checkpoint_manager.save()
            self.last_save_epoch = epoch

    def on_train_begin(self, logs=None):
        self.train_start_time = time.time()

    def on_train_end(self, logs=None):
        self.train_end_time = time.time()
        print(f"\nTraining took {self.train_end_time - self.train_start_time:.2f}s,"
              f" with {np.mean(self.epoch_times):.2f}s per epoch on average"
              f"\nTraining ended on epoch {self.epoch}")


import json
import time
import os
import random
import string
import ctypes

try:
    import pystyle
    import colored
    import requests
    import tls_client
    import threading
    import httpx
    import datetime
except ModuleNotFoundError:
    os.system('pip install pystyle')
    os.system('pip install colored')
    os.system('pip install requests')
    os.system('pip install tls_client')
    os.system('pip install threading')
    os.system('pip install httpx')
    os.system('pip install datetime')

from colored import fg
from pystyle import Write, System, Colors, Colorate
from tls_client import Session
from string import digits

lock = threading.Lock()
proxy_count = len(open('proxies.txt').readlines())
blue = fg(6)
reset = fg(7)
red = fg(1)
green = fg(2)
purple = fg(5)
pink = fg(216)
yellow = fg(226)
gray = fg(250)
views_sent = 0

def get_time_rn():
    date = datetime.datetime.now()
    hour = date.hour
    minute = date.minute
    second = date.second
    timee = "{:02d}:{:02d}:{:02d}".format(hour, minute, second)
    return timee

def save_proxies(proxies):
    with open("proxies.txt", "w") as file:
        file.write("\n".join(proxies))

def get_proxies():
    with open('proxies.txt', 'r', encoding='utf-8') as f:
        proxies = f.read().splitlines()
    if not proxies:
        proxy_log = {}
    else:
        proxy = random.choice(proxies)
        proxy_log = {
            "http://": f"http://{proxy}", "https://": f"http://{proxy}"
        }
    try:
        url = "https://api.proxyscrape.com/v2/?request=getproxies&protocol=http&timeout=10000&country=all"
        time_rn = get_time_rn()
        response = httpx.get(url, proxies=proxy_log, timeout=60)

        if response.status_code == 200:
            proxies = response.text.splitlines()
            save_proxies(proxies)
            print(f"{reset}{time_rn} {pink}| {reset}[ {pink}Proxy-Worker{reset} ] Success {purple}>{green} Scrapped Proxies {reset}[{pink} Total : {len(proxies)} {reset}]")
        else:
            print(f"{reset}{time_rn} {pink}| {reset}[ {pink}Proxy-Worker{reset} ] Error {purple}>{red} Failed Getting Proxies...")
            time.sleep(3)
            get_proxies()
    except httpx.ProxyError:
        pass
    except httpx.ReadError:
        pass
    except httpx.ConnectTimeout:
        pass
    except httpx.ReadTimeout:
        pass
    except httpx.ConnectError:
        pass
    except httpx.ProtocolError:
        pass

def check_proxy_count():
    with open("proxies.txt", "r") as file:
        lines = file.readlines()
        proxy_count = len(lines)
        time_rn = get_time_rn()
        if proxy_count < 105:
            print(f"{reset}{time_rn} {pink}| {reset}[ {pink}Proxy-Worker{reset} ] Warning {purple}>{yellow} You're close to running out of proxies.")
            print(f"{reset}{time_rn} {pink}| {reset}[ {pink}Proxy-Worker{reset} ] Re-Fill {purple}>{yellow} Filling proxies.txt with fresh and new proxies...")
            time.sleep(1.5)
            get_proxies()
        else:
            pass

def view_booster():
    check_proxy_count()
    thread_name = threading.currentThread().getName()
    with open("config.json") as f:
        data = json.load(f)
        github_link = data.get('github_link')
    global views_sent
    while True:
        ctypes.windll.kernel32.SetConsoleTitleW(f'Github Profile View Booster | By H4cK3dR4Du#0001 | Views Sent : {views_sent}')
        date = datetime.datetime.now()
        hour = date.hour
        minute = date.minute
        second = date.second
        time_rn = "{:02d}:{:02d}:{:02d}".format(hour, minute, second)
        with open('proxies.txt', 'r', encoding='utf-8') as f:
            proxies = f.read().splitlines()
        if not proxies:
            print(f"{reset}{time_rn} {pink}| {reset}[ {pink}{thread_name}{reset} ] Error {purple}>{red} No Proxy Found!")
            proxy_log = {}
        else:
            proxy = random.choice(proxies)
            proxy_log = {
                "http://": f"http://{proxy}", "https://": f"http://{proxy}"
            }
            print(f"{reset}{time_rn} {pink}| {reset}[ {pink}{thread_name}{reset} ] Loaded Proxy {purple}>{reset} {proxy}")
        try:
            response = httpx.get(github_link, proxies=proxy_log, timeout=20)
            if response.status_code == 200:
                date = datetime.datetime.now()
                hour = date.hour
                minute = date.minute
                second = date.second
                time_rn = "{:02d}:{:02d}:{:02d}".format(hour, minute, second)
                views_sent += 1
                print(f"{reset}{time_rn} {pink}| {reset}[ {pink}{thread_name}{reset} ] Success {purple}>{green} Sent View {reset}[{pink} Total : {views_sent} {reset}]")
            else:
                print(f"{reset}{time_rn} {pink}| {reset}[ {pink}{thread_name}{reset} ] Error {purple}>{red} Bad Gateaway 502")
        except httpx.ProxyError:
            print(f"{reset}{time_rn} {pink}| {reset}[ {pink}{thread_name}{reset} ] Bad Proxy {purple}> {red}{proxy} {reset}| [{pink}REMOVED{reset}]")
            with open('proxies.txt', 'r') as f:
                lines = f.readlines()
            with open('proxies.txt', 'w') as f:
                for line in lines:
                    if proxy not in line:
                        f.write(line)
        except httpx.ReadError:
            continue
        except httpx.ConnectTimeout:
            continue
        except httpx.ReadTimeout:
            continue
        except httpx.ConnectError:
            continue
        except httpx.ProtocolError:
            continue
        except ValueError:
            print(f"{reset}{time_rn} {pink}| {reset}[ {pink}{thread_name}{reset} ] Error {purple}> {red}Invalid Github Camo Link...")

def run():
    while True:
        view_booster()

with open("config.json") as f:
    data = json.load(f)

num_threads = data.get('threads', 250)
threads = []
for i in range(int(num_threads)):
    thread = threading.Thread(target=run, name=f"VIEW_BOOSTER-{i+1}")
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()


import requests
import pathlib
import pdal
import json
import pyproj
import pandas as pd
from shapely.geometry.polygon import Polygon
from sklearn.cluster import DBSCAN
import numpy as np

def pipeline_to_df(pipeline_):
    pipeline = pdal.Pipeline(json.dumps(pipeline_))
    pipeline.validate()
    pipeline.execute()
    arr = pipeline.arrays[0]
    description = arr.dtype.descr
    cols = [col for col, __ in description]
    df = pd.DataFrame({col: arr[col] for col in cols})
    df['X_0'] = df['X']
    df['Y_0'] = df['Y']
    df['Z_0'] = df['Z']
    df['X'] = df['X'] - df['X_0'].min()
    df['Y'] = df['Y'] - df['Y_0'].min()
    df['Z'] = df['Z'] - df['Z_0'].min()
    return df

def address_to_lazfile(address):
    f = open('all_workunits.txt')
    all_wu_data = f.read()
    f.close()
    workunits = [wu.strip().strip("/").strip("PRE").strip() for wu in all_wu_data.split("\n")]
    y = requests.post('https://protected-peak-85531.herokuapp.com/parcel_info', params={'address': address})
    parcel_info = y.json()
    z = requests.get('https://protected-peak-85531.herokuapp.com/get_point_cloud_workunits', params={'address': address})
    recieved_units = z.json()

    filename_original = "models/model_" + str(parcel_info["gisparcel_id"]) + '_original.laz'
    # filename_added_attributes = "models/model_" + str(parcel_info["gisparcel_id"]) + '_added_attributes.laz'
    # filename_buildings = "models/model_" + str(parcel_info["gisparcel_id"]) + '_buildings.laz'

    p = pathlib.Path(filename_original)

    if p.is_file():
        return filename_original

    f = open(filename_original, "w")
    f.close()
    matching_units = []
    for ru in recieved_units:
        for wu in workunits:
            if ru in wu:
                matching_units.append(wu)

    wu_link = matching_units[0]

    polygon_array = json.loads(parcel_info['polygon_details']['st_asgeojson'])['coordinates'][0][0]
    polygon_4326 = Polygon(polygon_array)
    polygon_4326_bounds = polygon_4326.bounds
    wsg84 = pyproj.Proj(init='epsg:4326')
    lambert = pyproj.Proj(init='epsg:3857')
    coords = [pyproj.transform(wsg84,lambert,x,y) for (x,y) in polygon_array]
    polygon = Polygon(coords)
    print(polygon.wkt)
    b = polygon.bounds
    cropper = {
    "pipeline": [
        {
            "bounds": str(([b[0], b[2]],[b[1], b[3]])),
            "filename": "ept://https://s3-us-west-2.amazonaws.com/usgs-lidar-public/" + wu_link,
            "type": "readers.ept",
            "tag": "readdata"
        },
        {   "type":"filters.crop",
            'polygon':polygon.wkt
        },
        {
            "filename": filename_original,
            "tag": "writerslas",
            "type": "writers.las"
        }
    ]}

    pipeline = pdal.Pipeline(json.dumps(cropper))
    pipeline.validate()
    n_points = pipeline.execute()
    return filename_original

def get_df_with_added_attributes(lazfile_path):
    reader = {
        "pipeline": [
            {
                "filename": lazfile_path,
                "type": "readers.las",
                "tag": "readdata"
            },
            {
                "type":"filters.smrf"
            },
            {
                "type":"filters.hag_nn"
            },
            {   "type":"filters.eigenvalues",
                "knn":16},
            {   "type":"filters.normal",
                "knn":16},
            {
                "type":"filters.approximatecoplanar",
                "knn":16
            },
            {
                "type":"filters.reciprocity",
                "knn":16
            }
        ]}
    return pipeline_to_df(reader)

def get_df_building_filtered(lazfile_path):
    reader = {
        "pipeline": [
            {
                "filename": lazfile_path,
                "type": "readers.las",
                "tag": "readdata"
            },
            {
                "type":"filters.smrf"
            },
            {
                "type":"filters.hag_nn"
            },
            {   "type":"filters.eigenvalues",
                "knn":16},
            {   "type":"filters.normal",
                "knn":16},
            {
                "type":"filters.approximatecoplanar",
                "knn":16
            },
            {
                "type":"filters.reciprocity",
                "knn":16
            },
            {
                "type":"filters.python",
                "add_dimension": "roof=int32",
                "script":"custom_filter.py",
                "function":"get_roof",
                "module":"anything"
            },

            {
                "type":"filters.range",
                "limits":"roof[1:1]"
            },
            {
                "type":"filters.outlier",
                "method":"statistical",
                "mean_k":200,
                "multiplier":0.8
            },
            {
                "type":"filters.range",
                "limits":"Classification![7:7]"
            },
            {
                "type":"filters.dbscan",
                "min_points":10,
                "eps":2.0,
                "dimensions":"X,Y,Z"
            },
        ]}
    return pipeline_to_df(reader)

def get_largest_building_df(lazfile_path):
    df = get_df_building_filtered(lazfile_path)
    df_n = df[df['Classification'] != 7]
    cluster_density = df_n['ClusterID'].value_counts()/df_n['ClusterID'].shape[0]
    if -1 in list(cluster_density.keys()):
        cluster_density.drop([-1], inplace=True)
    fcd = cluster_density.where(cluster_density > 0.1).dropna()
    print("Number of Structures: ", fcd.shape[0])
    largest_str_cluster = fcd.idxmax()
    other_str_clusters = [n for n in list(fcd.keys()) if n != largest_str_cluster]
    print("No of points:", df[df['ClusterID'] == largest_str_cluster].shape[0])
    print("Highest point of Building: ", df[df['ClusterID'] == largest_str_cluster]['HeightAboveGround'].max())
    print("Lowest point of Building: ", df[df['ClusterID'] == largest_str_cluster]['HeightAboveGround'].min())
    print("Avg height from gorund: ", df[df['ClusterID'] == largest_str_cluster]['HeightAboveGround'].mean())
    building_df = df[df['ClusterID'] == largest_str_cluster]
    return building_df

def get_separated_roof_labeled_building_data(building_df):
    df_copy = pd.DataFrame().reindex_like(building_df)
    dfs = []
    normals_to_points = building_df[['NormalX', 'NormalY', 'NormalZ']]
    clustering = DBSCAN(eps=0.01).fit(normals_to_points)
    building_df['labels_normal'] = clustering.labels_
    percentage_clusters = dict(building_df['labels_normal'].value_counts()/building_df.shape[0]*100)
    imp_points = {k:v for k,v in percentage_clusters.items() if v > 1 and k > -1}
    imp_clusters = imp_points.keys()
    i = 0
    for cluster_number in imp_clusters:
        df_cluster = building_df[building_df['labels_normal'] == cluster_number]
        Y = df_cluster[['X', 'Y']]
        spatial_clustering = DBSCAN(eps=3).fit(Y)
        df_cluster['labels_spatial'] = spatial_clustering.labels_
        for spatial_cluster in np.unique(spatial_clustering.labels_):
            df_spatial_cluster = df_cluster[df_cluster['labels_spatial'] == spatial_cluster]
            df_spatial_cluster['df_spatial_cluster'] = i
            building_df['labels_spatial'] = df_spatial_cluster['labels_spatial']
            dfs.append(df_spatial_cluster)
            i = i + 1
        final_df = pd.concat(dfs)
        return final_df


from django.urls import path
from RMenu import views

urlpatterns = [
    path('', views.index, name='index'),
    path('show_restaurants/', views.show_restaurants, name='show_restaurants'),
    path('add_restaurant/', views.add_restaurant, name='add_restaurant'),
    path('<int:id>/update_restaurant/', views.update_restaurant, name='update_restaurant'),
    path('<int:id>/delete_restaurant/', views.delete_restaurant, name='delete_restaurant'),
]


from django.shortcuts import render
from django.shortcuts import redirect
from django.shortcuts import get_object_or_404
from django.shortcuts import HttpResponse

from .models import Question, Submission, Image, File
from teams.models import Team

def question(request, question_id):
    this_question = get_object_or_404(Question, id=question_id)

    team_id = request.session.get('team_id', None)
    try:
        team = Team.objects.get(id=team_id)
    except Team.DoesNotExist:
        return redirect('/login')

    if request.method == 'GET':
        all_questions = Question.objects.all()

        images = Image.objects.filter(question_id=question_id)
        files = File.objects.filter(question_id=question_id)

        submissions = Submission.objects.filter(team_id=team_id)
        score = sum(map(lambda s: s.question.points, submissions))

        # score = 0
        # for submission in submissions:
        #     score += submission.question.points

        questions_answered = set(map(lambda s: s.question.id, submissions))

        # questions_answered = set()
        # for submission in submissions:
        #     questions_answered.add(submission.question.id)

        return render(request, 'questions/question.html', {
            'this_question': this_question,
            'all_questions': all_questions,
            'questions_answered': questions_answered,
            'teamname': team.teamname,
            'score': score,
            'images': images,
            'files': files
        })
    else:
        answer = request.POST.get("answer", None)
        if answer == this_question.answer:
            try:
                Submission.objects.get(team_id=team_id, question_id=question_id)
                return redirect(f'/question/{question_id}')
            except Submission.DoesNotExist:
                submission = Submission()

                submission.question = this_question
                submission.team = team

                submission.save()
                return redirect(f'/question/{question_id}')
        else:
            return redirect(f'/question/{question_id}')

def leaderboard(request):
    teams = Team.objects.all()
    # [(teamname, participant1, participant2, score), (...), ...]
    data = []
    for team in teams:
        submissions = Submission.objects.filter(team_id=team.id)
        score = sum(map(lambda s: s.question.points, submissions))
        data.append((team.teamname, team.name1, team.name2, score))

    data.sort(key=lambda x: x[3], reverse=True)

    return render(request, 'questions/leaderboard.html', {
        'teams': data
    })


"""Basic evolutionary model.

This model server as a common framework to all other evolutionary
algorithms in this package.
"""
import typing as t
import abc

import matplotlib.pyplot as plt
import numpy as np

_InstType = t.Union[float, np.ndarray, np.number, int]
_DeltaFuncType = t.Callable[..., t.Union[int, float]]
_DictArgType = t.Dict[str, t.Any]

class EvoBasic:
    """Basic evolutionary model framework."""

    def __init__(
            self,
            inst_range_low: _InstType,
            inst_range_high: _InstType,
            fitness_func: t.Callable[[_InstType], t.Union[int, float]],
            fitness_func_args: t.Optional[_DictArgType] = None,
            gene_num: int = 2,
            pop_size_parent: int = 128,
            pop_size_offspring: t.Optional[int] = None,
            gen_num: int = 10,
            mutation_prob: t.Optional[_InstType] = None,
            mutation_delta_func: t.Optional[
                t.Union[_DeltaFuncType, t.Sequence[_DeltaFuncType]]] = None,
            mutation_func_args: t.Optional[
                t.Union[_DictArgType, t.Sequence[_DictArgType]]] = None,
            gen_range_low: t.Optional[_InstType] = None,
            gen_range_high: t.Optional[_InstType] = None,
            overlapping_pops: bool = True,
            merge_populations: bool = False,
            selection_parent: str = "uniform",
            selection_parent_args: t.Optional[_DictArgType] = None,
            selection_target: str = "uniform",
            selection_target_args: t.Optional[_DictArgType] = None,
            reproduction: str = "asexual",
            reproduction_func: t.Optional[t.Callable[..., np.ndarray]] = None,
            reproduction_func_args: t.Optional[_DictArgType] = None,
    ):
        """Init the basic evolutionary algorithm framework.

        Arguments
        ---------
        inst_range_low : :obj:`np.ndarray` or :obj:`float`
            A scalar or numpy array for the lower bound for the genes
            (attributes) values. If a single number is given, the same
            lower bound will be used for all genes (attributes). If a
            numpy array is given, each position of the array must be
            the lower bound for the corresponding gene (i.e., the
            lower bound array must have dimension (gene_num,).)

        inst_range_high : :obj:`np.ndarray` or :obj:`float`
            The same as ``inst_range_low`` argument, but for the upper
            bound gene limit.

        fitness_func : callable
            Fitness function. Must receive a chromosome (instance) and
            return its respective fitness as a scalar value.

        fitness_func_args : dict, optional
            Extra arguments to the fitness function. If None, only the
            chromosome will be passed as argument to ``fitness_func``.

        gene_num : :obj:`int`, optional
            Number of genes for each chromosome, or the dimension of each
            instance/sample/individual.

        pop_size_parent : :obj:`int`, optional
            Size of the parent population. The greater is this number, the
            more parallelism (and less variance) is injected into the
            evolutionary algorithm search space.

        pop_size_offspring : :obj:`int`, optional
            Size of the offspring population, or the number of new samples
            (chromosomes) created in every evolutionary algorithm run (note
            that this is NOT the same as the number of offsprings in each
            generation.) The greater is this number, the more `delay` is
            injected into considering the information generated by the
            offsprings to generate new solutions. If None, then the
            offspring population size will have the same value given by
            ``pop_size_parent``.

        gen_num : :obj:`int`, optional
            Number of generations to run the evolutionary algorithm. One
            generation is defined as `number of new offsprings equal to
            the size of the parent population.`
            - If ``pop_size_parent`` > ``pop_size_offspring``, then the
            evolutionary algorithm is run more the once every generation.
            - If ``pop_size_parent`` == ``pop_size_offspring``, then the
            evolutionary algorithm is run exactly once every generation.
            - If ``pop_size_parent`` < ``pop_size_offspring``, then more
            than one generation is affected per evolutionary algorithm
            run.

        mutation_prob : :obj:`np.ndarray` or :obj:`float`, optional
            A scalar or numpy array giving the probability of mutation
            for each gene (attribute). If a single number is given,
            the same mutation probability is used to all genes. If an
            array is given, each position must be the mutation probability
            for the corresponding gene.

        mutation_delta_func : callable or a sequence of callables, optional
            Sampler of a distribution to generate the gene mutations.
            - If a single sampler is given, the same sampler will be used
            to generate mutation for all genes.
            - If a sequence is given, each position must generate the
            mutation for the corresponding gene.
            - If None given (None), then the mutation values will be drawn
            from a normal distribution of mean 0 and variance 1, for all
            genes.

        mutation_func_args : dict or a sequence of dicts, optional
            Arguments for the ``mutation_delta_func`` functions.
            - If a single dictionary is given, the same set of arguments
            will be given to every mutation function.
            - If a sequence of dictionary is given, then each position
            must kept the argumnets for each mutation function.
            - If None, no arguments will be passed to any mutation function.

            Note that, if this argument is not None, then the length of this
            argument must be either 1 (one dictionary), or match the length
            of the ``mutation_delta_func`` argument, if it is a sequence.

        gen_range_low : :obj:`np.ndarray` or :obj:`float`, optional
            The same as ``inst_range_low`` argument, but used only during the
            generation of the very first generation. If None, then the same
            value given by ``inst_range_low`` will be used.

        gen_range_high : :obj:`np.ndarray` or :obj:`float`, optional
            Same as ``gen_range_low``, but using ``inst_range_high`` as
            reference.

        overlapping_pops : :obj:`bool`, optional
            If True, make the offsprings compete with the parent generation
            a place into the next generation. If False, all the parent
            generation is replaced with a subset of the offspring generation.

        merge_populations : :obj:`bool`, optional
            If True, merge the parent and offspring populations before
            applying the selection scheme defined by ``selection_target``
            (see this argument below.)

        selection_parent : :obj:`str`, optional
            Scheme used to select individuals from the parent generation to
            reproduce. In order of increasing competition pressure, this
            argument must assume one value from the following list:
                1. `deterministic` (least pressure applied)
                2. `uniform`
                3. `fitness-prop`
                4. `k-power Ranking`
                5. `k-sized Tournament`
                6. `truncation` (tipically the most pressure applied)

        selection_parent_args : dict, optional
            Arguments for the ``selection_parent`` selected selection scheme.
            The following arguments can be customized:
                3. K-power Ranking:
                    - `power`: exponent coeffiecient to the ranking values. The
                        higher is this value, the more probability mass will
                        be focused on the chromosomes with larger fitness,
                        thus increasing the elitism factor in the selection.

                3. K-sized tournament:
                    - `size`: Size of the subsample of the current population to
                        choose the chromosome with the largest fitness, which
                        will be the chromosome chosen to reproduce.

        selection_target : :obj:`str`, optional
            The same as ``selection_parent``, but focused on:
                - If ``overlapping_pops`` is True, this argument defines the
                selection scheme used to select the target instances, selected
                to compete with the newly generated offsprings.
                - If ``overlapping_pops`` is False, this argument defines the
                selection scheme used to selected the offspring that will
                compete for a place into the next generation, with replacement
                (i.e., the same offspring chromosome may be replicated in the
                next generation, depending on the selection scheme chosen.)

        selection_target_args : dict, optional
            The same as ``selection_parent_args``, but for the ``selection_target``
            argument.

        reproduction : :obj:`str`, optional
            The type of reproduction. Must be either `sexual` or `asexual`.

        reproduction_func : callable, optional
            Reproduction function. If None, then `np.copy` is used by default
            (i.e., each offspring is exactly the copy of its parent.) If
            `reproduction` is `sexual`, then the first argument for this
            function will be a single chromosome. Othwerwise, it will be
            a two dimensional numpy array with each parent as different
            row.

        reproduction_func_args : dict, optional
            Extra arguments for the `reproduction_func` callable.
        """
        if not overlapping_pops and merge_populations:
            raise ValueError("'merge_populations' can't be True with "
                             "'overlapping_pops' being False.")

        VALID_SELECTIONS = ("deterministic", "uniform", "fitness-prop",
                            "tournament", "ranking", "truncation")

        if selection_parent not in VALID_SELECTIONS:
            raise ValueError("'selection_parent' ({}) not in {}.".format(
                selection_parent, VALID_SELECTIONS))

        if selection_target not in VALID_SELECTIONS:
            raise ValueError("'selection_target' ({}) not in {}.".format(
                selection_target, VALID_SELECTIONS))

        VALID_REPRODUCTION = ("sexual", "asexual")

        if reproduction not in VALID_REPRODUCTION:
            raise ValueError("'reproduction' ({}) not in {}.".format(
                selection_target, VALID_REPRODUCTION))

        self.fitness_func = fitness_func

        if fitness_func_args is None:
            fitness_func_args = {}

        if not np.isscalar(
                fitness_func(
                    np.zeros(gene_num, dtype=float), **fitness_func_args)):
            raise TypeError("'fitness_func' must return a scalar.")

        if pop_size_parent <= 0:
            raise ValueError("'pop_size_parent' must be positive (got {}.)".
                             format(pop_size_parent))

        if gene_num <= 0:
            raise ValueError(
                "'gene_num' must be positive (got {}.)".format(gene_num))

        if gen_num <= 0:
            raise ValueError(
                "'gen_num' must be positive (got {}.)".format(gen_num))

        if (not np.isscalar(inst_range_low) and inst_range_low.size > 1
                and inst_range_low.size != gene_num):
            raise ValueError("'inst_range_low' size ({}) does not match "
                             "with the instance dimension ({}). It must "
                             "be either 1 or assume the same size as the "
                             "'gene_num' argument.".format(
                                 inst_range_low.size, gene_num))

        if (not np.isscalar(inst_range_high) and inst_range_high.size > 1
                and inst_range_high.size != gene_num):
            raise ValueError("'inst_range_high' size ({}) does not match "
                             "with the instance dimension ({}). It must "
                             "be either 1 or assume the same size as the "
                             "'gene_num' argument.".format(
                                 inst_range_high.size, gene_num))

        if pop_size_offspring is None:
            pop_size_offspring = pop_size_parent

        if pop_size_offspring <= 0:
            raise ValueError("'pop_size_offspring' must be positive "
                             "(got {}.)".format(pop_size_offspring))

        if reproduction_func_args is None:
            reproduction_func_args = {}

        self.reproduction = reproduction
        self.reproduction_func = reproduction_func if reproduction_func else np.copy
        self.pop_size_parent = pop_size_parent
        self.pop_size_offspring = pop_size_offspring
        self.gene_num = gene_num
        self.gen_num = gen_num
        self.overlapping_pops = overlapping_pops
        self.merge_populations = merge_populations
        self.fitness_func_args = fitness_func_args.copy()
        self.reproduction_func_args = reproduction_func_args.copy()

        if mutation_prob is None:
            mutation_prob = 1.0 / self.gene_num

        if np.any(not 0 <= mutation_prob <= 1):
            raise ValueError("'mutation_prob' must be in [0, 1] range "
                             "(got {}.)".format(mutation_prob))

        self.inst_range_low = np.copy(inst_range_low)
        self.inst_range_high = np.copy(inst_range_high)

        self.selection_parent = selection_parent
        self.selection_target = selection_target

        self.selection_parent_args = self._build_selection_args(
            args=selection_parent_args, scheme=self.selection_parent)

        self.selection_target_args = self._build_selection_args(
            args=selection_target_args, scheme=self.selection_target)

        if gen_range_low is None:
            gen_range_low = self.inst_range_low

        if gen_range_high is None:
            gen_range_high = self.inst_range_high

        self.gen_range_low = gen_range_low
        self.gen_range_high = gen_range_high

        self.population = np.array([])
        self.fitness = np.array([])
        self.timestamps = np.array([])

        self.best_inst_id = -1
        self.best_inst = np.array([])
        self.best_inst_fitness = -np.inf
        self._fitness_cur_best_avg = -np.inf
        self._fitness_cur_best_std = 0.0

        self._online_plot = False
        self._time = -1
        self._alg_name = None

        self._plt_config = {}

        self._config_plot(online=False)

        if np.isscalar(mutation_prob):
            self.mutation_prob = np.full(
                shape=self.gene_num, fill_value=mutation_prob)

        else:
            self.mutation_prob = np.copy(mutation_prob)

        if mutation_delta_func is None:
            mutation_delta_func = (
                lambda loc=0.0, scale=1.0: np.random.normal(loc=loc, scale=scale))

        if mutation_func_args is None:
            mutation_func_args = {}

        if callable(mutation_delta_func):
            self.mutation_delta_func = [
                mutation_delta_func for _ in np.arange(self.gene_num)
            ]

        else:
            self.mutation_delta_func = mutation_delta_func

        if isinstance(mutation_func_args, dict):
            mutation_func_args = mutation_func_args.copy()
            self.mutation_func_args = [
                mutation_func_args for _ in np.arange(self.gene_num)
            ]

        else:
            self.mutation_func_args = mutation_func_args

        if len(self.mutation_func_args) != len(self.mutation_delta_func):
            raise ValueError("Length of 'mutation_func_args' ({}) and "
                             "'mutation_delta_func' ({}) differs.".format(
                                 len(self.mutation_func_args),
                                 len(self.mutation_delta_func)))

    @classmethod
    def _build_selection_args(cls, args: t.Optional[t.Dict[str, t.Any]],
                              scheme: str) -> t.Dict[str, t.Any]:
        """Build default argument list for selection schemes."""
        if args is not None: args = args.copy()
        else: args = {}

        if scheme == "tournament":
            args.setdefault("size", 2)

        elif scheme == "ranking":
            args.setdefault("power", 1)

        return args

    def run(self,
            random_state: t.Optional[int] = None,
            verbose: bool = False,
            return_solution: bool = False,
            avg_range: int = 16,
            time_invariant_fitness: bool = True,
            plot: bool = False,
            replot_fitness_contour: bool = False,
            plot_pause: float = 0.01,
            plot_contour_points: int = 32) -> np.ndarray:
        """Run the selected evolutionary algorithm.

        Arguments
        ---------
        random_state : :obj:`int`, optional
            If given, set the random seed before any pseudo-random number
            generation, to keep the results reproducible.

        verbose : :obj:`bool`, optional
            If True, print information related to every epoch.

        return_solution : :obj:`np.ndarray`, optional
            If True, return the chromosome (instance) with the best fitness.
            If False, return the whole population after the algorithm
            execution.

        avg_range : :obj:`int`, optional
            Number of most recent parent population fitness average and
            standard deviation to be kept.

        time_invariant_fitness : :obj:`bool`, optional
            If False, recalculate the population fitness every algorithm
            execution. If your fitness function is not time invariant,
            set this argument to True. Otherwise, keep it False to avoid
            unnecessary extra calculations, and improve performance.

        plot : :obj:`bool`, optional
            If True, do online plotting during the algorithm execution.

        replot_fitness_contour : :obj:`bool`, optional
            If True, replot the fitness function contour plot. It may be
            extremely computation expensive depending on the defined
            function limits and the fitness function complexity.

        plot_pause : :obj:`float`, optional
            Used only if ``plot`` is True. Number of seconds to wait
            before every epoch plot.

        plot_contour_points : :obj:`int`, optional
            Number of points, for each dimension, for the contour plot.
            The higher is this value, the more precise will be the contour
            plot.

        Returns
        -------
        np.ndarray
            If ``return_solution`` is True:
            - Return the chromosome (instance) with the best fitness.
            If ``return_solution`` is False:
            - Return the whole population after the algorithm execution.
        """
        if random_state is not None:
            np.random.seed(random_state)

        self.population = np.random.uniform(
            low=self.gen_range_low,
            high=self.gen_range_high,
            size=(self.pop_size_parent, self.gene_num))

        self.timestamps = np.arange(self.pop_size_parent, dtype=np.uint)
        self._time = self.pop_size_parent

        if not self._plt_config["fitness_avg"]:
            self._plt_config["fitness_avg"] = avg_range * [0.0]

        if not self._plt_config["fitness_std"]:
            self._plt_config["fitness_std"] = avg_range * [0.0]

        self.fitness = np.array([
            self.fitness_func(inst, **self.fitness_func_args)
            for inst in self.population
        ],
                                dtype=float)

        if plot:
            self._config_plot(online=True)
            self.plot(num_points=plot_contour_points, plot_pause=plot_pause)

        gen_ind = 0
        current_it = 0
        killed_num = 0

        while gen_ind < self.gen_num:
            self.population, cur_killed_num = self._gen_pop()

            if not time_invariant_fitness:
                self.fitness = np.apply_along_axis(
                    func1d=self.fitness_func,
                    axis=1,
                    arr=self.population,
                    **self.fitness_func_args)

            current_it += self.pop_size_offspring
            killed_num += cur_killed_num

            if current_it >= self.pop_size_parent:
                gen_ind += current_it // self.pop_size_parent
                current_it %= self.pop_size_parent

                if verbose:
                    print(
                        "Generation {} finished.".format(gen_ind),
                        "{} new instances.".format(killed_num)
                        if killed_num else "")

                killed_num = 0

                self._conf_it_statistics()

                if plot:
                    if replot_fitness_contour:
                        self.plot(
                            num_points=plot_contour_points,
                            plot_pause=plot_pause)
                    else:
                        self._plot_timestep(plot_pause=plot_pause)

        self.best_inst_id = np.argmax(self.fitness)
        self.best_inst = self.population[self.best_inst_id]
        self.best_inst_fitness = self.fitness[self.best_inst_id]

        if plot:
            self._plot_timestep(plot_pause=0)
            self._plt_config["fig"] = None

        self._online_plot = False

        if return_solution:
            return self.best_inst

        return self.population

    def _conf_it_statistics(self) -> None:
        """Configure statistics related to the current iteration."""
        self._plt_config["fitness_avg"].pop(0)
        self._plt_config["fitness_std"].pop(0)
        self._plt_config["fitness_avg"].append(np.mean(self.fitness))
        self._plt_config["fitness_std"].append(np.std(self.fitness))

        _fitness_mean = self._plt_config["fitness_avg"][-1]
        _fitness_std = self._plt_config["fitness_std"][-1]

        if self._fitness_cur_best_avg < _fitness_mean:
            self._fitness_cur_best_avg = _fitness_mean
            self._fitness_cur_best_std = _fitness_std

    @abc.abstractmethod
    def _gen_pop(self) -> t.Tuple[np.ndarray, int]:
        """Generate a new population either in-place or not.

        Access the parent population using `self.population` from
        this superclass.

        Returns
        -------
        tuple of np.ndarray and int
            Tuple with the following values (in this order):
            - The numpy array with the new population
            - The number of killed chromosomes (instances) from the
                parent population.
        """
        return self.population, 0

    def _create_mutation(self, num_offsprings: int = 1,
                         dtype=np.float) -> np.ndarray:
        """Create mutation for numeric types."""
        mutation_delta = np.zeros((num_offsprings, self.gene_num), dtype=dtype)

        for attr_ind, attr_p in enumerate(
                np.random.random(size=(self.gene_num, num_offsprings))):
            mutation_delta[:, attr_ind] = attr_p < self.mutation_prob[attr_ind]

            attr_noise = np.fromiter((self.mutation_delta_func[attr_ind](
                **self.mutation_func_args[attr_ind])
                                      for _ in np.arange(num_offsprings)),
                                     dtype=dtype)

            mutation_delta[:, attr_ind] *= attr_noise

        if num_offsprings == 1:
            return mutation_delta.ravel()

        return mutation_delta

    def _get_inst_ids(self, pop_size_target: int, fitness_source: np.ndarray,
                      scheme: str, pick_best: bool,
                      args: t.Dict[str, t.Any]) -> np.ndarray:
        """Get population indices based on the chosen selection ``scheme``."""
        pop_size_source = fitness_source.size

        if scheme == "tournament":
            tournament_size = args.get("size", 2)
            tournament_decision = np.argmax if pick_best else np.argmin

            tournament_ids = np.random.randint(
                pop_size_source, size=(pop_size_target, tournament_size))

            chosen_ids = tournament_decision(
                fitness_source[tournament_ids], axis=1)

            return tournament_ids[np.arange(self.
                                            pop_size_offspring), chosen_ids]

        if scheme == "fitness-prop":
            fitness = fitness_source if pick_best else -fitness_source
            shifted_fitness = fitness - np.min(fitness)
            sum_fitness = np.sum(shifted_fitness)

            if not np.equal(sum_fitness, 0):
                probs = shifted_fitness / sum_fitness
            else:
                probs = None

            return np.random.choice(
                pop_size_source, size=pop_size_target, replace=True, p=probs)

        if scheme == "ranking":
            power = args.get("power", 1)
            ranks = np.arange(fitness_source.size - 1, -1, -1)**power

            ranks[np.argsort(
                self.fitness if pick_best else -fitness_source)] = ranks

            probs = ranks / np.sum(ranks)

            return np.random.choice(
                pop_size_source, size=pop_size_target, replace=True, p=probs)

        if scheme == "truncation":
            ranks = np.argsort(
                fitness_source if pick_best else -fitness_source)

            if pop_size_target > pop_size_source:
                ranks = np.tile(
                    A=ranks, reps=pop_size_target // pop_size_source + 1)

            return ranks[-pop_size_target:]

        if scheme == "deterministic":
            inds = np.arange(pop_size_source)

            if pop_size_target > pop_size_source:
                inds = np.tile(
                    A=inds, reps=pop_size_target // pop_size_source + 1)

            return inds[:pop_size_target]

        # Default: uniform
        return np.random.randint(pop_size_source, size=pop_size_target)

    def _config_plot(self, online: bool = False) -> None:
        """Configure the class attributes related to plotting.

        Arguments
        ---------
        online : :obj:`bool`, optional
            If True, configure for online plotting (plot during the
            algorithm execution.)
        """
        if online:
            self._online_plot = True
            plt.ion()

        else:
            self._online_plot = False

        self._plt_config.setdefault("fitness_avg", [])
        self._plt_config.setdefault("fitness_std", [])
        self._plt_config.setdefault("fig", None)

        if self._plt_config["fig"] is None:
            self._plt_config["fig"] = plt.figure()
            self._plt_config["ax1"] = self._plt_config["fig"].add_subplot(121)
            self._plt_config["ax2"] = self._plt_config["fig"].add_subplot(122)

        self._plt_config["con"] = None
        self._plt_config["sct"] = None
        self._plt_config["avg_lines"] = None
        self._plt_config["fitness_max_line"] = None
        self._plt_config["fitness_max_line_std"] = None
        self._plt_config["legend"] = None

        plt.suptitle(
            "Algorithm: {} (Pop size: {}, Batch size: {})\n"
            "Parent selection: {}, Target selection: {}, reproduction is {}\n"
            "Overlapping population: {}, Merge population: {}\n".format(
                self._alg_name if self._alg_name else "Unknown",
                self.pop_size_parent, self.pop_size_offspring,
                self.selection_parent, self.selection_target,
                self.reproduction, self.overlapping_pops,
                self.merge_populations),
            fontsize=10)

        self._plt_config["ax1"].set_title("Fitness countour plot" + (
            " (best fit: {:.4f})".
            format(self.best_inst_fitness) if self.best_inst_id >= 0 else ""))
        self._plt_config["ax1"].set_xlabel("First dimension")
        self._plt_config["ax1"].set_ylabel("Second dimension")

        self._plt_config["ax2"].set_title("Fitness local average")
        self._plt_config["ax2"].set_xlabel("# of algorithm executions")
        self._plt_config["ax2"].set_ylabel("Average local fitness")

        if self.inst_range_low.size > 1:
            self._plt_config["ax1"].set_xlim(self.inst_range_low[0],
                                             self.inst_range_high[0])
            self._plt_config["ax1"].set_ylim(self.inst_range_low[1],
                                             self.inst_range_high[1])

        else:
            self._plt_config["ax1"].set_xlim(self.inst_range_low,
                                             self.inst_range_high)
            self._plt_config["ax1"].set_ylim(self.inst_range_low,
                                             self.inst_range_high)

    def _plot_timestep(self, plot_pause: float = 0.01):
        """Plot the current population scatter plot.

        Arguments
        ---------
        plot_pause : :obj:`float`, optional
            Number of seconds to wait before closing the current plot
            automatically.
        """
        if self._plt_config["sct"]:
            self._plt_config["sct"].remove()

        if self._plt_config["avg_lines"]:
            self._plt_config["avg_lines"].remove()

        if self._plt_config["fitness_max_line"]:
            self._plt_config["fitness_max_line"].remove()

        if self._plt_config["fitness_max_line_std"]:
            self._plt_config["fitness_max_line_std"].remove()

        if self.gene_num == 2:
            self._plt_config["sct"] = self._plt_config["ax1"].scatter(
                self.population[:, 0],
                self.population[:, 1],
                color="yellow",
                zorder=1)
        else:
            self._plt_config["sct"] = self._plt_config["ax1"].scatter(
                self.population, self.fitness, color="yellow", zorder=1)

        _shifted_time = self._time - self.pop_size_parent
        _xlim = (_shifted_time,
                 _shifted_time + len(self._plt_config["fitness_avg"]) - 1)

        self._plt_config["avg_lines"] = self._plt_config["ax2"].errorbar(
            x=np.arange(_xlim[0], _xlim[1] + 1),
            y=self._plt_config["fitness_avg"],
            yerr=self._plt_config["fitness_std"],
            color="black",
            label="Local fitness")

        self._plt_config["fitness_max_line"] = self._plt_config["ax2"].hlines(
            self._fitness_cur_best_avg,
            *_xlim,
            linestyle="--",
            color="red",
            label="Best local fitness")

        self._plt_config["fitness_max_line_std"] = self._plt_config[
            "ax2"].hlines([
                self._fitness_cur_best_avg - self._fitness_cur_best_std,
                self._fitness_cur_best_avg + self._fitness_cur_best_std,
            ],
                          *_xlim,
                          linestyle=":",
                          color="red")

        self._plt_config["ax2"].set_xlim(*_xlim)

        try:
            plt.pause(plot_pause)

        except Exception:
            pass

    def plot(self, num_points: int = 32, plot_pause: float = 0.0) -> None:
        """Plot the fitness curve contour plot with the population scatter plot.

        Arguments
        ---------
        num_points : :obj:`int`, optional
            Number of points, for each dimension, for the contour plot.
            The higher is this value, the more precise will be the contour
            plot.

        plot_pause : :obj:`float`, optional
            Number of seconds to wait before closing the current plot
            automatically.
        """
        if not self.population.size:
            raise ValueError("No population to plot. Run 'run' method first.")

        if self.gene_num > 2:
            raise ValueError(
                "Can't plot populations with more than 2 dimensions.")

        if not self._online_plot:
            self._config_plot(online=False)

        elif not plt.fignum_exists(self._plt_config["fig"].number):
            return

        if self._plt_config.get("con") is not None:
            for item in self._plt_config["con"].collections:
                item.remove()

        if self.gene_num == 2:
            if self.inst_range_low.size == 2:
                vals_x = np.linspace(self.inst_range_low[0],
                                     self.inst_range_high[0], num_points)
                vals_y = np.linspace(self.inst_range_low[1],
                                     self.inst_range_high[1], num_points)
            else:
                vals_x = vals_y = np.linspace(self.inst_range_low,
                                              self.inst_range_high, num_points)

            X, Y = np.meshgrid(vals_x, vals_y)
            Z = np.zeros((num_points, num_points), dtype=float)

            for i in np.arange(num_points):
                for j in np.arange(num_points):
                    inst = np.array([X[i, j], Y[i, j]], dtype=float)
                    Z[i, j] = self.fitness_func(inst, **self.fitness_func_args)

            self._plt_config["con"] = self._plt_config["ax1"].contourf(
                X, Y, Z, cmap="BuPu", zorder=-1)

        else:
            vals = np.linspace(self.inst_range_low, self.inst_range_high,
                               num_points)

            self._plt_config["con"] = self._plt_config["ax1"].plot(
                vals, [self.fitness_func(val) for val in vals], zorder=-1)

        self._plot_timestep(plot_pause=plot_pause)

        if self._plt_config.get("legend") is None:
            self._plt_config["legend"] = self._plt_config["ax2"].legend(
                loc="lower left")

        if not self._online_plot:
            plt.show()

        elif plt.fignum_exists(self._plt_config["fig"].number):
            plt.draw()

    def __str__(self) -> str:
        info = [[
            "Algorithm chosen:",
            self._alg_name if self._alg_name else "Unknown"
        ], ["Population size:", str(self.pop_size_parent)],
                [
                    "Using", ("" if self.overlapping_pops else "Non-") +
                    "overlapping population."
                ],
                [("M" if self.merge_populations else "Not m") +
                 "erging the parent "
                 "and offspring populations before selection."],
                ["Population offspring:",
                 str(self.pop_size_offspring)],
                [
                    "On average, {:.4f} offsprings per parent.".format(
                        self.pop_size_offspring / self.pop_size_parent)
                ], ["Reproduction is {}.".format(self.reproduction)],
                [
                    "    List of arguments:",
                    "" if self.reproduction_func_args else "None."
                ]]  # type: t.List[t.List[str]]

        for key, val in self.reproduction_func_args.items():
            info[-1].append("\n    * {} = {}".format(key, str(val)))

        info += [
            [],
            ["Selection mechanisms:"],
            [" - Parent selection:", self.selection_parent],
            [
                "    List of arguments:",
                "" if self.selection_parent_args else "None."
            ],
        ]

        for key, val in self.selection_parent_args.items():
            info[-1].append("\n    * {} = {}".format(key, str(val)))

        info += [
            [" - Target selection:", self.selection_target],
            [
                "    List of arguments:",
                "" if self.selection_target_args else "None."
            ],
        ]

        for key, val in self.selection_target_args.items():
            info[-1].append("\n    * {} = {}".format(key, str(val)))

        if self.best_inst_id >= 0:
            info += [
                [],
                ["Solution data:"],
                [
                    " - Best fitness found: {:.4f}".format(
                        self.best_inst_fitness)
                ],
                [" - Best instance index:",
                 str(self.best_inst_id)],
                [
                    " - Total epochs run:",
                    str(self._time // self.pop_size_parent)
                ],
            ]

        return "\n".join(map(" ".join, info))


from django.conf.urls import patterns, url
from repos import views as repo_views

urlpatterns = patterns('',
    url(r'^$', repo_views.HomeView.as_view(), name='home'),
    url(r'^about/$', repo_views.AboutView.as_view(), name='about'),
    url(r'^profile/$', repo_views.ProfileView.as_view(), name='profile'),
    url(r'^repo/(?P<repo_id>\d+)/activate$', repo_views.ActivateRepoView.as_view(activate=True), name='activate_repo'),
    url(r'^repo/(?P<repo_id>\d+)/deactivate$', repo_views.ActivateRepoView.as_view(activate=False), name='deactivate_repo'),
    url(r'^repo/(?P<repo_id>\d+)/update$', repo_views.UpdateRepoView.as_view(), name='update_repo'),
)


from typing import List, Optional
from pydantic import BaseModel, Field
from datetime import datetime
from .catalog_item import CatalogItemSchema
from .user import UserSchema
from .provision import ProvisionSchema
from .purpose import PurposeSchema
from .workshop import WorkshopSchema

class RequestSchema(BaseModel):
    id: str = Field(..., description="The unique identifier for the request.")
    catalog_id: int = Field(..., description="The unique identifier for the catalog item.")
    purpose_id: int = Field(..., description="The unique identifier for the purpose.")
    user_id: int = Field(..., description="The unique identifier for the user.")
    workshop_id: Optional[str] = Field(None, description="The unique identifier for the workshop.")
    category: Optional[str] = Field(None, description="The category of the request.")
    datasource: Optional[str] = Field(None, description="The datasource of the request.")
    deletion_requested_at: Optional[datetime] = Field(None,
                                                      description="The deletion requested at of the request.")
    display_name: Optional[str] = Field(None, description="The display name of the request.")
    provisioned_at: datetime = Field(..., description="The provisioned at of the request.")
    request_result: Optional[str] = Field(None, description="The request result of the request.")
    requested_at: datetime = Field(..., description="The requested at of the request.")
    retired_at: Optional[datetime] = Field(None, description="The retired at of the request.")
    stage: str = Field(..., description="The stage of the request.")
    user_experiences: int = Field(..., description="The user experiences of the request.")
    user_geo: str = Field(..., description="The user geo of the request.")
    user_group: str = Field(..., description="The user group of the request.")
    month: int = Field(..., description="The month of the request.")
    month_name: str = Field(..., description="The month name of the request.")
    month_ts: datetime = Field(..., description="The month ts of the request.")
    quarter: int = Field(..., description="The quarter of the request.")
    year: int = Field(..., description="The year of the request.")
    year_month: str = Field(..., description="The year month of the request.")

    catalog_item: Optional[CatalogItemSchema] = Field(None,
                                                      description="Details of the associated catalog item.")
    provisions: Optional[List[ProvisionSchema]] = Field(None,
                                                        description="Details of the associated provision.")
    purpose: Optional[PurposeSchema] = Field(None,
                                             description="Details of the associated purpose.")
    user: Optional[UserSchema] = Field(None,
                                       description="Details of the associated user.")
    workshop: Optional[WorkshopSchema] = Field(None,
                                               description="Details of the associated workshop.")

    class Config:
        from_attributes = True


import os

import torch
from data_processing import load_sst_dataset, split_text
from network import WordSANet

def get_sentiment(texts, dir_path):
    """
    Given list of strings, returns list of sentiments.
    negative = 0, neutral = 1, positive = 2
    """

    saved_model_filename = 'saved_66.9p_epoch10/saved_models/WordSANet:16531:200:lstm:108:1:0.0:lr=0.0007:wd=0.0:b=64epoch=10.pt'
    saved_model_path = os.path.join(dir_path, saved_model_filename)

    _, _, _, vocab = load_sst_dataset(
        char_base=False, three_labels=True, regression=False)

    model = WordSANet(vocab.vectors, layer_type='lstm',
        output_size=3,regression=False, hidden_size=108,
        num_layers=1, dropout=0.0)
    model.load_state_dict(torch.load(saved_model_path))
    model.eval()

    sentiments = []
    for sentence in texts:
        sentence_words = split_text(sentence)
        if len(sentence_words) < 1:
            sentiments.append(1)
            continue
        word_tensor = torch.zeros(len(sentence_words), dtype=int)
        for i, word in enumerate(sentence_words):
            index = vocab.stoi[word]
            word_tensor[i] = index
        out = model(word_tensor.unsqueeze(0))
        print(out)
        output_prob = torch.softmax(out, dim=1)
        # indices from 0-2 indicating sentiment class
        _, indices = output_prob.max(1)
        sentiments.append(indices[0].item())

    return sentiments

if __name__ == '__main__':
    dir_path = os.path.dirname(os.path.realpath(__file__))
    texts = [
        'Boys are good',
        'Girls are good',
        'Boys are bad',
        'Girls are bad',
        'Ivan is good', # positive
        'Ivan is definitely not good', # positive
        'Ivan is definitely not bad', # positive
        'Ivan is the coolest most awesome person in the world!', # positive
        'Ivan is okay, but not the greatest.', # neutral
        'Ivan is absolutely terrible and I abhor him.'] # negative
    print(texts)
    print(get_sentiment(texts, dir_path))


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

import configargparse

from onmt.utils.logging import init_logger
from onmt.translate.translator import build_translator

import onmt.opts as opts

def main(opt):
    translator = build_translator(opt)
    translator.translate(opt.corpora)

if __name__ == "__main__":
    parser = configargparse.ArgumentParser(
        description='translate.py',
        config_file_parser_class=configargparse.YAMLConfigFileParser,
        formatter_class=configargparse.ArgumentDefaultsHelpFormatter)
    opts.config_opts(parser)
    opts.add_md_help_argument(parser)
    opts.translate_opts(parser)

    opt = parser.parse_args()
    logger = init_logger(opt.log_file)
    main(opt)


import enum

class X(enum.Enum):
    a = 1
    b = 2

    @classmethod
    def foo(self):
        print('ccc')

if __name__ == "__main__":
    z = X['a']
    print(X.a)
    print(z)
    X.foo()
    z.foo()