Values of attributes

Orange.Value contains a value of an attribute. Value can be discrete, continuous or of some other type, like discrete or continuous distribution, or a string. The value can also contain an attribute descriptor of type Variable. This enables several operations which are otherwise unavailable.

When taking a value from an example (e.g. value = example[2]), what you get is a copy of the value, not a reference. Changing the value would not change the example from which it was got.


Attributes

value
The attribute's value. Values of discrete and continuous attributes are internally stored as integers or floating point numbers, respectively. This field, however, "contains" floating point numbers for continuous attributes and strings for discrete. If attribute descriptor (field variable) is known, the string is a symbolic value for the attribute; otherwise it contains a number enclosed in "<" and ">". If value is continuous or unknown, no descriptor is needed. For the latter, the result is a string '?', '~' or '.' for don't know, don't care and other, respectively.
svalue
While the previous field (value) can store only integers and floats, svalue can contain objects of any type derived from SomeValue, such as StringValue, DiscDistribution or ContDistribution.
variable
An attribute descriptor, associatied with the value. Can be None.
varType (read only)
The value's type. It can be orange.VarTypes.Discrete (1), orange.VarTypes.Continuous (2) or orange.VarType.OtherVar (3).
valueType (read only)
Tells whether the value is regular (known) or special. This field can be orange.ValueType.Regular (0), orange.ValueType.DC (1), orange.ValueType.DK (2), or any value from 3 to 255.

Methods

<constructors>
The are many ways to construct the Value. See the examples section.
<casting to numerical types>
Value can be casted to an int, float, long. Casting to numerical types requires the values to be known. For nominal values, the result of numerical cast is an index of the value.
<casting to string>
For nominal values, it returns symbolic value if the descriptor is defined. If not, it returns an index in arrow brackets (like "<2>"). For continuous values, a string representation of the value is returned. Symbols "?", "~" and "." are used for don't-knows, don't-cares and other types of unspecified values, respectively. StringValues can be casted to strings as well.
<casting to bool>
Values can be used in conditional expression. A Value is true if it is known (i.e. not special).
<arithmetic operations>
Continuous values can be added, subtracted, multiplied, divider, raised to powers. A negative and absolute value can also be computed. Results of arithmetic operations are not values but floats. Value can be added (subtracted...) to another value or to an float or integer.
<comparison>
Values can be compared. Both values must be of the same type (discrete, continuous). Continuous values can be compared as expected. Discrete values are compared by indices, not alphabetically. This enables ordered attributes; values "tiny", "little", "big" and "huge" should be compared as listed, not alphabetically. All discrete attributes are here treated as ordinal, not nominal; the descriptor's flag ordered is ignored. It is possible to compare two values of the same attribute (i.e. with the same descriptor) or two values of different attributes. When the values belong to different attributes, orange tries different ways to compare them. See examples below for details. Both, discrete and continuous values can be compared to strings, provided that the strings can be converted to attribute's values. It is not possible to compare any of the above attributes with string "small", and it is not possible to compare a continuous attribute with "parrot". Discrete values can be compared with integers which get treated as indices. Continuous values can be compared with any numeric object. Comparing two undefined values yields equality and comparing an undefined value with a defined yields an error.
native()
Returns the same as the attribute value - string for discrete and undefined values, floating point number for continuous.
firstValue(), nextValue(), randomValue()
These functions set the value to the firstValue, the next (from the current) or to a random value. This is not always possible - the value must have a descriptor and the descriptor must support the methods. Functions return true on success and false on failure.
isDK(), isDC(), isSpecial()
Return 1 if the value is don't know, don't care, or of these or any other special type, respectively. val.isSpecial() is thus equivalent to val.valueType!=0 and to not not val.

Examples

Construction

Let us first assume that you have defined two attribute descriptors

>>> fruit = orange.EnumVariable("fruit", values = ["plum", "apple", "lemon"]) >>> iq = orange.FloatVariable("iq")

Let us now define several values.

>>> lm = orange.Value(fruit, "lemon") >>> ap = orange.Value(fruit, 1) >>> un = orange.Value(fruit) >>> >>> Mary = orange.Value(iq, "105") >>> Harry = orange.Value(iq, 80) >>> Dick = orange.Value(iq)

When a descriptor is given, as in above cases, the attribute's value can be converted from a string. In case of EnumVariable, this can be a symbolic value (as for lm), in case of continuous attributes, the string should contain a number (as for Mary). Discrete values can also be given as indices.

>>> print ap apple

The value of ap is apple, since apple is the second fruit in the list of values. Thus, saying "ap = orange.Value(fruit, 1)" is equivalent to "ap = orange.Value(fruit, fruit.values[1])". Values of continuous attributes can be given numerically, as for Harry.

What about un and Dick? Those two Value's correspond to attributes fruit and iq, but the values are not specified. More accurately, they are unknown.

We can also omit the descriptor.

>>> sf = orange.Value(2) >>> Sally = orange.Value(118.0) >>> >>> print sf <2> >>> print Sally 118.000000

Note that the outputs are different. There's a reason for it. sf is discrete and Sally is continuous. The type of the argument - int or float - defines the type of the value constructed. But why <2>? It means "the third value" of some discrete attribute, but there's no descriptor so we have no symbolical name for it. But we can assign a descriptor:

>>> sf.variable = fruit >>> print sf lemon

Before delving into the Value's fields, let us list some further - working and non-working - ways to construct a Value.

>>> m = orange.Value("plum") Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: cannot convert 'plum' to value of an unknown attribute

This is hardly surprising when you think about it. The string "plum" cannot be converted to an index without having the attribute descriptor. The only two strings which can be passed without a descriptor are '?' and '~', the Orange's representation of "don't know" and "don't care". The value will be discrete.

How do we construct a continuous unknown value? You'll probably never need it, but, well, here it is.

>>> udv = orange.Value(orange.VarTypes.Continuous, orange.ValueTypes.DK)

This says that udv is a continuous variable with value "don't know". Replace DK with DC and you have a don't-care value. Replace Continuous with Discrete and you have a discrete value.

There's another way to construct a Value: you can pass any class derived from SomeValue to constructor. There are three such classes at the moment: StringValue, DiscDistribution and ContDistribution.

>>> city = orange.Value(orange.StringValue("Cicely")) >>> print city Cicely

There's another temptation you might have:

>>> val = orange.Value(fruit) >>> val = "plum"

This actually works, but not as you might wish. After the second line, val becomes an ordinary string, not an orange.Value. What you can do is

>>> val = orange.Value(fruit) >>> val.value = "plum"

Casting, Arithmetics and Comparison

There's not much to tell about casting and arithmetics since both work exactly as you'd expected them to. Well, probably - it depends upon whether you meant to apply arithmetical operations to any attributes but continuous. You cannot do that, you cannot add lemon to an apple.

When comparing values, you don't need to convert them into numbers. You can simply compare them to builtin types

>>> Harry>80 0 >>> Harry>=80 1

More often, you will check values within examples. We're skipping a part of documentation, but if the attribute iq appears in a domain of example table tab, you can print the examples with lower iq's by

>>> for e in tab: ... if e[iq]<90: ... print e

Comparing nominal values with strings is just as simple, except that strings are not compared alphabetically but by indices. Strings must be legal attribute's values:

>>> lm=="melon" Traceback (most recent call last): File "<interactive input>", line 1, in ? Exception: Attribute 'fruit' has no value 'melon'

When comparing values of different nominal attributes, Orange tries converting string representations from one attribute to another. Let us have a three- and a four-valued attribute.

>>> deg3 = orange.EnumVariable("deg3", values=["little", "medium", "big"]) >>> deg4 = orange.EnumVariable("deg4", values=["tiny", "little", "big", "huge"]) >>> val3 = orange.Value(deg3) >>> val4 = orange.Value(deg4)

When both attributes have the same value, such as "little" or "big", there's no problem. A more interesting case is

val3.value = "medium" val4.value = "little"

The values can be compared since it is known (from deg3) that "little" is less than "medium". But what about the following:

val3.value = "medium" val4.value = "huge"

Medium and huge can't be compared since they don't (both) appear in the same attribute. (There is a way: from attribute deg4 we see that "huge" is bigger than "big", which is in turn bigger than medium (from deg3). But Orange is not as smart as we.)

Orange requires that both attributes have the same ordering.

>>> degb = orange.EnumVariable(values=["black", "white"]) >>> degd = orange.EnumVariable(values=["white", "black"]) >>> print orange.Value(degb, "white") == orange.Value(degd, "white") 1 >>> print orange.Value(degb, "black") < orange.Value(degd, "white") Traceback (most recent call last): File "<interactive input>", line 1, in ? TypeError: Value.compare: values are of different types and have different orders

The first test succeeds. White equals white for both attributes. The second reports an error since the two attributes rank black and white differently.