# Calculator Service Operators Reference ## Overview The `CalculatorService` (`app/Services/CalculatorService.php`) evaluates formulas with Symfony's `ExpressionLanguage`. This document lists the operators, functions, and constants that are available in the current implementation. --- ## API Endpoints All endpoints live under `/api` and accept JSON. Responses use the standard `{ status, message, data }` envelope unless stated otherwise. ### Calculate By Test Site Uses the `testdefcal` definition for a test site. The incoming body supplies the variables required by the formula. ```http POST /api/calc/testsite/123 Content-Type: application/json { "result": 85, "gender": "female", "age": 30 } ``` Response: ```json { "status": "success", "data": { "result": 92.4, "testSiteID": 123, "formula": "{result} * {factor} + {age}", "variables": { "result": 85, "gender": "female", "age": 30 } } } ``` ### Calculate By Code Or Name Evaluates a configured calculation by `TestSiteCode` or `TestSiteName`. Returns a compact map with a single key/value or `{}` on failure. ```http POST /api/calc/testcode/GLU Content-Type: application/json { "result": 110, "factor": 1.1 } ``` Response: ```json { "GLU": 121 } ``` --- ## Supported Operators ### Arithmetic Operators | Operator | Description | Example | Result | |----------|-------------|---------|--------| | `+` | Addition | `5 + 3` | `8` | | `-` | Subtraction | `10 - 4` | `6` | | `*` | Multiplication | `6 * 7` | `42` | | `/` | Division | `20 / 4` | `5` | | `%` | Modulo | `20 % 6` | `2` | | `**` | Exponentiation (power) | `2 ** 3` | `8` | ### Comparison Operators | Operator | Description | Example | |----------|-------------|---------| | `==` | Equal | `{result} == 10` | | `!=` | Not equal | `{result} != 10` | | `<` | Less than | `{result} < 10` | | `<=` | Less than or equal | `{result} <= 10` | | `>` | Greater than | `{result} > 10` | | `>=` | Greater than or equal | `{result} >= 10` | ### Logical Operators | Operator | Description | Example | |----------|-------------|---------| | `and` / `&&` | Logical AND | `{result} > 0 and {factor} > 0` | | `or` / `||` | Logical OR | `{gender} == 1 or {gender} == 2` | | `!` / `not` | Logical NOT | `not ({result} > 0)` | ### Conditional Operators | Operator | Description | Example | |----------|-------------|---------| | `?:` | Ternary | `{result} > 10 ? {result} : 10` | | `??` | Null coalescing | `{result} ?? 0` | ### Parentheses Use parentheses to control operation precedence: ``` (2 + 3) * 4 // Result: 20 2 + 3 * 4 // Result: 14 ``` ### Notes - `^` is bitwise XOR (not exponentiation). Use `**` for powers. - Variables must be numeric after normalization (gender is mapped to 0/1/2). --- ## Functions Only the default ExpressionLanguage functions are available: | Function | Description | Example | |----------|-------------|---------| | `min(a, b, ...)` | Minimum value | `min({result}, 10)` | | `max(a, b, ...)` | Maximum value | `max({result}, 10)` | | `constant(name)` | PHP constant by name | `constant("PHP_INT_MAX")` | | `enum(name)` | PHP enum case by name | `enum("App\\Enum\\Status::Active")` | --- ## Constants ExpressionLanguage recognizes boolean and null literals: | Constant | Value | Description | |----------|-------|-------------| | `true` | `true` | Boolean true | | `false` | `false` | Boolean false | | `null` | `null` | Null value | --- ## Variables in CalculatorService When using `calculateFromDefinition()`, the following variables are automatically available: | Variable | Description | Type | |----------|-------------|------| | `{result}` | The test result value | Float | | `{factor}` | Calculation factor (default: 1) | Float | | `{gender}` | Gender value (0=Unknown, 1=Female, 2=Male) | Integer | | `{age}` | Patient age | Float | | `{ref_low}` | Reference range low value | Float | | `{ref_high}` | Reference range high value | Float | ### Gender Mapping The `gender` variable accepts the following values: | Value | Description | |-------|-------------| | `0` | Unknown | | `1` | Female | | `2` | Male | Or use string values: `'unknown'`, `'female'`, `'male'` --- ## Implicit Multiplication Implicit multiplication is not supported. Always use `*` between values: | Expression | Use Instead | |------------|-------------| | `2x` | `2 * x` | | `{result}{factor}` | `{result} * {factor}` | --- ## Usage Examples ### Basic Calculation ```php use App\Services\CalculatorService; $calculator = new CalculatorService(); // Simple arithmetic $result = $calculator->calculate("5 + 3 * 2"); // Result: 11 // Using min/max $result = $calculator->calculate("max({result}, 10)", ['result' => 7]); // Result: 10 ``` ### With Variables ```php $formula = "{result} * {factor} + 10"; $variables = [ 'result' => 5.2, 'factor' => 2 ]; $result = $calculator->calculate($formula, $variables); // Result: 20.4 ``` ### BMI Calculation ```php $formula = "{weight} / ({height} ** 2)"; $variables = [ 'weight' => 70, // kg 'height' => 1.75 // meters ]; $result = $calculator->calculate($formula, $variables); // Result: 22.86 ``` ### Gender-Based Calculation ```php // Apply different multipliers based on gender $formula = "{result} * (1 + 0.1 * {gender})"; $variables = [ 'result' => 100, 'gender' => 1 // Female = 1 ]; $result = $calculator->calculate($formula, $variables); // Result: 110 ``` ### Complex Formula ```php // Pythagorean theorem $formula = "(({a} ** 2 + {b} ** 2) ** 0.5)"; $variables = [ 'a' => 3, 'b' => 4 ]; $result = $calculator->calculate($formula, $variables); // Result: 5 ``` ### Using calculateFromDefinition ```php $calcDef = [ 'FormulaCode' => '{result} * {factor} + {gender}', 'Factor' => 2 ]; $testValues = [ 'result' => 10, 'gender' => 1 // Female ]; $result = $calculator->calculateFromDefinition($calcDef, $testValues); // Result: 21 (10 * 2 + 1) ``` --- ## Formula Validation Validate formulas before storing them: ```php $validation = $calculator->validate("{result} / {factor}"); // Returns: ['valid' => true, 'error' => null] $validation = $calculator->validate("{result} /"); // Returns: ['valid' => false, 'error' => 'Error message'] ``` ### Extract Variables Get a list of variables used in a formula: ```php $variables = $calculator->extractVariables("{result} * {factor} + {age}"); // Returns: ['result', 'factor', 'age'] ``` --- ## Error Handling The service throws exceptions for invalid formulas or missing variables: ```php try { $result = $calculator->calculate("{result} / 0"); } catch (\Exception $e) { // Handle division by zero or other errors log_message('error', $e->getMessage()); } ``` Common errors: - **Invalid formula syntax**: Malformed expressions - **Missing variable**: Variable placeholder not provided in data array - **Non-numeric value**: Variables must be numeric - **Division by zero**: Mathematical error --- ## Best Practices 1. **Always validate formulas** before storing in database 2. **Use placeholder syntax** `{variable_name}` for clarity 3. **Handle exceptions** in production code 4. **Test edge cases** like zero values and boundary conditions 5. **Document formulas** with comments in your code --- ## References - [Symfony ExpressionLanguage](https://symfony.com/doc/current/components/expression_language.html) - `app/Services/CalculatorService.php`