I am working on an encryption puzzle and am needing to take the exclusive or of two binary numbers (I'm using the operator package in Python). If I run operator.xor(1001111, 1100001) for instance I get the very weird output 2068086. Why doesn't it return 0101110 or at least 101110?
Because Python doesn't see that as binary numbers. Instead use:
operator.xor(0b1001111, 0b1100001)
The calculated answer is using the decimal values you provided, not their binary appearance. What you are really asking is...
1001111 ^ 1100001
When you mean is 79 ^ 97. Instead try using the binary literals as so...
0b1001111 ^ 0b1100001
See How do you express binary literals in Python? for more information.
Because 1001111 and 1100001 are not binary numbers. 1001111 is One million, one thousand, one hundred and eleven, while 1100001 is One million, one hundred thousands and one. Python doesn't recognize these as binary numbers. Binary numbers have to be prefixed with 0b to be recognized as binary numbers in Python/Python 3. So the correct way is this:
operator.xor(0b1001111, 0b1100001)
But hey! We get 46 as output. We should fix that. Thankfully, there IS a built-in in Python/Python 3. It's the function bin(n). That function prints a number a binary, prefixed with 0b. So our final code would be:
bin(operator.xor(0b1001111, 0b1100001))
If we want to hide the 0b (mostly in cases where that number is printed to the screen), we should use [2:] like this:
bin(operator.xor(0b1001111, 0b1100001))[2:]
A shorter way (warning looks like a tutorial for something you *should* already know)
Well, operator.xor() is too big for an operator :)
If that is the case (99.9%), instead you should use a^b. I think you already know this but why to import a whole module just for the xor operator? If you like to type the word xor instead, import the operator module like this: from operator import a, b.... Then use like this: bin(xor(a,b)). I hope you already know that stuff but I want to make sure you enjoy coding even more :)
Related
I would like to create a function which gives the following things
32_bit_binary(-1) should be '11111111111111111111111111111111'
32_bit_binary(1) should be '00000000000000000000000000000001'
Now I gave the following code
def 32_bit_binary(num_bits):
return '{:032b}'.format(num_bits)
But when I gave this
print(32_bit_binary(-1))
it came -00000000000000000000000000000001
What is wrong with the code?
As #gspr said, formatting as base 2 doesn’t give you the actual representation. You can solve it by masking the negative integer, which has infinitely many leading 1s for the purposes of bitwise operations, down to 32 bits:
return f"{num_bits & 0xffff_ffff:032b}"
String formatting like {:032b} does not give you the actual representation of the number. It just writes the number in base-2. That's a purely mathematical operation. Implementation details like how the computer represents said number (like using binary, using 2's complement for negative numbers, etc.) are not in the scope of those string formatting operations.
A good way to get at the actual representations of values in Python is the struct module. For example, struct.pack("#i", -1) returns the bytestring b'\xff\xff\xff\xff'. Printing that bytestring in binary is left as an exercise to the reader.
PS: For numbers other than -1, you may be surprised by the output of struct.pack. The term you'll want to look up is endianness, and the # in my struct.pack formatting string.
When i am tring this:
>>> "a".__add__("b")
'ab'
It is working. But this
>>> 1.__add__(2)
SyntaxError: invalid syntax
is not working.
And this is working:
>>> 1 .__add__(2) # notice that space after 1
3
What is going here? Is it about variable naming rules and is python thinks I am trying to create variable when I am not using space?
Python parser is intentionally kept dumb and simple. When it sees 1., it thinks you are midway through a floating point number, and 1._ is not a valid number (or more correctly, 1. is a valid float, and you can't follow a value by _: "a" __add__("b") is also an error). Thus, anything that makes it clear that . is not a part of the number helps: having a space before the dot, as you discovered (since space is not found in numbers, Python abandons the idea of a float and goes with integral syntax). Parentheses would also help: (1).__add__(2). Adding another dot does as well: 1..__add__(2) (here, 1. is a valid number, then .__add__ does the usual thing).
The python lexical parser tries to interpret an integer followed by a dot as a floating point number. To avoid this ambiguity, you have to add an extra space.
For comparison, the same code works without problem on a double:
>>> 4.23.__add__(2)
6.23
It also works if you put the int in parentheses:
>>> (5).__add__(4)
9
When you use 1. the interpreter think you started writing float number (you can see in the IDE (atleast Pycharm) the dot is blue, not white). The space tell it to treat 1. as a complete number, 1.0. 1..__add__(2) will also do the trick.
I am trying to create a binary number that contains a fraction. Something like this:
0b110.101
However, this gives a syntax error.
0b110
works fine though. How do you create a binary number that is not an integer?
How do you create a binary number that is not an integer?
Binary is a text representation of a number. String are used to store text, so one would use something like the following:
"110.101"
But I think you misstated your question. You don't want the binary representation of a number, you want the number itself. 110.1012 represents the number six and five eight. There are infinite ways to create create that number, including the following:
6 + 5/8
6.625
That said, I suspect you'd prefer to see the binary representation of the number in the source. Unfortunately, Python does not have decimal binary number literals. You could use
0b110101 / (1>>3)
bin_to_num("110.101")
Writing bin_to_num is left as an exercise to the reader.
You use the Binary fractions package.
This let's you convert binary-fraction strings into numbers and vice-versa
Example:
>>> from binary_fractions import Binary
>>> str(Binary(6.625))
'0b110.101'
>>> float(Binary("0b110.101"))
6.625
It has many more helper functions to manipulate binary strings such as: shift, add, fill, to_exponential, invert...
PS: Shameless plug, I'm the author of this package.
Hello my fellow coders!
I'm an absolute beginner to Python and coding in general. Right now, I'm writing a code that converts regular arabic numerals to roman. For numbers larger than 3 999, the romans usually wrote a line over a letter to make it thousand times larger. For example, IV with a line over it represented 4 000. How is this possible in Python? I have understood that you can create an "overscore" by writing "\u203E". How can I make this appear over a letter instead of beside it?
Regards
You need to use the combining character U+0304 instead.
>>> print(u'a\u0304')
ā
U+0305 is probably a better choice (as viraptor suggests). You can also use the Unicode Roman numerals (U+2160 through U+217f) instead of regular uppercase Latin letters, although (at least in my terminal) they don't render as well with the overline.
>>> print(u'\u2163\u0305')
Ⅳ̅
>>> print u'I\u0305V\u0305'
I̅V̅
(Or as I see it:
Notice the overline is centered over, but does not completely cover, the single-character Roman numeral 4.)
(Any pure text option will only be as good as the font and renderer used by the person running the code. Case in point, the I+V version does not even display consistently while I type this; sometimes the overbars are over the letters, sometimes they follow the letters.)
A combining overline is \u305 and it works quite well with "IV". What you want is for example: u'I\u0305V\u0305' (gives I̅V̅)
I looked for something online but didn't find it. The best workaround I'd suggest would be the following:
def over(character):
return "_\n"+character
Such as:
>>> print over("M")
_
M
>>>
I am trying to write a method in Python 3.2 that encrypts a phrase and then decrypts it. The problem is that the numbers are so big that when Python does math with them it immediately converts it into scientific notation. Since my code requires all the numbers to function scientific notation, this is not useful.
What I have is:
coded = ((eval(input(':'))+1213633288469888484)/2)+1042
Basically, I just get a number from the user and do some math to it.
I have tried format() and a couple other things but I can't get them to work.
EDIT: I use only even integers.
In python3, '/' does real division (e.g. floating point). To get integer division, you need to use //. In other words 100/2 yields 50.0 (float) whereas 100//2 yields 50 (integer)
Your code probably needs to be changed as:
coded = ((eval(input(':'))+1213633288469888484)//2)+1042
As a cautionary tale however, you may want to consider using int instead of eval:
coded = ((int(input(':'))+1213633288469888484)//2)+1042
If you know that the floating point value is really an integer, or you don't care about dropping the fractional part, you can just convert it to an int before you print it.
>>> print 1.2e16
1.2e+16
>>> print int(1.2e16)
12000000000000000