le sujet¶
un palindrome est un mot qui se lit dans les deux sens, par exemple non, radar ou kayak
on vous demande d’écrire un programme palindrom.py
v0: lorsqu’on le lance avec
python palindrom.pyle programme commence par vous demander d’entrer un mot
puis il vous indique si oui ou non c’est un palindrome, et s’arrêtev1: cette fois le programme continue cette logique jusqu’à ce qu’on entre le mot
exitqui signifie qu’on veut s’arrêter
solutions¶
v0: on traite un seul mot¶
pour voir la v0
"""
un programme qui demande un mot et dit si c'est un palindrome
"""
def is_palindrom(word):
# c'est plus robuste de projeter le mot en minuscule
word = word.lower()
# on tire simplement profit du slicing
return word == word[::-1]
def main():
mot = input("entrez le mot: ")
# maintenant je dois afficher le résultat
# ---- on pourrait faire ceci
# if is_palindrom(mot):
# print("oui")
# else:
# print("non")
# ---- en Python on fait plutôt comme ceci
# d'abord je décompose pour qu'on comprenne bien
# message = "oui" if is_palindrom(mot) else "non"
# print(message)
# ---- ce qui fait qu'à la fin comme je n'ai pas vraiment
# besoin de la variable message, j'écris juste ceci
print("oui" if is_palindrom(mot) else "non")
if __name__ == '__main__':
main()
v1: jusqu’à ce qu’on tape le mot “exit”¶
la v1
"""
boucle sans fin jusqu'à ce qu'on entre le mot 'exit'
"""
def is_palindrom(word):
return word.lower() == word.lower()[::-1]
def main():
while True:
mot = input("entrez le mot: ")
if mot == 'exit':
print("bye")
# ici on a le choix: break ou return
# ---- break
# je suis dans une boucle, mais qu'il n'y a rien
# à faire après le while, donc si je fais
# break
# je vais effectivement sortir de la boucle, et de la fonction
# ---- return
# mais le plus simple, comme je suis dans une fonction
# c'est de faire tout simplement
return
print("oui" if is_palindrom(mot) else "non")
if __name__ == '__main__':
main()
pour aller plus loin¶
bien sûr vous pouvez sophistiquer comme vous le sentez; par exemple
traiter des phrases complètes (enlever la ponctuation)
accepter les équivalences comme
é==e
la ponctuation¶
si vous vouliez ignorer la ponctuation, la librairie standard vient avec ceci:
import string
print(string.punctuation)mais c’est souvent insuffisant notamment avec le texte en français - par exemple pour les choses comme «
et pour traiter ces caractères-là vous allez faire plutôt (merci chatgpt :)
import unicodedata
def unicode_punctuation():
# U+0000 to U+10FFFF is the full Unicode range
return {
chr(i) for i in range(sys.maxunicode)
if unicodedata.category(chr(i)).startswith('P')
}les accents¶
de même, si vous voulez admettre que, par exempleEt la marine va venir à Malte (Victor Hugo)
est un palindrome, il va vous falloir “projeter” les caractères accentués (ici le à, mais aussi ç) sur les non-accentués (a, c, resp.)
et pour faire ça de nouveau, unicodedata vient à notre secours
import unicodedata
text = "cet été"
normalized = unicodedata.normalize('NKFD', text)
print(text)
-> affiche 'cet ete'voici ma version avec ces deux ajouts
"""
une version plus réaliste qui traite les accents et la ponctuation français
ça nous emmène un peu loin pour des débutants évidemment, mais si intérêt...
"""
import sys
import unicodedata
def to_ascii(text):
"""
Normalize the Unicode string to decompose combined letters and diacritics
"""
normalized = unicodedata.normalize('NFKD', text)
# Encode to ASCII bytes, ignoring characters that can't be encoded (like emojis)
ascii_bytes = normalized.encode('ASCII', 'ignore')
# Convert back to string
return ascii_bytes.decode('ASCII')
# on utilise les métadonnées de chaque caractère Unicode
# pour calculer la liste des caractères de ponctuation
def unicode_punctuation():
"""
returns a set with ALL the punctuation characters (there are 842 !)
"""
def qualifies(c):
category = unicodedata.category(c)
return (
# P stands for punctuation
category.startswith('P')
# These ones are spaces
or category == 'Zs')
return {
chr(i) for i in range(sys.maxunicode)
if qualifies(chr(i))
}
# on le range dans une variable, pas besoin de recalculer ça tout le temps
PUNCTUATION = unicode_punctuation()
def is_palindrom(word):
# on le met en minuscules
word = word.lower()
# on enlève la ponctuation
for sign in PUNCTUATION:
word = word.replace(sign, '')
# on remplace les accents par un équivalent
word = to_ascii(word)
return word.lower() == word.lower()[::-1]
def main():
while True:
mot = input("entrez le mot: ")
if mot == 'exit':
print("bye")
# ici on a le choix: break ou return
# ---- break
# je suis dans une boucle, mais qu'il n'y a rien
# à faire après le while, donc si je fais
# break
# je vais effectivement sortir de la boucle, et de la fonction
# ---- return
# mais le plus simple, comme je suis dans une fonction
# c'est de faire tout simplement
return
print("oui" if is_palindrom(mot) else "non")
if __name__ == '__main__':
main()