/// <summary> /// Bills with no recorded positions are considered bills with no reports. /// </summary> /// <returns></returns> private IOrderedEnumerable <BillRow> CollectNoPositionBills() { var all_bills = BillRow.RowSet(); // All bills for the current biennium. var result = from item in all_bills where ((item.Position == string.Empty) && (item.NegativeScore > 0)) orderby item.NegativeScore descending select item; return(result); }
/// <summary> /// Sets contents of some database tables, using data from table files contained in the zipped download. /// </summary> /// <returns>True if all is well, False if unable to access table files expected to be present</returns> public static bool EnsureGlobalData() // public so that XUnit TestNewOrChangePrefix can ensure table contents are available { bool result = true; Config.Instance.ReadYourself(); // Start of configuration data lifetime GlobalData.Profiles = new List <BillProfile>(); if (GlobalData.BillRows == null) { GlobalData.BillRows = BillRow.RowSet(); } if (GlobalData.HistoryTable == null) { string path = Path.Combine(Config.Instance.BillsFolder, "BILL_HISTORY_TBL.dat"); if (File.Exists(path)) { GlobalData.HistoryTable = new BillHistoryTable(path); } else { result = false; } } if (GlobalData.VersionTable == null) { string path = Path.Combine(Config.Instance.BillsFolder, "BILL_VERSION_TBL.dat"); if (File.Exists(path)) { GlobalData.VersionTable = new BillVersionTable(path); } else { result = false; } } if (GlobalData.LocationTable == null) { string path = Path.Combine(Config.Instance.BillsFolder, "LOCATION_CODE_TBL.dat"); if (File.Exists(path)) { GlobalData.LocationTable = new LocationCodeTable(path); } else { result = false; } } GlobalData.MostRecentEachBill = new List <Bill_Identifier>(); return(result); }
/// <summary> /// Build GlobalData.BillRows from scratch. /// The steps for this are /// 1. Import the BILL_TBL.dat data into GlobalData.BillRows. This fills 9 of the 15 BillRow fields. /// </summary> /// <param name="form1">The main (Form1) display form. Display messages and progress here.</param> /// <param name="path_bill_tbl">Fully-qualified path to BILL_TBL.dat</param> /// <param name="mostRecentEachBill">For each bill, the Bill_Identifier identifying the most recent version</param> private void BuildBillRowsTable(Form1 form1, string path_bill_tbl, List <BillProfile> profiles) { // Import BILL_TBL.dat, which is the legislative site's information on bills before the legislature. // Trim all non-bill items during the import -- we want only type AB and SB (Assembly and Senate Bills) var bill_table_wrapper = new Bill_Tbl_Wrapper(); bill_table_wrapper.ReadYourself(); // Import BILL_TBL.dat List <BillRow> rows_with_positions = BillRow.RowsetByQuery("Select * from Billrows Where Position <> ''"); List <BillRow> all_rows = BillRow.RowSet(); List <string> reports = BillUtils.HtmlFolderContents(); // Re-create GlobalData.BillRows, using data from bill_table_wrapper and elsewhere. GlobalData.BillRows.Clear(); List <string> SkipIf = new List <String>() { "Chaptered", "Died", "Enrolled", "Failed", "Failed Passage in Committee", "Vetoed" }; foreach (var item in bill_table_wrapper) { // Don't process bills that will not progress further in the legislature. //string result = SkipIf.FirstOrDefault(s => s == item.Current_status); //if (result != null) continue; // Use data from bill_table_wrapper. Some fields are left blank. var bill_row = new BillRow(); bill_row.MeasureType = item.Measure_type; // e.g. AB bill_row.MeasureNum = BillUtils.Ensure4DigitNumber(item.Measure_num); // e.g. 0010 bill_row.Bill = $"{bill_row.MeasureType}{BillUtils.EnsureNoLeadingZerosBill(bill_row.MeasureNum)}"; // e.g. AB10 //bill_row.Lob = item.; //bill_row.NegativeScore = item; //bill_row.PositiveScore = item; //bill_row.Position = item; // Hand Entered, e.g. Monitor bill_row.BillVersionID = VersionID(item); // e.g. 20190AB199INT //bill_row.Author = item; //bill_row.Title = item; bill_row.Location = item.Current_location; // e.g. CX08 bill_row.Location2nd = item.Current_secondary_loc; // e.g. Committee bill_row.MeasureState = item.Measure_state; // e.g. Amended Assembly bill_row.CurrentHouse = item.Current_house; // e.g. Assembly bill_row.CurrentStatus = item.Current_status; // e.g. In Committee Process // Obtain the author, title, lob file path, and positive/negative scores from the profile for this bill var four_digit_billid = BillUtils.Ensure4DigitNumber(bill_row.Bill); var profile = (from x in profiles where x.Identifier.BillID == four_digit_billid select x).First(); if (profile != null) { bill_row.Author = profile.Identifier.Author; bill_row.Title = profile.Identifier.Title; bill_row.Lob = profile.Identifier.LobPath; bill_row.NegativeScore = profile.NegScore; bill_row.PositiveScore = profile.PosScore; } else { throw new ApplicationException($"InitializeBillRows.BuildBillRowsTable: Bill {bill_row.Bill} is present in bill_table_wrapper, but not in GlobalData.Profiles."); } // Fill in the Position data -- the position we are taking on this bill. If we have a position, it is // in one of two places // 1. The database BillRows table (not all bills have a report), or var pos = (from x in rows_with_positions where x.Bill == bill_row.Bill select x).FirstOrDefault(); if (pos != null) { bill_row.Position = pos.Position; } // 2. If that table hasn't been updated, in the actual report // If the two are in conflict, the bill report wins. var short_id = BillUtils.EnsureNoLeadingZerosBill(bill_row.Bill); var report_file = (from x in reports where x.Contains($"{short_id}.html") select x).FirstOrDefault(); if (report_file != null) { var report = new BillReport(report_file); bill_row.Position = report.Position; } // Add this row to GlobalData.BillRows GlobalData.BillRows.Add(bill_row); } // Sort the table before returning it. Ordered by bill ID, e.g. AB0001, communicates well GlobalData.BillRows = GlobalData.BillRows.OrderBy(a => a.Bill).ToList(); }
/// <summary> /// This background worker performs the time-consuming task of searching all current bills for two words /// that are within a specified distance of each other. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void bgw_SearchNearby(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; if (worker == null) { throw new ApplicationException("bgw_SearchNearby failed to instantiate BackgroundWorker"); } // Ensure passed strings are valid. If so take the minimum and maximum distance values. string param_problem = ""; bgwSearchArguments args = (bgwSearchArguments)e.Argument; if (NEWs(args.word1)) { BuildErrorMessage(ref param_problem, "First word must be specified"); } if (NEWs(args.word2)) { BuildErrorMessage(ref param_problem, "Second word must be specified"); } if (NEWs(args.text_min)) { BuildErrorMessage(ref param_problem, "Minimum size must be specified"); } if (NEWs(args.text_max)) { BuildErrorMessage(ref param_problem, "Maximum must be specified"); } args.word1 = args.word1.Trim(); args.word2 = args.word2.Trim(); args.text_min = args.text_min.Trim(); args.text_max = args.text_max.Trim(); if (!Int16.TryParse(args.text_min, out short min_dist)) { BuildErrorMessage(ref param_problem, "Unable to parse Minimum distance"); } if (min_dist < 0) { BuildErrorMessage(ref param_problem, "Minimum distance must not be negative"); } if (!Int16.TryParse(args.text_max, out short max_dist)) { BuildErrorMessage(ref param_problem, "Unable to parse Maximum distance"); } if (max_dist < 0) { BuildErrorMessage(ref param_problem, "Maximum distance must not be negative"); } if (param_problem.Length > 0) { throw new ApplicationException(param_problem); } GlobalData.BillRows = BillRow.RowSet(); var bills = GlobalData.BillRows.OrderBy(item => item.Bill).ToList(); int one_percent = bills.Count / 100; Regex rx = CreateRegex(args.word1, args.word2, min_dist, max_dist); int progress_bar_value = 0; using (StreamWriter sw_matches = new StreamWriter("C:/Scratch/Scout2_Matches.txt")) { using (StreamWriter sw_bills = new StreamWriter("C:/Scratch/Scout2_Bills.txt")) { int count = 0; foreach (var bill in bills) { MatchCollection found = SingleFile(bill, rx); if (found.Count > 0) { sw_bills.WriteLine($"{bill.Bill}"); sw_matches.WriteLine($"{bill.Bill} {bill.Title} ({bill.Author})"); foreach (var match in found) { sw_matches.WriteLine($"\t{Cleanup(match.ToString())}"); } } if (++count % one_percent == 0) { worker.ReportProgress(++progress_bar_value); } } } } }