pub(crate) fn read_ticket_votes2013(metadata:&ElectionMetadata,path:&Path, state:&str) -> anyhow::Result<Vec<BTL>> {
    let splits = get_deduced_aec_ticket_splits2013(state)?;
    let mut rdr = csv::Reader::from_reader(skip_first_line_of_file(path)?);
    let mut res = vec![];
    for result in rdr.records() {
        let record = result?;
        if state == &record[0] { // right state
            let group_id = &record[1];
            let ticket_votes = record[4].parse::<usize>()?;
            if ticket_votes>0 {
                let tickets = &metadata.parties.iter().find(|p|&p.column_id==group_id).unwrap().tickets;
                let num_tickets = tickets.len();
                if num_tickets==0 { return Err(anyhow!("Group {} has {} votes but not tickets",group_id,ticket_votes));}
                let portion = ticket_votes/num_tickets;
                let excess = ticket_votes%num_tickets;
                let choice = if excess>0 { match splits.get(&group_id).cloned() { Some(u)=>u, None => return Err(anyhow!("Group {} has an unspecified rounding choice between 0 and {}",group_id,num_tickets-1))} } else {0};
                for i in 0..num_tickets {
                    let extra = if excess==0 {0} else {match num_tickets { // whether there should be a rounding vote added to this ticket.
                        2 => if i==choice {1} else {0},
                        3 => if (i==choice)==(excess==1) {1} else {0},
                        _ => 0,
                    }};
                    res.push(BTL{ candidates: tickets[i].clone(), n: portion+extra });
                }
            }
        }
    }
    Ok(res)
}
/// Read the file SenateUseOfGvtByGroupDownload for 2013 to get the number of voters voting for each ticket.
/// Nasty hack - return as BTLs, as ATL has different meaning to tickets, and don't want to complicate ElectionData with ticket votes.
Read the file SenateUseOfGvtByGroupDownload for 2013 to get the number of voters voting for each ticket.
Nasty hack - return as BTLs, as ATL has different meaning to tickets, and don't want to complicate ElectionData with ticket votes.
Read the file SenateUseOfGvtByGroupDownload for 2013 to get the number of voters voting for each ticket . Nasty hack - return as BTLs as ATL has different meaning to tickets and don ' t want to complicate ElectionData with ticket votes .
pub(crate) fn read_ticket_votes2013(metadata:&ElectionMetadata,path:&Path, state:&str) -> anyhow::Result<Vec<BTL>> {
    let splits = get_deduced_aec_ticket_splits2013(state)?;
    let mut rdr = csv::Reader::from_reader(skip_first_line_of_file(path)?);
    let mut res = vec![];
    for result in rdr.records() {
        let record = result?;
        if state == &record[0] { // right state
            let group_id = &record[1];
            let ticket_votes = record[4].parse::<usize>()?;
            if ticket_votes>0 {
                let tickets = &metadata.parties.iter().find(|p|&p.column_id==group_id).unwrap().tickets;
                let num_tickets = tickets.len();
                if num_tickets==0 { return Err(anyhow!("Group {} has {} votes but not tickets",group_id,ticket_votes));}
                let portion = ticket_votes/num_tickets;
                let excess = ticket_votes%num_tickets;
                let choice = if excess>0 { match splits.get(&group_id).cloned() { Some(u)=>u, None => return Err(anyhow!("Group {} has an unspecified rounding choice between 0 and {}",group_id,num_tickets-1))} } else {0};
                for i in 0..num_tickets {
                    let extra = if excess==0 {0} else {match num_tickets { // whether there should be a rounding vote added to this ticket.
                        2 => if i==choice {1} else {0},
                        3 => if (i==choice)==(excess==1) {1} else {0},
                        _ => 0,
                    }};
                    res.push(BTL{ candidates: tickets[i].clone(), n: portion+extra });
                }
            }
        }
    }
    Ok(res)
}
pub ( crate ) fn read_ticket_votes2013 ( metadata : & ElectionMetadata , path : & Path , state : & str ) -> anyhow :: Result < Vec < BTL > > { let splits = get_deduced_aec_ticket_splits2013 ( state ) ? ; let mut rdr = csv :: Reader :: from_reader ( skip_first_line_of_file ( path ) ? ) ; let mut res = vec ! [ ] ; for result in rdr . records ( ) { let record = result ? ; if state == & record [ 0 ] { // right state let group_id = & record [ 1 ] ; let ticket_votes = record [ 4 ] . parse :: < usize > ( ) ? ; if ticket_votes > 0 { let tickets = & metadata . parties . iter ( ) . find ( | p | & p . column_id == group_id ) . unwrap ( ) . tickets ; let num_tickets = tickets . len ( ) ; if num_tickets == 0 { return Err ( anyhow ! ( " " group_id ticket_votes ) ) ; } let portion = ticket_votes / num_tickets ; let excess = ticket_votes % num_tickets ; let choice = if excess > 0 { match splits . get ( & group_id ) . cloned ( ) { Some ( u ) => u , None => return Err ( anyhow ! ( " " group_id num_tickets 1 ) ) } } else { 0 } ; for i in 0 .. num_tickets { let extra = if excess == 0 { 0 } else { match num_tickets { // whether there should be a rounding vote added to this ticket. 2 => if i == choice { 1 } else { 0 } , 3 => if ( i == choice ) == ( excess == 1 ) { 1 } else { 0 } , _ => 0 , } } ; res . push ( BTL { candidates : tickets [ i ] . clone ( ) , n : portion + extra } ) ; } } } } Ok ( res ) }
Read the file SenateUseOfGvtByGroupDownload for 2013 to get the number of voters voting for each ticket.
Read the file SenateUseOfGvtByGroupDownload for 2013 to get the number of voters voting for each ticket .
metadata
&ElectionMetadata
path
&Path
state
&str
metadata
&ElectionMetadata
path
&Path
state
&str