Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Fonctions] Fait semblant de modifer ma variable...

Mais c'est écrit noir sur blanc!!! ><

Sujet résolu
    9 novembre 2011 à 23:42:03

    Bonsoir,

    Dans un petit programme que j'essaie de mettre au point, j'ai voulu créer une fonction semblable à input, mais qui se plaignerait si l'utilisateur n'entre pas un entier et le ferais alors recommencer:
    # -*-coding:Latin-1 -*
    import os
    
    def intput():
    		entrance=False;
    		while entrance==False:
    			try: #On vérifie que la valeur entrée est bien un nombre.
    					entrance=float(input());
    					#Python ne réagit pas quand on entre un zéro
    					#J'ai du créer ce if pour éviter que le logiciel ne reste coincé:
    					#Je ne sais pa ssi le remède est le if ou le break
    					#Mais là n'est pas le problème dont je parle.
    					if entrance==0:
    						entrance=int(0);
    						break;
    			except:#La valeur n'est pas un nombre
    				print("Entrée incorrecte");
    				entrance=False;
    				continue;
    			if entrance%1!=0: #La valeur est un float
    				print("Valeur incorrecte: nombre à virgule");
    				entrance=False;
    				continue;
    			else:#Si la valeur entrée est utilisable:
    				#On fait passer son type de float à int
    				entrance=int(entrance);
    				print("");
    intput();
    print(entrance);
    				
    os.system("pause")
    


    Lorsque je test mon bout de code, j'essaie de rentrer un chaîne:
    "Entrée incorrecte", le programme me fait recommencer;
    j'entre un float:
    "Valeur incorrecte, chiffre à virgule, le programme me fait recommencer;

    Jusque là, tout va bien, j'entre alors un entier: 5
    le programme arrive à la ligne ou je lui demande de m'afficher ce que j'ai entré:
    "NameError: name 'entrance' is not defined" => o_Owtf?!?
    Pourtant si je suit le programme, entrance aurait du prendre tour-à-tour les valeurs False, float(5) et int(5), je l'ai défini trois fois, entrance.

    J'essaie de placer "entrance=False;" à l'extèrieur du bloc "def intput():"
    À la fin, le programme m'annonce que entrance est toujours égal à False.
    (Et la boucle while, t'en fait quoi? -_-)

    J'essaie de remplacer "def intput():" par un simple "if True:". (Pour ne pas avoir à refaire les tabulations)
    La, le programme fonctionne exactement comme il le devrait, entrance vaut bien cinq à la sortie de la boucle.
    J'en conclue que mon code est correct, et que tout viens du "def intput():"

    => Ma réaction première fut de penser que les fonctions via "def" ne peuvent pas mofifier ou créer de variables.
    Mon regard se pose sur une autre fonction que j'ai créée, qui modifie le contenu de plusieurs dictionnaires à la fois, et qui fonctionne au poil.

    Qu'est-ce qui se passe? T-T
    Ce sont des lignes de codes que je vais souvent utiliser, et j'aimerais vraiment réussir à les compresser en une seule ligne...

    Merci d'avance.

    Edit: Je n'en suis qu'à la page dictionnaire du tutoriel Python
    • Partager sur Facebook
    • Partager sur Twitter
    Y s'taient cachés les steaks hachés.
      10 novembre 2011 à 1:15:56

      ta fonction ne retourne rien et entance n'est pas déclaré dans le __main__:

      def intput():
          bla bla bla
          return entrance
      
      entrance = intput()
      print(entrance)
      
      • Partager sur Facebook
      • Partager sur Twitter

      Python c'est bon, mangez-en. 

        10 novembre 2011 à 16:39:04

        Cette solution je l'avais déjà envisagée un peu plus tôt. ( print(intput(); plus exactement)
        Je met quand même que ça m'a aidé parce que c'est exactement ce que j'ai pensé, et pour d'autres.

        Mais ce que j'aimerais, c'est comprendre pourquoi cette fonction ne peux pas modifier de variable, alors qu'une autre fonction quasiment identique le peut:
        C'est bien joli d'avoir une soluce, mais en programmation vaux mieux aussi avoir la cause du problème...
        def statedit(dic,key):
        		while dic[key]==False:
        			try: #On vérifie que la valeur entrée est bien un nombre.
        				dic[key]=float(input());
        				#Python ignore l'input quand on entre la valeur 0
        				#J'ai du créer ce if pour éviter que le logiciel ne reste coincé:
        				if dic[key]==0:
        					dic[key]=int(dic[key]);
        					break;
        			except:
        				print("Entrée incorrecte");
        				continue;
        			if dic[key]<0:#On vérifie que la valeur entrée est positive
        				dic[key]=False;
        				print("Valeur incorrecte: négative");
        				continue;
        			elif dic[key]>dic["max"]:#On vérifie que la valeur ne dépasse pas un certain seuil
        				#La valeur max étant incluse dans le dictionnaire
        				dic[key]=False;
        				print("Valeur incorrecte: trop élevée");
        				continue;
        			elif dic[key]%1!=0:
        				dic[key]=False;
        				print("Valeur incorrecte: nombre à virgule");
        				continue;
        			else:#Si la valeur entrée est utilisable:
        				dic[key]=int(dic[key]);
        				dic["max"]-=dic[key];#Opération spécifique au programme
        				print("");
        

        Je vous jure que cette fonction là fonctionne au poil. Et pourtant intput ne marche pas alors que je l'ai réalisé depuis un copié-collé de cette fonction
        Ou est la différence?

        Citation : josmiley

        ta fonction ne retourne rien


        Ma première fonction, statedit, ne retourne rien non plus, et pourtant les variables sont bien modifiées.

        Citation : josmiley

        entrance n'est pas déclaré dans le __main__:


        Je ne suis pas sur d'avoir bien compris, mais si tu veux dire que entrance doit être défini hors du bloc "def intput:", j'ai dit que j'avais déjà essayé, et que entrance conservais la valeur False après opération.
        Edit: Maintenant il me met UnboundLocalError: local variable 'entrance' referenced before assignement"
        Je crois comprendre ce que ça veux dire, mais je comprend pas pourquoi ça lui pose problème. -__-

        Et quand je défini entrance aux deux endroits, il conserve la valeur qu'il avait avant le bloc def intput.
        • Partager sur Facebook
        • Partager sur Twitter
        Y s'taient cachés les steaks hachés.
          10 novembre 2011 à 17:04:13

          Parce que dans un cas, tu passes les variables par référence à ta question et pas dans l'autre. Informe-toi sur la portée des variables et le passage des variables par référence.
          • Partager sur Facebook
          • Partager sur Twitter
            10 novembre 2011 à 18:39:27

            Ce fut fructueux mais ardu.
            Personnellement j'y réfléchirait à deux fois la prochaine fois que j'enverrais quelqu'un sur l'outil de recherche... -_-'

            Bon, après avoir cherché ici, ici et là, j'ai enfin saisit la notion des globales et des locales, et j'ai cru comprendre que faire passer une variable en paramètre permettait de l'utiliser comme une globale.

            J'ai réussi à faire fonctionner le code tel quel en rajoutant "global entrance" entre les lignes 4 et 5.
            J'ai tenté de l'inclure entre les lignes 5 et 6, donc après avoir défini entrance, et python m'a afficher un message bizzare, mais à continué à jouer le programme.
            Je suppose que c'est juste un mise en garde.

            Par contre, pour mon code statedit, si je n'ai pas eu à utiliser global, c'est parce que les dictionnaires sont forcément global ou parce que je l'ai rentré en paramètre?
            Au début j'aurais dit paramètre sans hésité, mais comme cette version du intput ne fonctionne pas mieux que l'originale, j'ai un gros doute:
            # -*-coding:Latin-1 -*
            import os
            entr=False
            def intput(entrance):
            		entrance=False
            		while entrance==False:
            			try: #On vérifie que la valeur entrée est bien un nombre.
            					entrance=float(input());
            					#Python ne réagit pas quand on entre un zéro
            					#J'ai du créer ce if pour éviter que le logiciel ne reste coincé:
            					#Je ne sais pa ssi le remède est le if ou le break
            					if entrance==0:
            						entrance=int(0);
            						break;
            			except:#La valeur n'est pas un nombre
            				print("Entrée incorrecte");
            				entrance=False;
            				continue;
            			if entrance%1!=0: #La valeur est un float
            				print("Valeur incorrecte: nombre à virgule");
            				entrance=False;
            				continue;
            			else:#Si la valeur entrée est utilisable:
            				#On fait passer son type de float à int
            				entrance=int(entrance);
            				print("");
            intput(entr);
            #Théoriquement, entr devrait subir les même opérations que entrance.
            print("Vous avez entré", entr);
            #Pas de bol: entr==False
            				
            os.system("pause")
            

            Sans cette interrogation, j'aurais fait passé le sujet en résolu.
            • Partager sur Facebook
            • Partager sur Twitter
            Y s'taient cachés les steaks hachés.
            Anonyme
              10 novembre 2011 à 22:16:16

              Encore une petite aide pour téclairer

              >>> def deux():
              	return 2
              
              >>> mon_deux = deux()
              >>> print(mon_deux)
              2
              >>> 
              >>> 
              >>> a = 5
              >>> def modif_a():
              	global a
              	a = 7
              
              	
              >>> modif_a()
              >>> a
              7
              
              • Partager sur Facebook
              • Partager sur Twitter
                11 novembre 2011 à 12:05:01

                Tout ça je l'ai déjà compris, tu me présente un cas ou modifie une variable avec return et un autre avec global.
                Maintenant ce que j'aimerais savoir c'est pourquoi dans ma fonction statedit, je n'ai eu besoin d'aucun de ces deux bout de code.
                • Partager sur Facebook
                • Partager sur Twitter
                Y s'taient cachés les steaks hachés.
                Anonyme
                  11 novembre 2011 à 12:39:07

                  Tu as vu les dictionnaires?

                  >>> def test(dico, key):
                  	dico[key] = 5
                  
                  	
                  >>> dict = {}
                  >>> test(dict, "a")
                  >>> dict
                  {'a': 5}
                  



                  Edit: Je te conseille fortement de lire ceci.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 novembre 2011 à 18:53:16

                    *sig* Deux pages plus loin de là ou j'en était. T-T
                    => Statedit modifie le dictionnaire à travers une méthode, non par affectation.
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Y s'taient cachés les steaks hachés.
                    Anonyme

                    [Fonctions] Fait semblant de modifer ma variable...

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown