conversion is now a formula
All checks were successful
gitea.arg.rip/vassago/pipeline/head This commit looks good

This commit is contained in:
adam 2025-06-19 19:20:21 -04:00
parent b859d99c92
commit 76632b4543
6 changed files with 81 additions and 69 deletions

View File

@ -19,8 +19,8 @@ public class UnitConvert : Behavior
if (theseMatches != null && theseMatches.Count > 0 && theseMatches[0].Groups != null && theseMatches[0].Groups.Count == 5) if (theseMatches != null && theseMatches.Count > 0 && theseMatches[0].Groups != null && theseMatches[0].Groups.Count == 5)
{ {
decimal asNumeric = 0; double asNumeric = 0;
if (decimal.TryParse(theseMatches[0].Groups[1].Value, out asNumeric)) if (double.TryParse(theseMatches[0].Groups[1].Value, out asNumeric))
{ {
Console.WriteLine("let's try and convert..."); Console.WriteLine("let's try and convert...");
Behaver.Instance.SendMessage(message.Channel.Id, Conversion.Converter.Convert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower())); Behaver.Instance.SendMessage(message.Channel.Id, Conversion.Converter.Convert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower()));

View File

@ -10,13 +10,14 @@ namespace vassago.Conversion
public string Canonical { get; set; } public string Canonical { get; set; }
public IEnumerable<string> Aliases { get; set; } public IEnumerable<string> Aliases { get; set; }
} }
public class LinearPair public class FormulaicPair
{ {
public string item1 { get; set; } public string item1 { get; set; }
public string item2 { get; set; } public string item2 { get; set; }
public decimal factor { get; set; } public string formulaforward {get; set; }
public string formulabackward {get; set; }
} }
public IEnumerable<KnownUnit> Units { get; set; } public IEnumerable<KnownUnit> Units { get; set; }
public IEnumerable<LinearPair> LinearPairs { get; set; } public IEnumerable<FormulaicPair> FormulaicPairs { get; set; }
} }
} }

View File

@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord; using Discord;
using Discord.WebSocket; using Discord.WebSocket;
using Jace;
using Newtonsoft.Json; using Newtonsoft.Json;
using QRCoder; using QRCoder;
@ -16,12 +17,12 @@ namespace vassago.Conversion
{ {
public static class Converter public static class Converter
{ {
private delegate decimal Convert1Way(decimal input);
private static string currencyPath; private static string currencyPath;
private static ExchangePairs currencyConf = null; private static ExchangePairs currencyConf = null;
private static DateTime lastUpdatedCurrency = DateTime.UnixEpoch; private static DateTime lastUpdatedCurrency = DateTime.UnixEpoch;
private static List<Tuple<string, string, Convert1Way, Convert1Way>> knownConversions = new List<Tuple<string, string, Convert1Way, Convert1Way>>(); private static List<Tuple<string, string,Func<double, double>, Func<double, double>>> knownConversions = new List<Tuple<string, string, Func<double, double>,Func<double, double>>>();
private static Dictionary<List<string>, string> knownAliases = new Dictionary<List<string>, string>(new List<KeyValuePair<List<string>, string>>()); private static Dictionary<List<string>, string> knownAliases = new Dictionary<List<string>, string>(new List<KeyValuePair<List<string>, string>>());
private static CalculationEngine engine = new CalculationEngine();
public static string DebugInfo() public static string DebugInfo()
{ {
var convertibles = knownConversions.Select(kc => kc.Item1).Union(knownConversions.Select(kc => kc.Item2)).Union( var convertibles = knownConversions.Select(kc => kc.Item1).Union(knownConversions.Select(kc => kc.Item2)).Union(
@ -44,16 +45,16 @@ namespace vassago.Conversion
} }
private static void loadStatic() private static void loadStatic()
{ {
knownConversions = new List<Tuple<string, string, Convert1Way, Convert1Way>>(); knownConversions = new List<Tuple<string, string, Func<double, double>, Func<double, double>>>();
knownAliases = new Dictionary<List<string>, string>(new List<KeyValuePair<List<string>, string>>()); knownAliases = new Dictionary<List<string>, string>(new List<KeyValuePair<List<string>, string>>());
var convConf = JsonConvert.DeserializeObject<ConversionConfig>(File.ReadAllText("assets/conversion.json").ToLower()); var convConf = JsonConvert.DeserializeObject<ConversionConfig>(File.ReadAllText("assets/conversion.json").ToLower());
foreach (var unit in convConf.Units) foreach (var unit in convConf.Units)
{ {
knownAliases.Add(unit.Aliases.ToList(), unit.Canonical); knownAliases.Add(unit.Aliases.ToList(), unit.Canonical);
} }
foreach (var lp in convConf.LinearPairs) foreach (var lp in convConf.FormulaicPairs)
{ {
AddLinearPair(lp.item1, lp.item2, lp.factor); AddLinearPair(lp.item1, lp.item2, lp.formulaforward, lp.formulabackward );
} }
loadCurrency(); loadCurrency();
} }
@ -78,12 +79,12 @@ namespace vassago.Conversion
{ {
knownAliases.Add(new List<string>() { rate.Key.ToLower() }, rate.Key); knownAliases.Add(new List<string>() { rate.Key.ToLower() }, rate.Key);
} }
AddLinearPair(currencyConf.Base, rate.Key, rate.Value); AddLinearPair(currencyConf.Base, rate.Key, $"i1 * {rate.Value}", $"i1 / {rate.Value}");
} }
} }
} }
public static string Convert(decimal numericTerm, string sourceunit, string destinationUnit) public static string Convert(double numericTerm, string sourceunit, string destinationUnit)
{ {
//normalize units //normalize units
var normalizationAttemptSource = NormalizeUnit(sourceunit.ToLower()); var normalizationAttemptSource = NormalizeUnit(sourceunit.ToLower());
@ -264,12 +265,20 @@ namespace vassago.Conversion
} }
return null; return null;
} }
private static void AddLinearPair(string key1, string key2, decimal factor) private static void AddLinearPair(string key1, string key2, string formulaForward, string formulaBackward)
{ {
var reverseFactor = 1.0m / factor; knownConversions.Add(new Tuple<string, string, Func<double, double>, Func<double, double>>(
knownConversions.Add(new Tuple<string, string, Convert1Way, Convert1Way>( key1,
key1, key2, x => x * factor, y => y * reverseFactor key2,
)); (Func<double, double>) engine.Formula(formulaForward)
.Parameter("i1", DataType.FloatingPoint)
.Result(DataType.FloatingPoint)
.Build(),
(Func<double, double>) engine.Formula(formulaBackward)
.Parameter("i1", DataType.FloatingPoint)
.Result(DataType.FloatingPoint)
.Build()
));
} }
} }
} }

View File

@ -171,7 +171,7 @@ public class DiscordInterface : ProtocolInterface
case "freedomunits": case "freedomunits":
try try
{ {
var amt = Convert.ToDecimal((double)(command.Data.Options.First(o => o.Name == "amount").Value)); var amt = (double)(command.Data.Options.First(o => o.Name == "amount").Value);
var src = (string)command.Data.Options.First(o => o.Name == "src-unit").Value; var src = (string)command.Data.Options.First(o => o.Name == "src-unit").Value;
var dest = (string)command.Data.Options.First(o => o.Name == "dest-unit").Value; var dest = (string)command.Data.Options.First(o => o.Name == "dest-unit").Value;
var conversionResult = Conversion.Converter.Convert(amt, src, dest); var conversionResult = Conversion.Converter.Convert(amt, src, dest);

View File

@ -1416,61 +1416,62 @@
] ]
} }
], ],
"linearPairs":[ "FormulaicPairs":[
{"item1":"kg", "item2":"g", "factor":1000}, {"item1":"°C", "item2":"℉", "formulaforward": "i1 * 1.8 + 32", "formulabackward": "(i1 - 32) / 1.8"},
{"item1":"lb", "item2":"oz", "factor":16},
{"item1":"kg", "item2":"lb", "factor":2.204623},
{"item1":"kg", "item2":"stone", "factor":0.157473},
{"item1":"km", "item2":"m", "factor":1000}, {"item1":"kg", "item2":"g", "formulaforward": "i1 * 1000", "formulabackward": "i1 / 1000"},
{"item1":"mi", "item2":"ft", "factor":5280}, {"item1":"lb", "item2":"oz", "formulaforward": "i1 * 16", "formulabackward": "i1 / 16"},
{"item1":"m", "item2":"in", "factor":39.37008}, {"item1":"kg", "item2":"lb", "formulaforward": "i1 * 2.204623", "formulabackward": "i1 / 2.204623"},
{"item1":"m", "item2":"cm", "factor":100}, {"item1":"kg", "item2":"stone", "formulaforward": "i1 * 0.157473", "formulabackward": "i1 / 0.157473"},
{"item1":"cm", "item2":"mm", "factor":10},
{"item1":"m", "item2":"μm", "factor":1000000},
{"item1":"km", "item2":"mi", "factor":0.6213712},
{"item1":"ft", "item2":"in", "factor":12},
{"item1":"yd", "item2":"ft", "factor":3},
{"item1":"football field", "item2":"yd", "factor":100},
{"item1":"chain", "item2":"yd", "factor":22},
{"item1":"chain", "item2":"link", "factor":100},
{"item1":"furlong", "item2":"mi", "factor":8},
{"item1":"rod", "item2":"ft", "factor":16.5},
{"item1":"AU", "item2":"ly", "factor": 0.0000158125},
{"item1":"ly", "item2":"km", "factor": 946070000000},
{"item1":"pc", "item2":"AU", "factor":206266.3},
{"item1":"blue whale length", "item2": "m", "factor": 29.9},
{"item1":"m", "item2": "ångström", "factor": 10000000000},
{"item1":"smoot", "item2": "ft", "factor": 5.583333333333},
{"item1":"uncle jordan", "item2": "cm", "factor":192.405},
{"item1":"floz", "item2":"mL", "factor":29.57344}, {"item1":"km", "item2":"m", "formulaforward": "i1 * 1000", "formulabackward": "i1 / 1000"},
{"item1":"L", "item2":"mL", "factor":1000}, {"item1":"mi", "item2":"ft", "formulaforward": "i1 * 5280", "formulabackward": "i1 / 5280"},
{"item1":"L", "item2":"floz", "factor":33.81402}, {"item1":"m", "item2":"in", "formulaforward": "i1 * 39.37008", "formulabackward": "i1 / 39.37008"},
{"item1":"hhd", "item2":"gal", "factor":54}, {"item1":"m", "item2":"cm", "formulaforward": "i1 * 100", "formulabackward": "i1 / 100"},
{"item1":"barrel", "item2":"kilderkin", "factor":2}, {"item1":"cm", "item2":"mm", "formulaforward": "i1 * 10", "formulabackward": "i1 / 10"},
{"item1":"barrel", "item2":"firkin", "factor":4}, {"item1":"m", "item2":"μm", "formulaforward": "i1 * 1000000", "formulabackward": "i1 / 1000000"},
{"item1":"firkin", "item2":"gal", "factor":10.8}, {"item1":"km", "item2":"mi", "formulaforward": "i1 * 0.6213712", "formulabackward": "i1 / 0.6213712"},
{"item1":"pint", "item2":"floz", "factor":16}, {"item1":"ft", "item2":"in", "formulaforward": "i1 * 12", "formulabackward": "i1 / 12"},
{"item1":"cup", "item2":"floz", "factor":8}, {"item1":"yd", "item2":"ft", "formulaforward": "i1 * 3", "formulabackward": "i1 / 3"},
{"item1":"gill", "item2":"floz", "factor":4}, {"item1":"football field", "item2":"yd", "formulaforward": "i1 * 100", "formulabackward": "i1 / 100"},
{"item1":"tbsp", "item2":"tsp", "factor":3}, {"item1":"chain", "item2":"yd", "formulaforward": "i1 * 22", "formulabackward": "i1 / 22"},
{"item1":"tbsp", "item2":"floz", "factor":0.5}, {"item1":"chain", "item2":"link", "formulaforward": "i1 * 100", "formulabackward": "i1 / 100"},
{"item1":"gal", "item2":"floz", "factor":128}, {"item1":"furlong", "item2":"mi", "formulaforward": "i1 * 8", "formulabackward": "i1 / 8"},
{"item1":"gal", "item2":"qt", "factor":4}, {"item1":"rod", "item2":"ft", "formulaforward": "i1 * 16.5", "formulabackward": "i1 / 16.5"},
{"item1":"AU", "item2":"ly", "formulaforward": "i1 * 0.0000158125", "formulabackward": "i1 / 0.0000158125"},
{"item1":"ly", "item2":"km", "formulaforward": "i1 * 946070000000", "formulabackward": "i1 / 946070000000"},
{"item1":"pc", "item2":"AU", "formulaforward": "i1 * 206266.3", "formulabackward": "i1 / 206266.3"},
{"item1":"blue whale length", "item2": "m", "formulaforward": "i1 * 29.9", "formulabackward": "i1 / 29.9"},
{"item1":"m", "item2": "ångström", "formulaforward": "i1 * 10000000000", "formulabackward": "i1 / 10000000000"},
{"item1":"smoot", "item2": "ft", "formulaforward": "i1 * 5.583333333333", "formulabackward": "i1 / 5.583333333333"},
{"item1":"uncle jordan", "item2": "cm", "formulaforward": "i1 * 192.405", "formulabackward": "i1 / 192.405"},
{"item1":"floz", "item2":"mL", "formulaforward": "i1 * 29.57344", "formulabackward": "i1 / 29.57344"},
{"item1":"L", "item2":"mL", "formulaforward": "i1 * 1000", "formulabackward": "i1 / 1000"},
{"item1":"L", "item2":"floz", "formulaforward": "i1 * 33.81402", "formulabackward": "i1 / 33.81402"},
{"item1":"hhd", "item2":"gal", "formulaforward": "i1 * 54", "formulabackward": "i1 / 54"},
{"item1":"barrel", "item2":"kilderkin", "formulaforward": "i1 * 2", "formulabackward": "i1 / 2"},
{"item1":"barrel", "item2":"firkin", "formulaforward": "i1 * 4", "formulabackward": "i1 / 4"},
{"item1":"firkin", "item2":"gal", "formulaforward": "i1 * 10.8", "formulabackward": "i1 / 10.8"},
{"item1":"pint", "item2":"floz", "formulaforward": "i1 * 16", "formulabackward": "i1 / 16"},
{"item1":"cup", "item2":"floz", "formulaforward": "i1 * 8", "formulabackward": "i1 / 8"},
{"item1":"gill", "item2":"floz", "formulaforward": "i1 * 4", "formulabackward": "i1 / 4"},
{"item1":"tbsp", "item2":"tsp", "formulaforward": "i1 * 3", "formulabackward": "i1 / 3"},
{"item1":"tbsp", "item2":"floz", "formulaforward": "i1 * 0.5", "formulabackward": "i1 / 0.5"},
{"item1":"gal", "item2":"floz", "formulaforward": "i1 * 128", "formulabackward": "i1 / 128"},
{"item1":"gal", "item2":"qt", "formulaforward": "i1 * 4", "formulabackward": "i1 / 4"},
{"item1":"acre", "item2":"yd^2", "factor":4840}, {"item1":"acre", "item2":"yd^2", "formulaforward": "i1 * 4840", "formulabackward": "i1 / 4840"},
{"item1":"yd^2", "item2":"m^2", "factor":0.836127}, {"item1":"yd^2", "item2":"m^2", "formulaforward": "i1 * 0.836127", "formulabackward": "i1 / 0.836127"},
{"item1":"mph", "item2":"knot", "factor":0.868976}, {"item1":"mph", "item2":"knot", "formulaforward": "i1 * 0.868976", "formulabackward": "i1 / 0.868976"},
{"item1":"mph", "item2":"kph", "factor":1.609343550606653}, {"item1":"mph", "item2":"kph", "formulaforward": "i1 * 1.609343550606653", "formulabackward": "i1 / 1.609343550606653"},
{"item1":"kPa", "item2":"Pa", "formulaforward": "i1 * 1000", "formulabackward": "i1 / 1000"},
{"item1":"kPa", "item2":"Pa", "factor":1000}, {"item1":"Nm^2", "item2":"Pa", "formulaforward": "i1 * 1", "formulabackward": "i1 / 1"},
{"item1":"Nm^2", "item2":"Pa", "factor":1}, {"item1":"Pa", "item2":"bar", "formulaforward": "i1 * 100", "formulabackward": "i1 / 100"},
{"item1":"Pa", "item2":"bar", "factor":100}, {"item1":"atm", "item2":"Pa", "formulaforward": "i1 * 101325", "formulabackward": "i1 / 101325"},
{"item1":"atm", "item2":"Pa", "factor":101325}, {"item1":"bar", "item2":"psi", "formulaforward": "i1 * 14.5038", "formulabackward": "i1 / 14.5038"}
{"item1":"bar", "item2":"psi", "factor":14.5038}
] ]
} }

View File

@ -15,6 +15,7 @@
<PackageReference Include="bootstrap" Version="5.3.3" /> <PackageReference Include="bootstrap" Version="5.3.3" />
<PackageReference Include="discord.net" Version="3.10.0" /> <PackageReference Include="discord.net" Version="3.10.0" />
<PackageReference Include="greyn.franz" Version="2.1.0" /> <PackageReference Include="greyn.franz" Version="2.1.0" />
<PackageReference Include="jace" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.20" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.20" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.5"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>