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