Python-The Collatz Sequence

Innanzitutto, nota come stai duplicando i calcoli:

print(num//2)num = num //2

Ciò potrebbe non causare problemi con questo codice specifico, ma non è una buona pratica. Stai facendo il doppio del lavoro necessario, il che può causare problemi di prestazioni una volta iniziato a scrivere codice più complicato. Esegui il calcolo una volta e salva il risultato. In questo caso, però, tutto ciò che devi fare è invertire quelle linee e usare num:

num = num // 2print(num)

Inoltre, assicurati di avere una spaziatura adeguata attorno agli operatori ed essere coerente.

I tuoi casi if e elif sono esclusivi l’uno dell’altro e il tuo else non dovrebbe mai accadere. Se la prima condizione è vera, allora l’altra deve essere falsa e viceversa. Non c’è bisogno del secondo controllo. Una volta riscritto, vedrai che la stampa in ogni caso non è necessaria. Si può solo stampare dopo:

while num > 1: if num % 2 == 0: num = num // 2 else: num = 3 * num + 1 print(num)

Dal momento che stai solo riassegnando num una delle due opzioni basate su una condizione, un’espressione condizionale può essere utilizzata anche qui in modo pulito:

while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) print(num)

Le parentesi graffe non sono necessarie, ma penso che siano utili qui a causa del numero di operatori coinvolti.

Stampare i numeri non è l’ideale qui. Nella maggior parte del codice, è necessario essere in grado di utilizzare i dati che si producono. Se volessi analizzare la sequenza prodotta, dovresti fare qualcosa per intercettare lo stdout, che è costoso ed eccessivamente complicato. Rendilo una funzione che accumula e restituisce un elenco. Negli esempi seguenti, ho anche aggiunto alcuni suggerimenti di tipo per rendere più chiaro quale sia il tipo di dati:

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

Oppure, un approccio molto più pulito è quello di renderlo un generatore che produce i numeri:

# 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))

Ci sono alcune cose notevoli su getNum:

Python usa “snake_case”, non”camelCase”.

L’uso di global num qui non è necessario e confuso. Proprio come prima, esplicitamente return tutti i dati che la funzione produce:

def get_num() -> int: raw_num = input("> ") try: return int(raw_num) except ValueError: print('Please enter a number') return get_num()

Nota come invece di riassegnare un num globale, stiamo solo restituendo il numero. Ho anche distanziato un po ‘ le cose e ho usato alcuni nomi più appropriati. Concettualmente, direi che num = input("> ") è sbagliato. Nel momento in cui viene eseguito, num non contiene un numero (contiene una stringa).

Questo non è un buon uso della ricorsione. Probabilmente non ti causerà alcun problema, ma se il tuo utente è davvero stupido e inserisce dati errati ~1000 volte, il tuo programma si bloccherà. Basta usare un ciclo:

def get_num() -> int: while True: raw_num = input("> ") try: return int(raw_num) except ValueError: print('Please enter a number')

In linguaggi come Python, fai attenzione a usare la ricorsione nei casi in cui non hai garanzie su quante volte la funzione si ripresenterà.

Probabilmente chiamerei anche questo qualcosa di più vicino a ask_for_num. “get” non rende molto chiaro da dove provengono i dati.

Preso del tutto, finirai con:

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')

Che può essere utilizzato come:

num = ask_for_num()for n in collatz_gen(num): print(n)

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.