From d3dce8794c114a0900146536e57695319f0120c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gonz=C3=A1lez?= Date: Sun, 21 Sep 2025 16:35:54 +0200 Subject: [PATCH] removing initial unit list, more units and formulas --- lib/corpus.dart | 5 + lib/defaults/default_corpus.dart | 1 + lib/defaults/formulas.d4rt | 28 ++--- lib/defaults/units/time.d4rt.units | 31 ++++++ lib/defaults/units/velocity.d4rt.units | 25 +++-- lib/main.dart | 143 +++++-------------------- test/widget_test.dart | 30 ------ 7 files changed, 92 insertions(+), 171 deletions(-) create mode 100644 lib/defaults/units/time.d4rt.units delete mode 100644 test/widget_test.dart diff --git a/lib/corpus.dart b/lib/corpus.dart index 2a13df5..5d782ac 100644 --- a/lib/corpus.dart +++ b/lib/corpus.dart @@ -54,6 +54,10 @@ class Corpus{ return _tags[tag]?.toList(growable:false) as List; } + List getFormulas(){ + return _allFormulas.values.toList(growable:false); + } + final Multimap _baseToUnits = Multimap.create(); final Map _allUnits = {}; @@ -75,6 +79,7 @@ class Corpus{ UnitSpec getUnit(String unit) { if (!_allUnits.containsKey(unit)) { + print( _allUnits.keys.join(",") ); throw ArgumentError("Unit not found:$unit"); } return _allUnits.get(unit); diff --git a/lib/defaults/default_corpus.dart b/lib/defaults/default_corpus.dart index fffefd4..374e2a2 100644 --- a/lib/defaults/default_corpus.dart +++ b/lib/defaults/default_corpus.dart @@ -17,6 +17,7 @@ Future createDefaultCorpus() async{ "lib/defaults/units/temperature.d4rt.units", "lib/defaults/units/velocity.d4rt.units", "lib/defaults/units/mass.d4rt.units", + "lib/defaults/units/time.d4rt.units", "lib/defaults/units/angle.d4rt.units", ]; diff --git a/lib/defaults/formulas.d4rt b/lib/defaults/formulas.d4rt index c3f7a48..2f32507 100644 --- a/lib/defaults/formulas.d4rt +++ b/lib/defaults/formulas.d4rt @@ -14,9 +14,9 @@ Where: ![Free Fall Diagram](https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/Free-fall.svg/1200px-Free-fall.svg.png)''', "input": [ {"name": "t", "unit": "second"}, // Time in seconds - {"name": "g", "unit": "m/s²"} // Gravitational acceleration + {"name": "g", "unit": "meters per second"} // Gravitational acceleration ], - "output": {"name": "h", "unit": "m"}, // Height in meters + "output": {"name": "h", "unit": "meter"}, // Height in meters "d4rtCode": "h = 0.5 * g * pow(t, 2)", "tags": ["physics", "kinematics"] }, @@ -36,11 +36,11 @@ Where: ![Gravitation](https://upload.wikimedia.org/wikipedia/commons/thumb/3/33/NewtonsLawOfUniversalGravitation.svg/1200px-NewtonsLawOfUniversalGravitation.svg.png)''', "input": [ - {"name": "m1", "unit": "kg"}, // Mass 1 - {"name": "m2", "unit": "kg"}, // Mass 2 - {"name": "r", "unit": "m"} // Distance between masses + {"name": "m1", "unit": "kilogram"}, // Mass 1 + {"name": "m2", "unit": "kilogram"}, // Mass 2 + {"name": "r", "unit": "meter"} // Distance between masses ], - "output": {"name": "F", "unit": "N"}, // Force in newtons + "output": {"name": "F", "unit": "newton"}, // Force in newtons "d4rtCode": "F = (6.67430e-11 * m1 * m2) / pow(r, 2)", "tags": ["physics", "astronomy", "gravity"] }, @@ -59,10 +59,10 @@ Where: ![Kinetic Energy](https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Kinetic_energy.svg/1200px-Kinetic_energy.svg.png)''', "input": [ - {"name": "m", "unit": "kg"}, // Mass - {"name": "v", "unit": "m/s"} // Velocity + {"name": "m", "unit": "kilogram"}, // Mass + {"name": "v", "unit": "meters per second"} // Velocity ], - "output": {"name": "KE", "unit": "J"}, // Energy in joules + "output": {"name": "KE", "unit": "joule"}, // Energy in joules "d4rtCode": "KE = 0.5 * m * pow(v, 2)", "tags": ["physics", "energy", "mechanics"] }, @@ -78,8 +78,8 @@ Where: "- `g` = Gravitational acceleration\n\n" "![Projectile Motion](https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Projectile_motion_diagram.png/800px-Projectile_motion_diagram.png)", "input": [ - {"name": "v", "unit": "m/s"}, // Initial velocity - {"name": "θ", "unit": "deg"} // Launch angle + {"name": "v", "unit": "meters per second"}, // Initial velocity + {"name": "θ", "unit": "degree"} // Launch angle ], "output": {"name": "R", "unit": "m"}, // Horizontal distance "d4rtCode": "R = (pow(v, 2) * sin(2 * radians(θ))) / 9.80665", @@ -99,10 +99,10 @@ Where: ![Newton's Second Law](https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Newtonslawsofmotion.jpg/800px-Newtonslawsofmotion.jpg)''', "input": [ - {"name": "m", "unit": "kg"}, // Mass - {"name": "a", "unit": "m/s²"} // Acceleration + {"name": "m", "unit": "kilogram"}, // Mass + {"name": "a", "unit": "meters per square second"} // Acceleration ], - "output": {"name": "F", "unit": "N"}, // Force in newtons + "output": {"name": "F", "unit": "newton"}, // Force in newtons "d4rtCode": "F = m * a", "tags": ["physics", "mechanics", "newton"] }, diff --git a/lib/defaults/units/time.d4rt.units b/lib/defaults/units/time.d4rt.units new file mode 100644 index 0000000..be766e6 --- /dev/null +++ b/lib/defaults/units/time.d4rt.units @@ -0,0 +1,31 @@ +[ + { + "name": "second", + "symbol": "s", + "isBase": true + }, + { + "name": "minute", + "symbol": "min", + "baseUnit": "second", + "factor": 60 + }, + { + "name": "hour", + "symbol": "hr", + "baseUnit": "second", + "factor": 3600 + }, + { + "name": "day", + "symbol": "d", + "baseUnit": "second", + "factor": 86400 + }, + { + "name": "week", + "symbol": "wk", + "baseUnit": "second", + "factor": 604800 + } +] \ No newline at end of file diff --git a/lib/defaults/units/velocity.d4rt.units b/lib/defaults/units/velocity.d4rt.units index 3699cce..96c7f88 100644 --- a/lib/defaults/units/velocity.d4rt.units +++ b/lib/defaults/units/velocity.d4rt.units @@ -1,37 +1,44 @@ [ { - "name": "meters_per_second", + "name": "meters per second", "symbol": "m/s", "isBase": true }, + { - "name": "kilometers_per_hour", + "name": "meters per square second", + "symbol": "m/s²", + "isBase": true + }, + + { + "name": "kilometers per hour", "symbol": "km/h", - "baseUnit": "meters_per_second", + "baseUnit": "meters per second", "factor": 0.277778 }, { - "name": "miles_per_hour", + "name": "miles per hour", "symbol": "mph", - "baseUnit": "meters_per_second", + "baseUnit": "meters per second", "factor": 0.44704 }, { - "name": "feet_per_second", + "name": "feet per second", "symbol": "ft/s", - "baseUnit": "meters_per_second", + "baseUnit": "meters per second", "factor": 0.3048 }, { "name": "knot", "symbol": "kn", - "baseUnit": "meters_per_second", + "baseUnit": "meters per second", "factor": 0.514444 }, { "name": "mach", "symbol": "M", - "baseUnit": "meters_per_second", + "baseUnit": "meters per second", "factor": 343.0 } ] diff --git a/lib/main.dart b/lib/main.dart index f67246c..dda93b2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:resource_portable/resource.dart' show Resource; import 'dart:convert'; -import 'ai/unit_list.dart'; +import 'ai/formula_screen.dart'; import 'corpus.dart'; import 'defaults/default_corpus.dart'; @@ -17,7 +17,30 @@ void main() { if (snapshot.hasError) { return Center(child: Text('Error loading units: ${snapshot.error}')); } - return UnitList(corpus: snapshot.data!); + return Scaffold( + appBar: AppBar(title: const Text('Formulas')), + body: ListView.builder( + itemCount: snapshot.data!.getFormulas().length, + itemBuilder: (context, index) { + final formula = snapshot.data!.getFormulas()[index]; + return ListTile( + title: Text(formula.name), + subtitle: Text(formula.description ?? ''), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FormulaScreen( + formula: formula, + corpus: snapshot.data!, + ), + ), + ); + }, + ); + }, + ), + ); } return const Center(child: CircularProgressIndicator()); }, @@ -26,119 +49,3 @@ void main() { } -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // TRY THIS: Try running your application with "flutter run". You'll see - // the application has a purple toolbar. Then, without quitting the app, - // try changing the seedColor in the colorScheme below to Colors.green - // and then invoke "hot reload" (save your changes or press the "hot - // reload" button in a Flutter-supported IDE, or press "r" if you used - // the command line to start the app). - // - // Notice that the counter didn't reset back to zero; the application - // state is not lost during the reload. To reset the state, use hot - // restart instead. - // - // This works for code too, not just values: Most code changes can be - // tested with just a hot reload. - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // TRY THIS: Try changing the color here to a specific color (to - // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar - // change color while the other colors stay the same. - backgroundColor: Theme.of(context).colorScheme.inversePrimary, - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text('You have pushed the button this many times:'), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index 8da5160..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:d4rt_formulas/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -}