# Unitted Functions¶

A function which handles UnitArrays and UnitScalars is a unitted function. Unitted functions are created with the `has_units()` decorator. The units can be specified by passing arguments to the decorator or by constructing a special docstring.

## Decorator arguments¶

```from numpy import array
from scimath.units.api import has_units
from scimath.units.length import feet, meter
@has_units(inputs="a:an array:units=ft;b:array:units=ft",
outputs="result:an array:units=m")
""" Add two arrays in ft and convert them to m.

"""
return (a + b) * feet / meter
```

To use has_units with decorator arguments, pass string arguments “inputs” and (optionally) “outputs”. See the `has_units()` docstring or visit the User Reference page for details on the syntax.

## Formatted docstring¶

```from scimath.units.api import has_units, UnitArray
@has_units
""" Add two arrays in ft and convert them to m.

Parameters
----------
a : array : units=ft
An array
b : array : units=ft
Another array

Returns
-------
c : array : units=m
c = a + b
"""
return (a + b) * feet / meter
```

Using the has_units decorator with a docstring has the benefit of using a ReST-compatible format, so the unitting specification doubles as a documentation entry. See the `has_units()` docstring or visit the User Reference page for details on the syntax. The example above produces the following documentation entry when built with Sphinx:

## Unitted function output¶

In the examples above, we told add() to expect two values, `a` and `b` and convert them to feet for use in the function. Then we specified that the output would be in meters. Inside the function, `a` and `b` are not unitted, and the function is responsible for the conversion. (Remember our caveat regarding conversion factors.)

Unitted functions can accept either regular Python objects (of the appropriate type) or the equivalent unitted objects. The return type depends on what it was passed.

```>>> add(1,2)
0.9144000000000001
```

In this case, add() accepted two integer arguments in feet, added them and returned an integer value in meters.

```>>> add(UnitScalar(1, units="foot"), UnitScalar(2, units="foot"))
UnitScalar(0.9144000000000001, units='1.0*m')
```

In this case, add() accepted two UnitScalar arguments in feet and returned a UnitScalar in pure meters.

```>>> add(UnitScalar(0.5, units="meter"), UnitScalar(50, units="cm"))
UnitScalar(1.0, units='1.0*m')
```

Finally, in this case, a conversion to feet was made for the calculation inside the function, and the value was converted back to meters when returned.

If no units are specified in the outputs or if no output string is given, then a regular scalar data type will be returned.

It may be useful to define new units for use in a project and have them available throughout an application. This is done by extending the unit parser to handle user-defined units, described in the next section.