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 № 1W 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).