/ / Dlaczego moja funkcja Pythona działa w konsoli, ale nie w przypadku wywołania w kodzie? - python, python-3.x

Dlaczego moja funkcja Pythona działa w konsoli, ale nie po wywołaniu w kodzie? - python, python-3.x

Próbuję nauczyć się Pythona, pracując nad problemami na stronie projektu Euler. Wiem dokładnie, co chcę zrobić, a moja metoda działa na papierze, ale nie mogę sprawić, by kod działał.

Link GitHub: https://github.com/albyr/euler-python/blob/master/euler3.py

Stworzyłem dwie funkcje, z których jedna określa współczynniki liczby docelowej, a druga sprawdza, czy dana liczba jest liczbą pierwszą.

# Function that finds all the factors of a given number
def findfactors(n):
# for i in range(1,int(sqrt(n)+1)):
for i in range(1,n+1):
if n/i == int(n/i):
factors.append(i)

# Function that checks if a number is prime
def checkprime(n):
# Trial division
for i in range(2,int(sqrt(n)+1)):
if n/i == int(n/i):
# Number gives a remainder upon division and therefore is not prime
isprime = False
break
else:
isprime = True
if isprime == True:
return True
elif isprime == False:
return False

Jestem pewien, że dla ekspertów ten kod wygląda okropnie. Ale działa, gdy używam powłoki Pythona:

>>> checkprime(9)
False
>>> checkprime(79)
True
>>> checkprime(factors[3])
True

Ale kiedy uruchamiam program za pomocą F5, otrzymuję:

Traceback (most recent call last):
File "/home/alby/euler-python/euler3.py", line 45, in <module>
checkprime(factors[i])
File "/home/alby/euler-python/euler3.py", line 32, in checkprime
if isprime == True:
UnboundLocalError: local variable "isprime" referenced before assignment

Jeśli wywołam funkcję checkprime z poziomu programu z zakodowanym numerem (np. checkprime(77)) Nie mam żadnego wyjścia. Jestem pewien, że jest to coś podstawowego w sposobie, w jaki Python działa, czego nie rozumiem, ale nie mogę przez całe życie wypracować, co.

Jakieś sugestie?

Odpowiedzi:

5 dla odpowiedzi № 1

W twoim kodzie Github widzimy, że próbujesz zadzwonić checkprime(1) (przy pierwszej iteracji przez ostatnią pętlę).

# Check each factor to see if it is prime or compound
for i in range(0,len(factors)):
print (factors[i])
# Why can"t I call checkprime here, like this? It works in the console.
checkprime(factors[i])

Ale spójrz na swój kod:

def checkprime(n):
# Trial division
for i in range(2,int(sqrt(n)+1)):
if n/i == int(n/i):
# Number gives a remainder upon division and therefore is not prime
isprime = False
break
else:
isprime = True

Gdyby n = 1, następnie range(2, int(sqrt(1)+1)) jest range(2,2) który jest pusty ... tak isprime nigdy się nie ustawia, ponieważ ciało pętli nigdy nie zostanie uruchomione.

Pamiętaj, że argumenty do range() powierzchnia na wpół otwarte interwał - range(x,y) jest „liczbami całkowitymi zaczynającymi się od x i kończącymi przed y. Tak więc range(2,3) = [2] i range(2,2) = [].

Inną kwestią jest tutaj findfactors() wraca 1 jako pierwszy czynnik - prawdopodobnie nie jest to, czego chcesz:

def findfactors(n):
# for i in range(1,int(sqrt(n)+1)):
for i in range(1,n+1):

W przypadku sprawdzania pierwotnej faktoryzacji prawdopodobnie chcesz zacząć od 2, nie 1 (ponieważ wszystko jest podzielne przez 1).


Ponadto ten kod jest zbędny:

if isprime == True:
return True
elif isprime == False:
return False

Możesz po prostu napisać to jako ...

return isprime

Albo możesz pójść o krok lepiej i nigdy nie używać isprime po pierwsze - wystarczy wymienić isprime = True z return True i isprime = False z return False.

Wreszcie skrót dla int(n/i) jest n // i - Python "s // operator robi podział na liczby całkowite.


0 dla odpowiedzi nr 2

Jeśli chodzi o drukowanie bez wyjścia, po prostu użyj print(checkprime(77)) zamiast tego podczas uruchamiania z F5 i powinieneś otrzymać swoje wyjście. Podczas uruchamiania wywołania Python domyślnie nic nie drukuje (lub przynajmniej drukuje tylko ostatnie polecenie).