Addition binary numbers [closed] - python

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I need a help of my code, i have make addition of passing two variable of two binary numbers and the answer is incorrect!
in my code
import data as s
s.num
s.demo
def add_binary_nums(x,y):
max_len = max(len(x), len(y))
x = x.zfill(max_len)
y = y.zfill(max_len)
result = ''
carry = 0
for i in range(max_len-1, -1, -1):
r = carry
r += 1 if x[i] == '1' else 0
r += 1 if y[i] == '1' else 0
result = ('1' if r % 2 == 1 else '0') + result
carry = 0 if r < 2 else 1
if carry !=0 : result = '1' + result
return result.zfill(max_len)
print("start here")
demoo = (add_binary_nums(s.num,s.demo))
print(demoo)
assume the values as num="011000100110111101100010" and demo="001" and the answer of above code is 011000100110111101100110 , and it's wrong answer! when i pass the value like
num="011000100110111101100010"
demo="001"
i got the the answer 01111011000010110011101010 .
and fpr passing the value like
print(add_binary_nums('001', '001'))
the result will be 01100010011011110110010 i'm getting 3 different results!!
Any suggestion!

space not effect, i remove the space and the answer is same wrong
I tried your script and found out you have an extra space on the right side of your value variable. If you remove it, it should work (returns 010). I would recommend to trim your input values before proceeding with the algorithm.
value = value.strip()
If you just interested in the result but not in implementation (May be you are trying to learn something new or it is an assignment), you can first convert the binary numbers to int and add them and again convert back to binary string.
See this code:
value = '001 '
demo = '001'
def add_binary_nums(x,y):
x_int = int(x, 2)
y_int = int(y, 2)
result = x_int + y_int
return '{0:08b}'.format(result)
print(add_binary_nums(value, demo))
Output:
00000010
To understand '{0:08b}'.format(result), visit this link.
EDIT:
thx, for sure i care about the implementation, its not assignemt or homework to convert numbers into binary, and the code above its peace of my program, im passing many variables have binary number i give u one example , when i pass variable from other python code, assume , n="011000100110111101100010" and m="0001", when i run the code , its shows wrong answer!, remember i'm pass variable and i got result 011000100110111101100110 !
Try the code below. I am getting the right results with python3.
value = '011000100110111101100010'
demo = '0001'
def add_binary_nums(x,y):
x=x.strip()
y=y.strip()
max_len = max(len(x), len(y))
print("Max: %d X: %s Y %s" %(max_len, x, y))
x = x.zfill(max_len)
y = y.zfill(max_len)
result = ''
carry = 0
print("X: %s Y: %s" % (x, y))
for i in range(max_len-1, -1, -1):
print(i)
r = carry
r += 1 if x[i] == '1' else 0
r += 1 if y[i] == '1' else 0
result = ('1' if r % 2 == 1 else '0') + result
carry = 0 if r < 2 else 1
if carry !=0 : result = '1' + result
return result.zfill(max_len)
demoo = (add_binary_nums(demo, value))
print(demoo)

The problem only exists with the trailing space. When running the code with trailing space it produces the output 0011, when running the code without the trailing space produces the output 010
The reason this occurs is due to the space and how you use zfill. If we look at the data when there is a trailing space on one of them.
if we assume x="001" and y='001 ' then max_len will be set as 4 since y has 4 chars in it. you then do zfill on x and zfill on y. this will pad x with an extra leading 0 to make it 4 chars. It will have no effect on y since its already 4 chars. So you will end up with
x="0001"
y="001 "
As you can see these are now not in the same representation. So when you start to do your calculations your first iteration on index 3 will be comparing the "1" from x and the space char from y. You code says if its not a 1 then its a 0. since space isnt a 1 then you default it to a 0.
So your essentially treating it like
x="0001"
y="0010"
and the result of that would indeed correctly be "0011"
So the issue is 100% with your space in the string. I would suggest either validate your input to the function to be sure it contains only 1s or 0s if it doesnt raise a ValueError. Or at a minimum call strip method of string to remove any leading or trailing spaces from the string.

Look at how you initialized your variables (empty space, quotes). Seems off to me for a binary representation...
value = '001 '
demo = "001"

Just use python binary literals: How do you express binary literals in Python?
Rewrite print(add_binary_nums(value, demo)) as print(bin(int(value, 2), int(demo, 2)))

running your code leaves me with the result 0011 not as you mentioned 001001. Leaving out the space in the first "value" variable leaves me with the result 010.
Hope this helps!
Edit: I also would suggest to just add the numbers in int-mode and then convert the int back to binary if you insist in having the space and the input as you have.

Related

Convert x digit number into two digit number

I am currently having x number in a list, and I am trying to convert inconsistent data that may be in 1 digit, 5 digit or 2 digit.
How can I convert all into 2 digit number?
Example:
def List_Convert_2_Digit(z):
for i in range(len(z)):
while(z[i]<100 or z[i]>10):
if(z[i]<100):
z[i]=z[i]/10
else:
z[i]=z[i]*10
return z
list_a = [5.2,1600,520,3600,13,55,4000]
result_list= List_Convert_2_Digit(list_a)
Result should yields: [52,16,52,36,13,55,40]
But the above code does not work and it's running forever.
I've tried mod, but it is not what I am looking for.
It looks like you just want to take the first two characters from each, and if there is a separator (dot in your case) ignore it.
In that case you can do this:
two_digit_list = [int(str(x).replace('.', '')[:2]) for x in List]
If other non numeric characters than a dot are going to appear your would have to deal with those as well of course :)
What this does is just converts the numbers to a string, removes dots and then grabs the first two characters and converts it back to an int.
EDIT: Since I saw you replied to someone above that single digit numbers should have 0 added to the end you can do this instead to cover that case:
two_digit_list = [int(str(x).replace('.', '')[:2]) if len(str(x).replace('.', '')) > 1 else int(f"{x}0") for x in List]
At that point it's a bit too long to be a pretty list comprehension so you could always just break it up into a for loop if it's unclear, might be a good exercise if nothing else :)
This is a simple solve to this.
yield_list = []
number_list = [5.2,1600,520,3600,13,55,4000]
for number in number_list:
string = str(number)
string =string.replace('.', '')
yield_list.append(string[:2])
yield_list
There is an error in your logic; your < and > are flipped. This code works:
def List_Convert_2_Digit(z):
for i in range(len(z)):
while(z[i]>100 or z[i]<10):
if(z[i]>100):
z[i]=z[i]/10
else:
z[i]=z[i]*10
return z
Solution that increases/decreases the numbers magnitude until we can get the left two digits:
def two_digit_list(lst):
rv = []
for item in lst:
if item < 10:
item *= 10
while item > 99:
item //= 10
rv.append(int(item))
return rv

Don't quite understand logic of this nested loop - can't revise

I was looking for previously answered questions regarding finding repeated substrings in an array, and came across https://cs.stackexchange.com/questions/79182/im-looking-for-an-algorithm-to-find-unknown-patterns-in-a-string. It does exactly what I want, except it analyzes a single string (and finds repetitions of single characters), whereas I'd like to analyze an array (with integers, some exceeding 9). I can't accomplish this with the code as is, because for example "10" would be understood as "1" and "0".
So instead of the example "ABACBABAABBCBABA", I'd want to analyze [A, B, A, C...]. More to the point, I'd eventually want to work with integers [1, 4, 3, 1, 4...]
I've tried modifying the code, however I don't think I fully understand the logic of the nested loop. Could anyone please help?
I've been doing some work on the original problem, I still don't understand the reason for the outer loop, but I've managed to mimic the original reference script (for arrays instead of strings).
I wanted to post it in case someone else may find use for it. I'm sure it's not the most efficient way, but it seems to work. If anyone sees holes in it, by all means please advise:
def countSubs(total, sub):
totalCount = 0
for i in range(len(total) - len(sub) + 1):
testCount = 0
for j in range(len(sub)):
if sub[j] == total[i + j]:
testCount += 1
if testCount == len(sub):
totalCount += 1
return totalCount
minLength = 3
minCount = 2
test = [1,2,1,3,2,-1,2,-1,2,4,2,4,2,5,2,5,2,5,6,7,-1,7,-1,8,7,6,-1,9,-1,9,8,7,10]
rectDict = {}
for sublen in range(minLength, int(len(test)/minCount)):
for i in range(0, len(test) - sublen):
sub = test[i:i + sublen]
cnt = countSubs(test, sub)
#not necessary to concatenate with commas, but for visual legibility
subText = ''.join(str(e) + ',' for e in sub)
if cnt >= minCount and subText not in recDict:
recDict[subText[:-1]] = cnt
print(rectDict)

Read Bits for definded length at defined position

I have a bitstring.Bitarray and want to read from a certain position to another position.
I have the int variable length in a for loop, so for example I have:
length = 2
and my Bitarray looks something like:
msgstr = bitstring.BitArray(0b11110011001111110)
id = bitstring.BitArray()
m = 0
while 5 != m:
/////////////
Length changes in value part of Code
/////////////
x = 0
if m == 0:
while length != x:
id.append = msgstr[x] #msgstr is the BitArray that needs to be read
x = x + 1
m = m + 1
I then want to read the first two bits and convert them into an int, so that I have:
id == 3
And for the next round when length has changed in value it should start from the third bit etc.
The code inside your loop only does anything if m == 0, but then you increment m, so m is only 0 the first time through the loop. The rest of the times you go through your loop, it doesn't seem to actually be doing anything.
Also, where you say
id.append = msgstr[x]
you probably actually want
id.append(msgstr[x])
It also seems like you might benefit from using Python's slice notation.
I do not understand exactly what you goal is but do you had a look at https://wiki.python.org/moin/BitManipulation ?

how to make an imputed string to a list, change it to a palindrome(if it isn't already) and reverse it as a string back

A string is palindrome if it reads the same forward and backward. Given a string that contains only lower case English alphabets, you are required to create a new palindrome string from the given string following the rules gives below:
1. You can reduce (but not increase) any character in a string by one; for example you can reduce the character h to g but not from g to h
2. In order to achieve your goal, if you have to then you can reduce a character of a string repeatedly until it becomes the letter a; but once it becomes a, you cannot reduce it any further.
Each reduction operation is counted as one. So you need to count as well how many reductions you make. Write a Python program that reads a string from a user input (using raw_input statement), creates a palindrome string from the given string with the minimum possible number of operations and then prints the palindrome string created and the number of operations needed to create the new palindrome string.
I tried to convert the string to a list first, then modify the list so that should any string be given, if its not a palindrome, it automatically edits it to a palindrome and then prints the result.after modifying the list, convert it back to a string.
c=raw_input("enter a string ")
x=list(c)
y = ""
i = 0
j = len(x)-1
a = 0
while i < j:
if x[i] < x[j]:
a += ord(x[j]) - ord(x[i])
x[j] = x[i]
print x
else:
a += ord(x[i]) - ord(x[j])
x [i] = x[j]
print x
i = i + 1
j = (len(x)-1)-1
print "The number of operations is ",a print "The palindrome created is",( ''.join(x) )
Am i approaching it the right way or is there something I'm not adding up?
Since only reduction is allowed, it is clear that the number of reductions for each pair will be the difference between them. For example, consider the string 'abcd'.
Here the pairs to check are (a,d) and (b,c).
Now difference between 'a' and 'd' is 3, which is obtained by (ord('d')-ord('a')).
I am using absolute value to avoid checking which alphabet has higher ASCII value.
I hope this approach will help.
s=input()
l=len(s)
count=0
m=0
n=l-1
while m<n:
count+=abs(ord(s[m])-ord(s[n]))
m+=1
n-=1
print(count)
This is a common "homework" or competition question. The basic concept here is that you have to find a way to get to minimum values with as few reduction operations as possible. The trick here is to utilize string manipulation to keep that number low. For this particular problem, there are two very simple things to remember: 1) you have to split the string, and 2) you have to apply a bit of symmetry.
First, split the string in half. The following function should do it.
def split_string_to_halves(string):
half, rem = divmod(len(string), 2)
a, b, c = '', '', ''
a, b = string[:half], string[half:]
if rem > 0:
b, c = string[half + 1:], string[rem + 1]
return (a, b, c)
The above should recreate the string if you do a + c + b. Next is you have to convert a and b to lists and map the ord function on each half. Leave the remainder alone, if any.
def convert_to_ord_list(string):
return map(ord, list(string))
Since you just have to do a one-way operation (only reduction, no need for addition), you can assume that for each pair of elements in the two converted lists, the higher value less the lower value is the number of operations needed. Easier shown than said:
def convert_to_palindrome(string):
halfone, halftwo, rem = split_string_to_halves(string)
if halfone == halftwo[::-1]:
return halfone + halftwo + rem, 0
halftwo = halftwo[::-1]
zipped = zip(convert_to_ord_list(halfone), convert_to_ord_list(halftwo))
counter = sum([max(x) - min(x) for x in zipped])
floors = [min(x) for x in zipped]
res = "".join(map(chr, floors))
res += rem + res[::-1]
return res, counter
Finally, some tests:
target = 'ideal'
print convert_to_palindrome(target) # ('iaeai', 6)
target = 'euler'
print convert_to_palindrome(target) # ('eelee', 29)
target = 'ohmygodthisisinsane'
print convert_to_palindrome(target) # ('ehasgidihmhidigsahe', 84)
I'm not sure if this is optimized nor if I covered all bases. But I think this pretty much covers the general concept of the approach needed. Compared to your code, this is clearer and actually works (yours does not). Good luck and let us know how this works for you.

Why do I get a 'valueError' despite explicitly returning the expected number of values?

This is merge sort tweaked to count inversions. My code throws an odd error
(I'm implementing algos to learn python 3.x).
In line 11,
in merge_sort first_sorted_half, x = merge_sort(arr[:half])
[Previous line repeated 12 more times] ValueError: not enough values
to unpack (expected 2, got 1)
Even though I explicitly return two values? I'm new to python 3 so I'd like to understand exactly what's going on here, I can't seem to find a similar issue anywhere. A link to python docs for more on this would also be appreciated!
def merge_sort(arr):
if len(arr) <= 1:
return arr
half = int(len(arr)/2)
first_sorted_half, x = merge_sort(arr[:half])
second_sorted_half, y = merge_sort(arr[half:])
merged_halves, z = merge(first_sorted_half, second_sorted_half)
return merged_halves, x + y + z
def merge(first_half, second_half):
n = len(first_half) + len(second_half)
i = 0
j = 0
split_inversions = 0
ans = []
for k in range(n):
if i >= len(first_half):
ans.append(second_half[j])
j += 1
continue
if j >= len(second_half):
ans.append(first_half[i])
i += 1
continue
if first_half[i] > second_half[j]:
ans.append(second_half[j])
j += 1
split_inversions += len(first_half) - i
elif first_half[i] < second_half[j]:
ans.append(first_half[i])
i += 1
return ans, split_inversions
numbers = [3,2,1,4,5,6,8,10,9]
print(merge_sort(numbers))
The error you are getting says that your program executed that recursive call 12 times, and at the end it couldn't unpack the result.
What that means is, python expects you to return two values from merge_sort, because you unpack the result into first_sorted_half and x. However, when you return only arr from the condition len(arr) <=1, there is no value to unpack, only there exists the array.
So how you fix that is returning a value for the base case, like return arr, len(arr).
Whilst ilke444 is right - a bit more clarification is needed. To start: returning data variables is what you need but I do not know much about the len(arr) <=1 , and I am quite new to stackflow, I do not know this feature of Python 3. I specialize in Pygame/ standard packages.
First thing - arr in this "Code Snippet" (If it is) is not defined; and/or will need to be defined. Len stands for length as you know - and uses a quote (' ') to use it.
Like so:
len('arr')
would print:
3
because there are 3 Characters in this set. You are obviously new to python 3 as you said because the syntax is slightly different.
As this probably only solves the first bit - with this info I will leave you with 1 thing more.
Call to print requires a quote (' '),
Lists have [ ] Brackets instead of (),
Dictionaries have {} brackets and variables now require definition either by variable definition or function unless put in quote marks.
Thanks,
Jerry

Categories