I am trying to define a function to convert a binary number to a decimal number and check if it is an absolute square or not. I am passing a list of binary numbers as the argument and the function is supposed to print "True" or "False" as the output in the same order as that of the list elements; depicting whether or not they are absolute squares.
While trying so I am getting a syntax error in the ninth line where I am trying to calculate the decimal equivalent of the binary digits by adding the individual values arising out of each binary digit owing to it's position.
Logic of Execution: 1001 in Binary means [pow(2,3)*1 + pow(2,2)*0 + pow(2,1)*0 + pow(2,0)*1] in Decimal. It's equal to 9 which is an absolute square of 3. So the output should be "True"
import math
n = int(input("Enter the total no of elements to check: "))
num_list = []
for k in range (n):
print("Enter the number at position "+str(k)+" : ")
num = int(input())
num_list.append(num)
#print(num_list) for debugging purpose
def Binary_SquareRoot_Checker(input_list):
for i in input_list:
q = str(i)
no_of_digit = len(q)
#For each element of the list, we need to count the no of digits present
addition_num = 0
for p in range (no_of_digit):
r = q[p]
value = (2**(no_of_digit - (p+1)) * int(r)
addition_num = addition_num + value
#print(addition_num) just to see the decimal number
root = math.sqrt(sum_num)
if int(root + 0.5) ** 2 == sum_num:
#Checking for absolute square property
print("True")
else:
print("False")
Binary_SquareRoot_Checker(num_list)
I am getting Syntax Error at addition_num = addition_num + value
Please tell me why this error is being reported?
In the 20th line, change:
value = (2**(no_of_digit - (p+1)) * int(r)
To:
value = (2**(no_of_digit - (p+1)) * int(r) )
Related
I encountered an issue with my Python script that converts binary to decimals. The caveat with this script is that I can only use basic computational functions (+, -, *, /, **, %, //), if/else, and for/while loops.
Shown below is my script:
x = int(input("Enter your binary input: "))
z=0
while x != 0:
for y in range (0,20):
if (x % 2 == 0):
z += 0*2**y
x = int(x/10)
elif (x % 2 != 0):
z += 1*2**y
x = int(x/10)
print(z)
While my script works for binaries with short length (e.g., 1101 = 13), it does not work for long binaries (especially those that have a length of 20). For example, inputting a binary of 11111010010011000111, my script returns an output of 1025217 instead of 1025223.
Can anyone point me to my mistake?
Thank you in advance!
Floating arithmetic isn't perfect and has a precision limit.
11111010010011000111 / 10 gives 1.1111010010011e+18, which when converted to an integer will give you a wrong result and it snowballs from there.
>>> int(11111010010011000111 / 10)
1111101001001100032
The more binary digits you have, the more "off" your calcuations will be.
In order to avoid the problem you encountered, use floor division, ie, x // 10.
Or you can skip turning x into a number and do the necessary power calculations based off each binary digit and its position.
x = input("Enter your binary input: ")[::-1]
n = 0
# this would be more elegant with `enumerate()`, but I assume you can't use it
# same for `sum()` and a comprehension list
for i in range(len(x)):
n += int(x[i])*2**i
print(n)
You can use the following method
to multiple each of the binary digits with its corresponding value of 2 raised to the power to its index (position from right – 1) and sum them up.
binary = input('Binary number: ')
decimal = 0
binary_len = len(binary)
for x in binary:
binary_len = binary_len - 1
decimal += pow(2,binary_len) * int(x)
print(decimal)
input : 11111010010011000111
output : 1025223
More examples
You should not use int to convert any number if you have to write a number converter.
Just use string operations:
digits = input("Enter your binary input: ")
number = 0
for digit in digits:
number = number * 2 + (digit == "1")
print(number)
output
Enter your binary input: 11111010010011000111
1025223
This question already has answers here:
Sum the digits of a number
(11 answers)
Closed 10 months ago.
A simple python code for getting sum of every digit in n integer. I tried a while to get the number of digit and for loop to get the sum. Sometime it's working. But sometime it's giving one less. like 22222 should be 10. But i am getting 9.
import math
def number_adder():
number = int(input('Enter a natural number: ', )) #Inputs user value. Specifically a natural number
sum = 0
number_of_digit = 0
for digit in str(number):
number_of_digit += 1 # getting number of digit in the input value
number = number * 10 ** (-number_of_digit + 1)
sum += math.floor(number)
number -= math.floor(number)
for digit in range(number_of_digit - 1):
number = number * 10
sum += math.floor(number)
number -= math.floor(number)
print('The sum of all digits of the value is, ', sum)
number_adder()
You are making this way too complicated.
Just do:
>>> n=22222
>>> sum(int(x) for x in str(n))
10
And
>>> n=12345
>>> sum(int(x) for x in str(n))
15
Explanation:
sum(int(x) for x in str(n))
^ turn the number into a string
^ strings are iterable character by character
^ ^ ^ a comprehension loop to loop over those
^ ^ ^ characters
^ each character assigned to x
^ turn x back into a integer
^ sum all those digits together
Here is a less terse example:
n=123456
total=0
for ch in str(n):
print(f'{ch:>3}')
total+=int(ch)
print(f'===\n{total:>3}')
Prints:
1
2
3
4
5
6
===
21
You could do it even more compactly by using the map() function which in this case, applies the int function to every string representation of each digit, then each int digit is being summed by the sum() function.
Sidenote: Please don't use sum as a variable name because it's a built-in function, and you are shadowing it.
def number_adder():
#Inputs user value. Specifically a natural number
number = int(input('Enter a natural number: '))
num_sum = sum(map(int, str(number)))
print('The sum of all digits of the value is', num_sum)
number_adder()
Output (with an input of 22222):
Enter a natural number: 22222
The sum of all digits of the value is 10
The problem
def number_adder():
# [...]
sum += math.floor(number)
number -= math.floor(number)
print(number)
# Prints: 0.22219999999999995
# [...]
I added a print statement to check the value of number out and given the input 22222 the output for number at that point was: 0.22219999999999995. That happens because Python doesn't execute floating point operations with infinite precision, so that's the most precise value it can get for the substraction given sum and number.
(Check Python error in basic subtraction? and Python error in basic subtraction? as examples).
Naturally, when looping through the decimals of number the following happens:
for digit in range(number_of_digit - 1):
number = number * 10
sum += math.floor(number)
number -= math.floor(number)
0.2221999...5 <-- Adds a 2
0.221999...5 <-- Adds a 2
0.21999...5 <-- Adds a 2
0.19999...5 <-- Adds a 1
And that's the reason why you get 9 as the final number (Adding up to the previous value of 2).
Possible solution:
Replace number -= math.floor(number) in the two lines that I point out with number = round(number - math.floor(number), number_of_digit - 1) to get back the original decimal values by rounding
import math
def number_adder():
# [...]
sum += math.floor(number)
# Round number to `number_of_digit - 1` decimals
# This will yield: `0.2222` for the original input `22222`
number = round(number - math.floor(number), number_of_digit - 1) # (1) <---
for digit in range(number_of_digit - 1):
number = number * 10
sum += math.floor(number)
# Round `number` again here as this is a new floating point operation
# (number_of_digit - digit - 2) are the remaining decimal points
number = round(number - math.floor(number), number_of_digit - digit - 2) # (2) <---
print("The sum of all digits of the value is, ", sum)
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
I want to write a program that can calculate the sum of an integer as well as count its digits . It will keep doing this until it becomes a one digit number.
For example, if I input 453 then its sum will be 12 and digit 3.
Then it will calculate the sum of 12=1+2=3 it will keep doing this until it becomes one digit. I did the first part but i could not able to run it continuously using While . any help will be appreciated.
def main():
Sum = 0
m = 0
n = input("Please enter an interger: ")
numList = list(n)
count = len(numList)
for i in numList:
m = int(i)
Sum = m+Sum
print(Sum)
print(count)
main()
It is not the most efficient way, but it doesn't matter much here; to me, this is a problem to elegantly solve by recursion :)
def sum_digits(n):
n = str(n)
if int(n) < 10:
return n
else:
count = 0
for c in n:
count += int(c)
return sum_digits(count)
print sum_digits(123456789) # --> 9 # a string
A little harder to read:
def sum_digits2(n):
if n < 10:
return n
else:
return sum_digits2(sum(int(c) for c in str(n))) # this one returns an int
There are a couple of tricky things to watch out for. Hopefully this code gets you going in the right direction. You need to have a conditional for while on the number of digits remaining in your sum. The other thing is that you need to covert back and forth between strings and ints. I have fixed the while loop here, but the string <-> int problem remains. Good luck!
def main():
count = 9999
Sum = 0
m = 0
n = input("Please enter an integer: ")
numList = list(n)
while count > 1:
count = len(numList)
for i in numList:
m = int(i)
Sum = m+Sum
print(Sum)
print(count)
# The following needs to be filled in.
numlist = ???
main()
You can do this without repeated string parsing:
import math
x = 105 # or get from int(input(...))
count = 1 + int(math.log10(x))
while x >= 10:
sum = 0
for i in xrange(count):
sum += x % 10
x /= 10
x = sum
At the end, x will be a single-digit number as described, and count is the number of original digits.
I would like to give credit to this stackoverflow question for a succinct way to sum up digits of a number, and the answers above for giving you some insight to the solution.
Here is the code I wrote, with functions and all. Ideally you should be able to reuse functions, and here the function digit_sum(input_number) is being used over and over until the size of the return value (ie: length, if sum_of_digits is read as a string) is 1. Now you can use the while loop to keep checking till the size is what you want, and then abort.
def digit_sum(input_number):
return sum(int(digit) for digit in str(input_number))
input_number = input("Please enter a number: ")
sum_of_digits = digit_sum(input_number)
while(len(str(sum_of_digits)) > 1):
sum_of_digits = digit_sum(input_number)
output = 'Sum of digits of ' + str(input_number) + ' is ' + str(sum_of_digits)
print output
input_number = sum_of_digits
this is using recursive functions
def sumo(n):
sumof = 0
while n > 0:
r = n%10 #last digit
n = n/10 # quotient
sumof += r #add to sum
if sumof/10 == 0: # if no of digits in sum is only 1, then return
return sumof
elif sumof/10 > 0: #else call the function on the sumof
sumo(sumof)
Probably the first temptation would be to write
while x > 9:
x = sum(map(int, str(x)))
that literally means "until there is only one digit replace x by the sum of its digits".
From a performance point of view however one should note that computing the digits of a number is a complex operation because Python (and computers in general) store numbers in binary form and each digit in theory requires a modulo 10 operation to be extracted.
Thus if the input is not a string to begin with you can reduce the number of computations noting that if we're interested in the final sum (and not in the result of intermediate passes) it doesn't really matter the order in which the digits are summed, therefore one could compute the result directly, without converting the number to string first and at each "pass"
while x > 9:
x = x // 10 + x % 10
this costs, from a mathematical point of view, about the same of just converting a number to string.
Moreover instead of working out just one digit however one could also works in bigger chunks, still using maths and not doing the conversion to string, for example with
while x > 99999999:
x = x // 100000000 + x % 100000000
while x > 9999:
x = x // 10000 + x % 10000
while x > 99:
x = x // 100 + x % 100
while x > 9:
x = x // 10 + x % 10
The first loop works 8 digits at a time, the second 4 at a time, the third two and the last works one digit at a time. Also it could make sense to convert the intermediate levels to if instead of while because most often after processing n digits at a time the result will have n or less digits, leaving while loops only for first and last phases.
Note that however the computation at this point is so fast that Python general overhead becomes the most important part and thus not much more can be gained.
You could define a function to find the sum and keep updating the argument to be the most recent sum until you hit one digit.
def splitSum(num):
Sum = 0
for i in str(num):
m = int(i)
Sum = Sum + m
return str(Sum)
n = input("Please enter an integer: ")
count = 0
while count != 1:
Sum = splitSum(n)
count = len(Sum)
print(Sum)
print(count)
n = Sum
decimal = input("Please insert a number: ")
if decimal > 256:
print "Value too big!"
elif decimal < 1:
print "Value too small!"
else:
decimal % 2
binary1 = []
binary0 = []
if decimal % 2 == 0:
binary1.append[decimal]
else:
binary0.append[decimal]
print binary1
print binary0
So Far, I want to test this code, it says on line 13:
TypeError: builtin_function_or_method' object has no attribute
__getitem__.
I don't understand why it is wrong.
I would like to convert the decimal number into binary. I only wanted to try and get the first value of the input then store it in a list to use then add it to another list as either a 0, or a 1. And if the input doesn't divide by 2 equally, add a zero. How would I do this?
binary1.append[decimal]
You tried to get an element from the append method, hence triggering the error. Since it's a function or method, you need to use the appropriate syntax to invoke it.
binary1.append(decimal)
Ditto for the other append call.
In response to your binary question. It is possible to brute-force your way to a solution quite easily. The thinking behind this is we will take any number N and then subtract N by 2 to the biggest power that will be less than N. For instance.
N = 80
2^6 = 64
In binary this is represented as 1000000.
Now take N - 2^6 to get 16.
Find the biggest power 2 can be applied to while being less than or equal to N.
2^4 = 16
In binary this now represented as 1010000.
For the actual code.
bList = []
n = int(raw_input("Enter a number"))
for i in range(n, 0, -1): # we will start at the number, could be better but I am lazy, obviously 2^n will be greater than N
if 2**i <= n: # we see if 2^i will be less than or equal to N
bList.append(int( "1" + "0" * i) ) # this transfers the number into decimal
n -= 2**i # subtract the input from what we got to find the next binary number
print 2**i
print sum(bList) # sum the binary together to get final binary answer