diff --git a/ifrs17-template/Test/ScenarioDataImportTest.ipynb b/ifrs17-template/Test/ScenarioDataImportTest.ipynb index 594b996c..b0419970 100644 --- a/ifrs17-template/Test/ScenarioDataImportTest.ipynb +++ b/ifrs17-template/Test/ScenarioDataImportTest.ipynb @@ -55,7 +55,7 @@ { "cell_type": "code", "source": [ - "var EnableScenarioBackup = EnableScenario;" + "var EnableScenarioBackup = Scenarios.EnableScenario;" ], "metadata": {}, "execution_count": 0, @@ -64,7 +64,7 @@ { "cell_type": "code", "source": [ - "EnableScenario = true;" + "Scenarios.EnableScenario = true;" ], "metadata": {}, "execution_count": 0, @@ -952,7 +952,7 @@ { "cell_type": "code", "source": [ - "EnableScenario = EnableScenarioBackup;" + "Scenarios.EnableScenario = EnableScenarioBackup;" ], "metadata": {}, "execution_count": 0, diff --git a/ifrs17-template/Test/ScenarioYieldCurveImportTest.ipynb b/ifrs17-template/Test/ScenarioYieldCurveImportTest.ipynb index 6fce00f2..843dbf9f 100644 --- a/ifrs17-template/Test/ScenarioYieldCurveImportTest.ipynb +++ b/ifrs17-template/Test/ScenarioYieldCurveImportTest.ipynb @@ -55,7 +55,7 @@ { "cell_type": "code", "source": [ - "var EnableScenarioBackup = EnableScenario;" + "var EnableScenarioBackup = Scenarios.EnableScenario;" ], "metadata": {}, "execution_count": 0, @@ -64,7 +64,7 @@ { "cell_type": "code", "source": [ - "EnableScenario = true;" + "Scenarios.EnableScenario = true;" ], "metadata": {}, "execution_count": 0, @@ -734,7 +734,7 @@ { "cell_type": "code", "source": [ - "EnableScenario = EnableScenarioBackup;" + "Scenarios.EnableScenario = EnableScenarioBackup;" ], "metadata": {}, "execution_count": 0, diff --git a/ifrs17/Constants/Consts.ipynb b/ifrs17/Constants/Consts.ipynb index b3889647..d3077e10 100644 --- a/ifrs17/Constants/Consts.ipynb +++ b/ifrs17/Constants/Consts.ipynb @@ -383,34 +383,12 @@ { "cell_type": "code", "source": [ - "public bool EnableScenario = false;" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "public const string ScenarioDefault = \"Best Estimate\";" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "public const string ScenariosAll = \"All\";" - ], - "metadata": {}, - "execution_count": 0, - "outputs": [] - }, - { - "cell_type": "code", - "source": [ - "public const string ScenariosDelta = \"Delta\";" + "public static class Scenarios{", + "\n public static bool EnableScenario = false;", + "\n public const string Default = \"Best Estimate\";", + "\n public const string All = nameof(All);", + "\n public const string Delta = nameof(Delta);", + "\n}" ], "metadata": {}, "execution_count": 0, diff --git a/ifrs17/Import/Importers.ipynb b/ifrs17/Import/Importers.ipynb index a5b2932b..87a517db 100644 --- a/ifrs17/Import/Importers.ipynb +++ b/ifrs17/Import/Importers.ipynb @@ -542,7 +542,7 @@ "\n break;", "\n }", "\n }", - "\n return allArgs.Where(x => (!EnableScenario && x.Scenario == null) || EnableScenario).ToArray();", + "\n return allArgs.Where(x => (!Scenarios.EnableScenario && x.Scenario == null) || Scenarios.EnableScenario).ToArray();", "\n}" ], "metadata": {}, @@ -669,10 +669,9 @@ "using static Systemorph.Vertex.Equality.IdentityPropertyExtensions;", "\npublic async static Task ValidateForMandatoryAocSteps(this IWorkspace workspace, IDataSet dataSet, HashSet mandatoryAocSteps)", "\n{ ", - "\n var excludedProperties = new[]{nameof(AocType), nameof(Novelty)};", - "\n var includingProperties = typeof(RawVariable).GetIdentityProperties().Select(x=>x.Name).Except(excludedProperties).ToArray();", + "\n var ignoreProperties = new[]{nameof(AocType), nameof(Novelty)};", "\n var missingAocStepsByIdentityProperties = (await workspace.Query().ToListAsync())", - "\n .GroupBy(x => x.ToStringWith(properties: includingProperties),", + "\n .GroupBy(x => x.ToIdentityString(ignoreProperties),", "\n x => new AocStep(x.AocType, x.Novelty),", "\n (properties, parsedAocSteps) => (properties, mandatoryAocSteps.Except(parsedAocSteps))", "\n );", diff --git a/ifrs17/Report/ReportMutableScopes.ipynb b/ifrs17/Report/ReportMutableScopes.ipynb index f6cb212f..d77923d7 100644 --- a/ifrs17/Report/ReportMutableScopes.ipynb +++ b/ifrs17/Report/ReportMutableScopes.ipynb @@ -295,10 +295,10 @@ "\n IDataCube Cube { get{", "\n var data = GetScope(Identity.reportType).GetDataCube();", "\n // TODO: suggestion to place the filter here instead of having it in every applicability scope", - "\n if(Identity.scenario != ScenariosAll && Identity.scenario != ScenariosDelta) return data;", - "\n if(Identity.scenario == ScenariosAll) return data.Select(x => x.Scenario == null? x with {Scenario = ScenarioDefault } : x).ToDataCube();", + "\n if(Identity.scenario != Scenarios.All && Identity.scenario != Scenarios.Delta) return data;", + "\n if(Identity.scenario == Scenarios.All) return data.Select(x => x.Scenario == null? x with {Scenario = Scenarios.Default } : x).ToDataCube();", "\n var bestEstimateById = data.Where(x => x.Scenario == null).ToDictionary(x => x.ToIdentityString());", - "\n return data.Select(x => x.Scenario == null ? x with { Scenario = ScenarioDefault } ", + "\n return data.Select(x => x.Scenario == null ? x with { Scenario = Scenarios.Default } ", "\n : x with { Value = x.Value - (bestEstimateById.TryGetValue((x with {Scenario = null}).ToIdentityString(), out var be)? be.Value : 0.0) }).ToDataCube();", "\n }}", "\n} " diff --git a/ifrs17/Utils/Extensions.ipynb b/ifrs17/Utils/Extensions.ipynb index dec7c53d..c3587cec 100644 --- a/ifrs17/Utils/Extensions.ipynb +++ b/ifrs17/Utils/Extensions.ipynb @@ -199,7 +199,7 @@ { "cell_type": "markdown", "source": [ - "# ToIdentityString" + "# Identity property reader" ], "metadata": {}, "execution_count": 0, @@ -208,16 +208,30 @@ { "cell_type": "code", "source": [ - "using System.Text;", - "\npublic static string ToIdentityString(this T v, params string[] excludingProperties) where T : class", - "\n{", - "\n StringBuilder sb = new StringBuilder();", - "\n var propertyInfos = v.GetType()", - "\n .GetProperties()", - "\n .Where(x => Attribute.IsDefined(x, typeof(IdentityPropertyAttribute)) && !excludingProperties.Contains(x.Name))", - "\n .OrderByDescending(x => x.PropertyType.Name).ThenByDescending(x => x.Name)", - "\n .Select(x => sb.Append(x.Name).Append(\":\").Append(v.GetType().GetProperty(x.Name)?.GetValue(v, null)).Append(\", \")).ToArray();", - "\n return propertyInfos.Count() == 0? v.ToString() : propertyInfos.Select(p => p.ToString()).ToArray().Last();", + "using static Systemorph.Vertex.Equality.IdentityPropertyExtensions;", + "\nusing System.Linq.Expressions;", + "\npublic static class IdentityReader where T : class {", + "\n private static Dictionary> ExpressionsByExcludedProperties = new();", + "\n public static string Concat(string first, string second) => first + \" \" + second;", + "\n public static string GetString(Object item) => (item == null) ? \"\" : item.ToString();", + "\n", + "\n private static Func GetToIdentityExpression(string[] excludedProperties) {", + "\n var pm = Expression.Parameter(typeof(T));", + "\n var expression = typeof(T).GetIdentityProperties().Where(x => !excludedProperties.Contains(x.Name))", + "\n .SelectMany(x => new Expression[]{ Expression.Constant(x.Name.ToString()+\":\"),", + "\n Expression.Call(typeof(IdentityReader).GetMethod(nameof(GetString)), Expression.Convert(Expression.Property(pm, x.Name), typeof(Object))) }", + "\n ).Aggregate((x, y) => Expression.Call(typeof(IdentityReader).GetMethod(nameof(IdentityReader.Concat)), x, y));", + "\n return Expression.Lambda>(expression, pm).Compile();", + "\n }", + "\n", + "\n public static string ToString(T x, string[] excludedProperties) {", + "\n var key = string.Join(\",\", excludedProperties.OrderBy(x => x));", + "\n if(!ExpressionsByExcludedProperties.TryGetValue(key, out var expression)) {", + "\n ExpressionsByExcludedProperties[key] = GetToIdentityExpression(excludedProperties);", + "\n return ExpressionsByExcludedProperties[key](x);", + "\n }", + "\n return expression(x);", + "\n }", "\n}" ], "metadata": {}, @@ -227,7 +241,7 @@ { "cell_type": "markdown", "source": [ - "# ToString with including properties" + "# ToString with excluding properties" ], "metadata": {}, "execution_count": 0, @@ -236,11 +250,10 @@ { "cell_type": "code", "source": [ - "public static string ToStringWith(this T variable, string[] properties) where T : BaseVariableIdentity", + "public static string ToIdentityString(this T variable, string[] ignoreProperties = null) where T : class", "\n{", - "\n var propertiesRead = variable.ToString().Split('{', '}')[1].Split(',');", - "\n var propertiesFiltered = propertiesRead.Where(x=> properties.Contains(x.Split('=')[0].Trim()));", - "\n return string.Join(\", \", propertiesFiltered).Trim();", + "\n if (ignoreProperties == null) ignoreProperties = new string[0];", + "\n return IdentityReader.ToString(variable, ignoreProperties);", "\n}" ], "metadata": {},