J'ai écrit un programme FizzBuzz piloté par des tests en utilisant la bibliothèque doctest standard.
http://docs.python.jp/2/library/doctest.html (Commencez à citer) Le module doctest recherche du texte qui ressemble à une session Python interactive, exécute le contenu de la session et voit s'il se comporte exactement comme il est écrit. doctest est souvent utilisé aux fins suivantes.
Vérifiez que le contenu de la docstring est à jour en vérifiant que tous les exemples d'exécution interactive dans la docstring (chaîne de documentation) du module fonctionnent comme écrit. Un test de régression est réalisé en vérifiant que les exemples d'exécution interactive dans le fichier de test ou l'objet de test fonctionnent comme prévu. Vous pouvez rédiger un document de didacticiel pour un package qui utilise de nombreux exemples d'entrée / sortie. Un document peut être un "test lisible" ou un "document exécutable", selon que vous vous concentrez sur des exemples d'entrée / sortie ou des commentaires. (Fin de la citation)
doctest semble être un excellent outil qui peut être utilisé pour les tests de régression lors de la vérification des documents (commentaires). Je n'ai pas d'autre choix que d'essayer ça.
http://www.atmarkit.co.jp/ait/articles/1403/05/news035.html (Commencez à citer (titre uniquement)) [1] Ecrire un code de test qui échoue [2] Écrivez le code à tester pour que le test passe de l'échec au succès [3] Ajoutez un code de test qui provoque l'échec du test [4] Écrivez le code à tester pour que le test passe de l'échec au succès [5] Refactoriser tout en maintenant le test réussi (Fin de la citation)
Cette fois, nous suivrons cette méthode.
J'ai décidé les spécifications de manière appropriée. Nom de la fonction: fizzbuzz (n) une fonction: Si la valeur d'entrée n est un multiple de 3, la chaîne 'Fizz' est renvoyée et Si la valeur d'entrée n est un multiple de 5, la chaîne "Buzz" est renvoyée et Si la valeur d'entrée n est un multiple de 15, la chaîne 'FizzBuzz' est renvoyée et Autre que cela, une fonction qui génère l'entier n.
n doit être un entier représenté par un type entier, un type entier long ou un type minoritaire à virgule flottante. (Pour le type minoritaire à virgule flottante, la partie fractionnaire doit être 0.) Si un petit nombre est entré, une exception InputError est renvoyée.
Tout d'abord, la mise en œuvre temporaire
def fizzbuzz(n):
'''
Si la valeur d'entrée n est un multiple de 3'Fizz'Renvoie la chaîne
Si la valeur d'entrée n est un multiple de 5'Buzz'Renvoie la chaîne
Si la valeur d'entrée n est un multiple de 15'FizzBuzz'Renvoie la chaîne
Autre que cela, une fonction qui génère l'entier n.
Exemple:
>>> fizzbuzz(3)
'Fizz'
n doit être un entier représenté par un type entier, un type entier long ou un type minoritaire à virgule flottante.
(Pour le type minoritaire à virgule flottante, la partie fractionnaire doit être 0.)
Si un petit nombre est entré, InputError est renvoyé.
'''
return 'Fizz'
if __name__ == '__main__':
import doctest
doctest.testmod()
Exécuter (-v est une option pour une sortie détaillée). Si vous n'ajoutez pas -v, les informations ne seront générées que lorsque le test échoue.
python fizzbuzz_doctest.py -v
Dans cet état, ok sort.
Essayez d'ajouter un cas de test
>>> fizzbuzz(5)
'Buzz'
L'erreur suivante est sortie.
File "fizzbuzz_doctest.py", line12, in __main__.fizzbuzz
Failed example:
fizzbuzz(5)
Expected:
'Buzz'
Got:
'Fizz'
1 items had no tests:
__main__
Modifiez comme suit.
if (n%3) == 0:
return 'Fizz'
elif (n%5) == 0:
return 'Buzz'
Répéter ce qui précède [1]
Répéter ce qui précède [2]
Les tests d'exception semblent nécessiter de commencer par Traceback. De plus, vous pouvez omettre la ligne médiane avec ....
>>> fizzbuzz(5.5)
Traceback (most recent call last):
...
ValueError: n must be integer. n: 5.500000
# coding: utf-8
def fizzbuzz(n):
'''
Si la valeur d'entrée n est un multiple de 3'Fizz'Renvoie la chaîne
Si la valeur d'entrée n est un multiple de 5'Buzz'Renvoie la chaîne
Si la valeur d'entrée n est un multiple de 15'FizzBuzz'Renvoie la chaîne
Autre que cela, une fonction qui génère l'entier n.
Exemple:
>>> fizzbuzz(3)
'Fizz'
>>> fizzbuzz(36)
'Fizz'
>>> fizzbuzz(5)
'Buzz'
>>> fizzbuzz(50)
'Buzz'
>>> fizzbuzz(15)
'FizzBuzz'
>>> fizzbuzz(45)
'FizzBuzz'
>>> fizzbuzz(2)
2
>>> fizzbuzz(49)
49
n doit être un entier représenté par un type entier, un type entier long ou un type minoritaire à virgule flottante.
(Pour le type minoritaire à virgule flottante, la partie fractionnaire doit être 0.)
Si un petit nombre est entré, ValueError est renvoyé.
>>> fizzbuzz(1.0)
1
>>> fizzbuzz(5.0)
'Buzz'
>>> fizzbuzz(5.5)
Traceback (most recent call last):
...
ValueError: n must be integer. n: 5.500000
'''
if n != int(n):
raise ValueError( 'n must be integer. n: %f' % n )
n = int(n)
if (n%15) == 0:
return 'FizzBuzz'
elif (n%3) == 0:
return 'Fizz'
elif (n%5) == 0:
return 'Buzz'
else:
return n
if __name__ == '__main__':
import doctest
doctest.testmod()
Il semble que le code final puisse être obtenu par refactoring tout en assurant le fonctionnement par des tests.
Par exemple, vous pouvez apporter les modifications suivantes: Afin de réduire le coût de référence de l'instruction if, créez une liste avec le reste divisé par 15 de 1 à 15 à l'avance, et déterminez la chaîne de caractères à renvoyer en vous référant à cette liste.
'''
if (n%15) == 0:
return 'FizzBuzz'
elif (n%3) == 0:
return 'Fizz'
elif (n%5) == 0:
return 'Buzz'
else:
return n
'''
fizzbuzz_list = []
for i in range(15):
if (i%15) == 0:
fizzbuzz_list.append('FizzBuzz')
elif (i%5) == 0:
fizzbuzz_list.append('Buzz')
elif (i%3) == 0:
fizzbuzz_list.append('Fizz')
else:
fizzbuzz_list.append(0)
r = int(n%15)
return fizzbuzz_list[r] if fizzbuzz_list[r] else n
Vous pouvez effectuer un test de régression avec la commande suivante sans écrire de nouveau test.
python fizzbuzz_doctest.py -v
Changeons encore l'algorithme.
'''
if (n%15) == 0:
return 'FizzBuzz'
elif (n%3) == 0:
return 'Fizz'
elif (n%5) == 0:
return 'Buzz'
else:
return n
fizzbuzz_list = []
for i in range(15):
if (i%15) == 0:
fizzbuzz_list.append('FizzBuzz')
elif (i%5) == 0:
fizzbuzz_list.append('Buzz')
elif (i%3) == 0:
fizzbuzz_list.append('Fizz')
else:
fizzbuzz_list.append(0)
'''
fizzbuzz_list = ['FizzBuzz', 0, 0, 'Fizz', 0, 'Buzz', 'Fizz', 0, 0, 'Fizz', 'Buzz', 0, 'Fizz', 0, 0 ]
r = n%15
return fizzbuzz_list[r] if fizzbuzz_list[r] else n
Vous pouvez exécuter le test de régression avec la commande suivante comme auparavant.
python fizzbuzz_doctest.py -v
Non seulement le code mais aussi la documentation sont complets.
# coding: utf-8
def fizzbuzz(n):
'''
Si la valeur d'entrée n est un multiple de 3'Fizz'Renvoie la chaîne
Si la valeur d'entrée n est un multiple de 5'Buzz'Renvoie la chaîne
Si la valeur d'entrée n est un multiple de 15'FizzBuzz'Renvoie la chaîne
Autre que cela, une fonction qui génère l'entier n.
Exemple:
>>> fizzbuzz(3)
'Fizz'
>>> fizzbuzz(36)
'Fizz'
>>> fizzbuzz(5)
'Buzz'
>>> fizzbuzz(50)
'Buzz'
>>> fizzbuzz(15)
'FizzBuzz'
>>> fizzbuzz(45)
'FizzBuzz'
>>> fizzbuzz(2)
2
>>> fizzbuzz(49)
49
n doit être un entier représenté par un type entier, un type entier long ou un type minoritaire à virgule flottante.
(Pour le type minoritaire à virgule flottante, la partie fractionnaire doit être 0.)
Si un petit nombre est entré, ValueError est renvoyé.
>>> fizzbuzz(1.0)
1
>>> fizzbuzz(5.0)
'Buzz'
>>> fizzbuzz(5.5)
Traceback (most recent call last):
...
ValueError: n must be integer. n: 5.500000
'''
if n != int(n):
raise ValueError( 'n must be integer. n: %f' % n )
n = int(n)
fizzbuzz_list = ['FizzBuzz', 0, 0, 'Fizz', 0, 'Buzz', 'Fizz', 0, 0, 'Fizz', 'Buzz', 0, 'Fizz', 0, 0 ]
r = n%15
return fizzbuzz_list[r] if fizzbuzz_list[r] else n
if __name__ == '__main__':
import doctest
doctest.testmod()
Il semble facile à utiliser car vous pouvez tester et créer des documents à la fois. Il a été souligné que le code devient difficile à lire car les commentaires sont longs, mais les deux avantages sont que quitter le document améliore la maintenabilité et que la qualité peut être garantie en exécutant le test de régression. se sentir comme.