Problème chaîne de caractère. [Résolu/Fermé]

Signaler
Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
-
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
-
Bonjour à tous, voilà dans un programme j'aimerai demander un chiffre à l'utilisateur petit problème: Il faut enfaîte que dans ce qu'il ai rentré je regarde si il y a un + ou un - et si il y en a un, j'aimerai que le + ou le - sois obligatoirement au début, et j'aimerai qu'il puisse n'en rentré que un des deux, et qu'il puisse n'en rentré que un.
En gros voila ce que j'aimerai:
input("Nombre à rentré:")
si l'utilisateur rentre -12156- et bien ça marque réessayer, si il tape 1-2 sa marque réessaye également, si il tape -32 et bien la boucle le "laisse passer".
Voilà en gros ce que j'aimerai. Je suppose qu'il faudra des méthodes, et bien j'aimerai juste que vous me l'ai donniez; sans me faire le code m'voyez? Juste pour que je fasse un peu tout seul :P Voilà merci à celui qui pourra m'aider :D



12 réponses

Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
3
SVP C'est pour un devoir :/
Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
3
SVP c'est pour demain
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Bonsoir

Python c'est facile

Premièrement, utilises-tu Python 2 ou 3 ?
Deuxièement, sais-tu écrire l'instruction pour obtenir l'entrée de données , càd la saisie par le programme de ce que l'utilisateur va entrer ?

Les deux questions sont liées: l'instruction diffère un peu entre Python 2 et Python 3
Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
3
J'utilise Python 3, et oui Python c'est facile dés que on en connait plus que moi ^^ Et pour ce qui est de votre dernière question j'ai pas compris ^^ Mais si c'est ce que j'ai compris oui je sais le faire c'est :
nom_variable=input("Chaîne de caractère")
Voilà merci. :)
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Voilà c'est ça. Bon maintenant mets cette instruction dans une boucle avec un print pour afficher chaque entrée
Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
3
Non mais enfaîte c'est fait tout ça j'aurai juste besoin de comment faire pour détecter si le + ou le - n'est répéter qu'une fois et il faut qu'il soit obligatoirement au début.
Voilà merci :)
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Il faut maintenat écrire une condition qui vérifie qu'il y a un signe + ou un signe - au tout début de la chaîne
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
quelles portions exactement tu ne comprends pas ?

Le all()

C'est une fonction qui prend une succession d'objets et qui regarde s'il sont tous True

Par exemple print( all( (True,True,True) ) ) affiche True


print( all( (True,1,True, 145) ) ) affiche True car Python considère ce qui n'est pas 0, [], () etc comme True

print( all( ('a' in 'jab',14,True,'de' in 'zdety') ) ) affiche True

etc


[c in "0123456789.-+" for c in saisie]
se lit:
liste de tous les booléens
c in chaîne "0123456789.-+"

pour tous les caractères c de la chaîne saisie pris l'un après l'autre

C'est ce qu'on appelle une list comprehension.
Mais entre parenthèses de all() , ce n'est pas la peine de mettre les crochets

Donc all( c in "0123456789.-+" for c in saisie)
passe en revue tous les caractères c de saisie et regarde la valeur de
 c in  "0123456789.-+"
et quand ça arrive au bout de la chaîne saisie, si tous les tests ont été True alors all(.....) renvoie True

NB: un booléen c'est simplement les objets True et False
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Je sens que le code suivant va mieux te convenir, ça doit être le all() qui ne te plait pas:

# -*- coding: cp1252 -*-

def saisie_decimal():
while True:
saisie=input("entrer un nombre décimal:")
diagnostic = True
for c in saisie:
if c not in "0123456789.-+":
diagnostic = False

if diagnostic:
return float(saisie)

nombre=saisie_decimal()
print(nombre)
> heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013

Et bien enfaite c'est mon professeur qui l'a fais ^^ et a vrai dire je suis totalement d'accord avec toi ne t'en fais pas j'ai eu la même réaction en voyant ça, mais bon ^^ enfin bref merci pour ton aide l'ami ;)
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Je ne comprends pas bien pourquoi tu mets une réponse en commentaire ici ni tout ce que tu écris. As tu vu mon dernier message d'hier soir tout en bas ? Je n'aurai rien à ajouter
J'espère que tu auras appris deux trois choses dans l'échange.
Salut
Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
3
Désoler mais je n'ai absolument pas compris à quoi sa faisait référence ^^ Ça répond a ce que j'ai demander ou c'est toute autre chose que tu es entrain de me montré ?
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Exécute le code pour voir ce qu'il fait
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Excuse moi, on peut enlever la ligne
# -*- coding: cp1252 -*- 
Elle ne sert q'en Python 2 quand il y a des accents dans le code
Mais les scripts en Python 3 étant codés en UTF-8, ils acceptent automatiquement les caractères accentués sans avoir besoin de cette ligne
Scuse, j'utilise Python 2. 7 de façon habituelle
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Bon, alors ?

Dans l'état actuel du code, quand on entre une saisie qui contient un autre caractère que l'un de ceux de la chaîne "0123456789.-+" ,
l'objet
diagnostic
, qui a la valeur
 True 
avant de commencer la boucle de tests
for c in "0123456789.-+"
,
prend la valeur
False
.
Et donc le
return 
n'est pas exécuté et ça repart pour un tour de la boucle while

Mais il n'y a pas que cette boucle de tests à faire, il faut vérifier d'autres conditions.
Et donc maintenat il faut ajouter ces conditions

Bon, alors ?
Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
3
Mais si j'ai bien compris ça reviens à faire exactement la même chose que mon programme de base ^^ Non ?
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Non pas exactement la même chose puisque mon code marche tandis que le tien ne marche pas.
Ca t'arrive de faire tourner un code pour voir ce qu'il fait ?

Il est vrai que je cherche à obtenir un code qui réalise l'objectif que tu veux atteindre. Donc il y a des similitudes. Mais le tien ne marche pas
J'obtiens ceci par exemple en entrant une mauvaise valeur:

entrer un nombre décimal:12A4
Traceback (most recent call last):
File "C:\Python32\a effacer.py", line 12, in <module>
nombre=saisie_decimal()
File "C:\Python32\a effacer.py", line 9, in saisie_decimal
return float(saisie)
ValueError: could not convert string to float: '12A4'
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
La différence entre mon code et le tien, c'est que dans ton code tu écris
saisie_correcte=False 

avant la boucle
 for c in saisie: 

et tu changes avec
saisie_correcte=True 
quand l'un des caractères n'est pas bon

tandis que dans mon code
diagnostic = True

avant la boucle
et change avec
diagnostic = False
si l'un des caractères n'est pas bon

Faut regarder les choses de près, pas de 3 mètres de haut
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Bon, ça se traine et je dois partir.
Voilà l'algorithme, il te reste à trouver comment écrire en Python les conditions qui sont en français:

def saisie_decimal():
while True:
saisie=input("entrer un nombre décimal:")
diagnostic = True
for c in saisie:
if c not in "0123456789.-+":
diagnostic = False
if premier caractère de saisie not in ('-','+'):
diagnostic = False
if (nombre de '-' est supérieur à 1) or \
(nombre de '+' est supérieur à 1):
diagnostic = False

if diagnostic:
return float(saisie)

nombre=saisie_decimal()
print(nombre)

bonsoir
Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
3
Bizarre parce que avec le miens lorsque je marque n'importe quoi (Des lettres + des chiffres, etc) et bien sa ne me fais pas l'erreur que tu rencontre je peux même te le prouver en te faisant un screen ! Donc avant de commencer à m'accabler de réflexions on ce calme!
heyquem
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
Scuse, je vois ce qu'il y a eu.
Comme un con je me suis gourré d'indentation
pour l'instruction
return float(saisie) 

Au lieu de la mettre en dehors de la boucle
while
, je l'ai mise dedans , comme dans mon code.

C'est parce que lorsque je copie le code que tu as donné plus haut, et que je le colle dans un script, j'ai toutes les instructions qui s'écrivent les unes à la suite des autres sur la même ligne, et j'ai été obligé de faire des retours à la ligne pour remettre ton code en bonne ordre.
Sauf que je me suis gourré pour l'instruction return

En plus comme j'ai Python 2 et Python 3 installés tous les deux mais que j'utilise Python 2 habituellement, il faut que je fasse un micmac pour bien ouvrir les codes en Python 3 et pas Python 2.

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

Donc effectivement dans ces conditions, ton code marche.
Mais il est aberrant de faire prendre à l'objet
saisie_correcte
la valeur
True
quand justement la saisie n'est pas correcte. Ca a ajouté à ma confusion.

En faisant comme je fais dans mon code il n'y a pas besoin d'initialiser un objet à
True
ou
False
avant la boucle
while
, le programme rentre directement dans la boucle while et en ressort dès que l'instruction
return float(saisie)
est exécutée, ce qui se produit si diagnostic reste
True
tout le long des tests.
La logique de mon code, c'est de commencer les tests avec la valeur
True
pour
diagnostic
et il faut que cette valeur tienne le coup au travers de tous les tests pour pouvoir passer à l'instruction
return
.

Tu peux garder ton algorithme si tui préfères mais il n'est pas très logique, il y a plus de mal à le comprendre que le mien, je trouve. Mais tu fais comme tu veux.
Par contre tu pourras demander à ton prof de comparer et de te dire celui qu'il estime préférable, je ne me fais pas trop de souci.
Messages postés
114
Date d'inscription
dimanche 3 juillet 2011
Statut
Membre
Dernière intervention
31 juillet 2014
3
Et bien merci beaucoup désoler de m'être emballé...
Merci beaucoup.
Messages postés
759
Date d'inscription
mercredi 17 juin 2009
Statut
Membre
Dernière intervention
29 décembre 2013
119
J'ai continué de penser au problème.

- Dans mon dernier post, j'ai écrit que ton code n'était pas très logique.
Ben si , il est logique, puisqu'il fonctionne bien. Point barre.

- J'ai écrit aussi qu'il y a plus de mal à le comprendre.
Ben non. J'aurais dû écrire: J'AI plus de mal à le comprendre. Tout simplement parce que j'étais habitué à envisager la solution sous l'angle de l'algorithme qui se trouve dans mon code. Mais ce n'est pas parce que je vois les choses avec ma subjectivité que c'est automatiquement la meilleure façon de faire.

- J'ai écrit aussi que tu devrais soumettre les deux codes pour comparaison à ton prof.
Mais c'est ce que j'ai fait moi même, pour voir s'il y avait vraiment des raisons déterminantes pour dire que c'est mon algorithme qui est le meilleur.
Ben y en a pas de déterminante.
Tu utilises un identifiant
saisie_correcte
qui est aberrant étant donné sa fonction. Mais ce n'est pas un point déterminant, on peut facilement changer cet identifiant pour un autre, par exemple c'est plus clair si on écrit ton code ainsi:

def saisie_decimal():
SAISIR=True
while SAISIR:
saisie=input("entrer un nombre décimal:")
SAISIR=False
for c in saisie:
if c not in "0123456789.-+":
SAISIR=True
return float(saisie)

Donc ce point n'étant pas déterminant, quels sont les autres ?

- Dans ton code, tu initialises
SAISIR
à False avant de faire les tests, moi j'initialise
diagnostic
à True. C'est pareil, ça fait une initialisation.
- Ensuite tu donnes la valeur booléenne inverse à
SAISIR
si les tests ne détectent pas une saisie correcte, je fais pareil pour
diagnostic
.
- Ensuite comment sort-on de la boucle while ?
Dans ton code c'est l'instruction
while
qui effectue un test sur
SAISIR
. Dans mon code je suis obligé de faire un test
if diagnostic
.
Dans les deux cas, il y a un if quelque part.
- Il y a juste que dans ton code tu es obligé d'initialiser la valeur de
SAISIR
avant la boucle while, moi pas. Mais ce n'est pas un point majeur.

Résultat: objectivement les deux code se valent.

Mais cet succession d'initialisation de valeur à True ou False, et de réaffectation de valeur False ou True ne me plaisait toujours pas.
Je me suis dit que ce qu'il faut faire, c'est que puisque l'instruction while implique un
if
caché, il faut mettre les tests dans ce
while
.
Donc j'ai trouvé le code suivant meilleur:

def saisir(x) :
for c in x:
if c not in "0123456789.-+":
return True
if x[0] not in '-+' \
or x.count('-')>1 \
or x.count('+')>1 :
return True

n = 'go'
while saisir(n):
n = input("entrer un nombre décimal:")


Mais en réfléchissant encore un peu, je me suis dit: si on vérifie en tout premier lieu que le premier caractère soit un
'-'
ou un
'+'
, alors le fait qu'il n'y ait pas d'autre '-' ou '+' dans la saisie nécessite qu'il n'y en ait pas dans les caractères au delà du premier. Il suffit de tester cette dernière condition pour éviter d'utiliser
count()
pour vérifier les nombres de '-' et de '+'.



def saisir(x) :
if x[0] not in '-+':
return True
for c in x[1:]:
if c not in "0123456789.":
return True

n = 'go'
while saisir(n):
n = input("entrer un nombre décimal:")

Mais si on appuie sur ENTER sans rien entrer on va avoir une erreur.
Donc il faut mettre
 if x
comme premier test (c'est équivalent à
if x!=''
).
Si en plus on utilise la fonction
any()
[c'est le contraire de la fonction
all() 
: elle renvoie False dès qu'elle trouve un élément équivalent à False dans la séquence qu'on lui passe en argument] alors on obtient:



def saisir(x) :
if not x \
or (x[0] not in '-+') \
or any(c not in "0123456789." for c in x[1:]):
return True

n = 'go'
while saisir(n):
n = input("entrer un nombre décimal:")

Enfin, comme j'estime inutile de tartiner les codes avec des fonctions qui ne se justifient pas, on peut tout aussi bien écrire tout simplement:

n = 'go'
while not n \
or (n[0] not in '-+') \
or any(c not in "0123456789." for c in n[1:]):
n = input("entrer un nombre décimal:")

print ('n==',n)

Simple Python, non ?

===========================

Tout ceci étant dit, la vraie façon de vérifier qu'une saisie est une nombre décimal, c'est de laisser l'interpréteur Python vérifier lui-même s'il parvient à interpréter une chaîne saisie comme un nombre décimal, et pour le cas où il n'y arrive pas, on met l'essai dans une clause
try...except
qui gère ça toute seule:

while True:
n = input('Entrez : ')
try:
n = float(n)
break
except:
pass

print('n==',n)

Note qu'avec cet algorithme, il n'est pas nécessaire de spécifier le signe + pour les nombres positifs entrés.