preparando apgar

This commit is contained in:
Álvaro González 2025-11-09 20:29:58 +01:00
parent e04276cb2a
commit 13612e7601
10 changed files with 74 additions and 40 deletions

View file

@ -37,8 +37,8 @@ void main() {
print(' Mass: 10.0 kg'); print(' Mass: 10.0 kg');
print(' Acceleration: 9.8 m/s²'); print(' Acceleration: 9.8 m/s²');
print(' Calculated Force: $force N'); print(' Calculated Force: $force N');
print(' Output variable: ${evaluator.getOutputVariableName(newtonFormula)}'); print(' Output variable: ${newtonFormula.output.name}');
print(' Output magnitude: ${evaluator.getOutputVariableMagnitude(newtonFormula)}'); print(' Output magnitude: ${newtonFormula.output.unit}');
} catch (e) { } catch (e) {
print(' Error: $e'); print(' Error: $e');
} }

View file

@ -105,11 +105,11 @@ class _FormulaScreenState extends State<FormulaScreen> {
// Convert input to base unit if needed // Convert input to base unit if needed
// Always convert from dropdown unit to variable's base unit // Always convert from dropdown unit to variable's base unit
late final convertedValue; late final convertedValue;
if( value is Number ) { if( value is Number && input.unit != null ) {
convertedValue = widget.corpus.convert( convertedValue = widget.corpus.convert(
value, value,
_selectedUnits[input.name]!, _selectedUnits[input.name]!,
input.unit, input.unit as String,
); );
} }
else{ else{
@ -124,11 +124,17 @@ class _FormulaScreenState extends State<FormulaScreen> {
final result = evaluator.evaluate(widget.formula, inputValues); final result = evaluator.evaluate(widget.formula, inputValues);
// Convert output to selected unit if needed // Convert output to selected unit if needed
String? unit = widget.formula.output.unit;
if( unit != null ) {
_result = widget.corpus.convert( _result = widget.corpus.convert(
result, result,
widget.formula.output.unit, unit,
_selectedOutputUnit!, _selectedOutputUnit!,
).toStringAsFixed(2); ).toStringAsFixed(2);
}
else{
_result = result;
}
//print( "_evaluateFormula: result:${result} _result:${_result}"); //print( "_evaluateFormula: result:${result} _result:${_result}");

View file

@ -34,7 +34,7 @@ class Corpus{
if( checkUnits ){ if( checkUnits ){
for( final inputVar in formula.input + [formula.output] ){ for( final inputVar in formula.input + [formula.output] ){
if( !_allUnits.containsKey(inputVar.unit) ){ if( inputVar.unit != null && !_allUnits.containsKey(inputVar.unit) ){
throw ArgumentError( "Unit not found: ${inputVar.unit}"); throw ArgumentError( "Unit not found: ${inputVar.unit}");
} }
} }
@ -71,7 +71,10 @@ class Corpus{
} }
} }
List<String> unitsOfSameMagnitude(String unit){ List<String> unitsOfSameMagnitude(String? unit){
if( unit == null ){
return ["unitless"];
}
final base = getUnit(unit).baseUnit; final base = getUnit(unit).baseUnit;
return _baseToUnits[base] as List<String>; return _baseToUnits[base] as List<String>;
} }
@ -113,7 +116,7 @@ class Corpus{
} }
final ret = _convertUsingCode(x, unit.codeFromUnitToBase as String); final ret = _convertUsingCode(x, unit.codeFromUnitToBase as String);
return ret as Number; return ret;
} }
Number _convertFromBase(Number x, String toUnit) { Number _convertFromBase(Number x, String toUnit) {
@ -128,7 +131,7 @@ class Corpus{
} }
final ret = _convertUsingCode(x, unit.codeFromBaseToUnit as String); final ret = _convertUsingCode(x, unit.codeFromBaseToUnit as String);
return ret as Number; return ret;
} }
@ -140,17 +143,19 @@ class Corpus{
final ret = _evaluate(completeSourceExpression); final ret = _evaluate(completeSourceExpression);
return ret; return ret;
} }
catch(e1,stack){ catch(e1, stack1){
try{ try{
completeSourceStatement = _converterFromCodeStringAsStatement(x, code); completeSourceStatement = _converterFromCodeStringAsStatement(x, code);
final ret = _evaluate(completeSourceStatement); final ret = _evaluate(completeSourceStatement);
return ret; return ret;
} }
catch( e2, stack ){ catch( e2, stack2 ){
print(completeSourceExpression); print(completeSourceExpression);
print(e1); print(e1);
print(stack1);
print(completeSourceStatement); print(completeSourceStatement);
print(e2); print(e2);
print(stack2);
throw FormulaEvaluationException( "Evaluation as statement and expression failed" ); throw FormulaEvaluationException( "Evaluation as statement and expression failed" );
} }
} }

View file

@ -17,6 +17,7 @@ Future<Corpus> createDefaultCorpus() async{
"lib/defaults/units/force.d4rt.units", "lib/defaults/units/force.d4rt.units",
"lib/defaults/units/mass.d4rt.units", "lib/defaults/units/mass.d4rt.units",
"lib/defaults/units/pressure.d4rt.units", "lib/defaults/units/pressure.d4rt.units",
"lib/defaults/units/scalar.d4rt.units",
"lib/defaults/units/temperature.d4rt.units", "lib/defaults/units/temperature.d4rt.units",
"lib/defaults/units/time.d4rt.units", "lib/defaults/units/time.d4rt.units",
"lib/defaults/units/velocity.d4rt.units", "lib/defaults/units/velocity.d4rt.units",

View file

@ -126,13 +126,13 @@ Where:
"name": "Apgar Score", "name": "Apgar Score",
"description": "Newborn health assessment scoring system\n\nScores 0-2 for:\n1. Heart rate\n2. Breathing\n3. Muscle tone\n4. Reflexes\n5. Skin color\nTotal score 0-10", "description": "Newborn health assessment scoring system\n\nScores 0-2 for:\n1. Heart rate\n2. Breathing\n3. Muscle tone\n4. Reflexes\n5. Skin color\nTotal score 0-10",
"input": [ "input": [
{"name": "HeartRate", "unit": "integer"}, {"name": "HeartRate", "values": ["hr1", "hr2", "hr3"] },
{"name": "Breathing", "unit": "integer"}, {"name": "Breathing", "values": ["hr1", "hr2", "hr3"] },
{"name": "MuscleTone", "unit": "integer"}, {"name": "MuscleTone", "values": ["hr1", "hr2", "hr3"] },
{"name": "Reflexes", "unit": "integer"}, {"name": "Reflexes", "values": ["hr1", "hr2", "hr3"] },
{"name": "SkinColor", "unit": "integer"} {"name": "SkinColor", "values": ["hr1", "hr2", "hr3"] }
], ],
"output": {"name": "Result", "unit": "Apgar score"}, "output": {"name": "Result", "unit": "scalar"},
"d4rtCode": """ "d4rtCode": """
var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor; var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor;
var interpretation = switch (total) { var interpretation = switch (total) {

View file

@ -0,0 +1,3 @@
[
{"name": "scalar", "symbol": "", "isBase": true}
]

View file

@ -121,13 +121,7 @@ class FormulaEvaluator {
} }
} }
String getOutputVariableName(Formula formula) {
return formula.output.name;
}
String getOutputVariableMagnitude(Formula formula) {
return formula.output.unit;
}
List<String> getInputVariableOrder(Formula formula) { List<String> getInputVariableOrder(Formula formula) {
return formula.inputVarNames()..sort(); return formula.inputVarNames()..sort();
@ -166,9 +160,9 @@ class FormulaEvaluator {
} }
} }
buffer.writeln(""" buffer.writeln("""
late var ${getOutputVariableName(formula)}; late var ${formula.output.name};
${formula.d4rtCode} ${formula.d4rtCode}
return ${getOutputVariableName(formula)}; return ${formula.output.name};
} }
""" """
); );

View file

@ -101,12 +101,18 @@ class UnitSpec {
class VariableSpec { class VariableSpec {
final String name; final String name;
final String unit; final String? unit;
final List<dynamic>? allowedValues;
VariableSpec({required this.name, required this.unit}); VariableSpec({required this.name, this.unit, this.allowedValues}){
final valuesValid = allowedValues != null && allowedValues?.isNotEmpty == true;
if( unit == null && !valuesValid ){
throw new ArgumentError("$name: at least unit or allowedValues should be valid");
}
}
@override @override
String toString() => 'var($name: $unit)'; String toString() => 'var($name: $unit${allowedValues != null ? ' allowed: $allowedValues' : ''})';
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
@ -114,10 +120,11 @@ class VariableSpec {
other is VariableSpec && other is VariableSpec &&
runtimeType == other.runtimeType && runtimeType == other.runtimeType &&
unit == other.unit && unit == other.unit &&
name == other.name; name == other.name &&
const DeepCollectionEquality().equals(allowedValues, other.allowedValues);
@override @override
int get hashCode => Object.hash(unit, name); int get hashCode => Object.hash(unit, name, allowedValues != null ? const DeepCollectionEquality().hash(allowedValues!) : 0);
} }
class Formula { class Formula {
@ -196,8 +203,25 @@ class Formula {
factory Formula.fromSet(Map<Object?, Object?> theSet) { factory Formula.fromSet(Map<Object?, Object?> theSet) {
VariableSpec parseVar(Map<Object?, Object?> varSpec) { VariableSpec parseVar(Map<Object?, Object?> varSpec) {
String name = SetUtils.stringValue(varSpec, "name"); String name = SetUtils.stringValue(varSpec, "name");
String unit = SetUtils.stringValue(varSpec, "unit"); String? unit;
return VariableSpec(name: name, unit: unit); if (varSpec.containsKey("unit")) {
unit = SetUtils.stringValue(varSpec, "unit");
}
final allowed = varSpec['values'] as List<dynamic>?;
if (allowed != null) {
final types = allowed.map((v) => v.runtimeType).toSet();
if (types.length > 1) {
throw ArgumentError('Allowed values must be all Strings or all Numbers');
}
if (!types.contains(String) && !types.contains(double) && !types.contains(int)) {
throw ArgumentError('Allowed values must be Strings or Numbers');
}
}
return VariableSpec(
name: name,
unit: unit,
allowedValues: allowed?.toList(growable: false),
);
} }
String name = SetUtils.stringValue(theSet, "name"); String name = SetUtils.stringValue(theSet, "name");

View file

@ -29,6 +29,7 @@ main(){
} }
"""; """;
final interpreter = D4rt(); final interpreter = D4rt();
interpreter.grant(FilesystemPermission.readPath("/etc/passwd"));
final result = interpreter.execute(source: completeSource); final result = interpreter.execute(source: completeSource);
expect(result, contains("root")); expect(result, contains("root"));

View file

@ -152,7 +152,7 @@ void main() {
d4rtCode: 'force = x;', d4rtCode: 'force = x;',
); );
expect(evaluator.getOutputVariableName(formula), 'force'); expect(formula.output.name, 'force');
}); });
test( test(
@ -165,7 +165,7 @@ void main() {
d4rtCode: 'force = x;', d4rtCode: 'force = x;',
); );
expect(evaluator.getOutputVariableMagnitude(formula), 'Newton'); expect(formula.output.unit, 'Newton');
}, },
); );
@ -177,8 +177,8 @@ void main() {
d4rtCode: 'result = x;', d4rtCode: 'result = x;',
); );
expect(evaluator.getOutputVariableName(validFormula), 'result'); expect(validFormula.output.name, 'result');
expect(evaluator.getOutputVariableMagnitude(validFormula), 'Newton'); expect(validFormula.output.unit, 'Newton');
}); });
}); });