E05 - Nétiquette⚓︎
Le problème
Proposition 1⚓︎
def retour_ligne(nb_caracteres,caracteres):
i=0
retour_car=''
car_test=''
while i<nb_caracteres:
car_test = caracteres[i:81+i]
if len(car_test)>80:
x = car_test.rfind(' ')
retour_car = retour_car + car_test[0:x] + '\n'
i=i+x+1
else:
retour_car=retour_car+car_test
i=nb_caracteres+1
return retour_car
nb_c=int(input())
car=input()
print(retour_ligne(nb_c,car))
import doctest
doctest.testmod()
- utiliser
rfind
c'est un peu tricher... (beaucoup) - La fonction est bien trop obscure !!!
Proposition 2⚓︎
def arrangement(nb_caractères: int, texte: str, compte: int)-> None:
""" Écrit au fur à mesure, le texte en sautant une ligne
tout les 80 caractères sans couper les mots en deux.
>>> 217
>>> Prologin est le concours national d'informatique. Prologin selectionne egalement l'equipe de France pour les Olympiades Internationales d'Informatique, evenement qui reunit 80 pays dans un lieu different chaque annee.
>>> arrangement(nb_caractères, texte)
Prologin est le concours national d'informatique. Prologin selectionne egalement
l'equipe de France pour les Olympiades Internationales d'Informatique, evenement
qui reunit 80 pays dans un lieu different chaque annee.
"""
for mot in texte:
compte += len(mot)
if compte >= 80:
print()
compte = 0
else:
print(" ",end="")
print(mot, end="")
# Test (C'est en commentaire car il ne passe pas les test :\)
# import doctest
# doctest.testmod()
# Entrée
nb_caractères = int(input())
texte = list(input().split(" "))
# Sortie
compte = 0
arrangement(nb_caractères, texte, compte)
-
C'est la longueur des mots avec espace qui doit être inférieur à 80, toi tu as oublié de compter les espaces.
-
On peut réparer ta fonction avec
compte = 0
for mot in texte:
if compte == 0:
# on débute la première ligne
print(mot, end="")
compte = len(mot)
elif compte + 1 + len(mot) <= 80:
print(" ", mot, sep="", end="")
compte += 1 + len(mot)
else:
print()
print(mot, end="")
compte = len(mot)
Ça reste peu pratique.
Proposition 3⚓︎
def Netiquette(string, longueur):
"""
Prend en paramètre une chaine de caractère, et la transforme de sorte à
ce qu'elle respecte la Netiquette (80 chr par ligne)
Ou en tout cas, ça essaye. Ca râte misérablement, car je ne sais pas comment vérifier sur chaque mot.
Ca respecte la Netiquette, mais ne respecte pas les espaces.
>>> Netiquette(Prologin est le concours national d'informatique. Prologin selectionne egalement l'equipe de France pour les Olympiades Internationales d'Informatique, evenement qui reunit 80 pays dans un lieu different chaque annee.)
'Prologin est le concours national d'informatique. Prologin selectionne egalement
l'equipe de France pour les Olympiades Internationales d'Informatique, evenement
qui reunit 80 pays dans un lieu different chaque annee.'
"""
nouvelle_string = ""
for i, lettre in enumerate(string):
if i % 80 == 0:
nouvelle_string += '\n'
nouvelle_string += string[i]
return nouvelle_string[1:]
#input
_ = int(input())
texte = input()
#output
print(Netiquette(texte, _))
- Tu n'utilises pas le second paramètre ; ne l'inclus donc pas dans les paramètres !
- Ton code est incorrect, il coupe les mots. On veut que les mots ne soient pas coupés, il faut couper aux espaces... Ceux juste avant de dépasser la ligne de 80...
- C'est une très mauvaise pratique d'accumuler des lettres dans une chaine de caractères. On préfère accumuler dans une liste (ou une file), puis faire un collage
"".join(...)
Proposition 4⚓︎
def Nétiquette(chaine: str, long_chaine: int) -> str:
"""
Affiche une chaine avec la norme "Nétiquette" qui consiste a ce que les ligne de dépasse pas 80 caractères.
>>> Nétiquette("Prologin est le concours national d'informatique. Prologin selectionne egalement l'equipe", 90)
Prologin est le concours national d'informatique. Prologin selectionne egalement
l'equipe
"""
compteur = 80
while compteur <= long_chaine:
if chaine[compteur] == " ":
print(chaine[:compteur])
chaine = chaine[compteur + 1:]
compteur = 80
long_chaine = len(chaine) - 1
else:
compteur -= 1
print(chaine)
# Test
import doctest
doctest.testmod()
# Entrée
long_chaine = int(input())
chaine = input()
# Sortie
Nétiquette(chaine, long_chaine)
- Méthode intéressante, mais elle pourrait échouer à cause de
long_chaine = len(chaine) - 1
; le-1
étant faux dans de rares cas.
Proposition 5⚓︎
def netiquette(texte: str) -> str:
"""
Renvoie une chaine de caractere dont certains espaces ont été remplacé par
des sauts de ligne ('\n') de telle sorte qu'aucune ligne ne dépasse 80
colonnes.
"""
if len(texte) <= 80:
return texte
else:
i_cesure = 80
while texte[i_cesure] != " ":
i_cesure -= 1
return texte[:i_cesure] + '\n' + netiquette(texte[i_cesure + 1:])
import doctest
doctest.testmod()
nb_caracteres = int(input())
texte = input()
print(netiquette(texte))
-
Presque parfait.
-
Tu pouvais juste ajouter un paramètre par défaut sur la largeur de césure, et donner un doctest complet qui fait moins de 80 de large.
- Pour le doctest, c'est légal de faire :
"""
>>> texte = "Un exemple court."
>>> print(netiquette(texte), 15)
Un exemple
court.
"""
Cela t'évite d'écrire des \n
dans la docstring.
Corrigé du professeur⚓︎
On remarque qu'une version récursive est bien plus simple à écrire et à comprendre qu'une version itérative. Mais, quand c'est presque aussi facile à écrire et comprendre, on préfère les versions itératives.
"""
author: Franck CHAMBON
problem: https://prologin.org/train/2004/semifinal/netiquette
"""
def netiquette(texte: str, largeur=80) -> str:
"""Renvoie le texte formaté sur plusieurs lignes,
avec une largeur maximale définie, 80 par défaut.
>>> print(netiquette("123 12 1", largeur=4))
123
12 1
"""
l_texte = len(texte)
if l_texte <= largeur:
return texte
else:
# On cherche l'indice de la première espace à gauche de largeur.
i = largeur
while texte[i] != ' ':
i -= 1
return texte[:i] + "\n" + netiquette(texte[i+1:], largeur)
# Tests
import doctest
doctest.testmod()
# Entrée
longueur = int(input())
texte = input()
assert longueur == len(texte)
# Sortie
print(netiquette(texte))
doctest facile
Il est utile ici de choisir un paramètre supplémentaire, la longueur maximale autorisée. Cela permet de pouvoir ajouter un doctest de taille raisonnable.
On peut utiliser print
dans le doctest !
pré-condition
Quand on rentre dans la boucle while
, au maximum i = largeur
et texte[i]
ne provoque pas d'erreur, en effet, juste avant on vient de tester et on est dans le cas largeur < l_texte
.
D'autre part, i
ne peut pas devenir nul, il y aurait un mot trop long.