Bonjour Cedricphilibert,



L'ennui de ta solution du message #15 (voyelle dans un mot) , c'est que tu demandes beaucoup de travail à ton programme pour obtenir une information simple:

- tu obliges le programme à toujours parcourir la totalité du mot, alors que l'itération pourrait être stoppée quand une voyelle est rencontrée

- tu fais tenir le compte des voyelles rencontrées, et non seulement des voyelles mais aussi des consonnes: pour chaque lettre tu obliges le programme à exécuter une instruction d'addition, ce qui est un travail superflu car il n'y a pas d'intérêt à pouvoir aller au delà de la réponse 'y en a zéro ou y en a plus que zéro' en étant capable de répondre 'y en à pile 4'.


Il vaut mieux stopper l'itération dès qu'une voyelle est rencontrée ==> pour cela, il y a un mot clé intéressant: break.

Pour symboliser s'il y a une voyelle ou s'il n'y en a pas ==> il suffit d'une variable pouvant prendre deux valeurs correspondant aux deux cas: 1 = 'y en a au moins une' , 0 = 'y en a pas du tout'

On va appeler diag cette variable et on va parcourir le mot: à chaque consonne, diag prendra la valeur 0, et si on rencontre une voyelle, diag prend la valeur 0 et on sort de la boucle.

Traduction en code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
mot = 'radeau'
for caract in mot:
    if caract in 'aeiouy':
        diag = 1
        break
    else:
        diag = 0
 
if diag:  print "Il y a au moins une voyelle dans le mot"
else:  print "Il n'y a pas de voyelle dans le mot"




Ce qui est bien avec Python, c'est que le code est tellement clair qu'on peut facilement réfléchir en regardant un code.
En observant le code ci-dessus:


1)
Combien de fois diag prend elle la valeur 1 ? Une seule fois puisqu'on sort de la boucle juste après.
Combien de fois diag prend elle la valeur 0 ? Autant de fois qu'il y a de consonnes. Et c'est une répétition inutile puisque une affectation de 1 est susceptible de modifier cette valeur au tour suivant.

Eh bien justement: puisqu'en gros la boucle ne sert qu'à modifier la valeur de diag de 0 à 1 quand une voyelle est rencontrée, autant fixer diag à 0 avant de commencer la boucle:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
mot = 'radeau'
diag = 0
for caract in mot:
    if caract in 'aeiouy':
        diag = 1
        break
 
if diag:  print "Il y a au moins une voyelle dans le mot"
else:  print "Il n'y a pas de voyelle dans le mot"
Voilà qui est plus concis.



2)
En regardant le premier code:
- si caract in 'aeiouy' est True, diag prend la valeur 1.
- sinon, caract in 'aeiouy' est False, diag prend la valeur 0.

Or Python traite True et 1 comme identiques, et False et 0 de même.
On en sort une idée:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
mot = 'radeau'
for caract in mot:
    diag = caract in 'aeiouy'
    if diag:
        break
 
if diag:  print "Il y a au moins une voyelle dans le mot"
else:  print "Il n'y a pas de voyelle dans le mot"
On a encore éliminé une ligne.



3)
Il y a un autre mot clé qui a le même effet d'interruption immédiate de ce qui est en cours, c'est le mot return qui fait sortir d'une fonction.

Ceci doit faire penser à regarder ce qui se passe si on met l'algorithme sous forme de fonction.

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
mot = 'radeau'
 
def voy(le_mot):
    for caract in le_mot:
        diagnostic = caract in 'aeiouy'
        if diagnostic:
            return diagnostic
    return diagnostic
 
diag = voy(mot)
 
if diag:
    print "Il y a au moins une voyelle dans le mot"
else:
    print "Il n'y a pas de voyelle dans le mot"
Si diagnostic devient égal à 1 au cours de l'itération, le premier return est exécuté, le programme sort de la fonction et le second return n'est pas exécuté.

La différence essentielle avec les codes précédents, c'est qu'il y a ici un second return qui renvoie la valeur 0 puisque s'il est exécuté c'est que la boucle for a été passée sans que diagnostic prenne une autre valeur que 0.

Mais dès lors qu'on a deux renvois ==> on peut les mettre à profit pour renvoyer deux chaînes qui contiennent la même information que 0 ou 1:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
mot = 'radeau'
 
def voy(le_mot):
    for caract in le_mot:
        diagnostic = caract in 'aeiouy'
        if diagnostic:
            return "Il y a au moins une voyelle dans le mot"
    return "Il n'y a pas de voyelle dans le mot"
 
diag = voy(mot)   
print diag
Et tant qu'on y est, on va au plus direct:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
mot = 'radeau'
 
def voy(le_mot):
    for caract in le_mot:
        if caract in 'aeiouy':
            return "Il y a au moins une voyelle dans le mot"
    return "Il n'y a pas de voyelle dans le mot"
 
print voy(mot)




-----------------------------------------------------------

Mais tout ça est de la tambouille. Il faut prendre le réflexe de chercher les fonctions de Python qui font des actions plus abstraites correspondant à des besoins conceptuels généraux. En l'occurence

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
mot = 'radeau'
diag = any( caract in 'aeiouy' for caract in mot)
if any( caract in 'aeiouy' for caract in mot):
    print "Il y a au moins une voyelle dans le mot"
else:
    print "Il n'y a pas de voyelle dans le mot"
Il y a dans l'expression any( caract in 'aeiouy' for caract in mot) une fonction, any() , et une expression génératrice, g = ( caract in 'aeiouy' for caract in mot)

Si on ne reconnaît pas dans l'expression
any( caract in 'aeiouy' for caract in mot)
l'écriture canonique
any( (caract in 'aeiouy' for caract in mot) ) ,
c'est que Python permet la facilité de s'épargner deux parenthèses.

Une expression génératrice est un objet qui délivre des valeurs l'une après l'autre quand on lui demande, non seulement par une boucle for:
for x in g:
mais aussi par la méthode next()

Exemple:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
li = [12,23,6,10,35,98,8,243,86]
print 'for u in li: ',
for u in li:  print str(2*u),
 
g = (str(2*u) for u in li)
print '\nfor u in  g: ',
for u in g:
    while '6' in u:
        try:
            u = g.next()
        except:
            pass
    print u,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
for u in li:  24 46 12 20 70 196 16 486 172 
for u in  g:  24 12 20 70 172




any() est une fonction qui parcourt un itérable et qui renvoie la valeur True dès qu'elle rencontre une valeur True ou équivalente à True.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
any(([],(),[],0,False,[])) #renvoie False
any(([],(),[1,2],0,False,[])) # renvoie True


-----------------------

Je ne peux pas m'empêcher de signaler aussi la méthode suivante, très lisible,
pour signer la présence ou l'absence de voyelle dans un mot:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
mot = 'alhambra'
if set(mot).intersection('aeiouy'):
    print "Il y a au moins une voyelle dans le mot"
else:
    print "il n'y a pas de voyelle dans le mot"



-------------------------------------------------------

Ceci dit, comme l'a dit wiztricks, le plus important est sans doute de retenir qu'une chaîne est une sorte de liste;
mais qui n'est pas mutable, c'est à dire qu'on ne peut pas écrire

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
mot = 'tamis'
mot[2] = 'p'


Il existe une structure de données du type 'chaîne mutable' en Python:
ce type est celui des instances de la classe mmap.mmap mais celles-ci ne peuvent être créées qu'à partir d'un fichier, dont elles assurent une représentation fort efficiente car elles disposent à la fois des méthodes de fichier et des méthodes de chaînes.