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(); } }
Dictionary <string, string> GetFootnoteParametersForIntelli(int count = 3) { Dictionary <string, string> footnoteParameters = new Dictionary <string, string>(); DefinitionAdmin.Fun dummyFun = new DefinitionAdmin.Fun(); DefPar.Footnote.Add(dummyFun); DefQuery.AddAllPar(dummyFun); foreach (string footnoteParameterName in dummyFun.GetParList().Keys) { string description = ""; for (int i = 1; i <= count; ++i) //offer 3 (resp. 'count') of each type, e.g. Amount#1, Amount#2, Amount#3 { string name = footnoteParameterName; if (footnoteParameterName.ToLower() == DefPar.Footnote.Amount.ToLower()) { name = DefPar.Value.AMOUNT + DefQuery.HAS_PAR_MARKER + i.ToString(); //#_Amount -> Amount#xi } else { name = name.Replace("#_", DefQuery.HAS_PAR_MARKER + i.ToString() + "[_"); //e.g. #_LowLim -> #xi[_LowLim] name += "]"; } footnoteParameters.Add(name, "(new) " + description); //"(new)" in contrast to "(value)" of an existing footnote-parameter } } return(footnoteParameters); }
private static List <AddParameterTag> GetFullParList(string funName) { List <AddParameterTag> pars = new List <AddParameterTag>(); DefinitionAdmin.Fun fun = DefinitionAdmin.GetFunDefinition(funName, false); if (fun == null) { return(pars); } List <AddParameterTag> commonPars = new List <AddParameterTag>(), footnotePars = new List <AddParameterTag>(); foreach (var p in fun.GetParList()) { AddPar(p); } foreach (var pg in fun.GetGroupParList()) { foreach (var p in pg.par) { AddPar(p, pg); } } pars.AddRange(commonPars); pars.AddRange(footnotePars); // to get parameters in order: fun/common/footnotes return(pars); void AddPar(KeyValuePair <string, DefinitionAdmin.Par> p, DefinitionAdmin.ParGroup pg = null) { if (p.Key.ToLower() == DefPar.DefConst.Const_Monetary.ToLower()) { return; // Const_Monetary is not allowed, but needs to exist in library, because it is used in some countries (e.g. el, ie) } string parName = p.Key.ToUpper() == DefPar.PAR_TYPE.PLACEHOLDER.ToString().ToUpper() ? DefinitionAdmin.ParTypeToString(DefPar.PAR_TYPE.PLACEHOLDER) : p.Key; AddParameterTag apt = new AddParameterTag() { _parName = parName, _parDef = p.Value, _parGroup = pg }; if (p.Value.isFootnote) { footnotePars.Add(apt); } else if (p.Value.isCommon) { commonPars.Add(apt); } else { pars.Add(apt); } } }
/// <summary> check for compulsory parameters </summary> private void CheckForCompleteness(Dictionary <string, ExeXml.Par> xmlParList, DefinitionAdmin.Fun funDef) { // check if compulsory non-group parameters are available foreach (var p in funDef.GetParList()) { string parName = p.Key; DefinitionAdmin.Par parDef = p.Value; if (parDef.minCount == 0) { continue; // optional parameter (e.g. Allocate's Share_Between) } // (note that footnote-parameters are always optional) bool found = false; if (parDef.maxCount == 1) // check for unique compulsory parameter (e.g. ArithOp's Formula) { if (GetUniquePar <ParBase>(parName) != null) { found = true; } else // could still be available as substitute (e.g. output_var not available, but output_add_var) { foreach (string substitute in parDef.substitutes) { if (GetUniquePar <ParBase>(substitute) != null) { found = true; break; } } ; } } if (parDef.maxCount > 1) // check for non-unique parameter, where at least one must be defined (e.g. SetDefault's Dataset) { if (GetNonUniquePar <ParBase>(parName).Count > 0) { found = true; } else // unlikely, but could still be available as substitute { foreach (string substitute in parDef.substitutes) { if (GetNonUniquePar <ParBase>(substitute).Count > 0) { found = true; break; } } ; } } if (!found) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $" {description.Get()}: compulsory parameter {parName} is missing" }); } } // check if compulsory groups, and compulsory parameter within groups are available foreach (var groupDef in funDef.GetGroupParList()) { if (groupDef.minCount > 0) // check for compulsory group, e.g. BenCalc's Comp_X-group { if (!groupPar.ContainsKey(groupDef.groupName)) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $" {description.Get()}: compulsory group {groupDef.groupName} is missing" }); } } // whether or not the group is compulsory it can (if existent) ask for completeness, i.e. have compulsory parts if (!groupPar.ContainsKey(groupDef.groupName)) { continue; // no such group exists } foreach (var p in groupDef.par) // loop over the group-definition's parameters (e.g. Comp_Cond, Comp_perTU, Comp_LowLim, ...) { string parName = p.Key; DefinitionAdmin.Par parDef = p.Value; if (parDef.minCount == 0) { continue; // optional parameter (e.g. Comp_LowLim) } // check for compulsory parameter (e.g. Comp_Cond) foreach (var g in GetParGroups(groupDef.groupName)) // loop over all existent groups { // (e.g. all components of an actual BenCalc) int groupNo = g.Key; List <ParBase> groupPar = g.Value; int found = 0; if (parDef.maxCount == 1) // check for unique compulsory group-parameter (e.g. BenCalc's Comp_Cond) { if (GetUniqueGroupPar <ParBase>(parName, groupPar) != null) { ++found; } foreach (string substitute in parDef.substitutes) { if (GetUniqueGroupPar <ParBase>(substitute.ToLower(), groupPar) != null) { ++found; } } if (found > 1) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $" {description.Get()}: double definition of group-parameter {parName} (group {groupNo})" }); } } if (parDef.maxCount > 1) // check for non-unique compulsory group-parameter (e.g. Uprate's AggVarPart) { if (GetNonUniqueGroupPar <ParBase>(parName, groupPar).Count > 0) { ++found; } foreach (string substitute in parDef.substitutes) { if (GetNonUniqueGroupPar <ParBase>(substitute.ToLower(), groupPar).Count > 0) { ++found; } } } if (found == 0) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $" {description.Get()}: compulsory group-parameter {parName} (group {groupNo}) is missing" }); } } } } }
//returns the footnote parameters which need to be added when a formula was changed //e.g. formula contains 'Amount#4711' (and did not contain that before the change): footnote parameter #Amount with group 4711 must be added internal static Dictionary <KeyValuePair <string, string>, DefinitionAdmin.Par> GetFootnoteParametersToAdd(TreeListNode node, ref string formulaText) { Dictionary <KeyValuePair <string, string>, DefinitionAdmin.Par> footnoteParametersToAdd = new Dictionary <KeyValuePair <string, string>, //name and group of new footnote parameter DefinitionAdmin.Par>(); //definition (from config file) of new parameter int nextFootnote = TreeListManager.GetNextAvailableFootnoteCounter(node.ParentNode); string functionName = node.ParentNode.GetDisplayText(TreeListBuilder._policyColumnName); //search for Amount#xi (i.e Amount#x1, Amount#x2, etc.) for (int indexLabelAmount = formulaText.ToLower().IndexOf(DefPar.Value.AMOUNT.ToLower() + "#x"), indexNonDigit; indexLabelAmount >= 0; indexLabelAmount = formulaText.ToLower().IndexOf(DefPar.Value.AMOUNT.ToLower() + "#x")) { for (indexNonDigit = indexLabelAmount + DefPar.Value.AMOUNT.Length + 2; indexNonDigit < formulaText.Length && EM_Helpers.IsDigit(formulaText.ElementAt(indexNonDigit)); ++indexNonDigit) { ; //search first non digit after Amount#x } string parameterName = "#_" + DefPar.Value.AMOUNT; //#_Amount DefinitionAdmin.Par parDef = DefinitionAdmin.GetParDefinition(functionName, parameterName); KeyValuePair <string, string> parameterNameAndGroup = new KeyValuePair <string, string>(parameterName, nextFootnote.ToString()); footnoteParametersToAdd.Add(parameterNameAndGroup, parDef); //put parameter into list of footnote parameters which need to be generated string toReplace = SubstringFromTo(formulaText, indexLabelAmount, indexNonDigit - 1); //Amount#xi (e.g. Amount#x1) string replaceBy = DefPar.Value.AMOUNT + "#" + nextFootnote.ToString(); //Amount#f (e.g. Amount#x3) formulaText = formulaText.Replace(toReplace, replaceBy); //replace all occurrences (there might be more than one) ++nextFootnote; } //search for #xi[_yyy] (i.e. #x1[_Level], #x2[_Level], #x1[_UpLim], etc.) for (int indexPlaceholder = formulaText.IndexOf("[_"); indexPlaceholder >= 0; indexPlaceholder = formulaText.IndexOf("[_")) { int iStart = formulaText.Substring(0, indexPlaceholder).LastIndexOf("#x"); int iEnd = formulaText.Substring(indexPlaceholder).IndexOf("]") + indexPlaceholder; if (iStart >= 0 && iEnd >= 0 && EM_Helpers.IsNonNegInteger(SubstringFromTo(formulaText, iStart + 2, indexPlaceholder - 1))) { string parameterName = "#" + SubstringFromTo(formulaText, indexPlaceholder + 1, iEnd - 1); //#_yyy (e.g. #_Level) DefinitionAdmin.Fun funDef = DefinitionAdmin.GetFunDefinition(functionName, false); // check if function allows for this footnote if (funDef != null && (from p in funDef.GetParList() where p.Value.isFootnote && p.Key.ToLower() == parameterName.ToLower() select p).Count() > 0) { DefinitionAdmin.Par parDef = DefinitionAdmin.GetParDefinition(functionName, parameterName); KeyValuePair <string, string> parameterNameAndGroup = new KeyValuePair <string, string>(parameterName, nextFootnote.ToString()); footnoteParametersToAdd.Add(parameterNameAndGroup, parDef); //put parameter into list of footnote parameters which need to be generated string toReplace = SubstringFromTo(formulaText, iStart, iEnd); //#xi_yyy (e.g. #x1[_Level]) string replaceBy = "#" + nextFootnote.ToString(); //#f_yyy (e.g. #4) formulaText = formulaText.Replace(toReplace, replaceBy); //replace all occurrences (there might be more than one) ++nextFootnote; } else { break; //should not happen (though can), but to avoid infinite loop } } else { break; //should not happen (though can), but to avoid infinite loop } } //search for query#x (e.g. isNtoMchild#x) for (int indexPlaceholder = formulaText.IndexOf("#x"); indexPlaceholder >= 0; indexPlaceholder = formulaText.IndexOf("#x")) { string theQuery = string.Empty; foreach (string queryName in DefinitionAdmin.GetQueryNamesAndDesc().Keys) { string potQueryName = SubstringFromTo(formulaText, indexPlaceholder - (queryName.Length - 2), indexPlaceholder + 1).ToLower(); if (potQueryName == queryName.ToLower()) { theQuery = queryName; break; } } if (theQuery == string.Empty) { formulaText = formulaText.Substring(0, indexPlaceholder) + "#°" + formulaText.Substring(indexPlaceholder + 2); //no query found, replace #x preliminary by #° (change back below) } else //add all parameters of the query { Dictionary <string, DefinitionAdmin.Par> queryParameters = new Dictionary <string, DefinitionAdmin.Par>(); DefinitionAdmin.GetQueryDefinition(theQuery, out DefinitionAdmin.Query queryDef, out string dummy, false); if (queryDef != null) { queryParameters = queryDef.par; } List <string> alreadyCoveredByAlias = new List <string>(); // avoid adding e.g. #_income as well as #_info foreach (var q in queryParameters) { string queryParName = q.Key; DefinitionAdmin.Par queryParDef = q.Value; if (alreadyCoveredByAlias.Contains(queryParName)) { continue; } footnoteParametersToAdd.Add(new KeyValuePair <string, string>(queryParName, nextFootnote.ToString()), queryParDef); //put parameter into list of footnote parameters which need to be generated alreadyCoveredByAlias.AddRange(queryParDef.substitutes); } formulaText = formulaText.Substring(0, indexPlaceholder) + "#" + nextFootnote.ToString() + formulaText.Substring(indexPlaceholder + 2); //replace #x by #f (e.g. #x by #5) ++nextFootnote; } } formulaText = formulaText.Replace("#°", "#x"); return(footnoteParametersToAdd); }
internal override void PerformAction() { TreeListNode policyNode = _senderNode; if (_senderNode.ParentNode != null) { policyNode = _senderNode.ParentNode; } int newFunctionNodeIndex = -1; List <CountryConfig.FunctionRow> newFunctionRows = new List <CountryConfig.FunctionRow>(); foreach (CountryConfig.PolicyRow policyRow in (policyNode.Tag as PolicyTreeListTag).GetPolicyRows()) //loop over systems { CountryConfig.FunctionRow newFunctionRow = null; //(1) add function //if the sender node is a policy node: insert as last function ('Add Function' was called from policy node or 'Add Function After' was called from last function node in policy) if (_senderNode == policyNode) { newFunctionRow = CountryConfigFacade.AddFunctionRowAtTail(_functionName, policyRow, // the switch of a function inside an extension-policy cannot be changed, therefore add as on (otherwise one would need to remove the policy from the extension to be able to change the switch to on) ExtensionAndGroupManager.ShowExtensionSwitchEditor(policyRow) ? DefPar.Value.ON : DefPar.Value.NA); } //if the sender node is a function node: insert before ('Add Function Before' was called from function node) else { CountryConfig.FunctionRow neighbourFunction = (_senderNode.Tag as FunctionTreeListTag).GetFunctionRowOfSystem(policyRow.SystemRow.ID); newFunctionRow = CountryConfigFacade.AddFunctionRow(_functionName, neighbourFunction, true, ExtensionAndGroupManager.ShowExtensionSwitchEditor(policyRow) ? DefPar.Value.ON : DefPar.Value.NA); // see comment above newFunctionNodeIndex = _mainForm.treeList.GetNodeIndex(_senderNode); } _addedFunctionsIDs.Add(newFunctionRow.ID); //(2) add compulsory parameters DefinitionAdmin.Fun fun = DefinitionAdmin.GetFunDefinition(_functionName, false); if (fun != null) { for (short doCommon = 0; doCommon < 2; ++doCommon) // add function-specific parameters before common { foreach (var p in fun.GetParList()) { AddPar(p, false); } foreach (var pg in fun.GetGroupParList()) { if (pg.minCount > 0) { foreach (var p in pg.par) { AddPar(p, true); } } } void AddPar(KeyValuePair <string, DefinitionAdmin.Par> p, bool group) { string parName = p.Key.ToUpper() == DefPar.PAR_TYPE.PLACEHOLDER.ToString().ToUpper() ? DefinitionAdmin.ParTypeToString(DefPar.PAR_TYPE.PLACEHOLDER) : p.Key; DefinitionAdmin.Par parDef = p.Value; if (parDef.minCount > 0 && ((doCommon == 0 && !parDef.isCommon) || (doCommon == 1 && parDef.isCommon))) { CountryConfigFacade.AddParameterRowAtTail(newFunctionRow, parName, parDef, group ? "1" : string.Empty); } } } } newFunctionRows.Add(newFunctionRow); } _mainForm.GetTreeListBuilder().InsertFunctionNode(newFunctionRows, policyNode, newFunctionNodeIndex); }