IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Pause sur une fonction


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 23
    Points : 15
    Points
    15
    Par défaut Pause sur une fonction
    Bonjour,

    J'ai un petit soucis que je n'arrive pas à régler :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Machin:
             self.attribut1 = 0
             self.total = 0
    ....
             def methode1(self)
                       self.methode2()
                       self.total = self.total + self.attribut1
            def methode2(self)
                      mon_nombre = input('taper un chiffre')
                      self.attribut1 = mon_nombre
    .....
    Je voudrais que ma méthode1 attende que je rentre la valeur à l'attribut1 avant de continuer.

    Comment faire ? (mon exemple est juste pour illustrer ce que je recherche)

    Merci beaucoup

  2. #2
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Soit tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Machin:
        def __init__(self):
            self.attribut1 = 0
            self.total = 0
    et attribut1 et total sont des variables d’instance.


    Soit tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Truc:
        attribut1 = 0
        total = 0
    et attribut1 et total sont des variables de classe.


    Ce qui est bien aussi, c’est de dire quel est le souci.


    souci au singulier ne prend pas de s à la fin

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Ce qui est bien aussi, c’est de dire quel est le souci.
    Quand je demande de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.total = self.total + self.attribut1
    Je voudrais que l'input de methode2 soit pris en compte.
    Et dans mon cas print self.total est égal à 0

    Merci

  4. #4
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Ah c'est mieux avec une question

    Ça va ça ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Machin:
     
        def __init__(self,x = 0):
            self.attribut1 = 0
            self.total = 0
     
        def methode1(self,x=0):
            if x == 9:
                self.attribut1 = input('taper un chiffre : ')
                self.total = self.total + self.attribut1
                print self.total

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Ah c'est mieux avec une question
    oui
    Citation Envoyé par eyquem Voir le message
    Ça va ça ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Machin:
     
        def __init__(self,x = 0):
            self.attribut1 = 0
            self.total = 0
     
        def methode1(self,x=0):
            if x == 9:
                self.attribut1 = input('taper un chiffre : ')
                self.total = self.total + self.attribut1
                print self.total
    Ma methode1 fait appel à methode2, qui se charge de l'input. Par contre, c'est methode1 qui met à jour self.total. Voilà ce que je voudrais, si c'est possible.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    105
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2007
    Messages : 105
    Points : 145
    Points
    145
    Par défaut
    Bonjour,

    Excuse moi, mais que vaut x quand tu appel ta méthode "methode1" après avoir instancié ton objet ?

    Car si il ne vaut pas 9, tu ne fais pas appel à ta deuxième méthode !

    Salutations.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par aepli Voir le message
    Bonjour,

    Excuse moi, mais que vaut x quand tu appel ta méthode "methode1" après avoir instancié ton objet ?

    Car si il ne vaut pas 9, tu ne fais pas appel à ta deuxième méthode !

    Salutations.
    Sur mon exemple rien. J'ai oublié de l'enlever
    Je corrige ça, merci

  8. #8
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Avec des variables de classe ou avec des variables d’instances, les résultats sont identiques, alors je groupe les codes par deux dans les présentations des résultats suivantes.




    Les 2 codes suivants font ce que tu veux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Machin:
        attribut1 = 0
        total = 0
        def methode1(self):
            self.methode2()
            self.total = self.total + self.attribut1
        def methode2(self):
            mon_nombre = input('taper un chiffre ')
            self.attribut1 = mon_nombre
    
    a = Machin()
    print a.attribut1, '   ',a.total,'\n-------'
    a.methode1()
    print a.attribut1, '   ',a.total
    a.methode1()
    print a.attribut1, '   ',a.total
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Machin:
        def __init__(self):
            self.attribut1 = 0
            self.total = 0
        def methode1(self):
            self.methode2()
            self.total = self.total + self.attribut1
        def methode2(self):
            mon_nombre = input('taper un chiffre ')
            self.attribut1 = mon_nombre
    
    a = Machin()
    print a.attribut1, '   ',a.total,'\n-------'
    a.methode1()
    print a.attribut1, '   ',a.total
    a.methode1()
    print a.attribut1, '   ',a.total
    0 0
    -------
    taper un chiffre 13
    13 13
    taper un chiffre 5
    5 18




    Les 2 codes que voici ne font pas ce qu’on attend
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Machin:
        attribut1 = 0
        total = 0
    
        def methode1(self):
            self.methode2()
            self.total = self.total + self.attribut1
        def methode2(self):
            mon_nombre = input('taper un chiffre ')
            attribut1 = mon_nombre # au lieu de self.attribut1 = mon_nombre
    
    a = Machin()
    print a.attribut1, '   ',a.total,'\n-------'
    a.methode1()
    print a.attribut1, '   ',a.total
    a.methode1()
    print a.attribut1, '   ',a.total
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    class Machin:
        def __init__(self):
            self.attribut1 = 0
            self.total = 0
        def methode1(self):
            self.methode2()
            self.total = self.total + self.attribut1
        def methode2(self):
            mon_nombre = input('taper un chiffre ')
            attribut1 = mon_nombre # au lieu de self.attribut1 = mon_nombre
    
    a = Machin()
    print a.attribut1, '   ',a.total,'\n-------'
    a.methode1()
    print a.attribut1, '   ',a.total
    a.methode1()
    print a.attribut1, '   ',a.total
    0 0
    -------
    taper un chiffre 134
    0 0
    taper un chiffre 3
    0 0

    C’est explicable:
    attribut1 = mon_nombre crée une variable locale attribut1 dans la fonction methode2(), mais la variable self.attribut1 n’en est pas affectée puisque les changements impliquant des variables locales ne se répercutent pas à l’extérieur de la fonction.

    Dans self.total = self.total + self.attribut1, le programme prend donc les valeurs de self.total et self.attribut1, qui ont été mises à 0 à l’initialisation et calcule la nouvelle valeur de self.total, c’est à dire la tête à Toto.





    Les deux codes suivants plantent carrément.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Machin:
        attribut1 = 0
        total = 0
        def methode1(self):
            self.methode2()
            self.total = self.total + attribut1 # au lieu de self.attribut1
        def methode2(self):
            mon_nombre = input('taper un chiffre ')
            attribut1 = mon_nombre # au lieu de self.attribut1 = mon_nombre
    
    a = Machin()
    print a.attribut1, '   ',a.total,'\n-------'
    a.methode1()
    print a.attribut1, '   ',a.total
    a.methode1()
    print a.attribut1, '   ',a.total
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class Machin:
        def __init__(self):
            self.attribut1 = 0
            self.total = 0
        def methode1(self):
            self.methode2()
            self.total = self.total + attribut1# au lieu de self.attribut1
    
        def methode2(self):
            mon_nombre = input('taper un chiffre ')
            attribut1 = mon_nombre # au lieu de self.attribut1 = mon_nombre
    
    a = Machin()
    print a.attribut1, '   ',a.total,'\n-------'
    a.methode1()
    print a.attribut1, '   ',a.total
    a.methode1()
    print a.attribut1, '   ',a.total
    0 0
    -------
    taper un chiffre 145
    Traceback (most recent call last):
    File "E:\Python\Essais Python\zzz debian 6.py", line 14, in <module>
    a.methode1()
    File "E:\Python\Essais Python\zzz debian 6.py", line 7, in methode1
    self.total = self.total + attribut1
    NameError: global name 'attribut1' is not defined
    Cela ne change rien si on remet self.attribut1 = mon_nombre dans methode2() comme dans les deux premiers codes.


    Quelqu’un sait il dire pourquoi ?
    C'est ma nouvelle devinette.
    Il faut demander à NaB.
    .

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    105
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : Suisse

    Informations forums :
    Inscription : Septembre 2007
    Messages : 105
    Points : 145
    Points
    145
    Par défaut
    Bonjour,

    Je ne suis pas très bien réveillé ce matin, mais pour ton énigme il me semble que la réponse est dans la question ....
    NameError: global name 'attribut1' is not defined
    En tout cas pour ton deuxième code ...

    Salutations.

  10. #10
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Voilà ce que j'ai compris de ce type de sujet:

    Un attribut de classe (comme attribut1 et total dans l'exemple qui suit) doit être préfixé avec le nom de la classe, que ce soit dans une méthode ou à l'extérieur de la classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    class Machin:
        attribut1 = 0
        total = 0
     
        def methode1(self):
            self.methode2()
            Machin.total = Machin.total + Machin.attribut1
        def methode2(self):
            mon_nombre = input('taper un chiffre ')
            Machin.attribut1 = mon_nombre # au lieu de self.attribut1 = mon_nombre
     
    a = Machin()
    print Machin.attribut1, '   ',Machin.total,'\n-------'
    a.methode1()
    print Machin.attribut1, '   ',Machin.total
    a.methode1()
    print Machin.attribut1, '   ',Machin.total
    D'une manière générale, ce n'est pas une bonne pratique d'appeler, à l'extérieur de la classe, un attribut de classe en la préfixant par une variable d'instance de classe (comme a.attribut1 dans l'exemple ci-dessus):

    -> Cela peut marcher en lecture, à condition qu'il n'y ait pas un attribut d'instance de classe de même nom (donc prefixé par self lors de sa création à l'intérieur d'une méthode).

    -> Mais c'est dangereux en affectation, car on créé (s'il n'existe pas déjà) un attribut d'instance de classe qui va masquer l'attribut de classe. Par exemple, si dans le code ci-dessus, j'ajoute à la fin a.total=999, l'attribut de classe Machin.total ne changera pas. Par contre, j'aurai créé un nouvel attribut d'instance de classe a.total.


    En ce qui concerne les variables non-préfixées à l'intérieur d'une méthode:

    - si on lui affecte une valeur, elle est créée de ce fait à l'intérieur de cette méthode, mais détruite à la fin de son exécution.

    - si on veut la lire sans l'avoir créée avant dans la méthode, Python cherche dans les variables globales, mais pas dans les attributs de classe.

    J'ai bon?

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  11. #11
    Membre éclairé
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Points : 751
    Points
    751
    Par défaut
    Bonjour,
    Citation Envoyé par tyrtamos Voir le message
    D'une manière générale, ce n'est pas une bonne pratique d'appeler, à l'extérieur de la classe, un attribut de classe en la préfixant par une variable d'instance de classe (comme a.attribut1 dans l'exemple ci-dessus):
    Comment y accèdes-tu dans ces cas là ? En faisant Machin.attribut1 ?
    Ce point à toujours été un peu obscur pour moi venant de Java. Pour moi Machin.attribut1 est un accès statique (Si on le modifie, on modifie la valeur de attribut1 pour l'ensemble des instances de Machin), tandis que si l'on fait a.attribut1 = "un truc" on modifie l'attribut seulement pour l'instance de classe (getter/setter Java). En gros, pour moi, tous les attributs sont publics en Python, ce qui est bien pour la lisibilité du code, mais bizarre pour un programmeur venant de Java.
    Merci de m'éclairer sur ce point...

  12. #12
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Ha, tu viens du Java... là est la confusion je crois.
    Petite comparaison:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Java:
    class Machin {
        private String name; // variable d'instance
        private static int count; // Variable de classe
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # Python:
    class Machin:
        count = 0 # Variable de classe
     
        def __init__(self):
            self.name = "bidule" # Variable d'instance
    Concernant la visibilité (public/protected/default/private), il n'y a rien auquel tu ne puisses vraiment pas accéder, mais...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Visible: # Les classes sont publiques
        def __init__(self):
            self.name # public
            self._name # on s'accorde à dire que c'est protected
            self.__name # sera nommé en fait _Visible__name, considéré privé
            # Il n'y a pas de convention, à ma connaissance, pour la visibilité par défaut

  13. #13
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    C'est simple: un attribut de classe appartient à la classe et contient donc une même valeur pour toutes les instances de cette classe. Elle est définie
    - sans préfixe au même niveau que les méthodes de cette classe (même indentation que les "def"). Exemple: l'attribut "total"
    - ou à l'intérieur des méthodes, à condition de le préfixer par le nom de la classe. Exemple ici: Machin.truc="toto" qui est créé à l'intérieur de la méthode "methode1".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Machin:
        total = 0
     
        def methode1(self):
            Machin.total = 999
            Machin.truc="toto"
     
    a = Machin()
    a.methode1()
    print Machin.total
    999
    Comme je l'ai dit, on y accède à l'intérieur des méthodes de cette classe en le préfixant par le nom de la classe, et non par self. Au sein d'une méthode, "self" définit en fait l'appartenance à la future instance de classe.

    Dans le code ci-dessus, je peux essayer de lire Machin.Total en appelant a.total, et ça marche parce qu'il n'y a pas de "self.total" dans la classe. Mais si je fais a.total=111, je crée un nouvel attribut d'instance de classe "à la volée" qui vaudra 111. Après cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    a.total=111
    print a.total
    111
    print Machin.total
    999
     
    Machin.total=888
    print Machin.total
    888
    print a.total
    111
    Dès qu'on crée un attribut d'instance de classe, il masque l'attribut de classe si on veut le préfixer avec la variable d'instance (ici a).

    La seule façon de modifier et de charger la valeur de l'attribut de classe "total" (ici 999), c'est de le préfixer avec le nom de la classe (Machin), et ce sera la même valeur pour toutes les instance de classe: c'est le but principal des attributs de classe!!!

    Ok?

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 23
    Points : 15
    Points
    15
    Par défaut
    Merci énormément pour vos explications
    Ça me fait avancer dans mon apprentissage python, des personnes comme vous.

  15. #15
    Membre éclairé
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Points : 751
    Points
    751
    Par défaut
    Tout d'abord merci de vos réponse
    Citation Envoyé par Antoine_935 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # Python:
    class Machin:
        count = 0 # Variable de classe
     
        def __init__(self):
            self.name = "bidule" # Variable d'instance
    Concernant la visibilité (public/protected/default/private), il n'y a rien auquel tu ne puisses vraiment pas accéder, mais...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Visible: # Les classes sont publiques
        def __init__(self):
            self.name # public
            self._name # on s'accorde à dire que c'est protected
            self.__name # sera nommé en fait _Visible__name, considéré privé
            # Il n'y a pas de convention, à ma connaissance, pour la visibilité par défaut
    Je pense que cette convention de nommage serait à mettre dans la FAQ, pour les gens comme moi . Ainsi que la précision sur variable d'instance et de classe.

    Citation Envoyé par tyrtamos Voir le message
    Comme je l'ai dit, on y accède à l'intérieur des méthodes de cette classe en le préfixant par le nom de la classe, et non par self. Au sein d'une méthode, "self" définit en fait l'appartenance à la future instance de classe.
    C'est ce que je voulais dire dans mon précédent post. J'avais bien compris le fonctionnement, mais j'avais pas compris que tu faisais allusion à ce problème.

    Citation Envoyé par tyrtamos Voir le message
    Ok?
    Yes sir,
    Merci encore et désolé d3bian pour le détournement de ton sujet

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Besoin d'aide sur une fonction
    Par PrinceMaster77 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 30/08/2005, 17h40
  2. Probleme sur une fonction vérif
    Par PrinceMaster77 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/10/2004, 13h25
  3. Probleme de pointeur sur une fonction
    Par nicky78 dans le forum C
    Réponses: 2
    Dernier message: 23/05/2004, 20h26
  4. Erreur sur une fonction avec des paramètres
    Par Elois dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 05/05/2004, 21h00
  5. PerlDoc sur une fonction d'un module
    Par lesouriciergris dans le forum Modules
    Réponses: 2
    Dernier message: 13/03/2003, 20h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo