# Transform/Propagate

While the Unit abstraction may feel insufficient to express complex logic or limiting, we provide two mechanisms for arbitrary Python code execution that enable quick iteration without giving up the benefits of the Schema type enforcement.

# Map/Transform

MapUnit allows you to apply an arbitrary function to the output of a Unit.

from verdict.common.judge import JudgeUnit
from verdict.transform import MapUnit

JudgeUnit() \
    >> MapUnit(lambda judge: Schema.of(score=((judge.score / 5) * 7))) # normalize to 1-7 scale

It has native support for multiple dependencies, which are indexed first-come first-serve at definition-time.

Reduce
Index
from verdict import Layer

Layer(JudgeUnit(), 5) \
>> MapUnit(lambda judges: Schema.of(score=min(judge.score for judge in judges)))
Layer([
    JudgeUnit(DiscreteScale((1, 5), end_is_worst=False)),
    JudgeUnit(DiscreteScale((1, 5), end_is_worst=True))]) \
>> MapUnit(lambda judges: Schema.of(score=(judges[0].score + (6 - judges[1].score)) / 2))

Additionally, we provide the following built-in MapUnits for convenience.

MapUnit Description Output Schema
MeanPoolUnit Compute the mean of a list of values. Schema.of(field_name=field_type)
MaxPoolUnit Compute the mode of a list of values. Schema.of(field_name=field_type
MeanVariancePoolUnit Compute the mean and variance of a list of values. Schema.of(mean=float, variance=float)

# Propagate

You can specify special logic to modify the OutputSchema of a Unit post-execution by using the .propagate() directive. This is particularly useful for propagating forward the OutputSchema of a dependency. Refer to the Previous section for more details.

Propagate Dependency
MapUnit Example
from verdict.schema import Schema

ConversationalUnit("Proponent").propagate(
    lambda unit, previous, input, output: Schema.of(
        thought=previous.thought,
        conversation=output.conversation
    ))
from verdict.common.judge import JudgeUnit

JudgeUnit().propagate(
    lambda unit, previous, input, output: Schema.of(
        score=(previous.score / 5) * 7
    )) \
>> ...