├── README.md ├── .gitignore ├── .idea ├── vcs.xml ├── misc.xml └── modules.xml ├── src ├── main.rs ├── errors.rs ├── tests.rs └── lib.rs ├── Cargo.toml ├── res ├── test_result.csv ├── test_data.csv └── cons_name_translate.csv └── election_result_process.iml /README.md: -------------------------------------------------------------------------------- 1 | This program is in sole purpose of practise more rust. 2 | 3 | cargo run 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | res/all_data.csv 5 | res/all_results.csv 6 | res/output.csv 7 | .idea/workspace.xml 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate election_result_process; 2 | use election_result_process::{get_constituency_name, aggregate_result_by_symbols}; 3 | use std::env; 4 | 5 | 6 | fn main() { 7 | let args:Vec = env::args().collect(); 8 | aggregate_result_by_symbols(&args[1], &args[2]); 9 | } 10 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "election_result_process" 3 | version = "0.1.0" 4 | authors = ["Tarin Mahmood "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | csv = "1.1.1" 11 | regex = "1" 12 | -------------------------------------------------------------------------------- /res/test_result.csv: -------------------------------------------------------------------------------- 1 | Constituency,Center,আম,কাস্তে,গোলাপ ফুল,ধানের শীষ,নৌকা,মিনার,লাঙ্গল,হাত পাখা,হুক্কা,মোট বৈধ,মোট বাতিল,প্রদত্ত ভোট,শতকরা হার,total_voters 2 | 1 Panchagarh-1,"1 বাংলাবান্ধা সরকারী প্রাথমিক বিদ্যালয়, বাংলাবান্ধা বাংলাবান্ধা",2,0,181,693,1957,0,4,5,5,2847,22,2869,90.22%,3180 3 | 1 Panchagarh-1,"2 সিপাইপাড়া সরকারী প্রাথমিক বিদ্যালয়, সিপাইপাড়া, বাংলাবান্ধা সিপাইপাড়া, বাংলাবান্ধা",0,0,76,931,1509,0,1,1,1,2519,11,2530,91.20%,2774 4 | 2 Panchagarh-2,"1 কালিগঞ্জ এস, পি উচ্চ বিদ্যালয় কালিগঞ্জ",1,3,0,903,1544,0,12,52,3,2518,19,2537,78.30%,3240 5 | 3 Thakurgaon-1,1 আর কে স্টেট উচ্চ বিদ্যালয়,0,0,0,805,1097,3,0,26,0,1931,114,2045,70.88%,2885 6 | -------------------------------------------------------------------------------- /election_result_process.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/errors.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | use std::error::Error; 3 | 4 | #[derive(Debug, Clone)] 5 | pub struct InvalidConstituencyName; 6 | 7 | impl fmt::Display for InvalidConstituencyName { 8 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 9 | write!(f, "Failed to get constituency name") 10 | } 11 | } 12 | 13 | impl Error for InvalidConstituencyName { 14 | fn description(&self) -> &str { 15 | "Failed to get constituency name" 16 | } 17 | 18 | fn cause(&self) -> Option<&dyn Error> { 19 | // Generic error, underlying cause isn't tracked. 20 | None 21 | } 22 | } 23 | 24 | #[derive(Debug, Clone)] 25 | pub struct NotFamiliarRowType; 26 | 27 | impl fmt::Display for NotFamiliarRowType { 28 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 29 | write!(f, "Can't detect the type of row automatically") 30 | } 31 | } 32 | 33 | impl Error for NotFamiliarRowType { 34 | fn description(&self) -> &str { 35 | "Can't detect the type of row automatically" 36 | } 37 | 38 | fn cause(&self) -> Option<&dyn Error> { 39 | // Generic error, underlying cause isn't tracked. 40 | None 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /res/test_data.csv: -------------------------------------------------------------------------------- 1 | ,,,"০০১ পঞ্চগড়-১ : সংসদ সদস্য",,,,,,,,,,,,,,,,,, 2 | "কেন্দ্র","মোট ভোটার","আল রাশেদ প্রধান ","মোঃ আব্দুল্লাহ ","মোঃ সুমন রানা ","শেখ মোঃ- হাবিবুর রহমান ","ব্যারিস্টার মুহম্মদ নওশাদ জমির ","মোঃ মজাহারুল হক প্রধান ","মোঃ আবু সালেক ","মোট বৈধ","মোট বাতিল","প্রদত্ত ভোট","শতকরা হার",,,,,,,,, 3 | ,,"হুক্কা ","হাত পাখা ","গোলাপ ফুল ","আম ","ধানের শীষ ","নৌকা ","লাঙ্গল ",,,,,,,,,,,,, 4 | "1 বাংলাবান্ধা সরকারী প্রাথমিক বিদ্যালয়, বাংলাবান্ধা বাংলাবান্ধা ",3180,5,5,181,2,693,1957,4,2847,22,2869,90.22%,,,,,,,,, 5 | "2 সিপাইপাড়া সরকারী প্রাথমিক বিদ্যালয়, সিপাইপাড়া, বাংলাবান্ধা সিপাইপাড়া, বাংলাবান্ধা",2774,1,1,76,0,931,1509,1,2519,11,2530,91.20%,,,,,,,,, 6 | ,,,,,,,,,,,,,,,,,,,,, 7 | ,,,"০০২ পঞ্চগড়-২ : সংসদ সদস্য",,,,,,,,,,,,,,,,,, 8 | "কেন্দ্র","মোট ভোটার","তাসমিয়া প্রধান ","মোঃ ফয়জুর রহমান মিঠু ","মোঃ কামরুল হাসান প্রধান ","মোঃ নূরুল ইসলাম সুজন ","মোঃ আশরাফুল আলম ","ফরহাদ হোসেন আজাদ ","মোঃ লুৎফর রহমান রিপন ","মোট বৈধ","মোট বাতিল","প্রদত্ত ভোট","শতকরা হার",,,,,,,,, 9 | ,,"হুক্কা ","আম ","হাত পাখা ","নৌকা ","কাস্তে ","ধানের শীষ ","লাঙ্গল ",,,,,,,,,,,,, 10 | "1 কালিগঞ্জ এস, পি উচ্চ বিদ্যালয় কালিগঞ্জ",3240,3,1,52,1544,3,903,12,2518,19,2537,78.30%,,,,,,,,, 11 | ,,"০০৩ ঠাকুরগাঁও-১ : সংসদ সদস্য",,,,,,,,,,,,,,,,,,, 12 | ,,,,,,,,,,,,,,,,,,,,, 13 | "কেন্দ্র","মোট ভোটার","রমেশ চন্দ্র সেন ","মির্জা ফখরুল ইসলাম আলমগীর ","মোঃ আব্দুল জববার ","মোঃ রফিকুল ইসলাম ","মোট বৈধ","মোট বাতিল","প্রদত্ত ভোট","শতকরা হার",,,,,,,,,,,, 14 | ,,"নৌকা ","ধানের শীষ ","হাত পাখা ","মিনার ",,,,,,,,,,,,,,,, 15 | "1 আর কে স্টেট উচ্চ বিদ্যালয়",2885,1097,805,26,3,1931,114,2045,70.88%,,,,,,,,,,,, -------------------------------------------------------------------------------- /src/tests.rs: -------------------------------------------------------------------------------- 1 | use crate::{get_constituency_name, aggregate_result_by_symbols, check_for_new_symbols, is_constituency_row, is_center_information_row, CONSTITUENCY_REG, get_constituencies_translated, get_result, get_other_columns, extract_name}; 2 | use std::fs::File; 3 | use std::io::Read; 4 | use csv::StringRecord; 5 | use regex::Regex; 6 | use std::collections::{BTreeMap, HashMap}; 7 | 8 | const FILE_NAME: &str = "res/test_data.csv"; 9 | const OUTPUT_FILE_NAME: &str = "res/output.csv"; 10 | const CONST_LINE: &str = ",,\"০০৩ ঠাকুরগাঁও-১ : সংসদ সদস্য\",,,,,,,,,,,,,,,,,,,"; 11 | const CONST_LINE_WRONG: &str = ",,\"০০৩ ঠাকুরগাঁও১ সংসদ সদস্য\",,,,,,,,,,,,,,,,,,,"; 12 | const CONST_LINE_EXTRA_SPACE: &str = ",,,\"০০৩ ঠাকুরগাঁও-১ : সংসদ সদস্য\",,,,,,,,,,,,,,,,,,,"; 13 | const CONST_LINE_SHOULD_NOT_OK: &str = "৪০১, ৪০২, ৪০৩, ৪০৪, ৪০৫, ৪০৬, ৪০৭), (পুরুষ ভোটার-১"; 14 | 15 | #[test] 16 | pub fn t_regexp_correct() { 17 | let re = Regex::new(CONSTITUENCY_REG).unwrap(); 18 | assert!(re.is_match("০০১ Thisis-০১ : সংসদ সদস্য)")) 19 | } 20 | 21 | #[test] 22 | fn t_why_messing_up() { 23 | const CON: &str = r#",,,"০৫৪ রাজশাহী-৩",,,,,,,,,,,,,,,,,,"#; 24 | let r = read_single_csv_row(CON).unwrap(); 25 | println!("{:?}", r); 26 | assert!(is_constituency_row(&r)); 27 | let mut const_translated = HashMap::new(); 28 | const_translated.insert("০৫৪ রাজশাহী-৩".to_string(), "54 Rajshahi-3".to_string()); 29 | const_translated.insert("০০২ পঞ্চগড়-২ ".to_string(), "2 Panchagarh-2".to_string()); 30 | let n = get_constituency_name(&r, &const_translated).unwrap(); 31 | println!("{}", n); 32 | assert_eq!(n, "54 Rajshahi-3"); 33 | 34 | } 35 | 36 | 37 | #[test] 38 | fn t_constituency_row() { 39 | const CON: &str = r#",,,"০০১ পঞ্চগড়-১ : সংসদ সদস্য",,,,,,,,,,,,,,,,,,"#; 40 | let r = read_single_csv_row(CON); 41 | assert!(is_constituency_row(&r.unwrap())); 42 | } 43 | 44 | #[test] 45 | fn t_constituency_row_alt() { 46 | const CON: &str = r#",,,"০০১ পঞ্চগড়-১",,,,,,,,,,,,,,,,,,"#; 47 | let r = read_single_csv_row(CON); 48 | assert!(is_constituency_row(&r.unwrap())); 49 | } 50 | 51 | #[test] 52 | fn t_constituency_name_alt() { 53 | const CON: &str = r#",,,"০০১ পঞ্চগড়-১ : সংসদ সদস্য",,,,,,,,,,,,,,,,,,"#; 54 | let r = read_single_csv_row(CON).unwrap(); 55 | let mut const_translated = HashMap::new(); 56 | const_translated.insert("০০১ পঞ্চগড়-১".to_string(), "1 Panchagarh-1".to_string()); 57 | const_translated.insert("০০২ পঞ্চগড়-২ ".to_string(), "2 Panchagarh-2".to_string()); 58 | let n = get_constituency_name(&r, &const_translated).unwrap(); 59 | assert_eq!(n, "1 Panchagarh-1"); 60 | } 61 | 62 | #[test] 63 | fn t_invalid_constituency_name() { 64 | let re = Regex::new(CONSTITUENCY_REG).unwrap(); 65 | let r = extract_name(&re, CONST_LINE_SHOULD_NOT_OK); 66 | println!("{:?}", r); 67 | assert!(r.is_none()) 68 | } 69 | 70 | #[test] 71 | fn t_constituency_name() { 72 | const CON: &str = r#",,,"০০১ পঞ্চগড়-১",,,,,,,,,,,,,,,,,,"#; 73 | let r = read_single_csv_row(CON).unwrap(); 74 | let mut const_translated = HashMap::new(); 75 | const_translated.insert("০০১ পঞ্চগড়-১".to_string(), "1 Panchagarh-1".to_string()); 76 | const_translated.insert("০০২ পঞ্চগড়-২ ".to_string(), "2 Panchagarh-2".to_string()); 77 | let n = get_constituency_name(&r, &const_translated).unwrap(); 78 | assert_eq!(n, "1 Panchagarh-1"); 79 | } 80 | 81 | 82 | #[test] 83 | fn t_center_row() { 84 | const CEN: &str = r#"কেন্দ্র","মোট ভোটার","আল রাশেদ প্রধান ","মোঃ আব্দুল্লাহ ","মোঃ সুমন রানা ","শেখ মোঃ- হাবিবুর রহমান ","ব্যারিস্টার মুহম্মদ নওশাদ জমির ","মোঃ মজাহারুল হক প্রধান ","মোঃ আবু সালেক ","মোট বৈধ","মোট বাতিল","প্রদত্ত ভোট","শতকরা হার",,,,,,,,,"#; 85 | let r = read_single_csv_row(CEN); 86 | assert!(is_center_information_row(&r.unwrap())); 87 | } 88 | 89 | #[test] 90 | fn t_finding_all_symbols() { 91 | let lines = vec![ 92 | r#",,"হুক্কা ","হাত পাখা ","গোলাপ ফুল ","আম ","ধানের শীষ ","নৌকা ","লাঙ্গল ",,,,,,,,,,,,,"#, 93 | r#",,"হুক্কা ","আম ","হাত পাখা ","নৌকা ","কাস্তে ","ধানের শীষ ","লাঙ্গল ",,,,,,,,,,,,,"#, 94 | r#",,"নৌকা ","ধানের শীষ ","হাত পাখা ","মিনার ",,,,,,,,,,,,,,,,"# 95 | ]; 96 | let mut symbol_list = Vec::new(); 97 | for line in lines { 98 | let mut rdr = csv::ReaderBuilder::new() 99 | .has_headers(false) 100 | .from_reader(line.as_bytes()); 101 | let record = rdr.records().next().unwrap().unwrap(); 102 | check_for_new_symbols(&record, &mut symbol_list) 103 | } 104 | let p_result = vec!["হুক্কা", "হাত পাখা", "গোলাপ ফুল", "আম", "ধানের শীষ", "নৌকা", "লাঙ্গল", "কাস্তে", "মিনার"]; 105 | assert_eq!(p_result, symbol_list); 106 | } 107 | 108 | #[test] 109 | fn t_aggregate_result_by_symbols() { 110 | aggregate_result_by_symbols(FILE_NAME, OUTPUT_FILE_NAME); 111 | let mut content = String::new(); 112 | File::open("res/test_result.csv") 113 | .and_then(|mut f| f.read_to_string(&mut content)) 114 | .expect("Failed to load result file"); 115 | let mut original_result = String::new(); 116 | File::open("res/output.csv") 117 | .unwrap() 118 | .read_to_string(&mut original_result); 119 | assert_eq!(content, original_result); 120 | } 121 | 122 | #[test] 123 | fn t_find_constituency_names() { 124 | let c_list = get_constituencies_translated(); 125 | let record = read_single_csv_row(CONST_LINE); 126 | let name = get_constituency_name(&record.unwrap(), &c_list); 127 | assert_eq!(name.unwrap(), "3 Thakurgaon-1"); 128 | } 129 | 130 | #[test] 131 | fn t_find_constituency_names_on_fail() { 132 | let c_list = get_constituencies_translated(); 133 | let record = read_single_csv_row(CONST_LINE_WRONG); 134 | let res = get_constituency_name(&record.unwrap(), &c_list); 135 | println!("{:?}", res); 136 | assert!(res.is_err()); 137 | } 138 | 139 | #[test] 140 | fn t_find_constituency_names_with_spacing_issue() { 141 | let c_list = get_constituencies_translated(); 142 | let record = read_single_csv_row(CONST_LINE_EXTRA_SPACE); 143 | let name = get_constituency_name(&record.unwrap(), &c_list); 144 | assert_eq!(name.unwrap(), "3 Thakurgaon-1"); 145 | } 146 | 147 | #[test] 148 | fn t_parse_result_row() { 149 | let symbol_positions: Vec = vec!["নৌকা", "ধানের শীষ", "হাত পাখা", "মিনার"].iter().map(|k| k.to_string()).collect(); 150 | let r = r#"1 আর কে স্টেট উচ্চ বিদ্যালয়",2885,1097,805,26,3,1931,114,2045,70.88%,,,,,,,,,,,,"#; 151 | let record = read_single_csv_row(r).unwrap(); 152 | let mut results = BTreeMap::new(); 153 | let mut result_expected = BTreeMap::new(); 154 | result_expected.insert(symbol_positions[0].clone(), "1097".to_string()); 155 | result_expected.insert(symbol_positions[1].clone(), "805".to_string()); 156 | result_expected.insert(symbol_positions[2].clone(), "26".to_string()); 157 | result_expected.insert(symbol_positions[3].clone(), "3".to_string()); 158 | get_result(&record, &symbol_positions, &mut results); 159 | assert_eq!(result_expected, results); 160 | } 161 | 162 | #[test] 163 | fn t_parse_other_columns() { 164 | use std::iter::FromIterator; 165 | let other_columns = vec!["মোট বৈধ", "মোট বাতিল", "প্রদত্ত ভোট", "শতকরা হার"].iter().map(|s| s.to_string().clone()).collect::>(); 166 | let symbol_positions: Vec = vec!["নৌকা", "ধানের শীষ", "হাত পাখা", "মিনার"].iter().map(|k| k.to_string()).collect(); 167 | let r = r#"1 আর কে স্টেট উচ্চ বিদ্যালয়",2885,1097,805,26,3,1931,114,2045,70.88%,,,,,,,,,,,,"#; 168 | let record = read_single_csv_row(r).unwrap(); 169 | let mut result_expected = BTreeMap::from_iter( 170 | vec![ 171 | (other_columns[0].clone(), "1931".to_string()), 172 | (other_columns[1].clone(), "114".to_string()), 173 | (other_columns[2].clone(), "2045".to_string()), 174 | (other_columns[3].clone(), "70.88%".to_string()) 175 | 176 | ]); 177 | let mut results = BTreeMap::new(); 178 | get_other_columns(&record, &other_columns, 6, &mut results); 179 | assert_eq!(result_expected, results); 180 | } 181 | 182 | fn read_single_csv_row(row: &str) -> Result { 183 | let mut rdr = csv::ReaderBuilder::new().has_headers(false).from_reader(row.as_bytes()); 184 | rdr.records().next().unwrap() 185 | } 186 | 187 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate csv; 2 | 3 | use csv::{StringRecord, Writer}; 4 | use std::error::Error; 5 | use std::path::Path; 6 | use std::collections::HashMap; 7 | use crate::errors::InvalidConstituencyName; 8 | use regex::Regex; 9 | use std::collections::btree_map::BTreeMap; 10 | use std::ops::Index; 11 | 12 | 13 | mod errors; 14 | 15 | const CONSTITUENCY_REG: &str = "^(?P[০১২৩৪৫৬৭৮৯]{3} .[^-() ,]*-[০১২৩৪৫৬৭৮৯]{1,2})"; 16 | 17 | 18 | #[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] 19 | struct CenterDetails { 20 | constituency: String, 21 | center: String, 22 | } 23 | 24 | impl CenterDetails { 25 | fn new(constituency: &str, center: &str) -> CenterDetails { 26 | CenterDetails { 27 | constituency: constituency.to_string(), 28 | center: center.to_string(), 29 | } 30 | } 31 | } 32 | 33 | pub fn get_constituencies_translated() -> HashMap { 34 | let rdr = csv::ReaderBuilder::new() 35 | .has_headers(false) 36 | .from_path(Path::new("res/cons_name_translate.csv")); 37 | let mut cons_list = HashMap::new(); 38 | let mut b = false; 39 | let mut name = String::new(); 40 | for result in rdr.unwrap().records() { 41 | // load the row 42 | let record = result.unwrap(); 43 | if !b { 44 | name = record.get(0).unwrap().to_string(); 45 | } else { 46 | cons_list.insert(name.clone(), record.get(0).unwrap().to_string()); 47 | } 48 | b = !b; 49 | } 50 | cons_list 51 | } 52 | 53 | fn extract_name(re: &Regex, input: &str) -> Option { 54 | re.captures(input).and_then(|cap| { 55 | cap.name("cname").map(|login| login.as_str().to_string()) 56 | }) 57 | } 58 | // get constituency name 59 | pub fn get_constituency_name(line: &StringRecord, const_translated: &HashMap) -> Result> { 60 | // constituency names are located in 3rd column, ends at ':' sign 61 | // find to ':' and slice it to that position from 0 62 | let re = Regex::new(CONSTITUENCY_REG).unwrap(); 63 | let found: Vec = line.iter() 64 | .filter(|s| re.is_match(s)) 65 | .map(|s| extract_name(&re, s.clone()).unwrap()) 66 | .map(|k| const_translated.get(&k).unwrap_or(&k).to_string()) 67 | .collect(); 68 | found.get(0).ok_or_else(||InvalidConstituencyName.into()).and_then(|d| Ok(d.to_string())) 69 | } 70 | 71 | // go through a CSV file and calculate total votes par symbols on 72 | // polling centers and constituencies 73 | pub fn aggregate_result_by_symbols(file_name: &str, output_file: &str) -> Result<(), Box> { 74 | println!("Starting ..."); 75 | // start reading the csv file 76 | let const_translate = get_constituencies_translated(); 77 | let other_columns = vec!["মোট বৈধ", "মোট বাতিল", "প্রদত্ত ভোট", "শতকরা হার"].iter().map(|s| s.to_string().clone()).collect::>(); 78 | let rdr = csv::ReaderBuilder::new() 79 | .has_headers(false) 80 | .from_path(Path::new(file_name)); 81 | // all the data are aggregated in to a map 82 | let mut aggregated_data: BTreeMap> = BTreeMap::new(); 83 | // list of all the symbols 84 | let mut symbol_list: Vec = Vec::new(); 85 | let mut constituency = String::new(); 86 | // if next row is the list of symbols 87 | let mut symbol_list_row = false; 88 | // symbol ordering for current section 89 | let mut symbol_positions: Vec = Vec::new(); 90 | // go through all the lines 91 | let mut count = 0; 92 | // 93 | for result in rdr.unwrap().records() { 94 | // load the row 95 | let record = result.unwrap(); 96 | // check if it's a new constituency 97 | if is_constituency_row(&record) { 98 | // set the constituency name 99 | constituency = get_constituency_name(&record, &const_translate).unwrap(); 100 | if count > 0 { println!("{}", count) } 101 | count = 0; 102 | print!(r#""{}","#, constituency); 103 | // no need to process this row anymore 104 | continue; 105 | } 106 | // if center information provided, we'll get the symbols from next line 107 | if is_center_information_row(&record) { 108 | symbol_list_row = true; 109 | // no need to process this row anymore 110 | continue; 111 | } 112 | // if this row contains symbol list, get them and keep track of it 113 | if symbol_list_row { 114 | // find new symbols and add them to list 115 | check_for_new_symbols(&record, &mut symbol_list); 116 | // now go through all the symbols and mark their positions, which will be used when processing data 117 | symbol_positions = record.iter() 118 | .filter(|m| !m.is_empty()) 119 | .map(|m| m.trim().to_string()) 120 | .collect(); 121 | symbol_list_row = false; 122 | // no need to process this row anymore 123 | continue; 124 | } 125 | // we want to skip empty rows 126 | if record.iter().all(|m| m.is_empty()) { 127 | // no need to process this row anymore 128 | continue; 129 | } 130 | count+= 1; 131 | // store the votes 132 | let mut results = BTreeMap::new(); 133 | get_result(&record, &symbol_positions, &mut results); 134 | get_other_columns(&record, &other_columns, symbol_positions.len() + 2, &mut results); 135 | results.insert("total_voters".to_string(), record.get(1).unwrap().to_string()); 136 | // center 137 | let center = record.get(0).unwrap().trim(); 138 | // add to output map 139 | aggregated_data.insert(CenterDetails::new(constituency.as_str(), center), results); 140 | } 141 | // we will add all the symbols and then generate CSV file, 142 | // which is why we are storing all symbols in the list 143 | symbol_list.sort(); 144 | println!("Symbols found: {}", symbol_list.len()); 145 | // now generate rows for CSV, 146 | let mut result_rows = Vec::new(); 147 | aggregated_data.iter().for_each(|(k, v)| { 148 | let mut row = vec![ 149 | k.constituency.clone(), 150 | k.center.clone(), 151 | ]; 152 | // set values in the symbols 153 | symbol_list.iter().for_each(|symbol| { 154 | let votes: String = match v.get(symbol) { 155 | None => "0".to_string(), 156 | Some(i) => format!("{}", i), 157 | }; 158 | row.push(votes); 159 | }); 160 | other_columns.iter().for_each(|symbol| { 161 | let votes: String = match v.get(symbol) { 162 | None => "0".to_string(), 163 | Some(i) => format!("{}", i), 164 | }; 165 | row.push(votes); 166 | }); 167 | row.push(v["total_voters"].clone()); 168 | result_rows.push(row); 169 | }); 170 | println!("Rows found: {}", result_rows.len()); 171 | // write the file to output.csv 172 | let mut writer = Writer::from_path(output_file).unwrap(); 173 | let mut headers = vec!["Constituency".to_string(), "Center".to_string()]; 174 | headers.extend(symbol_list); 175 | headers.extend(other_columns); 176 | headers.push("total_voters".to_string()); 177 | writer.write_record(&headers); 178 | for result_row in result_rows { 179 | writer.write_record(&result_row); 180 | } 181 | Ok(()) 182 | } 183 | 184 | fn get_other_columns(record: &StringRecord, other_columns: &Vec, offset: usize, results: &mut BTreeMap) { 185 | for i in 0..other_columns.len() { 186 | results.insert( 187 | other_columns[i].to_string(), 188 | // first 2 columns of the record are, center and total votes. Skip them 189 | record.get(i + offset).unwrap_or("0").to_string(), 190 | ); 191 | } 192 | } 193 | 194 | fn get_result(record: &StringRecord, symbol_positions: &Vec, results: &mut BTreeMap) { 195 | for i in 0..symbol_positions.len() { 196 | results.insert( 197 | symbol_positions[i].to_string(), 198 | // first 2 columns of the record are, center and total votes. Skip them 199 | record.get(i + 2).unwrap_or("0").to_string() 200 | ); 201 | } 202 | } 203 | 204 | pub fn check_for_new_symbols(record: &StringRecord, symbols: &mut Vec) { 205 | for sym in record { 206 | let s = sym.trim().to_string(); 207 | if s.is_empty() { continue; } 208 | if symbols.contains(&s) { continue; } 209 | symbols.push(s); 210 | } 211 | } 212 | 213 | pub fn is_constituency_row(row: &StringRecord) -> bool { 214 | let re = Regex::new(CONSTITUENCY_REG).unwrap(); 215 | row.iter().any(|s| re.is_match(s)) 216 | } 217 | 218 | pub fn is_center_information_row(row: &StringRecord) -> bool { 219 | row[0].starts_with("কেন্দ্র") 220 | } 221 | 222 | 223 | #[cfg(test)] 224 | mod tests; 225 | -------------------------------------------------------------------------------- /res/cons_name_translate.csv: -------------------------------------------------------------------------------- 1 | ০০১ পঞ্চগড়-১ 2 | 1 Panchagarh-1 3 | ০০২ পঞ্চগড়-২ 4 | 2 Panchagarh-2 5 | ০০৩ ঠাকুরগাঁও-১ 6 | 3 Thakurgaon-1 7 | ০০৪ ঠাকুরগাঁও-২ 8 | 4 Thakurgaon-2 9 | ০০৫ ঠাকুরগাঁও-৩ 10 | 5 Thakurgaon-3 11 | ০০৬ দিনাজপুর-১ 12 | 6 Dinajpur-1 13 | ০০৭ দিনাজপুর-২ 14 | 7 Dinajpur-2 15 | ০০৮ দিনাজপুর-৩ 16 | 8 Dinajpur-3 17 | ০০৯ দিনাজপুর-৪ 18 | 9 Dinajpur-4 19 | ০১০ দিনাজপুর-৫ 20 | 10 Dinajpur-5 21 | ০১১ দিনাজপুর-৬ 22 | 11 Dinajpur-6 23 | ০১২ নীলফামারী-১ 24 | 12 Nilphamari-1 25 | ০১৩ নীলফামারী-২ 26 | 13 Nilphamari-2 27 | ০১৪ নীলফামারী-৩ 28 | 14 Nilphamari-3 29 | ০১৫ নীলফামারী-৪ 30 | 15 Nilphamari-4 31 | ০১৬ লালমনিরহাট-১ 32 | 16 Lalmonirhat-1 33 | ০১৭ লালমনিরহাট-২ 34 | 17 Lalmonirhat-2 35 | ০১৮ লালমনিরহাট-৩ 36 | 18 Lalmonirhat-3 37 | ০১৯ রংপুর-১ 38 | 19 Rangpur-1 39 | ০২০ রংপুর-২ 40 | 20 Rangpur-2 41 | ০২১ রংপুর-৩ 42 | 21 Rangpur-3 43 | ০২২ রংপুর-৪ 44 | 22 Rangpur-4 45 | ০২৩ রংপুর-৫ 46 | 23 Rangpur-5 47 | ০২৪ রংপুর-৬ 48 | 24 Rangpur-6 49 | ০২৫ কুড়িগ্রাম-১ 50 | 25 Kurigarm-1 51 | ০২৬ কুড়িগ্রাম-২ 52 | 26 Kurigarm-2 53 | ০২৭ কুড়িগ্রাম-৩ 54 | 27 Kurigarm-3 55 | ০২৮ কুড়িগ্রাম-৪ 56 | 28 Kurigarm-4 57 | ০২৯ গাইবান্ধা-১ 58 | 29 Gaibandha-1 59 | ০৩০ গাইবান্ধা-২ 60 | 30 Gaibandha-2 61 | ০৩১ গাইবান্ধা-৩ 62 | 31 Gaibandha-3 63 | ০৩২ গাইবান্ধা-৪ 64 | 32 Gaibandha-4 65 | ০৩৩ গাইবান্ধা-৫ 66 | 33 Gaibandha-5 67 | ০৩৪ জয়পুরহাট-১ 68 | 34 Joypurhat-1 69 | ০৩৫ জয়পুরহাট-২ 70 | 35 Joypurhat-2 71 | ০৩৬ বগুড়া-১ 72 | 36 Bogura-1 73 | ০৩৭ বগুড়া-২ 74 | 37 Bogura-2 75 | ০৩৮ বগুড়া-৩ 76 | 38 Bogura-3 77 | ০৩৯ বগুড়া-৪ 78 | 39 Bogura-4 79 | ০৪০ বগুড়া-৫ 80 | 40 Bogura-5 81 | ০৪১ বগুড়া-৬ 82 | 41 Bogura-6 83 | ০৪২ বগুড়া-৭ 84 | 42 Bogura-7 85 | ০৪৩ চাঁপাইনবাবগঞ্জ-১ 86 | 43 Chapai Nawabganj-1 87 | ০৪৪ চাঁপাইনবাবগঞ্জ-২ 88 | 44 Chapai Nawabganj-2 89 | ০৪৫ চাঁপাইনবাবগঞ্জ-৩ 90 | 45 Chapai Nawabganj-3 91 | ০৪৬ নত্তঁগা-১ 92 | 46 Naogaon-1 93 | ০৪৭ নত্তঁগা-২ 94 | 47 Naogaon-2 95 | ০৪৮ নত্তঁগা-৩ 96 | 48 Naogaon-3 97 | ০৪৯ নত্তঁগা-৪ 98 | 49 Naogaon-4 99 | ০৫০ নত্তঁগা-৫ 100 | 50 Naogaon-5 101 | ০৫১ নত্তঁগা-৬ 102 | 51 Naogaon-6 103 | ০৫২ রাজশাহী-১ 104 | 52 Rajshahi-1 105 | ০৫৩ রাজশাহী-২ 106 | 53 Rajshahi-2 107 | ০৫৪ রাজশাহী-৩ 108 | 54 Rajshahi-3 109 | ০৫৫ রাজশাহী-৪ 110 | 55 Rajshahi-4 111 | ০৫৬ রাজশাহী-৫ 112 | 56 Rajshahi-5 113 | ০৫৭ রাজশাহী-৬ 114 | 57 Rajshahi-6 115 | ০৫৮ নাটোর-১ 116 | 58 Natore-1 117 | ০৫৯ নাটোর-২ 118 | 59 Natore-2 119 | ০৬০ নাটোর-৩ 120 | 60 Natore-3 121 | ০৬১ নাটোর-৪ 122 | 61 Natore-4 123 | ০৬২ সিরাজগঞ্জ-১ 124 | 62 Sirajgonj-1 125 | ০৬৩ সিরাজগঞ্জ-২ 126 | 63 Sirajgonj-2 127 | ০৬৪ সিরাজগঞ্জ-৩ 128 | 64 Sirajgonj-3 129 | ০৬৫ সিরাজগঞ্জ-৪ 130 | 65 Sirajgonj-4 131 | ০৬৬ সিরাজগঞ্জ-৫ 132 | 66 Sirajgonj-5 133 | ০৬৭ সিরাজগঞ্জ-৬ 134 | 67 Sirajgonj-6 135 | ০৬৮ পাবনা-১ 136 | 68 Pabna-1 137 | ০৬৯ পাবনা-২ 138 | 69 Pabna-2 139 | ০৭০ পাবনা-৩ 140 | 70 Pabna-3 141 | ০৭১ পাবনা-৪ 142 | 71 Pabna-4 143 | ০৭২ পাবনা-৫ 144 | 72 Pabna-5 145 | ০৭৩ মেহেরপুর-১ 146 | 73 Meherpur-1 147 | ০৭৪ মেহেরপুর-২ 148 | 74 Meherpur-2 149 | ০৭৫ কুষ্টিয়া-১ 150 | 75 Kushtia-1 151 | ০৭৬ কুষ্টিয়া-২ 152 | 76 Kushtia-2 153 | ০৭৭ কুষ্টিয়া-৩ 154 | 77 Kushtia-3 155 | ০৭৮ কুষ্টিয়া-৪ 156 | 78 Kushtia-4 157 | ০৭৯ চুয়াডাঙ্গা-১ 158 | 79 Chuadanga-1 159 | ০৮০ চুয়াডাঙ্গা-২ 160 | 80 Chuadanga-2 161 | ০৮১ ঝিনাইদহ-১ 162 | 81 Jhenidha-1 163 | ০৮২ ঝিনাইদহ-২ 164 | 82 Jhenidha-2 165 | ০৮৩ ঝিনাইদহ-৩ 166 | 83 Jhenidha-3 167 | ০৮৪ ঝিনাইদহ-৪ 168 | 84 Jhenidha-4 169 | ০৮৫ যশোর-১ 170 | 85 Jashore-1 171 | ০৮৬ যশোর-২ 172 | 86 Jashore-2 173 | ০৮৭ যশোর-৩ 174 | 87 Jashore-3 175 | ০৮৮ যশোর-৪ 176 | 88 Jashore-4 177 | ০৮৯ যশোর-৫ 178 | 89 Jashore-5 179 | ০৯০ যশোর-৬ 180 | 90 Jashore-6 181 | ০৯১ মাগুড়া-১ 182 | 91 Magura-1 183 | ০৯২ মাগুড়া-২ 184 | 92 Magura-2 185 | ০৯৩ নড়াইল-১ 186 | 93 Narail-1 187 | ০৯৪ নড়াইল-২ 188 | 94 Narail-2 189 | ০৯৫ বাগেরহাট-১ 190 | 95 Bagerhat-1 191 | ০৯৬ বাগেরহাট-২ 192 | 96 Bagerhat-2 193 | ০৯৭ বাগেরহাট-৩ 194 | 97 Bagerhat-3 195 | ০৯৮ বাগেরহাট-৪ 196 | 98 Bagerhat-4 197 | ০৯৯ খুলনা-১ 198 | 99 Khulna-1 199 | ১০০ খুলনা-২ 200 | 100 Khulna-2 201 | ১০১ খুলনা-৩ 202 | 101 Khulna-3 203 | ১০২ খুলনা-৪ 204 | 102 Khulna-4 205 | ১০৩ খুলনা-৫ 206 | 103 Khulna-5 207 | ১০৪ খুলনা-৬ 208 | 104 Khulna-6 209 | ১০৫ সাতক্ষীরা-১ 210 | 105 Satkhira-1 211 | ১০৬ সাতক্ষীরা-২ 212 | 106 Satkhira-2 213 | ১০৭ সাতক্ষীরা-৩ 214 | 107 Satkhira-3 215 | ১০৮ সাতক্ষীরা-৪ 216 | 108 Satkhira-4 217 | ১০৯ বরগুনা-১ 218 | 109 Barguna-1 219 | ১১০ বরগুনা-২ 220 | 110 Barguna-2 221 | ১১১ পটুয়াখালী-১ 222 | 111 Patuakhali-1 223 | ১১২ পটুয়াখালী-২ 224 | 112 Patuakhali-2 225 | ১১৩ পটুয়াখালী-৩ 226 | 113 Patuakhali-3 227 | ১১৪ পটুয়াখালী-৪ 228 | 114 Patuakhali-4 229 | ১১৫ ভোলা-১ 230 | 115 Bhola-1 231 | ১১৬ ভোলা-২ 232 | 116 Bhola-2 233 | ১১৭ ভোলা-৩ 234 | 117 Bhola-3 235 | ১১৮ ভোলা-৪ 236 | 118 Bhola-4 237 | ১১৯ বরিশাল-১ 238 | 119 Barishal-1 239 | ১২০ বরিশাল-২ 240 | 120 Barishal-2 241 | ১২১ বরিশাল-৩ 242 | 121 Barishal-3 243 | ১২২ বরিশাল-৪ 244 | 122 Barishal-4 245 | ১২৩ বরিশাল-৫ 246 | 123 Barishal-5 247 | ১২৪ বরিশাল-৬ 248 | 124 Barishal-6 249 | ১২৫ ঝালোকাঠি-১ 250 | 125 Jhalokati-1 251 | ১২৬ ঝালোকাঠি-২ 252 | 126 Jhalokati-2 253 | ১২৭ পিরোজপুর-১ 254 | 127 Pirojpur-1 255 | ১২৮ পিরোজপুর-২ 256 | 128 Pirojpur-2 257 | ১২৯ পিরোজপুর-৩ 258 | 129 Pirojpur-3 259 | ১৩০ টাংগাইল-১ 260 | 130 Tangail-1 261 | ১৩১ টাংগাইল-২ 262 | 131 Tangail-2 263 | ১৩২ টাংগাইল-৩ 264 | 132 Tangail-3 265 | ১৩৩ টাংগাইল-৪ 266 | 133 Tangail-4 267 | ১৩৪ টাংগাইল-৫ 268 | 134 Tangail-5 269 | ১৩৫ টাংগাইল-৬ 270 | 135 Tangail-6 271 | ১৩৬ টাংগাইল-৭ 272 | 136 Tangail-7 273 | ১৩৭ টাংগাইল-৮ 274 | 137 Tangail-8 275 | ১৩৮ জামালপুর-১ 276 | 138 Jamalpur-1 277 | ১৩৯ জামালপুর-২ 278 | 139 Jamalpur-2 279 | ১৪০ জামালপুর-৩ 280 | 140 Jamalpur-3 281 | ১৪১ জামালপুর-৪ 282 | 141 Jamalpur-4 283 | ১৪২ জামালপুর-৫ 284 | 142 Jamalpur-5 285 | ১৪৩ শেরপুর-১ 286 | 143 Sherpur-1 287 | ১৪৪ শেরপুর-২ 288 | 144 Sherpur-2 289 | ১৪৫ শেরপুর-৩ 290 | 145 Sherpur-3 291 | ১৪৬ ময়মনসিংহ-১ 292 | 146 Mymensingh-1 293 | ১৪৭ ময়মনসিংহ-২ 294 | 147 Mymensingh-2 295 | ১৪৮ ময়মনসিংহ-৩ 296 | 148 Mymensingh-3 297 | ১৪৯ ময়মনসিংহ-৪ 298 | 149 Mymensingh-4 299 | ১৫০ ময়মনসিংহ-৫ 300 | 150 Mymensingh-5 301 | ১৫১ ময়মনসিংহ-৬ 302 | 151 Mymensingh-6 303 | ১৫২ ময়মনসিংহ-৭ 304 | 152 Mymensingh-7 305 | ১৫৩ ময়মনসিংহ-৮ 306 | 153 Mymensingh-8 307 | ১৫৪ ময়মনসিংহ-৯ 308 | 154 Mymensingh-9 309 | ১৫৫ ময়মনসিংহ-১০ 310 | 155 Mymensingh-10 311 | ১৫৬ ময়মনসিংহ-১১ 312 | 156 Mymensingh-11 313 | ১৫৭ নেত্রকোণা-১ 314 | 157 Netrokona-1 315 | ১৫৮ নেত্রকোণা-২ 316 | 158 Netrokona-2 317 | ১৫৯ নেত্রকোণা-৩ 318 | 159 Netrokona-3 319 | ১৬০ নেত্রকোণা-৪ 320 | 160 Netrokona-4 321 | ১৬১ নেত্রকোণা-৫ 322 | 161 Netrokona-5 323 | ১৬২ কিশোরগঞ্জ-১ 324 | 162 Kishoreganj-1 325 | ১৬৩ কিশোরগঞ্জ-২ 326 | 163 Kishoreganj-2 327 | ১৬৪ কিশোরগঞ্জ-৩ 328 | 164 Kishoreganj-3 329 | ১৬৫ কিশোরগঞ্জ-৪ 330 | 165 Kishoreganj-4 331 | ১৬৬ কিশোরগঞ্জ-৫ 332 | 166 Kishoreganj-5 333 | ১৬৭ কিশোরগঞ্জ-৬ 334 | 167 Kishoreganj-6 335 | ১৬৮ মানিকগঞ্জ-১ 336 | 168 Manikganj-1 337 | ১৬৯ মানিকগঞ্জ-২ 338 | 169 Manikganj-2 339 | ১৭০ মানিকগঞ্জ-৩ 340 | 170 Manikganj-3 341 | ১৭১ মুন্সিগঞ্জ-১ 342 | 171 Munshiganj-1 343 | ১৭২ মুন্সিগঞ্জ-২ 344 | 172 Munshiganj-2 345 | ১৭৩ মুন্সিগঞ্জ-৩ 346 | 173 Munshiganj-3 347 | ১৭৪ ঢাকা-১ 348 | 174 Dhaka-1 349 | ১৭৫ ঢাকা-২ 350 | 175 Dhaka-2 351 | ১৭৬ ঢাকা-৩ 352 | 176 Dhaka-3 353 | ১৭৭ ঢাকা-৪ 354 | 177 Dhaka-4 355 | ১৭৮ ঢাকা-৫ 356 | 178 Dhaka-5 357 | ১৭৯ ঢাকা-৬ 358 | 179 Dhaka-6 359 | ১৮০ ঢাকা-৭ 360 | 180 Dhaka-7 361 | ১৮১ ঢাকা-৮ 362 | 181 Dhaka-8 363 | ১৮২ ঢাকা-৯ 364 | 182 Dhaka-9 365 | ১৮৩ ঢাকা-১০ 366 | 183 Dhaka-10 367 | ১৮৪ ঢাকা-১১ 368 | 184 Dhaka-11 369 | ১৮৫ ঢাকা-১২ 370 | 185 Dhaka-12 371 | ১৮৬ ঢাকা-১৩ 372 | 186 Dhaka-13 373 | ১৮৭ ঢাকা-১৪ 374 | 187 Dhaka-14 375 | ১৮৮ ঢাকা-১৫ 376 | 188 Dhaka-15 377 | ১৮৯ ঢাকা-১৬ 378 | 189 Dhaka-16 379 | ১৯০ ঢাকা-১৭ 380 | 190 Dhaka-17 381 | ১৯১ ঢাকা-১৮ 382 | 191 Dhaka-18 383 | ১৯২ ঢাকা-১৯ 384 | 192 Dhaka-19 385 | ১৯৩ ঢাকা-২০ 386 | 193 Dhaka-20 387 | ১৯৪ গাজীপুর-১ 388 | 194 Gazipur-1 389 | ১৯৫ গাজীপুর-২ 390 | 195 Gazipur-2 391 | ১৯৬ গাজীপুর-৩ 392 | 196 Gazipur-3 393 | ১৯৭ গাজীপুর-৪ 394 | 197 Gazipur-4 395 | ১৯৮ গাজীপুর-৫ 396 | 198 Gazipur-5 397 | ১৯৯ নরসিংদী-১ 398 | 199 Narshingdhi-1 399 | ২০০ নরসিংদী-২ 400 | 200 Narshingdhi-2 401 | ২০১ নরসিংদী-৩ 402 | 201 Narshingdhi-3 403 | ২০২ নরসিংদী-৪ 404 | 202 Narshingdhi-4 405 | ২০৩ নরসিংদী-৫ 406 | 203 Narshingdhi-5 407 | ২০৪ নারায়ণগঞ্জ-১ 408 | 204 Narayanganj-1 409 | ২০৫ নারায়ণগঞ্জ-২ 410 | 205 Narayanganj-2 411 | ২০৬ নারায়ণগঞ্জ-৩ 412 | 206 Narayanganj-3 413 | ২০৭ নারায়ণগঞ্জ-৪ 414 | 207 Narayanganj-4 415 | ২০৮ নারায়ণগঞ্জ-৫ 416 | 208 Narayanganj-5 417 | ২০৯ রাজবাড়ী-১ 418 | 209 Rajbari-1 419 | ২১০ রাজবাড়ী-২ 420 | 210 Rajbari-2 421 | ২১১ ফরিদপুর-১ 422 | 211 Faridpur-1 423 | ২১২ ফরিদপুর-২ 424 | 212 Faridpur-2 425 | ২১৩ ফরিদপুর-৩ 426 | 213 Faridpur-3 427 | ২১৪ ফরিদপুর-৪ 428 | 214 Faridpur-4 429 | ২১৫ গোপালগঞ্জ-১ 430 | 215 Gopalganj-1 431 | ২১৬ গোপালগঞ্জ-২ 432 | 216 Gopalganj-2 433 | ২১৭ গোপালগঞ্জ-৩ 434 | 217 Gopalganj-3 435 | ২১৮ মাদারিপুর-১ 436 | 218 Madaripur-1 437 | ২১৯ মাদারিপুর-২ 438 | 219 Madaripur-2 439 | ২২০ মাদারীপুর-৩ 440 | 220 Madaripur-3 441 | ২২১ শরীয়তপুর-১ 442 | 221 Shariatpur-1 443 | ২২২ শরীয়তপুর-২ 444 | 222 Shariatpur-2 445 | ২২৩ শরীয়তপুর-৩ 446 | 223 Shariatpur-3 447 | ২২৪ সুনামগঞ্জ-১ 448 | 224 Sunamganj-1 449 | ২২৫ সুনামগঞ্জ-২ 450 | 225 Sunamganj-2 451 | ২২৬ সুনামগঞ্জ-৩ 452 | 226 Sunamganj-3 453 | ২২৭ সুনামগঞ্জ-৪ 454 | 227 Sunamganj-4 455 | ২২৮ সুনামগঞ্জ-৫ 456 | 228 Sunamganj-5 457 | ২২৯ সিলেট-১ 458 | 229 Sylhet-1 459 | ২৩০ সিলেট-২ 460 | 230 Sylhet-2 461 | ২৩১ সিলেট-৩ 462 | 231 Sylhet-3 463 | ২৩২ সিলেট-৪ 464 | 232 Sylhet-4 465 | ২৩৩ সিলেট-৫ 466 | 233 Sylhet-5 467 | ২৩৪ সিলেট-৬ 468 | 234 Sylhet-6 469 | ২৩৫ মৌলভীবাজার-১ 470 | 235 Maulvibazar-1 471 | ২৩৬ মৌলভীবাজার-২ 472 | 236 Maulvibazar-2 473 | ২৩৭ মৌলভীবাজার-৩ 474 | 237 Maulvibazar-3 475 | ২৩৮ মৌলভীবাজার-৪ 476 | 238 Maulvibazar-4 477 | ২৩৯ হবিগঞ্জ-১ 478 | 239 Habiganj-1 479 | ২৪০ হবিগঞ্জ-২ 480 | 240 Habiganj-2 481 | ২৪১ হবিগঞ্জ-৩ 482 | 241 Habiganj-3 483 | ২৪২ হবিগঞ্জ-৪ 484 | 242 Habiganj-4 485 | ২৪৩ ব্রাক্ষণবাড়িয়া-১ 486 | 243 Brahmanbaria-1 487 | ২৪৪ ব্রাক্ষণবাড়িয়া-২ 488 | 244 Brahmanbaria-2 489 | ২৪৫ ব্রাক্ষণবাড়িয়া-৩ 490 | 245 Brahmanbaria-3 491 | ২৪৬ ব্রাক্ষণবাড়িয়া-৪ 492 | 246 Brahmanbaria-4 493 | ২৪৭ ব্রাক্ষণবাড়িয়া-৫ 494 | 247 Brahmanbaria-5 495 | ২৪৮ ব্রাক্ষণবাড়িয়া-৬ 496 | 248 Brahmanbaria-6 497 | ২৪৯ কুমিল্লা-১ 498 | 249 Cumilla-1 499 | ২৫০ কুমিল্লা-২ 500 | 250 Cumilla-2 501 | ২৫১ কুমিল্লা-৩ 502 | 251 Cumilla-3 503 | ২৫২ কুমিল্লা-৪ 504 | 252 Cumilla-4 505 | ২৫৩ কুমিল্লা-৫ 506 | 253 Cumilla-5 507 | ২৫৪ কুমিল্লা-৬ 508 | 254 Cumilla-6 509 | ২৫৫ কুমিল্লা-৭ 510 | 255 Cumilla-7 511 | ২৫৬ কুমিল্লা-৮ 512 | 256 Cumilla-8 513 | ২৫৭ কুমিল্লা-৯ 514 | 257 Cumilla-9 515 | ২৫৮ কুমিল্লা-১০ 516 | 258 Cumilla-10 517 | ২৫৯ কুমিল্লা-১১ 518 | 259 Cumilla-11 519 | ২৬০ চাঁদপুর-১ 520 | 260 Chandpur-1 521 | ২৬১ চাঁদপুর-২ 522 | 261 Chandpur-2 523 | ২৬২ চাঁদপুর-৩ 524 | 262 Chandpur-3 525 | ২৬৩ চাঁদপুর-৪ 526 | 263 Chandpur-4 527 | ২৬৪ চাঁদপুর-৫ 528 | 264 Chandpur-5 529 | ২৬৫ ফেনী-১ 530 | 265 Feni-1 531 | ২৬৬ ফেনী-২ 532 | 266 Feni-2 533 | ২৬৭ ফেনী-৩ 534 | 267 Feni-3 535 | ২৬৮ নোয়াখালী-১ 536 | 268 Noakahli-1 537 | ২৬৯ নোয়াখালী-২ 538 | 269 Noakhali-2 539 | ২৭০ নোয়াখালী-৩ 540 | 270 Noakhali-3 541 | ২৭১ নোয়াখালী-৪ 542 | 271 Noakhali-4 543 | ২৭২ নোয়াখালী-৫ 544 | 272 Noakhali-5 545 | ২৭৩ নোয়াখালী-৬ 546 | 273 Noakhali-6 547 | ২৭৪ লক্ষীপুর-১ 548 | 274 Lakshmipur-1 549 | ২৭৫ লক্ষীপুর-২ 550 | 275 Lakshmipur-2 551 | ২৭৬ লক্ষীপুর-৩ 552 | 276 Lakshmipur-3 553 | ২৭৭ লক্ষীপুর-৪ 554 | 277 Lakshmipur-4 555 | ২৭৮ চট্রগ্রাম-১ 556 | 278 Chattogram-1 557 | ২৭৯ চট্রগ্রাম-২ 558 | 279 Chattogram-2 559 | ২৮০ চট্রগ্রাম-৩ 560 | 280 Chattogram-3 561 | ২৮১ চট্রগ্রাম-৪ 562 | 281 Chattogram-4 563 | ২৮২ চট্রগ্রাম-৫ 564 | 282 Chattogram-5 565 | ২৮৩ চট্রগ্রাম-৬ 566 | 283 Chattogram-6 567 | ২৮৪ চট্রগ্রাম-৭ 568 | 284 Chattogram-7 569 | ২৮৫ চট্রগ্রাম-৮ 570 | 285 Chattogram-8 571 | ২৮৬ চট্রগ্রাম-৯ 572 | 286 Chattogram-9 573 | ২৮৭ চট্রগ্রাম-১০ 574 | 287 Chattogram-10 575 | ২৮৮ চট্রগ্রাম-১১ 576 | 288 Chattogram-11 577 | ২৮৯ চট্রগ্রাম-১২ 578 | 289 Chattogram-12 579 | ২৯০ চট্রগ্রাম-১৩ 580 | 290 Chattogram-13 581 | ২৯১ চট্রগ্রাম-১৪ 582 | 291 Chattogram-14 583 | ২৯২ চট্রগ্রাম-১৫ 584 | 292 Chattogram-15 585 | ২৯৩ চট্রগ্রাম-১৬ 586 | 293 Chattogram-16 587 | ২৯৪ কক্সবাজার-১ 588 | 294 Cox's Bazar-1 589 | ২৯৫ কক্সবাজার-২ 590 | 295 Cox's Bazar-2 591 | ২৯৬ কক্সবাজার-৩ 592 | 296 Cox's Bazar-3 593 | ২৯৭ কক্সবাজার-৪ 594 | 297 Cox's Bazar-4 595 | ২৯৮ খাগড়াছড়ি-২ 596 | 298 Khagrachhari 597 | ২৯৯ রাঙ্গামাটি-২ 598 | 299 Rangamati 599 | ৩০০ বান্দারবান-২ 600 | 300 Bandarban 601 | --------------------------------------------------------------------------------