Python-The Collatz Sequence

po pierwsze, zwróć uwagę, jak powielasz obliczenia:

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

może to nie powodować problemów z tym konkretnym kodem, ale nie jest to dobra praktyka. Wykonujesz dwa razy więcej pracy, niż potrzebujesz, co może powodować problemy z wydajnością, gdy zaczniesz pisać bardziej skomplikowany kod. Wykonaj obliczenia raz i zapisz wynik. W tym przypadku wystarczy odwrócić te linie i użyć num:

num = num // 2print(num)

upewnij się również, że masz odpowiednie odstępy wokół operatorów i bądź spójny.

Twoje if i elif przypadki są wyłączne od siebie, a twoja else nigdy nie powinna się zdarzyć. Jeśli pierwszy warunek jest prawdziwy, to drugi musi być fałszywy i odwrotnie. Drugi czek nie jest potrzebny. Po przepisaniu zobaczysz, że drukowanie w każdym przypadku nie jest konieczne. Możesz wydrukować po:

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

ponieważ po prostu przywracasz num jedną z dwóch opcji opartych na warunku, wyrażenie warunkowe może być również użyte tutaj czysto:

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

szelki nie są konieczne, ale myślę, że są tu przydatne ze względu na liczbę zaangażowanych operatorów.

Drukowanie liczb nie jest tutaj idealne. W większości kodów musisz być w stanie korzystać z danych, które generujesz. Jeśli chcesz przeanalizować wytworzoną sekwencję, musisz zrobić coś przechwycić stdout, co jest drogie i zbyt skomplikowane. Uczyń z niej funkcję, która gromadzi i zwraca listę. W poniższych przykładach dodałem również kilka wskazówek typu, aby wyjaśnić, jaki jest typ danych:

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

lub, znacznie czystszym podejściem jest zrobienie z niego generatora, który daje liczby:

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

jest kilka istotnych rzeczy o getNum:

Python używa “snake_case”, a nie”camelCase”.

Twoje użycie global num tutaj jest niepotrzebne i mylące. Podobnie jak poprzednio, jawnie return wszelkie dane, które funkcja generuje:

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

zauważ, że zamiast przypisywać globalny num, po prostu zwracamy ten numer. Rozłożyłem trochę rzeczy i użyłem bardziej odpowiednich nazw. Koncepcyjnie powiedziałbym, że num = input("> ") się myli. W momencie uruchomienia num nie zawiera liczby (zawiera łańcuch znaków).

to nie jest dobre użycie rekurencji. Prawdopodobnie nie spowoduje to żadnych problemów, ale jeśli twój użytkownik jest naprawdę głupi i wprowadza błędne dane ~1000 razy, twój program ulegnie awarii. Wystarczy użyć pętli:

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

w językach takich jak Python, bądź ostrożny używając rekurencji w przypadkach, gdy nie masz gwarancji, ile razy funkcja będzie rekurencyjna.

też pewnie nazwałbym to coś bliżej ask_for_num. “get” nie wyjaśnia, skąd pochodzą dane.

wzięte w całości, skończysz z:

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

które można wykorzystać jak:

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

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.