Amaia
Amaia

Reputation: 19

SOLVED: My Python code returns None instead of a list

the value which is supposed to be returned is valid!!!! The print(self.affichage) just above shows that it works!!!! Why does it not return it ??? (the very last return)

so this code is a Polish Reverse Notation calculus : you read it from left to right, the numbers are stored in a pile, and the operands apply to the two upper numbers of the pile (the two most recent)

# here comes the actual code :


class Calculatrice():

    # création de la mémoire de la calculatrice
    def __init__(self):
        self.pile = []
        self.affichage = []

    def traitement(self,element):
        # opérateur
        if element in "+-*/":

            # on vérifie qu'il y a les nombres suffisants pour effectuer ces opérations
            if len(self.pile) > 1:

                # addition
                if element == "+":
                    resultat = self.pile[-2] + self.pile[-1]

                # soustraction
                elif element == "-":
                    resultat = self.pile[-2] - self.pile[-1]

                # multiplication
                elif element == "*":
                    resultat = self.pile[-2] * self.pile[-1]

                # division
                elif element == "/":
                    resultat = self.pile[-2] / self.pile[-1]

                # ATTENTION : dans les cas de ces opérations, seuls deux nombres sont nécessaire,
                # donc on peut généraliser les deux actions suivantes, mais ça ne devrait pas forcément être le cas.

                # on dépile les nombres traités
                del self.pile[len(self.pile)-2:]
                # on empile le résultat
                self.pile.append(resultat)

                return True

            elif len(self.pile) == 1:
                if element == "*":
                    # erreur : pas assez de nombres pour effectuer une multiplication
                    print("Erreur 03 : Pas assez de nombres pour effectuer la multiplication.")

                    return False

                elif element == "/":
                    # erreur : pas assez de nombres pour effectuer une division
                    print("Erreur 04 : Pas assez de nombres pour effectuer la division.")

                    return False

                # si c'est une addition, on considère qu'on ajoute le nombre à 0, donc la pile ne change pas
                else:
                    # si c'est une soustraction, on empile son opposé à la place du nombre
                    if element == "-":
                        self.pile[-1] = (self.pile[-1] * (-1))

                    return True

            # la taille de la pile = 0, c-à-d. qu'aucun nombre n'a été stocké au préalable
            else:
                print("Erreur 02 : Pas assez de nombres pour effectuer une opération.")

                return False

        else:
            for car in element:
                if car not in "0123456789.":
                    # erreur : caractère non reconnu
                    print("Erreur 01 : La commande n'a pas été comprise.")

                    return False

            # si on est arrivé jusqu'ici, on va considérer que c'est bon et que c'est un nombre

            # on empile l'élément
            self.pile.append(float(element))

            return True




    def npi(self,chaine):

        # si la récurrence n'est pas à sa limite
        if len(chaine) != 0:

            # on vérifie qu'il y a des espaces
            if " " in chaine:

                # on parcourt la chaine jusqu'à l'espace suivant
                i = 0
                temp = ""
                while chaine[i] != " ":
                    temp = temp+chaine[i]
                    i += 1

                # on a fini d'extraire cet élément : on le traite.
                traitement = self.traitement(temp)
                # si il y a eu des erreurs de traitement : on arrête tout.
                if traitement == False:
                    return ["Erreur"]

                else:
                    # on continue de traiter le reste de la chaîne
                    self.npi(chaine[i+1:])

            else:
                # il n'y a pas d'espace, donc il n'y a qu'un seul élément : on le traite.
                traitement = self.traitement(chaine)
                # si il y a eu des erreurs de traitement : on arrête tout.
                if traitement == False:
                    return ["Erreur"]

                # on a fini, on sort du if
                self.npi("")

        else:
            # la chaîne est vide : tous les éléments ont été traités. On renvoie le résultat final et on réinitialise la pile.
            self.affichage = self.pile.pop()
            print(self.affichage)
            return self.affichage

c = Calculatrice()

print(c.npi("2 3 + 4 -"))
# doit retourner 1

Upvotes: 0

Views: 276

Answers (2)

Code Pope
Code Pope

Reputation: 5459

You call npi recursively. In the last call the traitement variable is True. But your code looks like the following:

if traitement == False:
    return ["Erreur"]

else:
    # on continue de traiter le reste de la chaîne
    self.npi(chaine[i+1:])

and exits the function without returning anything. Therefore, you get the None object, when trying to print.

Upvotes: 0

rdas
rdas

Reputation: 21285

You are returning a value only in the base-case. For the recursive cases in npi you are not returning anything (i.e. returning None). The printed value comes from inside a recursive call, the return value from that call is lost once you go back to the calling method.

You need to add return statements for the recursive cases in npi

    def npi(self,chaine):

        # si la récurrence n'est pas à sa limite
        if len(chaine) != 0:

            # on vérifie qu'il y a des espaces
            if " " in chaine:

                # on parcourt la chaine jusqu'à l'espace suivant
                i = 0
                temp = ""
                while chaine[i] != " ":
                    temp = temp+chaine[i]
                    i += 1

                # on a fini d'extraire cet élément : on le traite.
                traitement = self.traitement(temp)
                # si il y a eu des erreurs de traitement : on arrête tout.
                if traitement == False:
                    return ["Erreur"]

                else:
                    # on continue de traiter le reste de la chaîne
                    return self.npi(chaine[i+1:])   # HERE

            else:
                # il n'y a pas d'espace, donc il n'y a qu'un seul élément : on le traite.
                traitement = self.traitement(chaine)
                # si il y a eu des erreurs de traitement : on arrête tout.
                if traitement == False:
                    return ["Erreur"]

                # on a fini, on sort du if
                return self.npi("")    # HERE

        else:
            # la chaîne est vide : tous les éléments ont été traités. On renvoie le résultat final et on réinitialise la pile.
            self.affichage = self.pile.pop()
            print(self.affichage)
            return self.affichage

Upvotes: 2

Related Questions