Python – La séquence Collatz
Tout d’abord, notez comment vous dupliquez les calculs:
print(num//2)num = num //2
Cela peut ne pas causer de problèmes avec ce code spécifique, mais ce n’est pas une bonne pratique. Vous faites deux fois plus de travail que nécessaire, ce qui peut entraîner des problèmes de performances une fois que vous commencez à écrire du code plus compliqué. Faites le calcul une fois et enregistrez le résultat. Dans ce cas cependant, tout ce que vous devez faire est d’inverser ces lignes et d’utiliser num
:
num = num // 2print(num)
Assurez-vous également d’avoir un espacement approprié autour des opérateurs et d’être cohérent.
Vos cas if
et elif
sont exclusifs l’un de l’autre, et votre else
ne devrait jamais se produire. Si la première condition est vraie, alors l’autre doit être fausse et vice-versa. Il n’y a pas besoin de la deuxième vérification. Une fois réécrit, vous verrez que l’impression dans tous les cas n’est pas nécessaire. Vous pouvez simplement imprimer après:
while num > 1: if num % 2 == 0: num = num // 2 else: num = 3 * num + 1 print(num)
Puisque vous ne faites que réaffirmer num
l’une des deux options basées sur une condition, une expression conditionnelle peut également être utilisée ici proprement:
while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) print(num)
Les accolades ne sont pas nécessaires, mais je pense qu’elles sont utiles ici en raison du nombre d’opérateurs impliqués.
Imprimer les chiffres n’est pas idéal ici. Dans la plupart des codes, vous devez pouvoir utiliser les données que vous produisez. Si vous vouliez analyser la séquence produite, vous deviez faire quelque chose pour intercepter la sortie standard, ce qui est coûteux et trop compliqué. Faites-en une fonction qui accumule et renvoie une liste. Dans les exemples suivants, j’ai également ajouté des indices de type pour préciser le type des données:
from typing import Listdef collatz(starting_num: int) -> List: nums = num = starting_num while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) nums.append(num) return nums
Ou, une approche beaucoup plus propre consiste à en faire un générateur qui donne les nombres:
# Calling this function returns a generator that produces ints# Ignore the two Nones, as they aren't needed for this kind of generatordef collatz_gen(starting_num: int) -> Generator: yield starting_num num = starting_num while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) yield num>>> list(collatz_gen(5))
Il y a quelques choses notables à propos de getNum
:
Python utilise “snake_case”, pas “CamelCase”.
Votre utilisation de global num
ici est inutile et déroutante. Comme précédemment, explicitement return
toutes les données produites par la fonction:
def get_num() -> int: raw_num = input("> ") try: return int(raw_num) except ValueError: print('Please enter a number') return get_num()
Notez qu’au lieu de réaffecter un num
global, nous ne faisons que renvoyer le nombre. J’ai également espacé un peu les choses et utilisé des noms plus appropriés. Conceptuellement, je dirais que num = input("> ")
est faux. Au moment où cela s’exécute, num
ne contient pas de nombre (il contient une chaîne).
Ce n’est pas une bonne utilisation de la récursivité. Cela ne vous posera probablement aucun problème, mais si votre utilisateur est vraiment stupide et saisit des données erronées ~ 1000 fois, votre programme se bloquera. Utilisez simplement une boucle:
def get_num() -> int: while True: raw_num = input("> ") try: return int(raw_num) except ValueError: print('Please enter a number')
Dans des langages comme Python, soyez prudent en utilisant la récursivité dans les cas où vous n’avez aucune garantie sur le nombre de fois où la fonction se recursifiera.
Je nommerais probablement ce quelque chose de plus proche de ask_for_num
. “get” ne précise pas très clairement d’où viennent les données.
Pris au total, vous vous retrouverez avec:
from typing import Generatordef collatz_gen(starting_num: int) -> Generator: yield starting_num num = starting_num while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) yield numdef ask_for_num() -> int: while True: raw_num = input("> ") try: return int(raw_num) except ValueError: print('Please enter a number')
Qui peut être utilisé comme:
num = ask_for_num()for n in collatz_gen(num): print(n)