Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Booleans have two possible values. Are there types that have three possible values? [duplicate]

Possible Duplicate:
What's the best way to implement an 'enum' in Python?

I’m writing a function that, ideally, I’d like to return one of three states: “yes”, “no”, and “don’t know”.

  1. Do any programming languages have a type that has three, and only three states? Like a boolean, but with three states instead of two?

  2. In languages that don’t have such a type (like Python), what’s the best type to represent this?

    Currently I think I’ll go with an integer (0 for “no”, 1 for “don’t know” and 2 for “yes”), but maybe there’s a better way? Integers seem a bit “magic number”.

    I could return True, False or None, but as None would evaluate to False in most comparison contexts it seems a bit ripe for errors.

like image 412
Paul D. Waite Avatar asked Feb 29 '12 14:02

Paul D. Waite


People also ask

What are the two possible values of the type Boolean?

A variable of the primitive data type boolean can have two values: true and false (Boolean literals). or off. Boolean expressions use relational and logical operators. The result of a Boolean expression is either true or false.

Can a Boolean have 3 values?

It was interesting to read that the PostgreSQL boolean (alias “bool”) data type is actually Trinary not Binary and therefore has three possible states: TRUE, FALSE, and “unknown” (represented by a NULL). This is evidently the standard SQL three-valued logic system (also called Trinary, Ternary, Trivalent, 3VL, etc.

How many possible values are there for a Boolean variable?

A Boolean variable has only two possible values: true or false. It is common to use Booleans with control statements to determine the flow of a program. In this example, when the boolean value "x" is true, vertical black lines are drawn and when the boolean value "x" is false, horizontal gray lines are drawn.

Does Boolean only have two values?

There are just two values of type bool: true and false. They are used as the values of expressions that have yes-or-no answers. The following table shows some operators that yield boolean results and some operations on boolean values.


1 Answers

In Python I'd do that with a wrapper object that holds one of those three values; I'd use True, False, and None. Since the implicit truthiness value of a Boolean-like object with three possible values is problematic, we'll solve that by disallowing that entirely (raising an exception in __nonzero__(), or in Python 3, __bool__()), thus requiring that comparisons always be done explicitly, using in, ==, or !=. We'll implement equality as identity so that only the specific singleton values True, False, and None are matched.

class Tristate(object):      def __init__(self, value=None):        if any(value is v for v in (True, False, None)):           self.value = value        else:            raise ValueError("Tristate value must be True, False, or None")      def __eq__(self, other):        return (self.value is other.value if isinstance(other, Tristate)                else self.value is other)      def __ne__(self, other):        return not self == other      def __nonzero__(self):   # Python 3: __bool__()        raise TypeError("Tristate object may not be used as a Boolean")      def __str__(self):         return str(self.value)      def __repr__(self):         return "Tristate(%s)" % self.value 

Usage:

t = Tristate(True) t == True           # True t != False          # True t in (True, False)  # True bool(t)             # Exception! if t: print "woo"   # Exception! 

When using Tristate objects, you must explicitly specify which values to match, i.e. foo == True or bar != None. You can also do foo in (False, None) to match multiple values (though of course in two values is the same as != with a single value). If there are other logic operations you wish to be able to perform with these objects, you could implement these as methods, or possibly by overriding certain operators (sadly, however, logical not, and, and or are not overrideable, though there's a proposal to add that).

Also note that you can't override id() in Python, so e.g. Tristate(None) is None is False; the two objects are in fact different. Since good Python style is to use is when comparing against singletons, this is unfortunate, but unavoidable.

Edit 4/27/16: Added support for comparing one Tristate object to another.

like image 183
kindall Avatar answered Sep 26 '22 08:09

kindall