// 按照出版时间,将一个期节点插入this.Issues数组的适当位置 // 可能会抛出异常 void AddIssueByPublishTime(OneIssue issue) { // 规范为10位 string strPublishTime = issue.PublishTime; strPublishTime = CannonicalizepublishTimeString(strPublishTime); strPublishTime = strPublishTime.PadRight(10, '0'); for (int i = 0; i < this.Issues.Count; i++) { OneIssue current_issue = this.Issues[i]; // 规范为10位 string strCurrentPublishTime = current_issue.PublishTime; strCurrentPublishTime = CannonicalizepublishTimeString(strCurrentPublishTime); strCurrentPublishTime = strCurrentPublishTime.PadRight(10, '0'); if (strPublishTime < strCurrentPublishTime) { this.Issues.Insert(i, issue); return; } } this.Issues.Add(issue); }
// 按照出版时间,将一个期节点插入this.Issues数组的适当位置 // 可能会抛出异常 void AddIssueByIssueNo(OneIssue issue) { // 规范为10位 string strYear = issue.PublishTime.Substring(0, 4); string strIssue = issue.Issue.PadLeft(3, '0'); string strLastYear = "0000"; string strLastIssue = "000"; for (int i = 0; i < this.Issues.Count; i++) { OneIssue current_issue = this.Issues[i]; // 规范为10位 string strCurrentYear = current_issue.PublishTime.Substring(0, 4); string strCurrentIssue = current_issue.Issue.PadLeft(3, '0'); if (String.Compare(strYear, strLastYear) >= 0 && string.Compare(strIssue, strLastIssue) > 0 && String.Compare(strYear, strCurrentYear) <= 0 && String.Compare(strIssue, strCurrentIssue) <= 0) { this.Issues.Insert(i, issue); return; } strLastYear = strCurrentYear; strLastIssue = strCurrentIssue; } this.Issues.Add(issue); }
// 移动出版时间 // 可能会抛出异常 static void MovePublishTime(List <OneIssue> issues, List <int> indices, TimeSpan delta) { for (int i = 0; i < indices.Count; i++) { int index = indices[i]; OneIssue issue = issues[index]; string strRest = ""; string strPublishTime = issue.PublishTime; strPublishTime = DateTimeUtil.CannonicalizePublishTimeString(strPublishTime); if (strPublishTime.Length > 8) { strRest = strPublishTime.Substring(8); strPublishTime = strPublishTime.Substring(0, 8); } DateTime time = DateTimeUtil.Long8ToDateTime(strPublishTime); time = time + delta; strPublishTime = DateTimeUtil.DateTimeToString8(time); strPublishTime += strRest; issue.PublishTime = strPublishTime; } }
// 在this.Issues中根据年、期号查找一个节点 // return: // -1 not found // >=0 found int FindIssue(string strYear, string strIssue, int nStartIndex) { for (int i = nStartIndex; i < this.Issues.Count; i++) { OneIssue issue = this.Issues[i]; string strCurrentYear = issue.PublishTime.Substring(0, 4); if (strYear == strCurrentYear && issue.Issue == strIssue) { return(i); } } return(-1); }
private void LoadOptions() { // get options from external json file var optionsFilename = OptionsFileTextBox.Text; if (IsNullOrWhiteSpace(optionsFilename)) { throw new Exception("Please select a JSON Options file"); } var optionsJson = File.ReadAllText(optionsFilename); var serializer = new JavaScriptSerializer(); AllOptions = serializer.Deserialize <Options>(optionsJson); // create IDs for all issues var issueId = 1001; foreach (var issue in AllOptions.Issues) { var oneIssue = new OneIssue { Issue = issue.Trim(), IssueId = issueId }; if (_IssueDictionary.ContainsKey(oneIssue.Issue)) { throw new VoteException($"Duplicate issue: \"{oneIssue.Issue}\""); } _IssueDictionary.Add(oneIssue.Issue, oneIssue); //_IssueIdDictionary.Add(issueId, oneIssue); issueId++; } // create IDs for all topics var topicId = 1001; foreach (var topic in AllOptions.Topics) { var oneTopic = new OneTopic { Topic = topic.Topic.Trim(), TopicId = topicId }; if (_TopicDictionary.ContainsKey(oneTopic.Topic)) { throw new VoteException($"Duplicate topic: \"{oneTopic.Topic}\""); } if (topic.Issues.Count == 0) { throw new VoteException($"No issues for topic: \"{oneTopic.Topic}\""); } foreach (var issue in topic.Issues) { if (!_IssueDictionary.TryGetValue(issue.Trim(), out var oneIssue)) { throw new VoteException( $"Missing issue: \"{issue.Trim()}\" for topic \"{oneTopic.Topic}\""); } oneIssue.TopicIds.Add(topicId); oneTopic.IssueIds.Add(oneIssue.IssueId); } _TopicDictionary.Add(topic.Topic.Trim(), oneTopic); //_TopicIdDictionary.Add(topicId, oneTopic); topicId++; } // make sure all Issues have at least one topic foreach (var kvp in _IssueDictionary) { if (kvp.Value.TopicIds.Count == 0) { throw new VoteException($"No topics for issue: \"{kvp.Value.Issue}\""); } } // load the answers file CSV var answersFilename = AnswersFileTextBox.Text; if (IsNullOrWhiteSpace(answersFilename)) { throw new Exception("Please select a CSV Answers Mapping file"); } var missingTopics = 0; var duplicateTopics = 0; using (var csvReader = new CsvReader(new StringReader(File.ReadAllText(answersFilename)), true)) { var headers = csvReader.GetFieldHeaders(); while (csvReader.ReadNextRecord()) { var questions = csvReader[headers[0]].Split('\n'); var topic = csvReader[headers[1]].Trim(); if (!_TopicDictionary.TryGetValue(topic, out var topicEntry)) { AppendStatusText($"Missing topic {topic} for answers {csvReader[headers[0]]}"); missingTopics++; } else { // create question map entries foreach (var question in questions) { var key = Regex.Match(question, @"\((?<key>.+)\)$").Groups["key"].Value; if (IsNullOrWhiteSpace(key)) { throw new Exception($"Missing key in question {question}"); } if (_QuestionDictionary.TryGetValue(key, out var questionEntry)) { if (questionEntry != topicEntry.TopicId) { AppendStatusText($"Queston key {key} maps to different topics"); duplicateTopics++; } } else { _QuestionDictionary.Add(key, topicEntry.TopicId); } } } } } if (missingTopics > 0) { throw new VoteException($"There were {missingTopics} missing topics in answers mapping"); } if (duplicateTopics > 0) { throw new VoteException($"There were {duplicateTopics} duplicate topics with conflicting mapping in answers mapping"); } }
// 将猜测的期节点合并到this.Issues数组中 int MergeGuessIssues(List <OneIssue> guess_issues, out string strError) { strError = ""; try { List <int> not_matchs = new List <int>(); int nLastIndex = 0; TimeSpan last_delta = new TimeSpan(0); for (int i = 0; i < guess_issues.Count; i++) { OneIssue guess_issue = guess_issues[i]; string strYear = guess_issue.PublishTime.Substring(0, 4); string strIssue = guess_issue.Issue; // 在this.Issues中根据年、期号查找一个节点 // return: // -1 not found // >=0 found int index = FindIssue(strYear, strIssue, nLastIndex); if (index == -1) { not_matchs.Add(i); // 没有匹配上的下标 // 将一个期节点插入this.Issues数组的适当位置 // 可能会抛出异常 AddIssueByIssueNo(guess_issue); guess_issue.IsGuess = true; } else { OneIssue found = this.Issues[index]; string strRealPublishTime = found.PublishTime; string strGuessPublishTime = guess_issue.PublishTime; strRealPublishTime = CannonicalizePublishTimeString(strRealPublishTime); strGuessPublishTime = CannonicalizePublishTimeString(strGuessPublishTime); // 看看差多少天,然后对前面没有匹配的节点的出版时间进行相应的平移 DateTime real = DateTimeUtil.Long8ToDateTime(strRealPublishTime); DateTime guess = DateTimeUtil.Long8ToDateTime(strGuessPublishTime); TimeSpan delta = real - guess; last_delta = delta; // 移动出版时间 // 可能会抛出异常 MovePublishTime(guess_issues, not_matchs, delta); not_matchs.Clear(); } } // 最后一段没有匹配上的 if (not_matchs.Count > 0 && last_delta != new TimeSpan(0)) { // 移动出版时间 // 可能会抛出异常 MovePublishTime(guess_issues, not_matchs, last_delta); not_matchs.Clear(); } return(0); } catch (Exception ex) { strError = ex.Message; return(-1); } }
// 创建每个期对象 // return: // -1 error // 0 无法获得订购时间范围 // 1 成功 public int CreateIssues(out string strError) { strError = ""; List <OneIssue> issues = new List <OneIssue>(); string strStartDate = ""; string strEndDate = ""; // 获得可用的最大订购时间范围 // return: // -1 error // 0 not found // 1 found int nRet = GetMaxOrderRange(out strStartDate, out strEndDate, out strError); if (nRet == -1) { return(-1); } if (nRet == 0) { strError = "无法获得订购时间范围"; return(0); } // 在时间范围内寻找当年期号为'1'的已经存在的期节点, // 如果不存在,则假定第一期的当年期号为'1' string strCurrentPublishTime = strStartDate; int nCurrentIssue = 1; // 进行循环,增补全部节点 for (; ;) { try { // 检查一下这个出版时间是否超过订购时间范围? if (InOrderRange(strCurrentPublishTime) == false) { break; // 避免最后多插入一个 } } catch (Exception ex) { strError = ex.Message; return(-1); } OneIssue issue = new OneIssue(); issue.LoadRecord("<root />", out strError); issue.PublishTime = strCurrentPublishTime; issue.Issue = nCurrentIssue.ToString(); issues.Add(issue); string strNextPublishTime = ""; int nNextIssue = 0; /* * string strNextIssue = ""; * string strNextZong = ""; * string strNextVolume = ""; * */ { int nIssueCount = 0; // 获得一年内的期总数 // return: // -1 出错 // 0 无法获得 // 1 获得 nRet = GetOneYearIssueCount(strCurrentPublishTime, out nIssueCount, out strError); try { // 预测下一期的出版时间 // parameters: // strPublishTime 当前这一期出版时间 // nIssueCount 一年内出多少期 strNextPublishTime = NextPublishTime(strCurrentPublishTime, nIssueCount); } catch (Exception ex) { // 2009/2/8 strError = "在获得日期 '" + strCurrentPublishTime + "' 的后一期出版日期时发生错误: " + ex.Message; return(-1); } if (strNextPublishTime == "????????") { break; } try { // 检查一下这个出版时间是否超过订购时间范围? if (InOrderRange(strNextPublishTime) == false) { break; // 避免最后多插入一个 } } catch (Exception ex) { strError = ex.Message; return(-1); } // 号码自动增量需要知道一个期是否跨年,可以通过查询采购信息得到一年所订阅的期数 if (nCurrentIssue >= nIssueCount) { // 跨年了 // strNextIssue = "1"; nNextIssue = 1; } else { // strNextIssue = (nCurrentIssue + 1).ToString(); nNextIssue = nCurrentIssue + 1; } /* * strNextZong = IncreaseNumber(ref_item.Zong); * if (nRefIssue >= nIssueCount && nIssueCount > 0) * strNextVolume = IncreaseNumber(ref_item.Volume); * else * strNextVolume = ref_item.Volume; */ } // nCreateCount++; strCurrentPublishTime = strNextPublishTime; nCurrentIssue = nNextIssue; } // 将猜测的期节点合并到this.Issues数组中 nRet = MergeGuessIssues(issues, out strError); if (nRet == -1) { return(-1); } return(1); }