Percent Johnson Vote Required for Hillary Clinton Win

A friend of mine wanted to show that under reasonable assumptions Clinton still would’ve lost the election even if it were a head-to-head contest. In other words, third party candidates didn’t cost Clinton the election. All he really wanted to find out is what percentage of Johnson voters had to vote Clinton in order for Clinton to win. This is pretty easy to do; I could probably solve this in less than 5 minutes in Excel. However, he wrote the code in Mathematica, and so I decided to do it in Rust. I used two crates, csv and serde. Csv is needed to read the CSV election data, and serde to put the data into a struct so that it is nicely formatted with names and everything. The code should be pretty self-explanatory, as it is not very complex. Take note of the error handling, which I tried to do properly even though there wasn’t any real need for it here. Here is the code.

extern crate csv;
extern crate serde;

#[macro_use]
extern crate serde_derive;

use std::error::Error;
use std::process;

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct Record {
    state: String,
    trump: f32,
    clinton: f32,
    johnson: f32,
    stein: f32,
    mcmullin: f32,
    electoralvotes: u32,
}

fn get_electoralvotes(record: &Record, x: f32) -> u32 {
    let new_trump = record.trump + record.mcmullin + ((1.0 - x) * record.johnson);
    let new_clinton = record.clinton + record.stein + (x * record.johnson);
    if new_trump > new_clinton {
        return 0;
    } else {
        return record.electoralvotes;
    }
}

fn run() -> Result<(), Box> {
    for i in 0..100 {
        let x: f32 = i as f32 / 100.0;
        let mut clinton_ev = 0;
        let mut rdr = csv::Reader::from_path("./src/grouped_data.csv")?;
        for result in rdr.deserialize() {
            let record: Record = result?;
            let state_ev = get_electoralvotes(&record, x);
            clinton_ev += state_ev;
        }
        if clinton_ev >= 270 {
            println!("{}", x);
            println!("{}", clinton_ev);
            break;
        }
    }
    Ok(())
}

fn main() {
    if let Err(err) = run() {
        println!("{}", err);
        process::exit(1);
    }
}