Python: float(var) conversion in Python wont work [duplicate] - python

This question already has answers here:
How do I get a decimal value when using the division operator in Python?
(13 answers)
Closed 8 years ago.
this is my code:
def pmi(w1,w2):
x = float(1)
x = (bg_fdist[(w1, w2)])/(f_brown[(w1)]*f_brown[(w2)])
print x
the values entered will be:
>>> bg_fdist[('of','the')]
9781
>>> f_brown[('of')]
36412
>>> f_brown[('the')]
6997`
so i expect my x to be very small and between 0 and 1.
but i get as a return:
>>>> pmi('of','the')
0
i assume that might be, because x gets still handled as an integer? why is this? can anyone point out how i might get my expected result?
greetings!

The x that you have declared as float(1) has nothing whatsoever to do with the result of the calculation in the second line: it was simply thrown away and replaced with the result from there. Instead, you'll need to explicitly case some of the elements of that calculation to floats.
The whole thing could be made clearer by splitting it up, like this:
def pmi(w1,w2):
first = float(bg_fdist[(w1, w2)])
second = float(f_brown[(w1)]*f_brown[(w2)])
result = first/second
return result

If you do
>>> x = float(1)
>>> x
1.0
>>> type(x)
<type 'float'>
x is indeed a float. But if after you instanciate it with an int, it's not a float anymore:
>>> x = 2
>>> x
2
>>> type(x)
<type 'int'>
When doing your division, you are using integer so:
>>> x = 2/4
>>> x
0
>>> type(x)
<type 'int'>
You still have an integer. Instead you could use float on your variable in your equation:
>>> x = float(2)/4
>>> x
0.5
You could also use from __future__ import division.
The current division (/) operator has an ambiguous meaning for
numerical arguments: it returns the floor of the mathematical
result of division if the arguments are ints or longs, but it
returns a reasonable approximation of the division result if the
arguments are floats or complex.
See: PEP 238

Related

What is the body of __hash__ function for the type int in cython python3 [duplicate]

When hash() method is called in Python 3, I noticed that it doesn't return a long-length integer when taking in int data type but with string type.
Is this supposed to work this way? If that actually is the case, for the int type to have a short hash value, won't it cause collision since it's too short?
for i in [i for i in range(5)]:
print(hash(i))
print(hash("abc"))
The Result:
0
1
2
3
4
4714025963994714141
In CPython, default Python interpreter implementation, built-in hash is done in this way:
For numeric types, the hash of a number x is based on the reduction
of x modulo the prime P = 2**_PyHASH_BITS - 1. It's designed so that
hash(x) == hash(y) whenever x and y are numerically equal, even if
x and y have different types
_PyHASH_BITS is 61 (64-bit systems) or 31 (32-bit systems)(defined here)
So on 64-bit system built-in hash looks like this function:
def hash(number):
return number % (2 ** 61 - 1)
That's why for small ints you got the same values, while for example hash(2305843009213693950) returns 2305843009213693950 and hash(2305843009213693951) returns 0
The only purpose of the hash function is to produce an integer value that can be used to insert an object into a dict. The only thing hash guarantees is that if a == b, then hash(a) == hash(b). For a user-defined class Foo, it is the user's responsibility to ensure that Foo.__eq__ and Foo.__hash__ enforce this guarantee.
Anything else is implementation-dependent, and you shouldn't read anything into the value of hash(x) for any value x. Specifically, hash(a) == hash(b) is allowed for a != b, and hash(x) == x is not required for any particular x.
You should use hashlib module:
>>> import hashlib()
>>> m.update(b'abc')
>>> m.hexdigest()

Complex number Data type in Python3

If I write x=5+j in python3. It shows me type(x) is an int. why this
not considered as a complex number?
You forgot write number before j if you write 5+1j and check type you get what you want (complex type), like below:
x = 5+1j
type(x)
#complex
For define complex numbers you can use different approaches.
You can use np.complex like below:
import numpy as np
x = np.complex(5,1)
type(x)
# complex
print(x)
# (5+1j)
Also You can use cmath:
import cmath
x = complex(5,1)
type(x)
# complex
print(x)
# (5+1j)
You could use the cmath module which allows you to work with complex numbers.
A very simple example of usage:
import cmath
x = 5 + 1*1j
# alternatively
# x = complex(5,1)
print(type(x))
print(x)
Check out more: https://docs.python.org/3/library/cmath.html
It's a standard package, so you don't have to install anything.
The fact that type(x) is int probably means that you already have a variable j in your code, and that variable is an int. Just like this:
>>> j = 10
>>> x = 5 + j
>>> type(x)
<class 'int'>
Now, if you wish to create a complex number, you may either use the built-in complex function:
>>> x = complex(5, 1)
>>> x
(5+1j)
>>> type(x)
<class 'complex'>
or write a literal complex number:
>>> x = 5 + 1j
>>> x
(5+1j)
>>> type(x)
<class 'complex'>
The main difference between this and what you wrote is that 5 + j means "5 plus a variable called j", whereas 5 + 1j means "5 plus the complex number 1j". Remember that j is not the imaginary unit, it is the name of a variable. If you wish to write a complex literal, you need to write something like <number>j. In particular, the imaginary unit can be written as 1j.

Different Python Variables with Same Value Pointing to Same Object [duplicate]

This question already has answers here:
"is" operator behaves unexpectedly with integers
(11 answers)
Closed 7 years ago.
In python, I have declared two variables with same value. Strangely, they are pointing to same object. I need to understand how this objects and their corresponding values are assigned.
#!/usr/bin/python
a = 100
b = 100
print id(a)
print id(b)
--------------------
Output :
157375428
157375428
-------------------
I assume, a and b are two different variables with same value. Then why the same object is pointing to both of them ?
By calling id(a) you actually get same result as when calling id(100), a and b share the same instance of 100. I know this is quite confusing, almost every other programming language behaves differently. Maybe you shouldn't think a and b as variables but instead "named references" to objects.
Technically a and b are two different variables.
In Python a variable is a just a name. Values are somewhere else and a variable refers to a value.
From the Python documentation
For immutable types, operations that compute new values may actually
return a reference to any existing object with the same type and
value, while for mutable objects this is not allowed. E.g., after a = 1; b = 1, a and b may or may not refer to the same object with the
value one, depending on the implementation.
Python pre-allocates a number of integers (see http://blog.lerner.co.il/why-you-should-almost-never-use-is-in-python/). For instance, on my computer I have:
>>> x = 100
>>> y = 100
>>> x is y
True
But:
>>> x = 10**1000
>>> y = 10**1000
>>> x is y
False
In fact, we can see that only the first 256 positive integers are pre-allocated:
>>> x = 0
>>> y = 0
>>> while True:
... if not x is y:
... print x
... break
... x += 1
... y += 1
...
257

Complex number in python

How to write a complex number in python? Indeed I have:
import math
a=3
b=4
function=a*j*x+b*y
I don't want to write directly 3j in my function since I absolutely want to use a, so how to convert a into a complex number? Cause in matlab it works when printing :
a=3
b=a*i
The result will gave: 0 + 3.0000i
Thank you for your answers.
j alone is a variable, you can have the complex number by typing 1j
>>> type(j)
NameError: name 'j' is not defined
>>> type(1j)
<type 'complex'>
So your code can be written as a function as
def function(x, y):
a = 3
b = 4
return a*1j*x+b*y
You can use the complex function to create a complex number from variables:
>>> a = 3
>>> b = 4
>>> complex(a, b)
(3+4j)
You can simply use Python's Built in complex() function
>>> first_number = 10
>>> second_number = 15
>>> complex(first_number, second_number)
(10+15j)

Does Python have an equivalent to java.lang.Math.nextUp? [duplicate]

This question already has answers here:
Increment a Python floating point value by the smallest possible amount
(15 answers)
Closed 6 years ago.
I have a Python float, and I want to have the floats which are 1 ULP greater and lesser.
In Java, I would do this with Math.nextUp(x) and Math.nextAfter(x, Double.NEGATIVE_INFINITY).
Is there a way to do this in Python? I thought about implementing it myself with math.frexp and math.ldexp but as far as I know Python doesn't specify the size of floating point types.
Update: In Python 3.9+ there is math.nextafter():
>>> import math
>>> x = 4
>>> math.nextafter(x, math.inf)
4.000000000000001
Old answer:
You could look at how Decimal.next_plus()/Decimal.next_minus() are implemented:
>>> from decimal import Decimal as D
>>> d = D.from_float(123456.78901234567890)
>>> d
Decimal('123456.789012345674564130604267120361328125')
>>> d.next_plus()
Decimal('123456.7890123456745641306043')
>>> d.next_minus()
Decimal('123456.7890123456745641306042')
>>> d.next_toward(D('-inf'))
Decimal('123456.7890123456745641306042')
Make sure that decimal context has values that you need:
>>> from decimal import getcontext
>>> getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999999, Emax=999999999,
capitals=1, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])
Alternatives:
Call C99 nextafter() using ctypes:
>>> import ctypes
>>> nextafter = ctypes.CDLL(None).nextafter
>>> nextafter.argtypes = ctypes.c_double, ctypes.c_double
>>> nextafter.restype = ctypes.c_double
>>> nextafter(4, float('+inf'))
4.000000000000001
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
Using numpy:
>>> import numpy
>>> numpy.nextafter(4, float('+inf'))
4.0000000000000009
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
Despite different repr(), the result is the same.
If we ignore edge cases then a simple frexp/ldexp solution from #S.Lott answer works:
>>> import math, sys
>>> m, e = math.frexp(4.0)
>>> math.ldexp(2 * m + sys.float_info.epsilon, e - 1)
4.000000000000001
>>> _.as_integer_ratio()
(4503599627370497, 1125899906842624)
pure Python next_after(x, y) implementation by #Mark Dickinson that takes into account edge cases. The result is the same in this case.
I am not sure if this is what you want, but sys.float_info.epsilon is the "difference between 1 and the least value greater than 1 that is representable as a float", and you could do x * (1 + sys.float_info.epsilon).
http://docs.python.org/library/sys.html#sys.float_info

Categories