Leapfrog Expression Syntax Guide¶
This guide explains the expression syntax used in Leapfrog calculators and how pollywog represents them.
See also
Helper Functions Guide - Use helper functions instead of manual expressions
Tutorials - See complete examples of expression usage
Common Workflow Patterns - Common expression patterns and recipes
Understanding Leapfrog Calculations¶
In Leapfrog, calculations are defined using a specialized expression language that allows you to:
Reference variables using square brackets:
[variable_name]Apply mathematical operations:
+,-,*,/,^(power)Use built-in functions for numerical transformations
Create conditional logic with if/else statements
Categorize data based on thresholds or conditions
Variable References¶
Variables in Leapfrog expressions are referenced using square brackets. This allows Leapfrog to distinguish between variable names and other text.
# Reference a single variable
Number(name="Au_scaled", expression=["[Au] * 2.0"])
# Reference multiple variables in an expression
Number(name="total_grade", expression=["[Au] + [Ag] + [Cu]"])
# Reference block model variables
Number(name="density_calc", expression=["[block_density] * [block_volume]"])
Common variable contexts in Leapfrog:
Drillhole variables: Assay data, downhole surveys, lithology codes
Block model variables: Estimated grades, geological domains, density
Mesh variables: Surface attributes, interpolated values
Points variables: Discrete point data, sample locations
Mathematical Operations¶
Pollywog supports all standard mathematical operations used in Leapfrog:
# Addition and subtraction
Number(name="net_grade", expression=["[Au_est] - [Au_waste]"])
# Multiplication and division
Number(name="metal_content", expression=["[grade] * [tonnage] / 1000"])
# Exponentiation (power)
Number(name="Au_squared", expression=["[Au] ^ 2"])
# Parentheses for order of operations
Number(name="weighted_avg", expression=["([Au] * [weight_Au] + [Ag] * [weight_Ag]) / ([weight_Au] + [weight_Ag])"])
Built-in Functions¶
Leapfrog provides many built-in functions that pollywog emulates. These functions are available in calculation expressions:
Mathematical Functions¶
# Logarithmic functions
Number(name="Au_log10", expression=["log([Au], 10)"]) # Base 10 logarithm
Number(name="Au_ln", expression=["ln([Au])"]) # Natural logarithm
Number(name="Au_exp", expression=["exp([Au])"]) # Exponential (e^x)
# Square root
Number(name="Au_sqrt", expression=["sqrt([Au])"])
# Absolute value
Number(name="Au_abs", expression=["abs([Au] - [Au_target])"])
Trigonometric Functions¶
# Basic trigonometry
Number(name="sin_angle", expression=["sin([angle])"])
Number(name="cos_angle", expression=["cos([angle])"])
Number(name="tan_angle", expression=["tan([angle])"])
# Inverse trigonometry
Number(name="asin_val", expression=["asin([ratio])"])
Number(name="acos_val", expression=["acos([ratio])"])
Number(name="atan_val", expression=["atan([slope])"])
Rounding and Clamping¶
# Clamp values to a range
Number(name="Au_clamped", expression=["clamp([Au], 0)"]) # Minimum of 0
Number(name="Au_range", expression=["clamp([Au], 0, 10)"]) # Between 0 and 10
# Round to decimal places
Number(name="Au_round", expression=["round([Au], 2)"]) # 2 decimal places
Number(name="Au_round_int", expression=["round([Au])"]) # Round to integer
# Round to significant figures
Number(name="Au_sf", expression=["roundsf([Au], 3)"]) # 3 significant figures
# Floor and ceiling
Number(name="Au_floor", expression=["floor([Au])"]) # Round down
Number(name="Au_ceiling", expression=["ceiling([Au])"]) # Round up
# Truncate (remove decimal part)
Number(name="Au_trunc", expression=["truncate([Au])"])
Min and Max¶
# Minimum and maximum of multiple values
Number(name="max_grade", expression=["max([Au], [Ag], [Cu])"])
Number(name="min_grade", expression=["min([Au], [Ag], [Cu])"])
# Useful for creating composite variables
Number(name="best_estimate", expression=["max([est_kriging], [est_idw])"])
String Functions¶
String functions are useful for working with categorical data and text fields:
# Concatenate strings
Category(name="full_code", expression=["concat([domain], '_', [zone])"])
# String tests (return true/false)
# These are typically used in conditional expressions
# startswith([text], 'prefix')
# endswith([text], 'suffix')
# contains([text], 'substring')
# like([text], 'pattern')
# regexp([text], 'regex_pattern')
Constants¶
Pollywog provides access to mathematical constants:
# Pi and e are available as constants
Number(name="circle_area", expression=["pi * [radius] ^ 2"])
Number(name="exponential", expression=["e ^ [rate]"])
Value Status Functions¶
Leapfrog provides auxiliary functions to query the status of values:
# is_normal: Returns true if value is a normal numeric value (not blank, without_value, or outside)
Number(name="has_valid_Au", expression=[
If("is_normal([Au])", "1", "0")
])
# is_blank: Returns true if value is blank (similar to NaN/null)
Number(name="is_missing", expression=[
If("is_blank([density])", "1", "0")
])
# is_without_value: Returns true if estimation could not be performed
Number(name="needs_reestimation", expression=[
If("is_without_value([Au_kriged])", "1", "0")
])
# is_outside: Returns true if value is outside domain boundary
Number(name="outside_domain", expression=[
If("is_outside([Au_est])", "1", "0")
])
# Common pattern: Use not is_normal() to check for any special value
Number(name="Au_validated", expression=[
If("not is_normal([Au])", "0", "[Au]")
])
Value statuses in Leapfrog:
normal: Regular numeric value
blank: Empty/null value (general missing data)
without_value: Estimation could not be performed (e.g., insufficient data)
outside: Evaluation outside domain boundary
Conditional Logic (If/Else)¶
Conditional logic is essential for domain-based calculations, classification, and applying business rules.
Basic If/Else¶
from pollywog.core import If, Number
# Simple if/else using the shorthand syntax
Number(name="Au_adjusted", expression=[
If("[Au] > 5", "[Au] * 0.9", "[Au]")
])
# Multiple conditions
Number(name="Au_category", expression=[
If([
("[Au] <= 0.5", "0.25"), # If Au <= 0.5, return 0.25
("[Au] <= 2.0", "1.0"), # Else if Au <= 2.0, return 1.0
("[Au] <= 5.0", "3.5"), # Else if Au <= 5.0, return 3.5
], otherwise=["7.5"]) # Otherwise return 7.5
])
Domain-Based Calculations¶
A common pattern in resource estimation is applying different formulas based on geological domains:
from pollywog.core import If, IfRow, Number
# Apply different recovery factors by domain
Number(name="Au_recovered", expression=[
If([
("[domain] = 'oxide'", "[Au_est] * 0.92"),
("[domain] = 'transition'", "[Au_est] * 0.85"),
("[domain] = 'sulfide'", "[Au_est] * 0.78"),
], otherwise=["[Au_est] * 0.75"]) # Default recovery
])
# Combine conditions
Number(name="dilution_factor", expression=[
If([
("([domain] = 'high_grade') and ([Au] > 3)", "1.05"),
("([domain] = 'high_grade') and ([Au] <= 3)", "1.10"),
("[domain] = 'low_grade'", "1.20"),
], otherwise=["1.15"])
])
Categorical Outputs¶
Use the Category class for text-based outputs:
from pollywog.core import If, Category
Category(name="ore_type", expression=[
If([
("[Au] > 2 and [domain] = 'oxide'", "'high_grade_oxide'"),
("[Au] > 2", "'high_grade'"),
("[Au] > 0.5", "'medium_grade'"),
], otherwise=["'low_grade'"])
])
Boolean Comparisons¶
Comparison operators available in expressions:
=: Equal to!=: Not equal to>: Greater than>=: Greater than or equal to<: Less than<=: Less than or equal toand: Logical ANDor: Logical ORnot: Logical NOT
# Complex condition
Number(name="mineable", expression=[
If("([Au] >= 0.3) and ([thickness] >= 2) and ([depth] <= 300)", "1", "0")
])
Working with Missing Values¶
Leapfrog has specific value statuses (blank, without_value, outside) for different types of missing or special values. Use the value status functions to handle them properly:
# Provide default values for missing data
Number(name="Au_clean", expression=["clamp([Au], 0)"])
# Use is_normal() to check for valid numeric values
Number(name="Au_default", expression=[
If("not is_normal([Au])", "0.001", "[Au]") # Check for blank/special values
])
# Use is_blank() to specifically check for blank values
Number(name="has_density", expression=[
If("is_blank([density])", "0", "1")
])
# Handle estimation failures (without_value status)
Number(name="Au_final", expression=[
If("is_without_value([Au_kriged])", "[Au_idw]", "[Au_kriged]") # Fallback to IDW
])
# Add small epsilon to avoid log(0) errors
Number(name="Au_log_safe", expression=["log([Au] + 1e-6)"])
Best Practices for Expressions¶
Use descriptive variable names:
Au_final_recoveredis better thanafAdd comments: Use the
comment_equationparameter to document complex logicAvoid magic numbers: Define threshold values clearly or use variables
Break complex calculations into steps: Multiple simple calculations are easier to debug than one complex expression
Use helper functions: Pollywog’s helpers (Sum, Product, WeightedAverage, etc.) make code more readable
Clamp inputs: Protect against invalid values (negative grades, divide by zero)
Test edge cases: Ensure your expressions handle boundary conditions correctly
Example: Complete Workflow¶
Here’s a comprehensive example showing various expression types:
from pollywog.core import CalcSet, Number, Category, If
from pollywog.helpers import WeightedAverage, CategoryFromThresholds
calcset = CalcSet([
# 1. Data cleaning
Number(name="Au_clean", expression=["clamp([Au], 0)"],
comment_equation="Remove negative values"),
Number(name="density_clean", expression=["clamp([density], 1.5, 5.0)"],
comment_equation="Clamp density to realistic range"),
# 2. Transformations
Number(name="Au_log", expression=["log([Au_clean] + 1e-6)"],
comment_equation="Log transform with epsilon for zeros"),
# 3. Domain-based adjustments
Number(name="Au_adjusted", expression=[
If([
("[domain] = 'oxide'", "[Au_clean] * 0.95"),
("[domain] = 'sulfide'", "[Au_clean] * 0.90"),
], otherwise=["[Au_clean]"])
], comment_equation="Apply domain-specific scaling"),
# 4. Weighted average from multiple estimates
WeightedAverage(
variables=["Au_kriging", "Au_idw", "Au_nn"],
weights=[0.6, 0.3, 0.1],
name="Au_composite",
comment="Weighted combination of estimation methods"
),
# 5. Economic calculations
Number(name="metal_tonnes", expression=["[Au_composite] * [tonnes] / 31.1035"],
comment_equation="Convert grade to troy ounces"),
Number(name="revenue", expression=["[metal_tonnes] * [Au_price] * [recovery]"],
comment_equation="Estimated revenue per block"),
# 6. Classification
CategoryFromThresholds(
variable="Au_composite",
thresholds=[0.3, 1.0, 3.0],
categories=["waste", "low_grade", "medium_grade", "high_grade"],
name="ore_class",
comment="Classify blocks by gold grade"
),
])
# Export to Leapfrog
calcset.to_lfcalc("comprehensive_example.lfcalc")
See Also¶
Tutorials - Complete workflow examples
Helper Functions Guide - Pollywog helper functions
API Reference - Full API documentation