This question arises when I read a generator tutorial https://realpython.com/introduction-to-python-generators/. is_palindrome(101) returns True, but the code didn't print 101. I debugged and saw yield 101 led the execution back to the main for loop, which immediately went back to the generator, which is very confusing. The generator yields 101, hence it should be an element of for j in pal_gen:, isn't it?
def is_palindrome(num):
# Skip single-digit inputs
if num // 10 == 0:
return False
temp = num
reversed_num = 0
while temp != 0:
reversed_num = (reversed_num * 10) + (temp % 10)
temp = temp // 10
if num == reversed_num:
return True
else:
return False
def infinite_palindromes():
num = 0
while True:
if is_palindrome(num):
i = (yield num)
if i is not None:
num = i
num += 1
if __name__=='__main__':
pal_gen = infinite_palindromes()
for j in pal_gen:
print(f'j={j}')
digits = len(str(j))
if digits == 5:
pal_gen.close()
pal_gen.send(10 ** (digits))
Currently the output is:
j=11
j=111
j=1111
j=10101
Traceback (most recent call last):
File "generator.py", line 33, in <module>
pal_gen.send(10 ** (digits))
StopIteration
You'll notice it is skipping one between each. 101 is missing, 1001 is missing. 10001 is missing. I'm pretty sure send leads the generator to run to the next yield statement. For example, use the following code:
if __name__=='__main__':
pal_gen = infinite_palindromes()
for j in pal_gen:
print('j={}'.format(j))
digits = len(str(j))
if digits == 5:
pal_gen.close()
print(pal_gen.send(10 ** (digits)))
This will print out the missing values between the "j's":
j=11
101
j=111
1001
j=1111
10001
j=10101
Consider redoing your for statement with a while:
if __name__=='__main__':
pal_gen = infinite_palindromes()
j=next(pal_gen)
digits=0
while digits<5:
print('j={}'.format(j))
digits = len(str(j))
j = pal_gen.send(10 ** (digits))
else:
pal_gen.close()
Related
I have a mission to write a recursive function named Reduce. This function should reduce all the zeros from number and return new number.
for example:
Reduce(-160760) => -1676
Reduce(1020034000) => 1234
I started to to something but I got stuck in the condition. here's the code I wrote so far:
def Reduce(num):
while num != 0:
if num % 10 != 0:
newNum = (num % 10) +
Reduce(num//10)
def reduce(num):
if num == 0: return 0
if num < 0: return -reduce(-num)
if num % 10 == 0:
return reduce(num // 10)
else:
return num % 10 + 10 * reduce(num // 10)
String version of recursive function:
def reduce(n):
return int(reduce_recursive(str(n), ''))
def reduce_recursive(num, res):
if not num: # if we've recursed on the whole input, nothing left to do
return res
if num[0] == '0': # if the character is '0', ignore it and recurse on the next character
return reduce_recursive(num[1:], res)
return reduce_recursive(num[1:], res+num[0]) # num[0] is not a '0' so we add it to the result and we move to the next character
>>> reduce(1200530060)
12536
I have been getting a syntax error with code which does prime-factorization
The is this Code
from sys import argv
from os import system, get_terminal_size
from math import sqrt
number = int(argv[1])
width = get_terminal_size().columns
prime_numbers = []
prime_factors = []
_ = system('clear')
print()
def is_prime(n):
for i in range(2, n):
if n % i == 0:
return False
return True
if is_prime(number):
print(f"It is a prime number \nIts only factors are 1 and itself \n1, {number}")
exit()
x = len(str(number))
for i in range(2, int(sqrt(number))):
if is_prime(i):
prime_numbers.append(i)
#print(f"found ")
#print(prime_numbers)
i = 0
while True:
if (number % prime_numbers[i] != 0):
i += 1
continue
prime_factors.append(prime_numbers[i])
print("%2d | %3d".center(width) % (prime_numbers[i], number))
print("_________".center(width))
number /= prime_numbers[i]
if number == 1:
break
print("1".center(width))
print("Answer ")
i = len(prime_factors)
j = 1
for k in prime_factors:
if j == i:
print(k)
break
print(f"{k}", end=" X ")
j += 1
This works for small numbers , less than 4 or 5 digits but gives an index error for bigger ones.
If I remove the sqrt function on line 24 it starts taking too long.
The errors look like this
Traceback (most recent call last):
File "prime-factor.py", line 33, in <module>
if (number % prime_numbers[i] != 0):
IndexError: list index out of range
real 0m0.049s
user 0m0.030s
sys 0m0.014s
(base) Souravs-MacBook-Pro-5:Fun-Math-Algorithms aahaans$ time python3 prime-factor.py 145647
I am unable to resolve this issue, Id appreciate it if you could help me.
No need to rebuild what's already available primePy
from primePy import primes
primes.factors(101463649)
output
[7, 23, 73, 89, 97]
There are two basic issues with the code. One with the for loop for prime numbers, you have to check until int(sqrt(number))+1. And, in the while loop after that, you have to break when the number is below sqrt of the original number, for which another variable should be used. The corrected code is:
from sys import argv
from os import system, get_terminal_size
from math import sqrt
number = int(argv[1])
width = get_terminal_size().columns
prime_numbers = []
prime_factors = []
_ = system('clear')
print()
def is_prime(n):
for i in range(2, n):
if n % i == 0:
return False
return True
if is_prime(number):
print(f"It is a prime number \nIts only factors are 1 and itself \n1, {number}")
exit()
x = len(str(number))
limit = int(sqrt(number))
for i in range(2, limit+1):
if is_prime(i):
prime_numbers.append(i)
i = 0
while True:
if i == len(prime_numbers)-1:
# prime_factors.append(int(number))
break
if (number % prime_numbers[i] != 0):
i += 1
continue
prime_factors.append(prime_numbers[i])
print("%2d | %3d".center(width) % (prime_numbers[i], number))
print("_________".center(width))
number /= prime_numbers[i]
prime_factors.append(int(number))
print("%2d | %3d".center(width) % (number, number))
print("_________".center(width))
print("1".center(width))
print("Answer ")
i = len(prime_factors)
j = 1
for k in prime_factors:
if j == i:
print(k)
break
print(f"{k}", end=" X ")
j += 1
If my explanation wasn't clear, look at the changes in the code.
I wrote a small number factorization engine that can factor numbers.
import math
def LLL(N):
p = 1<<N.bit_length()-1
if N == 2:
return 2
if N == 3:
return 3
s = 4
M = pow(p, 2) - 1
for x in range (1, 100000):
s = (((s * N ) - 2 )) % M
xx = [math.gcd(s, N)] + [math.gcd(s*p+x,N) for x in range(7)] + [math.gcd(s*p-x,N) for x in range(1,7)]
try:
prime = min(list(filter(lambda x: x not in set([1]),xx)))
except:
prime = 1
if prime == 1:
continue
else:
break
#print (s, x, prime, xx)
return prime
Factor:
In [219]: LLL(10142789312725007)
Out[219]: 100711423
from https://stackoverflow.com/questions/4078902/cracking-short-rsa-keys
I also made Alpertons ECM SIQs engine work in python if you want factorization at that (over 60 digits level): https://github.com/oppressionslayer/primalitytest
I am currently working on a school assignment from the AI department where I have to make a Genetic Algorithm. It is meant to solve the 8 Queens problem using a list called board, where each index is a column and the value in that index is the row. The algorithm itself works fine, but every time I try to run it, it crashes after the while loop reaches populationSize - 2 (in this case 18). The error that I get is about line:
child = reproduce(population[l], population[l + 1], nqueens)
and the error is:
Traceback (most recent call last):
File "nqueens1.py", line 370, in
main()
File "nqueens1.py", line 363, in main
genetic_algorithm(board)
File "nqueens1.py", line 291, in genetic_algorithm
child = reproduce(population[l], population[l + 1], nqueens)
IndexError: list index out of range
I am trying to understand what is going wrong, but I do not see why it would go out of range. Here is the code that I have so far:
Function Reproduce
def reproduce(boardX, boardY, nqueens):
boardChild = [-1] * nqueens
n = random.randint(0, (nqueens - 1)) #percentage of how much of one parent is reproduced and how much of the other parent
d = 0
for d in range(n): # the first n part of parent x
boardChild[d] = boardX[d]
s = d + 1
for s in range(nqueens) : # the last n-(len(board)-1) part of parent y
boardChild[s] = boardY[s]
return boardChild
Function Mutate
def mutate(child):
print('mutate')
boardMutated = [-1] * len(child)
newColumn = random.randint(0, len(child)-1)
newRow = random.randint(0, len(child)-1)
boardMutated[newColumn] = newRow
return boardMutated
Genetic Algorithm
def genetic_algorithm(board):
optimum = (len(board) - 1) * len(board) / 2
print('optimum:' + str(optimum))
nqueens = len(board)
populationSize = 20
population = []
for i in range(populationSize -1): #initializes first pooulation
population.append([])
for _ in range(nqueens):
population[i].append(random.randint(0, nqueens-1))
population[i].append(evaluate_state(population[i]))
if evaluate_state(population[i]) == optimum:
print("solved puzzle! 0")
print_board(population[i])
return
t = 0
while t != 1000:
population.sort(key=lambda x: x[nqueens -1 ]) #sorts the population from highest population size
for i in range(populationSize -1):
del population[i][-1]
newPopulation = [ [] for _ in range(populationSize -1) ]
newPopulation[0] = reproduce(population[1], population[0], nqueens) #
chance = random.randint(0, 100)
if chance < 5: # small chance that the child gets mutated
newPopulation[0] = mutate(newPopulation[0])
if evaluate_state(newPopulation[0]) == optimum:
print('if evaluate_state(child) == optimum:')
print("Solved puzzle! 1")
print_board(newPopulation[0])
return
if evaluate_state(newPopulation[0]) == optimum:
print("Solved puzzle! 2")
print('if evaluate_state(newPopulation[1]) == optimum:')
print_board(newPopulation[1])
return
l = 0
while l != (populationSize -1):
print(str(l))
child = reproduce(population[l], population[l + 1], nqueens) # reproduces the new generation
print_board(child)
if evaluate_state(child) == optimum:
print('if evaluate_state(child) == optimum:')
print("Solved puzzle! 3")
print_board(child)
return
chance = random.randint(0, 100)
if chance < 5: # small chance that the child gets mutated
child = mutate(child)
if evaluate_state(child) == optimum:
print('if evaluate_state(child) == optimum:')
print("Solved puzzle! 4")
print_board(child)
return
newPopulation[l] = child
l += 1
t += 1
All the print-statements were added to see which parts did execute and which did not execute. The code crashes as soon as the l reaches 18 here, which of course it should not. All help would be appreciated!
I think population only has 19 items, not 20; all the populations are initialized using range(populationSize - 1) which only has 19 numbers (from 0 to 18).
You can check this by also printing out len(population)
I am new to Python. My only background in Python is CS50(Week 6). I am trying to implement Credit from pset6. In this, we have to implement Luhn's Algorithm.
But, I am getting the undermentioned error and I am not able to understand why:
Traceback (most recent call last):
File "credit.py", line 57, in <module>
main()
File "credit.py", line 9, in main
if IfAmex(arr_number):
File "credit.py", line 27, in IfAmex
if Luhn(card_n):
File "credit.py", line 50, in Luhn
sum2 = sum(int(c) for c in str(2 * card_n[i]) for i in range(1, len(card_n), 2))
NameError: name 'i' is not defined
Here is my code:
from sys import exit
from cs50 import get_int
def main():
number = get_int("Number: ")
# Converting the number into a list
arr_number = [int(x) for x in str(number)]
if IfAmex(arr_number):
print("AMEX")
exit(0)
elif IfMasCard(arr_number):
print("MASTERCARD")
exit(0)
elif IfVisa(arr_number):
print("VISA")
exit(0)
else:
print("INVALID")
exit(0)
def IfAmex(card_n):
if not len(card_n) == 15:
return False
if not (card_n[0] * 10 + card_n[1]) in [34, 37]:
return False
if Luhn(card_n):
return True
def IfMasCas(card_n):
if not len(card_n) == 16:
return False
if not (card_n[0] * 10 + card_n[1]) in range(51, 56):
return False
if Luhn(card_n):
return True
def IfVisa(card_n):
if not len(card_n) in [13, 16]:
return False
if not card_n[0] == 4:
return False
if Luhn(card_n):
return True
def Luhn(card_n):
# Reversing the digits
card_n = card_n[::-1]
sum1 = sum(card_n[::2])
sum2 = sum(int(c) for c in str(2 * card_n[i]) for i in range(1, len(card_n), 2)) # The Error Line
luhnsum = sum1 + sum2
return luhnsum % 10 == 0
if __name__ == '__main__':
main()
And the test case I used was(along with the correct output):
$ python credit.py
Number: 378282246310005
AMEX
Also, please tell me whether I am using exit() correctly or not.
You use i here as an index of card_n array. But you forgot to define it.
Define it and assign it to a value before using.
sum2 = sum(int(c) for c in str(2 * card_n[i])
old = [[0 for x in range(3)] for y in range(10)]
count =0
# check if the number has non-repeating digits
def different(number):
digit_list = [0] * 4
i = 0
while i:
digit_list[i] = number%10
number /= 10
i += 1
for x in range(0,3):
for y in range(x+1,3):
if digit_list[x] == digit_list[y]:
return False
return True
# save the tried numbers, plus and minus values
# for prediction of the next number
def save(number,plus,minus):
global count
old[count][0] = number
old[count][1] = plus
old[count][2] = minus
count += 1
return
# compare for plus values
def get_plus(number1,number2):
ret_value = 0
for x in range(0, 3):
if number1 % 10 == number2 % 10:
ret_value += 1
number1 /= 10
number2 /= 10
return ret_value
# compare for minus values
def get_minus(number1,number2):
temp = [[0]*4 for i in range(2)]
ret_value = 0
for x in range(0,3):
temp[0][x] = number1 % 10
temp[0][x] = number2 % 10
number1 /= 10
number2 /= 10
for x in range(0,3):
for y in range(0,3):
if x != y:
if temp[0][x] == temp[1][y]:
ret_value += 1
return ret_value
# compare the number to be asked with the numbers in the array
def control(number):
for x in range(0,count-1):
if get_plus(old[x][0],number) != old[x][1]:
return False
if get_minus(old[x][0],number) != old[x][2]:
return False
return True
def main():
flag = False
print('1023 ??')
plus = input('plus ?')
minus = input('minus ?')
save(1023, plus, minus)
print('4567 ??')
plus = input('plus ?')
minus = input('minus ?')
save(4567, plus, minus)
for i in range(1024, 9876):
if different(i):
if control(i):
print(i + ' ??')
plus = input('plus ?')
minus = input('minus ?')
save(i, plus, minus)
if plus == 4 and minus == 0:
print('I WON !!!')
flag = True
break
if not flag:
print('False')
return
main()
I am trying to make an AI for mindgame in python. But in this function it doesn't even start the for loop. Can anyone know why ?
The while loop in your different() function does nothing as while(0) will prevent the loop from running. Even if that would run, your different() function will always return false. At least in the last loop it will compare digit_list[3] == digit_list[3] as both loop range until 3. This is always true and the function will return false. Thus the code within your main loop will never be entered.
def different(number):
digit_list = [0] * 4
i = 0
while i:
digit_list[i] = number%10
number /= 10
i += 1
for x in range(0,3):
for y in range(x+1,3):
if digit_list[x] == digit_list[y]:
return False
return True
Try this one:
import random
def different(num):
digits = []
while num >= 1:
cur = num%10
if cur in digits:
return False
digits.append(cur)
num = (num - cur) / 10
return True
for i in range(0, 10000):
rand = random.randrange(1000, 10000)
if not different(rand):
print(rand)