Functional Weave
Code in Python

agri.seed-rate@1.0.0

impl/python.py

1,789 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

import math

from .agri_seed_rate_types import SeedRate
from .math_round_div import round_div  ← from math.round-div ^1.0.0 · built alongside by fune
from .math_round_float import round_float  ← from math.round-float ^1.0.0 · built alongside by fune


def seed_rate(target_plants_per_square_metre: int, thousand_grain_weight_grams: float, establishment_basis_points: int) -> SeedRate:
    """Seed rate (kg/ha) = target plants/m2 x TGW (g) / expected establishment (%).

    The TGW is taken to the centigram and the establishment is in basis points,
    so kg/ha is exactly plants x centigrams / basis points and is rounded once.
    Doing it in floats gets 100 x 1.15 / 100 = 1.1499999999999999, which rounds
    to 1.1 kg/ha instead of 1.2.
    """
    plants = target_plants_per_square_metre
    if isinstance(plants, bool) or not isinstance(plants, int) or plants < 1 or plants > 100000:
        raise ValueError("targetPlantsPerSquareMetre must be a whole number from 1 to 100000, received %r" % (plants,))
    tgw = thousand_grain_weight_grams
    if isinstance(tgw, bool) or not isinstance(tgw, (int, float)) or not math.isfinite(tgw) or tgw <= 0 or tgw > 1000:
        raise ValueError("thousandGrainWeightGrams must be a finite number greater than 0 and at most 1000, received %r" % (tgw,))
    centigrams = int(round(round_float(float(tgw), 2) * 100))
    if centigrams < 1:
        raise ValueError("thousandGrainWeightGrams must be at least 0.01 grams, received %r" % (tgw,))
    bp = establishment_basis_points
    if isinstance(bp, bool) or not isinstance(bp, int) or bp < 1 or bp > 10000:
        raise ValueError("establishmentBasisPoints must be a whole number from 1 to 10000, received %r" % (bp,))
    return SeedRate(
        kg_per_hectare=round_div(plants * centigrams * 10, bp, "half-up") / 10,
        seeds_per_square_metre=round_div(plants * 100000, bp, "half-up") / 10,
    )