Skip to content
Snippets Groups Projects
getter.py 8.06 KiB
from typing import Dict, List
from .request_db import send_query_to_db
from . import bp


def get_selected_elements(id_mandatory_labels: int, id_forbiden_labels: str, number_of_mandatory_labels: str) -> List[Dict[int, str]] :
    """
    Return a set of elements which wear mandatory labels and don't wear forbiden labels.
    :param id_mandatory_labels: str
    :param id_forbiden_labels: str
    :param number_of_mandatory_labels: int
    :return: List[Dict[int, str]]

    EXEMPLE
    -------
    >>> print(get_selected_elements("","",0)) # si aucun labels n'est interdit ou obligatoire
    [{'id': 4, 'element_name': 'peugeot, 2000'}, {'id': 3, 'element_name': 'renault, 2000'}, {'id': 2, 'element_name': 'renault, bleu, 2000'}, {'id': 1, 'element_name': 'renault, rouge, 2000'}]
    >>> print(get_selected_elements("1,2","5,9",2)) # si la voiture doit-être bleu
    [{'id': 4, 'element_name': 'peugeot, 2000'}]
    >>> print(get_selected_elements("5","",1))
    [{'id': 3, 'element_name': 'renault, 2000'}, {'id': 2, 'element_name': 'renault, bleu, 2000'}, {'id': 1, 'element_name': 'renault, rouge, 2000'}]
    >>> print(get_selected_elements("","5",0))
    [{'id': 4, 'element_name': 'peugeot, 2020'}]
    """
    #query slightly vary if number_of_mandatory_labels > 0 or not
    if(number_of_mandatory_labels):
        query = '''
                    SELECT 
                        ELEMENT.*
                    FROM 
                        ELEMENT 
                            INNER JOIN 
                        ELEMENT_LABEL 
                                ON ELEMENT.id=ELEMENT_LABEL.id_element 
                    WHERE 
                            id_label IN ({}) 
                        AND 
                            id_element NOT IN (
                                            SELECT 
                                                id_element 
                                            FROM 
                                                ELEMENT 
                                                    INNER JOIN 
                                                ELEMENT_LABEL 
                                                        ON ELEMENT.id=ELEMENT_LABEL.id_element
                                            WHERE 
                                                id_label IN ({})) 
                                            GROUP BY id_element 
                                            HAVING COUNT(*) = {} 
                                            Order BY element_name
        '''.format(id_mandatory_labels, id_forbiden_labels, number_of_mandatory_labels)
    else:
        query = '''
                    SELECT 
                        ELEMENT.*
                    FROM 
                        ELEMENT 
                            INNER JOIN 
                        ELEMENT_LABEL 
                                ON ELEMENT.id = ELEMENT_LABEL.id_element 
                    WHERE 
                        id_element NOT IN (
                                        SELECT 
                                            id_element 
                                        FROM 
                                            ELEMENT 
                                                INNER JOIN 
                                            ELEMENT_LABEL 
                                                    ON ELEMENT.id = ELEMENT_LABEL.id_element
                                        WHERE  id_label IN ({}) )
                    GROUP BY ELEMENT.id 
                    ORDER BY element_name ASC
        '''.format(id_forbiden_labels)

    selected_elements = send_query_to_db(query)
    return selected_elements

def get_discriminating_labels(selected_elements: List[Dict[int, str]]) -> List[Dict[int, str]] :
    """
        Return all labels associated to selected elements except non discrminating
        :param elements: list[Dict[str, str]]
        :return: list[Dict[int, str]]

        EXEMPLE
        -------
        >>> get_discriminating_labels([{"id":2,"name":"renault, bleu, 2000"}, {"id":1,"name":"renault, rouge, 2000"}])
        [{'id': 8, 'label_name': 'rouge'}, {'id': 9, 'label_name': 'bleu'}]
        >>> get_discriminating_labels([])
        []
    """
    id_selected_elements: str = get_ids(selected_elements)
    number_of_selected_elements = len(selected_elements)

    # select labels of selected elements and delete labels commun to all elements
    query = '''
                    SELECT 
                        LABEL.id
                        , label_name 
                    FROM 
                        ELEMENT 
                            INNER JOIN 
                        ELEMENT_LABEL 
                                ON ELEMENT.id=ELEMENT_LABEL.id_element 
                            INNER JOIN 
                        LABEL 
                                ON ELEMENT_LABEL.id_label=LABEL.id 
                    WHERE 
                        id_element IN ({}) 
                    GROUP BY id_label 
                    HAVING COUNT(*) < {}
        '''.format(id_selected_elements, number_of_selected_elements)

    discriminating_labels = send_query_to_db(query)
    return discriminating_labels

def get_high_discriminating_labels(discriminating_labels: List[Dict[int, str]]) -> List[Dict[int, str]] :
    """
        Return a set of new labels to continue your selection with it
        :param elements: list[Dict[str, str]]
        :return: list[Dict[int, str]]

        EXEMPLE
        -------
        >>> get_high_discriminating_labels([{"id":7, "name":"couleur"}, {"id":8, "name":"rouge"}, {"id":9, "name":"bleu"}])
        [{'id': 7, 'label_name': 'couleur'}]
    """
    id_discriminating_labels = get_ids(discriminating_labels)

    # delete all childrens of discriminating labels set
    query = '''
                    SELECT 
                        * 
                    FROM (
                            SELECT 
                                id, 
                                label_name
                            FROM 
                                LABEL 
                            WHERE 
                                LABEL.id IN({})
                        ) 
                    WHERE 
                        id NOT IN   (
                                    SELECT 
                                        B.id AS id_fils 
                                    FROM    (
                                            SELECT 
                                                * 
                                            FROM 
                                                LABEL 
                                            WHERE 
                                                id IN ({})
                                            ) AS A, 
                                        LABEL AS B 
                                    WHERE 
                                        A.id=B.father_id
                                    )
        '''.format(id_discriminating_labels, id_discriminating_labels)

    labels = send_query_to_db(query)
    return labels

def get_ids(objects: List[Dict[int, str]]) -> str :
    """
    Return all ids of the object's set
    :param objects: list[Dict[str, str]]
    :param attribut: str
    :return: str

    EXEMPLE
    -------
    >>> print(get_ids([{"id":1, "name":"a"},{"id":2, "name":"b"}]))
    1,2
    >>> print(get_ids([]))
    <BLANKLINE>
    """
    objects_ids = ""
    for object in objects:
        objects_ids +=  str(object["id"]) + ","
    #remove last extra comma
    return objects_ids[0:-1]

def get_user_selection(number_of_mandatory_labels: int, optional1: str, optional2: str) -> tuple :
    '''
    Return the right values of id_mandatory_labels and id_forbiden_labels when optional2 is missing.
    It is necessary because optional1 could be id_mandatory_labels or id_forbiden_labels.
    :param number_of_mandatory_labels: int
    :param optional1: str
    :param optional2: str
    :return:
    '''
    if int(number_of_mandatory_labels):
        id_mandatory_labels = optional1
        id_forbiden_labels = optional2
    else:
        id_mandatory_labels = optional2
        id_forbiden_labels = optional1
    return id_mandatory_labels, id_forbiden_labels