antes de drift

This commit is contained in:
Your Name 2026-02-07 16:16:00 +01:00
parent 0f3424b58d
commit 20a981ad9f
8 changed files with 370 additions and 16 deletions

View file

@ -16,10 +16,10 @@
"description": r""" "description": r"""
Calculates vertical displacement under constant gravity Calculates vertical displacement under constant gravity
$$h = \\frac{1}{2}gt^2$$ $$h = \frac{1}{2}gt^2$$
Where: Where:
- $g$: Gravitational acceleration ($9.81\\ \\mathrm{m/s^2}$ on Earth) - $g$: Gravitational acceleration $9.81\ \mathrm{m/s^2}$ on Earth
- $t$: Time in free fall (seconds) - $t$: Time in free fall (seconds)
![Free Fall Diagram](https://altcalculator.com/wp-content/uploads/2023/08/Free-Fall.png)""", ![Free Fall Diagram](https://altcalculator.com/wp-content/uploads/2023/08/Free-Fall.png)""",
@ -38,10 +38,10 @@ Where:
"description": r''' "description": r'''
Newton's law of universal gravitation Newton's law of universal gravitation
\(F = G\\frac{m_1m_2}{r^2}\) \(F = G\frac{m_1m_2}{r^2}\)
Where: Where:
- $G$: Gravitational constant ($6.674\\times 10^{-11}\\ \\mathrm{N\\cdot m^2/kg^2}$) - $G$: Gravitational constant ($6.674\times 10^{-11}\ \mathrm{N\cdot m^2/kg^2}$)
- $m_1, m_2$: Masses of two objects - $m_1, m_2$: Masses of two objects
- $r$: Distance between centers of masses - $r$: Distance between centers of masses
@ -62,7 +62,7 @@ Where:
"description": r''' "description": r'''
Energy possessed by a moving object Energy possessed by a moving object
$$KE = \\frac{1}{2}mv^2$$ $$KE = \frac{1}{2}mv^2$$
Where: Where:
- $m$: Mass of object - $m$: Mass of object
@ -82,10 +82,10 @@ Where:
{ {
"name": "Projectile Range", "name": "Projectile Range",
"description": r"""Calculates horizontal distance of projectile motion "description": r"""Calculates horizontal distance of projectile motion
$$R = \\frac{v^2 \\sin(2\\theta)}{g}$$ $$R = \frac{v^2 \sin(2\theta)}{g}$$
Where: Where:
- $v$: Initial velocity - $v$: Initial velocity
- $\\theta$: Launch angle - $\theta$: Launch angle
- $g$: Gravitational acceleration - $g$: Gravitational acceleration
![Projectile Motion](https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Projectile_motion_diagram.png/800px-Projectile_motion_diagram.png)""", ![Projectile Motion](https://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Projectile_motion_diagram.png/800px-Projectile_motion_diagram.png)""",
"input": [ "input": [
@ -105,11 +105,11 @@ Where:
"description": r''' "description": r'''
Force equals mass times acceleration Force equals mass times acceleration
$$F = m \\cdot a$$ $$F = m \cdot a$$
Where: Where:
- $m$: Mass of object ($\\mathrm{kg}$) - $m$: Mass of object ($\mathrm{kg}$)
- $a$: Acceleration ($\\mathrm{m/s^2}$) - $a$: Acceleration ($\mathrm{m/s^2}$)
![Newton's Second Law](https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Newtonslawsofmotion.jpg/800px-Newtonslawsofmotion.jpg)''', ![Newton's Second Law](https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Newtonslawsofmotion.jpg/800px-Newtonslawsofmotion.jpg)''',
"input": [ "input": [
@ -186,7 +186,7 @@ $$E = mc^2$$
Where: Where:
- $E$: Energy (Joules) - $E$: Energy (Joules)
- $m$: Mass (kilograms) - $m$: Mass (kilograms)
- $c$: Speed of light ($299,792,458\\ \\mathrm{m/s}$) - $c$: Speed of light $299,792,458$ $\mathrm{m/s}$
This equation shows that mass can be converted to energy and vice versa.''', This equation shows that mass can be converted to energy and vice versa.''',
"input": [ "input": [
@ -249,7 +249,7 @@ The negative sign indicates the force opposes the displacement.''',
"description": r''' "description": r'''
Force required to keep an object moving in circular motion Force required to keep an object moving in circular motion
$$F = \\frac{mv^2}{r}$$ $$F = \frac{mv^2}{r}$$
Where: Where:
- $F$: Centripetal force (Newtons) - $F$: Centripetal force (Newtons)
@ -274,7 +274,7 @@ This force acts toward the center of the circle.''',
"description": r''' "description": r'''
Relationship between wave speed, frequency, and wavelength Relationship between wave speed, frequency, and wavelength
$$v = f\\lambda$$ $$v = f\lambda$$
Where: Where:
- $v$: Wave speed (m/s) - $v$: Wave speed (m/s)
@ -319,7 +319,7 @@ The square of the hypotenuse is equal to the sum of squares of the other two sid
"description": r''' "description": r'''
Relationship between the sides and angles of any triangle Relationship between the sides and angles of any triangle
$$\\frac{a}{\\sin A} = \\frac{b}{\\sin B} = \\frac{c}{\\sin C}$$ $$\frac{a}{\sin A} = \frac{b}{\sin B} = \frac{c}{\sin C}$$
Where: Where:
- $a$, $b$, $c$: Sides of the triangle - $a$, $b$, $c$: Sides of the triangle
@ -346,7 +346,7 @@ This rule is useful for solving triangles when certain combinations of angles an
"description": r''' "description": r'''
Generalization of the Pythagorean theorem for any triangle Generalization of the Pythagorean theorem for any triangle
$$c^2 = a^2 + b^2 - 2ab\\cos(C)$$ $$c^2 = a^2 + b^2 - 2ab\cos(C)$$
Where: Where:
- $a$, $b$, $c$: Sides of the triangle - $a$, $b$, $c$: Sides of the triangle
@ -372,7 +372,7 @@ This rule relates all three sides of a triangle to one of its angles.''',
"description": r''' "description": r'''
Fundamental Pythagorean identity in trigonometry Fundamental Pythagorean identity in trigonometry
$$\\sin^2(\\theta) + \\cos^2(\\theta) = 1$$ $$\sin^2(\theta) + \cos^2(\theta) = 1$$
Where: Where:
- $\theta$: Any angle in radians or degrees - $\theta$: Any angle in radians or degrees

View file

@ -0,0 +1,19 @@
[
{
"name": "newton per meter",
"symbol": "N/m",
"isBase": true
},
{
"name": "newton per centimeter",
"symbol": "N/cm",
"baseUnit": "newton per meter",
"factor": 100
},
{
"name": "kilonewton per meter",
"symbol": "kN/m",
"baseUnit": "newton per meter",
"factor": 1000
}
]

View file

@ -0,0 +1,53 @@
[
{
"name": "ampere",
"symbol": "A",
"isBase": true
},
{
"name": "milliampere",
"symbol": "mA",
"baseUnit": "ampere",
"factor": 0.001
},
{
"name": "microampere",
"symbol": "µA",
"baseUnit": "ampere",
"factor": 0.000001
},
{
"name": "ohm",
"symbol": "Ω",
"isBase": true
},
{
"name": "kiloohm",
"symbol": "kΩ",
"baseUnit": "ohm",
"factor": 1000
},
{
"name": "megaohm",
"symbol": "MΩ",
"baseUnit": "ohm",
"factor": 1000000
},
{
"name": "volt",
"symbol": "V",
"isBase": true
},
{
"name": "millivolt",
"symbol": "mV",
"baseUnit": "volt",
"factor": 0.001
},
{
"name": "kilovolt",
"symbol": "kV",
"baseUnit": "volt",
"factor": 1000
}
]

View file

@ -0,0 +1,25 @@
[
{
"name": "hertz",
"symbol": "Hz",
"isBase": true
},
{
"name": "kilohertz",
"symbol": "kHz",
"baseUnit": "hertz",
"factor": 1000
},
{
"name": "megahertz",
"symbol": "MHz",
"baseUnit": "hertz",
"factor": 1000000
},
{
"name": "gigahertz",
"symbol": "GHz",
"baseUnit": "hertz",
"factor": 1000000000
}
]

View file

@ -1,6 +1,8 @@
// dart // dart
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter_markdown_latex/flutter_markdown_latex.dart';
import 'package:markdown/markdown.dart' as markdown;
import '../formula_models.dart'; import '../formula_models.dart';
import '../formula_evaluator.dart'; import '../formula_evaluator.dart';
import '../corpus.dart'; import '../corpus.dart';
@ -215,6 +217,13 @@ class _FormulaScreenState extends State<FormulaScreen> {
child: MarkdownBody( child: MarkdownBody(
data: widget.formula.description!, data: widget.formula.description!,
shrinkWrap: true, shrinkWrap: true,
builders: {
'latex': LatexElementBuilder(),
},
extensionSet: markdown.ExtensionSet(
[LatexBlockSyntax()],
[LatexInlineSyntax()],
),
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),

View file

@ -198,6 +198,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.7+1" version: "0.7.7+1"
flutter_markdown_latex:
dependency: "direct main"
description:
name: flutter_markdown_latex
sha256: "839e76a84abb3632ffcebbd450cf93c7e9894af65622527d23f0084cee1bfd04"
url: "https://pub.dev"
source: hosted
version: "0.3.4"
flutter_math_fork:
dependency: transitive
description:
name: flutter_math_fork
sha256: "6d5f2f1aa57ae539ffb0a04bb39d2da67af74601d685a161aff7ce5bda5fa407"
url: "https://pub.dev"
source: hosted
version: "0.7.4"
flutter_svg:
dependency: transitive
description:
name: flutter_svg
sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -376,6 +400,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
node_preamble: node_preamble:
dependency: transitive dependency: transitive
description: description:
@ -400,6 +432,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.9.1"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1"
url: "https://pub.dev"
source: hosted
version: "7.0.1"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -416,6 +464,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.5.2" version: "1.5.2"
provider:
dependency: transitive
description:
name: provider
sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
url: "https://pub.dev"
source: hosted
version: "6.1.5+1"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:
@ -637,6 +693,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.5" version: "3.1.5"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6
url: "https://pub.dev"
source: hosted
version: "1.1.19"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
url: "https://pub.dev"
source: hosted
version: "1.1.13"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "201e876b5d52753626af64b6359cd13ac6011b80728731428fd34bc840f71c9b"
url: "https://pub.dev"
source: hosted
version: "1.1.20"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -693,6 +773,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
xml:
dependency: transitive
description:
name: xml
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
url: "https://pub.dev"
source: hosted
version: "6.6.1"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:

View file

@ -38,6 +38,7 @@ dependencies:
d4rt: d4rt:
flutter_d4rt: flutter_d4rt:
flutter_markdown: flutter_markdown:
flutter_markdown_latex:
flutter_code_editor: flutter_code_editor:
collection: any collection: any

View file

@ -0,0 +1,159 @@
import 'package:d4rt_formulas/corpus.dart';
import 'package:d4rt_formulas/defaults/default_corpus.dart';
import 'package:d4rt_formulas/formula_evaluator.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:d4rt_formulas/formula_models.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
Future<Corpus> createTestCorpus() async {
return createDefaultCorpus();
}
Future<Corpus> testCorpus = createTestCorpus();
group('Physics Formulas Tests', () {
test('evaluates Mass-Energy Equivalence formula (E=mc²)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Mass-Energy Equivalence")!;
final evaluator = FormulaEvaluator();
// Test with 1 kg of mass
final result = evaluator.evaluate(formula, {
'm': 1.0, // 1 kg
});
// E = mc² = 1 * (299792458)² 8.98755179 × 10^16 Joules
expect(result, closeTo(8.98755179e16, 1e12));
});
test('evaluates Ohm\'s Law formula (V=IR)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Ohm's Law")!;
final evaluator = FormulaEvaluator();
// Test with 2 amperes and 5 ohms
final result = evaluator.evaluate(formula, {
'I': 2.0, // 2 Amperes
'R': 5.0, // 5 Ohms
});
// V = I * R = 2 * 5 = 10 Volts
expect(result, 10.0);
});
test('evaluates Hooke\'s Law formula (F=-kx)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Hooke's Law")!;
final evaluator = FormulaEvaluator();
// Test with spring constant k=100 N/m and displacement x=0.5 m
final result = evaluator.evaluate(formula, {
'k': 100.0, // 100 N/m
'x': 0.5, // 0.5 m
});
// F = -k * x = -100 * 0.5 = -50 N
expect(result, -50.0);
});
test('evaluates Centripetal Force formula (F=mv²/r)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Centripetal Force")!;
final evaluator = FormulaEvaluator();
// Test with m=10 kg, v=5 m/s, r=2 m
final result = evaluator.evaluate(formula, {
'm': 10.0, // 10 kg
'v': 5.0, // 5 m/s
'r': 2.0, // 2 m
});
// F = (m * v²) / r = (10 * 25) / 2 = 250 / 2 = 125 N
expect(result, 125.0);
});
test('evaluates Wave Equation formula (v=fλ)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Wave Equation")!;
final evaluator = FormulaEvaluator();
// Test with frequency f=50 Hz and wavelength λ=2 m
final result = evaluator.evaluate(formula, {
'f': 50.0, // 50 Hz
'lambda': 2.0, // 2 m
});
// v = f * λ = 50 * 2 = 100 m/s
expect(result, 100.0);
});
});
group('Trigonometry Formulas Tests', () {
test('evaluates Pythagorean Theorem formula (a²+b²=c²)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Pythagorean Theorem")!;
final evaluator = FormulaEvaluator();
// Test with a=3, b=4 (classic 3-4-5 triangle)
final result = evaluator.evaluate(formula, {
'a': 3.0, // 3 m
'b': 4.0, // 4 m
});
// c = (a² + b²) = (9 + 16) = 25 = 5
expect(result, 5.0);
});
test('evaluates Sine Rule formula (a/sin A = b/sin B)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Sine Rule")!;
final evaluator = FormulaEvaluator();
// Test with a=5, angle A=30°, angle B=60°
final result = evaluator.evaluate(formula, {
'a': 5.0, // Side a = 5 m
'A': 30.0, // Angle A = 30 degrees
'B': 60.0, // Angle B = 60 degrees
});
// b = (a * sin(B)) / sin(A) = (5 * sin(60°)) / sin(30°)
// b = (5 * 0.866) / 0.5 = 4.33 / 0.5 = 8.66
expect(result, closeTo(8.66, 0.01));
});
test('evaluates Cosine Rule formula (c²=a²+b²-2ab cos C)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Cosine Rule")!;
final evaluator = FormulaEvaluator();
// Test with a=5, b=7, angle C=60°
final result = evaluator.evaluate(formula, {
'a': 5.0, // Side a = 5 m
'b': 7.0, // Side b = 7 m
'C': 60.0, // Angle C = 60 degrees
});
// c = (a² + b² - 2ab*cos(C))
// c = (25 + 49 - 2*5*7*cos(60°))
// c = (74 - 70*0.5) = (74 - 35) = 39 6.24
expect(result, closeTo(6.24, 0.01));
});
test('evaluates Trigonometric Identity formula (sin²θ + cos²θ = 1)', () async {
final corpus = await testCorpus;
final formula = corpus.getFormula("Trigonometric Identity")!;
final evaluator = FormulaEvaluator();
// Test with θ=45°
final result = evaluator.evaluate(formula, {
'theta': 45.0, // 45 degrees
});
// sin²(45°) + cos²(45°) should equal 1
// (0.707)² + (0.707)² = 0.5 + 0.5 = 1
expect(result, closeTo(1.0, 0.001));
});
});
}