healthier/models.py
def replace(food_item, status=None):
        """
        Takes foo_item:<foo_item object> and status:<STR> returns a Tuple(True or False, <Queryset> or None)
        the tuple is True when "healthier"* replacements food_item are found having as much as possible identical
        categories as food_item.categories.

        *"healthier" means in this case :
            - if status=None, the food items returned will have both better (inferior) nutri-score and Nova-grade
            - is stauts=nutry-only, the food items returnes will have only a better (inferior) nutri-score.

        Due to the variable number and order of foo_item.categories the function gets the food_items present
        in DB in a <Queryset> for each category converts it into set() and use intersect() two times in a row
        to find food_items that have the most categories in common with food_item.
        """
        # increase to have the results matching more food_item categories (not <1)
        CATEGORY_MATCHING_PRECISION = 1
        categories = list(food_item.categories.all())
        # search every item that have better nutri-score and novagrade through all food_item categories
        # or only nutri_score
        # if result in the queryset strores it in  query[] as a frozenset
        if status == None:
            replacements = {
                Food_item.objects.filter(
                    categories__name=category,
                    nutri_score_fr__lt=food_item.nutri_score_fr,
                    nova_grade__lt=food_item.nova_grade,
                ).order_by(
                    "nutri_score_fr", "nova_grade",
                )
                for category in categories
            }
        elif status == "nutri-only":
            replacements = {
                Food_item.objects.filter(
                    categories__name=category,
                    nutri_score_fr__lt=food_item.nutri_score_fr,
                ).order_by("nutri_score_fr", "nova_grade")
                for category in categories
            }
        query = []
        {
            query.append(frozenset(list(replacement)))
            for replacement in replacements
            if replacement.exists()
        }
        cat_number = len(query)
        if cat_number == 1:
            # not enough categories to give a good result (may be a generic category... )
            return (False, None)
        elif cat_number > 1:
            for cat in range(cat_number):
                sets_list = []
                i = cat_number-1
                # first loop : intersection of set 1 with all of the query
                if cat == 0:
                    while i >= 0:
                        {sets_list.append(query[x]) for x in range(i+1) if x!=cat}
                        intersect = query[cat].intersection(*sets_list)
                        if len(intersect)> 0 and i >= CATEGORY_MATCHING_PRECISION:
                            return (True, intersect)
                        i -= 1
                # next loops : several sets intersections have already been checked / no need to compare all sets again.
                # check only query[cat] intersection with all sets of query that have index < cat-1
                # if cat 2 : only one new possibility to check, for cat 3 : 2 new ...)
                elif cat > 1:
                    while i>=0:
                        {sets_list.append(query[x]) for x in range(i+1) if x!=cat and x<cat-1}
                        intersect = query[cat].intersection(*sets_list)
                        if len(intersect)> 0 and i >= CATEGORY_MATCHING_PRECISION:
                            return (True, intersect)
                        i-=1
            return (False, None)
        else :
            return (False, None)

        Takes foo_item:<foo_item object> and status:<STR> returns a Tuple(True or False, <Queryset> or None)
        the tuple is True when "healthier"* replacements food_item are found having as much as possible identical
        categories as food_item.categories.

        *"healthier" means in this case :
            - if status=None, the food items returned will have both better (inferior) nutri-score and Nova-grade
            - is stauts=nutry-only, the food items returnes will have only a better (inferior) nutri-score.

        Due to the variable number and order of foo_item.categories the function gets the food_items present
        in DB in a <Queryset> for each category converts it into set() and use intersect() two times in a row
        to find food_items that have the most categories in common with food_item.
        
Takes foo_item: and status: returns a Tuple(True or False,  or None)
the tuple is True when "healthier"* replacements food_item are found having as much as possible identical
categories as food_item.categories.

"healthier" means in this case :
if status=None, the food items returned will have both better (inferior) nutri-score and Nova-grade
is stauts=nutry-only, the food items returnes will have only a better (inferior) nutri-score.

Due to the variable number and order of foo_item.categories the function gets the food_items present
in DB in a  for each category converts it into set() and use intersect() two times in a row
to find food_items that have the most categories in common with food_item.
Takes foo_item : and status : returns a Tuple ( True or False or None ) the tuple is True when " healthier " * replacements food_item are found having as much as possible identical categories as food_item . categories . " healthier " means in this case : if status = None the food items returned will have both better ( inferior ) nutri - score and Nova - grade is stauts = nutry - only the food items returnes will have only a better ( inferior ) nutri - score . Due to the variable number and order of foo_item . categories the function gets the food_items present in DB in a for each category converts it into set () and use intersect () two times in a row to find food_items that have the most categories in common with food_item .
def replace(food_item, status=None):
        CATEGORY_MATCHING_PRECISION = 1
        categories = list(food_item.categories.all())
        if status == None:
            replacements = {
                Food_item.objects.filter(
                    categories__name=category,
                    nutri_score_fr__lt=food_item.nutri_score_fr,
                    nova_grade__lt=food_item.nova_grade,
                ).order_by(
                    "nutri_score_fr", "nova_grade",
                )
                for category in categories
            }
        elif status == "nutri-only":
            replacements = {
                Food_item.objects.filter(
                    categories__name=category,
                    nutri_score_fr__lt=food_item.nutri_score_fr,
                ).order_by("nutri_score_fr", "nova_grade")
                for category in categories
            }
        query = []
        {
            query.append(frozenset(list(replacement)))
            for replacement in replacements
            if replacement.exists()
        }
        cat_number = len(query)
        if cat_number == 1:
            return (False, None)
        elif cat_number > 1:
            for cat in range(cat_number):
                sets_list = []
                i = cat_number-1
                if cat == 0:
                    while i >= 0:
                        {sets_list.append(query[x]) for x in range(i+1) if x!=cat}
                        intersect = query[cat].intersection(*sets_list)
                        if len(intersect)> 0 and i >= CATEGORY_MATCHING_PRECISION:
                            return (True, intersect)
                        i -= 1
                elif cat > 1:
                    while i>=0:
                        {sets_list.append(query[x]) for x in range(i+1) if x!=cat and x<cat-1}
                        intersect = query[cat].intersection(*sets_list)
                        if len(intersect)> 0 and i >= CATEGORY_MATCHING_PRECISION:
                            return (True, intersect)
                        i-=1
            return (False, None)
        else :
            return (False, None)
def replace ( food_item , status = None ) : CATEGORY_MATCHING_PRECISION = 1 categories = list ( food_item . categories . all ( ) ) if status == None : replacements = { Food_item . objects . filter ( categories__name = category , nutri_score_fr__lt = food_item . nutri_score_fr , nova_grade__lt = food_item . nova_grade , ) . order_by ( "nutri_score_fr" , "nova_grade" , ) for category in categories } elif status == "nutri-only" : replacements = { Food_item . objects . filter ( categories__name = category , nutri_score_fr__lt = food_item . nutri_score_fr , ) . order_by ( "nutri_score_fr" , "nova_grade" ) for category in categories } query = [ ] { query . append ( frozenset ( list ( replacement ) ) ) for replacement in replacements if replacement . exists ( ) } cat_number = len ( query ) if cat_number == 1 : return ( False , None ) elif cat_number > 1 : for cat in range ( cat_number ) : sets_list = [ ] i = cat_number - 1 if cat == 0 : while i >= 0 : { sets_list . append ( query [ x ] ) for x in range ( i + 1 ) if x != cat } intersect = query [ cat ] . intersection ( * sets_list ) if len ( intersect ) > 0 and i >= CATEGORY_MATCHING_PRECISION : return ( True , intersect ) i -= 1 elif cat > 1 : while i >= 0 : { sets_list . append ( query [ x ] ) for x in range ( i + 1 ) if x != cat and x < cat - 1 } intersect = query [ cat ] . intersection ( * sets_list ) if len ( intersect ) > 0 and i >= CATEGORY_MATCHING_PRECISION : return ( True , intersect ) i -= 1 return ( False , None ) else : return ( False , None )
Takes foo_item:<foo_item object> and status:<STR> returns a Tuple(True or False, <Queryset> or None)
the tuple is True when "healthier"* replacements food_item are found having as much as possible identical
categories as food_item.categories.
Takes foo_item : <foo_item object > and status : <STR > returns a Tuple ( True or False <Queryset > or None ) the tuple is True when " healthier " * replacements food_item are found having as much as possible identical categories as food_item . categories .
"""
        Takes foo_item:<foo_item object> and status:<STR> returns a Tuple(True or False, <Queryset> or None)
        the tuple is True when "healthier"* replacements food_item are found having as much as possible identical
        categories as food_item.categories.

        *"healthier" means in this case :
            - if status=None, the food items returned will have both better (inferior) nutri-score and Nova-grade
            - is stauts=nutry-only, the food items returnes will have only a better (inferior) nutri-score.

        Due to the variable number and order of foo_item.categories the function gets the food_items present
        in DB in a <Queryset> for each category converts it into set() and use intersect() two times in a row
        to find food_items that have the most categories in common with food_item.
        """ # increase to have the results matching more food_item categories (not <1) # search every item that have better nutri-score and novagrade through all food_item categories # or only nutri_score # if result in the queryset strores it in  query[] as a frozenset # not enough categories to give a good result (may be a generic category... ) # first loop : intersection of set 1 with all of the query # next loops : several sets intersections have already been checked / no need to compare all sets again. # check only query[cat] intersection with all sets of query that have index < cat-1 # if cat 2 : only one new possibility to check, for cat 3 : 2 new ...)
food_item
status