I'm working on this series of problems.
I do not understand question 11 and the way int() is being used. I understand that converting x directly into an int causes the loss of some zeroes so doing that was out of the question but I'm not understanding what
intp = int(p,2)
is suppose to be doing. Printing out intp I get the following values, 4,3,10,9. How is that at all related to 0100,0011,1010,1001? Also why are zeros lost in the first place?
Question 11
Level 2
Question: Write a program which accepts a sequence of comma separated
4 digit binary numbers as its input and then check whether they are
divisible by 5 or not. The numbers that are divisible by 5 are to be
printed in a comma separated sequence.
Example:
0100,0011,1010,1001
Then the output should be:
1010
Notes: Assume the data is input by console.
Hints: In case of input data being supplied to the question, it should
be assumed to be a console input.
value = []
items=[x for x in raw_input().split(',')]
for p in items:
print p
intp = int(p, 2)
print intp
if not intp%5:
value.append(p)
print ','.join(value)
To convert binary number into Decimal, we have to use the python built-in int function, which takes the binary number and the base of number system as an argument.
Example:
>>> p='1010'
>>> c=int(p,2)
>>> print c
10
int() function in Python and Python3 converts a number in a given base to decimal.
Syntax :int(string, base)
Parameter :
string: consists of 1's and 0's
base : (integer value) base of the number.
Returns :
Returns an integer value, which is equivalent
of binary string in the given base.
for more information Click here
As the grumpy comments up above suggested, the int function takes a second argument, which is the base of the conversion. So it's taking the base 2 (binary) variable bound to p and turning it to a base-10 int, i.e., normal human.
value = []
items=[x for x in input().split(',')]
for p in items:
intp = int(p, 2)
value.append(intp)
for x in value:
if x%5==0:
print(bin(x))
Related
import math
a = math.sqrt(25)
print(a)
My output is 5.0, how can I get a 5 (whole number) instead?
You have to check and explicitly convert to integer:
if x == (y := int(x)):
x = y
Or, without the assignment operator:
if x == int(x):
x = int(x)
As of python 3.8, you can use math.isqrt:
math.isqrt(25)
Keep in mind that this will always return an integer, even if the input is not a perfect square.
In a reduced manner, you can use a 1 line if operator to assign an integer value to the result of sqrt if both integer and decimal values are the same:
import math
a = math.sqrt(25)
a = int(a) if int(a)==a else a
print(a)
It depends a little on what exact behavior you want: do you want to just print the number without the decimal, or do you want to round a number to an integer?
For the print statement, Python tries to convert whatever is passed to it to a String in order to print it, and by default it gives floating point numbers decimal places. To stop that, we can use string formatting:
print("{:.0f}".format(a))
What this is doing is making a string (the double quotes "") that contains a special format marker (the curly braces {}). Inside the format marker is the code for the desired behavior (0 decimal places on a floating point number). Then we call the .format method of the string and pass the value (a) we want to be used inside the special format marker.
This looks somewhat arcane and ugly, but is the safest method to print what you want because it does not change 'a' and is easily customizable to other printing behaviors.
For rounding a number and converting it to an int, you can either use int() or round(): both will take in a float and output an integer that will print cleanly (and be an integer for future computation). There is no requirement for the thing being converted to actually be an integer but there is different behavior for the two functions: int returns the value of the first digit of a number, while round returns the rounded value (IE round(1.9) -> 2, int(1.9) -> 1, etc).
I have created the following snippet of code and I am trying to convert my 5 dp DNumber to a 2 dp one and insert this into a string. However which ever method I try to use, always seems to revert the DNumber back to the original number of decimal places (5)
Code snippet below:
if key == (1, 1):
DNumber = '{r[csvnum]}'.format(r=row)
# returns 7.65321
DNumber = """%.2f""" % (float(DNumber))
# returns 7.65
Check2 = False
if DNumber:
if DNumber <= float(8):
Check2 = True
if Check2:
print DNumber
# returns 7.65
string = 'test {r[csvhello]} TESTHERE test'.format(r=row).replace("TESTHERE", str("""%.2f""" % (float(gtpe))))
# returns: test Hello 7.65321 test
string = 'test {r[csvhello]} TESTHERE test'.format(r=row).replace("TESTHERE", str(DNumber))
# returns: test Hello 7.65321 test
What I hoped it would return: test Hello 7.65 test
Any Ideas or suggestion on alternative methods to try?
It seems like you were hoping that converting the float to a 2-decimal-place string and then back to a float would give you a 2-decimal-place float.
The first problem is that your code doesn't actually do that anywhere. If you'd done that, you would get something very close to 7.65, not 7.65321.
But the bigger problem is that what you're trying to do doesn't make any sense. A float always has 53 binary digits, no matter what. If you round it to two decimal digits (no matter how you do it, including by converting to string and back), what you actually get is a float rounded to two decimal digits and then rounded to 53 binary digits. The closest float to 7.65 is not exactly 7.65, but 7.650000000000000355271368.* So, that's what you'd end up with. And there's no way around that; it's inherent to the way float is stored.
However, there is a different type you can use for this: decimal.Decimal. For example:
>>> f = 7.65321
>>> s = '%.2f' % f
>>> d = decimal.Decimal(s)
>>> f, s, d
(7.65321, '7.65', Decimal('7.65'))
Or, of course, you could just pass around a string instead of a float (as you're accidentally doing in your code already), or you could remember to use the .2f format every time you want to output it.
As a side note, since your DNumber ends up as a string, this line is not doing anything useful:
if DNumber <= 8:
In Python 2.x, comparing two values of different types gives you a consistent but arbitrary and meaningless answer. With CPython 2.x, it will always be False.** In a different Python 2.x implementation, it might be different. In Python 3.x, it raises a TypeError.
And changing it to this doesn't help in any way:
if DNumber <= float(8):
Now, instead of comparing a str to an int, you're comparing a str to a float. This is exactly as meaningless, and follows the exact same rules. (Also, float(8) means the same thing as 8.0, but less readable and potentially slower.)
For that matter, this:
if DNumber:
… is always going to be true. For a number, if foo checks whether it's non-zero. That's a bad idea for float values (you should check whether it's within some absolute or relative error range of 0). But again, you don't have a float value; you have a str. And for strings, if foo checks whether the string is non-empty. So, even if you started off with 0, your string "0.00" is going to be true.
* I'm assuming here that you're using CPython, on a platform that uses IEEE-754 double for its C double type, and that all those extra conversions back and forth between string and float aren't introducing any additional errors.
** The rule is, slightly simplified: If you compare two numbers, they're converted to a type that can hold them both; otherwise, if either value is None it's smaller; otherwise, if either value is a number, it's smaller; otherwise, whichever one's type has an alphabetically earlier name is smaller.
I think you're trying to do the following - combine the formatting with the getter:
>>> a = 123.456789
>>> row = {'csvnum': a}
>>> print 'test {r[csvnum]:.2f} hello'.format(r=row)
test 123.46 hello
If your number is a 7 followed by five digits, you might want to try:
print "%r" % float(str(x)[:4])
where x is the float in question.
Example:
>>>x = 1.11111
>>>print "%r" % float(str(x)[:4])
>>>1.11
How can we get the length of a hexadecimal number in the Python language?
I tried using this code but even this is showing some error.
i = 0
def hex_len(a):
if a > 0x0:
# i = 0
i = i + 1
a = a/16
return i
b = 0x346
print(hex_len(b))
Here I just used 346 as the hexadecimal number, but my actual numbers are very big to be counted manually.
Use the function hex:
>>> b = 0x346
>>> hex(b)
'0x346'
>>> len(hex(b))-2
3
or using string formatting:
>>> len("{:x}".format(b))
3
While using the string representation as intermediate result has some merits in simplicity it's somewhat wasted time and memory. I'd prefer a mathematical solution (returning the pure number of digits without any 0x-prefix):
from math import ceil, log
def numberLength(n, base=16):
return ceil(log(n+1)/log(base))
The +1 adjustment takes care of the fact, that for an exact power of your number base you need a leading "1".
As Ashwini wrote, the hex function does the hard work for you:
hex(x)
Convert an integer number (of any size) to a hexadecimal string. The result is a valid Python expression.
Why will it not print out the position of a integer/float until I have converted it to a string?
example
x = 123
print x[0] # error
To fix this I have to do
x = 123
print str(x)[0]
But why do I have to make it into a string for it to work?
Well, why should this work in the first place? What is the nth index of a number; what is index 0 of the decimal number 123?
Is it 1 because of its decimal representation?
Is it 7 because of its hexadecimal representation (7B)?
Is it 0 because of its hexadecimal representation (0x7B)?
Is it 1 because of its octal representation (173)?
Is it 0 because of its octal representation (0173)?
Is it 1 because of its binary representation (1111011)
Is it 1 because of its binary representation with the least significant bit first (1101111)?
Is it S because that’s what 123 is in ASCII?
…
As you can see, this is very unclear, and it does not make sense to begin with. When using the index access on a list, you get the nth element of the list. When you use the index access on a sequence, you get the nth element of the sequence. A string is a sequence of characters, so when using the index access on a string, you get the nth element of the string sequence; the nth character. A number is no sequence, only its string representation in some format is.
123 is but one representation of the integer value. Python int values are not sequences or mappings, so [item] indexing has no meaning for them.
By turning the number into a string, you 'capture' the representation into a series of digit characters and you then can get the first one.
Another way to do it would be to divide by 10 until you have a number lower than 10:
x = 123
while x > 10:
x //= 10
print x # prints the number 1
Note that x then holds an int still, not a single-character string.
The simple answer is because you have the wrong type. Integers don't support indexing -- and I really don't think they should (they're not sequences or mappings and I can't think of any way that indexing an integer actually makes sense).
Note that there is more than one way to represent an integer as well:
>>> 0x7b == 123
True
So in this case, who is to say that x[0] should return 1 instead of 0 (or 7) depending on how you want to think of it?
As a side note to the excellent answers above, this is one way you can convert a number to a list of numbers to allow indexing:
In [2]: map(int,str(123))
Out[2]: [1, 2, 3]
In [3]: map(int,str(123))[0]
Out[3]: 1
In [4]: type(map(int,str(123))[0])
Out[4]: int
Let us suppose that we have a string representing a binary fraction such as:
".1"
As a decimal number this is 0.5. Is there a standard way in Python to go from such strings to a number type (whether it is binary or decimal is not strictly important).
For an integer, the solution is straightforward:
int("101", 2)
>>>5
int() takes an optional second argument to provide the base, but float() does not.
I am looking for something functionally equivalent (I think) to this:
def frac_bin_str_to_float(num):
"""Assuming num to be a string representing
the fractional part of a binary number with
no integer part, return num as a float."""
result = 0
ex = 2.0
for c in num:
if c == '1':
result += 1/ex
ex *= 2
return result
I think that does what I want, although I may well have missed some edge cases.
Is there a built-in or standard method of doing this in Python?
The following is a shorter way to express the same algorithm:
def parse_bin(s):
return int(s[1:], 2) / 2.**(len(s) - 1)
It assumes that the string starts with the dot. If you want something more general, the following will handle both the integer and the fractional parts:
def parse_bin(s):
t = s.split('.')
return int(t[0], 2) + int(t[1], 2) / 2.**len(t[1])
For example:
In [56]: parse_bin('10.11')
Out[56]: 2.75
It is reasonable to suppress the point instead of splitting on it, as follows. This bin2float function (unlike parse_bin in previous answer) correctly deals with inputs without points (except for returning an integer instead of a float in that case).
For example, the invocations bin2float('101101'), bin2float('.11101'), andbin2float('101101.11101')` return 45, 0.90625, 45.90625 respectively.
def bin2float (b):
s, f = b.find('.')+1, int(b.replace('.',''), 2)
return f/2.**(len(b)-s) if s else f
You could actually generalize James's code to convert it from any number system if you replace the hard coded '2' to that base.
def str2float(s, base=10):
dot, f = s.find('.') + 1, int(s.replace('.', ''), base)
return f / float(base)**(len(s) - dot) if dot else f
You can use the Binary fractions package. With this package you can convert binary-fraction strings into floats and vice-versa.
Example:
>>> from binary_fractions import Binary
>>> float(Binary("0.1"))
0.5
>>> str(Binary(0.5))
'0b0.1'
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.