preparando apgar
This commit is contained in:
parent
e04276cb2a
commit
13612e7601
10 changed files with 74 additions and 40 deletions
|
|
@ -37,8 +37,8 @@ void main() {
|
|||
print(' Mass: 10.0 kg');
|
||||
print(' Acceleration: 9.8 m/s²');
|
||||
print(' Calculated Force: $force N');
|
||||
print(' Output variable: ${evaluator.getOutputVariableName(newtonFormula)}');
|
||||
print(' Output magnitude: ${evaluator.getOutputVariableMagnitude(newtonFormula)}');
|
||||
print(' Output variable: ${newtonFormula.output.name}');
|
||||
print(' Output magnitude: ${newtonFormula.output.unit}');
|
||||
} catch (e) {
|
||||
print(' Error: $e');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,11 +105,11 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
// Convert input to base unit if needed
|
||||
// Always convert from dropdown unit to variable's base unit
|
||||
late final convertedValue;
|
||||
if( value is Number ) {
|
||||
if( value is Number && input.unit != null ) {
|
||||
convertedValue = widget.corpus.convert(
|
||||
value,
|
||||
_selectedUnits[input.name]!,
|
||||
input.unit,
|
||||
input.unit as String,
|
||||
);
|
||||
}
|
||||
else{
|
||||
|
|
@ -124,11 +124,17 @@ class _FormulaScreenState extends State<FormulaScreen> {
|
|||
final result = evaluator.evaluate(widget.formula, inputValues);
|
||||
|
||||
// Convert output to selected unit if needed
|
||||
String? unit = widget.formula.output.unit;
|
||||
if( unit != null ) {
|
||||
_result = widget.corpus.convert(
|
||||
result,
|
||||
widget.formula.output.unit,
|
||||
unit,
|
||||
_selectedOutputUnit!,
|
||||
).toStringAsFixed(2);
|
||||
}
|
||||
else{
|
||||
_result = result;
|
||||
}
|
||||
|
||||
//print( "_evaluateFormula: result:${result} _result:${_result}");
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class Corpus{
|
|||
|
||||
if( checkUnits ){
|
||||
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}");
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
return _baseToUnits[base] as List<String>;
|
||||
}
|
||||
|
|
@ -113,7 +116,7 @@ class Corpus{
|
|||
}
|
||||
|
||||
final ret = _convertUsingCode(x, unit.codeFromUnitToBase as String);
|
||||
return ret as Number;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Number _convertFromBase(Number x, String toUnit) {
|
||||
|
|
@ -128,7 +131,7 @@ class Corpus{
|
|||
}
|
||||
|
||||
final ret = _convertUsingCode(x, unit.codeFromBaseToUnit as String);
|
||||
return ret as Number;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -140,17 +143,19 @@ class Corpus{
|
|||
final ret = _evaluate(completeSourceExpression);
|
||||
return ret;
|
||||
}
|
||||
catch(e1,stack){
|
||||
catch(e1, stack1){
|
||||
try{
|
||||
completeSourceStatement = _converterFromCodeStringAsStatement(x, code);
|
||||
final ret = _evaluate(completeSourceStatement);
|
||||
return ret;
|
||||
}
|
||||
catch( e2, stack ){
|
||||
catch( e2, stack2 ){
|
||||
print(completeSourceExpression);
|
||||
print(e1);
|
||||
print(stack1);
|
||||
print(completeSourceStatement);
|
||||
print(e2);
|
||||
print(stack2);
|
||||
throw FormulaEvaluationException( "Evaluation as statement and expression failed" );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ Future<Corpus> createDefaultCorpus() async{
|
|||
"lib/defaults/units/force.d4rt.units",
|
||||
"lib/defaults/units/mass.d4rt.units",
|
||||
"lib/defaults/units/pressure.d4rt.units",
|
||||
"lib/defaults/units/scalar.d4rt.units",
|
||||
"lib/defaults/units/temperature.d4rt.units",
|
||||
"lib/defaults/units/time.d4rt.units",
|
||||
"lib/defaults/units/velocity.d4rt.units",
|
||||
|
|
|
|||
|
|
@ -126,13 +126,13 @@ Where:
|
|||
"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",
|
||||
"input": [
|
||||
{"name": "HeartRate", "unit": "integer"},
|
||||
{"name": "Breathing", "unit": "integer"},
|
||||
{"name": "MuscleTone", "unit": "integer"},
|
||||
{"name": "Reflexes", "unit": "integer"},
|
||||
{"name": "SkinColor", "unit": "integer"}
|
||||
{"name": "HeartRate", "values": ["hr1", "hr2", "hr3"] },
|
||||
{"name": "Breathing", "values": ["hr1", "hr2", "hr3"] },
|
||||
{"name": "MuscleTone", "values": ["hr1", "hr2", "hr3"] },
|
||||
{"name": "Reflexes", "values": ["hr1", "hr2", "hr3"] },
|
||||
{"name": "SkinColor", "values": ["hr1", "hr2", "hr3"] }
|
||||
],
|
||||
"output": {"name": "Result", "unit": "Apgar score"},
|
||||
"output": {"name": "Result", "unit": "scalar"},
|
||||
"d4rtCode": """
|
||||
var total = HeartRate + Breathing + MuscleTone + Reflexes + SkinColor;
|
||||
var interpretation = switch (total) {
|
||||
|
|
|
|||
3
lib/defaults/units/scalar.d4rt.units
Normal file
3
lib/defaults/units/scalar.d4rt.units
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[
|
||||
{"name": "scalar", "symbol": "", "isBase": true}
|
||||
]
|
||||
|
|
@ -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) {
|
||||
return formula.inputVarNames()..sort();
|
||||
|
|
@ -166,9 +160,9 @@ class FormulaEvaluator {
|
|||
}
|
||||
}
|
||||
buffer.writeln("""
|
||||
late var ${getOutputVariableName(formula)};
|
||||
late var ${formula.output.name};
|
||||
${formula.d4rtCode}
|
||||
return ${getOutputVariableName(formula)};
|
||||
return ${formula.output.name};
|
||||
}
|
||||
"""
|
||||
);
|
||||
|
|
|
|||
|
|
@ -101,12 +101,18 @@ class UnitSpec {
|
|||
|
||||
class VariableSpec {
|
||||
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
|
||||
String toString() => 'var($name: $unit)';
|
||||
String toString() => 'var($name: $unit${allowedValues != null ? ' allowed: $allowedValues' : ''})';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
|
|
@ -114,10 +120,11 @@ class VariableSpec {
|
|||
other is VariableSpec &&
|
||||
runtimeType == other.runtimeType &&
|
||||
unit == other.unit &&
|
||||
name == other.name;
|
||||
name == other.name &&
|
||||
const DeepCollectionEquality().equals(allowedValues, other.allowedValues);
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(unit, name);
|
||||
int get hashCode => Object.hash(unit, name, allowedValues != null ? const DeepCollectionEquality().hash(allowedValues!) : 0);
|
||||
}
|
||||
|
||||
class Formula {
|
||||
|
|
@ -196,8 +203,25 @@ class Formula {
|
|||
factory Formula.fromSet(Map<Object?, Object?> theSet) {
|
||||
VariableSpec parseVar(Map<Object?, Object?> varSpec) {
|
||||
String name = SetUtils.stringValue(varSpec, "name");
|
||||
String unit = SetUtils.stringValue(varSpec, "unit");
|
||||
return VariableSpec(name: name, unit: unit);
|
||||
String? 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");
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ main(){
|
|||
}
|
||||
""";
|
||||
final interpreter = D4rt();
|
||||
interpreter.grant(FilesystemPermission.readPath("/etc/passwd"));
|
||||
final result = interpreter.execute(source: completeSource);
|
||||
|
||||
expect(result, contains("root"));
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ void main() {
|
|||
d4rtCode: 'force = x;',
|
||||
);
|
||||
|
||||
expect(evaluator.getOutputVariableName(formula), 'force');
|
||||
expect(formula.output.name, 'force');
|
||||
});
|
||||
|
||||
test(
|
||||
|
|
@ -165,7 +165,7 @@ void main() {
|
|||
d4rtCode: 'force = x;',
|
||||
);
|
||||
|
||||
expect(evaluator.getOutputVariableMagnitude(formula), 'Newton');
|
||||
expect(formula.output.unit, 'Newton');
|
||||
},
|
||||
);
|
||||
|
||||
|
|
@ -177,8 +177,8 @@ void main() {
|
|||
d4rtCode: 'result = x;',
|
||||
);
|
||||
|
||||
expect(evaluator.getOutputVariableName(validFormula), 'result');
|
||||
expect(evaluator.getOutputVariableMagnitude(validFormula), 'Newton');
|
||||
expect(validFormula.output.name, 'result');
|
||||
expect(validFormula.output.unit, 'Newton');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue