from flask import abort, jsonify
from flask_login import login_required

from depc.apiv1 import api, format_object, get_payload
from depc.controllers.variables import VariableController
from depc.users import TeamPermission

VISIBLE = ["name", "value", "type", "expression"]

def format_variable(source):
    visible = list(VISIBLE)
    s = format_object(source, visible)
    return s

@api.route("/teams/<team_id>/variables")
@login_required
def list_team_variables(team_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    variables = VariableController.list(
        filters={
            "Variable": {
                "team_id": team_id,
                "rule_id": None,
                "source_id": None,
                "check_id": None,
            }
        }
    )

    return jsonify([format_variable(v) for v in variables]), 200

@api.route("/teams/<team_id>/rules/<rule_id>/variables")
@login_required
def list_rule_variables(team_id, rule_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    variables = VariableController.list(
        filters={
            "Variable": {
                "team_id": team_id,
                "rule_id": rule_id,
                "source_id": None,
                "check_id": None,
            }
        }
    )

    return jsonify([format_variable(v) for v in variables]), 200

@api.route("/teams/<team_id>/sources/<source_id>/variables")
@login_required
def list_source_variables(team_id, source_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    variables = VariableController.list(
        filters={
            "Variable": {
                "team_id": team_id,
                "rule_id": None,
                "source_id": source_id,
                "check_id": None,
            }
        }
    )

    return jsonify([format_variable(v) for v in variables]), 200

@api.route("/teams/<team_id>/sources/<source_id>/checks/<check_id>/variables")
@login_required
def list_check_variables(team_id, source_id, check_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    variables = VariableController.list(
        filters={
            "Variable": {
                "team_id": team_id,
                "rule_id": None,
                "source_id": source_id,
                "check_id": check_id,
            }
        }
    )

    return jsonify([format_variable(v) for v in variables]), 200

@api.route("/teams/<team_id>/variables/<variable_id>")
@login_required
def get_team_variable(team_id, variable_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    variable = VariableController.get(
        filters={
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": None,
                "check_id": None,
            }
        }
    )

    return jsonify(format_variable(variable)), 200

@api.route("/teams/<team_id>/rules/<rule_id>/variables/<variable_id>")
@login_required
def get_rule_variable(team_id, rule_id, variable_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    variable = VariableController.get(
        filters={
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": rule_id,
                "source_id": None,
                "check_id": None,
            }
        }
    )

    return jsonify(format_variable(variable)), 200

@api.route("/teams/<team_id>/sources/<source_id>/variables/<variable_id>")
@login_required
def get_source_variable(team_id, source_id, variable_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    variable = VariableController.get(
        filters={
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": source_id,
                "check_id": None,
            }
        }
    )

    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/sources/<source_id>/checks/<check_id>/variables/<variable_id>"
)
@login_required
def get_check_variable(team_id, source_id, check_id, variable_id):
    """

    .. :quickref: GET; Lorem ipsum."""
    if not TeamPermission.is_user(team_id):
        abort(403)

    variable = VariableController.get(
        filters={
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": source_id,
                "check_id": check_id,
            }
        }
    )

    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/variables",
    methods=["POST"],
    request_schema=("v1_variable", "variable_input"),
)
@login_required
def post_team_variable(team_id):
    """

    .. :quickref: POST; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    payload = get_payload()
    payload.update({"team_id": team_id})
    variable = VariableController.create(payload)
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/rules/<rule_id>/variables",
    methods=["POST"],
    request_schema=("v1_variable", "variable_input"),
)
@login_required
def post_rule_variable(team_id, rule_id):
    """

    .. :quickref: POST; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    payload = get_payload()
    payload.update({"team_id": team_id, "rule_id": rule_id})
    variable = VariableController.create(payload)
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/sources/<source_id>/variables",
    methods=["POST"],
    request_schema=("v1_variable", "variable_input"),
)
@login_required
def post_source_variable(team_id, source_id):
    """

    .. :quickref: POST; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    payload = get_payload()
    payload.update({"team_id": team_id, "source_id": source_id})
    variable = VariableController.create(payload)
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/sources/<source_id>/checks/<check_id>/variables",
    methods=["POST"],
    request_schema=("v1_variable", "variable_input"),
)
@login_required
def post_check_variable(team_id, source_id, check_id):
    """

    .. :quickref: POST; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    payload = get_payload()
    payload.update({"team_id": team_id, "source_id": source_id, "check_id": check_id})
    variable = VariableController.create(payload)
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/variables/<variable_id>",
    methods=["PUT"],
    request_schema=("v1_variable", "variable_input"),
)
@login_required
def put_team_variable(team_id, variable_id):
    """

    .. :quickref: PUT; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    payload = get_payload()
    variable = VariableController.update(
        payload,
        {
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": None,
                "check_id": None,
            }
        },
    )
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/rules/<rule_id>/variables/<variable_id>",
    methods=["PUT"],
    request_schema=("v1_variable", "variable_input"),
)
@login_required
def put_rule_variable(team_id, rule_id, variable_id):
    """

    .. :quickref: PUT; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    payload = get_payload()
    variable = VariableController.update(
        payload,
        {
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": rule_id,
                "source_id": None,
                "check_id": None,
            }
        },
    )
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/sources/<source_id>/variables/<variable_id>",
    methods=["PUT"],
    request_schema=("v1_variable", "variable_input"),
)
@login_required
def put_source_variable(team_id, source_id, variable_id):
    """

    .. :quickref: PUT; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    payload = get_payload()
    variable = VariableController.update(
        payload,
        {
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": source_id,
                "check_id": None,
            }
        },
    )
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/sources/<source_id>/checks/<check_id>/variables/<variable_id>",
    methods=["PUT"],
    request_schema=("v1_variable", "variable_input"),
)
@login_required
def put_check_variable(team_id, source_id, check_id, variable_id):
    """

    .. :quickref: PUT; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    payload = get_payload()
    variable = VariableController.update(
        payload,
        {
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": source_id,
                "check_id": check_id,
            }
        },
    )
    return jsonify(format_variable(variable)), 200

@api.route("/teams/<team_id>/variables/<variable_id>", methods=["DELETE"])
@login_required
def delete_team_variable(team_id, variable_id):
    """

    .. :quickref: DELETE; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    variable = VariableController.delete(
        filters={
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": None,
                "check_id": None,
            }
        }
    )
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/rules/<rule_id>/variables/<variable_id>", methods=["DELETE"]
)
@login_required
def delete_rule_variable(team_id, rule_id, variable_id):
    """

    .. :quickref: DELETE; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    variable = VariableController.delete(
        filters={
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": rule_id,
                "source_id": None,
                "check_id": None,
            }
        }
    )
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/sources/<source_id>/variables/<variable_id>", methods=["DELETE"]
)
@login_required
def delete_source_variable(team_id, source_id, variable_id):
    """

    .. :quickref: DELETE; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    variable = VariableController.delete(
        filters={
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": source_id,
                "check_id": None,
            }
        }
    )
    return jsonify(format_variable(variable)), 200

@api.route(
    "/teams/<team_id>/sources/<source_id>/checks/<check_id>/variables/<variable_id>",
    methods=["DELETE"],
)
@login_required
def delete_check_variable(team_id, source_id, check_id, variable_id):
    """

    .. :quickref: DELETE; Lorem ipsum."""
    if not TeamPermission.is_manager_or_editor(team_id):
        abort(403)

    variable = VariableController.delete(
        filters={
            "Variable": {
                "id": variable_id,
                "team_id": team_id,
                "rule_id": None,
                "source_id": source_id,
                "check_id": check_id,
            }
        }
    )
    return jsonify(format_variable(variable)), 200


class MACPieException(Exception):
    """MACPie common exception."""


import os
from collections import OrderedDict
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
from .building import Building
from .datastore.datastore import join_key
from .utils import get_datastore
from .timeframe import TimeFrame

class DataSet(object):
    """
    Attributes
    ----------
    buildings : OrderedDict
        Each key is an integer, starting from 1.
        Each value is a nilmtk.Building object.

    store : nilmtk.DataStore

    metadata : dict
        Metadata describing the dataset name, authors etc.
        (Metadata about specific buildings, meters, appliances etc.
        is stored elsewhere.)
        See nilm-metadata.readthedocs.org/en/latest/dataset_metadata.html#dataset
    """

    def __init__(self, filename=None, format='HDF',mode='a'):
        """
        Parameters
        ----------
        filename : str
            path to data set

        format : str
            format of output. Either 'HDF' or 'CSV'. Defaults to 'HDF'
        """
        self.store = None
        self.buildings = OrderedDict()
        self.metadata = {}
        if filename is not None:
            self.import_metadata(get_datastore(filename, format,mode))

    def import_metadata(self, store):
        """
        Parameters
        ----------
        store : nilmtk.DataStore
        """
        self.store = store
        self.metadata = store.load_metadata()
        self._init_buildings(store)
        return self

    def save(self, destination):
        for b_id, building in self.buildings.items():
            building.save(destination, '/building' + str(b_id))

    def _init_buildings(self, store):
        buildings = store.elements_below_key('/')
        buildings.sort()

        for b_key in buildings:
            building = Building()
            building.import_metadata(
                store, '/'+b_key, self.metadata.get('name'))
            self.buildings[building.identifier.instance] = building

    def set_window(self, start=None, end=None):
        """Set the timeframe window on self.store. Used for setting the
        'region of interest' non-destructively for all processing.

        Parameters
        ----------
        start, end : str or pd.Timestamp or datetime or None
        """
        if self.store is None:
            raise RuntimeError("You need to set self.store first!")

        tz = self.metadata.get('timezone')
        if tz is None:
            raise RuntimeError("'timezone' is not set in dataset metadata.")

        self.store.window = TimeFrame(start, end, tz)

    def describe(self, **kwargs):
        """Returns a DataFrame describing this dataset.
        Each column is a building.  Each row is a feature."""
        keys = list(self.buildings.keys())
        keys.sort()
        results = pd.DataFrame(columns=keys)
        for i, building in self.buildings.items():
            results[i] = building.describe(**kwargs)
        return results

    def plot_good_sections(self, axes=None, label_func=None, gap=0, **kwargs):
        """Plots all good sections for all buildings.

        Parameters
        ----------
        axes : list of axes or None.
            If None then they will be generated.

        Returns
        -------
        axes : list of axes
        """
        n = len(self.buildings)
        if axes is None:
            n_meters_per_building = [len(elec.all_meters())
                                     for elec in self.elecs()]
            gridspec_kw = dict(height_ratios=n_meters_per_building)
            fig, axes = plt.subplots(
                n, 1, sharex=True, gridspec_kw=gridspec_kw)

        assert n == len(axes)
        for i, (ax, elec) in enumerate(zip(axes, self.elecs())):
            elec.plot_good_sections(ax=ax, label_func=label_func, gap=gap,
                                    **kwargs)
            ax.set_title('House {}'.format(elec.building()), y=0.4, va='top')
            ax.grid(False)
            for spine in ax.spines.values():
                spine.set_linewidth(0.5)
            if i == n // 2:
                ax.set_ylabel('Meter', rotation=0,
                              ha='center', va='center', y=.4)

        ax.set_xlabel('Date')

        plt.tight_layout()
        plt.subplots_adjust(hspace=0.05)
        plt.draw()

        return axes

    def elecs(self):
        return [building.elec for building in self.buildings.values()]

    def clear_cache(self):
        for elec in self.elecs():
            elec.clear_cache()

    def plot_mains_power_histograms(self, axes=None, **kwargs):
        n = len(self.buildings)
        if axes is None:
            fig, axes = plt.subplots(n, 1, sharex=True)
        assert n == len(axes)

        for ax, elec in zip(axes, self.elecs()):
            ax = elec.mains().plot_power_histogram(ax=ax, **kwargs)
            ax.set_title('House {}'.format(elec.building()))
        return axes

    def get_activity_script(self, filename):
        """Extracts an activity script from this dataset.

        Saves the activity script to an HDF5 file.
        Keys in the HDF5 file take the form:
        '/building<building_i>/<appliance type>__<appliance instance>'
        e.g. '/building1/electric_oven__1'
        Spaces in the appliance type are replaced by underscores.

        Each table is of fixed format and stores a pd.Series.
        The index is the datetime of the start time or end time of
        each appliance activation.  The values are booleans.  True means
        the start time of an appliance activation; false means the
        end time of an appliance activation.

        Parameters
        ----------
        filename : str
            The full filename, including path and suffix, for the HDF5 file
            for storing the activity script.
        """
        store = pd.HDFStore(
            filename, mode='w', complevel=9, complib='blosc')

        for building in self.buildings.values():
            submeters = building.elec.submeters().meters

            for meter in submeters:
                appliance = meter.dominant_appliance()
                key = '/building{:d}/{:s}__{:d}'.format(
                    building.identifier.instance,
                    appliance.identifier.type.replace(' ', '_'),
                    appliance.identifier.instance)
                print("Computing activations for", key)

                activations = meter.get_activations()
                starts = []
                ends = []
                for activation in activations:
                    starts.append(activation.index[0])
                    ends.append(activation.index[-1])
                del activations
                starts = pd.Series(True, index=starts)
                ends = pd.Series(False, index=ends)
                script = pd.concat([starts, ends])
                script = script.sort_index()
                store[key] = script
                del starts, ends

        store.close()


# Copyright (c) 2015-2017, NVIDIA CORPORATION.  All rights reserved.
from __future__ import absolute_import

from . import option_list
import digits.device_query

option_list['gpu_list'] = ','.join([str(x) for x in range(len(digits.device_query.get_devices()))])


def leiaDinheiro(msg):
    ok = False
    while not ok:
        entrada = str(input(msg)).replace(',', '.').strip()
        if entrada.isalpha():
            print(f'\033[1;31mERRO! \"{entrada}\" é um valor inválido!\033[m')
        else:
            ok = True
            return float(entrada)


# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
#
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from msrest.serialization import Model

class EnvironmentDeploymentPropertiesFragment(Model):
    """Properties of an environment deployment.

    :param arm_template_id: The Azure Resource Manager template's identifier.
    :type arm_template_id: str
    :param parameters: The parameters of the Azure Resource Manager template.
    :type parameters:
     list[~azure.mgmt.devtestlabs.models.ArmTemplateParameterPropertiesFragment]
    """

    _attribute_map = {
        'arm_template_id': {'key': 'armTemplateId', 'type': 'str'},
        'parameters': {'key': 'parameters', 'type': '[ArmTemplateParameterPropertiesFragment]'},
    }

    def __init__(self, *, arm_template_id: str=None, parameters=None, **kwargs) -> None:
        super(EnvironmentDeploymentPropertiesFragment, self).__init__(**kwargs)
        self.arm_template_id = arm_template_id
        self.parameters = parameters


#!/usr/bin/env python
#-----------------------------*-python-*----------------------------------------#
# file   src/cdi_ipcress/python/ipcress_reader.py
# author Alex Long <along@lanl.gov>
# date   Monday, December 15, 2014, 5:44 pm
# brief  This script has fucntions that parse an IPCRESS file and returns a
#        dictionary that contains data for each property and each material
#        present in the file. This script also contains interpolation functions
#        for opacity data.
# note   Copyright (C) 2016, Triad National Security, LLC.
#        All rights reserved.
#--------------------------------------------------------------------------------------------------#

# import block
################################################################################
import re
from numpy import arange, sin, pi, min, max
import sys
import struct
import numpy as np
from struct import *
from math import *
################################################################################

# These are the functions that are used to read data from the
# binary IPCRESS file. It also contains a function for interpolating in
# density and temperature. The data locations are specified in
# cdi_ipcress/doc/IPCRESS_File_Format.pdf

################################################################################
def get_data_for_id(filename, data_start_index, num_entries):
  temp_grid = []
  # "rb" is read binary mode
  with open(filename, "rb") as f:
    f.seek(data_start_index*8)
    for i in range(num_entries):
      word = f.read(8)
      temp_grid.append(unpack('>d', word)[0])
  return temp_grid
################################################################################

################################################################################
def write_data_for_id(filename, data_start_index, num_entries, new_values):
  # "wb" is write binary mode
  with open(filename, "r+b") as f:
    f.seek(data_start_index*8)
    for i in range(num_entries):
      s = struct.pack('>d', new_values[i])
      f.write(s)
################################################################################

################################################################################
def interpolate_mg_opacity_data(T_grid, rho_grid, hnu_grid, op_data, \
    target_rho, target_T, print_str=""):
  n_rho = len(rho_grid)
  n_T = len(T_grid)
  n_hnu = len(hnu_grid)

  # don't allow extrapolation
  if (target_rho  < np.min(rho_grid)):  target_rho = np.min(rho_grid)
  if (target_rho  > np.max(rho_grid)):  target_rho = np.max(rho_grid)
  if (target_T    < np.min(T_grid)):    target_T = np.min(T_grid)
  if (target_T    > np.max(T_grid)):    target_T = np.max(T_grid)
  if (print_str is not None):
    print( \
      "Interpolating {0}--Target rho: {1} , target T: {2}".format( \
      print_str, target_rho, target_T))

  # get correct index of adjacent density points
  rho_L = 1000; rho_G =0
  for rho_i, rho in enumerate(rho_grid[:-1]):
    if ( target_rho >= rho and target_rho<=rho_grid[rho_i+1]):
      rho_L = rho_i
      rho_G = rho_i+1
      break

  # get correct index of adjacent temperature points
  T_L = 1000; T_G = 0
  for T_i, T in enumerate(T_grid[:-1]):
    if ( target_T >= T and target_T<=T_grid[T_i+1]):
      T_L = T_i
      T_G = T_i+1
      break

  #print("Temperature interpolation bounds: {0} {1}".format(T_grid[T_L], T_grid[T_G]))
  #print("Density interpolation bounds: {0} {1}".format(rho_grid[rho_L], rho_grid[rho_G]))

  #get the adjacent rows of the opacity index
  #get the points of the opacity index
  rho_L_T_L = op_data[n_rho*T_L*(n_hnu-1) + rho_L*(n_hnu-1) : n_rho*T_L*(n_hnu-1) + rho_L*(n_hnu-1) + (n_hnu-1) ]
  rho_L_T_G = op_data[n_rho*T_G*(n_hnu-1) + rho_L*(n_hnu-1) : n_rho*T_G*(n_hnu-1) + rho_L*(n_hnu-1) + (n_hnu-1) ]
  rho_G_T_L = op_data[n_rho*T_L*(n_hnu-1) + rho_G*(n_hnu-1) : n_rho*T_L*(n_hnu-1) + rho_G*(n_hnu-1) + (n_hnu-1) ]
  rho_G_T_G = op_data[n_rho*T_G*(n_hnu-1) + rho_G*(n_hnu-1) : n_rho*T_G*(n_hnu-1) + rho_G*(n_hnu-1) + (n_hnu-1) ]

  interp_op = []
  #interpolate for each frequency point
  for i in range(n_hnu-1):
    #if (rho_L_T_L[i] < 1.0e-10) or (rho_L_T_G[i] < 1.0e-10) or (rho_G_T_L[i] < 1.0e-10) or (rho_G_T_G[i] < 1.0e10):
    #  interp_op.append(1.0e-10)
    #print("{0} {1} {2} {3}" .format(rho_L_T_L[i], rho_L_T_G[i], rho_G_T_L[i], rho_G_T_G[i]))
    log_op_T_L  = log(rho_L_T_L[i]) + log(target_rho/rho_grid[rho_L]) / log(rho_grid[rho_G]/rho_grid[rho_L]) * log(rho_G_T_L[i]/rho_L_T_L[i])
    log_op_T_G  = log(rho_L_T_G[i]) + log(target_rho/rho_grid[rho_L]) / log(rho_grid[rho_G]/rho_grid[rho_L]) * log(rho_G_T_G[i]/rho_L_T_G[i])
    log_op =  log_op_T_L + log(target_T/T_grid[T_L]) / log(T_grid[T_G]/T_grid[T_L]) * (log_op_T_G - log_op_T_L)
    interp_op.append(exp(log_op))

  print("hnu(keV)      opacity(sq_cm/g)     opacity(1/cm)")
  for i, hnu in enumerate(hnu_grid[:-1]):
    print("{0}   {1}   {2}".format( 0.5*(hnu + hnu_grid[i+1]), interp_op[i], interp_op[i]*target_rho))
  return interp_op
###############################################################################

################################################################################
def interpolate_gray_opacity_data(T_grid, rho_grid, op_data, target_rho, \
    target_T, print_str = ""):
  n_rho = len(rho_grid)
  n_T = len(T_grid)

  # don't allow extrapolation
  if (target_rho  < np.min(rho_grid)):  target_rho = np.min(rho_grid)
  if (target_rho  > np.max(rho_grid)):  target_rho = np.max(rho_grid)
  if (target_T    < np.min(T_grid)):    target_T = np.min(T_grid)
  if (target_T    > np.max(T_grid)):    target_T = np.max(T_grid)
  if (print_str is not None):
    print( \
      "Interpolating {0}--Target rho: {1} , target T: {2}".format( \
      print_str, target_rho, target_T))

  rho_L = 1000; rho_G =0
  for rho_i, rho in enumerate(rho_grid[:-1]):
    if ( target_rho >= rho and target_rho<=rho_grid[rho_i+1]):
      rho_L = rho_i
      rho_G = rho_i+1
      break

  for T_i, T in enumerate(T_grid[:-1]):
    if ( target_T >= T and target_T<=T_grid[T_i+1]):
      T_L = T_i
      T_G = T_i+1
      break

  #get the adjacent rows of the opacity index
  rho_L_T_L = op_data[n_rho*T_L + rho_L]
  rho_L_T_G = op_data[n_rho*T_G + rho_L]
  rho_G_T_L = op_data[n_rho*T_L + rho_G]
  rho_G_T_G = op_data[n_rho*T_G + rho_G]

  #interpolate in log space
  #print("{0} {1} {2} {3}" .format(rho_L_T_L, rho_L_T_G, rho_G_T_L, rho_G_T_G))
  log_op_T_L  = log(rho_L_T_L) + log(target_rho/rho_grid[rho_L]) / log(rho_grid[rho_G]/rho_grid[rho_L]) * log(rho_G_T_L/rho_L_T_L)
  log_op_T_G  = log(rho_L_T_G) + log(target_rho/rho_grid[rho_L]) / \
    log(rho_grid[rho_G]/rho_grid[rho_L]) * log(rho_G_T_G/rho_L_T_G)
  log_op =  log_op_T_L + log(target_T/T_grid[T_L]) / \
    log(T_grid[T_G]/T_grid[T_L]) * (log_op_T_G - log_op_T_L)
  interp_op = exp(log_op)

  #print("opacity(sq_cm/g)     opacity(1/cm)")
  #print("{0}   {1}".format(interp_op, interp_op*target_rho))
  return interp_op
###############################################################################

###############################################################################
def read_information_from_file(ipcress_file):

  word_array = []
  with open(ipcress_file, "rb") as f:
    for i in range(26):
      word = f.read(8)
      if not word:
          break
      word_array.append(word)
      #print(int(unpack('>d', word)[0]))

  title = word_array[0]
  toc_int= []
  offset = 2
  for i in range(offset,offset+24):
    toc_int.append( int(unpack('>d', word_array[i])[0]))

  n_data_records = toc_int[14]
  mxrec = toc_int[1] - toc_int[0]
  mxkey = toc_int[16]
  #print("Number of data records: {0}".format(n_data_records))
  #print("Beginnging of data: {0}".format(toc_int[0]))
  #print("Max records: {0} , max search keys: {1}".format(mxrec, mxkey))

  mat_property = []

  ds = []
  dfo = []
  tdf = []
  num_mats = 0
  mat_ids= []
  with open(ipcress_file, "rb") as f:
    # Read in array that lists the data sizes in this file
    f.seek(toc_int[0]*8)
    #print("Table of data sizes")
    for i in range(n_data_records):
      word = f.read(8)
      ds.append(int(unpack('>d', word)[0]))

    # Read in array gives the offsets between data
    f.seek(toc_int[1]*8)
    #print("Table of data file offesets")
    for i in range(n_data_records):
      word = f.read(8)
      dfo.append(int(unpack('>d', word)[0]))

    # Read in material IDs present in this file
    f.seek(dfo[0]*8)
    #print("Table of  material identifiers")
    word = f.read(8)
    num_mats = int(unpack('>d', word)[0])
    for i in range(num_mats):
      word = f.read(8)
      mat_ids.append( int(unpack('>d', word)[0]))

    # Read in list of properties in this file available for each material
    # entries in this table are 24 bytes each
    f.seek(toc_int[10]*8)
    #print("Table of data fields for each  material")
    word = f.read(72) #ignore the first 72 bytes, they don't contain useful information
    for i in range(1,toc_int[14]):
      #oredering is "matID" "data type" "fill"
      temp_property = []
      for j in range(mxkey):
        three_string = []
        three_string.append( f.read(8).decode("utf-8"))
        three_string.append( f.read(8).decode("utf-8"))
        three_string.append( f.read(8).decode("utf-8"))
        if (j==0): temp_property.append(three_string[2].strip() )
        elif (j==1): temp_property.append(three_string[0].strip())
        else: temp_property.append(i) #index of data table containing values
      try:
        temp_property = [temp_property[0].decode('ascii'), \
                         temp_property[1].decode('ascii'), temp_property[2]]
        mat_property.append(temp_property)
      except:
        mat_property.append(temp_property)

  materials = []
  for m in range(num_mats):
    materials.append([ m, mat_ids[m]])

  #print("{0} materials in file".format(num_mats))
  #for i in range(num_mats):
  #  print("  Matieral ID: {0}".format(mat_ids[i]))

  #print("List of available properties")
  #for i in property:
  #  print(i)

  #return the list of available properties, data file offsets and data sizes
  return materials, mat_property, dfo, ds
################################################################################

###############################################################################
def write_information_to_file(ipcress_file, material_ID, mat_property, new_values):
  materials, property_list, dfo, ds = read_information_from_file(ipcress_file)
  # check to make sure material is in file
  material_IDs = []
  for imat in materials:
    material_IDs.append(str(imat[1]))
  if (not (material_ID in material_IDs)):
    print("ERROR: Material ID not found in file, not changing anything!")
    return

  # try to find property in file
  property_found = False
  propery_index = 0
  for prop_i, prop in enumerate(property_list):
    if (material_ID == prop[0] and mat_property == prop[1]):
      property_found = True
      property_index = prop_i
      break

  # make sure sizes match of property you're about to write
  if (property_found and  ds[property_index+1] != len(new_values)):
    print("ERROR: Number of new values does not match size of old values, not changing anything!")
    return

  # if the combination of property and material was found, write the new data to
  # the ipcress file
  if property_found:
    write_data_for_id( ipcress_file, dfo[property_index+1], \
      ds[property_index+1], new_values)
  else:
    print("ERROR: Combination of material ID and property not found, not changing anything!")
  return
################################################################################

################################################################################
# Checks to see if there are any zeros in the opcaity data--zero data is
# difficult to handle and for now we are going to ignore data sets that contain
# zeros and print an error message
def check_valid_data(opacity_grid):
  for item in opacity_grid:
    if (item != 0.0):
      return True
  return False
################################################################################

################################################################################
# return a dictionary where the keys are "<material ID>_<property_ID>" and the
# values are the data
def get_property_map_from_ipcress_file(ipcress_file):
  #load data from IPCRESS file
  # dfo is the array of data file offsets, ds is the array of data sizes
  materials, property_list, dfo, ds = read_information_from_file(ipcress_file)

  #build dictionary of data, keys are "property_matID"
  table_key_dict = {}
  for prop_i, prop in enumerate(property_list):
    table_key_dict["{0}_{1}".format(prop[1], prop[0])] = get_data_for_id( ipcress_file, dfo[prop_i+1], ds[prop_i+1])

  material_list = []
  for material in materials:
    material_list.append(material[1])

  return table_key_dict, material_list

################################################################################


# START LAB EXERCISE 9
print('LAB EXERCISE 09 \n')

# PROBLEM 1 (4 Points)

class Book():
    """
    This is a class that contains information on Books.

    Attributes:
        title (str): The title of the book.
        author (str): The name of the author.

    """
    def __init__(self, title, author):
        """
        The constructor of the <Book> class. Here you will need to create
        the instance variables that were described in the docstring above.
        Note that the attributes are defined by parameters passed to this constructor method.

        Parameters:
            title (str): The title of the book.
            author (str): The name of the author.

        Returns:
            None
        """

        pass # Implement

    def __str__(self):
        """
        String method for the <Book> class. Whenever an instance of <Book> is passed to the
        str() or print() functions, the string from this method will be returned.

        Parameters:
            None

        Returns:
            str: A string representation of <Book> instance in the format "<title> by <author>"
        """
        pass # Implement

# PROBLEM 2 (4 Points)

class Library():
    """
    This is a class that contains information on a Library.

    Attributes:
        books (list): List of book instances in the library.
        torn_pages_tolerance (int): Number of torn pages a book can have and the library will still accept.

    """
    def __init__(self):
        """
        The constructor of the <Library> class. Here you will need to create instance variables
        described in the docstring above. The Library constructor should take NO positional arguments, but
        set instance variables <books> to an empty list and <torn_pages_tolerance> to 3.

        Parameters:
            None

        Returns:
            None
        """

        pass # Implement

    def __str__(self):
        """
        String method for the <Library> class.

        Parameters:
            None

        Returns:
            str: A string representation of <Book> instance in the format:
                "This library contains <number of books> books"

        """

        pass # Implement

# PROBLEM 3 (2 Points)

    def will_accept(self, book):
        """
        Determines if the library will add a book instance to its collection
        depending on its conditions.

        if book instance is of Book class, return True.
        if book instance is of PaperbackBook class and the number of torn pages
          is less than or equal to the library's torn page tolerance, return True.
        else return False.
            HINT: there is a built-in isinstance() function to check what class an isntance
            came from

        Parameters:
            book: instance of any book class

        Returns:
            Boolean (True or False)
        """

        pass # Implement

# PROBLEM 4 (2 Points)

    def add_book(self, book):
        """
        This method will modify the <books> attribute by appending the parameter <book>
        to it if the library will accept the book.
            HINT: call will_accept within this method to determine if book can be added

        Parameters:
            book: instance of any book class

        Returns:
            None
        """

        pass # Implement

# PROBLEM 5 (2 Points)

class PaperbackBook(Book): # <- remember to fill in () for class inheritence!
    """
    This is a PaperbackBook class that inherits from the Book class. It will inherit
    all attributes and methods from Book. You will overwrite the parent constructor
    to add an additional property but inherit the string method as is.

     Attributes:
        title (str): The title of the book.
        author (str): The name of the author.
        num_torn_pages (int): The number of torn pages in the PaperBook.

    """

    def __init__(self, title, author):
        """
        The constructor of the <PaperbackBook> class. Here you will need to inherit the attributes
        from the parent class, but add an additional instance variable <num_torn_pages>
        and initialize it to 0. Note that the constructor takes two positional arguments, but will
        set three instance variables.

        Parameters:
            title (str): The title of the book.
            author (str): The name of the author.

        Returns:
            None
        """

        pass # Implement

# PROBLEM 6 (2 Points)

    def rip_page(self):
        """
        This method will modify the <num_torn_pages> and increase it by one every time the
        method is called.

        Parameters:
            None

        Returns:
            None
        """
        pass # Implement

# PROBLEM 7 (4 Points)

def main():

    # 7.1 Create an instance of <Book>

    homer_odyssey = None

    # print instance of book
    print(homer_odyssey)

    # 7.2 Create an instance of <PaperbackBook>

    angelou_rise = None

    # print instance of PaperbackBook
    print(angelou_rise)

    # 7.3 Create an instance of <Library>

    lib = None

    # 7.4 Add book to the library

    pass # Implement

    # 7.5 Increase number of torn pages

    pass # Implement

    # 7.6 Set number of torn pages

    torn_pages = None

    # 7.7 Try to add Paperbook to the library

    pass # Implement

    # 7.8 Print out the library's books

    pass # Implement

# END CODING HERE - - - - - - - - - - - - - - - - - - - - - - - - - - - -

if __name__ == '__main__':
    main()


import torch
import torch.nn as nn
import torch.nn.functional as f
from torch.nn import init
from .submodules import ConvLayer, UpsampleConvLayer, TransposedConvLayer, RecurrentConvLayer, ResidualBlock, ConvLSTM, ConvGRU, RecurrentResidualLayer

def skip_concat(x1, x2):
    return torch.cat([x1, x2], dim=1)

def skip_sum(x1, x2):
    return x1 + x2

class BaseUNet(nn.Module):
    def __init__(self, num_input_channels, num_output_channels=1, skip_type='sum', activation='sigmoid',
                 num_encoders=4, base_num_channels=32, num_residual_blocks=2, norm=None, use_upsample_conv=True):
        super(BaseUNet, self).__init__()

        self.num_input_channels = num_input_channels
        self.num_output_channels = num_output_channels
        self.skip_type = skip_type
        self.apply_skip_connection = skip_sum if self.skip_type == 'sum' else skip_concat
        self.activation = activation
        self.norm = norm

        if use_upsample_conv:
            print('Using UpsampleConvLayer (slow, but no checkerboard artefacts)')
            self.UpsampleLayer = UpsampleConvLayer
        else:
            print('Using TransposedConvLayer (fast, with checkerboard artefacts)')
            self.UpsampleLayer = TransposedConvLayer

        self.num_encoders = num_encoders
        self.base_num_channels = base_num_channels
        self.num_residual_blocks = num_residual_blocks
        self.max_num_channels = self.base_num_channels * pow(2, self.num_encoders)

        assert(self.num_input_channels > 0)
        assert(self.num_output_channels > 0)

        self.encoder_input_sizes = []
        for i in range(self.num_encoders):
            self.encoder_input_sizes.append(self.base_num_channels * pow(2, i))

        self.encoder_output_sizes = [self.base_num_channels * pow(2, i + 1) for i in range(self.num_encoders)]

        self.activation = getattr(torch, self.activation, 'sigmoid')

    def build_resblocks(self):
        self.resblocks = nn.ModuleList()
        for i in range(self.num_residual_blocks):
            self.resblocks.append(ResidualBlock(self.max_num_channels, self.max_num_channels, norm=self.norm))

    def build_decoders(self):
        decoder_input_sizes = list(reversed([self.base_num_channels * pow(2, i + 1) for i in range(self.num_encoders)]))

        self.decoders = nn.ModuleList()
        for input_size in decoder_input_sizes:
            self.decoders.append(self.UpsampleLayer(input_size if self.skip_type == 'sum' else 2 * input_size,
                                                    input_size // 2,
                                                    kernel_size=5, padding=2, norm=self.norm))

    def build_prediction_layer(self):
        self.pred = ConvLayer(self.base_num_channels if self.skip_type == 'sum' else 2 * self.base_num_channels,
                              self.num_output_channels, 1, activation=None, norm=self.norm)

class UNet(BaseUNet):
    def __init__(self, num_input_channels, num_output_channels=1, skip_type='sum', activation='sigmoid',
                 num_encoders=4, base_num_channels=32, num_residual_blocks=2, norm=None, use_upsample_conv=True):
        super(UNet, self).__init__(num_input_channels, num_output_channels, skip_type, activation,
                                   num_encoders, base_num_channels, num_residual_blocks, norm, use_upsample_conv)

        self.head = ConvLayer(self.num_input_channels, self.base_num_channels,
                              kernel_size=5, stride=1, padding=2)  # N x C x H x W -> N x 32 x H x W

        self.encoders = nn.ModuleList()
        for input_size, output_size in zip(self.encoder_input_sizes, self.encoder_output_sizes):
            self.encoders.append(ConvLayer(input_size, output_size, kernel_size=5,
                                           stride=2, padding=2, norm=self.norm))

        self.build_resblocks()
        self.build_decoders()
        self.build_prediction_layer()

    def forward(self, x):
        """
        :param x: N x num_input_channels x H x W
        :return: N x num_output_channels x H x W
        """

        # head
        x = self.head(x)
        head = x

        # encoder
        blocks = []
        for i, encoder in enumerate(self.encoders):
            x = encoder(x)
            blocks.append(x)

        # residual blocks
        for resblock in self.resblocks:
            x = resblock(x)

        # decoder
        for i, decoder in enumerate(self.decoders):
            x = decoder(self.apply_skip_connection(x, blocks[self.num_encoders - i - 1]))

        img = self.activation(self.pred(self.apply_skip_connection(x, head)))

        return img

class UNetRecurrent(BaseUNet):
    """
    Recurrent UNet architecture where every encoder is followed by a recurrent convolutional block,
    such as a ConvLSTM or a ConvGRU.
    Symmetric, skip connections on every encoding layer.
    """

    def __init__(self, num_input_channels, num_output_channels=1, skip_type='sum',
                 recurrent_block_type='convlstm', activation='sigmoid', num_encoders=4, base_num_channels=32,
                 num_residual_blocks=2, norm=None, use_upsample_conv=True):
        super(UNetRecurrent, self).__init__(num_input_channels, num_output_channels, skip_type, activation,
                                            num_encoders, base_num_channels, num_residual_blocks, norm,
                                            use_upsample_conv)

        self.head = ConvLayer(self.num_input_channels, self.base_num_channels,
                              kernel_size=5, stride=1, padding=2)  # N x C x H x W -> N x 32 x H x W

        self.encoders = nn.ModuleList()
        for input_size, output_size in zip(self.encoder_input_sizes, self.encoder_output_sizes):
            self.encoders.append(RecurrentConvLayer(input_size, output_size,
                                                    kernel_size=5, stride=2, padding=2,
                                                    recurrent_block_type=recurrent_block_type,
                                                    norm=self.norm))

        self.build_resblocks()
        self.build_decoders()
        self.build_prediction_layer()

    def forward(self, x, prev_states):
        """
        :param x: N x num_input_channels x H x W
        :param prev_states: previous LSTM states for every encoder layer
        :return: N x num_output_channels x H x W
        """

        # head
        x = self.head(x)
        head = x

        if prev_states is None:
            prev_states = [None] * self.num_encoders

        # encoder
        blocks = []
        states = []
        for i, encoder in enumerate(self.encoders):
            x, state = encoder(x, prev_states[i])
            blocks.append(x)
            states.append(state)

        # residual blocks
        for resblock in self.resblocks:
            x = resblock(x)

        # decoder
        for i, decoder in enumerate(self.decoders):
            x = decoder(self.apply_skip_connection(x, blocks[self.num_encoders - i - 1]))

        # tail
        img = self.activation(self.pred(self.apply_skip_connection(x, head)))

        return img, states

class UNetFire(BaseUNet):
    """
    """

    def __init__(self, num_input_channels, num_output_channels=1, skip_type='sum',
                 recurrent_block_type='convgru', base_num_channels=16,
                 num_residual_blocks=2, norm=None, kernel_size=3,
                 recurrent_blocks={'resblock': [0]}):
        super(UNetFire, self).__init__(num_input_channels=num_input_channels,
                                       num_output_channels=num_output_channels,
                                       skip_type=skip_type,
                                       base_num_channels=base_num_channels,
                                       num_residual_blocks=num_residual_blocks,
                                       norm=norm)
        self.kernel_size = kernel_size
        self.recurrent_blocks = recurrent_blocks
        print(self.num_input_channels)
        self.head = RecurrentConvLayer(self.num_input_channels,
                                       self.base_num_channels,
                                       kernel_size=self.kernel_size,
                                       padding=self.kernel_size // 2,
                                       recurrent_block_type=recurrent_block_type,
                                       norm=self.norm)
        self.num_recurrent_units = 1
        self.resblocks = nn.ModuleList()
        recurrent_indices = self.recurrent_blocks.get('resblock', [])
        for i in range(self.num_residual_blocks):
            if i in recurrent_indices or -1 in recurrent_indices:
                self.resblocks.append(RecurrentResidualLayer(
                    in_channels=self.base_num_channels,
                    out_channels=self.base_num_channels,
                    recurrent_block_type=recurrent_block_type,
                    norm=self.norm))
                self.num_recurrent_units += 1
            else:
                self.resblocks.append(ResidualBlock(self.base_num_channels,
                                                    self.base_num_channels,
                                                    norm=self.norm))

        self.pred = ConvLayer(2 * self.base_num_channels if self.skip_type == 'concat' else self.base_num_channels,
                              self.num_output_channels, kernel_size=1, padding=0, activation=None, norm=None)

    def forward(self, x, prev_states):
        """
        :param x: N x num_input_channels x H x W
        :param prev_states: previous LSTM states for every encoder layer
        :return: N x num_output_channels x H x W
        """

        if prev_states is None:
            prev_states = [None] * (self.num_recurrent_units)

        states = []
        state_idx = 0

        # head
        x, state = self.head(x, prev_states[state_idx])
        state_idx += 1
        states.append(state)

        # residual blocks
        recurrent_indices = self.recurrent_blocks.get('resblock', [])
        for i, resblock in enumerate(self.resblocks):
            if i in recurrent_indices or -1 in recurrent_indices:
                x, state = resblock(x, prev_states[state_idx])
                state_idx += 1
                states.append(state)
            else:
                x = resblock(x)

        # tail
        img = self.pred(x)
        return img, states


from unittest import mock
import unittest

import pytest

from .main import some_func

class TestMain(unittest.TestCase):
    @pytest.fixture(autouse=True)
    def _setup_service(self):
        self.mock_object = mock.MagicMock()

    def test_some_func(self):
        assert some_func() == 3

    # def test_mock(self):
    #     assert self.mock_object.some_method.called


from checkov.common.models.enums import CheckResult, CheckCategories
from checkov.cloudformation.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.util.type_forcers import force_list

class ALBListenerTLS12(BaseResourceCheck):

    def __init__(self):
        name = "Ensure that Application Load Balancer Listener is using TLS v1.2"
        id = "CKV_AWS_103"
        supported_resources = ['AWS::ElasticLoadBalancingV2::Listener']
        categories = [CheckCategories.GENERAL_SECURITY]
        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)

    def scan_resource_conf(self, conf):
        """
            validates that ALB Listener is using TLS v1.2
            https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-listener.html
        :param conf: aws_alb_listener configuration
        :return: <CheckResult>
        """

        if 'Properties' in conf.keys():
            if 'Protocol' in conf['Properties'].keys():
                # Check SslPolicy only if protocol is HTTPS or TLS.
                # Other protocols are not intresting within the context of this check.
                if conf['Properties']['Protocol'] in ('HTTPS', 'TLS'):
                    if 'SslPolicy' in conf['Properties'].keys():
                        if conf['Properties']['SslPolicy'].startswith(("ELBSecurityPolicy-FS-1-2", "ELBSecurityPolicy-TLS-1-2")):
                            return CheckResult.PASSED
                    return CheckResult.FAILED
                elif conf['Properties']['Protocol'] in ('TCP', 'UDP', 'TCP_UDP'):
                    return CheckResult.PASSED
                for idx_action, action in enumerate(conf['Properties']['DefaultActions']):
                    redirects = action.get("RedirectConfig", [])
                    for idx_redirect, redirect in enumerate(force_list(redirects)):
                        if redirect.get("Protocol", []) == 'HTTPS':
                            return CheckResult.PASSED
        return CheckResult.FAILED

check = ALBListenerTLS12()


#  Bep Marketplace ELE
#  Copyright (c) 2016-2021 Kolibri Solutions
#  License: See LICENSE file or https://github.com/KolibriSolutions/BepMarketplace/blob/master/LICENSE
#
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models

from proposals.models import Proposal
from timeline.models import TimeSlot
from django.conf import settings

class Application(models.Model):
    """
    A student's application to a proposal.
    """
    Priority = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(settings.MAX_NUM_APPLICATIONS)])
    Proposal = models.ForeignKey(Proposal, on_delete=models.CASCADE, related_name='applications')
    Student = models.ForeignKey(User, on_delete=models.CASCADE, related_name='applications')
    Timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.Student.get_username() + " to " + self.Proposal.__str__()

    class Meta:
        ordering = ["Priority"]

class Distribution(models.Model):
    """A student distributed to a proposal.x"""
    Proposal = models.ForeignKey(Proposal, on_delete=models.PROTECT, related_name='distributions')
    Student = models.ForeignKey(User, on_delete=models.CASCADE, related_name='distributions')
    TimeSlot = models.ForeignKey(TimeSlot, on_delete=models.PROTECT, related_name='distributions')
    Application = models.OneToOneField(Application, on_delete=models.SET_NULL, blank=True, null=True, related_name='distributions')

    def TotalGrade(self):
        """
        Return total grade of student as not-rounded float
        :return:
        """
        return sum([r.Grade * r.Category.Weight for r in self.results.all()]) / 100

    def TotalGradeRounded(self):
        """
        Grade rounded to half points.
        :return:
        """
        return round(self.TotalGrade() * 2, 0) / 2

    def missing_files(self):
        return self.TimeSlot.filetypes.exclude(pk__in=self.files.values_list('Type', flat=True))

    def missing_file_gradings(self):
        return self.files.filter(Type__CheckedBySupervisor=True).filter(staffresponse__isnull=True)

    def __str__(self):
        return self.Proposal.Title + " to " + self.Student.usermeta.get_nice_name() + " (" + self.Student.username + ")"


"""             Tuple as Data Structure
We have see how we interpreted tuples as data structures

The position of the object contained in the tuple gives it meaning

For example, we can represent a 2D coordinate as: (10, 20)
                                                    x   y

If pt is a position tuple, we can retrieve the x and    x, y = pt      or  x = pt[0]
y coordinates using:                                                       y = py[1]

For example, to calculate the distance of pt from the origin we could write:

dist = math.sgrt(pt[0] ** 2 + pt[1] ** 2)

Now this is not very readable, and if someone sees this code they will have ti know thatpt[0] mans the x-coordinate and pt[1] means the y-coordinate.

This is not very transparent.

            # Using a class instead.
At this point, in order to make things clearer for the reader (not the complier, the reader), we might want to approach this using a class method instead.

"""
class Point2D:
    def __init__(self, x, y):
        self.x = x


#!/usr/bin/python3

import os
import sys
import math

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import data_utils

load_fn = data_utils.load_cls_train_val
balance_fn = None
map_fn = None
keep_remainder = True
save_ply_fn = None

num_class = 40

batch_size = 32
sample_num = 512
num_epochs = 4096
step_val = 500

learning_rate_base = 0.01
decay_steps = 8000
decay_rate = 0.5
learning_rate_min = 1e-6

weight_decay = 1e-5

jitter = 0.0
jitter_val = 0.0
jitter_test = 0.0

rotation_range = [0, 0, 0, 'u']
rotation_range_val = [0, 0, 0, 'u']
rotation_range_test = [0, 0, 0, 'u']
rotation_order = 'rxyz'

scaling_range = [0, 0, 0, 'g']
scaling_range_val = [0, 0, 0, 'u']
scaling_range_test = [0, 0, 0, 'u']

sample_num_variance = 1 // 8
sample_num_clip = 1 // 4

x = 3

xconv_param_name = ('K', 'D', 'P', 'C', 'links')
xconv_params = [dict(zip(xconv_param_name, xconv_param)) for xconv_param in
                [(8, 1, -1, 16 * x, []),
                 (12, 2, 384, 32 * x, []),
                 (16, 2, 128, 64 * x, []),
                 (16, 3, 128, 128 * x, [])]]

with_global = True

fc_param_name = ('C', 'dropout_rate')
fc_params = [dict(zip(fc_param_name, fc_param)) for fc_param in
             [(128 * x, 0.0),
              (64 * x, 0.8)]]

sampling = 'random'

optimizer = 'adam'
epsilon = 1e-2

data_dim = 6
use_extra_features = False
with_X_transformation = True
sorting_method = None


from __future__ import print_function, absolute_import, division  # makes KratosMultiphysics backward compatible with python 2.6 and 2.7
#import kratos core and applications
import KratosMultiphysics
import KratosMultiphysics.DelaunayMeshingApplication as KratosDelaunay
import KratosMultiphysics.PfemFluidDynamicsApplication as KratosPfemFluid
from importlib import import_module

def CreateMeshingDomain(main_model_part, custom_settings):
    return FluidMeshingDomain(main_model_part, custom_settings)

class FluidMeshingDomain(object):

    ##constructor. the constructor shall only take care of storing the settings
    ##and the pointer to the main_model part.
    ##
    ##real construction shall be delayed to the function "Initialize" which
    ##will be called once the mesher is already filled
    def __init__(self, main_model_part, custom_settings):

        self.echo_level = 1
        self.main_model_part = main_model_part

        ##settings string in json format
        default_settings = KratosMultiphysics.Parameters("""
        {
	    "python_module": "meshing_domain",
            "model_part_name": "model_part_name",
            "alpha_shape": 2.4,
            "offset_factor": 0.0,
            "meshing_strategy":{
               "python_module": "meshing_strategy",
               "meshing_frequency": 0.0,
               "remesh": false,
               "refine": false,
               "reconnect": false,
               "transfer": false,
               "constrained": false,
               "mesh_smoothing": false,
               "variables_smoothing": false,
               "elemental_variables_to_smooth":[],
               "reference_element_type": "Element2D3N",
               "reference_condition_type": "CompositeCondition2D2N"
            },
            "spatial_bounding_box":{
                "use_bounding_box" : true,
                "initial_time"     : 0.0,
                "final_time"       : 1000.0,
                "upper_point"      : [10,10,10],
                "lower_point"      : [-10,-10,-10]
            },
            "spatial_refining_box"            : {
                    "use_refining_box" : false,
                    "mesh_size"        : 0.1,
                    "initial_time"     : 0.0,
                    "final_time"       : 1,
                    "upper_point"      : [10,10,10],
                    "lower_point"      : [-10,-10,-10]
            },
            "refining_parameters":{
               "critical_size": 0.0,
               "threshold_variable": "PLASTIC_STRAIN",
               "reference_threshold" : 0.0,
               "error_variable": "NORM_ISOCHORIC_STRESS",
               "reference_error" : 0.0,
               "add_nodes": true,
               "insert_nodes": false,
               "remove_nodes": {
                   "apply_removal": false,
                   "on_distance": false,
                   "on_threshold": false,
                   "on_error": false
               },
               "remove_boundary": {
                   "apply_removal": false,
                   "on_distance": false,
                   "on_threshold": false,
                   "on_error": false
               },
               "refine_elements": {
                   "apply_refinement": false,
                   "on_distance": false,
                   "on_threshold": false,
                   "on_error": false
               },
               "refine_boundary": {
                   "apply_refinement": false,
                   "on_distance": false,
                   "on_threshold": false,
                   "on_error": false
               }
            },
            "elemental_variables_to_transfer":[]
        }
        """)

        ##overwrite the default settings with user-provided parameters
        self.settings = custom_settings
        self.settings.ValidateAndAssignDefaults(default_settings)

        #construct the meshing strategy
        python_module_name = "KratosMultiphysics.PfemFluidDynamicsApplication"
        full_module_name = python_module_name + "." + self.settings["meshing_strategy"]["python_module"].GetString()
        meshing_module = import_module(full_module_name)
        #meshing_module = __import__(self.settings["meshing_strategy"]["python_module"].GetString())
        self.MeshingStrategy = meshing_module.CreateMeshingStrategy(self.main_model_part, self.settings["meshing_strategy"])

        self.active_remeshing = False
        if( self.settings["meshing_strategy"]["remesh"].GetBool() or self.settings["meshing_strategy"]["transfer"].GetBool() ):
            self.active_remeshing = True

        print("::[Meshing_Domain]:: (",self.settings["model_part_name"].GetString()," ) -BUILT-")

    ####

    def Initialize(self):

        print("::[Meshing Domain]:: -START-")

        self.dimension = self.main_model_part.ProcessInfo[KratosMultiphysics.SPACE_DIMENSION]

        # Set MeshingParameters
        self.SetMeshingParameters()

        # Meshing Stratety
        self.MeshingStrategy.SetEchoLevel(self.echo_level)
        self.MeshingStrategy.Initialize(self.MeshingParameters, self.dimension)

        print("::[Meshing Domain]:: -END- ")

    ####

    #
    def SetInfoParameters(self):

        # Create InfoParameters
        self.InfoParameters  = KratosDelaunay.MeshingInfoParameters()
        self.InfoParameters.Initialize()

    #
    def SetTransferParameters(self):

        # Create TransferParameters
        self.TransferParameters = KratosDelaunay.TransferParameters()
        transfer_variables = self.settings["elemental_variables_to_transfer"]
        #for variable in transfer_variables:
        #    self.TransferParameters.SetVariable( KratosMultiphysics.KratosGlobals.GetVariable( variable.GetString() ) )
        for i in range(0, transfer_variables.size() ):
            self.TransferParameters.SetVariable(KratosMultiphysics.KratosGlobals.GetVariable(transfer_variables[i].GetString()))

    #
    def SetRefiningParameters(self):

        # Create RefiningParameters
        self.RefiningParameters = KratosDelaunay.RefiningParameters()
        self.RefiningParameters.Initialize()

        # parameters
        self.RefiningParameters.SetAlphaParameter(self.settings["alpha_shape"].GetDouble())

        # set mesh refinement in box
        size = self.dimension
        refining_box = self.settings["spatial_refining_box"]
        if(refining_box["use_refining_box"].GetBool()):
            self.MeshingParameters.SetUseRefiningBox(True)
            self.MeshingParameters.SetRefiningBoxMinimumPoint(refining_box["lower_point"][0].GetDouble(),refining_box["lower_point"][1].GetDouble(),refining_box["lower_point"][2].GetDouble())
            self.MeshingParameters.SetRefiningBoxMaximumPoint(refining_box["upper_point"][0].GetDouble(),refining_box["upper_point"][1].GetDouble(),refining_box["upper_point"][2].GetDouble())
            self.MeshingParameters.SetRefiningBoxTimeInterval(refining_box["initial_time"].GetDouble(),refining_box["final_time"].GetDouble())
            self.MeshingParameters.SetRefiningBoxMeshSize(refining_box["mesh_size"].GetDouble())

        removing_options = KratosMultiphysics.Flags()

        #remove nodes
        remove_nodes = self.settings["refining_parameters"]["remove_nodes"]
        removing_options.Set(KratosDelaunay.MesherUtilities.REMOVE_NODES, remove_nodes["apply_removal"].GetBool())
        removing_options.Set(KratosDelaunay.MesherUtilities.REMOVE_NODES_ON_DISTANCE, remove_nodes["on_distance"].GetBool())
        removing_options.Set(KratosDelaunay.MesherUtilities.REMOVE_NODES_ON_ERROR, remove_nodes["on_error"].GetBool())
        removing_options.Set(KratosDelaunay.MesherUtilities.REMOVE_NODES_ON_THRESHOLD, remove_nodes["on_threshold"].GetBool())

        #remove boundary
        remove_boundary = self.settings["refining_parameters"]["remove_boundary"]
        removing_options.Set(KratosDelaunay.MesherUtilities.REMOVE_BOUNDARY_NODES, remove_boundary["apply_removal"].GetBool())
        removing_options.Set(KratosDelaunay.MesherUtilities.REMOVE_BOUNDARY_NODES_ON_DISTANCE, remove_boundary["on_distance"].GetBool())
        removing_options.Set(KratosDelaunay.MesherUtilities.REMOVE_BOUNDARY_NODES_ON_ERROR, remove_boundary["on_error"].GetBool())
        removing_options.Set(KratosDelaunay.MesherUtilities.REMOVE_BOUNDARY_NODES_ON_THRESHOLD, remove_boundary["on_threshold"].GetBool())

        refining_options = KratosMultiphysics.Flags()
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE, self.settings["meshing_strategy"]["refine"].GetBool())
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_ADD_NODES, self.settings["refining_parameters"]["add_nodes"].GetBool())
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_INSERT_NODES, self.settings["refining_parameters"]["insert_nodes"].GetBool())

        #refine elements
        refine_elements = self.settings["refining_parameters"]["refine_elements"]
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_ELEMENTS, refine_elements["apply_refinement"].GetBool())
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_ELEMENTS_ON_DISTANCE, refine_elements["on_distance"].GetBool())
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_ELEMENTS_ON_ERROR, refine_elements["on_error"].GetBool())
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_ELEMENTS_ON_THRESHOLD, refine_elements["on_threshold"].GetBool())

        #refine boundary
        refine_boundary = self.settings["refining_parameters"]["refine_boundary"]
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_BOUNDARY, refine_boundary["apply_refinement"].GetBool())
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_BOUNDARY_ON_DISTANCE, refine_boundary["on_distance"].GetBool())
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_BOUNDARY_ON_ERROR, refine_boundary["on_error"].GetBool())
        refining_options.Set(KratosDelaunay.MesherUtilities.REFINE_BOUNDARY_ON_THRESHOLD, refine_boundary["on_threshold"].GetBool())

        self.RefiningParameters.SetRefiningOptions(refining_options)
        self.RefiningParameters.SetRemovingOptions(removing_options)

    #
    def SetMeshingParameters(self):

        # Create MeshingParameters
        self.MeshingParameters = KratosDelaunay.MeshingParameters()
        self.MeshingParameters.Initialize()

        self.MeshingParameters.SetSubModelPartName(self.settings["model_part_name"].GetString())

        if(self.active_remeshing):

            self.MeshingParameters.SetAlphaParameter(self.settings["alpha_shape"].GetDouble())
            self.MeshingParameters.SetOffsetFactor(self.settings["offset_factor"].GetDouble())

            self.SetInfoParameters()
            self.SetTransferParameters()
            self.SetRefiningParameters()

            self.MeshingParameters.SetInfoParameters(self.InfoParameters)
            self.MeshingParameters.SetTransferParameters(self.TransferParameters)
            self.MeshingParameters.SetRefiningParameters(self.RefiningParameters)

            bounding_box = self.settings["spatial_bounding_box"]
            if(bounding_box["use_bounding_box"].GetBool()):
              self.MeshingParameters.SetUseBoundingBox(True)
              self.MeshingParameters.SetBoundingBoxLowerPoint(bounding_box["lower_point"][0].GetDouble(),bounding_box["lower_point"][1].GetDouble(),bounding_box["lower_point"][2].GetDouble())
              self.MeshingParameters.SetBoundingBoxUpperPoint(bounding_box["upper_point"][0].GetDouble(),bounding_box["upper_point"][1].GetDouble(),bounding_box["upper_point"][2].GetDouble())
              self.MeshingParameters.SetBoundingBoxTimeInterval(bounding_box["initial_time"].GetDouble(),bounding_box["final_time"].GetDouble())

    #
    def ExecuteMeshing(self):

        if( self.active_remeshing ):
            self.MeshingStrategy.GenerateMesh()

    #
    def Check(self):

        # set mesher utilities
        self.mesher_utils = KratosDelaunay.MesherUtilities()

        # set the domain labels to mesh mesher
        critical_mesh_size = self.settings["refining_parameters"]["critical_size"].GetDouble()

        critical_radius = self.mesher_utils.CheckCriticalRadius(self.main_model_part,critical_mesh_size)
        print(" CriticalRadius ", critical_radius)

    #
    def Active(self):
        return self.active_remeshing

    #
    def SetEchoLevel(self, echo_level):
        self.echo_level = echo_level

    #
    def GetVariables(self):

        nodal_variables = []
        transfer_variables = self.settings["elemental_variables_to_transfer"]
        for i in range(0, transfer_variables.size() ):
            nodal_variables.append(transfer_variables[i].GetString())

        return nodal_variables

    #
    def ComputeAverageMeshParameters(self):

        MesherUtils = KratosDelaunay.MesherUtilities();
        self.domain_volume =  MesherUtils.ComputeModelPartVolume(self.main_model_part)
        self.element_mean_volume = 0

        number_of_elements =  self.main_model_part.NumberOfElements()
        nodes_for_element  =  self.main_model_part.ProcessInfo[KratosMultiphysics.SPACE_DIMENSION] + 1

        if(number_of_elements != 0):
            self.element_mean_volume = self.domain_volume/float(number_of_elements*nodes_for_element)

        self.RefiningParameters.SetMeanVolume(self.element_mean_volume)

    #
    def GetMeanVolume(self):

        return self.element_mean_volume

    #
    def GetTotalVolume(self):

        return self.domain_volume

    #
    def ComputeInitialAverageMeshParameters(self):

        self.mesh_parameters =  KratosPfemFluid.ComputeAveragePfemMeshParameters(self.main_model_part, self.MeshingParameters,self.echo_level)
        self.mesh_parameters.Execute()

        # numFluid=0
        # mean_nodal_h=0
        # for node in self.main_model_part.Nodes:
        #     if (node.Is(KratosMultiphysics.FLUID)):
        #         numFluid+=1
        #         nodal_h=node.GetSolutionStepValue(KratosMultiphysics.NODAL_H)
        #         mean_nodal_h+=nodal_h

        # mean_nodal_h*=1.0/numFluid;

        # self.RefiningParameters.SetCriticalRadius(mean_nodal_h)
        # self.RefiningParameters.SetInitialRadius(mean_nodal_h)

        # delta_time = self.main_model_part.ProcessInfo[KratosMultiphysics.DELTA_TIME]
        # self.main_model_part.ProcessInfo.SetValue(KratosPfemFluid.INITIAL_DELTA_TIME,delta_time)
        # self.main_model_part.ProcessInfo.SetValue(KratosPfemFluid.CURRENT_DELTA_TIME,delta_time)
        # self.main_model_part.ProcessInfo.SetValue(KratosMultiphysics.PREVIOUS_DELTA_TIME,delta_time)
        # self.main_model_part.ProcessInfo.SetValue(KratosPfemFluid.TIME_INTERVAL_CHANGED,False)

    def SetTimeDataOnProcessInfo(self):

        delta_time = self.main_model_part.ProcessInfo[KratosMultiphysics.DELTA_TIME]
        self.main_model_part.ProcessInfo.SetValue(KratosPfemFluid.INITIAL_DELTA_TIME,delta_time)
        self.main_model_part.ProcessInfo.SetValue(KratosPfemFluid.CURRENT_DELTA_TIME,delta_time)
        self.main_model_part.ProcessInfo.SetValue(KratosMultiphysics.PREVIOUS_DELTA_TIME,delta_time)
        self.main_model_part.ProcessInfo.SetValue(KratosPfemFluid.TIME_INTERVAL_CHANGED,False)

    #