# -*- coding: utf-8 -*-
__author__ = 'videns'
import re

from scanModules.linuxDetect import linuxDetect

class debBasedDetect(linuxDetect):
    def __init__(self,sshPrefix):
        self.supportedFamilies = ('debian','ubuntu', 'kali')
        super(debBasedDetect, self).__init__(sshPrefix)

    def osDetect(self):
        osDetection = super(debBasedDetect, self).osDetect()
        if osDetection:
            (osVersion, osFamily, osDetectionWeight) = osDetection

            if osFamily in self.supportedFamilies:
                osDetectionWeight = 60
                return (osVersion, osFamily, osDetectionWeight)

        version = self.sshCommand("cat /etc/debian_version")
        if version:
            osVersion = re.search("(\d+)\.",version).group(1)
            osFamily = "debian"
            osDetectionWeight = 60
            return (osVersion, osFamily, osDetectionWeight)

    def getPkg(self):
        pkgList = self.sshCommand("dpkg-query -W -f='${Package} ${Version} ${Architecture}\n'")
        return pkgList.splitlines()


import math

def capital_recovery_factor(rate=0.05, life=25):
    '''
    capital recovery factor, the ratio used to determine the present value of a series of equal annual cash payments.
    The payments could be made weekly, monthly, quarterly, yearly, or at any other regular interval of time, and are
    commonly known as annuities.

    Given present value P, we have:
    P =  A(\frac{1}{1+i}+\frac{1}{(1+i)^2}+...+\frac{1}{(1+i)^{life}})
    with A denoting the annuity.
    Futher
    A = crf *P

    :param rate: annual rate
    :param life: years
    :return: annuity
    '''
    crf = (rate * (1 + rate) ** life) / ((1 + rate) ** life - 1)
    return crf  # Money/year

def cost_of_energy(capacity, capex, omcost, capacity_factor=0.4, rate=0.05, life=25):
    '''
    cost of energy
    :param capex: capital expenditure, considering the depreciation, euros/MW
    :param omcost: o&m cost, euros/MW, 2% capex, a typical value
    :param capacity_factor: The average power generated, divided by the rated peak power.
    :param rate: annual interest rate
    :param life: project life, year
    :return: cost of energy, euros/Mwh
    '''
    coe = (capex * capital_recovery_factor(rate, life) * capacity + omcost * capacity) / (
                capacity * 8640 * capacity_factor)
    return coe

def net_present_value(initial_investment=100, interest_rate=0.07, annual_cost=10, annual_profit=20, length_project=20):
    '''
    Net present value is used to evaluate the profitability of a project by transforming all cash flows -both the costs
    and profits - in the future to their present value.
    If Npv is bigger than zero, the investor will benefit from this project, vice versa.
    :param initial_investment:
    :param interest_rate:
    :param annual_cost:
    :param annual_profit:
    :param length_project:
    :return:
    '''
    npv = -initial_investment
    for i in range(length_project):
        npv = npv - annual_cost / math.pow(1 + interest_rate, i + 1) + annual_profit / math.pow(1 + interest_rate,
                                                                                i + 1)
    return npv

def internal_rate_of_return(initial_investment=100, annual_cost=10, annual_profit=20, length_project=20):
    def npv(interest_rate):
        return net_present_value(initial_investment=initial_investment, interest_rate=interest_rate,
                                 annual_cost=annual_cost,
                                 annual_profit=annual_profit, length_project=length_project)

    if annual_profit < annual_cost:
        return -1
    else:
        a = -1
        b = 1
        c = (a + b) / 2
        while math.fabs(npv(c)) >= 1e-6:
            if npv(c) < 0:
                (b,c) = (c, (c+a)/2)
                # b = c
                # c = (c + a) / 2
            else:
                (a,c) = (c,(c+b)/2)
                # a = c
                # c = (c + b) / 2
        return c

if __name__ == '__main__':
    a = capital_recovery_factor()
    b = cost_of_energy(26.8, 3e6, 3e6 * 0.02, 0.4)
    print(a, b)
    print('Only consider O&M cost: {}'.format(cost_of_energy(26.8, 0, 3e6 * 0.02)))
    c = internal_rate_of_return(initial_investment=100, annual_cost=10, annual_profit=20,
                                length_project=20)
    print(c)
    print(net_present_value(initial_investment=100, interest_rate=c, annual_cost=10, annual_profit=20,
                            length_project=20))


class Solution:
    @staticmethod
    def solveSudoku(board) -> None:
        #     """
        #     Do not return anything, modify board in-place instead.
        #     """
        #     self.backtracking(board)

        # def backtracking(self, board: List[List[str]]) -> bool:
        #     # 若有解，返回True；若无解，返回False
        #     for i in range(len(board)): # 遍历行
        #         for j in range(len(board[0])):  # 遍历列
        #             # 若空格内已有数字，跳过
        #             if board[i][j] != '.': continue
        #             for k in range(1, 10):
        #                 if self.is_valid(i, j, k, board):
        #                     board[i][j] = str(k)
        #                     if self.backtracking(board): return True
        #                     board[i][j] = '.'
        #             # 若数字1-9都不能成功填入空格，返回False无解
        #             return False
        #     return True # 有解

        # def is_valid(self, row: int, col: int, val: int, board: List[List[str]]) -> bool:
        #     # 判断同一行是否冲突
        #     for i in range(9):
        #         if board[row][i] == str(val):
        #             return False
        #     # 判断同一列是否冲突
        #     for j in range(9):
        #         if board[j][col] == str(val):
        #             return False
        #     # 判断同一九宫格是否有冲突
        #     start_row = (row // 3) * 3
        #     start_col = (col // 3) * 3
        #     for i in range(start_row, start_row + 3):
        #         for j in range(start_col, start_col + 3):
        #             if board[i][j] == str(val):
        #                 return False
        #     return True
        row = [set(range(1, 10)) for _ in range(9)]  # 行剩余可用数字
        col = [set(range(1, 10)) for _ in range(9)]  # 列剩余可用数字
        block = [set(range(1, 10)) for _ in range(9)]  # 块剩余可用数字

        empty = []  # 收集需填数位置
        for i in range(9):
            for j in range(9):
                if board[i][j] != '.':  # 更新可用数字
                    val = int(board[i][j])
                    row[i].remove(val)
                    col[j].remove(val)
                    block[(i // 3) * 3 + j // 3].remove(val)
                else:
                    empty.append((i, j))

        def backtrack(iter=0):
            if iter == len(empty):  # 处理完empty代表找到了答案
                return True
            i, j = empty[iter]
            b = (i // 3) * 3 + j // 3
            for val in row[i] & col[j] & block[b]:
                row[i].remove(val)
                col[j].remove(val)
                block[b].remove(val)
                board[i][j] = str(val)
                if backtrack(iter + 1):
                    return True
                row[i].add(val)  # 回溯
                col[j].add(val)
                block[b].add(val)
            return False

        backtrack()


import random
import math

BOT_NAME = "Kenta"

class RandomAgent:
    """Agent that picks a random available move.  You should be able to beat it."""
    def __init__(self, sd=None):
        if sd is None:
            self.st = None
        else:
            random.seed(sd)
            self.st = random.getstate()

    def get_move(self, state):
        if self.st is not None:
            random.setstate(self.st)
        return random.choice(state.successors())

class HumanAgent:
    """Prompts user to supply a valid move."""
    def get_move(self, state, depth=None):
        move__state = dict(state.successors())
        prompt = "Kindly enter your move {}: ".format(sorted(move__state.keys()))
        move = None
        while move not in move__state:
            try:
                move = int(input(prompt))
            except ValueError:
                continue
        return move, move__state[move]

class MinimaxAgent:
    """Artificially intelligent agent that uses minimax to optimally select the best move."""

    def get_move(self, state):
        """Select the best available move, based on minimax value."""
        nextp = state.next_player()
        best_util = -math.inf if nextp == 1 else math.inf
        best_move = None
        best_state = None

        for move, state in state.successors():
            util = self.minimax(state)
            if ((nextp == 1) and (util > best_util)) or ((nextp == -1) and (util < best_util)):
                best_util, best_move, best_state = util, move, state
        return best_move, best_state

    def minimax(self, state):
        """Determine the minimax utility value of the given state.

        Args:
            state: a connect383.GameState object representing the current board

        Returns: the exact minimax utility value of the state
        """
        #
        # Fill this in!
        #
        if state.is_full():
            return state.utility()
        if state.next_player() == 1:
            m = self.maxV(state)
        else:
            m = self.minV(state)
        return m

    def maxV(self, state):
        if state.is_full():
            return state.utility()
        m = -math.inf
        for s in state.successors():
            cur = self.minV(s[1])
            if cur > m:
                m = cur
        return m
    def minV(self, state):
        if state.is_full():
            return state.utility()
        m = math.inf
        for s in state.successors():
            cur = self.maxV(s[1])
            if cur < m:
                m = cur
        return m

class MinimaxHeuristicAgent(MinimaxAgent):
    """Artificially intelligent agent that uses depth-limited minimax to select the best move."""

    def __init__(self, depth_limit):
        self.depth_limit = depth_limit

        # if len(state.successors()) == 0:
        #     return state.utility()
        # m = -math.inf
        # for s in state.successors():
        #     cur = self.minV(s[1])
        #     if cur > m:
        #         m = cur
        # return m

    def maxE(self, state, i):
        if state.is_full():
            return state.utility()
        if i == self.depth_limit:
            return self.evaluation(state)
        m = -math.inf
        for s in state.successors():
            cur = self.minE(s[1], i+1)
            if cur > m:
                m = cur
        return m

    def minE(self, state, i):
        if state.is_full():
            return state.utility()
        if i == self.depth_limit:
            return self.evaluation(state)
        m = math.inf
        for s in state.successors():
            cur = self.maxE(s[1], i+1)
            if cur < m:
                m = cur
        return m

    def minimax(self, state):
        """Determine the heuristically estimated minimax utility value of the given state.

        The depth data member (set in the constructor) determines the maximum depth of the game
        tree that gets explored before estimating the state utilities using the evaluation()
        function.  If depth is 0, no traversal is performed, and minimax returns the results of
        a call to evaluation().  If depth is None, the entire game tree is traversed.

        Args:
            state: a connect383.GameState object representing the current board

        Returns: the minimax utility value of the state
        """
        #
        # Fill this in!
        #
        moves = 0
        for r in state.board:
            for c in r:
                if c == 0:
                    moves += 1
        print(moves)
        if self.depth_limit > moves:
            return super().minimax(state)

        if self.depth_limit == 0:
            return self.evaluation(state)

        else:
            if state.next_player() == 1:
                m = self.maxE(state, 0)
            else:
                m = self.minE(state, 0)
            return m

    def evaluation(self, state):
        """Estimate the utility value of the game state based on features.

        N.B.: This method must run in constant time for all states!

        Args:
            state: a connect383.GameState object representing the current board

        Returns: a heuristic estimate of the utility value of the state
        """
        #Based on scores method in connect383, but counts enemy 2 in a rows
        p1_score = 0
        p2_score = 0
        for run in state.get_rows() + state.get_cols():
            #elt is next player, length is length of streak
            for elt, length in streaks(run):
                if (elt == 1) and (length >= 3):
                    p1_score += length ** 2
                # count enemy two in a rows but weight them less than normal streaks
                if (elt == -1) and (length >= 3):
                    if length == 2:
                        p1_score -= 1
                    else:
                        p2_score += length ** 2
        for d in state.get_diags():
            for elt, length in streaks(d):
                if (elt == 1) and (length >= 3):
                    p1_score += length ** 1.5
                # count enemy two in a rows but weight them less than normal streaks
                elif (elt == -1) and (length >= 2):
                    if length == 2:
                        p1_score -= length
                    else:
                        p2_score += length ** 1.5
        return p1_score - p2_score

def streaks(lst):
    """Get the lengths of all the streaks of the same element in a sequence."""
    rets = []  # list of (element, length) tuples
    prev = lst[0]
    curr_len = 1
    for curr in lst[1:]:
        if curr == prev:
            curr_len += 1
        else:
            rets.append((prev, curr_len))
            prev = curr
            curr_len = 1
    rets.append((prev, curr_len))
    return rets
def get_rows(state):
    """Return a list of rows for the board."""
    return [[c for c in r] for r in state.board]

def get_cols(state):
    """Return a list of columns for the board."""
    return list(zip(*state.board))

def get_diags(state):
    """Return a list of all the diagonals for the board."""
    b = [None] * (len(state.board) - 1)
    grid_forward = [b[i:] + r + b[:i] for i, r in enumerate(state.get_rows())]
    forwards = [[c for c in r if c is not None] for r in zip(*grid_forward)]
    grid_back = [b[:i] + r + b[i:] for i, r in enumerate(state.get_rows())]
    backs = [[c for c in r if c is not None] for r in zip(*grid_back)]
    return forwards + backs

class MinimaxPruneAgent(MinimaxAgent):
    """Smarter computer agent that uses minimax with alpha-beta pruning to select the best move."""

    def minimax(self, state):
        """Determine the minimax utility value the given state using alpha-beta pruning.

        The value should be equal to the one determined by MinimaxAgent.minimax(), but the
        algorithm should do less work.  You can check this by inspecting the value of the class
        variable GameState.state_count, which keeps track of how many GameState objects have been
        created over time.  This agent does not use a depth limit like MinimaxHeuristicAgent.

        N.B.: When exploring the game tree and expanding nodes, you must consider the child nodes
        in the order that they are returned by GameState.successors().  That is, you cannot prune
        the state reached by moving to column 4 before you've explored the state reached by a move
        to to column 1.

        Args:
            state: a connect383.GameState object representing the current board

        Returns: the minimax utility value of the state
        """
        #
        # Fill this in!
        #
        if state.is_full():
            return state.utility()
        if state.next_player() == 1:
            m = self.maxAB(state, -math.inf, math.inf)
        else:
            m = self.minAB(state, -math.inf, math.inf)
        return m

    def maxAB(self, state, a, b):
        if state.is_full():
            return state.utility()
        m = -math.inf
        for s in state.successors():
            m = max(m, self.minAB(s[1], a, b))
            if m >= b:
                return m
            a = max(a, m)
        return m
    def minAB(self, state, a, b):
        if state.is_full():
            return state.utility()
        m = math.inf
        for s in state.successors():
            m = min(m, self.maxAB(s[1], a, b))
            if m <= a:
                return m
            b = min(b, m)
        return m

# N.B.: The following class is provided for convenience only; you do not need to implement it!

class OtherMinimaxHeuristicAgent(MinimaxAgent):
    """Alternative heursitic agent used for testing."""

    def __init__(self, depth_limit):
        self.depth_limit = depth_limit

    def minimax(self, state):
        """Determine the heuristically estimated minimax utility value of the given state."""
        #
        # Fill this in, if it pleases you.
        #
        return 26  # Change this line, unless you have something better to do.

# Player 2 wins! 9 - 18
# Player 1 generated 10645 states
# Player 2 generated 46391 states

# Player 2 wins! 9 - 18
# Player 1 generated 3031 states
# Player 2 generated 7771 states


import sys
import logging
# This module is used by non-GUI programs and thus must not import gtk.

# A wrapper around 'logging' with some convenience stuff.  In particular:
#   -- You initialize it with a prefix (like "wimpiggy.window"), but can pass
#      a type= kwarg to any of the loggin methods to further specialize the
#      logging target (like "damage" to get "wimpiggy.window.damage").
#   -- You can pass exc_info=True to any method, and sys.exc_info() will be
#      substituted.
#   -- __call__ is an alias for debug
#   -- The default logging target is set to the name of the module where
#      Logger() was called.

class Logger(object):
    def __init__(self, base=None):
        if base is None:
            base = sys._getframe(1).f_globals["__name__"]
        self._base = base

    def getLogger(self, type=None):
        name = self._base
        if type:
            name += ". " + type
        return logging.getLogger(name)

    def log(self, level, msg, *args, **kwargs):
        if kwargs.get("exc_info") is True:
            kwargs["exc_info"] = sys.exc_info()
        type = None
        if "type" in kwargs:
            type = kwargs["type"]
            del kwargs["type"]
        self.getLogger(type).log(level, msg, *args, **kwargs)

    def _method_maker(level):
        return (lambda self, msg, *args, **kwargs:
                self.log(level, msg, *args, **kwargs))

    debug = _method_maker(logging.DEBUG)
    __call__ = debug
    info = _method_maker(logging.INFO)
    warn = _method_maker(logging.WARNING)
    error = _method_maker(logging.ERROR)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/4/9 15:20
# @Author  : Zoe
# @Site    :
# @File    : dilate.py
# @Software: PyCharm Community Edition
import cv2
import numpy as np
from matplotlib import pyplot as plt

def dilate(img):
    kernel = np.ones((3, 3), np.uint8)
    dilate = cv2.dilate(img, kernel, iterations=1)
    titles = ['Original Image', 'Dilate Image']
    images = [img, dilate]
    plt.figure()
    for i in range(2):
        plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
        plt.title(titles[i])
        plt.xticks([])
        plt.yticks([])
    plt.show()

if __name__ == '__main__':
    # 读入灰度图像
    image = cv2.imread('./data/1.jpg', 0)
    if image is None:
        raise Exception("No image load!")
    dilate(image)


from rest_framework import generics, permissions, status
from rest_framework.authentication import TokenAuthentication
from rest_framework.filters import OrderingFilter
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.schemas.openapi import AutoSchema
from rest_framework.views import APIView

from .filters import *
from .models import DidatticaTestiRegolamento, DidatticaCdsAltriDati, DidatticaCdsAltriDatiUfficio
from .serializers import *
from .services import *
from .pagination import UnicalStorageApiPaginationList

### useful for storage backend only ###
from organizational_area.models import OrganizationalStructureOfficeEmployee
from crud.utils.settings import *
### end useful for storage backend only ###

# permissions.IsAuthenticatedOrReadOnly
# allow authenticated users to perform any request. Requests for
# unauthorised users will only be permitted if the request method is
# one of the "safe" methods; GET, HEAD or OPTIONS
from .utils import encode_labels, encrypt, decrypt

class ApiEndpointList(generics.ListAPIView):
    pagination_class = UnicalStorageApiPaginationList
    permission_classes = [permissions.AllowAny]
    # filter_backends = [OrderingFilter]
    # ordering_fields = '__all__'
    allowed_methods = ('GET',)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.language = None

    def get(self, obj, **kwargs):
        self.language = str(
            self.request.query_params.get(
                'lang', 'null')).lower()
        if self.language == 'null':
            self.language = self.request.LANGUAGE_CODE

        queryset = self.get_queryset()

        serializer = self.get_serializer(queryset, many=True)

        results = self.paginate_queryset(serializer.data)
        results = {
            'data': results,
            'language': self.language,
        }
        return self.get_paginated_response(results)

    def get_serializer_context(self):
        context = super().get_serializer_context()
        context.update({'language': self.language})
        return context

class ApiEndpointDetail(ApiEndpointList):

    def get(self, obj, **kwargs):
        self.language = str(
            self.request.query_params.get(
                'lang', 'null')).lower()
        if self.language == 'null':
            self.language = self.request.LANGUAGE_CODE

        queryset = self.get_queryset()
        if queryset is not None and len(queryset) > 0:
            serializer = self.get_serializer(queryset[0], many=False)
            return Response({
                'results': serializer.data,
                'labels': encode_labels(serializer.data, self.language)
            })

        return Response({
            'results': {},
            'labels': {}
        })

class ApiEndpointListSupport(ApiEndpointList):
    pagination_class = None
    permission_classes = [permissions.AllowAny]
    allowed_methods = ('GET',)

    def get(self, obj, **kwargs):
        self.language = str(
            self.request.query_params.get(
                'lang', 'null')).lower()
        if self.language == 'null':
            self.language = self.request.LANGUAGE_CODE

        queryset = self.get_queryset()

        if queryset is not None and len(queryset) > 0:
            serializer = self.get_serializer(queryset, many=True)
            return Response({
                'results': serializer.data,
                'labels': encode_labels(list(serializer.data)[0], self.language)
            })

        return Response({
            'results': {},
            'labels': {}
        })

# ----CdS----

# class ApiStatus(APIView):
#
#     description = 'Restituisce lo stato( health check API ) '
#
#
#     def get(self, *args, **kwargs):
#
#         return Response(content_type='application/problem+json')

class ApiCdSList(ApiEndpointList):
    description = 'Restituisce un elenco di Corsi di studio con un set' \
                  ' minimo di informazioni. Opera su ' \
                  '“DIDATTICA_REGOLAMENTO” e restituisce tutti i record' \
                  ' che corrispondono ai parametri impostati in input, ' \
                  'ordinati secondo il parametro indicato, nella lingua' \
                  ' selezionata (in mancanza, per le lingue straniere si' \
                  ' restituiscono dati in inglese o, se non presenti,' \
                  ' in italiano)'
    serializer_class = CdSSerializer
    filter_backends = [ApiCdsListFilter]

    def get_queryset(self):
        return ServiceDidatticaCds.cdslist(
            self.language, self.request.query_params)

class ApiCdSDetail(ApiEndpointDetail):
    description = 'Restituisce le informazioni di uno specifico' \
                  ' Corso di Studio che sono contenute nelle tabelle' \
                  ' DIDATTICA_REGOLAMENTO e DIDATTICA_TESTI_REGOLAMENTO' \
                  ' nella lingua indicata (in mancanza, si restituiscono' \
                  ' dati in inglese per altre lingue straniere o, se non' \
                  ' presenti, in italiano)'
    serializer_class = CdsInfoSerializer
    filter_backends = []

    def get_queryset(self):
        cdsid_param = self.kwargs['regdidid']
        res = DidatticaCds.objects.filter(
            didatticaregolamento__regdid_id=cdsid_param)
        langs = res.prefetch_related('didatticacdslingua')

        res = res.values(
            'didatticaregolamento__regdid_id',
            'didatticaregolamento__aa_reg_did',
            'didatticaregolamento__frequenza_obbligatoria',
            'dip__dip_id',
            'dip__dip_cod',
            'dip__dip_des_it',
            'dip__dip_des_eng',
            'cds_id',
            'cds_cod',
            'cdsord_id',
            'nome_cds_it',
            'nome_cds_eng',
            'tipo_corso_cod',
            'tipo_corso_des',
            'cla_miur_cod',
            'cla_miur_des',
            'intercla_miur_cod',
            'intercla_miur_des',
            'durata_anni',
            'valore_min',
            'codicione',
            'didatticaregolamento__titolo_congiunto_cod',
            'didatticaregolamento__stato_regdid_cod',
            'area_cds',
            'area_cds_en',
        ).distinct()

        for r in res:
            erogation_mode = DidatticaRegolamento.objects.filter(cds_id=r['cds_id'],
                                                                 stato_regdid_cod__exact='A').values(
            'modalita_erogazione'
            )
            if (len(erogation_mode) != 0):
                r['ErogationMode'] = erogation_mode
            else:
                r['ErogationMode'] = None

        res = list(res)

        if len(res) == 0:
            return None

        texts = DidatticaTestiRegolamento.objects.filter(
            regdid=cdsid_param).values(
            'regdid__regdid_id',
            'clob_txt_ita',
            'clob_txt_eng',
            'testo_regdid_url',
            'tipo_testo_regdid_cod',
            'profilo',
            'profilo_eng')

        list_profiles = {}
        last_profile = ""

        res[0]['Languages'] = langs.values(
            "didatticacdslingua__lingua_des_it",
            "didatticacdslingua__lingua_des_eng").distinct()

        res[0]['URL_CDS_DOC'] = None
        res[0]['URL_CDS'] = None
        res[0]['INTRO_CDS_FMT'] = None
        res[0]['URL_CDS_VIDEO'] = None
        res[0]['DESC_COR_BRE'] = None
        res[0]['OBB_SPEC'] = None
        res[0]['REQ_ACC'] = None
        res[0]['REQ_ACC_2'] = None
        res[0]['PROFILO'] = None
        res[0]['PROVA_FINALE'] = None
        res[0]['PROVA_FINALE_2'] = None

        for text in texts:
            if text['tipo_testo_regdid_cod'] != 'FUNZIONI' and text['tipo_testo_regdid_cod'] != 'COMPETENZE' and text['tipo_testo_regdid_cod'] != 'SBOCCHI':
                if (text['clob_txt_eng'] is None and self.language !=
                        "it") or self.language == 'it':
                    res[0][text['tipo_testo_regdid_cod']] = text['clob_txt_ita']
                else:
                    res[0][text['tipo_testo_regdid_cod']] = text['clob_txt_eng']
            else:
                if (self.language !=
                        "it" and text["profilo_eng"] is None) or self.language == 'it':
                    if text["profilo"] != last_profile:
                        last_profile = text["profilo"]
                        list_profiles[last_profile] = {}
                elif text[f'{ self.language == "it" and "profilo" or "profilo_eng" }'] != last_profile: # pragma: no cover
                    last_profile = text[f'{self.language == "it" and "profilo" or "profilo_eng"}']
                    list_profiles[last_profile] = {}

                if (text["clob_txt_eng"] is None and self.language !=
                        "it") or self.language == 'it':
                    list_profiles[last_profile][text['tipo_testo_regdid_cod']
                                                ] = text["clob_txt_ita"]
                else:
                    list_profiles[last_profile][text['tipo_testo_regdid_cod']
                                                ] = text['clob_txt_eng']
        res[0]['PROFILO'] = list_profiles

        res[0]['OtherData'] = DidatticaCdsAltriDati.objects.filter(regdid_id=cdsid_param).values(
            'matricola_coordinatore',
            'nome_origine_coordinatore',
            'matricola_vice_coordinatore',
            'nome_origine_vice_coordinatore',
            'num_posti',
            'modalita_iscrizione',
            'manifesto_studi',
            'regolamento_didattico',
            'ordinamento_didattico'
        ).distinct()

        res[0]['OfficesData'] = DidatticaCdsAltriDatiUfficio.objects.filter(cds_id=res[0]['cds_id']).values(
            'ordine',
            'nome_ufficio',
            'matricola_riferimento',
            'nome_origine_riferimento',
            'telefono',
            'email',
            'edificio',
            'piano',
            'orari',
            'sportello_online'
        ).distinct()

        return res

class ApiCdSStudyPlansList(ApiEndpointList):
    description = 'Restituisce un elenco di Piani di Studio'
    serializer_class = CdSStudyPlansSerializer
    filter_backends = []

    def get_queryset(self):
        cdsid_param = str(self.kwargs['regdidid'])

        return ServiceDidatticaAttivitaFormativa.getStudyPlans(
            regdid_id=cdsid_param)

class ApiStudyPlanDetail(ApiEndpointDetail):
    description = 'Restituisce i dettagli su un singolo piano di studi'
    serializer_class = CdSStudyPlanSerializer
    filter_backends = []

    def get_queryset(self):
        studyplanid = str(self.kwargs['studyplanid'])

        return ServiceDidatticaAttivitaFormativa.getStudyPlan(
            studyplanid=studyplanid)

class StudyPlanActivitiesList(AutoSchema):
    def get_operation_id(self, path, method):
        return 'listCdsStudyPlanActivities'

class ApiStudyPlanActivitiesList(ApiEndpointList):
    description = 'Restituisce l’elenco degli insegnamenti' \
                  ' di un Piano di Studio con info sintetiche'
    serializer_class = StudyPlansActivitiesSerializer
    filter_backends = []
    schema = StudyPlanActivitiesList()

    def get_queryset(self):
        studyplanid = str(self.kwargs['studyplanid'])

        return ServiceDidatticaAttivitaFormativa.getAttivitaFormativaByStudyPlan(
            studyplanid=studyplanid)

class ApiAllStudyActivitiesList(ApiEndpointList):
    description = 'Restituisce l’elenco degli insegnamenti' \
                  ' di un Piano di Studio con info sintetiche'
    serializer_class = StudyActivitiesSerializer
    filter_backends = [ApiAllActivitiesListFilter]

    def get_queryset(self):
        request = self.request
        department = request.query_params.get('department')
        cds = request.query_params.get('cds')
        academic_year = request.query_params.get('academic_year')
        period = request.query_params.get('period')
        ssd = request.query_params.get('ssd')
        teaching = request.query_params.get('teaching')
        teacher = request.query_params.get('teacher')
        course_year = request.query_params.get('course_year')
        cds_cod = request.query_params.get('cds_cod')
        teacher_code = decrypt(request.query_params.get('teacher_code'))

        return ServiceDidatticaAttivitaFormativa.getAllActivities(self.language, department, cds, academic_year, period, ssd, teacher, teaching, course_year, cds_cod, teacher_code)

class ApiStudyActivityDetail(ApiEndpointDetail):
    description = 'Restituisce le informazioni' \
                  ' dettagliate su un singolo “Insegnamento”'
    serializer_class = StudyActivityInfoSerializer
    filter_backends = []

    def get_queryset(self):

        studyactivityid = str(self.kwargs['studyactivityid'])

        return ServiceDidatticaAttivitaFormativa.getAttivitaFormativaWithSubModules(
            af_id=studyactivityid, language=self.language)

class StudyActivityInfo(AutoSchema):
    def get_operation_id(self, path, method):
        return 'retrieveCdsStudyPlanActivity'

class ApiStudyActivityInfo(ApiEndpointDetail):
    description = 'Restituisce le informazioni' \
                  ' dettagliate su un singolo “Insegnamento”'
    serializer_class = StudyActivityInfoSerializer
    filter_backends = []
    schema = StudyActivityInfo()

    def get_queryset(self):
        studyactivityid = str(self.kwargs['studyactivityid'])

        return ServiceDidatticaAttivitaFormativa.getAttivitaFormativaWithSubModules(
            af_id=studyactivityid, language=self.language)

# class ApiCdSMainTeachersList(ApiEndpointList):
#     description = 'Fornisce l’elenco dei docenti di riferimento' \
#                   ' (o di tutti i docenti ???) associati ad un CdS.' \
#                   ' Per ogni docente riporta poche informazioni' \
#                   ' identificative: Nome, Ruolo, Settore scientifico' \
#                   ' disciplinare, …'
#     serializer_class = CdSMainTeachersSerializer
#     filter_backends = [ApiCdSMainTeachersFilter]
#
#     def get_queryset(self):
#         regdid_id = self.request.query_params.get('cdsid')
#         if not regdid_id:
#             return None
#
#         return ServiceDidatticaAttivitaFormativa.getDocentiPerReg(regdid_id)

# ----Ricerca----

# class ApiTeacherResearchGroupsList(ApiEndpointList):
#     description = 'La funzione restituisce l’elenco ' \
#                   'dei gruppi di ricerca del docente ordinati per nome.'
#     serializer_class = TeacherResearchGroupsSerializer
#     filter_backends = []
#
#     def get_queryset(self):
#         teacherid = self.kwargs['teacherid']
#
#         return ServiceDocente.getResearchGroups(teacherid)

class ApiResearchGroupsList(ApiEndpointList):
    description = 'La funzione restituisce l’elenco ' \
                  'dei gruppi di ricerca ordinati per nome.'
    serializer_class = AllResearchGroupsSerializer
    filter_backends = [ApiResearchGroupsListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        teacher = decrypt(request.query_params.get('teacher'))
        department = request.query_params.get('department')
        cod = request.query_params.get('coderc1')

        return ServiceDocente.getAllResearchGroups(search, teacher, department, cod)

class ApiTeacherResearchLinesList(ApiEndpointList):
    description = 'La funzione restituisce l’elenco delle Linee di' \
                  ' ricerca del docente ordinati ' \
                  'per Tipo (applicata/di base) e Nome.'
    serializer_class = TeacherResearchLinesSerializer
    filter_backends = []

    def get_queryset(self):
        teacherid = decrypt(self.kwargs['teacherid'])

        only_active = True
        # get only active elements if public
        # get all elements if in CRUD backend
        request = self.request
        if request.user.is_superuser: only_active = False # pragma: no cover
        if request.user.is_authenticated: # pragma: no cover
            my_offices = OrganizationalStructureOfficeEmployee.objects.filter(employee=request.user,
                                                                              office__name=OFFICE_RESEARCHLINES,
                                                                              office__is_active=True,
                                                                              office__organizational_structure__is_active=True)
            if my_offices.exists(): only_active = False

        return ServiceDocente.getResearchLines(teacherid, only_active)

class ApiBaseResearchLinesList(ApiEndpointList):
    description = 'La funzione restituisce l’elenco delle Linee di' \
                  ' ricerca di base'
    serializer_class = BaseResearchLinesSerializer
    filter_backends = [ApiBaseResearchLinesListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        teacher = decrypt(self.request.query_params.get('teacher'))
        department = request.query_params.get('department')
        year = request.query_params.get('year')

        only_active = True
        # get only active elements if public
        # get all elements if in CRUD backend
        if request.user.is_superuser: only_active = False # pragma: no cover
        if request.user.is_authenticated: # pragma: no cover
            my_offices = OrganizationalStructureOfficeEmployee.objects.filter(employee=request.user,
                                                                              office__name=OFFICE_RESEARCHLINES,
                                                                              office__is_active=True,
                                                                              office__organizational_structure__is_active=True)
            if my_offices.exists(): only_active = False

        return ServiceDocente.getBaseResearchLines(
            search, teacher, department, year, only_active)

class ApiAppliedResearchLinesList(ApiEndpointList):
    description = 'La funzione restituisce l’elenco delle Linee di' \
                  ' ricerca applicate'
    serializer_class = AppliedResearchLinesSerializer
    filter_backends = [ApiAppliedResearchLinesListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        teacher = decrypt(self.request.query_params.get('teacher'))
        department = request.query_params.get('department')
        year = request.query_params.get('year')

        only_active = True
        # get only active elements if public
        # get all elements if in CRUD backend
        if request.user.is_superuser: only_active = False # pragma: no cover
        if request.user.is_authenticated: # pragma: no cover
            my_offices = OrganizationalStructureOfficeEmployee.objects.filter(employee=request.user,
                                                                              office__name=OFFICE_RESEARCHLINES,
                                                                              office__is_active=True,
                                                                              office__organizational_structure__is_active=True)
            if my_offices.exists(): only_active = False

        return ServiceDocente.getAppliedResearchLines(
            search, teacher, department, year, only_active)

class ApiAllResearchLinesList(ApiEndpointList):
    description = 'La funzione restituisce l’elenco di tutte le Linee di' \
                  ' ricerca'
    serializer_class = AllResearchLinesSerializer
    filter_backends = [ApiAllResearchLinesListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        year = request.query_params.get('year')
        department = request.query_params.get('department')
        ercs = request.query_params.get('ercs')
        asters = request.query_params.get('asters')
        exclude_base = request.query_params.get('exclude_base')
        exclude_applied = request.query_params.get('exclude_applied')

        only_active = True
        # get only active elements if public
        # get all elements if in CRUD backend
        if request.user.is_superuser: only_active = False # pragma: no cover
        if request.user.is_authenticated: # pragma: no cover
            my_offices = OrganizationalStructureOfficeEmployee.objects.filter(employee=request.user,
                                                                              office__name=OFFICE_RESEARCHLINES,
                                                                              office__is_active=True,
                                                                              office__organizational_structure__is_active=True)
            if my_offices.exists(): only_active = False

        return ServiceDocente.getAllResearchLines(search,
                                                  year,
                                                  department,
                                                  ercs,
                                                  asters,
                                                  exclude_base,
                                                  exclude_applied,
                                                  only_active)

# ----Docenti----

class ApiTeachersList(ApiEndpointList):
    description = 'Restituisce un elenco di Docenti che hanno una copertura attiva in ateneo, con un set minimo di ' \
                  'informazioni identificative: Nome, Ruolo, ' \
                  'Settore scientifico disciplinare, …'
    serializer_class = TeachersSerializer
    filter_backends = [ApiTeachersListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        regdidid = request.query_params.get('regdid')
        department = request.query_params.get('department')
        role = request.query_params.get('role')
        cds = request.query_params.get('cds')
        year = request.query_params.get('year')

        return ServiceDocente.teachersList(
            search, regdidid, department, role, cds, year)

class TeachingCoveragesList(AutoSchema):
    def get_operation_id(self, path, method):
        return 'listTeachingCoverages'

class ApiTeachingCoveragesList(ApiEndpointList):
    description = 'Restituisce un elenco di Docenti con il fl_docente=1 e fl_cessato=0'\
        'con un set minimo di informazioni identificative: Nome, Ruolo, ' \
                  'Settore scientifico disciplinare, …'
    serializer_class = TeachersSerializer
    filter_backends = [ApiTeachersListFilter]
    schema = TeachingCoveragesList()

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        regdidid = request.query_params.get('regdid')
        department = request.query_params.get('department')
        role = request.query_params.get('role')
        cds = request.query_params.get('cds')
        year = request.query_params.get('year')

        return ServiceDocente.teachingCoveragesList(
            search, regdidid, department, role, cds, year)

class ApiTeacherStudyActivitiesList(ApiEndpointList):
    description = 'La funzione restituisce l’elenco degli insegnamenti' \
                  ' (per gli ultimi anni) ordinati per anno e nome' \
                  ' dell’insegnamento.'
    serializer_class = TeacherStudyActivitiesSerializer
    filter_backends = [ApiTeacherStudyActivitiesFilter]

    def get_queryset(self):
        request = self.request
        teacherid = decrypt(self.kwargs['teacherid'])
        year = request.query_params.get('year')
        yearFrom = request.query_params.get('yearFrom')
        yearTo = request.query_params.get('yearTo')

        return ServiceDocente.getAttivitaFormativeByDocente(
            teacherid, year, yearFrom, yearTo)

class TeachingCoverageStudyActivitiesList(AutoSchema):
    def get_operation_id(self, path, method):
        return 'listTeachingCoverageStudyActivities'

class ApiTeachingCoverageActivitiesList(ApiTeacherStudyActivitiesList):
    schema = TeachingCoverageStudyActivitiesList()

class ApiTeacherDetail(ApiEndpointDetail):
    description = 'La funzione restituisce la scheda informativa' \
                  ' dettagliata di un docente'
    serializer_class = TeacherInfoSerializer
    filter_backends = []

    def get_queryset(self):

        teacherid = decrypt(self.kwargs['teacherid'])

        return ServiceDocente.getDocenteInfo(teacherid)

class ApiTeacherMaterials(ApiEndpointList):
    description = 'La funzione restituisce il materiale didattico di un docente'
    serializer_class = TeacherMaterialsSerializer
    filter_backends = []

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        teacherid = decrypt(self.kwargs['teacherid'])
        return ServiceDocente.getDocenteMaterials(request.user, teacherid, search)

class ApiTeacherMaterial(ApiEndpointDetail):
    description = 'La funzione restituisce il materiale diddattico specifico di un docente'
    serializer_class = TeacherMaterialsSerializer
    filter_backends = []

    def get_queryset(self):
        teacherid = decrypt(self.kwargs['teacherid'])
        return ServiceDocente.getDocenteMaterials(teacherid)

class ApiTeacherNews(ApiEndpointList):
    description = 'La funzione restituisce le news di un docente'
    serializer_class = TeacherNewsSerializer
    filter_backends = []

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        teacherid = decrypt(self.kwargs['teacherid'])

        return ServiceDocente.getDocenteNews(request.user, teacherid, search)

class TeachingCoveragesInfo(AutoSchema):
    def get_operation_id(self, path, method):
        return 'retrieveTeachingCoverageInfo'

class ApiTeachingCoverageDetail(ApiTeacherDetail):
    schema = TeachingCoveragesInfo()

# ----Dottorati----

class ApiPhdList(ApiEndpointList):
    description = 'La funzione restituisce una lista di dottorati'
    serializer_class = PhdSerializer
    filter_backends = [ApiPhdListFilter]

    def get_queryset(self):
        return ServiceDottorato.getPhd(self.request.query_params)

# ---- Tipologie Lauree ----

class ApiDegreeTypesList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle tipologie di lauree'
    serializer_class = DegreeTypesSerializer
    filter_backends = []

    def get_queryset(self):
        return ServiceDidatticaCds.getDegreeTypes()

# ---- Dipartimenti ----

class ApiDepartmentsList(ApiEndpointList):
    description = 'La funzione restituisce la lista dei dipartimenti'
    serializer_class = DepartmentSerializer
    filter_backends = []

    def get_queryset(self):
        return ServiceDipartimento.getDepartmentsList(self.language)

class ApiDepartmentDetail(ApiEndpointDetail):
    description = 'La funzione restituisce uno specifico dipartimento'
    serializer_class = DepartmentSerializer
    filter_backends = []

    def get_queryset(self):
        departmentcod = self.kwargs['departmentcod']
        return ServiceDipartimento.getDepartment(departmentcod)

class ApiAddressbookList(ApiEndpointList):
    description = 'La funzione restituisce la rubrica telefonica del personale'
    serializer_class = AddressbookSerializer
    filter_backends = [ApiAddressbookListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        phone = request.query_params.get('phone')
        structureid = request.query_params.get('structure')
        structuretypes = request.query_params.get('structuretypes')
        role = request.query_params.get('role')
        structuretree = request.query_params.get('structuretree')

        return ServicePersonale.getAddressbook(
            search, structureid, structuretypes, role, structuretree, phone)

class ApiStructuresList(ApiEndpointList):
    description = 'La funzione restituisce le strutture organizzative'
    serializer_class = StructuresSerializer
    filter_backends = [ApiStructuresListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        father = request.query_params.get('father')
        depth = request.query_params.get('depth')
        type = request.query_params.get('type')
        return ServicePersonale.getStructuresList(search, father, type, depth)

class ApiStructureTypesList(ApiEndpointListSupport):
    description = 'La funzione restituisce le tipologie di strutture organizzative'
    serializer_class = StructureTypesSerializer
    filter_backends = [ApiStructuresListFilter]

    def get_queryset(self):
        father = self.request.query_params.get('father')
        return ServicePersonale.getStructureTypes(father)

class ApiAcademicYearsList(ApiEndpointListSupport):
    description = 'La funzione restituisce gli anni accademici'
    serializer_class = AcademicYearsSerializer
    filter_backends = []

    def get_queryset(self):
        return ServiceDidatticaCds.getAcademicYears()

class ApiStructureDetail(ApiEndpointDetail):
    description = 'La funzione restituisce una specifica struttura'
    serializer_class = StructureDetailSerializer
    filter_backends = [ApiStructuresListFilter]

    def get_queryset(self):
        structureid = self.kwargs['structureid']
        return ServicePersonale.getStructure(structureid)

class ApiRolesList(ApiEndpointListSupport):
    description = 'La funzione restituisce i ruoli'
    serializer_class = RolesSerializer
    filter_backends = []

    def get_queryset(self):
        return ServiceDocente.getRoles()

class ApiPersonaleDetail(ApiEndpointDetail):
    description = 'La funzione restituisce una specifica persona'
    serializer_class = PersonaleSerializer
    # filter_backends = [ApiAddressbookListFilter]

    def get_queryset(self):
        personaleid = decrypt(self.kwargs['personaleid'])

        return ServicePersonale.getPersonale(personaleid)

class ApiLaboratoryDetail(ApiEndpointDetail):
    description = 'La funzione restituisce un laboratorio specifico'
    serializer_class = LaboratoryDetailSerializer
    # filter_backends = [ApiAddressbookListFilter]

    def get_queryset(self):
        laboratoryid = self.kwargs['laboratoryid']

        return ServiceLaboratorio.getLaboratory(self.language, laboratoryid)

class ApiLaboratoriesList(ApiEndpointList):
    description = 'La funzione restituisce i laboratori'
    serializer_class = LaboratoriesSerializer
    filter_backends = [ApiLaboratoriesListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        area = request.query_params.get('area')
        department = request.query_params.get('department')
        erc1 = request.query_params.get('erc1')
        teacher = decrypt(request.query_params.get('teacher'))
        infrastructure = request.query_params.get('infrastructure')
        scope = request.query_params.get('scope')

        return ServiceLaboratorio.getLaboratoriesList(
            self.language, search, area, department, erc1, teacher, infrastructure, scope)

class ApiLaboratoriesAreasList(ApiEndpointList):
    description = 'La funzione restituisce la lista degli ambiti dei laboratori'
    serializer_class = LaboratoriesAreasSerializer
    filter_backends = []

    def get_queryset(self):
        return ServiceLaboratorio.getLaboratoriesAreasList()

class ApiErc1List(ApiEndpointList):
    description = 'La funzione restituisce la lista degli erc1'
    serializer_class = Erc1Serializer
    filter_backends = []

    def get_queryset(self):

        return ServiceLaboratorio.getErc1List()

class ApiErc2List(ApiEndpointList):
    description = 'La funzione restituisce la lista degli erc2'
    serializer_class = Erc2Serializer
    filter_backends = []

    def get_queryset(self):

        return ServiceLaboratorio.getErc2List()

class ApiErc0List(ApiEndpointList):
    description = 'La funzione restituisce la lista degli erc0'
    serializer_class = Erc0Serializer
    filter_backends = []

    def get_queryset(self):

        return ServiceLaboratorio.getErc0List()

class ApiPublicationsList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle pubblicazioni di un dato docente'
    serializer_class = PublicationsSerializer
    filter_backends = [ApiPublicationsListFilter]

    def get_queryset(self):
        request = self.request
        teacherid = decrypt(self.kwargs.get('teacherid')) if self.kwargs.get('teacherid') else ''
        search = request.query_params.get('search')
        year = request.query_params.get('year')
        type = request.query_params.get('type')
        structure = request.query_params.get('structure')

        return ServiceDocente.getPublicationsList(
            teacherid, search, year, type, structure)

class TeachingCoveragePublicationsList(AutoSchema):
    def get_operation_id(self, path, method):
        return 'listTeachingCoveragePublications'

class ApiTeachingCoveragePublicationsList(ApiPublicationsList):
    schema = TeachingCoveragePublicationsList()

class TeacherPublicationsList(AutoSchema):
    def get_operation_id(self, path, method):
        return 'listTeacherPublications'

class ApiTeacherPublicationsList(ApiPublicationsList):
    schema = TeacherPublicationsList()

class ApiPublicationsCommunityTypesList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle tipologie di pubblicazioni'
    serializer_class = PublicationsCommunityTypesSerializer
    filter_backends = []

    def get_queryset(self):
        return ServiceDocente.getPublicationsCommunityTypesList()

class ApiPublicationDetail(ApiEndpointDetail):
    description = 'La funzione restituisce il dettaglio di una pubblicazione'
    serializer_class = PublicationSerializer
    filter_backends = []

    def get_queryset(self):
        publicationid = self.kwargs['publicationid']

        return ServiceDocente.getPublication(publicationid)

class TeacherPublicationDetail(AutoSchema):
    def get_operation_id(self, path, method):
        return 'retrieveTeacherPublication'

class ApiTeacherPublicationDetail(ApiPublicationDetail):
    schema = TeacherPublicationDetail()

class TeachingCoveragePublicationsDetail(AutoSchema):
    def get_operation_id(self, path, method):
        return 'retrieveTeachingCoveragePublication'

class ApiTeachingCoveragePublicationDetail(ApiPublicationDetail):
    schema = TeachingCoveragePublicationsDetail()

class ApiAddressbookStructuresList(ApiEndpointList):
    description = 'La funzione restituisce le strutture organizzative a cui un docente afferisce'
    serializer_class = AddressbookStructuresSerializer
    filter_backends = [ApiStructuresListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        father = request.query_params.get('father')
        type = request.query_params.get('type')

        return ServicePersonale.getAllStructuresList(search, father, type)

class AddressbookStructureDetail(AutoSchema):
    def get_operation_id(self, path, method):
        return 'retrieveAddressbookStructureDetail'

class ApiAddressbookStructureDetail(ApiStructureDetail):
    schema = AddressbookStructureDetail()

class ApiInfrastructuresList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle infrastrutture di riferimento'
    serializer_class = InfrastructuresSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceLaboratorio.getInfrastructures()

class ApiPatentsList(ApiEndpointList):
    description = 'La funzione restituisce la lista dei brevetti'
    serializer_class = PatentsSerializer
    filter_backends = [ApiPatentsListFilter]

    def get_queryset(self):
        request = self.request
        only_active = True

        # get only active elements if public
        # get all elements if in CRUD backend
        if request.user.is_superuser: only_active = False # pragma: no cover
        if request.user.is_authenticated: # pragma: no cover
            my_offices = OrganizationalStructureOfficeEmployee.objects.filter(employee=request.user,
                                                                              office__name=OFFICE_PATENTS,
                                                                              office__is_active=True,
                                                                              office__organizational_structure__is_active=True)
            if my_offices.exists(): only_active = False
        # end get active/all elements

        search = request.query_params.get('search')
        techarea = request.query_params.get('techarea')
        structure = request.query_params.get('structure')

        return ServiceBrevetto.getPatents(search, techarea, structure, only_active)

class ApiPatentDetail(ApiEndpointDetail):
    description = 'La funzione restituisce uno specifico brevetto'
    serializer_class = PatentsSerializer
    filter_backends = []

    def get_queryset(self):

        patentid = self.kwargs['patentid']

        return ServiceBrevetto.getPatentDetail(patentid)

class ApiLaboratoriesScopesList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle finalità dei laboratori'
    serializer_class = LaboratoriesScopesSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceLaboratorio.getScopes()

class ApiCompaniesList(ApiEndpointList):
    description = 'La funzione restituisce la lista degli spin-off'
    serializer_class = CompaniesSerializer
    filter_backends = [ApiCompaniesListFilter]

    def get_queryset(self):
        request = self.request
        only_active = True

        # get only active elements if public
        # get all elements if in CRUD backend
        if request.user.is_superuser: only_active = False # pragma: no cover
        if request.user.is_authenticated: # pragma: no cover
            my_offices = OrganizationalStructureOfficeEmployee.objects.filter(employee=request.user,
                                                                              office__name=OFFICE_COMPANIES,
                                                                              office__is_active=True,
                                                                              office__organizational_structure__is_active=True)
            if my_offices.exists(): only_active = False
        # end get active/all elements

        search = request.query_params.get('search')
        techarea = request.query_params.get('techarea')
        spinoff = request.query_params.get('spinoff')
        startup = request.query_params.get('startup')
        departments = request.query_params.get('departments')

        return ServiceCompany.getCompanies(search, techarea, spinoff, startup, departments, only_active)

class ApiCompanyDetail(ApiEndpointDetail):
    description = 'La funzione restituisce un particolare spinoff/startup'
    serializer_class = CompaniesSerializer
    filter_backends = []

    def get_queryset(self):

        companyid = self.kwargs['companyid']

        return ServiceCompany.getCompanyDetail(companyid)

class ApiTechAreasList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle aree tecnologiche'
    serializer_class = TechAreasSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceCompany.getTechAreas()

class ApiProjectsList(ApiEndpointList):
    description = 'La funzione restituisce la lista dei progetti'
    serializer_class = ProjectSerializer
    filter_backends = [ApiProjectsListFilter, OrderingFilter]

    def get_queryset(self):
        request = self.request
        only_active = True

        # get only active elements if public
        # get all elements if in CRUD backend
        if request.user.is_superuser: only_active = False # pragma: no cover
        if request.user.is_authenticated: # pragma: no cover
            my_offices = OrganizationalStructureOfficeEmployee.objects.filter(employee=request.user,
                                                                              office__name=OFFICE_PROJECTS,
                                                                              office__is_active=True,
                                                                              office__organizational_structure__is_active=True)
            if my_offices.exists(): only_active = False
        # end get active/all elements

        search = request.query_params.get('search')
        techarea = request.query_params.get('techarea')
        infrastructure = request.query_params.get('infrastructure')
        programtype = request.query_params.get('programtype')
        territorialscope = request.query_params.get('territorialscope')
        notprogramtype = request.query_params.get('-programtype')
        year =request.query_params.get('year')

        return ServiceProgetto.getProjects(search,
                                           techarea,
                                           infrastructure,
                                           programtype,
                                           territorialscope,
                                           notprogramtype,
                                           year,
                                           only_active)

class ApiProjectDetail(ApiEndpointDetail):
    description = 'La funzione restituisce il dettaglio'
    serializer_class = ProjectSerializer
    filter_backends = []

    def get_queryset(self):

        projectid = self.kwargs['projectid']

        return ServiceProgetto.getProjectDetail(projectid)

class ApiStructureFunctionsList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle funzioni della unità organizzativa'
    serializer_class = StructureFunctionsSerializer
    filter_backends = []

    def get_queryset(self):

        return ServicePersonale.getStructureFunctions()

class ApiProjectsTerritorialScopesList(ApiEndpointList):
    description = 'La funzione restituisce la lista degli ambiti territoriali'
    serializer_class = TerritorialScopesSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceProgetto.getTerritorialScopes()

class ApiProjectsProgramTypesList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle tipologie di programmi di progetto'
    serializer_class = ProgramTypesSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceProgetto.getProgramTypes()

class ApiCdsAreasList(ApiEndpointListSupport):
    description = 'La funzione restituisce la lista delle aree dei cds'
    serializer_class = CdsAreasSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceDidatticaCds.getCdsAreas()

class ApiProjectsInfrastructuresList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle infrastrutture dei progetti'
    serializer_class = ProjectInfrastructuresSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceProgetto.getProjectInfrastructures()

class ApiPersonnelCfList(ApiEndpointList):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]
    description = 'La funzione restituisce la lista dei cf del personale'
    serializer_class = PersonnelCfSerializer
    filter_backends = []

    def get_queryset(self):

        roles = self.request.query_params.get('roles')

        return ServicePersonale.getPersonnelCfs(roles)

class ApiSortingContacts(ApiEndpointList):
    description = 'La funzione riceve in input il codice di un corso di studio e restituisce i docenti che appartengono a quel cds con dipartimento e uffici'
    serializer_class = SortingContactsSerializer
    filter_backends = []

    def get_queryset(self):

        cdscod = self.kwargs['cdscod']

        return ServiceDidatticaCds.getContacts(cdscod)

class ApiHighFormationMastersList(ApiEndpointList):
    description = 'La funzione restituisce i master alta formazione'
    serializer_class = HighFormationMastersSerializer
    filter_backends = [ApiHighFormationMastersListFilter]

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        director = request.query_params.get('director')
        coursetype = request.query_params.get('coursetype')
        erogation = request.query_params.get('erogation')
        department = request.query_params.get('department')
        language = request.query_params.get('language')
        year = request.query_params.get('year')

        return ServiceDidatticaCds.getHighFormationMasters(search, director, coursetype, erogation, department, language, year)

class ApiHighFormationMastersDetail(ApiEndpointDetail):
    description = 'La funzione restituisce il dettaglio di un master'
    serializer_class = HighFormationMastersSerializer
    filter_backends = [ApiHighFormationMastersListFilter]

    def get_queryset(self):

        master_id = self.kwargs['id']

        return ServiceDidatticaCds.getHighFormationMaster(master_id)

class ApiErogationModesList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle modalità di erogazione'
    serializer_class = ErogationModesSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceDidatticaCds.getErogationModes()

class ApiHighFormationCourseTypesList(ApiEndpointList):
    description = 'La funzione restituisce la lista dei tipi di corso dell\'alta formazione'
    serializer_class = HighFormationCourseTypesSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceDidatticaCds.getHighFormationCourseTypes()

class ApiPersonIdSchema(AutoSchema):
    def get_operation_id(self, path, method):
        return 'getPersonId'

class ApiPersonId(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]
    description = 'La funzione restituisce il codice criptato di una persona'
    schema = ApiPersonIdSchema()

    def post(self, request, *args, **kwargs):
        data = request.data
        matricola = data.get("id","")
        if not matricola:
            return Response("Il dato non è stato inserito", status=status.HTTP_404_NOT_FOUND)
        p = Personale.objects.filter(matricola=matricola).first()
        if not p:
            return Response("Il dato non esiste", status=status.HTTP_404_NOT_FOUND)
        return Response(encrypt(matricola))

class ApiDecryptedPersonIdSchema(AutoSchema):
    def get_operation_id(self, path, method):
        return 'getDecryptedPersonId'

class ApiDecryptedPersonId(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]
    description = 'La funzione restituisce la matricola in chiaro una persona'
    schema = ApiDecryptedPersonIdSchema()

    def post(self, request, *args, **kwargs):
        data = request.data
        encrypted_matricola = data.get("id","")
        if not encrypted_matricola:
            return Response("Il dato non è stato inserito", status=status.HTTP_404_NOT_FOUND)
        try:
            m = decrypt(encrypted_matricola)
            return Response(m)
        except:
            return Response("Non è stato possibile decriptare il dato", status=status.HTTP_404_NOT_FOUND)

class ApiAster1List(ApiEndpointList):
    description = 'La funzione restituisce la lista degli aster1'
    serializer_class = Asters1Serializer
    filter_backends = []

    def get_queryset(self):

        return ServiceLaboratorio.getAster1List()

class ApiAster2List(ApiEndpointList):
    description = 'La funzione restituisce la lista degli aster2'
    serializer_class = Asters2Serializer
    filter_backends = []

    def get_queryset(self):

        return ServiceLaboratorio.getAster2List()

class ApiPhdActivitiesList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle attività dei dottorati'
    serializer_class = PhdActivitiesSerializer
    filter_backends = []

    def get_queryset(self):
        request = self.request
        search = request.query_params.get('search')
        structure = request.query_params.get('structure')
        phd = request.query_params.get('phd')
        ssd = request.query_params.get('ssd')
        teacher = request.query_params.get('teacher')

        return ServiceDottorato.getPhdActivities(search, structure, phd, ssd, teacher)

class ApiPhdActivityDetail(ApiEndpointDetail):
    description = 'La funzione restituisce il dettaglio di una attività riferita ad un dottorato'
    serializer_class = PhdActivitiesSerializer
    filter_backends = []

    def get_queryset(self):

        activity_id = self.kwargs['id']

        return ServiceDottorato.getPhdActivity(activity_id)

class ApiRefPhdList(ApiEndpointList):
    description = 'La funzione restituisce la lista dei dottorati di riferimento'
    serializer_class = RefPhdSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceDottorato.getRefPhd()

class ApiRefStructuresList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle strutture di riferimento'
    serializer_class = RefStructuresSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceDottorato.getRefStructures()

class ApiPhdSsdList(ApiEndpointList):
    description = 'La funzione restituisce la lista degli ssd dei dottorati'
    serializer_class = PhdSsdListSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceDottorato.getPhdSsdList()

class ApiPhdActivityTypeList(ApiEndpointList):
    description = 'La funzione restituisce la lista delle tipologie di dottorato'
    serializer_class = PhdActivityTypeSerializer
    filter_backends = []

    def get_queryset(self):

        return ServiceDottorato.getPhdActivityTypeList()


from flir_tool import *

class Preprocess:
    def __init__(self, csv_file, image_size, stride, defect_area):
        self.csv_file_path = csv_file
        self.image_size = int(image_size)
        self.stride = int(stride)
        self.defect_area = float(defect_area)

        self.H = 15 #GFRP height
        self.W = 210 #GFRP width

        self.csv_load()
        separate_frames(self.csv_file_path, self.csv_file, self.stride, self.defect_area, self.image_size, self.image_size, self.W, self.H)

    def csv_load(self):
        self.csv_file = load_csv(self.csv_file_path)
        self.csv_file = extract_frames(self.csv_file)

def set_contact():
    csv_file = file_choose()
    image_size = input("image height:")
    stride = input("Stride:")
    defect_area = input("defect loc:")
    Preprocess(csv_file, image_size, stride, defect_area)

def run():
    set_contact()

if __name__ == "__main__":
    run()


#!/usr/bin/python2.7

import urllib.request, re

#id = '12345'
#id = '8022'
id = '63579'
for i in range(400):
    line = urllib.request.urlopen("http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=" + id).readline().decode('utf-8')
    print(line)
    id = re.search('the next nothing is (\d+)', line).group(1)


import sys
input = sys.stdin.readline
INF = float('inf')

v, e = map(int, input().split())
digraph = [list(0 if i == j else INF for i in range(v)) for j in range(v)]

for _ in range(e):
    n, m, w = map(int, input().split())
    digraph[n-1][m-1] = w

for k in range(v):
    for i in range(v):
        for j in range(v):
            if digraph[i][j] > digraph[i][k] + digraph[k][j]:
                digraph[i][j] = digraph[i][k] + digraph[k][j]

result = list()
for i in range(v):
    for j in range(v):
        temp = digraph[i][j] + digraph[j][i]
        if 0 < temp < INF:
            result.append(temp)

print(min(result) if result else '-1')


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# michael a.g. aïvázis
# orthologue
# (c) 1998-2019 all rights reserved
#

# externals
import pyre.parsing
import pyre.tracking
import pyre.patterns

# class declaration
class ScheduleParser(pyre.parsing.parser):
    """
    A simple parser for schedule specification files
    """

    # types
    from .ScheduleScanner import ScheduleScanner as lexer

    # interface
    def parse(self, uri, stream, locator):
        """
        Harvest the schedule events in {stream}
        """
        # initialize my context
        self.employee = []
        self.days = []
        # set up my processor
        processor = self.processor(locator)
        # tokenize the {stream}
        self.scanner.pyre_tokenize(uri=uri, stream=stream, client=processor)
        # all done
        return self.schedule

    # meta methods
    def __init__(self, **kwds):
        # chain up
        super().__init__(**kwds)
        # initialize the list of harvested tasks
        self.schedule = pyre.patterns.vivify(levels=2, atom=list)

        # the production table
        self.productions = {
            # the ignorables
            self.scanner.start: self.ignore,
            self.scanner.comment: self.ignore,
            self.scanner.whitespace: self.ignore,
            self.scanner.finish: self.ignore,
            # context specifier
            self.scanner.employee: self.processEmployee,
            }
        # and the list of errors encountered during parsing
        self.errors = []
        # all done
        return

    # implementation details
    @pyre.patterns.coroutine
    def processor(self, locator):
        """
        Receive tokens from the scanner and handle them
        """
        # for ever
        while True:
            # attempt to
            try:
                # get a token
                token = yield
            # if anything goes wrong
            except self.ParsingError as error:
                # save the error
                self.errors.append(error)
                # and move on
                continue

            # if we retrieved a well formed token, attempt to
            try:
                # look up the relevant production based on this terminal
                production = self.productions[type(token)]
            # if i don't have a production for this token
            except KeyError:
                # it must be a syntax error; build a locator
                loc = pyre.tracking.chain(this=token.locator, next=locator)
                # and an error
                error = self.SyntaxError(token=token, locator=loc)
                # save it
                self.errors.append(error)
                # move on
                continue
            # if all goes well, invoke the production
            yield from production(current=token)
        # all done
        return

    def ignore(self, **kwds):
        """
        Do nothing
        """
        # there is nothing to do here
        return []

    def processEmployee(self, current):
        """
        Process an {employee} token
        """
        # get the name of the employee
        employee = current.lexeme

        # while there are day specifications to process
        while True:
            # grab the next token
            days = yield
            # if it is not a day spec
            if type(days) is not self.scanner.days:
                # put it back
                self.scanner.pyre_pushback(days)
                # and bail
                return

            # convert the token into a list of days
            days = [ day.strip() for day in days.lexeme.split(',') ]

            # the current task is
            currentStation = None
            currentStart = None
            # now extract the assignments
            while True:
                # grab the next token
                task = yield
                # if it is a comment, ignore it
                if type(task) is self.scanner.comment: continue
                # if it is not a task
                if type(task) is not self.scanner.task:
                    # put it back
                    self.scanner.pyre_pushback(task)
                    # and bail
                    break
                # extract the station and the time
                station, time = tuple(item.strip() for item in task.lexeme.split('@'))
                # if i have a current task
                if currentStation:
                    # for every day it shows up
                    for day in days:
                        # it ends when this one starts
                        self.schedule[employee][day].append((currentStation, currentStart, time))

                # adjust my cursors
                currentStation, currentStart = (None, None) if station == 'out' else (station, time)

        # all done
        return

# end of file


import numpy as np
import pickle
import sys
import matplotlib.pyplot as plt
import random

def LoadBatch(filename):
    """ Copied from the dataset website """
    with open('Datasets/' + filename, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')
        X = dict[b"data"].T
        y = dict[b"labels"]
        Y = (np.eye(10)[y]).T
    return X, Y, y

def unpickle(file):
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')

    return dict

def normalize_data(data, mean, std):
    if mean is None and std is None:
        mean = np.mean(data, axis=1,
                       keepdims=True)  # mean of each row (for all images)
        std = np.std(data, axis=1, keepdims=True)  # Std of each row
    data = (data - mean) / std
    return data, mean, std

X_train, Y_train, y_train = LoadBatch('cifar-10-batches-py/data_batch_1')

X_train, mean_train, std_train = normalize_data(X_train, None, None)

X_val, Y_val, y_val = LoadBatch('cifar-10-batches-py/data_batch_2')

X_val = normalize_data(X_val, mean_train, std_train)[0]

X_test, Y_test, y_test = LoadBatch('cifar-10-batches-py/data_batch_3')

X_test = normalize_data(X_test, mean_train, std_train)[0]

batches = unpickle('Datasets/cifar-10-batches-py/batches.meta')

label_names = [
    label_name.decode('utf-8') for label_name in batches[b'label_names']
]

def init_weights(input_dimension, output_dimension, seed=0, std=0.01):
    #randomize weights with seed:
    np.random.seed(seed)
    W = np.random.normal(size=(output_dimension, input_dimension),
                         loc=0,
                         scale=std)
    np.random.seed(seed)
    b = np.random.normal(size=(output_dimension, 1), loc=0, scale=std)
    return W, b

def softmax(x):
    """ Standard definition of the softmax function """
    e_x = np.exp(x)
    p = e_x / e_x.sum(axis=0)
    return p

def EvaluateClassifier(X, W, b):
    """ Softmax acitvation function """
    a = softmax(W @ X + b)
    return a

def ComputeCost(X_c, Y, W, b, lmbda):

    #predictions, cross entropy loss
    P = EvaluateClassifier(X_c, W, b)
    # loss function term
    loss_cross = -np.sum(Y * np.log(P))
    # regularzation term
    loss_regularization = lmbda * (W**2).sum()
    return loss_cross / X_c.shape[1] + loss_regularization

def ComputeAccuracy(X_c, y_c, W_star, b_star):
    #calculates mean accuracy of predictions
    probabilities = EvaluateClassifier(X_c, W_star, b_star)
    return np.mean(y_c == np.argmax(probabilities, 0))

def ComputeGradients(X_b, Y_b, W_star, b_star, lamb):
    n = X_b.shape[1]
    O = Y_b.shape[0]
    predicted_labels = EvaluateClassifier(X_b, W_star, b)
    G = -(Y_b - predicted_labels)
    grad_W = (G @ X_b.T) / n + 2 * lamb * W_star
    grad_b = (G @ np.ones(shape=(n, 1)) / n).reshape(O, 1)
    return grad_W, grad_b

def ComputeGradsNum(X, Y, P, W, b, lamda, h=0.000001):
    #Converted from matlab code
    no = W.shape[0]
    d = X.shape[0]

    grad_W = np.zeros(W.shape)
    grad_b = np.zeros((no, 1))

    c = ComputeCost(X, Y, W, b, lamda)

    for i in range(len(b)):
        b_try = np.array(b)
        b_try[i] += h
        c2 = ComputeCost(X, Y, W, b_try, lamda)
        grad_b[i] = (c2 - c) / h

    for i in range(W.shape[0]):
        for j in range(W.shape[1]):
            W_try = np.array(W)
            W_try[i, j] += h
            c2 = ComputeCost(X, Y, W_try, b, lamda)
            grad_W[i, j] = (c2 - c) / h

    return [grad_W, grad_b]

def ComputeGradsNumSlow(X, Y, P, W, b, lamda, h=0.000001):
    """ Converted from matlab code """
    no = W.shape[0]
    d = X.shape[0]

    grad_W = np.zeros(W.shape)
    grad_b = np.zeros((no, 1))

    for i in range(len(b)):
        b_try = np.array(b)
        b_try[i] -= h
        c1 = ComputeCost(X, Y, W, b_try, lamda)

        b_try = np.array(b)
        b_try[i] += h
        c2 = ComputeCost(X, Y, W, b_try, lamda)

        grad_b[i] = (c2 - c1) / (2 * h)

    for i in range(W.shape[0]):
        for j in range(W.shape[1]):
            W_try = np.array(W)
            W_try[i, j] -= h
            c1 = ComputeCost(X, Y, W_try, b, lamda)

            W_try = np.array(W)
            W_try[i, j] += h
            c2 = ComputeCost(X, Y, W_try, b, lamda)

            grad_W[i, j] = (c2 - c1) / (2 * h)

    return [grad_W, grad_b]

def test_gradients_num(X, Y, W, b, lambda_):
    # Finction for checking the analytical gradietn with the numerical ones.
    # Compute the gradients analytically
    P = EvaluateClassifier(X, W, b)
    grad_W_analytical, grad_b_analytical = ComputeGradients(
        X, Y, W, b, lambda_)

    # Compute the gradients numerically
    grad_W_numerical, grad_b_numerical = ComputeGradsNum(
        X, Y, P, W, b, lambda_)
    grad_W_numerical_slow, grad_b_numerical_slow = ComputeGradsNumSlow(
        X, Y, P, W, b, lambda_)
    # Absolute error between numerically and analytically computed gradient
    grad_W_abs_diff = np.abs(grad_W_numerical - grad_W_analytical)
    grad_b_abs_diff = np.abs(grad_b_numerical - grad_b_analytical)

    grad_W_abs_diff_slow = np.abs(grad_W_numerical_slow - grad_W_analytical)
    grad_b_abs_diff_slow = np.abs(grad_b_numerical_slow - grad_b_analytical)
    # Absolute errors........

    print('For weights the maximum absolute error is ' +
          str((grad_W_abs_diff).max()))
    print(
        'For bias the maximum absolute error is ' + str(
            (grad_b_abs_diff).max()), "\n")

    print('For weights (slow grads) the maximum absolute error is ' +
          str((grad_W_abs_diff_slow).max()))
    print(
        'For bias (slow grads) the maximum absolute error is ' + str(
            (grad_b_abs_diff_slow).max()), "\n")

    # Relative error between numerically and analytically computed gradient
    grad_W_abs_sum = np.maximum(
        np.abs(grad_W_numerical) + np.abs(grad_W_analytical), 0.00000001)
    grad_b_abs_sum = np.maximum(
        np.abs(grad_b_numerical) + np.abs(grad_b_analytical), 0.00000001)

    print('For weights the maximum relative error is ' +
          str((grad_W_abs_diff / grad_W_abs_sum).max()))
    print('For bias the maximum relative error is ' +
          str((grad_b_abs_diff / grad_b_abs_sum).max()))

    grad_W_abs_sum_slow = np.maximum(
        np.abs(grad_W_numerical_slow) + np.abs(grad_W_analytical), 0.00000001)
    grad_b_abs_sum_slow = np.maximum(
        np.abs(grad_b_numerical_slow) + np.abs(grad_b_analytical), 0.00000001)

    print('For weights (slow grad) the maximum relative error is ' +
          str((grad_W_abs_diff_slow / grad_W_abs_sum_slow).max()))
    print('For bias (slow grad) the maximum relative error is ' +
          str((grad_b_abs_diff_slow / grad_b_abs_sum_slow).max()))

def miniBatchGD(X_trainn, Y_trainn, y_trainn, W_star, b_star, X_validation,
                Y_validation, y_validation, GDparams, lmbda):
    #need x_train- X_test, X_validation and Y_validation as inputs...
    # take out params from dictionary
    eta = GDparams['eta']
    n_batch = GDparams['n_batch']
    n_epochs = GDparams['n_epochs']
    N = X_trainn.shape[1]  # Number of data images
    d = X_trainn.shape[0]

    #Dictionary for the results of the trained network
    nn_dict = {
        'epochs': [],
        'train_loss': [],
        'train_accuracy': [],
        'validation_loss': [],
        'validation_acuracy': []
    }
    for epoch in range(n_epochs):
        np.random.seed(epoch)
        # permutation of indicies
        shuffled_indexes = np.random.permutation(N)
        for j in range(N // n_batch):
            #differently than in Matlab...
            j_start = j * n_batch
            j_end = (j + 1) * n_batch

            # batch of shuffled indicies
            X_batch = X_trainn[:, shuffled_indexes[j_start:j_end]]
            Y_batch = Y_trainn[:, shuffled_indexes[j_start:j_end]]
            grad_W, grad_b = ComputeGradients(X_batch, Y_batch, W_star, b_star,
                                              lmbda)
            W_star -= eta * grad_W
            b_star -= eta * grad_b
        nn_dict['epochs'].append(epoch + 1)
        #print("Accuracy shape: ", ComputeAccuracy(X, y, W_star, b_star))
        nn_dict['train_accuracy'].append(
            ComputeAccuracy(X_trainn, y_trainn, W_star, b_star))

        nn_dict['train_loss'].append(
            ComputeCost(X_trainn, Y_trainn, W_star, b_star, lmbda))

        nn_dict['validation_acuracy'].append(
            ComputeAccuracy(X_validation, y_validation, W_star, b_star))

        nn_dict['validation_loss'].append(
            ComputeCost(X_validation, Y_validation, W_star, b_star, lmbda))

        print("Epoch " + str(epoch + 1) + ", train loss: " +
              str(nn_dict['train_loss'][-1]) + ", train accuracy=" +
              str(nn_dict['train_accuracy'][-1]) + "\r")

    return W_star, b_star, nn_dict

def montage(W, label_names, GDparams):
    """ Display the image for each label in W """
    eta = GDparams['eta']
    n_batch = GDparams['n_batch']
    n_epochs = GDparams['n_epochs']

    fig, ax = plt.subplots(1, 10, figsize=(15, 2.5))
    plt.suptitle("Weights for n_batch= " + str(GDparams['n_batch']) +
                 ", eta = " + str(GDparams['eta']) + "and labda = " +
                 str(lambda_))
    for i in range(10):
        im = W[i, :].reshape(32, 32, 3, order='F')

        sim = (im - np.min(im[:])) / (np.max(im[:]) - np.min(im[:]))
        sim = sim.transpose(1, 0, 2)

        ax[i].imshow(sim, interpolation='nearest')
        ax[i].set_title(label_names[i])
        ax[i].axis('off')
    plt.show()

def plot_learning_curve(nn_dictionary):
    """ Function for plotting the accuracy and loss for the training/validation data over epoches"""
    fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(12, 6))

    epochs = nn_dictionary['epochs']
    train_loss = nn_dictionary['train_loss']
    train_accuracy = nn_dictionary['train_accuracy']

    validation_acuracy = nn_dictionary['validation_acuracy']
    validation_loss = nn_dictionary['validation_loss']

    ax[0].plot(epochs, train_loss, label="Train loss")
    ax[0].plot(epochs, validation_loss, label="Validation loss")

    ax[0].legend()
    ax[0].set(xlabel='Epoch', ylabel='Loss (cross entropy)')
    ax[0].grid()

    ax[1].plot(epochs, validation_acuracy, label="validation_acuracy")
    ax[1].plot(epochs, train_accuracy, label="train_accuracy")
    ax[1].legend()
    ax[1].set(xlabel='Epoch', ylabel='Accuracy')
    ax[1].grid()
    plt.show()

input_dimension = X_train.shape[0]
output_dimension = Y_train.shape[0]
W, b = init_weights(input_dimension, output_dimension)

#For numerical gradients checks
# test on the entire image nr 100,
#X = X_train[:, [100]]
#Y = Y_train[:, [100]]

# test on the 50 first inputs on one image (nr 100)
#X = X_train[0:50, [100]]
#Y = Y_train[0:50, [100]]
#W = W[:, 0:50]
#b = b[:, 0:50]

#X = X_train
#Y = Y_train
#y = y_train

X_v = X_val
Y_v = Y_val
y_v = y_val
lambda_ = 1

#test_gradients_num(X, Y, W, b, lambda_)
#exit()
#lambda_ = 0
GDparams = {'n_batch': 100, 'eta': 0.001, 'n_epochs': 40}
W_new, b_new, nn_dict = miniBatchGD(X_train, Y_train, y_train, W, b, X_v, Y_v,
                                    y_v, GDparams, lambda_)

c = ComputeCost(X_test, Y_test, W_new, b_new, lambda_)
#ComputeCost(X, Y, W, b, lmbda):
accc = ComputeAccuracy(X_test, y_test, W_new, b_new)

print("Accuracy on test set is :", accc)
print("Cost on test set is :", c)

montage(W_new, label_names, GDparams)  #vizualize the trained weights
plot_learning_curve(nn_dict)


from numbers import Integral
from pylops import LinearOperator

class FunctionOperator(LinearOperator):
    r"""Function Operator.

    Simple wrapper to functions for forward `f` and adjoint `fc`
    multiplication.

    Functions :math:`f` and :math:`fc` are such that
    :math:`f:\mathbb{F}^m \to \mathbb{F}^n` and
    :math:`fc:\mathbb{F}^n \to \mathbb{F}^m` where :math:`\mathbb{F}` is
    the appropriate underlying type (e.g., :math:`\mathbb{R}` for real or
    :math:`\mathbb{C}` for complex)

    FunctionOperator can be called in the following ways:
    ``FunctionOperator(f, n)``, ``FunctionOperator(f, n, m)``,
    ``FunctionOperator(f, fc, n)``, and ``FunctionOperator(f, fc, n, m)``.

    The first two methods can only be used for forward modelling and
    will return `NotImplementedError` if the adjoint is called.
    The first and third method assume the matrix (or matrices) to be square.
    All methods can be called with the `dtype` keyword argument.

    Parameters
    ----------
    f : :obj:`callable`
        Function for forward multiplication.
    fc : :obj:`callable`, optional
        Function for adjoint multiplication.
    n : :obj:`int`, optional
        Number of rows (length of data vector).
    m : :obj:`int`, optional
        Number of columns (length of model vector).
    dtype : :obj:`str`, optional
        Type of elements in input array.

    Attributes
    ----------
    shape : :obj:`tuple`
        Operator shape :math:`[n \times m]`
    explicit : :obj:`bool`
        Operator contains a matrix that can be solved explicitly (``True``) or
        not (``False``)

    Examples
    --------
    >>> from pylops.basicoperators import FunctionOperator
    >>> def forward(v):
    ...     return np.array([2*v[0], 3*v[1]])
    ...
    >>> A = FunctionOperator(forward, 2)
    >>> A
    <2x2 FunctionOperator with dtype=float64>
    >>> A.matvec(np.ones(2))
    array([2.,  3.])
    >>> A @ np.ones(2)
    array([2.,  3.])
    """
    def __init__(self, f, *args, **kwargs):
        try:
            self.dtype = kwargs['dtype']
        except KeyError:
            self.dtype = 'float64'
        self.explicit = False

        super().__init__()

        self.f = f

        # call is FunctionOperator(f, n)
        if len(args) == 1:
            self.shape = (args[0], args[0])
            self.fc = None
        elif len(args) == 2:
            # call is FunctionOperator(f, n, m)
            if isinstance(args[0], Integral):
                self.shape = (args[0], args[1])
                self.fc = None
            # call is FunctionOperator(f, fc, n)
            else:
                self.fc = args[0]
                self.shape = (args[1], args[1])
        # call is FunctionOperator(f, fc, n, m)
        elif len(args) == 3:
            self.fc = args[0]
            self.shape = args[1:3]

    def _matvec(self, x):
        return self.f(x)

    def _rmatvec(self, x):
        if self.fc is None:
            raise NotImplementedError("Adjoint not implemented")
        else:
            return self.fc(x)


import cv2
import urllib.request
import numpy as np

#classifiers
face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')  #for detecting faces in the image
eyes = cv2.CascadeClassifier('haarcascade_eye.xml')

# get the image link from the user
image_url = input("Please enter the image URL: ")

try:
    # download the image from the URL
    resp = urllib.request.urlopen(image_url)
    # reads image data and converts into NumPy array of unsigned 8-bit ints
    img_array = np.asarray(bytearray(resp.read()), dtype=np.uint8)
    img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)

    #convert image to grayscale
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # run face classifier with scale factor 1.1 and minimum number of neighbour rectangles 4
    classify = face.detectMultiScale(gray_img, 1.1, 4)

    # create rectangles of model from bounding box
    for (x,y, w, h) in classify:
        #draws rectangle around detected face
        cv2.rectangle(img, (x,y), (x+w, y+h), (255, 255, 0), 2)
        roi_gray = gray_img[y:y+h, x:x+w]
        roi_colour = img[y:y+h, x:x+w]
        # runs eye detection classifier on grayscale region of interest
        eyes_create = eyes.detectMultiScale(roi_gray)
        for (xe, ye, we, he) in eyes_create:
            #create bounding box on eyes
            cv2.rectangle(roi_colour, (xe, ye), (xe+we, ye+he), (0, 127, 255), 2)

    #display image
    cv2.imshow('img', img)
    cv2.waitKey()

except Exception as e:
    print("Error occurred: ", e)