private static void PrintParAsDefined(FunBase fun) { DefinitionAdmin.Fun funDef = DefinitionAdmin.GetFunDefinition(fun.description.GetFunName()); PrintSubHeading("Possible parameters"); CompOpt(funDef.GetParList()); foreach (DefinitionAdmin.ParGroup group in funDef.GetGroupParList()) { RandColor.WriteLine($"{(group.minCount > 0 ? "Compuslory" : "Optional")} group {group.groupName}:", colorHeading); CompOpt(group.par, " "); } void CompOpt(Dictionary <string, DefinitionAdmin.Par> parList, string space = "") { RandColor.Write($"{space}Compulsory: ", colorHeading); foreach (var par in parList) { if (par.Value.minCount > 0) { RandColor.Write($"{par.Key} ", GetSwapColor()); } } RandColor.Write(Environment.NewLine + $"{space}Optional: ", colorHeading); foreach (var par in parList) { if (par.Value.minCount == 0) { RandColor.Write($"{par.Key} ", GetSwapColor()); } } Console.WriteLine(); } }
public static void PrintFunInfo() { foreach (var fun in infoStore.spine) { RandColor.Write($"{fun.Value.description.GetPolName()} {fun.Value.description.GetFunName()} ", colorHeading); RandColor.Write($"order: {fun.Key} ", GetSwapColor()); RandColor.WriteLine($"id: {fun.Value.description.funID}", GetSwapColor()); } RandColor.WriteLine(Environment.NewLine + "- - - - - - - - - - - - - - - - - - - - - - - - ", colorHeading); RandColor.WriteLine(Environment.NewLine + "Press x to exit, order to analyse function", colorHeading); do { RandColor.Write("order: ", GetSwapColor()); string o = Console.ReadLine(); if (o == "x") { break; } if (!int.TryParse(o, out int order) || !infoStore.spine.ContainsKey(order)) { continue; } PrintParAsDefined(infoStore.spine[order]); PrintParAsRead(infoStore.spine[order]); RandColor.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - ", colorHeading); } while (true); }
public static void PrintTUInfo() { PrintHeading("Household info - taxunits"); PrintSubHeading($"{infoStore.indexTUs.Count} TUs defined:"); foreach (string tuName in infoStore.indexTUs.Keys) { RandColor.Write($"{tuName} ", GetSwapColor()); } Console.WriteLine(); if (infoStore.hhAdmin == null) { return; } int nTestHH = 3; int i = 0; PrintSubHeading($"first and last {nTestHH} households"); foreach (HH hh in infoStore.hhAdmin.hhs) { if (Exclude(ref i, nTestHH, infoStore.hhAdmin.hhs.Count)) { continue; } ConsoleColor color = GetSwapColor(); foreach (var tu in hh.hhTUs) { RandColor.WriteLine($"{tu.Key}: {tu.Value.Count} unit(s) in HH {i}", color); } } }
private static void PrintHeading(string heading) { RandColor.Write(Environment.NewLine + "* * * ", colorHeading); foreach (char c in heading.ToUpper()) { RandColor.Write($"{c} ", colorHeading); } RandColor.WriteLine(" * * *", colorHeading); }
public static void PrintGeneralInfo() { PrintHeading("General info"); if (infoStore.hhAdmin == null) { RandColor.WriteLine("No info on households available", colorInfo); return; } int pCnt = 0; foreach (HH hh in infoStore.hhAdmin.hhs) { pCnt += hh.personVarList.Count; } RandColor.WriteLine($"Number of households: {infoStore.hhAdmin.hhs.Count:N0}", colorInfo); RandColor.WriteLine($"Number of persons: {pCnt:N0}", colorInfo); HH anyHH = infoStore.hhAdmin.hhs[0]; RandColor.WriteLine($"Number of numeric variables: {anyHH.personVarList[0].Count:N0}", colorInfo); RandColor.WriteLine($"Number of string variables: {anyHH.personStringVarList[0].Count:N0}", colorInfo); }
public static void PrintHHInfo() { PrintHeading("Household info - variables"); if (infoStore.hhAdmin == null) { RandColor.WriteLine("No info on households available", colorInfo); return; } int nTestHH = 5; int i = 0; PrintSubHeading($"first and last {nTestHH} households"); foreach (string varName in infoStore.operandAdmin.GetPersonVarNameList()) { RandColor.Write($"{varName,7} ", GetSwapColor()); } RandColor.WriteLine(""); // header: names of variables foreach (HH hh in infoStore.hhAdmin.hhs) { if (Exclude(ref i, nTestHH, infoStore.hhAdmin.hhs.Count)) { continue; } ConsoleColor color = GetSwapColor(); for (int iPerson = 0; iPerson < hh.personVarList.Count; ++iPerson) { foreach (var d in hh.personVarList[iPerson]) { RandColor.Write($"{Math.Round(d,2, MidpointRounding.AwayFromZero),7} ", color); } foreach (var s in hh.personStringVarList[iPerson]) { RandColor.Write($"{s} ", color); } Console.WriteLine(); } } }
public static void PrintParInfo() { RandColor.WriteLine(Environment.NewLine + "parameter-order (140011-12) or function-order (140011) for analysis, x to exit", colorHeading); do { RandColor.Write("order: ", GetSwapColor()); string o = Console.ReadLine(); if (o == "x") { break; } string fo, parOrder; fo = o.Contains("-") ? o.Substring(0, o.IndexOf('-')) : o; parOrder = o.Contains("-") ? o.Substring(o.IndexOf('-')).TrimStart(new char[] { '-' }) : string.Empty; if (!double.TryParse(fo, out double funOrder) || !infoStore.spine.ContainsKey(funOrder)) { continue; } if (parOrder == string.Empty) { foreach (var p in infoStore.spine[funOrder].TestGetAllPar(true)) { RandColor.WriteLine($"{p.description.GetParName()} {p.description.par.order}", GetSwapColor()); } continue; } ParBase anaPar = GetPar(funOrder, parOrder); if (anaPar != null) { PrintParDetails(anaPar); } RandColor.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - ", colorHeading); } while (true); ParBase GetPar(double funOrder, string parOrder) { return((from p in infoStore.spine[funOrder].TestGetAllPar(true) where p.description.par.order == parOrder select p).FirstOrDefault()); } }
private static void PrintParDetails(ParBase par) { RandColor.WriteLine(par.description.Get(), GetSwapColor()); RandColor.WriteLine($"xml-value: {par.xmlValue}", GetSwapColor()); if (infoStore.hhAdmin == null) { return; } HH dummyHH = infoStore.hhAdmin.GetFirstHH(); List <Person> dummyTU = new List <Person>() { new Person(0) }; if (par.GetType() == typeof(ParBool)) { RandColor.WriteLine($"value: {(par as ParBool).GetBoolValue()}", GetSwapColor()); } else if (par.GetType() == typeof(ParCateg)) { RandColor.WriteLine($"value: {(par as ParCateg).GetCateg()}", GetSwapColor()); } else if (par.GetType() == typeof(ParNumber)) { RandColor.WriteLine($"value: {(par as ParNumber).GetValue()}", GetSwapColor()); } else if (par.GetType() == typeof(ParTU)) { string tuName = (par as ParTU).name; dummyHH.GetTUs(tuName); // that's to "use" the TU, i.e. to create it for the HH RandColor.WriteLine($"TU {tuName} has {dummyHH.hhTUs[tuName].Count} unit(s) in 1st HH", GetSwapColor()); } else if (par.GetType() == typeof(ParVar)) { RandColor.WriteLine($"value: {(par as ParVar).GetValue(dummyHH, dummyTU)}", GetSwapColor()); } else if (par.GetType() == typeof(ParOutVar)) // there is actually nothing to check, out-vars just care for registration { RandColor.WriteLine($"index: {(par as ParOutVar).index}", GetSwapColor()); } else if (par.GetType() == typeof(ParIL)) { RandColor.WriteLine($"value: {(par as ParIL).GetValue(dummyHH, dummyTU)}", GetSwapColor()); } else if (par.GetType() == typeof(ParVarIL)) { RandColor.WriteLine($"value: {(par as ParVarIL).GetValue(dummyHH, dummyTU)}", GetSwapColor()); } else if (par.GetType() == typeof(ParFormula)) { RandColor.WriteLine($"value: {(par as ParFormula).GetValue(dummyHH, dummyTU)}", GetSwapColor()); } else if (par.GetType() == typeof(ParCond)) { RandColor.WriteLine($"ParCond not yet handled", ConsoleColor.DarkMagenta); } else { RandColor.WriteLine($"unknow type: {par.GetType()}", GetSwapColor()); } }
private static void PrintSubHeading(string heading) { RandColor.WriteLine($"- - - {heading} - - -", colorHeading); }
// also see "explanation wrt new handling of ChangeParam" in Explanations.cs private void AdaptChangeParam_Fun(EM2Item fun, EM2Country.Content ctryContent, List <string> errors) { if (fun.name.ToLower() != DefFun.ChangeParam.ToLower()) { return; } // === G A T H E R I N F O R M A T I O N === // get all parameters of the ChangeParam ... // i.e. Param_Id, Param_NewVal, Param_CondVal, RunCond, #_DataBasename, #_xxx (i.e. other footnote-parameters) var allPar = from p in ctryContent.parameters where p.Value.properties.ContainsKey(EM2TAGS.FUNCTION_ID) && p.Value.properties[EM2TAGS.FUNCTION_ID] == fun.id select p; // ... and put them into lists that allow deciding on what to do with them string idRunCond = null; // id of Run_Cond-parameter List <string> idDataBaseFootnotes = new List <string>(); // ids of footnote-parameters #_DataBase (referred by Run_Cond) List <string> idsParamId_ChangeSwitch = new List <string>(); // ids of Param_Id-parameters, which refer to a function or policy List <string> idsVal_ChangeSwitch = new List <string>(); // ids of Param_New/CondVal-parameters with value on/off/toggle List <string> idsParamId_ChangeParam = new List <string>(); // ids of Param_Id-parameters, which refer to a parameter List <string> idsVal_ChangeParam = new List <string>(); // ids of Param_CondVal-parameters with another value than on/off/toggle List <string> idsOtherFootnotes = new List <string>(); // ids of other footnote-parameters than #_DataBase (rather unlikely) bool hasChangeParam_Par = false; // has parameters that belong into a ChangeParam function bool hasChangeSwitch_Par = false; // has parameters that belong into a ChangeSwitch function foreach (var par in allPar) { // --- Param_Id --- if (par.Value.name.ToLower() == DefPar.ChangeParam.Param_Id.ToLower()) { // Param_Id refers to a policy or function -> belongs into a ChangeSwitch function bool?refersToPolFun = RefersToPolFun(par.Value.id); if (refersToPolFun == true) { idsParamId_ChangeSwitch.Add(par.Value.id); hasChangeSwitch_Par = true; } // Param_Id refers to a parameter -> belongs into a ChangeParam function else if (refersToPolFun == false) { idsParamId_ChangeParam.Add(par.Value.id); hasChangeParam_Par = true; } //else: parameter is n/a in all systems } // --- Run_Cond --- else if (par.Value.name.ToLower() == DefPar.Common.Run_Cond.ToLower()) { idRunCond = par.Key; } // --- #_DataBase --- else if (par.Value.name.ToLower() == DefQuery.Par.DataBasename.ToLower()) { idDataBaseFootnotes.Add(par.Key); } // --- Param_CondVal or Param_NewVal --- else if (par.Value.name.ToLower() == DefPar.ChangeParam.Param_NewVal.ToLower() || par.Value.name.ToLower() == DefPar.ChangeParam.Param_CondVal.ToLower()) { // Param_Cond/NewVal's value = off/on/toggle -> belongs into a ChangeSwitch function bool?isSwitchChange = IsSwitchChange(par.Value.id); if (isSwitchChange == true) { idsVal_ChangeSwitch.Add(par.Value.id); hasChangeSwitch_Par = true; } // Param_Cond/NewVal's value = some parameter-change -> belongs into a ChangeParam function else if (isSwitchChange == false) { idsVal_ChangeParam.Add(par.Value.id); hasChangeParam_Par = true; } //else: parameter is n/a in all systems } // --- other (valid) parameter can only be another footnote parameter than #_DataBase --- else { idsOtherFootnotes.Add(par.Key); } } // === T R A N S F O R M A C T I O N S === if (hasChangeSwitch_Par && hasChangeParam_Par) // splitting the function in two is complicated (must invent ids ...) and is not { // necessary for existing countries/add-ons, thus do not forsee before necessary ... // AddError("impossible to assign all parameters to either a ChangeParam or ChangeSwitch function"); // return; // unfortunately it seems that we need a solution for this a bit complicated case, thus: SeparateSwitchFun(); hasChangeSwitch_Par = false; } // note (!hasChangeSwitch_Par && !hasChangeParam_Par) is theoretically possible, if all pars are n/a, but that wouldn't do any harm // --- change to ChangeSwitch function --- if (hasChangeSwitch_Par) { fun.name = DefFun.ChangeSwitch; foreach (string id in idsParamId_ChangeSwitch) // rename 'Param_Id' to 'PolFun' { ctryContent.parameters[id].name = DefPar.ChangeSwitch.PolFun; } foreach (string id in idsVal_ChangeSwitch) // rename 'Param_CondVal'/'Param_NewVal' to 'SwitchNewVal' { // and change possible 'toggle'-value to 'off' ctryContent.parameters[id].name = DefPar.ChangeSwitch.Switch_NewVal; foreach (var sysPar in GetSysPar(id)) { if (XmlHelpers.RemoveCData(sysPar.value).ToLower() == DefPar.Value.TOGGLE) { sysPar.value = DefPar.Value.OFF; } } // else: no change necessary for on / off / n/a } // no change necessary for other parameters, i.e. Run_Cond and associated footnotes } // --- adapt ChangeParam function --- if (hasChangeParam_Par) { // if 'RunCond={IsUsedDatabase#1}' transform to 'Database=xxx', otherwise error (e.g. an actual run-time RunCond or a more complicated RunCond) if (idRunCond != null && !TransformRunCond()) { return; } // rename from Param_CondVal to Param_NewVal if necessary foreach (string id in idsVal_ChangeParam) { ctryContent.parameters[id].name = DefPar.ChangeParam.Param_NewVal; } // no change necessary for Param_Id (keeps Guid or symbolic id) // ignore other parameters - if there are e.g. unnecessary footnotes, this is also wrong for the old executable } // === H E L P E R F U N C T I O N S === void AddError(string error) { errors.Add($"{ctryContent.general.name}: Failed to transform {fun.name} ({fun.id}): {error} (hint: case not yet handled by transformer)"); } bool TransformRunCond() { bool runCondDefined = false; List <EM2Country.SysItem> runCondVals = GetSysPar(idRunCond).ToList(); foreach (EM2Country.SysItem runCondVal in runCondVals) { string runCond = XmlHelpers.RemoveCData(runCondVal.value).Replace(" ", "").ToLower(); if (runCond == DefPar.Value.NA) { continue; } // remove everything that is allowed in a simple enough run-cond, to then check for empty string for (int i = 999; i >= 1; --i) { runCond = runCond.Replace($"isuseddatabase#{i}", ""); } runCond = runCond.Replace("{}", "").Replace("|", ""); if (runCond != string.Empty) { AddError("too complex Run_Cond"); // still continue, so the country still runs } runCondDefined = true; } if (runCondDefined) // rename '#_Database' to 'Dataset' if RunCond is actually {IsUsedDatabase#1} { // (system values are ok, i.e. contain the respective dataset-name) if (idDataBaseFootnotes.Count() == 0) { AddError("missing database specification"); return(false); } foreach (string idDataBaseFootnote in idDataBaseFootnotes) { ctryContent.parameters[idDataBaseFootnote].name = DefPar.ChangeParam.Dataset; } } // remove the RunCond and its system values ctryContent.parameters.Remove(idRunCond); foreach (EM2Country.SysItem runCondVal in runCondVals) { ctryContent.sysPar.Remove(runCondVal); } return(true); } bool?RefersToPolFun(string id_Param_Id) { bool allNa = true; foreach (EM2Country.SysItem sysPar in GetSysPar(id_Param_Id)) { string id = (XmlHelpers.RemoveCData(sysPar.value)); if (id == DefPar.Value.NA) { continue; } allNa = false; if (EM_Helpers.IsGuid(id)) // i.e. most likely this is a country-file (and not an add-on) { if (!ctryContent.parameters.ContainsKey(id)) { return(true); // a bit unsafe, as only "most likely" a country-file } } // i.e. could still be a country-par-guid in an add-on else // i.e. must be an add-on (unless this is an invalid use of symbolic-id in a country file or otherwise invalid) { if (!AddOn.IsParSymbolicID(id)) { return(true); } } // note: a maybe "safer" way to assess whether the id refers to a parameter or to a policy or function } // would be to analyse the corresponding ParamCond/NewVal (on/off/toggle->Pol/Fun), but that's complex to code if (allNa) { return(null); } return(false); } bool?IsSwitchChange(string id_Param_NewVal) { bool allNa = true; foreach (EM2Country.SysItem sysPar in GetSysPar(id_Param_NewVal)) { string newVal = (XmlHelpers.RemoveCData(sysPar.value)).ToLower(); if (newVal == DefPar.Value.OFF || newVal == DefPar.Value.ON || newVal == DefPar.Value.TOGGLE) { return(true); } if (newVal != DefPar.Value.NA) { allNa = false; } } if (allNa) { return(null); } return(false); } IEnumerable <EM2Country.SysItem> GetSysPar(string parId) { return(from sp in ctryContent.sysPar where sp.itemID == parId select sp); } void SeparateSwitchFun() { // first generate a separate ChangeSwitch function ... EM2Item switchFun = EM2Item.Copy(fun, ctryContent.sysFun, out List <EM2Country.SysItem> switchFunSysVals); switchFun.name = DefFun.ChangeSwitch; switchFun.order = 1234567; // unimportant for a ChangeSwitch ctryContent.functions.Add(switchFun.id, switchFun); ctryContent.sysFun.AddRange(switchFunSysVals); // ... then "move" parameters from existing ChangeParam to new ChangeSwitch ... foreach (string id in idsParamId_ChangeSwitch) { ctryContent.parameters[id].partentId = switchFun.id; // move ... ctryContent.parameters[id].properties[EM2TAGS.FUNCTION_ID] = switchFun.id; ctryContent.parameters[id].name = DefPar.ChangeSwitch.PolFun; // ... and rename 'Param_Id' to 'PolFun' foreach (var x in ctryContent.parameters[id].properties) { RandColor.WriteLine($"{x.Key}={x.Value}"); } } foreach (string id in idsVal_ChangeSwitch) { ctryContent.parameters[id].partentId = switchFun.id; // move ... ctryContent.parameters[id].properties[EM2TAGS.FUNCTION_ID] = switchFun.id; ctryContent.parameters[id].name = DefPar.ChangeSwitch.Switch_NewVal; // ... rename 'Param_CondVal'/'Param_NewVal' to 'SwitchNewVal' ... foreach (var sysPar in GetSysPar(id)) // ... and change possible 'toggle'-value to 'off' { if (XmlHelpers.RemoveCData(sysPar.value).ToLower() == DefPar.Value.TOGGLE) { sysPar.value = DefPar.Value.OFF; } } } // ... finally copy possible run-condition ... if (idRunCond == null) { return; } EM2Item runCond = EM2Item.Copy(ctryContent.parameters[idRunCond], ctryContent.sysPar, out List <EM2Country.SysItem> runCondSysVals); runCond.partentId = switchFun.id; runCond.properties[EM2TAGS.FUNCTION_ID] = switchFun.id; ctryContent.parameters.Add(runCond.id, runCond); ctryContent.sysPar.AddRange(runCondSysVals); // ... and its footnotes foreach (string footNoteId in idDataBaseFootnotes) { EM2Item footNote = EM2Item.Copy(ctryContent.parameters[footNoteId], ctryContent.sysPar, out List <EM2Country.SysItem> footNoteSysVals); footNote.partentId = switchFun.id; footNote.properties[EM2TAGS.FUNCTION_ID] = switchFun.id; ctryContent.parameters.Add(footNote.id, footNote); ctryContent.sysPar.AddRange(footNoteSysVals); } } }