Python script for finding keith numbers not working - python

I am trying to make a python program that will find keith numbers. If you don't what keith numbers are, here is a link explaining them:
Keith Numbers - Wolfram MathWorld
My code is
from decimal import Decimal
from time import sleep
activator1 = 1
while (activator1 == 1):
try:
limit = int(raw_input("How many digits do you want me to stop at?"))
activator1 = 0
except ValueError:
print "You did not enter an integer"
limitlist = []
activator2 = 1
while (activator2 <= limit):
limitlist.append(activator2)
activator2 += 1
print limitlist
add1 = 0
add = 0
count = 9
while 1:
sleep (0.1)
numbers = list(str(count))
for i in limitlist:
if (i > 0) & (add < count):
add = sum(Decimal(i) for i in numbers)
lastnumber = int(numbers[-1])
add1 = lastnumber+int(add)
numbers.reverse()
numbers.pop()
numbers.append(add1)
print add1
print add
print count
print numbers
if (add1 == count):
print"________________________________"
print add1
print count
elif (i > 0) & (add > count):
count += 1
break
It doesn't output any errors but it just outputs
18
9
9
[18]
Could someone please tell me why it doesn't just repeatedly find Keith numbers within the number of integers range?

You have it in front of you:
add1 = 18
add = 9
count = 9
numbers = [18]
You're in an infinite loop with no output. You get this for once. After this, i runs through the values 1, 2, and 3. Each time through the for loop, all three if conditions are False. Nothing changes, you drop out of the for loop, and go back to the top of the while. Here, you set numbers back to ['9'], and loop forever.
I suggest that you learn two skills:
Basic debugging: learn to single-step through a debugger, looking at variable values. Alternately, learn to trace your logic on paper and stick in meaningful print statements. (My version of this is at the bottom of this answer.)
Incremental programming: Write a few lines of code and get them working. After you have them working (test with various input values and results printed), continue to write a few more. In this case, you wrote a large block of code, and then could not see the error in roughly 50 lines. If you code incrementally, you'll often be able to isolate the problem to your most recent 3-5 lines.
while True:
# sleep (0.1)
numbers = list(str(count))
print "Top of while; numbers=", numbers
for i in limitlist:
print "Top of for; i =", i, "\tadd =", add, "\tcount =", count, "\tadll =", add1
if (i > 0) & (add < count):
add = sum(Decimal(i) for i in numbers)
lastnumber = int(numbers[-1])
add1 = lastnumber+int(add)
numbers.reverse()
numbers.pop()
numbers.append(add1)
print "add1\t", add1
print "add\t", add
print "count\t", count
print "numbers", numbers
if (add1 == count):
print"________________________________"
print add1
print count
elif (i > 0) & (add > count):
count += 1
print "increment count:", count
break

Prune has already given you good advices! Let's put a little example of what he meant though, let's say you got an algorithm which determine whether n is a keith number or not and also a test loop to print some keith numbers:
def keith_number(n):
c = str(n)
a = list(map(int, c))
b = sum(a)
while b < n:
a = a[1:] + [b]
b = sum(a)
return (b == n) & (len(c) > 1)
N = 5
for i in range(N):
a, b = 10**i, 10**(i + 1)
print("[{0},{1}]".format(a, b))
print([i for i in filter(keith_number, range(a, b))])
print('-' * 80)
such snippet gives you this:
[1,10]
[]
--------------------------------------------------------------------------------
[10,100]
[14, 19, 28, 47, 61, 75]
--------------------------------------------------------------------------------
[100,1000]
[197, 742]
--------------------------------------------------------------------------------
[1000,10000]
[1104, 1537, 2208, 2580, 3684, 4788, 7385, 7647, 7909]
--------------------------------------------------------------------------------
[10000,100000]
[31331, 34285, 34348, 55604, 62662, 86935, 93993]
--------------------------------------------------------------------------------
Wow, that's awesome... but wait, let's say you don't understand the keith_number function and you want to explore a little bit the algorithm in order to understand its guts. What about if we add some useful debug lines?
def keith_number(n):
c = str(n)
a = list(map(int, c))
b = sum(a)
print("{0} = {1}".format("+".join(map(str, a)), b))
while b < n:
a = a[1:] + [b]
b = sum(a)
print("{0} = {1}".format("+".join(map(str, a)), b))
return (b == n) & (len(c) > 1)
keith_number(14)
print '-' * 80
keith_number(15)
that way you'll be able to trace the important steps and the algorithm will make sense in your head:
1+4 = 5
4+5 = 9
5+9 = 14
--------------------------------------------------------------------------------
1+5 = 6
5+6 = 11
6+11 = 17
Conclusion: I'd advice you learn how to debug your own code instead asking strangers about it ;-)

I hope this solves your problem , and also I'm actually new here , so basically I solved it with the use of lists I hope u can understand :)
def kieth(n):
n1 = n[::-1]
f = [0]
[f.insert(0, int(x)) for x in n1]
for x in range(1, int(n)):
if f[-2] == int(n):
break
else:
f.insert(-1, sum(f[-abs(len(n1)) - 1:-1]))
return True if int(n) in f else False
n = input(" enter a number ")
print("is a kieth number " if kieth(str(n)) else "not a keith")

Related

hailstone program in python

i have to write a hailstone program in python
you pick a number, if it's even then half it, and if it's odd then multiply it by 3 and add 1 to it. it says to continue this pattern until the number becomes 1.
the program will need methods for the following:
accepting user input
when printing the sequence, the program should loop until the number 1.
print a count for the number of times the loop had to run to make the sequence.
here's a sample run:
prompt (input)
Enter a positive integer (1-1000). To quit, enter -1: 20
20 10 5 16 8 4 2 1
The loop executed 8 times.
Enter a positive integer (1-1000). To quit, enter -1: 30
30 15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
The loop executed 19 times.
Enter a positive integer (1-1000). To quit, enter -1: -1
Thank you for playing Hailstone.
right now i have this:
count = 0
def hailstone(n):
if n > 0
print(n)
if n > 1:
if n % 2 == 0:
hailstone(n / 2)
else:
hailstone((n * 3) + 1)
count = count + 1
i don't know what to do after this
Try to think in a modular way, make two functions: check_number() and user_call(). Check_number will verify if the current number in the loop is odd or even and the user_call() just wraps it to count how many times the loop did iterate.
I found the exercise in a great book called Automate Boring Stuff with Python, you have to check it out, if you don't know it already.
Here's my code. Try to use what serves you the best.
from sys import exit
def check_number(number):
if number % 2 ==0:
print(number // 2)
return(number // 2)
else:
print(number*3+1)
return number*3+1
def user_call(number):
count = 0
while number != 1:
count += 1
number = check_number(number)
return count
if __name__ == "__main__":
try:
number = int(input('Give a number \n'))
count = user_call(number)
print('count ',count)
except Exception as e:
exit()
you can use global
visit https://www.programiz.com/python-programming/global-keyword to learn more
import sys
res = []
def hailstone(number):
global res
if number > 1:
if number % 2 == 0:
res.append( number // 2 )
hailstone(res[len(res)-1])
else:
res.append(number * 3 + 1)
hailstone(res[len(res)-1])
return res
number = int(input('Enter a positive integer. To quit, enter -1: '))
if number <= 0 or number == 0:
print('Thank you for playing Hailstone.')
sys.exit()
else:
answers = hailstone(number)
for answer in answers:
print(answer)
print('The loop executed {} times.'.format(len(answers) + 1))
I used recursion to solve the problem.
Heres my code:
Edit: All criteria met
count = 0
list_num = []
def input_check():
number = int(input("Enter a positive integer (1-1000). To quit, enter -1: "))
if number >= 1 and number <= 1000:
hailstone_game(number)
elif number == -1:
return
else:
print("Please type in a number between 1-1000")
input_check()
def hailstone_game(number):
global count
while number != 1:
count += 1
list_num.append(number)
if number % 2 == 0:
return hailstone_game(int(number/2))
else:
return hailstone_game(int(number*3+1))
list_num.append(1) # cheap uncreative way to add the one
print(*list_num, sep=" ")
print(f"The loop executed {count} times.")
return
input_check()
Additional stuff that could be done:
- Catching non-integer inputs using try / except
Keep in mind when programming it is a good habit to keep different functions of your code separate, by defining functions for each set of 'commands'. This leads to more readable and easier to maintain code. Of course in this situation it doesn't matter as the code is short.
Your recursive function is missing a base/terminating condition so it goes into an infinite loop.
resultArray = [] #list
def hailstone(n):
if n <= 0: # Base Condition
return
if n > 0:
resultArray.append(n)
if n > 1:
if n % 2 == 0:
hailstone(int(n/2))
else:
hailstone((n * 3) + 1)
# function call
hailstone(20)
print(len(resultArray), resultArray)
Output
8 [20, 10, 5, 16, 8, 4, 2, 1]
Here's a recursive approach for the problem.
count=0
def hailstone(n):
global count
count+=1
if n==1:
print(n)
else:
if n%2==0:
print(n)
hailstone(int(n/2))
else:
print(n)
hailstone(3*n+1)
hailstone(21)
print(f"Loop executed {count} times")

Looking for Clarification on how this "For-Loop" works

I'm a complete beginner to programming so forgive me for my naivete.
I wanted to make a program in Python that lets me print a given N number of prime numbers, where N is inputted by the user. I searched a little on "for/while" loops and did some tinkering. I ran a program I saw online and modified it to suit the problem. Here is the code:
i = 1
print("Hi! Let's print the first N prime numbers.")
nPrimes = int(input("Enter your N: "))
counter = 0
while True:
c = 0 #another initialization
for x in range (1, (i + 1)):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
if c == 2:
print(i, end = " ")
counter = counter + 1
if counter > = nPrimes: #if it reaches the number input, the loop will end.
break
i = i+1
print(": Are your", nPrimes, "prime number/s!")
print()
print("Thanks for trying!")
This should be able to print the amount of prime numbers the user so likes. It is a working code, though I am having difficulty trying to understand it. It seems that the variable c is important in deciding whether or not to print the variable i (which in our case is the supposed prime number during that interval).
We do c + 1 to c every time our variable a has a remainder of 0 in a = i % x. Then, if c reaches 2, the current variable i is printed, and variable c re-initializes itself to 0 once a prime number has been found and printed.
This I can comprehend, but I get confused once the numbers of i get to values 4 and onwards. *How is 4 skipped by the program and not printed when it has 2+ factors in the range that makes its remainder equal to zero? Wouldn't c == 2 for 4 and thus print 4? *And how would the program continue to the next number, 5? (Given that variable N is a large enough input).
Any clarifications would be greatly appreciated. Thank you so much!
From Wikipedia we know:
A prime number (or a prime) is a natural number greater than 1 that cannot be formed by multiplying two smaller natural numbers.
So to find a prime, is to find a natural number, aka an integer, which can only be exactly divided by 1 or itself. This is called Approach of Definition to find primes.
Hence, the following loop traverses through all integers from 1 to i,
and it counts how many times the integer i can be exactly divided by them.
for x in range (1, (i + 1)):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
And later you judge if the integer i can only be exactly divided by 1 and itself.
If true, you got a prime;
otherwise you just keep on.
if c == 2:
print(i, end = " ")
counter = counter + 1
if counter > = nPrimes: #if it reaches the number input, the loop will end.
break
Meanwhile, you can improve this prime searching algorithm a little bit by changing i = 1 to i = 2 in the beginning and adding an if statement:
# Start from 2 instead of 1
# and end at `i - 1` instead of `i`
for x in range (2, i):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
# Abandon the loop
# because an integer with factors other than 1 and itself
# is unevitably a composite number, not a prime
if c > 0:
break
if c == 0:
print(i, end = " ")
counter = counter + 1
if counter >= nPrimes: #if it reaches the number input, the loop will end.
break
This twist improves the efficiency of your program because you avoid unnecessary and meaningless amount of work.
To prevent potential infinite loop resulting from while expression,
you should replace while True: with while counter < nPrimes:. And the code turns out to be like this:
#if it reaches the number input, the loop will end.
while counter < nPrimes:
c = 0 #another initialization
# Start from 2 instead of 1
# and end at `i - 1` instead of `i`
for x in range (2, i):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
# Abandon the loop
# because an integer with factors other than 1 and itself
# is unevitably a composite number, not a prime
if c > 0:
break
if c == 0:
print(i, end = " ")
counter = counter + 1
i = i + 1
If you want to read more about how to improve your program's efficiency in finding primes, read this code in C language. :P
c in this case is used to count the number of numbers that divide evenly into i.
for example, if i = 8: 8 is divisible by 1, 2, 4, and 8. so c = 4 since there are 4 things that divide evenly into it
if i = 5: 5 is divisible by 1 and 5. so c = 2 since there are 2 numbers that divide evenly into it
if i = 4 (where you seem to be confused): 4 is divisible by 1, 2, and 4. so c = 3, not 2.

How can I display all numbers in range 0-N that are "super numbers"

The program asks the user for a number N.
The program is supposed to displays all numbers in range 0-N that are "super numbers".
Super number: is a number such that the sum of the factorials of its
digits equals the number.
Examples:
12 != 1! + 2! = 1 + 2 = 3 (it's not super)
145 = 1! + 4! + 5! = 1 + 24 + 120 (is super)
The part I seem to be stuck at is when the program displays all numbers in range 0-N that are "super numbers". I have concluded I need a loop in order to solve this, but I do not know how to go about it. So, for example, the program is supposed to read all the numbers from 0-50 and whenever the number is super it displays it. So it only displays 1 and 2 since they are considered super
enter integer: 50
2 is super
1 is super
I have written two functions; the first is a regular factorial program, and the second is a program that sums the factorials of the digits:
number = int(input ("enter integer: "))
def factorial (n):
result = 1
i = n * (n-1)
while n >= 1:
result = result * n
n = n-1
return result
#print(factorial(number))
def breakdown (n):
breakdown_num = 0
remainder = 0
if n < 10:
breakdown_num += factorial(n)
return breakdown_num
else:
while n > 10:
digit = n % 10
remainder = n // 10
breakdown_num += factorial(digit)
#print (str(digit))
#print(str(breakdown_num))
n = remainder
if n < 10 :
#print (str(remainder))
breakdown_num += factorial(remainder)
#print (str(breakdown_num))
return breakdown_num
#print(breakdown(number))
if (breakdown(number)) == number:
print(str(number)+ " is super")
Existing answers already show how to do the final loop to tie your functions together. Alternatively, you can also make use of more builtin functions and libraries, like sum, or math.factorial, and for getting the digits, you can just iterate the characters in the number's string representation.
This way, the problem can be solved in a single line of code (though it might be better to move the is-super check to a separate function).
def issuper(n):
return sum(math.factorial(int(d)) for d in str(n)) == n
N = 1000
res = [n for n in range(1, N+1) if issuper(n)]
# [1, 2, 145]
First I would slightly change how main code is executed, by moving main parts to if __name__ == '__main__', which will execute after running this .py as main file:
if __name__ == '__main__':
number = int(input ("enter integer: "))
if (breakdown(number)) == number:
print(str(number)+ " is super")
After that it seems much clearer what you should do to loop over numbers, so instead of above it would be:
if __name__ == '__main__':
number = int(input ("enter integer: "))
for i in range(number+1):
if (breakdown(i)) == i:
print(str(i)+ " is super")
Example input and output:
enter integer: 500
1 is super
2 is super
145 is super
Small advice - you don't need to call str() in print() - int will be shown the same way anyway.
I haven't done much Python in a long time but I tried my own attempt at solving this problem which I think is more readable. For what it's worth, I'm assuming when you say "displays all numbers in range 0-N" it's an exclusive upper-bound, but it's easy to make it an inclusive upper-bound if I'm wrong.
import math
def digits(n):
return (int(d) for d in str(n))
def is_super(n):
return sum(math.factorial(d) for d in digits(n)) == n
def supers_in_range(n):
return (x for x in range(n) if is_super(x))
print(list(supers_in_range(150))) # [1, 2, 145]
I would create a lookup function that tells you the factorial of a single digit number. Reason being - for 888888 you would recompute the factorial of 8 6 times - looking them up in a dict is much faster.
Add a second function that checks if a number isSuper() and then print all that are super:
# Lookup table for single digit "strings" as well as digit - no need to use a recursing
# computation for every single digit all the time - just precompute them:
faks = {0:1}
for i in range(10):
faks.setdefault(i,faks.get(i-1,1)*i) # add the "integer" digit as key
faks.setdefault(str(i), faks [i]) # add the "string" key as well
def fakN(n):
"""Returns the faktorial of a single digit number"""
if n in faks:
return faks[n]
raise ValueError("Not a single digit number")
def isSuper(number):
"Checks if the sum of each digits faktorial is the same as the whole number"
return sum(fakN(n) for n in str(number)) == number
for k in range(1000):
if isSuper(k):
print(k)
Output:
1
2
145
Use range.
for i in range(number): # This iterates over [0, N)
if (breakdown(number)) == number:
print(str(number)+ " is super")
If you want to include number N as well, write as range(number + 1).
Not quite sure about what you are asking for. From the two functions you write, it seems you have solid knowledge about Python programming. But from your question, you don't even know how to write a simple loop.
By only answering your question, what you need in your main function is:
for i in range(0,number+1):
if (breakdown(i)) == i:
print(str(i)+ " is super")
import math
def get(n):
for i in range(n):
l1 = list(str(i))
v = 0
for j in l1:
v += math.factorial(int(j))
if v == i:
print(i)
This will print all the super numbers under n.
>>> get(400000)
1
2
145
40585
I dont know how efficient the code is but it does produce the desired result :
def facto():
minr=int(input('enter the minimum range :')) #asking minimum range
maxr=int(input('enter the range maximum range :')) #asking maximum range
i=minr
while i <= maxr :
l2=[]
k=str(i)
k=list(k) #if i=[1,4,5]
for n in k: #taking each element
fact=1
while int(n) > 0: #finding factorial of each element
n=int(n)
fact=fact*n
n=n-1
l2.append(fact) #keeping factorial of each element eg : [1,24,120]
total=sum(l2) # taking the sum of l2 list eg 1+24+120 = 145
if total==i: #checking if sum is equal to the present value of i.145=145
print(total) # if sum = present value of i than print the number
i=int(i)
i=i+1
facto()
input : minr =0 , maxr=99999
output :
1
2
145
40585

print factors of a number in python

I'm trying to print the factors of the number 20 in python so it goes:
20
10
5
4
2
1
I realize this is a pretty straightforward question, but I just had a question about some specifics in my attempt. If I say:
def factors(n):
i = n
while i < 0:
if n % i == 0:
print(i)
i-= 1
When I do this it only prints out 20. I figure there's something wrong when I assign i=n and then decremented i, is it also affecting n? How does that work?
Also I realize this could probably be done with a for loop but when I use a for loop I can only figure out how to print the factors backwards so that I get: 1, 2, 5, 10....
Also I need to do this using just iteration. Help?
Note: This isn't a homework question I'm trying to relearn python on my own since it's been a while so I feel pretty silly being stuck on this question :(
while i < 0:
This will be false right from the start, since i starts off positive, presumably. You want:
while i > 0:
In words, you want to "start i off at n, and decrement it while it is still greater than 0, testing for factors at each step".
>>> def factors(n):
... i = n
... while i > 0: # <--
... if n % i == 0:
... print(i)
... i-= 1
...
>>> factors(20)
20
10
5
4
2
1
The while condition should be i > 0 and not i < 0 because it will never satisfy it as i begins in 20 (or more in other cases)
Hope my answer helps!
#The "while True" program allows Python to reject any string or characters
while True:
try:
num = int(input("Enter a number and I'll test it for a prime value: "))
except ValueError:
print("Sorry, I didn't get that.")
continue
else:
break
#The factor of any number contains 1 so 1 is in the list by default.
fact = [1]
#since y is 0 and the next possible factor is 2, x will start from 2.
#num % x allows Python to see if the number is divisible by x
for y in range(num):
x = y + 2
if num % x is 0:
fact.append(x)
#Lastly you can choose to print the list
print("The factors of %s are %s" % (num, fact))

Print statements in a for loop

I am working on a function which takes a positive integer N and computes the following sum:
1 - 2 + 3 - 4 + 5 - 6 + .... N.
My professor said we can not use "math formulas" on this, so how could I go about it?
I thought about using a for loop, but I don't know how or what to write for the print statement. This is what I have so far:
n=int(input("enter N="))
for i in range(1, n+1, 1):
if i % 2 == 0:
# I'm not sure what print statement to write here
I tried print(i= "+" i+1) and just weird stuff like that, but I get errors and am lost after that.
what i have now
n=int(input('enter N='))
total=0
print("sum",)
for i in range(1, n+1, 1):
if i % 2 == 0:
count=count - i
print("-", i)
else:
count=count + i
print("+", i, end=" ")
print("=", total)
#still get errors saying name count not defined and unsupported sperand for +:
First, to accumulate the sum as described, and to do it by looping instead of "using math formulas", you want to do this:
n=int(input("enter N="))
total = 0
for i in range(1, n+1, 1):
if i % 2 == 0:
????
else:
????
print(total)
You should be able to figure out what the ???? are: you need to do something to total for each i, and it's different for even and odd.
Now, if you want it to print out something like this:
sum 1 - 2 + 3 - 4 + 5 - 6 + .... N = X
You can print things out along the way like this:
n=int(input("enter N="))
total = 0
print ("sum", end=" ")
for i in range(1, n+1, 1):
if i % 2 == 0:
print("-", i, end=" ")
????
else:
if i == 1:
print(i, end=" ")
else:
print("+", i, end=" ")
????
print("=", total)
If you want to keep negative and positive totals separately and then add them, as you mentioned in an edit, change total = 0 to ntotal, ptotal = 0, 0, then change each of the ???? parts so one works on one total, one on the other.
All of the above is for Python 3. If you want to run it in Python 2, you need to turn those print function calls into print statements. For the simple cases where we use the default newline ending, that's just a matter of removing the parentheses. But when we're using the end=" ", Python 2's print statement doesn't take keyword parameters like that, so you instead have to use the "magic comma", which means to end the printout with a space instead of a newline. So, for example, instead of this:
print("+", i, end=" ")
You'd do this:
print "+", i,
Again, for Python 3, you don't have to worry about that. (Also, there are ways to make the exact same code run in both Python 2 and 3—e.g., use sys.stdout.write—which you may want to read up on if you're using both languages frequently.)
You're most of the way there already. I'm not sure why you think you need to put a print statement inside the loop, though. You only want one result, right? You already have if i % 2 == 0 - which is the case where it's even - and you want to either add or subtract based on whether the current i is odd or even. So keep a running tally, add or subtract in each loop iteration as appropriate, and print the tally at the end.
You see the difference between what happens with odd and even numbers, which is good.
So, as you cycle through the list, if the number is even, you do one operation, or else you do another operation.
After you've computed your result, then you print it.
There are a lot of explanations in the answers already here. So I will try to address the different ways in which you can compute this sum:
Method 1:
def mySum(N):
answer = 0
for i in range(1, N+1):
if i%2:
answer += i
else:
answer -= i
return answer
Method 2:
def mySum(N):
answer = 0
for i in range(1, N+1, 2):
answer += i
for i in range(2, N+1, 2):
answer -= i
return answer
Method 3:
def mySum(N):
pos = range(1, N+1, 2)
neg = range(2, N+1, 2)
return sum(pos) - sum(neg)
Method 4:
def mySum(N):
return sum([a-b for a,b in zip(range(1, N+1, 2), zip(2, N+1, 2))])
Method 5:
def mySum(N):
return sum([i*-1 if not i%2 else i for i in range(1,N+1)])
Method 6:
def mySum(N):
return sum(map(lambda n: n*[-1, 1][i%2], range(1, N+1)))
Again, these are only to help prime you into python. Others have provided good explanations, which this is not meant to be
count = 0
print "0"
for i in range(1, n+1, 1):
if i % 2 == 0:
count = count - i
print "-" , i
else:
count = count + i
print "+" , i
print "=", count

Categories