#!/usr/bin/env python

import re
from ParseRules import QuenbRuleParser
from bottle import abort

def setup(db):
    """
    Populates the initial rules/actions database.
    """
    db.execute("""CREATE TABLE IF NOT EXISTS actions
               (id INTEGER PRIMARY KEY,
               module TEXT,
               function TEXT,
               args TEXT,
               title TEXT, description TEXT)""")

    db.execute("""CREATE TABLE IF NOT EXISTS rules
               (id INTEGER PRIMARY KEY,
               priority INT NOT NULL, rule TEXT,
               action INTEGER NOT NULL,
               FOREIGN KEY(action) REFERENCES actions(id))""")

    db.execute("""CREATE TABLE IF NOT EXISTS oneshot_rules
               (id INTEGER PRIMARY KEY,
               priority INT NOT NULL, rule TEXT,
               action INTEGER NOT NULL,
               FOREIGN KEY(action) REFERENCES actions(id))""")

    # TODO The default action is hit if there is no configuration
    # on the server, so make it something funny.
    db.execute("""INSERT OR IGNORE INTO actions
               (id, module, function, args, title, description)
               VALUES (
                 0, 'quenb-builtin', 'display_image', 'http://placekitten.com/$window_width/$window_height',
                 'Default', 'Default rule if nothing else matches'
               )""")

    # There must always be a rule at the bottom. Well, I say there must
    # be.
    if not list(db.execute("SELECT * FROM rules")):
        db.execute("""INSERT OR IGNORE INTO rules
                      (id, priority, rule, action)
                      VALUES (0, 0, "true", 0)""")

def getRules(db):
    """
    Given the QuenB database, return a result with rule/action tuples
    """
    with db:
        oneshots = [dict(row) for row in db.execute("""
          SELECT oneshot_rules.id AS id, priority, rule, action, module, function, args, title, description
          FROM oneshot_rules
          INNER JOIN actions
          ON oneshot_rules.action = actions.id
          ORDER BY priority ASC
        """)]

        main = [dict(row) for row in db.execute("""
          SELECT rules.id AS id, priority, rule, action, module, function, args, title, description
          FROM rules
          INNER JOIN actions
          ON rules.action = actions.id
          ORDER BY priority ASC
        """)]

        return {
            'oneshots' : oneshots,
            'main' : main,
        }

def getRule(db, id):
    """
    Given the QuenB database, return a single rule tuple
    """
    with db:
        return [dict(row) for row in db.execute("""
          SELECT id, module, function, args, title, description
          FROM rules
          WHERE id = ?
        """, id)]

def putRule(db, data):
    """
    Given the QuenB database, create a new Rule with the given settings
    """
    with db:
        for needed in ['priority', 'action', 'rule']:
            if needed not in data or not data[needed]:
                data[needed] = ''

        parser = QuenbRuleParser()
        rule = data['rule']
        if not parser.checkRule(rule):
            abort(400, 'Invalid rule ysntax')

        ok = db.execute("""
         INSERT INTO rules (priority, rule, action)
         VALUES(?, ?, ?)
        """, (data['priority'], data['rule'], data['action']))

        c = db.execute("""
          SELECT rules.id as id, priority, rule, actions.id as action_id, actions.title as action_title
          FROM rules INNER JOIN actions ON(actions.id = rules.action)
          WHERE rules.id = last_insert_rowid()
        """)
        row = c.fetchone()

        if row:
            return dict(row)
        else:
            return None

def postRule(db, id, _data):
    """
    Given the QuenB database, update a Rule with the given settings
    """
    with db:

        # Delete anything we don't like the look of
        data = {}
        for field in _data:
            fieldlc = field.lower().strip()
            if fieldlc in ['priority', 'action', 'rule']:
                data[fieldlc] = _data[field]

        parser = QuenbRuleParser()
        rule = data['rule']
        if not parser.checkRule(rule):
            abort(400, 'Invalid rule ysntax')

        # Build a list of placeholders and values for the SET key=value, key=value clause
        placeholders = []
        fields_values = []
        for field, value in data.iteritems():
            placeholders.append('{} = ?'.format(field))
            fields_values.append(value)
        placeholders = ', '.join(placeholders)

        db.execute("""
         UPDATE rules
         SET {}
         WHERE id = ?
        """.format(placeholders), fields_values + [id])

        c = db.execute("""
          SELECT rules.id as id, priority, rule, actions.id as action_id, actions.title as action_title
          FROM rules INNER JOIN actions ON(actions.id = rules.action)
          WHERE rules.id = ?
        """, (id,))

        row = c.fetchone()

        if row:
            return dict(row)
        else:
            return None

def deleteRule(db, id, oneshot = False):
    """
    Given the QuenB database, delete a rule
    """
    with db:
        if oneshot:
            db.execute("""
              DELETE FROM oneshot_rules
              WHERE id = ?
            """, (id,))
        else:
            db.execute("""
              DELETE FROM rules
              WHERE id = ?
            """, (id,))

def updateRuleField(db, rule_id, field, value):
    """
    Updates a specific field for a rule, used by the fancy-schmancy rules editing table to edit a field at a time.
    """
    with db:
        # A bit hacky, but works around the problem of identifiers not being parameterisable
        field = field.strip().lower()
        if field in ['priority', 'rule', 'action']:

            db.execute("""
            UPDATE rules
            SET {} = ?
            WHERE id = ?
            """.format(field), (value, rule_id))

            # Send back whatever's in the database, whether updated or not
            return [row[0] for row in db.execute("""
            SELECT {} FROM rules WHERE id=?
            """.format(field), (rule_id,))][0]

def getActions(db):
    """
    Given the QuenB database, return a result with action tuples
    """
    with db:
        return [dict(row) for row in db.execute("""
          SELECT id, module, function, args, title, description
          FROM actions
          ORDER BY title ASC
        """)]

def getAction(db, id):
    """
    Given the QuenB database, return a single action tuple
    """
    with db:
        return [dict(row) for row in db.execute("""
          SELECT id, module, function, args, title, description
          FROM actions
          WHERE id = ?
        """, id)]

def _plugin2functions(plugin_spec):
    matches = re.match(r'^(\S+)\.([^.]+)$', plugin_spec)
    if matches:
        module = matches.group(1)
        function = matches.group(2)
    else:
        module = None
        function = data['plugin']

    return (module, function)

def putAction(db, data):
    """
    Given the QuenB database, create a new Action with the given settings
    """
    with db:
        for needed in ['plugin', 'args', 'title', 'description']:
            if needed not in data or not data[needed]:
                data[needed] = ''

        (module, function) = _plugin2functions(data['plugin'])

        db.execute("""
         INSERT INTO actions (module, function, args, title, description)
         VALUES(?, ?, ?, ?, ?)
        """, (module, function, data['args'], data['title'], data['description']))

        c = db.execute("""
          SELECT id, module, function, args, title, description
          FROM actions
          WHERE id = last_insert_rowid()
        """)
        return dict(c.fetchone())

def postAction(db, id, data):
    """
    Given the QuenB database, update an Action with the given settings
    """
    with db:

        # Delete anything we don't like the look of
        for field in data:
            if field not in ['plugin', 'args', 'title', 'description']:
                del data[field]

        if 'plugin' in data:
            (module, function) = _plugin2functions(data['plugin'])

            del data['plugin']
            data['module'] = module
            data['function'] = function

        # Build a list of placeholders and values for the SET key=value, key=value clause
        placeholders = []
        fields_values = []
        for field, value in data.iteritems():
            placeholders.append('{} = ?'.format(field))
            fields_values.append(value)
        placeholders = ', '.join(placeholders)

        db.execute("""
         UPDATE actions
         SET {}
         WHERE id = ?
        """.format(placeholders), fields_values + [id])

        c = db.execute("""
          SELECT id, module||'.'||function as plugin, args, title, description
          FROM actions
          WHERE id = ?
        """, (id,))

        row = c.fetchone()

        if row:
            return dict(row)
        else:
            return None

def deleteAction(db, id):
    """
    Given the QuenB database, delete an action
    """
    with db:
        db.execute("""
          DELETE FROM actions
          WHERE id = ?
        """, (id,))

def updateActionField(db, action_id, field, value):
    """
    Updates a specific field for an action, used by the fancy-schmancy action editing table to edit a field at a time.
    """
    with db:
        # A bit hacky, but works around the problem of identifiers not being parameterisable
        field = field.strip().lower()
        if field in ['title', 'description']:

            db.execute("""
            UPDATE actions
            SET {} = ?
            WHERE id = ?
            """.format(field), (value, action_id))

            # Send back whatever's in the database, whether updated or not
            return [row[0] for row in db.execute("""
            SELECT {} FROM actions WHERE id=?
            """.format(field), (action_id,))][0]


"""####################################################################
    Title: Solving the source localization problem of spinal cord
    potentials for electric dipoles in the cervical spinal cord
    Subtitle: Main
    Author: Markus E. Oberndorfer
####################################################################"""

# ---- IMPORT PACKAGES ----
from pathlib import Path
import matplotlib.pyplot as plt
from os.path import isfile, isdir
from os import mkdir
from numpy import load

# ----- IMPORT CUSTOM FUNCTIONS -----
from custom_functions import ModelSelection, LoadData, ProcessData
from custom_functions import DipolesLeadfield, ElectrodePositions
from custom_functions import ChannelPlotWP_1, ChannelPlotWP_2
from custom_functions import GetWaveformPoints, sLORETA, ShowSolution
from custom_functions import CalcHyperparams, VisualizeHyperParams

# ---- IMPORT PARAMETERS ----
from params import params_elec, mat_conduc

######### SET THESE VARIABLES #########
#-------------------------------------#
user_ID = 'XYZ'
num_dipoles_per_section = 2
fs = 512
alpha = 0.05
# These parameters can be changed if needed
HYPERPARAM_SEARCH = True
PLOT_HP_DATA = True
#------------------------------------#

################## MAIN ###################
print('\n--------------------------------------------')
print('Starting "Source Localization: Spinal Cord"')
print('-------------------------------------------- \n \n')

''' Setup '''
# Create folder structure
main_path = Path(__file__).parent
user_folder = 'user_' + user_ID
user_folder = main_path / 'data' / user_folder
images_folder = user_folder / 'images'
processed_data_folder = user_folder / 'processed_data'
if not isdir(user_folder):
    exit('Create a user folder. See ReadMe.md file.')
if not isdir(images_folder):
    mkdir(images_folder)
if not isdir(processed_data_folder):
    mkdir(processed_data_folder)

# Make paths for processed data
processed_data_path = main_path / 'data' / user_folder / 'processed_data'
processed_data_path = processed_data_path / 'data_avg.npy'

processed_data_path_par = main_path / 'data' / user_folder / 'processed_data'
processed_data_path_par = processed_data_path_par / 'data_participants.npy'

#########################################
'''' ======== LOAD ALL FILES ======== '''
#########################################

# Select the model or load existing model
mesh, params_geom, loc_C7, maxh_ = ModelSelection(user_ID, main_path)

# Load the data and process it or load already processed data
if isfile(processed_data_path) and isfile(processed_data_path_par):
    data_SCP = load(processed_data_path)
    data_SCP_participants = load(processed_data_path_par)
else:
    _ , data_SCP, data_marker, num_participants = LoadData(main_path,
                                                           user_folder)
    data_SCP, data_SCP_participants = ProcessData(data_SCP, data_marker,
                                                  num_participants, fs,
                                                  main_path, user_ID)

# Plot the average signal with the waveform points being marked
ChannelPlotWP_1(data_SCP, fs, save = True, main_path = main_path,
                 user_ID = user_ID)
ChannelPlotWP_2(data_SCP, fs, save = True, main_path = main_path,
                 user_ID = user_ID)

# Define the position of the electrodes (depending on C7)
electrodes, N_E = ElectrodePositions(loc_C7, params_elec, params_geom)

############################################
'''' ==== CALCULATE HYPERPARAMETERS ==== '''
############################################

if HYPERPARAM_SEARCH:
    # These following two lists are the hyperparameter values that are tested
    alpha_hp = [0.005, 0.01, 0.05, 0.1, 0.2, 0.35, 0.5]
    num_dip_hp = [1,2,3,4,5]

    if PLOT_HP_DATA:
        hp, data_plot_hp = CalcHyperparams(params_geom, num_dip_hp, alpha_hp,
                                           electrodes, user_ID, main_path,
                                           data_SCP, mesh, mat_conduc, maxh_,
                                           fs, plot_data = True)
        F_vals_P1 = data_plot_hp[0]
        F_vals_N1 = data_plot_hp[1]
        F_vals_P2 = data_plot_hp[2]

        # Visualization of the Hyperparameters' Influence on
        # the Error-Functional
        VisualizeHyperParams(F_vals_P1, num_dip_hp, alpha_hp, 'P1',
                              save=True, main_path=main_path,
                              user_ID = user_ID)
        VisualizeHyperParams(F_vals_N1, num_dip_hp, alpha_hp, 'N1',
                              save=True, main_path=main_path,
                              user_ID = user_ID)
        VisualizeHyperParams(F_vals_P2, num_dip_hp, alpha_hp, 'P2',
                              save=True, main_path=main_path,
                              user_ID = user_ID)
    else:
        hp = CalcHyperparams(params_geom, num_dip_hp, alpha_hp,
                            electrodes, user_ID, main_path,
                            data_SCP, mesh, mat_conduc, maxh_,
                            fs, plot_data = False)

    alpha = hp[0]
    num_dipoles_per_section = hp[1]

#########################################
'''' ==== SOLVE INVERSE PROBLEM ==== '''
#########################################

# Create dipoles that are necessary for the Leadfield-Calculation
dipoles, z_vals = DipolesLeadfield(params_geom, num_dipoles_per_section)
# Solve the inverser problem
J = sLORETA(data_SCP, mesh, mat_conduc, maxh_, dipoles, electrodes,
            user_ID, main_path, alpha)

print('Inverse Problem calculated.')

#####################################
'''' ==== VISUALIZE SOLUTION ==== '''
#####################################

# Calculate the Waveform-Points, at which the solution is visualized
P1, N1, P2 = GetWaveformPoints(J, data_SCP, fs)
J_WP = [J[P1,:], J[N1,:], J[P2,:]]

# Create a 3D image of the solution at all time points P1, N1 and P2
# view options:
# frontal, lower_frontal, upper_frontal, upper_right, upper_left
ShowSolution(J_WP, params_geom, z_vals, num_dipoles_per_section,
             view = 'frontal', save = True, path = images_folder)

plt.show()

print('\n--------------------------------------------')
print('Finished "Source Localization: Spinal Cord"')
print('-------------------------------------------- \n \n')


import numpy as np
import pandas as pd

import torch
import torch.nn.functional as f
from torch.utils.data import Dataset, DataLoader, SequentialSampler
import torchvision.transforms as transforms

class MxIFReader(Dataset):
    def __init__(self, data_csv_path, split_name, marker_panel, input_markers, output_markers, training=False, img_size=256, percent=100):
        """
        Custom PyTorch dataset for reading and preprocessing multi-channel multiplexed images.

        Args:
            data_csv_path (str): Path to a CSV file with Image_Path and Split_Name columns.
            split_name (str): Name of the split (e.g., 'train', 'valid', 'test', 'inference').
            marker_panel (list): A list of marker names in the same order as the channels in the MXIF images
            input_markers (list): A list of marker names to be used as input to the model.
            output_markers (list): A list of marker names to be used as output to the model.
            training (bool, optional): If True, preprocesses the images for training; otherwise, for validation. Defaults to False.
            img_size (int, optional): The size of the images to be returned by the data loader. Defaults to 256.
            percent (int, optional): Percentage of samples to include from the data. Defaults to 100%.
        """
        self.data_csv_path = data_csv_path
        self.split_name = split_name
        self.marker_panel = marker_panel
        self.input_markers = input_markers
        self.output_markers = output_markers
        self.training = training
        self.img_size = img_size

        # Read the CSV file and filter rows based on split_name
        df = pd.read_csv(self.data_csv_path)
        df = df[df['Split_Name'] == split_name]
        self.x = df['Image_Path'].tolist()

        if percent < 100:
            # Randomly select a subset of samples based on percent
            rand_perm = np.random.permutation(len(self.x))
            sample_count = int(len(self.x)*percent/100)
            rand_perm = rand_perm[:sample_count]
            self.x = [self.x[idx] for idx in rand_perm]

        # Get the channel indexes for input and output markers
        self.input_channel_indexes = []
        for marker_name in self.input_markers:
            self.input_channel_indexes.append(self.marker_panel.index(marker_name.upper()))

        self.output_channel_indexes = []
        for marker_name in self.output_markers:
            self.output_channel_indexes.append(self.marker_panel.index(marker_name.upper()))

    def __len__(self):
        return len(self.x)

    def __getitem__(self, idx):
        """
        Returns a tuple containing the input and output images, image path, and image dimensions.

        Args:
            idx (int): Index of the sample.

        Returns:
            tuple: Tuple containing input_img, output_img, img_path, img_dim.
        """
        img_path = self.x[idx]
        img = np.load(img_path)  # Load the image as a numpy array (N, H, W) where N is the number of markers
        img = torch.tensor(img / 255.0)  # Convert to tensor and normalize to [0, 1]
        img_dim = [img.shape[1], img.shape[2]]

        if self.training:
            img = self.preprocess_train(img, self.img_size)
        else:
            img = self.preprocess_valid(img, self.img_size)

        input_img = torch.zeros((len(self.input_channel_indexes), img.shape[1], img.shape[2]))
        output_img = torch.zeros((len(self.output_channel_indexes), img.shape[1], img.shape[2]))

        for i in range(len(self.input_channel_indexes)):
            input_img[i, :, :] = img[self.input_channel_indexes[i], :, :]

        for i in range(len(self.output_channel_indexes)):
            output_img[i, :, :] = img[self.output_channel_indexes[i], :, :]

        return input_img, output_img, img_path, img_dim

    @staticmethod
    def preprocess_train(img, target_size):
        """
        Preprocesses the image for training by applying random crops, horizontal, and vertical flips.

        Args:
            img (torch.Tensor): Input image tensor.
            target_size (int): Target size for random crop.

        Returns:
            torch.Tensor: Preprocessed image tensor.
        """
        preprocess = transforms.Compose([
            transforms.RandomCrop(target_size),
            transforms.RandomHorizontalFlip(),
            transforms.RandomVerticalFlip()
        ])
        img = preprocess(img)
        img = torch.rot90(img, np.random.randint(4), [1, 2])
        return img

    @staticmethod
    def preprocess_valid(img, target_size):
        """
        Preprocesses the image for validation by applying center crop and padding if necessary.

        Args:
            img (torch.Tensor): Input image tensor.
            target_size (int): Target size for center crop.

        Returns:
            torch.Tensor: Preprocessed image tensor.
        """
        if target_size > img.shape[1]:
            rows = target_size - img.shape[1]
            cols = target_size - img.shape[2]
            img = f.pad(img, (0, cols, 0, rows), "constant", 0)
        preprocess = transforms.Compose([
            transforms.CenterCrop(target_size)
        ])
        img = preprocess(img)
        return img

    @staticmethod
    def get_data_loader(dataset, batch_size=4, training=False, num_workers=4):
        """
        Returns a data loader for the given dataset.

        Args:
            dataset (MxIFReader): Custom dataset object.
            batch_size (int, optional): Batch size. Defaults to 4.
            training (bool, optional): If True, creates a training data loader; otherwise, creates a validation data loader. Defaults to False.
            num_workers (int, optional): Number of workers for data loading. Defaults to 4.

        Returns:
            torch.utils.data.DataLoader: Data loader object.
        """
        if training:
            loader = DataLoader(dataset, batch_size=batch_size, shuffle=True, drop_last=True, num_workers=num_workers)
        else:
            loader = DataLoader(dataset, batch_size=batch_size, sampler=SequentialSampler(dataset), drop_last=False, num_workers=num_workers)
        return loader


# Write a program that reads three numbers and counts the number of even numbers.
num1, num2, num3 = int(input('Enter the first number:')), int(input('Second:')), int(input('Last:'))
count = 0
if num1 % 2 == 0:
    count += 1
if num2 % 2 == 0:
    count += 1
if num3 % 2 == 0:
    count += 1
print('Number of even numbers:', count)


"""LRUCache"""
from collections import deque
import logging
import logging.config
import argparse

log_conf = {
    "version": 1,
    "formatters": {
        "for_file": {
            "format": "%(asctime)s\t%(levelname)s\t%(message)s",
        },
        "for_std": {
            "format": "%(message)s",
        },
    },
    "handlers": {
        "file_handler": {
            "class": "logging.FileHandler",
            "level": "DEBUG",
            "filename": "cache.log",
            "formatter": "for_file",

        },
        "std_handler": {
            "level": "WARNING",
            "formatter": "for_std",
            "class": "logging.StreamHandler",
        },
    },
    "loggers": {
        "file": {
            "level": "DEBUG",
            "handlers": ["file_handler"],
        },
        "std": {
            "level": "DEBUG",
            "handlers": ["std_handler", "file_handler"]
        },
    },
}

class LRUCache:
    """LRUCache"""

    def __init__(self, limit=42, logging_method='file'):
        self.limit = limit
        self.dictionary = {}
        self.order = deque()
        self.logger = logging.getLogger(logging_method)
        self.logger.info("Created LRUCache with parameters: limit=%s, "
                         "logging_method=%s.", limit, logging_method)

    def get(self, key=None):
        """LRUCache"""
        if key is None:
            self.logger.error('Trying to call LRUCache.get() '
                              'without parameter.')
        if key in self.dictionary:
            self.order.remove(key)
            self.order.append(key)
        else:
            self.logger.warning('Trying to get key from LRUCache that '
                                'does not exists: "%s"', key)
        return self.dictionary.get(key)

    def set(self, key='', value=''):
        """LRUCache"""
        if not key:
            self.logger.warning("Key field is empty.")
        if not value:
            self.logger.warning("Value field is empty.")
        self.logger.info('Element is added to cache: "%s": "%s"', key, value)
        if key in self.dictionary:
            self.get(key)
            if self.dictionary[key] != value:
                self.dictionary[key] = value
            return
        if len(self.dictionary) >= self.limit:
            to_remove = self.order.popleft()
            self.logger.debug('Key "%s" removed from cache', to_remove)
            self.dictionary.pop(to_remove)
        self.dictionary[key] = value
        self.order.append(key)

if __name__ == '__main__':
    logging.config.dictConfig(log_conf)
    logger = logging.getLogger('file')
    logger.debug('--- ANOTHER ONE START OF THE PROGRAM ---.')

    parser = argparse.ArgumentParser(description='logging_method')
    parser.add_argument('-s', help='logging_method', default='file')
    args = parser.parse_args()
    method = args.s

    cache = LRUCache(limit=1, logging_method=method)
    cache.set('key_1', 'val_1')
    cache.set()
    cache.get('key_2')


# -*- coding: utf-8 -*-

import json
import uuid

from datetime import datetime

import arrow

from collections import OrderedDict

from .datastructures import NotSet

class SerializerBase(object):

    def serialize_response(self, response):
        meta = response.meta
        if meta['pagination'] is not None:
            if meta['pagination']['limit'] is NotSet:
                meta['pagination']['limit'] = None
            if meta['pagination']['offset'] is NotSet:
                meta['pagination']['offset'] = None
        body = self._build_envelope(response_type=response.response_type,
                                    status=response.status_code,
                                    error=response.error,
                                    code=getattr(response, 'code', None),
                                    params=getattr(response, 'params', None),
                                    data=response.get_response_data(),
                                    meta=meta)
        # Remove paginated flag because no longer needed
        try:
            del body['meta']['pagination']['paginated']
        except (TypeError, KeyError):
            pass
        serialized_body = self._serialize_data(body)
        return serialized_body

    @staticmethod
    def _build_envelope(response_type, status, error, code, params, data, meta):
        envelope = OrderedDict()
        envelope['type'] = response_type
        envelope['status'] = status
        envelope['error'] = error
        envelope['error_code'] = code
        envelope['errors'] = [
            {
                'level': 'error',   # Only pass back errors for now
                'code': code,
                'params': params,
            }
        ] if code else None
        envelope['data'] = data
        envelope['meta'] = meta
        return envelope

    def _serialize_data(self, data):
        err_msg = 'This method must be implemented by a subclass.'
        raise NotImplementedError(err_msg)

class JsonSerializer(SerializerBase):

    def _serialize_data(self, data):
        return json.dumps(data, default=handler)

def handler(obj):
    if hasattr(obj, 'isoformat'):
        if isinstance(obj, datetime):
            obj = arrow.get(obj)
        return obj.isoformat()
    elif isinstance(obj, uuid.UUID):
        return str(obj)
    elif isinstance(obj, bytes):
        return obj.decode('utf-8')
    else:
        err_msg = 'Object of type %s with value of %s is not JSON serializable'
        raise TypeError(err_msg % (type(obj), repr(obj)))


#IMPORT PARA A GERAÇÃO DE GRAFICOS
import matplotlib.pyplot as plt

#MEU RU - COMO PEDE NO ENUNCIADO, UTILIZEI OS 3 PRIMEIROS DIGITOS
RU = 3773638
a = 3
b = 7
c = 7

#CRIAÇÃO DO VETOR COM 10 POSIÇOES
vetorX = list(range(1, 11))

#CALCULA OS VALORES DE Y COM A EQUAÇÃO PARA VALOR DE X NO VETOR
y = [a * vetorXi + b * vetorXi - c for vetorXi in vetorX]

#PLOTAR OS PONTOS COM CORES
plt.plot(vetorX[0], y[0], marker = "o", markersize=12, markerfacecolor='blue')
plt.plot(vetorX[1], y[1], marker = "o", markersize=12, markerfacecolor='red')
plt.plot(vetorX[2], y[2], marker = "o", markersize=12, markerfacecolor='green')
plt.plot(vetorX[3], y[3], marker = "o", markersize=12, markerfacecolor='black')
plt.plot(vetorX[4], y[4], marker = "o", markersize=12, markerfacecolor='yellow')
plt.plot(vetorX[5], y[5], marker = "o", markersize=12, markerfacecolor='orange')
plt.plot(vetorX[6], y[6], marker = "o", markersize=12, markerfacecolor='brown')
plt.plot(vetorX[7], y[7], marker = "o", markersize=12, markerfacecolor='pink')
plt.plot(vetorX[8], y[8], marker = "o", markersize=12, markerfacecolor='silver')
plt.plot(vetorX[9], y[9], marker = "o", markersize=12, markerfacecolor='purple')

# NOMEAR EIXO X
plt.xlabel('EIXO X')

# NOMEAR EIXO Y
plt.ylabel('EIXO Y')

#LEGENDA DO GRÁFICO
plt.legend([f'POSIÇÃO X={vetorX[0]} POSIÇÃO Y={y[0]}',
            f'POSIÇÃO X={vetorX[1]} POSIÇÃO Y={y[1]}',
            f'POSIÇÃO X={vetorX[2]} POSIÇÃO Y={y[2]}',
            f'POSIÇÃO X={vetorX[3]} POSIÇÃO Y={y[3]}',
            f'POSIÇÃO X={vetorX[4]} POSIÇÃO Y={y[4]}',
            f'POSIÇÃO X={vetorX[5]} POSIÇÃO Y={y[5]}',
            f'POSIÇÃO X={vetorX[6]} POSIÇÃO Y={y[6]}',
            f'POSIÇÃO X={vetorX[7]} POSIÇÃO Y={y[7]}',
            f'POSIÇÃO X={vetorX[8]} POSIÇÃO Y={y[8]}',
            f'POSIÇÃO X={vetorX[9]} POSIÇÃO Y={y[9]}'])

#GRADE NO GRÁFICO
plt.grid()

# TÍTULO DO GRÁFICO
plt.title('Exercício 02 - EQUAÇÃO LINEAR')

# MOSTRAR GRÁFICO
plt.show()


from contextlib import contextmanager
from typing import List, Tuple, Dict
from datetime import datetime

Reply = Tuple[int, datetime, str, str, int]

CREATE_REPLIES = """CREATE TABLE IF NOT EXISTS replies (
    id SERIAL PRIMARY KEY, origin TIMESTAMP, content TEXT,
    creator_name TEXT, post_id INTEGER,
    FOREIGN KEY(creator_name) REFERENCES users(username),
    FOREIGN KEY(post_id) REFERENCES posts(id)
);"""

INSERT_INTO_REPLIES = "INSERT INTO replies (origin, content, creator_name, post_id) VALUES (%s, %s, %s, %s) RETURNING id;"

# -replies
SELECT_ALL_REPLIES = "SELECT * FROM replies;"
SELECT_REPLIES_IN_POST = "SELECT * FROM replies WHERE post_id = %s;"

EDIT_REPLY = "UPDATE replies SET content = %s where id = %s;"

DELETE_REPLY = "DELETE FROM replies where id = %s;"

@contextmanager
def get_cursor(connection):
    with connection:
        with connection.cursor() as cursor:
            yield cursor

def create_reply(connection, origin: datetime, content: str, creator_name: str, post_id: int) -> int:
    with get_cursor(connection) as cursor:
        cursor.execute(INSERT_INTO_REPLIES, (origin, content, creator_name, post_id))
        reply_id = cursor.fetchone()[0]
        return reply_id

def all_replies(connection):
    with get_cursor(connection) as cursor:
        cursor.execute(SELECT_ALL_REPLIES)
        return cursor.fetchall()

def replies_in_post(connection, post_id: int) -> List[Reply]:
    with get_cursor(connection) as cursor:
        cursor.execute(SELECT_REPLIES_IN_POST, [post_id])
        return cursor.fetchall()

def update_reply(connection, content: str, reply_id):
    with get_cursor(connection) as cursor:
        cursor.execute(EDIT_REPLY, (content, reply_id))

def delete_reply(connection, reply_id: int):
    with get_cursor(connection) as cursor:
        cursor.execute(DELETE_REPLY, [reply_id])


"""add depth and step to comment

Revision ID: 9758751f8e81
Revises: 2c1df37a2e4e
Create Date: 2018-07-06 20:06:23.445170

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '9758751f8e81'
down_revision = '2c1df37a2e4e'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('comment', sa.Column('depth', sa.Integer(), nullable=False))
    op.add_column('comment', sa.Column('step', sa.Integer(), nullable=False))
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('comment', 'step')
    op.drop_column('comment', 'depth')
    # ### end Alembic commands ###


# A neural network -based model for predicting moral reasoning.

import time

import collections

import numpy as np

import ccobra

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms

class MLP(nn.Module):
    def __init__(self, input_size=12, hidden_size=256, output_size=3):
        super(MLP, self).__init__()

        self.input_size = input_size
        self.hidden_size  = hidden_size
        self.output_size = output_size
        self.fc1 = torch.nn.Linear(self.input_size, self.hidden_size)
        self.relu = torch.nn.ReLU()
        self.fc2 = torch.nn.Linear(self.hidden_size, self.output_size)
        self.sigmoid = torch.nn.Sigmoid()

    def forward(self, x):

        hidden = self.fc1(x)
        relu1 = self.relu(hidden)
        output = self.fc2(relu1)
        output = self.sigmoid(output)
        return output

# Input mapping for the different dilemmas
dilemma_mppng =  {"PW-RT": [1,-3,3,-1,1,-5,5,-1], "OB-PW":[0,-4,3,-1,1,-3,3,-1], "RT-OB":[1,-5,5,-1,0,-4,3,-1]}

gender_mppng = {"m": [0], "w": [1]}

output_mppng = {1: [1,0,0], 2: [0,1,0], 3:[0,0,1]}

def create_input(data):
    auxiliary = data['aux']

    dilemma = dilemma_mppng[data['task'][0][0]]
    gender = gender_mppng[auxiliary['Geschlecht']]
    logical = [auxiliary['Logikerfahrung']/5]
    maths = [auxiliary['Mathekenntnisse']/5]
    age = [auxiliary['Alter']/100]
    return dilemma + gender + logical + maths + age

class MLPModel(ccobra.CCobraModel):
    def __init__(self, name='MLP', k=1):
        super(MLPModel, self).__init__(name, ["moral"], ["single-choice"])

        self.net = MLP()

        self.n_epochs = 75

        self.optimizer = optim.SGD(self.net.parameters(),lr=0.01)
        self.loss =  nn.CrossEntropyLoss()

    def pre_train(self, dataset):
        torch.device('cuda' if torch.cuda.is_available() else 'cpu')

        x = []
        y = []

        for subj_train_data in dataset:
            subj_x = []
            subj_y = []
            for seq_train_data in subj_train_data:

                seq_train_data['task'] = seq_train_data['item'].task
                inp = create_input(seq_train_data)

                target = output_mppng[seq_train_data['response']]

                subj_x.append(inp)

                subj_y.append(target)

            x.append(subj_x)
            y.append(subj_y)
        x = np.array(x)
        y = np.array(y)

        self.train_x = torch.from_numpy(x).float()
        self.train_y = torch.from_numpy(y).float()

        self.train_network(self.train_x, self.train_y, self.n_epochs, verbose=True)

    def train_network(self, train_x, train_y, n_epochs, verbose=False):
            print('Starting training...')
            for epoch in range(self.n_epochs):
                start_time = time.time()

                # Shuffle the training data
                perm_idxs = np.random.permutation(np.arange(len(train_x)))
                train_x = train_x[perm_idxs]
                train_y = train_y[perm_idxs]

                losses = []
                for idx in range(len(train_x)):
                    cur_x = train_x[idx]
                    cur_y = train_y[idx]

                    inp = cur_x.view(-1,1,12)

                    outputs = self.net(inp)

                    loss = self.loss(outputs.view(-1,3), cur_y.argmax(1))
                    self.optimizer.zero_grad()
                    loss.backward()
                    self.optimizer.step()

                    losses.append(loss.item())

            print('Epoch {}/{} ({:.2f}s): {:.4f} ({:.4f})'.format(
                epoch + 1, n_epochs, time.time() - start_time, np.mean(losses), np.std(losses)))

            accs = []
            for subj_idx in range(len(self.train_x)):
                pred = self.net(self.train_x[subj_idx].view(-1,1,12))
                pred_max = pred.view(-1,3).argmax(1)
                truth = self.train_y[subj_idx].argmax(1)

                acc = torch.mean((pred_max == truth).float()).item()
                accs.append(acc)

            print('   acc mean: {:.2f}'.format(np.mean(accs)))
            print('   acc std : {:.2f}'.format(np.std(accs)))

            self.net.eval()

    def predict(self, item, **kwargs):
        input = {'task': item.task}
        input['aux'] = kwargs
        x = torch.FloatTensor(create_input(input))
        output = self.net(x.view(1, 1, -1))

        label = np.argmax(output.detach().numpy())

        self.prediction = label + 1

        return self.prediction


# -*- coding: utf-8 -*-
"""
Created on Wed Jun 14 17:31:58 2017

@author: Administrator
"""

#==============================================================================
#用户基本信息子主题
#==============================================================================

import pandas as pd
from pandas import DataFrame
import csv

##用户基本信息
tem = r"D:\mili\Datamart\rawdata_csv_py\applend"
ten = r"D:\mili\Datamart\rawdata_csv_py\appdp"
tmp_dir = r"D:\mili\Datamart\pyscript\submart"

df=pd.read_csv(tem+"\\"+ "user_base_info.csv")

df = df.drop(["ID",
"REMARK",
"CREATED_USER_ID",
"CREATED_USER_NAME",
"CREATED_TIME" ,
"UPDATED_USER_ID" ,
"UPDATED_USER_NAME",
"UPDATED_TIME",
"VERSION"], axis=1)

df.SEX = df.SEX.map({0: '女', 1: '男'})
df.columns = df.columns.str.lower()

csvfile = tmp_dir + '\\'+ "user_base_info.csv"
df.to_csv(csvfile,sep=',',index=False ,encoding = 'utf-8')

#==============================================================================
# 计算总服务费
#==============================================================================
#==============================================================================
# import pandas as pd
# from pandas import DataFrame
# import csv
#
# ##申请审批状态
# tem = r"D:\mili\Datamart\rawdata_csv_py\applend"
# ten = r"D:\mili\Datamart\rawdata_csv_py\appdp"
# tmp_dir = r"D:\mili\Datamart\pyscript\submart"
#
# df=pd.read_csv(tem +"\\"+ "loan_info.csv")
#
# df=df[["apply_code","contract_amount", "loan_amt", "period" ,"service_amt", "loan_date", "status"]]
#
# df=df[df["status"]==304]
# #按照索引删除
# index=list(df[df["loan_date"]=='2017-06-16'].index)
# df.drop(index,axis=0)
# df = df.drop_duplicates(['apply_code'])
#
#
# loan_amt_sum=df['contract_amount'].sum()
# service_amt_sum=df['service_amt'].sum()
# rate=service_amt_sum/loan_amt_sum
#==============================================================================

A02_用户基本信息子主题.py


import pymysql
import json
import numpy
#数据转换为矩阵
def create_dataset(dataset, window=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-window-1):
        #窗口数据
        dataX.append(dataset[i:(i+window),0])
        #目标数据
        dataY.append(dataset[i + window, 0])

    return numpy.array(dataX), numpy.array(dataY)

def get_data(g_id):
    price = []
    try:
        with open("dbconfig.json","r") as f:
            dbjson = json.load(f)
            cnn = pymysql.Connect(**dbjson)
    except pymysql.Error as e:
        print('connect failed!{}'.format(e))

    cursor = cnn.cursor()

    try:
        sql = 'select max_price from futures where g_id = %s order by date asc;'%g_id

        cursor.execute(sql)
        for p in cursor:
            #去除当天未交易
            if p[0]==0:continue
            price.append(p)
    except mysql.connector.Error as e:
        print('query error!{}'.format(e))
    finally:
        cursor.close()
        cnn.close()

    data = numpy.array(price)   #获取最高价序列
    dataset = data.astype("float32")
    return dataset


def backward_propagate(inputs,xs, hs, hsr, ps, targets):
    ## inputs = list of nparrays
    ## targets = list of target labels..zero indexed
    dWxh, dWhh, dWhy = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why)
    dWxhr, dWhhr, dWhyr = np.zeros_like(Wxh), np.zeros_like(Whh), np.zeros_like(Why)
    dbh, dby, dbhr = np.zeros_like(bh), np.zeros_like(by) ,np.zeros_like(bh)

    dy={}
    T=len(inputs)-1
    for t in range(len(inputs)):
        dy[t] = np.zeros_like(ps[t])
        #if t==T:
        dy[t]=np.copy(ps[t])
        dy[t][targets[t]] -= 1
        dWhy += np.dot(dy[t], hs[t].T)
        dWhyr += np.dot(dy[t], hsr[t].T)
        dby += dy[t]

    dhnext = np.zeros_like(hs[0])
    for t in reversed(range(len(inputs))):
        dh = np.dot(Why.T, dy[t]) + dhnext # backprop into h
        dhraw = (1 - hs[t] * hs[t]) * dh # backprop through tanh nonlinearity
        dbh += dhraw
        dWxh += np.dot(dhraw, xs[t].T)
        dWhh += np.dot(dhraw, hs[t-1].T)
        dhnext = np.dot(Whh.T, dhraw)

    dhnext = np.zeros_like(hs[0])
    for t in range(len(inputs)):
        dh = np.dot(Whyr.T, dy[t]) + dhnext # backprop into h
        dhraw = (1 - hsr[t] * hsr[t]) * dh # backprop through tanh nonlinearity
        dbhr += dhraw
        dWxhr += np.dot(dhraw, xs[t].T)
        dWhhr += np.dot(dhraw, hsr[t+1].T)
        dhnext = np.dot(Whhr.T, dhraw)

    for dparam in [dWxh, dWhh, dWhy, dWxhr, dWhhr, dWhyr, dbh, dby, dbhr]:
        np.clip(dparam, -5, 5, out=dparam) # clip to mitigate exploding gradients
    return dWxh, dWhh, dWhy, dWxhr, dWhhr, dWhyr, dbh, dby, dbhr, hs[len(inputs)-1]


from django.shortcuts import render, redirect
from django.views import View
from .models import Booking
from django.http import JsonResponse
from .forms import BookingForm

def bookingview(request):
    if request.method == 'POST':
        form = BookingForm(request.POST)

        if form.is_valid():
            form.save()
            return redirect('/')

    form_booking = BookingForm()

    return render(request, 'booking.html', context={'form_booking': form_booking})

class BookingView(View):

    @staticmethod
    def get(request, *args, **kwargs):
        date = Booking.objects.all()
        return render(request, 'booking.html', {'date': date})

class CheckBookingDate(View):

    @staticmethod
    def get(request, *args, **kwargs):
        btnData = request.GET.get('btnData')
        btnService = request.GET.get('btnService')
        booked_service = list(Booking.objects.all().values_list('date_field', 'service_field', 'time_field'))
        booked_time = []
        for date, service, time in booked_service:
            if btnData in date and btnService in service:
                booked_time.append(time)
        if not booked_time:
            return JsonResponse({'data': False})
        else:
            return JsonResponse({'data': booked_time})


class Solution:
    def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
        indegree = defaultdict(set)
        outdegree = defaultdict(list)
        queue  = deque()
        visited = set()
        ans = []
        for end   , start  in prerequisites:
            indegree[end].add(start)
            outdegree[start].append(end)

        for i in range(numCourses):
            if i not in indegree:
                queue.append(i)
        while queue:
            course = queue.popleft()
            ans.append(course)
            for val in outdegree[course]:
                indegree[val].remove(course)
                if len(indegree[val]) == 0:
                    queue.append(val)
        if len(ans) != numCourses:
            return []

        return ans


import copy
import time
import json
import errno
import os
import subprocess
import functools
from subprocess import Popen, TimeoutExpired, run
from tempfile import NamedTemporaryFile
from time import sleep

from retrying import retry
import pytest

SERVER_RESTART_DELAY_MS = 10_1000
CLIENT_RETRY_INTERVAL_MS = 1_000
class SshConnectionError(Exception):

    def __init__(self):
        super().__init__(self, "Ssh connection failed")

def is_ssh_connection_error(exception):
    return isinstance(exception, SshConnectionError)

def has_ssh_connection_err_msg(output):
    err_msgs = ["Connection closed by remote host",
                "Connection reset by peer",
                "Connection refused"]

    for msg in err_msgs:
        if output.find(msg) != -1:
            return True

    return False

@functools.lru_cache(10)
@retry(retry_on_exception=is_ssh_connection_error, stop_max_attempt_number=3, wait_fixed=5000)
def num_cuda_devices(ip):
    proc = run("ssh {} nvidia-smi -L".format(ip), shell=True,
               stdout=subprocess.PIPE, stderr=subprocess.PIPE,
               timeout=60, encoding="utf-8")

    if has_ssh_connection_err_msg(proc.stderr):
        raise SshConnectionError()

    # the command "nvidia-smi -L" print 1 line for each GPU
    # An example line is like:
    #  GPU 0: NVIDIA A100-SXM4-40GB (UUID: GPU-ddba3c80-ed95-c778-0c47-8cdf2ce99787)
    # Therefore here we count number of lines that starts with GPU
    result = 0
    lines = proc.stdout.split("\n")
    for line in lines:
        if line.find("GPU") == 0:
            result += 1

    return result

@functools.lru_cache(10)
@retry(retry_on_exception=is_ssh_connection_error, stop_max_attempt_number=3, wait_fixed=5000)
def num_neuron_devices(ip):
    proc = run("ssh {} neuron-ls -j".format(ip), shell=True,
               stdout=subprocess.PIPE, stderr=subprocess.PIPE,
               timeout=60, encoding="utf-8")

    if has_ssh_connection_err_msg(proc.stderr):
        raise SshConnectionError()

    if proc.returncode !=0:
        return 0

    return len(json.loads(proc.stdout))

@functools.lru_cache(10)
@retry(retry_on_exception=is_ssh_connection_error, stop_max_attempt_number=3, wait_fixed=5000)
def num_neuron_cores_on_device(ip, device_id):
    proc = run("ssh {} neuron-ls -j".format(ip), shell=True,
               stdout=subprocess.PIPE, stderr=subprocess.PIPE,
               timeout=60, encoding="utf-8")

    if has_ssh_connection_err_msg(proc.stderr):
        raise SshConnectionError()

    proc.check_returncode()
    return json.loads(proc.stdout)[device_id]["nc_count"]

@retry(retry_on_exception=is_ssh_connection_error, stop_max_attempt_number=3, wait_fixed=5000)
def is_neuron_device_available(ip, device_id):
    proc = run("ssh {} neuron-ls -j".format(ip), shell=True,
               stdout=subprocess.PIPE, stderr=subprocess.PIPE,
               timeout=60, encoding="utf-8")

    if has_ssh_connection_err_msg(proc.stderr):
        raise SshConnectionError()

    proc.check_returncode()
    processes = json.loads(proc.stdout)[device_id]["neuron_processes"]
    return len(processes) == 0

def wait_until_neuron_device_available(ip, device_id):
    numtry = 0
    maxtry = 100
    for numtry in range(maxtry):
        if is_neuron_device_available(ip, device_id):
            return

        time.sleep(1)

    raise RuntimeError("Error: neuron device {} is not available after {} tries".format(device_id, maxtry))

def num_hmem_devices(ip, hmem_type):
    function_table = {
        "cuda" : num_cuda_devices,
        "neuron" : num_neuron_devices
    }

    if hmem_type not in function_table:
        raise RuntimeError("Error: unknown hmem type {}".format(hmem_type))

    return function_table[hmem_type](ip)

def has_cuda(ip):
    return num_cuda_devices(ip) > 0

def has_neuron(ip):
    return num_neuron_devices(ip) > 0

@retry(retry_on_exception=is_ssh_connection_error, stop_max_attempt_number=3, wait_fixed=5000)
def has_hmem_support(cmdline_args, ip):
    binpath = cmdline_args.binpath or ""
    cmd = "timeout " + str(cmdline_args.timeout) \
          + " " + os.path.join(binpath, "check_hmem") \
          + " " + "-p " + cmdline_args.provider
    if cmdline_args.environments:
        cmd = cmdline_args.environments + " " + cmd
    proc = run("ssh {} {}".format(ip, cmd),
               stdout=subprocess.PIPE,
               stderr=subprocess.STDOUT,
               shell=True,
               universal_newlines=True)
    if has_ssh_connection_err_msg(proc.stdout):
        raise SshConnectionError()

    return proc.returncode == 0

PASS = 1
SKIP = 2
FAIL = 3

def check_returncode(returncode, strict):
    """
    check one return code
    @param returncode: input
    @param strict: whether to use strict mode, which treat all error as failure.
                   In none strict mode, ENODATA and ENOSYS is treated as pass
    @return: a tuple with return type (PASS, SKIP and FAIL), and a messge.
             when return type is PASs, message will be None
    """
    if returncode == 0:
        return PASS, None

    if not strict:
        if returncode == errno.ENODATA:
            return SKIP, "ENODATA"

        if returncode == errno.ENOSYS:
            return SKIP, "ENOSYS"

    error_msg = "returncode {}".format(returncode)
    # all tests are run under the timeout command
    # which will return 124 when timeout expired.
    if returncode == 124:
        error_msg += ", timeout"

    return FAIL, error_msg

def check_returncode_list(returncode_list, strict):
    """
    check a list of returncode, and call pytest's handler accordingly.
        If there is failure in return, call pytest.fail()
        If there is no failure, but there is skip in return, call pytest.skip()
        If there is no failure or skip, do nothing
    @param resultcode_list: a list of return code
    @param strict: a boolean indicating wether strict mode should be used.
    @return: no return
    """
    result = PASS
    reason = None
    for returncode in returncode_list:
        # note that failure has higher priority than skip, therefore:
        #
        #     if a failure is encoutered, we break out immediately
        #     if a skip is encountered, we record it and continue
        #
        # this ensures skip can be overwritten by failure
        cur_result,cur_reason = check_returncode(returncode, strict)

        if cur_result != PASS:
            result = cur_result
            reason = cur_reason

        if cur_result == FAIL:
            break

    if result == FAIL:
        pytest.fail(reason)

    if result == SKIP:
        pytest.skip(reason)

class UnitTest:

    def __init__(self, cmdline_args, base_command, is_negative=False, failing_warn_msgs=None):
        if isinstance(failing_warn_msgs, str):
            failing_warn_msgs = [failing_warn_msgs]

        if failing_warn_msgs:
            self._cmdline_args = copy.copy(cmdline_args)
            self._cmdline_args.append_environ("FI_LOG_LEVEL=warn")
        else:
            self._cmdline_args = cmdline_args

        self._failing_warn_msgs = failing_warn_msgs
        self._base_command = base_command
        self._is_negative = is_negative
        if "neuron" in base_command and "PYTEST_XDIST_WORKER" in os.environ:
            host_ip = self._cmdline_args.server_id
            worker_id = int(os.environ["PYTEST_XDIST_WORKER"].replace("gw", ""))
            neuron_device_id = worker_id % num_neuron_devices(host_ip)
            num_cores = num_neuron_cores_on_device(host_ip, neuron_device_id)
            additional_environment = "NEURON_RT_VISIBLE_CORES={}".format(
                neuron_device_id * num_cores)
            wait_until_neuron_device_available(host_ip, neuron_device_id)
        else:
            additional_environment = None

        self._command = self._cmdline_args.populate_command(base_command, "host", additional_environment=additional_environment)

    @retry(retry_on_exception=is_ssh_connection_error, stop_max_attempt_number=3, wait_fixed=5000)
    def run(self):
        if self._cmdline_args.is_test_excluded(self._base_command, self._is_negative):
            pytest.skip("excluded")

        # start running
        outfile = NamedTemporaryFile(prefix="fabtests_server.out.").name
        process = Popen(self._command + "> " + outfile + " 2>&1", shell=True)

        timeout = False
        try:
            process.wait(timeout=self._cmdline_args.timeout)
        except TimeoutExpired:
            process.terminate()
            timeout = True

        output = open(outfile).read()
        print("")
        print("command: " + self._command)
        if has_ssh_connection_err_msg(output):
            print("encountered ssh connection issue")
            raise SshConnectionError()

        print("stdout: ")
        print(output)
        os.unlink(outfile)

        assert not timeout, "timed out"
        check_returncode_list([process.returncode], self._cmdline_args.strict_fabtests_mode)

        if self._failing_warn_msgs:
            for msg in self._failing_warn_msgs:
                assert output.find(msg) == -1

class ClientServerTest:

    def __init__(self, cmdline_args, executable,
                 iteration_type=None,
                 completion_semantic="transmit_complete",
                 prefix_type="wout_prefix",
                 datacheck_type="wout_datacheck",
                 message_size=None,
                 memory_type="host_to_host",
                 timeout=None,
                 warmup_iteration_type=None,
                 completion_type="queue"):

        self._cmdline_args = cmdline_args
        self._timeout = timeout or cmdline_args.timeout
        self._server_base_command, server_additonal_environment = self.prepare_base_command("server", executable, iteration_type,
                                                              completion_semantic, prefix_type,
                                                              datacheck_type, message_size,
                                                              memory_type, warmup_iteration_type,
                                                              completion_type)
        self._client_base_command, client_additonal_environment = self.prepare_base_command("client", executable, iteration_type,
                                                              completion_semantic, prefix_type,
                                                              datacheck_type, message_size,
                                                              memory_type, warmup_iteration_type,
                                                              completion_type)

        self._server_command = self._cmdline_args.populate_command(self._server_base_command, "server", self._timeout, server_additonal_environment)
        self._client_command = self._cmdline_args.populate_command(self._client_base_command, "client", self._timeout, client_additonal_environment)

    def prepare_base_command(self, command_type, executable,
                             iteration_type=None,
                             completion_semantic="transmit_complete",
                             prefix_type="wout_prefix",
                             datacheck_type="wout_datacheck",
                             message_size=None,
                             memory_type="host_to_host",
                             warmup_iteration_type=None,
                             completion_type="queue"):
        if executable == "fi_ubertest":
            return "fi_ubertest", None

        '''
            all execuables in fabtests (except fi_ubertest) accept a common set of arguments:
                -I: number of iteration
                -U: delivery complete (transmit complete if not specified)
                -k: force prefix mode (not force prefix mode if not specified)
                -v: data verification (no data verification if not specified)
                -S: message size
                -w: number of warmup iterations
            this function will construct a command with these options
        '''

        command = executable[:]
        if iteration_type == "short":
            command += " -I 5"
        elif iteration_type == "standard":
            if not (self._cmdline_args.core_list is None):
                command += " --pin-core " + self._cmdline_args.core_list
            pass
        elif iteration_type is None:
            pass
        else:
            command += " -I " + str(iteration_type)

        if warmup_iteration_type:
            command += " -w " + str(warmup_iteration_type)

        if completion_semantic == "delivery_complete":
            command += " -U"
        else:
            assert completion_semantic == "transmit_complete"

        # Most fabtests actually run as -t queue by default.
        # However, not all fabtests binaries support -t option.
        # Therefore, only add this option for tests
        # that requests counter type explicitly.
        if completion_type == "counter":
            command += " -t counter"
        else:
            assert completion_type == "queue"

        if datacheck_type == "with_datacheck":
            command += " -v"
        else:
            if datacheck_type != "wout_datacheck":
                print("datacheck_type: " + datacheck_type)
            assert datacheck_type == "wout_datacheck"

        if prefix_type == "with_prefix":
            command += " -k"
        else:
            assert prefix_type == "wout_prefix"

        if message_size:
            command += " -S " + str(message_size)

        # in communication test, client is sender, server is receiver
        client_memory_type, server_memory_type = memory_type.split("_to_")
        host_memory_type, host_ip = (server_memory_type, self._cmdline_args.server_id) if command_type == "server" else (
            client_memory_type, self._cmdline_args.client_id)

        if host_memory_type == "host":
            return command, None    # no addtional environment variable

        assert host_memory_type == "cuda" or host_memory_type == "neuron"

        if not has_hmem_support(self._cmdline_args, host_ip):
            pytest.skip("no hmem support")

        num_hmem = num_hmem_devices(host_ip, host_memory_type)
        if num_hmem == 0:
                pytest.skip("no {} device".format(host_memory_type))

        command += " -D " + host_memory_type
        additional_environment = None

        if "PYTEST_XDIST_WORKER" in os.environ:
            worker_id = int(os.environ["PYTEST_XDIST_WORKER"].replace("gw", ""))
            hmem_device_id = worker_id % num_hmem
            if host_memory_type == "cuda":
                command += " -i {}".format(hmem_device_id)
            else:
                assert host_memory_type == "neuron"
                num_cores = num_neuron_cores_on_device(host_ip, hmem_device_id)
                additional_environment = "NEURON_RT_VISIBLE_CORES={}".format(
                    hmem_device_id * num_cores)
                wait_until_neuron_device_available(host_ip, hmem_device_id)

            if self._cmdline_args.provider == "efa":
                import efa.efa_common
                efa_device = efa.efa_common.get_efa_device_name_for_cuda_device(host_ip, hmem_device_id, num_hmem)
                command += " -d {}-rdm".format(efa_device)

        return command, additional_environment

    def _run_client_command(self, server_process, client_command, client_output_file=None,
                            run_client_asynchronously=False):

        if server_process.poll():
            if client_output_file:
                with open(client_output_file, "w") as f:
                    f.write("")
            raise RuntimeError("Server has terminated")

        print("")
        print("client_command: " + client_command)

        process = Popen(client_command, stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT, shell=True, universal_newlines=True)
        if run_client_asynchronously:
            return process

        client_timed_out = False
        output = ""
        try:
            output, _ = process.communicate(timeout=self._timeout)
            if client_output_file:
                with open(client_output_file, "w") as f:
                    f.write(output)
        except TimeoutExpired:
            client_timed_out = True
            process.terminate()

        if has_ssh_connection_err_msg(output):
            print("client encountered ssh connection issue!")
            raise SshConnectionError()

        print("client_stdout:")
        print(output)
        print(f"client returncode: {process.returncode}")

        if client_timed_out:
            raise RuntimeError("Client timed out")

        return process

    @retry(retry_on_exception=is_ssh_connection_error, stop_max_attempt_number=3, wait_fixed=SERVER_RESTART_DELAY_MS)
    def run(self):
        if self._cmdline_args.is_test_excluded(self._server_base_command):
            pytest.skip("excluded")

        if self._cmdline_args.is_test_excluded(self._client_base_command):
            pytest.skip("excluded")

        # Start server
        print("")
        print("server_command: " + self._server_command)
        server_process = Popen(self._server_command, stdout=subprocess.PIPE,
                               stderr=subprocess.STDOUT, shell=True, universal_newlines=True)
        sleep(1)

        client_returncode = -1
        try:
            # Start client
            # Retry on SSH connection error until server timeout
            client_returncode = retry(
                retry_on_exception=is_ssh_connection_error,
                stop_max_delay=self._timeout * 1000,  # Convert to milliseconds
                wait_fixed=CLIENT_RETRY_INTERVAL_MS,
            )(self._run_client_command)(server_process, self._client_command).returncode
        except Exception as e:
            print("Client error: {}".format(e))
            # Clean up server if client is terminated unexpectedly
            server_process.terminate()

        server_output = ""
        server_timed_out = False
        try:
            server_output, _ = server_process.communicate(
                timeout=self._timeout)
        except TimeoutExpired:
            server_process.terminate()
            server_timed_out = True

        if has_ssh_connection_err_msg(server_output):
            print("encountered ssh connection issue!")
            raise SshConnectionError()

        print("server_stdout:")
        print(server_output)
        print(f"server returncode: {server_process.returncode}")

        if server_timed_out:
            raise RuntimeError("Server timed out")

        check_returncode_list([server_process.returncode, client_returncode],
                              self._cmdline_args.strict_fabtests_mode)

class MultinodeTest(ClientServerTest):

    def __init__(self, cmdline_args, server_base_command,
                 client_base_command, client_hostname_list,
                 run_client_asynchronously=True):
        self._cmdline_args = cmdline_args
        self.numclient = len(client_hostname_list)
        self._timeout = self._cmdline_args.timeout

        self._server_base_command = cmdline_args.populate_command(server_base_command, "server", self._timeout)
        self._client_base_command_list = []
        for client_hostname in client_hostname_list:
            cmdline_args_copy = copy.copy(cmdline_args)
            cmdline_args_copy.client_id = client_hostname
            self._client_base_command_list.append(cmdline_args_copy.populate_command(client_base_command, "client", self._timeout))
        self._run_client_asynchronously = run_client_asynchronously

    @retry(retry_on_exception=is_ssh_connection_error, stop_max_attempt_number=3, wait_fixed=SERVER_RESTART_DELAY_MS)
    def run(self):
        if self._cmdline_args.is_test_excluded(self._server_base_command):
            pytest.skip("excluded")

        # _client_base_command_list is populated from the same client_base_command,
        # so it should be safe to only check the first one.
        if self._cmdline_args.is_test_excluded(self._client_base_command_list[0]):
            pytest.skip("excluded")

        server_outfile = NamedTemporaryFile(prefix="fabtests_server.out.").name

        # start running
        server_process = Popen(self._server_base_command + "> " + server_outfile + " 2>&1", shell=True)
        sleep(1)

        client_process_list = [None] * self.numclient
        client_outfile_list = [None] * self.numclient
        for i in range(self.numclient):
            client_outfile_list[i] = NamedTemporaryFile(prefix="fabtests_client_{}.out.".format(i)).name
            try:
                # Start client
                # Retry on SSH connection error until server timeout
                client_process_list[i] = retry(
                    retry_on_exception=is_ssh_connection_error,
                    stop_max_delay=self._timeout * 1000,  # Convert to milliseconds
                    wait_fixed=CLIENT_RETRY_INTERVAL_MS,
                )(self._run_client_command)(server_process, self._client_base_command_list[i],
                                            client_outfile_list[i],
                                            self._run_client_asynchronously)
            except Exception as e:
                print("Client error: {}".format(e))
                # Clean up server if client is terminated unexpectedly
                server_process.terminate()

        server_timed_out = False
        try:
            server_process.wait(timeout=self._timeout)
        except TimeoutExpired:
            server_process.terminate()
            server_timed_out = True

        if has_ssh_connection_err_msg(open(server_outfile).read()):
            print("encountered ssh connection issue!")
            raise SshConnectionError()

        client_timed_out = False
        # for syncrhonous clients, this is already
        # handled in self._run_client_command
        if self._run_client_asynchronously:
            for i in range(self.numclient):
                try:
                    output, _ = client_process_list[i].communicate(timeout=self._timeout)
                    with open(client_outfile_list[i], "w") as f:
                        f.write(output)
                except TimeoutExpired:
                    client_process_list[i].terminate()
                    client_timed_out = True

        print("")
        print("server_command: " + self._server_base_command)
        print("server_stdout:")
        print(open(server_outfile).read())
        os.unlink(server_outfile)

        for i in range(self.numclient):
            print("client_{}_command: ".format(i) + self._client_base_command_list[i])
            print("client_{}_stdout:".format(i))
            print(open(client_outfile_list[i]).read())
            os.unlink(client_outfile_list[i])

        if server_timed_out:
            raise RuntimeError("Server timed out")

        if client_timed_out:
            raise RuntimeError("Client timed out")

        strict = self._cmdline_args.strict_fabtests_mode

        returncode_list = [server_process.returncode]
        for i in range(self.numclient):
            returncode_list.append(client_process_list[i].returncode)

        check_returncode_list(returncode_list, strict)


from __future__ import annotations

from typing import TYPE_CHECKING, Any, Callable, Sequence

from starlite import HTTPRouteHandler, OpenAPIConfig, Request, Response, Router
from starlite.contrib.jwt import JWTAuth, JWTCookieAuth
from starlite.security.session_auth import SessionAuth

from starlite_users.dependencies import get_service_dependency
from starlite_users.exceptions import (
    RepositoryException,
    TokenException,
    repository_exception_handler,
    token_exception_handler,
)
from starlite_users.route_handlers import (
    get_auth_handler,
    get_current_user_handler,
    get_password_reset_handler,
    get_registration_handler,
    get_role_management_handler,
    get_user_management_handler,
    get_verification_handler,
)
from starlite_users.user_handlers import (
    get_jwt_retrieve_user_handler,
    get_session_retrieve_user_handler,
)

__all__ = ["StarliteUsers"]

if TYPE_CHECKING:
    from starlite.config import AppConfig

    from starlite_users.config import StarliteUsersConfig

class StarliteUsers:
    """A Starlite extension for authentication, authorization and user management."""

    def __init__(self, config: "StarliteUsersConfig") -> None:
        """Construct a StarliteUsers instance."""
        self._config = config

    def on_app_init(self, app_config: "AppConfig") -> "AppConfig":
        """Register routers, auth strategies etc on the Starlite app.

        Args:
            app_config: An instance of [AppConfig][starlite.config.AppConfig]
        """
        auth_backend = self._get_auth_backend()
        route_handlers = self._get_route_handlers(auth_backend)

        app_config.openapi_config = OpenAPIConfig(
            title="Security API",  # TODO: make configurable
            version="0.1.0",  # TODO: make configurable
        )
        # will always be true
        app_config = auth_backend.on_app_init(app_config)
        app_config.route_handlers.extend(route_handlers)

        exception_handlers: dict[type[Exception], Callable[[Request, Any], Response]] = {
            TokenException: token_exception_handler,
            RepositoryException: repository_exception_handler,
        }
        app_config.exception_handlers.update(exception_handlers)  # type: ignore[arg-type]

        return app_config

    def _get_auth_backend(self) -> JWTAuth | JWTCookieAuth | SessionAuth:
        if self._config.auth_backend == "session":
            return SessionAuth(
                retrieve_user_handler=get_session_retrieve_user_handler(
                    user_model=self._config.user_model,
                    role_model=self._config.role_model,
                    user_repository_class=self._config.user_repository_class,
                ),
                session_backend_config=self._config.session_backend_config,  # type: ignore
                exclude=self._config.auth_exclude_paths,
            )
        if self._config.auth_backend == "jwt":
            return JWTAuth(
                retrieve_user_handler=get_jwt_retrieve_user_handler(
                    user_model=self._config.user_model,
                    role_model=self._config.role_model,
                    user_repository_class=self._config.user_repository_class,
                ),
                token_secret=self._config.secret.get_secret_value(),
                exclude=self._config.auth_exclude_paths,
            )

        return JWTCookieAuth(
            retrieve_user_handler=get_jwt_retrieve_user_handler(
                user_model=self._config.user_model,
                role_model=self._config.role_model,
                user_repository_class=self._config.user_repository_class,
            ),
            token_secret=self._config.secret.get_secret_value(),
            exclude=self._config.auth_exclude_paths,
        )

    def _get_route_handlers(
        self, auth_backend: JWTAuth | JWTCookieAuth | SessionAuth
    ) -> Sequence[HTTPRouteHandler | Router]:
        """Parse the route handler configs to get Routers."""

        handlers: list[HTTPRouteHandler | Router] = []
        service_dependency_provider = get_service_dependency(
            user_model=self._config.user_model,
            role_model=self._config.role_model,
            user_service_class=self._config.user_service_class,
            user_repository_class=self._config.user_repository_class,
            secret=self._config.secret,
            hash_schemes=self._config.hash_schemes,
        )
        if self._config.auth_handler_config:
            handlers.append(
                get_auth_handler(
                    login_path=self._config.auth_handler_config.login_path,
                    logout_path=self._config.auth_handler_config.logout_path,
                    user_read_dto=self._config.user_read_dto,
                    service_dependency=service_dependency_provider,
                    auth_backend=auth_backend,
                    tags=self._config.auth_handler_config.tags,
                )
            )
        if self._config.current_user_handler_config:
            handlers.append(
                get_current_user_handler(
                    path=self._config.current_user_handler_config.path,
                    user_read_dto=self._config.user_read_dto,
                    user_update_dto=self._config.user_update_dto,
                    service_dependency=service_dependency_provider,
                    tags=self._config.current_user_handler_config.tags,
                )
            )
        if self._config.password_reset_handler_config:
            handlers.append(
                get_password_reset_handler(
                    forgot_path=self._config.password_reset_handler_config.forgot_path,
                    reset_path=self._config.password_reset_handler_config.reset_path,
                    service_dependency=service_dependency_provider,
                    tags=self._config.password_reset_handler_config.tags,
                )
            )
        if self._config.register_handler_config:
            handlers.append(
                get_registration_handler(
                    path=self._config.register_handler_config.path,
                    user_create_dto=self._config.user_create_dto,
                    user_read_dto=self._config.user_read_dto,
                    service_dependency=service_dependency_provider,
                    tags=self._config.register_handler_config.tags,
                )
            )
        if self._config.role_management_handler_config:
            handlers.append(
                get_role_management_handler(
                    path_prefix=self._config.role_management_handler_config.path_prefix,
                    assign_role_path=self._config.role_management_handler_config.assign_role_path,
                    revoke_role_path=self._config.role_management_handler_config.revoke_role_path,
                    guards=self._config.role_management_handler_config.guards,
                    opt=self._config.role_management_handler_config.opt,
                    role_create_dto=self._config.role_create_dto,
                    role_read_dto=self._config.role_read_dto,
                    role_update_dto=self._config.role_update_dto,
                    user_read_dto=self._config.user_read_dto,
                    service_dependency=service_dependency_provider,
                    tags=self._config.role_management_handler_config.tags,
                )
            )
        if self._config.user_management_handler_config:
            handlers.append(
                get_user_management_handler(
                    path_prefix=self._config.user_management_handler_config.path_prefix,
                    guards=self._config.user_management_handler_config.guards,
                    opt=self._config.user_management_handler_config.opt,
                    user_read_dto=self._config.user_read_dto,
                    user_update_dto=self._config.user_update_dto,
                    service_dependency=service_dependency_provider,
                    tags=self._config.user_management_handler_config.tags,
                )
            )
        if self._config.verification_handler_config:
            handlers.append(
                get_verification_handler(
                    path=self._config.verification_handler_config.path,
                    user_read_dto=self._config.user_read_dto,
                    service_dependency=service_dependency_provider,
                    tags=self._config.verification_handler_config.tags,
                )
            )
        return handlers


import os
import sys
from pathlib import Path
import numpy as np
import torch
import torch.backends.cudnn as cudnn
import torch.nn.functional as F
import torch.optim as optim
from tensorboardX import SummaryWriter
from torch import nn
from torchvision.utils import make_grid
from advent.domain_adaptation.eval_UDA import display_stats
from advent.model.discriminator import get_fc_discriminator
from advent.utils.func import adjust_learning_rate, adjust_learning_rate_discriminator, fast_hist, per_class_iu
from advent.utils.func import loss_calc, bce_loss
from advent.utils.loss import entropy_loss, entropy_loss_with_regularization
from advent.utils.func import prob_2_entropy
from advent.utils.viz_segmask import colorize_mask
from advent.model.grl import LambdaWrapper
from tqdm import trange

def train_crcda(model, trainloader, targetloader, cfg, testloader=None):
    ''' UDA training with CrCDA '''
    # Create the model and start the training.
    input_size_source = cfg.TRAIN.INPUT_SIZE_SOURCE
    input_size_target = cfg.TRAIN.INPUT_SIZE_TARGET
    device = cfg.GPU_ID
    num_classes = cfg.NUM_CLASSES
    viz_tensorboard = os.path.exists(cfg.TRAIN.TENSORBOARD_LOGDIR)
    if viz_tensorboard:
        writer = SummaryWriter(log_dir=cfg.TRAIN.TENSORBOARD_LOGDIR)

    # SEGMNETATION NETWORK
    model.train()
    model.to(device)
    cudnn.benchmark = True
    cudnn.enabled = True

    # DISCRIMINATOR NETWORK
    # seg maps, i.e. output, level
    d_main = get_fc_discriminator(num_classes=num_classes)
    d_main.train()
    d_main.to(device)

    # OPTIMIZERS
    # segnet's optimizer
    optimizer = optim.SGD(model.optim_parameters(cfg.TRAIN.LEARNING_RATE),
                          lr=cfg.TRAIN.LEARNING_RATE,
                          momentum=cfg.TRAIN.MOMENTUM,
                          weight_decay=cfg.TRAIN.WEIGHT_DECAY)

    # discriminators' optimizers
    optimizer_d_main = optim.Adam(d_main.parameters(), lr=cfg.TRAIN.LEARNING_RATE_D,
                                  betas=(0.9, 0.99))

    # interpolate output segmaps
    interp = nn.Upsample(size=(input_size_source[1], input_size_source[0]), mode='bilinear',
                         align_corners=True)
    interp_target = nn.Upsample(size=(input_size_target[1], input_size_target[0]), mode='bilinear',
                                align_corners=True)

    # labels for adversarial training
    source_label = 0
    target_label = 1
    trainloader_iter = enumerate(trainloader)
    targetloader_iter = enumerate(targetloader)

    t = trange(cfg.TRAIN.EARLY_STOP + 1, desc='Loss', leave=True)
    for i_iter in t:
        # reset optimizers
        optimizer.zero_grad()
        # optimizer_d_aux.zero_grad()
        optimizer_d_main.zero_grad()
        # adapt LR if needed
        adjust_learning_rate(optimizer, i_iter, cfg)
        # adjust_learning_rate_discriminator(optimizer_d_aux, i_iter, cfg)
        adjust_learning_rate_discriminator(optimizer_d_main, i_iter, cfg)

        # UDA Training
        # only train segnet. Don't accumulate grads in disciminators
        for param in d_main.parameters():
            param.requires_grad = False

        # -------------- SOURCE FLOW --------------
        images_source, loss_c2, loss_c3, loss_seg, pred_src_layout, pred_src_seg = source_flow(cfg, device, interp, model, trainloader_iter)

        # -------------- TARGET FLOW --------------
        images, loss_adv_trg, loss_ent, loss_ent2, loss_ent3, pred_trg_layout, pred_trg_seg = target_flow(cfg, d_main, device, interp_target, model,
                                                                                source_label, targetloader_iter, i_iter)

        # -------------- DISCRIMINATOR --------------
        loss_d = 0
        if cfg.TRAIN.USE_DISCRIMINATOR:
            loss_d = update_discriminator(d_main, optimizer, optimizer_d_main, pred_src_layout, pred_trg_layout, source_label, target_label)
        del pred_src_layout
        del pred_trg_layout

        optimizer.step()
        # --------------- LOGGING -----------------
        current_losses = {
            'loss_src_seg': loss_seg,
            'loss_src_c2': loss_c2,
            'loss_src_c3': loss_c3,
            'loss_trg_ent': loss_ent,
            'loss_trg_ent2': loss_ent2,
            'loss_trg_ent3': loss_ent3,
            'loss_trg_adv': loss_adv_trg,
            'loss_d': loss_d  # this is only the d loss from training with target!
        }

        t.set_description(get_loss_string(current_losses, i_iter))
        logging(cfg, current_losses, d_main, device, i_iter, images, images_source, model, num_classes, pred_src_seg, pred_trg_seg, viz_tensorboard, writer, testloader=testloader)
        sys.stdout.flush()

        if i_iter % cfg.TRAIN.SAVE_PRED_EVERY == 0 and i_iter >= cfg.TRAIN.EARLY_STOP - 1:
            break

def source_flow(cfg, device, interp, model, trainloader_iter):
    _, batch = trainloader_iter.__next__()
    images_source, labels, patch_scale_labels, mini_patch_scale_labels, _, _ = batch
    pred_src_seg, pred_src_cr_mini, pred_src_cr = model(images_source.cuda(device))

    loss = 0
    pred_src_layout = []

    # L_seg
    loss_seg = 0
    if cfg.TRAIN.USE_SEG:
        pred_src_seg = interp(pred_src_seg)
        pred_src_layout.append(pred_src_seg)
        loss_seg = loss_calc(pred_src_seg, labels, device)
        loss += cfg.TRAIN.LAMBDA_SEG * loss_seg
        loss_seg = loss_seg.detach()
    # L_c2
    loss_c2 = 0
    if cfg.TRAIN.USE_MINI_PATCH:
        pred_src_cr_mini = interp(pred_src_cr_mini)
        pred_src_layout.append(pred_src_cr_mini)
        loss_c2 = loss_calc(pred_src_cr_mini, mini_patch_scale_labels, device)
        loss += cfg.TRAIN.LAMBDA_C2 * loss_c2
        loss_c2 = loss_c2.detach()
    # L_c3
    loss_c3 = 0
    if cfg.TRAIN.USE_PATCH:
        pred_src_cr = interp(pred_src_cr)
        pred_src_layout.append(pred_src_cr)
        loss_c3 = loss_calc(pred_src_cr, patch_scale_labels, device)
        loss += cfg.TRAIN.LAMBDA_C3 * loss_c3
        loss_c3 = loss_c3.detach()

    if cfg.TRAIN.USE_DISCRIMINATOR and len(pred_src_layout) > 0:
        pred_src_layout = concatenate_padding(pred_src_layout, device, padding_dimension=1, concat_dimension=0)

    if loss != 0:
        loss.backward()

    pred_src_layout = [tensor.detach() for tensor in pred_src_layout]
    return images_source, loss_c2, loss_c3, loss_seg, pred_src_layout, pred_src_seg.detach()

def target_flow(cfg, d_main, device, interp_target, model, source_label, targetloader_iter, i_iter):
    """ adversarial training with local minmax entropy loss and global alignment discriminator loss """
    _, batch = targetloader_iter.__next__()
    images_target, _, _, _ = batch
    lambda_wrapper = LambdaWrapper(lambda_=-1)
    pred_trg_seg, pred_trg_cr_mini, pred_trg_cr = model(images_target.cuda(device), grl_lambda=lambda_wrapper)

    loss = 0
    pred_trg_layout = []
    # L_ent
    loss_ent = 0
    if cfg.TRAIN.USE_SEG_ENT:
        pred_trg_seg = interp_target(pred_trg_seg)
        pred_trg_layout.append(pred_trg_seg)
        loss_ent = entropy_loss_with_regularization(F.softmax(pred_trg_seg), i_iter, cfg.TRAIN.ENT_REG_MAX_ITER)
        loss += cfg.TRAIN.LAMBDA_ENT * loss_ent
        loss_ent = loss_ent.detach()
    # L_ent2
    loss_ent2 = 0
    if cfg.TRAIN.USE_MINI_PATCH_ENT:
        pred_trg_cr_mini = interp_target(pred_trg_cr_mini)
        pred_trg_layout.append(pred_trg_cr_mini)
        loss_ent2 = entropy_loss_with_regularization(F.softmax(pred_trg_cr_mini), i_iter, cfg.TRAIN.ENT_REG_MAX_ITER)
        loss += cfg.TRAIN.LAMBDA_ENT2 * loss_ent2
        loss_ent2 = loss_ent2.detach()
    # L_ent2
    loss_ent3 = 0
    if cfg.TRAIN.USE_PATCH_ENT:
        pred_trg_cr = interp_target(pred_trg_cr)
        pred_trg_layout.append(pred_trg_cr)
        loss_ent3 = entropy_loss_with_regularization(F.softmax(pred_trg_cr), i_iter, cfg.TRAIN.ENT_REG_MAX_ITER)
        loss += cfg.TRAIN.LAMBDA_ENT3 * loss_ent3
        loss_ent3 = loss_ent3.detach()

    loss = -loss  # This way, seg heads maximize entropy, and feature extractor minimizes it

    if loss != 0:
        # keep grad graph for application of discriminator adv loss with different grl lambda
        loss.backward(retain_graph=(cfg.TRAIN.USE_DISCRIMINATOR and len(pred_trg_layout) > 0))

    loss_adv_trg = 0
    if cfg.TRAIN.USE_DISCRIMINATOR and len(pred_trg_layout) > 0:
        pred_trg_layout = concatenate_padding(pred_trg_layout, device, padding_dimension=1, concat_dimension=0)
        d_out = d_main(F.softmax(pred_trg_layout))  # TODO: Softmax here?
        loss_adv_trg = bce_loss(d_out, source_label)
        loss += cfg.TRAIN.LAMBDA_ADV * loss_adv_trg
        lambda_wrapper.set_lambda(1)
        loss.backward()
        loss_adv_trg = loss_adv_trg.detach()

    return images_target, loss_adv_trg, loss_ent, loss_ent2, loss_ent3, pred_trg_layout, pred_trg_seg.detach()

def update_discriminator(d_main, optimizer, optimizer_d_main, pred_src_layout, pred_trg_layout, source_label, target_label):
    # Train discriminator network
    # enable training mode on discriminator networks
    for param in d_main.parameters():
        param.requires_grad = True
    # train with source
    pred_src = pred_src_layout.detach()
    d_out = d_main(F.softmax(pred_src))  # TODO: Softmax here?
    loss_d = bce_loss(d_out, source_label)
    loss_d = loss_d / 2
    loss_d.backward()
    # train with target
    pred_trg = pred_trg_layout.detach()
    d_out = d_main(F.softmax(pred_trg))  # TODO: Softmax here?
    loss_d = bce_loss(d_out, target_label)
    loss_d = loss_d / 2
    loss_d.backward()
    optimizer_d_main.step()
    return loss_d.detach()

def logging(cfg, current_losses, d_main, device, i_iter, images, images_source, model, num_classes, pred_src_seg, pred_trg_seg, viz_tensorboard, writer, testloader=None):
    if i_iter % cfg.TRAIN.SAVE_PRED_EVERY == 0 and i_iter != 0:
        # print('\ntaking snapshot ...')
        # print('exp =', cfg.TRAIN.SNAPSHOT_DIR)
        snapshot_dir = Path(cfg.TRAIN.SNAPSHOT_DIR)
        torch.save(model.state_dict(), snapshot_dir / f'model_{i_iter}.pth')
        torch.save(d_main.state_dict(), snapshot_dir / f'model_{i_iter}_D_main.pth')
        if testloader is not None:
            eval_model(cfg, model, testloader, i_iter, writer, device)
    # Visualize with tensorboard
    if viz_tensorboard:
        log_losses_tensorboard(writer, current_losses, i_iter)

        if i_iter % cfg.TRAIN.TENSORBOARD_VIZRATE == cfg.TRAIN.TENSORBOARD_VIZRATE - 1:
            draw_in_tensorboard(writer, images, i_iter, pred_trg_seg, num_classes, 'T')
            draw_in_tensorboard(writer, images_source, i_iter, pred_src_seg, num_classes, 'S')

def get_loss_string(current_losses, i_iter):
    list_strings = []
    for loss_name, loss_value in current_losses.items():
        if loss_value != 0:
            list_strings.append(f'{loss_name} = {to_numpy(loss_value):.3f} ')
    full_string = ' '.join(list_strings)
    return f'iter = {i_iter} {full_string}'

def log_losses_tensorboard(writer, current_losses, i_iter):
    for loss_name, loss_value in current_losses.items():
        writer.add_scalar(f'data/{loss_name}', to_numpy(loss_value), i_iter)

def to_numpy(tensor):
    if isinstance(tensor, (int, float)):
        return tensor
    else:
        return tensor.data.cpu().numpy()

def concatenate_padding(tensors, device, padding_dimension=1, concat_dimension=0):
    new_list = []
    max_dim1 = 0
    for tensor in tensors:
        if np.shape(tensor)[padding_dimension] > max_dim1:
            max_dim1 = np.shape(tensor)[padding_dimension]

    for tensor in tensors:
        # tensor_size = list(np.shape(to_numpy(tensor)))
        tensor_size = list(np.shape(tensor))
        if tensor_size[padding_dimension] < max_dim1:
            tensor_size[padding_dimension] = max_dim1 - tensor_size[padding_dimension]
            new_list.append(torch.cat([tensor, torch.zeros(tensor_size).cuda(device)], padding_dimension))

    return torch.cat(new_list, concat_dimension)

def draw_in_tensorboard(writer, images, i_iter, pred_main, num_classes, type_):
    grid_image = make_grid(images[:3].clone().cpu().data, 3, normalize=True)
    writer.add_image(f'Image - {type_}', grid_image, i_iter)

    grid_image = make_grid(torch.from_numpy(np.array(colorize_mask(np.asarray(
        np.argmax(F.softmax(pred_main).cpu().data[0].numpy().transpose(1, 2, 0),
                  axis=2), dtype=np.uint8)).convert('RGB')).transpose(2, 0, 1)), 3,
                           normalize=False, range=(0, 255))
    writer.add_image(f'Prediction - {type_}', grid_image, i_iter)

    output_sm = F.softmax(pred_main).cpu().data[0].numpy().transpose(1, 2, 0)
    output_ent = np.sum(-np.multiply(output_sm, np.log2(output_sm)), axis=2,
                        keepdims=False)
    grid_image = make_grid(torch.from_numpy(output_ent), 3, normalize=True,
                           range=(0, np.log2(num_classes)))
    writer.add_image(f'Entropy - {type_}', grid_image, i_iter)

def eval_model(cfg, model, testloader, i_iter, writer, device, fixed_test_size=True, descriptor='target_miou', verbose=False, extra=True):
    # eval target
    interp_target = None
    if fixed_test_size:
        interp_target = nn.Upsample(size=(cfg.TEST.OUTPUT_SIZE_TARGET[1], cfg.TEST.OUTPUT_SIZE_TARGET[0]), mode='bilinear', align_corners=True)

    models = [model]
    interp = interp_target
    verbose = False
    assert len(cfg.TEST.RESTORE_FROM) == len(models), 'Number of models are not matched'
    hist = np.zeros((cfg.NUM_CLASSES, cfg.NUM_CLASSES))
    print("\nEvaluating Model...")
    for index, batch in enumerate(testloader):
        image, label, _, name = batch
        if not fixed_test_size:
            interp = nn.Upsample(size=(label.shape[1], label.shape[2]), mode='bilinear', align_corners=True)
        with torch.no_grad():
            output = None
            for model, model_weight in zip(models, cfg.TEST.MODEL_WEIGHT):
                pred_main = model(image.cuda(device))[model.get_main_index()]
                output_ = interp(pred_main).cpu().data[0].numpy()
                if output is None:
                    output = model_weight * output_
                else:
                    output += model_weight * output_
            assert output is not None, 'Output is None'
            output = output.transpose(1, 2, 0)
            output = np.argmax(output, axis=2)
        label = label.numpy()[0]
        hist += fast_hist(label.flatten(), output.flatten(), cfg.NUM_CLASSES)
        sys.stdout.flush()
    inters_over_union_classes = per_class_iu(hist)
    miou = np.nanmean(inters_over_union_classes)
    if extra:
        print('\033[93m' + 'target val mIoU = ' + str(round(miou * 100, 2)) +'\033[0m\n')
    else:
        print(f'mIoU = \t{round(miou * 100, 2)}')
    if writer is not None:
        writer.add_scalar(descriptor, miou, i_iter)
    if verbose:
        display_stats(cfg, testloader.dataset.class_names, inters_over_union_classes)


"""
Define a function called exact_change that takes the total change amount in cents and calculates the change
using the fewest coins. The coin types are pennies, nickels, dimes, and quarters.
Then write a main program that reads the total change amount as an integer input, calls exact_change(),
and outputs the change, one coin type per line. Use singular and plural coin names as appropriate, like
1 penny vs. 2 pennies. Output "no change" if the input is 0 or less.

Ex: If the input is:

0

(or less), the output is:

no change

Ex: If the input is:

45

the output is:

2 dimes
1 quarter

Your program must define and call the following function. The function exact_change() should return num_pennies, num_nickels, num_dimes, and num_quarters.
def exact_change(user_total)

"""
# Define your function here

def exact_change(num):
    if num <= 0:
       print('no change')
       num_pennies, num_nickels, num_dimes, num_quarters = 0, 0, 0, 0
       return num_pennies, num_nickels, num_dimes, num_quarters
    if num > 0:
        total = num
        num_quarters = int(total / 25)
        new_total = total - (25 * num_quarters)
        num_dimes = int(new_total / 10)
        new_total = new_total - (10 * num_dimes)
        num_nickels = int(new_total / 5)
        num_pennies = new_total - (num_nickels * 5)

        #print(f'Pennies {num_pennies}')
        #print(f'Nickels {num_nickels}')
        #print(f'Dimes {num_dimes}')
        #print(f'Quarters {num_quarters}')

        return num_pennies, num_nickels, num_dimes, num_quarters

if __name__ == '__main__':
    input_val = int(input())
    num_pennies, num_nickels, num_dimes, num_quarters = exact_change(input_val)

    # Type your code here.

    if num_pennies == 1:
        print(f'{num_pennies} penny')
    elif num_pennies > 1:
        print(f'{num_pennies} pennies')
    if num_nickels == 1:
        print(f'{num_nickels} nickel')
    elif num_nickels > 1:
        print(f'{num_nickels} nickels')
    if num_dimes == 1:
        print(f'{num_dimes} dime')
    elif num_dimes > 1:
        print(f'{num_dimes} dimes')
    if num_quarters == 1:
        print(f'{num_quarters} quarter')
    elif num_quarters > 1:
        print(f'{num_quarters} quarters')


#!/usr/bin/env python3
import yaml

from typing import List, AnyStr
from collections import Counter

from core.task import Task
from input_parser import add_task
from utils.plotter import Plotter, color_map

class Stats(Task):
    def __init__(self, plots: List[AnyStr] = None, **kwargs):
        super().__init__(**kwargs)
        self.plots = plots
        self.stats = {}

    def __call__(self):
        all_cwes = []

        for cn in self.challenges:
            challenge = self.kernel.get_challenge(cn)
            stats = challenge.stats()

            if 'hunks' in self.plots:
                _, manifest = challenge.get_manifest(force=True)
                snippets = manifest.get_snippets()
                stats['hunks'] = sum([len(s) for f, s in snippets.items()])

            self.stats[cn] = stats
            all_cwes.extend(stats['cwes'])

        self.cwes_counts = Counter(all_cwes)

        data = {
            'Number of': {
                'Challenges': len(self.stats),
                'Unique CWEs': len(self.cwes_counts),
            },
            'CWEs Counts': dict(self.cwes_counts.items())
        }
        print(yaml.dump(data, default_flow_style=False))
        self.plot()

    def plot(self):
        if self.plots:
            plotter = Plotter(out_path=self.kernel.configs.plots)
            if 'cwes' in self.plots:
                print(self.cwes_counts.values())
                plotter.pie(data=list(self.cwes_counts.values()), labels=list(self.cwes_counts.keys()), cmap='summer',
                            filename='cwes_pie')
                plotter.histogram([len(s['cwes']) for s in self.stats.values()], x_label='CWE count', cmap='plasma',
                                  y_label='Challenges', title="Histogram of number of CWEs per Challenges")
            if 'lines' in self.plots:
                plotter.histogram([s['lines'] for s in self.stats.values()], binwidth=500, filename='lines_hist',
                                  title="Histogram of the number of code lines per Challenge",
                                  x_label="Lines", y_label="Challenges", cmap='RdYlGn')
                plotter.histogram([s['vuln_lines'] for s in self.stats.values()], x_label="Lines", y_label="Challenges",
                                  cmap='autumn', filename='vuln_lines_hist',
                                  title="Histogram of the number of vulnerable lines per Challenge")
                plotter.histogram([s['patch_lines'] for s in self.stats.values()], x_label="Lines",
                                  y_label="Challenges", cmap='winter', filename='patch_lines_hist',
                                  title="Histogram of the number of patch lines per Challenge")
            if 'povs' in self.plots:
                plotter.histogram([s['povs'] for s in self.stats.values()], x_label="POVs", y_label="Challenges",
                                  cmap='Set1', filename='povs_hist',
                                  title="Histogram of the number of POVs across Challenges")
            if 'hunks' in self.plots:
                plotter.histogram([s['hunks'] for s in self.stats.values()], filename='hunks_hist',
                                  title="Histogram of the number of hunks per Challenge",
                                  x_label="Hunks", y_label="Challenges", cmap='RdYlGn')

    def __str__(self):
        return super().__str__()

def stats_args(input_parser):
    input_parser.add_argument('--plots', choices=['cwes', 'lines', 'povs', 'hunks'], nargs="+", default=None,
                              help='Specific plots for the stats')

stats_parser = add_task("stats", Stats, description="Statistics about benchmark challenges.")
stats_args(stats_parser)


from django import forms
from category.models import Category
from web_project import settings
from django.core.validators import RegexValidator

class FormSearchCategory(forms.Form):

    name = forms.CharField(
        widget = forms.TextInput(attrs={'class': 'form-control form-control-sm', 'maxlength': '70'}),
        required=False
    )

    #<input type="text" name="name" id="id_name" class="form-control form-control-sm" maxlength="100">

class CategoryForm(forms.ModelForm):

    class Meta:
        model = Category
        fields = ('name',)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.fields['name'].error_messages={'required': 'Campo obrigatório',
                                            'unique': 'Nome de categoria duplicado'
                                            }
        self.fields['name'].widget.attrs.update({'class': 'form-control form-control-sm', 'maxlength': '70'})