Compare commits

...

4 Commits

9 changed files with 28491 additions and 13273 deletions

View File

@ -1,5 +1,5 @@
package core package core
const Include_polls_within_n_days = 15 // const Include_polls_within_n_days = 15 // 30
const Std_additional_uncertainty = 0.0 // 4.0 / 100.0 const Std_additional_uncertainty = 0.5 / 100.0 // 4.0 / 100.0
const Weight_polls_vs_baserate = 0.8 // 0.75 const Weight_polls_vs_baserate = 0.75 // 0.75

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

80
main.go
View File

@ -35,7 +35,7 @@ type Poll struct {
/* Globals */ /* Globals */
var r = rand.New(rand.NewPCG(uint64(100), uint64(2224))) var r = rand.New(rand.NewPCG(uint64(100), uint64(2224)))
var dem_nominee_name = "Biden" var dem_nominee_name = "Harris"
var rep_nominee_name = "Trump" var rep_nominee_name = "Trump"
/* Sampling helper functions */ /* Sampling helper functions */
@ -54,24 +54,24 @@ func getChanceCandidateWinsFromPollShare(candidate_p float64, poll_sample_size f
} }
func getChanceRepublicanWinFromPoll(poll Poll, pretty_print bool) float64 { func getChanceRepublicanWinFromPoll(poll Poll, pretty_print bool) float64 {
biden_percentage, biden_exists := poll.PollResults[dem_nominee_name] harris_percentage, harris_exists := poll.PollResults[dem_nominee_name]
trump_percentage, trump_exists := poll.PollResults[rep_nominee_name] trump_percentage, trump_exists := poll.PollResults[rep_nominee_name]
if !biden_exists || !trump_exists { if !harris_exists || !trump_exists {
panic("PollResults of poll filtered to have Biden/Trump doesn't have Biden/Trump") panic("PollResults of poll filtered to have Harris/Trump doesn't have Harris/Trump")
} }
biden_share := biden_percentage / 100.0 // will panic if the item is not found, but we've previously filtered for it harris_share := harris_percentage / 100.0 // will panic if the item is not found, but we've previously filtered for it
trump_share := trump_percentage / 100.0 trump_share := trump_percentage / 100.0
normalized_trump_share := trump_share / (trump_share + biden_share) normalized_trump_share := trump_share / (trump_share + harris_share)
normalized_biden_share := biden_share / (trump_share + biden_share) normalized_harris_share := harris_share / (trump_share + harris_share)
joint_trump_biden_sample_size := (biden_share + trump_share) * float64(poll.SampleSize) joint_trump_harris_sample_size := (harris_share + trump_share) * float64(poll.SampleSize)
std_error_poll_mean := math.Sqrt((normalized_trump_share * normalized_biden_share) / joint_trump_biden_sample_size) std_error_poll_mean := math.Sqrt((normalized_trump_share * normalized_harris_share) / joint_trump_harris_sample_size)
p_republican_win := getProbabilityAboveX(0.5, normalized_trump_share, std_error_poll_mean) p_republican_win := getProbabilityAboveX(0.5, normalized_trump_share, std_error_poll_mean)
if pretty_print { if pretty_print {
fmt.Printf("\n\t\tSample size: %f", joint_trump_biden_sample_size) fmt.Printf("\n\t\tSample size: %f", joint_trump_harris_sample_size)
fmt.Printf("\n\t\tMean R: %f", 100.0*normalized_trump_share) fmt.Printf("\n\t\tMean R: %f", 100.0*normalized_trump_share)
fmt.Printf("\n\t\tStd of mean R: %f", 100*std_error_poll_mean) fmt.Printf("\n\t\tStd of mean R: %f", 100*std_error_poll_mean)
fmt.Printf("\n\t\tPoll says chance of R win: %f", p_republican_win) fmt.Printf("\n\t\tPoll says chance of R win: %f", p_republican_win)
@ -89,19 +89,19 @@ func getChanceRepublicanWinFromPollPlusUncertainty(poll Poll, state State, prett
} }
// Get the uncertainty from the poll // Get the uncertainty from the poll
biden_percentage, biden_exists := poll.PollResults[dem_nominee_name] harris_percentage, harris_exists := poll.PollResults[dem_nominee_name]
trump_percentage, trump_exists := poll.PollResults[rep_nominee_name] trump_percentage, trump_exists := poll.PollResults[rep_nominee_name]
if !biden_exists || !trump_exists { if !harris_exists || !trump_exists {
panic("PollResults of poll filtered to have Biden/Trump doesn't have Biden/Trump") panic("PollResults of poll filtered to have Harris/Trump doesn't have Harris/Trump")
} }
biden_share := biden_percentage / 100.0 // will panic if the item is not found, but we've previously filtered for it harris_share := harris_percentage / 100.0 // will panic if the item is not found, but we've previously filtered for it
trump_share := trump_percentage / 100.0 trump_share := trump_percentage / 100.0
normalized_trump_share := trump_share / (trump_share + biden_share) normalized_trump_share := trump_share / (trump_share + harris_share)
normalized_biden_share := biden_share / (trump_share + biden_share) normalized_harris_share := harris_share / (trump_share + harris_share)
joint_trump_biden_sample_size := (biden_share + trump_share) * float64(poll.SampleSize) joint_trump_harris_sample_size := (harris_share + trump_share) * float64(poll.SampleSize)
std_error_poll_mean := math.Sqrt((normalized_trump_share * normalized_biden_share) / joint_trump_biden_sample_size) std_error_poll_mean := math.Sqrt((normalized_trump_share * normalized_harris_share) / joint_trump_harris_sample_size)
/* Inject additional uncertainty */ /* Inject additional uncertainty */
/* /*
@ -160,21 +160,21 @@ func printStates(states []State) {
} }
// Aggregate poll // Aggregate poll
num_biden_votes := 0.0 num_harris_votes := 0.0
num_trump_votes := 0.0 num_trump_votes := 0.0
for _, poll := range state.Polls { for _, poll := range state.Polls {
biden_percentage, biden_exists := poll.PollResults[dem_nominee_name] harris_percentage, harris_exists := poll.PollResults[dem_nominee_name]
trump_percentage, trump_exists := poll.PollResults[rep_nominee_name] trump_percentage, trump_exists := poll.PollResults[rep_nominee_name]
if !biden_exists || !trump_exists { if !harris_exists || !trump_exists {
panic("PollResults of poll filtered to have Biden/Trump doesn't have Biden/Trump") panic("PollResults of poll filtered to have harris/Trump doesn't have harris/Trump")
} }
num_biden_votes += (biden_percentage / 100.0) * float64(poll.SampleSize) num_harris_votes += (harris_percentage / 100.0) * float64(poll.SampleSize)
num_trump_votes += (trump_percentage / 100.0) * float64(poll.SampleSize) num_trump_votes += (trump_percentage / 100.0) * float64(poll.SampleSize)
} }
aggregate_sample_size := num_biden_votes + num_trump_votes aggregate_sample_size := num_harris_votes + num_trump_votes
if aggregate_sample_size != 0.0 { if aggregate_sample_size != 0.0 {
var aggregate_poll = Poll{SampleSize: int(aggregate_sample_size), PollResults: make(map[string]float64)} var aggregate_poll = Poll{SampleSize: int(aggregate_sample_size), PollResults: make(map[string]float64)}
aggregate_poll.PollResults[dem_nominee_name] = 100.0 * num_biden_votes / aggregate_sample_size aggregate_poll.PollResults[dem_nominee_name] = 100.0 * num_harris_votes / aggregate_sample_size
aggregate_poll.PollResults[rep_nominee_name] = 100.0 * num_trump_votes / aggregate_sample_size aggregate_poll.PollResults[rep_nominee_name] = 100.0 * num_trump_votes / aggregate_sample_size
fmt.Printf("\n\tAggregate poll: %+v", aggregate_poll) fmt.Printf("\n\tAggregate poll: %+v", aggregate_poll)
@ -230,22 +230,22 @@ func sampleFromState(state State) VotesForEachParty {
p_republican_win := p_baserate_republican_win // if no polls p_republican_win := p_baserate_republican_win // if no polls
/* Consider polls */ /* Consider polls */
num_biden_votes := 0.0 num_harris_votes := 0.0
num_trump_votes := 0.0 num_trump_votes := 0.0
for _, poll := range state.Polls { for _, poll := range state.Polls {
biden_percentage, biden_exists := poll.PollResults[dem_nominee_name] harris_percentage, harris_exists := poll.PollResults[dem_nominee_name]
trump_percentage, trump_exists := poll.PollResults[rep_nominee_name] trump_percentage, trump_exists := poll.PollResults[rep_nominee_name]
if !biden_exists || !trump_exists { if !harris_exists || !trump_exists {
panic("PollResults of poll filtered to have Biden/Trump doesn't have Biden/Trump") panic("PollResults of poll filtered to have harris/Trump doesn't have harris/Trump")
} }
num_biden_votes += (biden_percentage / 100.0) * float64(poll.SampleSize) num_harris_votes += (harris_percentage / 100.0) * float64(poll.SampleSize)
num_trump_votes += (trump_percentage / 100.0) * float64(poll.SampleSize) num_trump_votes += (trump_percentage / 100.0) * float64(poll.SampleSize)
} }
aggregate_sample_size := num_biden_votes + num_trump_votes aggregate_sample_size := num_harris_votes + num_trump_votes
if aggregate_sample_size != 0.0 { if aggregate_sample_size != 0.0 {
var aggregate_poll = Poll{SampleSize: int(aggregate_sample_size), PollResults: make(map[string]float64)} var aggregate_poll = Poll{SampleSize: int(aggregate_sample_size), PollResults: make(map[string]float64)}
aggregate_poll.PollResults[dem_nominee_name] = 100.0 * num_biden_votes / aggregate_sample_size aggregate_poll.PollResults[dem_nominee_name] = 100.0 * num_harris_votes / aggregate_sample_size
aggregate_poll.PollResults[rep_nominee_name] = 100.0 * num_trump_votes / aggregate_sample_size aggregate_poll.PollResults[rep_nominee_name] = 100.0 * num_trump_votes / aggregate_sample_size
p_republican_win_aggregate_polls := getChanceRepublicanWinFromPollPlusUncertainty(aggregate_poll, state, false) p_republican_win_aggregate_polls := getChanceRepublicanWinFromPollPlusUncertainty(aggregate_poll, state, false)
@ -400,7 +400,7 @@ func readStates() ([]State, error) {
state_name := record[12] state_name := record[12]
end_date := record[14] end_date := record[14]
partisan := record[32] partisan := record[32]
candidate_name := record[44] candidate_name := record[44] // cat president_polls_state.csv | cut -d, -f 45
date_layout := "1/2/06" date_layout := "1/2/06"
parsed_date, err := time.Parse(date_layout, end_date) parsed_date, err := time.Parse(date_layout, end_date)
@ -440,31 +440,31 @@ func readStates() ([]State, error) {
// Add the aggregated poll data to the respective states // Add the aggregated poll data to the respective states
for state_name, polls := range state_polls_map { for state_name, polls := range state_polls_map {
// Filter polls by recency and by having both Biden and Trump // Filter polls by recency and by having both harris and Trump
var recent_polls []Poll var recent_polls []Poll
for _, poll := range polls { for _, poll := range polls {
if poll.Date.After(time.Now().AddDate(0, 0, -core.Include_polls_within_n_days)) { if poll.Date.After(time.Now().AddDate(0, 0, -core.Include_polls_within_n_days)) {
recent_polls = append(recent_polls, poll) recent_polls = append(recent_polls, poll)
} }
} }
var recent_biden_trump_polls []Poll var recent_harris_trump_polls []Poll
for _, recent_poll := range recent_polls { for _, recent_poll := range recent_polls {
has_biden := false has_harris := false
has_trump := false has_trump := false
for candidate_name, _ := range recent_poll.PollResults { for candidate_name, _ := range recent_poll.PollResults {
if candidate_name == dem_nominee_name { if candidate_name == dem_nominee_name {
has_biden = true has_harris = true
} else if candidate_name == rep_nominee_name { } else if candidate_name == rep_nominee_name {
has_trump = true has_trump = true
} }
} }
if has_biden && has_trump { if has_harris && has_trump {
recent_biden_trump_polls = append(recent_biden_trump_polls, recent_poll) recent_harris_trump_polls = append(recent_harris_trump_polls, recent_poll)
} }
} }
if state, exists := states[state_name]; exists { if state, exists := states[state_name]; exists {
state.Polls = recent_biden_trump_polls state.Polls = recent_harris_trump_polls
states[state_name] = state // Not redundant states[state_name] = state // Not redundant
} else { } else {
// fmt.Printf("Encountered new state: %s\n", state_name) // fmt.Printf("Encountered new state: %s\n", state_name)

1179
out/output-2024-08-01.txt Normal file

File diff suppressed because it is too large Load Diff

1214
out/output-2024-08-06.txt Normal file

File diff suppressed because it is too large Load Diff

1109
out/output-2024-08-09.txt Normal file

File diff suppressed because it is too large Load Diff

666
out/output-2024-09-26.txt Normal file

File diff suppressed because one or more lines are too long

666
out/output-2024-10-14.txt Normal file

File diff suppressed because one or more lines are too long