# Vectors

Vectors are the equivalent of Python's built-in lists with the difference that vectors are homogeneous. Hence they are always declared with a corresponding parameter type.

```python
from hanna import Configurable, Integer, Vector

class Cuboid(Configurable):
    size = Vector(Integer)
    
box = Cuboid({'size': [1, 2, 3]})
box.size  # [1, 2, 3]
```

### Customizing vectors

A vector accepts an arbitrary number of items by default and uses a list internally to store these items. Since a cuboid has three dimensions it would be convenient to fix the number of elements and to use a tuple instead of a list:

```python
class Cuboid(Configurable):
    size = Vector(Integer, n=3, as_=tuple)
    
# raises ValueError: "size" Too large (4 > 3)
box = Cuboid({'size': [1, 2, 3, 4]})
```

#### Alternative syntax

Different syntax for setting the container type or restricting the number of elements is available (the methods and operators return the parameter instance, so they can be chained):

```python
class Cuboid(Configurable):
    # Setting the container type.
    size = Vector(Integer, as_=tuple)
    size = Vector(Integer).as_(tuple)
    
    # Restricting the number of elements.
    size = Vector(Integer, n=3)
    size = Vector(Integer).len == 3
```

### Emulating N-tuples

Since creating a vector of specific type with a specific length is common task there is a even more concise syntax for that:

```python
class Cuboid(Configurable):
    size = 3 * Integer()
    
assert type(Cuboid.size) is Vector
```

This creates an Integer vector with the number of elements restricted to 3 and using a tuple to store the elements.

### Vectors of specific types

In order to facilitate reusing vectors of a specific type you can create a template by doing:

```python
from hanna import Vectors, Integer
IntVector = Vectors[Integer]
```

### Applying constraints

Any constraints applied to vectors are applied to each of their elements. For example:

```python
class Cuboid(Configurable):
    size = 3 * Integer() > 0
    
# raises ValueError: "size[2]" Too small (0 ≤ 0)
invalid_box = Cuboid({'size': [2, 1, 0})
```

This does not hold for constraints on meta characteristics such as `Vector.len`. This type of constraint is applied to the vector itself.
