package main import ( "encoding/csv" "fmt" rand "math/rand/v2" "os" "strconv" // "strings" ) /* Structs */ type State struct { Name string Votes int VictoriousPartyPerElection map[string]string } type VotesForEachParty struct { Democrats int Republicans int } type src = *rand.Rand /* Globals */ var r = rand.New(rand.NewPCG(uint64(1), uint64(2))) /* Load data from csvs */ func readStates() ([]State, error) { var states map[string]State = make(map[string]State) /* Electoral college votes for the 2024 election*/ votes_file, err := os.Open("data/electoral-college-votes.csv") if err != nil { return nil, fmt.Errorf("error opening the votes file: %v", err) } defer votes_file.Close() votes_reader := csv.NewReader(votes_file) if _, err := votes_reader.Read(); err != nil { // Skip header return nil, fmt.Errorf("error reading votes header: %v", err) } for { csv_record, err := votes_reader.Read() if err != nil { break // EOF or an error } votes, err := strconv.Atoi(csv_record[1]) if err != nil { continue // Error in converting votes, skip this record } state := csv_record[0] if _, exists := states[state]; !exists { states[state] = State{Name: state, Votes: votes, VictoriousPartyPerElection: make(map[string]string)} } } /* Election results */ var years = []string{"2000", "2004", "2008", "2012", "2016", "2020"} for _, year := range years { results_filename := fmt.Sprintf("data/results/%s.csv", year) results_file, err := os.Open(results_filename) if err != nil { return nil, fmt.Errorf("error opening the results file for %s: %v", year, err) } defer results_file.Close() resultsReader := csv.NewReader(results_file) if _, err := resultsReader.Read(); err != nil { // Skip header return nil, fmt.Errorf("error reading results header for %s: %v", year, err) } for { record, err := resultsReader.Read() if err != nil { break // EOF or an error } state, party := record[0], record[1] data, exists := states[state] if !exists { continue // State not found in votes map, skip } // Update the party winning in the specific year data.VictoriousPartyPerElection[year] = party states[state] = data } } // Convert statesData map to a slice for returning var states_slice []State for _, state := range states { states_slice = append(states_slice, state) } return states_slice, nil } func sampleFromState(state State) VotesForEachParty { switch state.Name { case "Nebraska": return VotesForEachParty{Democrats: 1, Republicans: 0} case "Maine": return VotesForEachParty{Democrats: 1, Republicans: 0} default: { p_republican := 0.0 for _, party := range state.VictoriousPartyPerElection { if party == "R" { p_republican++ } } p_republican = p_republican / float64(len(state.VictoriousPartyPerElection)) if r.Float64() < p_republican { return VotesForEachParty{Democrats: 0, Republicans: state.Votes} } else { return VotesForEachParty{Democrats: state.Votes, Republicans: 0} } } } } func main() { states, err := readStates() if err != nil { fmt.Println("Error:", err) return } for _, state := range states { fmt.Printf("%s: Votes: %d,\n\tWinners: ", state.Name, state.Votes) for year, party := range state.VictoriousPartyPerElection { fmt.Printf("[%s: %s] ", year, party) } election_sample := sampleFromState(state) fmt.Printf("\n\tSample: Democrat seats: %d, Republican seats: %d", election_sample.Democrats, election_sample.Republicans) fmt.Println() } }