public TraverseResult Merge(TreeNode node, TraverseResult a) { if (this.IsReady()) { return(this); } if (a.IsReady()) { return(a); } var result = new TraverseResult() { containsFirst = this.containsFirst || a.containsFirst, containsSecond = this.containsSecond || a.containsSecond }; if (result.containsFirst && result.containsSecond) { result.lca = node; } return(result); }
private List <TraverseResult> BuildResultList(TraverseResultCollection[] args, SppfNode node, Production production) { var resultList = new List <TraverseResult>(); foreach (var oneSet in OneOfEach(args)) { object payload = null; var action = production.Annotations.Action; if (action == null) { if (oneSet.Length > 0) { payload = oneSet[0].Payload; // default action } else { payload = null; } } else { payload = action.Act(oneSet); } var oneResult = new TraverseResult(payload, node, production); resultList.Add(oneResult); } return(resultList); }
private void BuildAndSetResult(SppfNode node) { if (_cache.ContainsKey(node) || _branchCache.ContainsKey(node)) { return; } if (node.Families.Count() == 0) { if (node is SppfEpsilon) { _cache[node] = new TraverseResultCollection(new List <TraverseResult> { new TraverseResult("", node, null) }); } else if (node is SppfWord sppfWord) { if (!(sppfWord.Word is Terminal terminal)) { throw new Exception(); } _cache[node] = new TraverseResultCollection(new List <TraverseResult> { new TraverseResult(terminal.Name, node, null) }); } return; } var resultList = new List <TraverseResult>(); foreach (var family in node.Families) { // var argList = new List<TraverseResultCollection>(); if (family.Members.Count == 0) { throw new NotImplementedException(); } else if (family.Members.Count == 1) { var child = family.Members[0]; var childValue = _cache[child]; if (node is SppfBranch) // this only happens in old (not contracted) sppf { if (family.Production != null) { throw new Exception(); } var newValues = new TraverseResultCollection[] { childValue }; _branchCache[node] = newValues; } else { if (family.Production == null) { throw new Exception(); } foreach (var tr in childValue) { var args = new TraverseResult[1] { tr }; var payload = GetPayload(args, family.Production); var oneResult = new TraverseResult(payload, node, family.Production); resultList.Add(oneResult); } } } else if (family.Members.Count == 2) { var left = family.Members[0]; var right = family.Members[1]; if (family.Production == null) { if (left is SppfBranch) // middle of long production { var leftValues = _branchCache[left]; var rightValue = _cache[right]; var newValues = AppendToArray(leftValues, rightValue); _branchCache[node] = newValues; } else // bottom left of a long production { var leftValue = _cache[left]; var rightValue = _cache[right]; var newValues = new TraverseResultCollection[] { leftValue, rightValue }; _branchCache[node] = newValues; } } else // top of production { var rightValue = _cache[right]; TraverseResultCollection[] args; if (left is SppfBranch) { var leftValues = _branchCache[left]; args = AppendToArray(leftValues, rightValue); } else { var leftValue = _cache[left]; args = new TraverseResultCollection[] { leftValue, rightValue }; } var someResults = BuildResultList(args, node, family.Production); resultList.AddRange(someResults); // throw new NotImplementedException(); } } else { throw new Exception(); } //foreach (var child in family.Members) { // if (!_cache.TryGetValue(child, out var childValue)) { // throw new Exception(); // } // argList.Add(childValue); //} // argSet.Add(argList.ToArray()); } var collection = new TraverseResultCollection(resultList); _cache[node] = collection; // var value = new TraverseResultCollection // var payload = GetPayload(_emptyArgs, ) }
private string checkArticle(XmlNode article, MainView frm1) { var sUrl = "http://not.initilaized"; bool changeMT = false; if (article["condition"].InnerText == "MT") // treat mint cards as near mint for pricing purposes { article["condition"].InnerText = "NM"; changeMT = true; } try { var sArticleID = article["idProduct"].InnerText; /*XmlDocument doc2 = MKMInteract.RequestHelper.makeRequest("https://api.cardmarket.com/ws/v2.0/products/" + sArticleID, "GET"); * * logBox.AppendText(OutputFormat.PrettyXml(doc2.OuterXml));*/ sUrl = "https://api.cardmarket.com/ws/v2.0/articles/" + sArticleID + "?idLanguage=" + article["language"]["idLanguage"].InnerText + "&minCondition=" + article["condition"].InnerText + "&start=0&maxResults=150&isFoil=" + article["isFoil"].InnerText + "&isSigned=" + article["isSigned"].InnerText + "&isAltered=" + article["isAltered"].InnerText; var doc2 = MKMInteract.RequestHelper.makeRequest(sUrl, "GET"); XmlNodeList similarItems = doc2.GetElementsByTagName("article"); List <double> prices = new List <double>(); string sOldPrice = article["price"].InnerText; double dOldPrice = Convert.ToDouble(sOldPrice, CultureInfo.InvariantCulture); int lastMatch = -1; bool ignoreSellersCountry = false; TraverseResult res = traverseSimilarItems(similarItems, article, ignoreSellersCountry, ref lastMatch, ref prices); if (settings.searchWorldwide && res == TraverseResult.NotEnoughSimilars) // if there isn't enough similar items being sold in seller's country, check other countries as well { ignoreSellersCountry = true; prices.Clear(); lastMatch = -1; res = traverseSimilarItems(similarItems, article, ignoreSellersCountry, ref lastMatch, ref prices); } double priceEstimation = 0; if (settings.priceSetPriceBy == PriceSetMethod.ByPercentageOfLowestPrice && res == TraverseResult.SequenceFound) { priceEstimation = prices[0] * settings.priceFactor; } else if (res == TraverseResult.Culled) { if (settings.logLessThanMinimum) { frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), sArticleID + ">>> " + article["product"]["enName"].InnerText + " (" + article["product"]["expansion"].InnerText + ", " + article["language"]["languageName"].InnerText + ")" + Environment.NewLine + "Current Price: " + article["price"].InnerText + ", unchanged, only " + (lastMatch + 1) + " similar items found (but some outliers were culled)" + (ignoreSellersCountry ? " - worldwide search!" : "") + Environment.NewLine, frm1); } return(null); } else if (res == TraverseResult.HighVariance) { if (settings.logHighPriceVariance) // this signifies that prices were not updated due to too high variance { frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), sArticleID + ">>> " + article["product"]["enName"].InnerText + " (" + article["product"]["expansion"].InnerText + ", " + article["language"]["languageName"].InnerText + ")" + Environment.NewLine + "NOT UPDATED - variance of prices among cheapest similar items is too high" + (ignoreSellersCountry ? " - worldwide search!" : "") + Environment.NewLine, frm1); } return(null); } else if (res == TraverseResult.NotEnoughSimilars) { if (settings.logLessThanMinimum) { frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), sArticleID + ">>> " + article["product"]["enName"].InnerText + " (" + article["product"]["expansion"].InnerText + ", " + article["language"]["languageName"].InnerText + ")" + Environment.NewLine + "Current Price: " + article["price"].InnerText + ", unchanged, only " + (lastMatch + 1) + " similar items found" + (ignoreSellersCountry ? " - worldwide search!" : "") + Environment.NewLine, frm1); } return(null); } else if (settings.condAcceptance == AcceptedCondition.SomeMatchesAbove && lastMatch + 1 < settings.priceMinSimilarItems) // at least one matching item above non-matching is required -> if there wasn't, the last match might have been before min. # of items { if (settings.logLessThanMinimum) { frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), sArticleID + ">>> " + article["product"]["enName"].InnerText + " (" + article["product"]["expansion"].InnerText + ", " + article["language"]["languageName"].InnerText + ")" + Environment.NewLine + "Current Price: " + article["price"].InnerText + ", unchanged, only " + (lastMatch + 1) + " similar items with an item with matching condition above them were found" + (ignoreSellersCountry ? " - worldwide search!" : "") + Environment.NewLine, frm1); } return(null); } else { // if any condition is allowed, use the whole sequence // if only matching is allowed, use whole sequence as well because it is only matching items if (settings.condAcceptance != AcceptedCondition.SomeMatchesAbove) { lastMatch = prices.Count - 1; } if (settings.priceSetPriceBy == PriceSetMethod.ByPercentageOfHighestPrice) { priceEstimation = prices[lastMatch] * settings.priceFactor; } else // estimation by average { for (int i = 0; i <= lastMatch; i++) { priceEstimation += prices[i]; // priceEstimation is initialized to 0 above } priceEstimation /= (lastMatch + 1); // linear interpolation between average (currently stored in priceEstimation) and highest price in the sequence if (settings.priceFactor > 0.5) { priceEstimation += (prices[lastMatch] - priceEstimation) * (settings.priceFactor - 0.5) * 2; } else if (settings.priceFactor < 0.5) // linear interpolation between lowest price and average { priceEstimation = prices[0] + (priceEstimation - prices[0]) * (settings.priceFactor) * 2; } } } if (priceEstimation < settings.priceMinRarePrice && (article["product"]["rarity"].InnerText == "Rare" || article["product"]["rarity"].InnerText == "Mythic")) { priceEstimation = settings.priceMinRarePrice; } // check the estimation is OK string sNewPrice = priceEstimation.ToString("f2", CultureInfo.InvariantCulture); // check it is not above the max price change limits foreach (var limits in settings.priceMaxChangeLimits) { if (dOldPrice < limits.Key) { if (Math.Abs(dOldPrice - priceEstimation) > dOldPrice * limits.Value) { priceEstimation = -1; if (settings.logHighPriceVariance) { frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), sArticleID + ">>> " + article["product"]["enName"].InnerText + " (" + article["product"]["expansion"].InnerText + ", " + article["language"]["languageName"].InnerText + ")" + Environment.NewLine + "NOT UPDATED - change too large: Current Price: " + sOldPrice + ", Calcualted Price:" + sNewPrice + (ignoreSellersCountry ? " - worldwide search!" : "") + Environment.NewLine, frm1); } } break; } } if (priceEstimation > 0 && // is < 0 if change was too large Math.Abs(priceEstimation - dOldPrice) != Double.Epsilon // don't update if it did not change - clearer log ) { if (settings.logUpdated && (settings.logSmallPriceChange || (priceEstimation > dOldPrice + settings.priceMinRarePrice || priceEstimation < dOldPrice - settings.priceMinRarePrice))) { frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), sArticleID + ">>> " + article["product"]["enName"].InnerText + " (" + article["product"]["expansion"].InnerText + ", " + article["language"]["languageName"].InnerText + ")" + Environment.NewLine + "Current Price: " + sOldPrice + ", Calcualted Price:" + sNewPrice + ", based on " + (lastMatch + 1) + " items" + (ignoreSellersCountry ? " - worldwide search!" : "") + Environment.NewLine, frm1); } if (changeMT) { article["condition"].InnerText = "MT"; } return(MKMInteract.RequestHelper.changeStockArticleBody(article, sNewPrice)); } } catch (Exception eError) { #if (DEBUG) frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), "ERR at : " + article["product"]["enName"].InnerText + "\n", frm1); frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), "ERR Msg : " + eError.Message + "\n", frm1); frm1.logBox.Invoke(new logboxAppendCallback(logBoxAppend), "ERR URL : " + sUrl + "\n", frm1); #endif using (var sw = File.AppendText(@".\\error_log.txt")) { sw.WriteLine("ERR at : " + article["product"]["enName"].InnerText); sw.WriteLine("ERR Msg : " + eError.Message); sw.WriteLine("ERR URL : " + sUrl); } } return(null); }