<reponame>qbecb1zen/booleano
# -*- coding: utf-8 -*-

# Copyright (c) 2009 by <NAME> <http://gustavonarea.net/>.

# This file is part of Booleano <http://code.gustavonarea.net/booleano/>.

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, distribute with
# modifications, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the following
# conditions:

# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
# IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the sale,
# use or other dealings in this Software without prior written authorization.
"""
Constant operands.

"""
from __future__ import unicode_literals

import six

from booleano.exc import InvalidOperationError
from booleano.operations.operands.core import Operand
from booleano.parser.symbol_table_builder import SymbolTableBuilder

__all__ = ["String", "Number", "Set"]

constants_symbol_table_builder = SymbolTableBuilder(use_key=False)


@constants_symbol_table_builder.register(type(None))
@six.python_2_unicode_compatible
class Constant(Operand):
    """
    Base class for constant operands.

    The only operation that is common to all the constants is equality (see
    :meth:`equals`).

    Constants don't rely on the context -- they are constant!

    if the value given to a Constant is None, all operation will resolve to False
    """

    operations = {'equality', 'inequality', 'boolean'}

    def __init__(self, constant_value):
        """

        :param constant_value: The Python value represented by the Booleano
            constant.
        :type constant_value: :class:`object`

        """
        self.constant_value = constant_value

    def to_python(self, context):
        """
        Return the value represented by this constant.

        """
        return self.constant_value

    def equals(self, value, context):
        """
        Check if this constant equals ``value``.

        """
        return self.constant_value is not None and self.constant_value == value

    def greater_than(self, value, context):
        return self.constant_value is not None and self.constant_value > value

    def less_than(self, value, context):
        return self.constant_value is not None and self.constant_value < value

    def check_equivalence(self, node):
        """
        Make sure constant ``node`` and this constant are equivalent.

        :param node: The other constant which may be equivalent to this one.
        :type node: Constant
        :raises AssertionError: If the constants are of different types or
            represent different values.

        """
        super(Constant, self).check_equivalence(node)
        assert node.constant_value == self.constant_value, u'Constants %s and %s represent different values' % (
            self,
            node
        )

    def __call__(self, context):
        """Does this variable evaluate to True?"""
        return bool(self.constant_value)

    def __str__(self):
        """Return the Unicode representation of this constant string."""
        return u'%r' % self.constant_value

    def __repr__(self):
        """Return the representation for this constant string."""
        return '<Constant %r>' % self.constant_value


@constants_symbol_table_builder.register(six.text_type)
@six.python_2_unicode_compatible
class String(Constant):
    u"""
    Constant string.
    this support native python resulution for membership, equiality and inequality
    """
    operations = {
        "equality",  # ==, !=
        "inequality",  # >, <, >=, <=
        "boolean",  # Logical values
        "membership",
    }

    def __init__(self, string):
        """

        :param string: The Python string to be represented by this Booleano
            string.
        :type string: :class:`basestring`

        ``string`` will be converted to :class:`unicode`, so it doesn't
        have to be a :class:`basestring` initially.

        """
        string = six.text_type(string)
        super(String, self).__init__(string)

    def equals(self, value, context):
        value = six.text_type(value)
        return super(String, self).equals(value, context)

    def belongs_to(self, value, context):
        value = six.text_type(value)
        return value in self.constant_value

    def is_subset(self, value, context):
        value = six.text_type(value)
        return value != self.constant_value and value in self.constant_value

    def greater_than(self, value, context):
        value = six.text_type(value)
        return self.constant_value > value

    def less_than(self, value, context):
        value = six.text_type(value)
        return self.constant_value < value

    def __call__(self, context):
        """Does this variable evaluate to True?"""
        return bool(six.text_type(self.constant_value))

    def __str__(self):
        """Return the Unicode representation of this constant string."""
        return u'"%s"' % self.constant_value

    def __repr__(self):
        """Return the representation for this constant string."""
        return '<String "%s">' % self.constant_value


@constants_symbol_table_builder.register(int)
@constants_symbol_table_builder.register(float)
@six.python_2_unicode_compatible
class Number(Constant):
    """
    Numeric constant.

    These constants support inequality operations; see :meth:`greater_than`
    and :meth:`less_than`.

    """

    operations = Constant.operations | set(['inequality'])

    def __init__(self, number):
        """

        :param number: The number to be represented, as a Python object.
        :type number: :class:`object`

        ``number`` is converted into a :class:`float` internally, so it can
        be an :class:`string <basestring>` initially.

        """
        number = float(number)
        super(Number, self).__init__(number)

    def equals(self, value, context):
        """
        Check if this numeric constant equals ``value``.

        :raises InvalidOperationError: If ``value`` can't be turned into a
            float.

        ``value`` will be turned into a float prior to the comparison, to
        support strings.

        """
        return super(Number, self).equals(self._to_number(value), context)

    def greater_than(self, value, context):
        """
        Check if this numeric constant is greater than ``value``.

        :raises InvalidOperationError: If ``value`` can't be turned into a
            float.

        ``value`` will be turned into a float prior to the comparison, to
        support strings.

        """
        return self.constant_value > self._to_number(value)

    def less_than(self, value, context):
        """
        Check if this numeric constant is less than ``value``.

        :raises InvalidOperationError: If ``value`` can't be turned into a
            float.

        ``value`` will be turned into a float prior to the comparison, to
        support strings.

        """
        return self.constant_value < self._to_number(value)

    def _to_number(self, value):
        """
        Convert ``value`` to a Python float and return the new value.

        :param value: The value to be converted into float.
        :return: The value as a float.
        :rtype: float
        :raises InvalidOperationError: If ``value`` can't be converted.

        """
        try:
            return float(value)
        except ValueError:
            raise InvalidOperationError('"%s" is not a number' % value)

    def __str__(self):
        """Return the Unicode representation of this constant number."""
        return six.text_type(self.constant_value)

    def __repr__(self):
        """Return the representation for this constant number."""
        return '<Number %s>' % self.constant_value


@constants_symbol_table_builder.register(set)
@constants_symbol_table_builder.register(frozenset)
@six.python_2_unicode_compatible
class Set(Constant):
    """
    Constant sets.

    These constants support membership operations; see :meth:`contains` and
    :meth:`is_subset`.

    """
    _is_leaf = False

    operations = Constant.operations | set(["inequality", "membership"])

    def __init__(self, *items):
        """

        :raises booleano.exc.InvalidOperationError: If at least one of the
            ``items`` is not an operand.

        """
        for item in items:
            if not isinstance(item, Operand):
                raise InvalidOperationError('Item "%s" is not an operand, so '
                                            'it cannot be a member of a set' %
                                            item)
        super(Set, self).__init__(set(items))

    def to_python(self, context):
        """
        Return a set made up of the Python representation of the operands
        contained in this set.

        """
        items = set(item.to_python(context) for item in self.constant_value)
        return items

    def equals(self, value, context):
        """Check if all the items in ``value`` are the same of this set."""
        value = set(value)
        return value == self.to_python(context)

    def less_than(self, value, context):
        """
        Check if this set has less items than the number represented in
        ``value``.

        :raises InvalidOperationError: If ``value`` is not an integer.

        """
        value = self._to_int(value)
        return len(self.constant_value) < value

    def greater_than(self, value, context):
        """
        Check if this set has more items than the number represented in
        ``value``.

        :raises InvalidOperationError: If ``value`` is not an integer.

        """
        value = self._to_int(value)
        return len(self.constant_value) > value

    def belongs_to(self, value, context):
        """
        Check that this constant set contains the ``value`` item.

        """
        for item in self.constant_value:
            try:
                if item.equals(value, context):
                    return True
            except InvalidOperationError:
                continue
        return False

    def is_subset(self, value, context):
        """
        Check that the ``value`` set is a subset of this constant set.

        """
        for item in value:
            if not self.belongs_to(item, context):
                return False
        return True

    def check_equivalence(self, node):
        """
        Make sure set ``node`` and this set are equivalent.

        :param node: The other set which may be equivalent to this one.
        :type node: Set
        :raises AssertionError: If ``node`` is not a set or it's a set
            with different elements.

        """
        Operand.check_equivalence(self, node)

        unmatched_elements = list(self.constant_value)
        assert len(unmatched_elements) == len(node.constant_value), 'Sets %s and %s do not have ' \
                                                                    'the same cardinality' % (
            unmatched_elements,
            node
        )

        # Checking that each element is represented by a mock operand:
        for element in node.constant_value:
            for key in range(len(unmatched_elements)):
                if unmatched_elements[key] == element:
                    del unmatched_elements[key]
                    break

        assert 0 == len(unmatched_elements), 'No match for the following elements: %s' % unmatched_elements

    def __str__(self):
        """Return the Unicode representation of this constant set."""
        elements = [six.text_type(element) for element in self.constant_value]
        elements = u", ".join(elements)
        return "{%s}" % elements

    def __repr__(self):
        """Return the representation for this constant set."""
        elements = [repr(element) for element in self.constant_value]

        elements = ", ".join(elements)
        if elements:
            elements = " " + elements
        return '<Set%s>' % elements

    @classmethod
    def _to_int(cls, value):
        """
        Convert ``value`` is to integer if possible.

        :param value: The value to be verified.
        :return: ``value`` as integer.
        :rtype: int
        :raises InvalidOperationError: If ``value`` is not an integer.

        This is a workaround for Python < 2.6, where floats didn't have the
        ``.is_integer()`` method.

        """
        try:
            value_as_int = int(value)
            is_int = value_as_int == float(value)
        except (ValueError, TypeError):
            is_int = False
        if not is_int:
            raise InvalidOperationError("To compare the amount of items in a "
                                        "set, the operand %s has to be an "
                                        "integer" % repr(value))
        return value_as_int

# -*- coding: utf-8 -*-

# Copyright (c) 2009 by <NAME> <http://gustavonarea.net/>.

# This file is part of Booleano <http://code.gustavonarea.net/booleano/>.

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, distribute with
# modifications, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the following
# conditions:

# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
# IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the sale,
# use or other dealings in this Software without prior written authorization.
"""
Constant operands.

"""
from __future__ import unicode_literals

import six

from booleano.exc import InvalidOperationError
from booleano.operations.operands.core import Operand
from booleano.parser.symbol_table_builder import SymbolTableBuilder

__all__ = ["String", "Number", "Set"]

constants_symbol_table_builder = SymbolTableBuilder(use_key=False)


@constants_symbol_table_builder.register(type(None))
@six.python_2_unicode_compatible
class Constant(Operand):
    """
    Base class for constant operands.

    The only operation that is common to all the constants is equality (see
    :meth:`equals`).

    Constants don't rely on the context -- they are constant!

    if the value given to a Constant is None, all operation will resolve to False
    """

    operations = {'equality', 'inequality', 'boolean'}

    def __init__(self, constant_value):
        """

        :param constant_value: The Python value represented by the Booleano
            constant.
        :type constant_value: :class:`object`

        """
        self.constant_value = constant_value

    def to_python(self, context):
        """
        Return the value represented by this constant.

        """
        return self.constant_value

    def equals(self, value, context):
        """
        Check if this constant equals ``value``.

        """
        return self.constant_value is not None and self.constant_value == value

    def greater_than(self, value, context):
        return self.constant_value is not None and self.constant_value > value

    def less_than(self, value, context):
        return self.constant_value is not None and self.constant_value < value

    def check_equivalence(self, node):
        """
        Make sure constant ``node`` and this constant are equivalent.

        :param node: The other constant which may be equivalent to this one.
        :type node: Constant
        :raises AssertionError: If the constants are of different types or
            represent different values.

        """
        super(Constant, self).check_equivalence(node)
        assert node.constant_value == self.constant_value, u'Constants %s and %s represent different values' % (
            self,
            node
        )

    def __call__(self, context):
        """Does this variable evaluate to True?"""
        return bool(self.constant_value)

    def __str__(self):
        """Return the Unicode representation of this constant string."""
        return u'%r' % self.constant_value

    def __repr__(self):
        """Return the representation for this constant string."""
        return '<Constant %r>' % self.constant_value


@constants_symbol_table_builder.register(six.text_type)
@six.python_2_unicode_compatible
class String(Constant):
    u"""
    Constant string.
    this support native python resulution for membership, equiality and inequality
    """
    operations = {
        "equality",  # ==, !=
        "inequality",  # >, <, >=, <=
        "boolean",  # Logical values
        "membership",
    }

    def __init__(self, string):
        """

        :param string: The Python string to be represented by this Booleano
            string.
        :type string: :class:`basestring`

        ``string`` will be converted to :class:`unicode`, so it doesn't
        have to be a :class:`basestring` initially.

        """
        string = six.text_type(string)
        super(String, self).__init__(string)

    def equals(self, value, context):
        value = six.text_type(value)
        return super(String, self).equals(value, context)

    def belongs_to(self, value, context):
        value = six.text_type(value)
        return value in self.constant_value

    def is_subset(self, value, context):
        value = six.text_type(value)
        return value != self.constant_value and value in self.constant_value

    def greater_than(self, value, context):
        value = six.text_type(value)
        return self.constant_value > value

    def less_than(self, value, context):
        value = six.text_type(value)
        return self.constant_value < value

    def __call__(self, context):
        """Does this variable evaluate to True?"""
        return bool(six.text_type(self.constant_value))

    def __str__(self):
        """Return the Unicode representation of this constant string."""
        return u'"%s"' % self.constant_value

    def __repr__(self):
        """Return the representation for this constant string."""
        return '<String "%s">' % self.constant_value


@constants_symbol_table_builder.register(int)
@constants_symbol_table_builder.register(float)
@six.python_2_unicode_compatible
class Number(Constant):
    """
    Numeric constant.

    These constants support inequality operations; see :meth:`greater_than`
    and :meth:`less_than`.

    """

    operations = Constant.operations | set(['inequality'])

    def __init__(self, number):
        """

        :param number: The number to be represented, as a Python object.
        :type number: :class:`object`

        ``number`` is converted into a :class:`float` internally, so it can
        be an :class:`string <basestring>` initially.

        """
        number = float(number)
        super(Number, self).__init__(number)

    def equals(self, value, context):
        """
        Check if this numeric constant equals ``value``.

        :raises InvalidOperationError: If ``value`` can't be turned into a
            float.

        ``value`` will be turned into a float prior to the comparison, to
        support strings.

        """
        return super(Number, self).equals(self._to_number(value), context)

    def greater_than(self, value, context):
        """
        Check if this numeric constant is greater than ``value``.

        :raises InvalidOperationError: If ``value`` can't be turned into a
            float.

        ``value`` will be turned into a float prior to the comparison, to
        support strings.

        """
        return self.constant_value > self._to_number(value)

    def less_than(self, value, context):
        """
        Check if this numeric constant is less than ``value``.

        :raises InvalidOperationError: If ``value`` can't be turned into a
            float.

        ``value`` will be turned into a float prior to the comparison, to
        support strings.

        """
        return self.constant_value < self._to_number(value)

    def _to_number(self, value):
        """
        Convert ``value`` to a Python float and return the new value.

        :param value: The value to be converted into float.
        :return: The value as a float.
        :rtype: float
        :raises InvalidOperationError: If ``value`` can't be converted.

        """
        try:
            return float(value)
        except ValueError:
            raise InvalidOperationError('"%s" is not a number' % value)

    def __str__(self):
        """Return the Unicode representation of this constant number."""
        return six.text_type(self.constant_value)

    def __repr__(self):
        """Return the representation for this constant number."""
        return '<Number %s>' % self.constant_value


@constants_symbol_table_builder.register(set)
@constants_symbol_table_builder.register(frozenset)
@six.python_2_unicode_compatible
class Set(Constant):
    """
    Constant sets.

    These constants support membership operations; see :meth:`contains` and
    :meth:`is_subset`.

    """
    _is_leaf = False

    operations = Constant.operations | set(["inequality", "membership"])

    def __init__(self, *items):
        """

        :raises booleano.exc.InvalidOperationError: If at least one of the
            ``items`` is not an operand.

        """
        for item in items:
            if not isinstance(item, Operand):
                raise InvalidOperationError('Item "%s" is not an operand, so '
                                            'it cannot be a member of a set' %
                                            item)
        super(Set, self).__init__(set(items))

    def to_python(self, context):
        """
        Return a set made up of the Python representation of the operands
        contained in this set.

        """
        items = set(item.to_python(context) for item in self.constant_value)
        return items

    def equals(self, value, context):
        """Check if all the items in ``value`` are the same of this set."""
        value = set(value)
        return value == self.to_python(context)

    def less_than(self, value, context):
        """
        Check if this set has less items than the number represented in
        ``value``.

        :raises InvalidOperationError: If ``value`` is not an integer.

        """
        value = self._to_int(value)
        return len(self.constant_value) < value

    def greater_than(self, value, context):
        """
        Check if this set has more items than the number represented in
        ``value``.

        :raises InvalidOperationError: If ``value`` is not an integer.

        """
        value = self._to_int(value)
        return len(self.constant_value) > value

    def belongs_to(self, value, context):
        """
        Check that this constant set contains the ``value`` item.

        """
        for item in self.constant_value:
            try:
                if item.equals(value, context):
                    return True
            except InvalidOperationError:
                continue
        return False

    def is_subset(self, value, context):
        """
        Check that the ``value`` set is a subset of this constant set.

        """
        for item in value:
            if not self.belongs_to(item, context):
                return False
        return True

    def check_equivalence(self, node):
        """
        Make sure set ``node`` and this set are equivalent.

        :param node: The other set which may be equivalent to this one.
        :type node: Set
        :raises AssertionError: If ``node`` is not a set or it's a set
            with different elements.

        """
        Operand.check_equivalence(self, node)

        unmatched_elements = list(self.constant_value)
        assert len(unmatched_elements) == len(node.constant_value), 'Sets %s and %s do not have ' \
                                                                    'the same cardinality' % (
            unmatched_elements,
            node
        )

        # Checking that each element is represented by a mock operand:
        for element in node.constant_value:
            for key in range(len(unmatched_elements)):
                if unmatched_elements[key] == element:
                    del unmatched_elements[key]
                    break

        assert 0 == len(unmatched_elements), 'No match for the following elements: %s' % unmatched_elements

    def __str__(self):
        """Return the Unicode representation of this constant set."""
        elements = [six.text_type(element) for element in self.constant_value]
        elements = u", ".join(elements)
        return "{%s}" % elements

    def __repr__(self):
        """Return the representation for this constant set."""
        elements = [repr(element) for element in self.constant_value]

        elements = ", ".join(elements)
        if elements:
            elements = " " + elements
        return '<Set%s>' % elements

    @classmethod
    def _to_int(cls, value):
        """
        Convert ``value`` is to integer if possible.

        :param value: The value to be verified.
        :return: ``value`` as integer.
        :rtype: int
        :raises InvalidOperationError: If ``value`` is not an integer.

        This is a workaround for Python < 2.6, where floats didn't have the
        ``.is_integer()`` method.

        """
        try:
            value_as_int = int(value)
            is_int = value_as_int == float(value)
        except (ValueError, TypeError):
            is_int = False
        if not is_int:
            raise InvalidOperationError("To compare the amount of items in a "
                                        "set, the operand %s has to be an "
                                        "integer" % repr(value))
        return value_as_int
# -*- coding: utf-8 -*- # Copyright (c) 2009 by <NAME> <http://gustavonarea.net/>. # This file is part of Booleano <http://code.gustavonarea.net/booleano/>. # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, distribute with # modifications, sublicense, and/or sell copies of the Software, and to permit # persons to whom the Software is furnished to do so, subject to the following # conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the sale, # use or other dealings in this Software without prior written authorization. Constant operands. Base class for constant operands.      The only operation that is common to all the constants is equality (see     :meth:`equals`).      Constants don't rely on the context -- they are constant!      if the value given to a Constant is None, all operation will resolve to False :param constant_value: The Python value represented by the Booleano             constant.         :type constant_value: :class:`object` Return the value represented by this constant. Check if this constant equals ``value``. Make sure constant ``node`` and this constant are equivalent.          :param node: The other constant which may be equivalent to this one.         :type node: Constant         :raises AssertionError: If the constants are of different types or             represent different values. Does this variable evaluate to True? Return the Unicode representation of this constant string. Return the representation for this constant string. Constant string.     this support native python resulution for membership, equiality and inequality # ==, != # >, <, >=, <= # Logical values :param string: The Python string to be represented by this Booleano             string.         :type string: :class:`basestring`          ``string`` will be converted to :class:`unicode`, so it doesn't         have to be a :class:`basestring` initially. Does this variable evaluate to True? Return the Unicode representation of this constant string. Return the representation for this constant string. Numeric constant.      These constants support inequality operations; see :meth:`greater_than`     and :meth:`less_than`. :param number: The number to be represented, as a Python object.         :type number: :class:`object`          ``number`` is converted into a :class:`float` internally, so it can         be an :class:`string <basestring>` initially. Check if this numeric constant equals ``value``.          :raises InvalidOperationError: If ``value`` can't be turned into a             float.          ``value`` will be turned into a float prior to the comparison, to         support strings. Check if this numeric constant is greater than ``value``.          :raises InvalidOperationError: If ``value`` can't be turned into a             float.          ``value`` will be turned into a float prior to the comparison, to         support strings. Check if this numeric constant is less than ``value``.          :raises InvalidOperationError: If ``value`` can't be turned into a             float.          ``value`` will be turned into a float prior to the comparison, to         support strings. Convert ``value`` to a Python float and return the new value.          :param value: The value to be converted into float.         :return: The value as a float.         :rtype: float         :raises InvalidOperationError: If ``value`` can't be converted. Return the Unicode representation of this constant number. Return the representation for this constant number. Constant sets.      These constants support membership operations; see :meth:`contains` and     :meth:`is_subset`. :raises booleano.exc.InvalidOperationError: If at least one of the             ``items`` is not an operand. Return a set made up of the Python representation of the operands         contained in this set. Check if all the items in ``value`` are the same of this set. Check if this set has less items than the number represented in         ``value``.          :raises InvalidOperationError: If ``value`` is not an integer. Check if this set has more items than the number represented in         ``value``.          :raises InvalidOperationError: If ``value`` is not an integer. Check that this constant set contains the ``value`` item. Check that the ``value`` set is a subset of this constant set. Make sure set ``node`` and this set are equivalent.          :param node: The other set which may be equivalent to this one.         :type node: Set         :raises AssertionError: If ``node`` is not a set or it's a set             with different elements. # Checking that each element is represented by a mock operand: Return the Unicode representation of this constant set. Return the representation for this constant set. Convert ``value`` is to integer if possible.          :param value: The value to be verified.         :return: ``value`` as integer.         :rtype: int         :raises InvalidOperationError: If ``value`` is not an integer.          This is a workaround for Python < 2.6, where floats didn't have the         ``.is_integer()`` method.