270toWin Election Simulation Automation
This Python script automates running simulations on the 270toWin 2024 Election Simulation website. It sets the simulation speed, runs the simulation a specified number of times, and tracks the results for each run. Throughout the process, it prints out information on which candidate won each simulation.
Features
- Automatically set the simulation speed on the 270toWin website.
- Run the simulation a specified number of times.
- Track how many times each candidate wins or ties during the simulation.
- Print results for each simulation run, including which candidate won and the running percentage of wins.
Prerequisites
Before running the script, make sure you have the following installed:
- Python 3.7 or higher: Download from python.org.
- Google Chrome: The script uses the Chrome browser to run the automation.
- ChromeDriver: Managed automatically by
webdriver-manager
. - Selenium: To install Selenium, run:
pip install selenium webdriver-manager
Setup Instructions
Step 1: Clone the Repository
To download this script, clone the repository using:
git clone https://github.com/thejessicafelts/270towin-simulation-automation.git
Then navigate into the new project folder:
cd 270towin-simulation-automation
Step 2: Install Required Packages
Make sure you have selenium
and webdriver-manager
installed:
pip install selenium webdriver-manager
Step 3: Preventing Your Computer from Sleeping During the Simulation
For Mac Users: Use the caffeinate
command to prevent your Mac from going to sleep while the script runs:
caffeinate -i python3 script_name.py
Replace script_name.py
with the actual name of your Python script. The -i
option ensures your Mac stays awake as long as the script is running.
For Windows Users: Adjust your power settings to prevent the computer from sleeping:
- Go to Settings > System > Power & Sleep.
- Under Sleep, set "When plugged in, PC goes to sleep after" to "Never."
Running the Script
Step 1: Modify Configuration (Optional)
Edit the following variables in the script if you need to adjust the settings:
url
: The URL of the 270toWin simulation page (default is set correctly).sim_speed_id
: The ID for the simulation speed button (default:sim_speed_4
).simulation_count
: Number of times to run the simulation (default:1000
).wait_time
: Time to wait (in seconds) between simulations (default:6
).
Step 2: Run the Script
Execute the script using:
Mac:
caffeinate -i python3 script_name.py
Windows:
Python script_name.py
Example Output:
--------------------------------------------------------------------------------
Simulation 1: democrat Wins.
----------
democrat: 320, republican: 218
democrat has won 100.00% of simulations. (1 out of 1)
--------------------------------------------------------------------------------
Simulation 2: republican Wins.
----------
democrat: 249, republican: 289
republican has won 50.00% of simulations. (1 out of 2)
--------------------------------------------------------------------------------
Simulation 3: democrat and republican have Tied.
----------
democrat: 269, republican: 269
50.00% of Simulations (1 of 3) have resulted in a Tie.
--------------------------------------------------------------------------------
Code Walkthrough
- Initialization: The script sets up the WebDriver using ChromeDriver and
webdriver-manager
. The simulation speed is set by finding and clicking the appropriate button on the website. - Simulation Loop: The script runs the simulation the specified number of times. After each simulation run, it waits for the results to appear and retrieves them using the designated HTML element IDs.
- Result Calculation & Display: The script calculates and prints the win percentage for democrat and republican, as well as the number of ties, after each simulation run.
Future Enhancements
- Final Summary: Add a final summary that prints the overall win percentages for democrat, republican, and ties at the end of all simulations.
- Robust Error Handling: Implement more error handling to gracefully handle issues, such as network interruptions or missing elements on the page.
- Command-Line Arguments: Allow users to specify
simulation_count
,wait_time
, and other configurations via command-line arguments for easier usage.
Troubleshooting
- ChromeDriver Issues: Ensure that your Chrome browser is up to date.
webdriver-manager
should handle most ChromeDriver version issues, but sometimes mismatches can occur. Updating Chrome typically resolves these. - Permissions Errors: If you encounter permissions issues when running the script on Windows, try running the command prompt as an Administrator.
- System Goes to Sleep: Make sure to use the
caffeinate
command on Mac or adjust the power settings on Windows as described above.
Contributing
Feel free to submit issues or pull requests if you'd like to contribute to improving the script. Make sure to follow proper coding standards and provide thorough explanations for any changes made.
Democrat | Republican | Ties | |||||
---|---|---|---|---|---|---|---|
Date | Simulations | Wins | % | Wins | % | Ties | % |
October 30, 2024 — 00:46 EDT | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 30, 2024 — 00:34 EDT | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 30, 2024 — 00:31 EDT | 10 | 4 | 40.0% | 6 | 60.0% | 0 | 0.0% |
October 30, 2024 — 00:27 EDT | 10 | 4 | 40.0% | 6 | 60.0% | 0 | 0.0% |
October 30, 2024 — 00:21 EDT | 10 | 4 | 40.0% | 6 | 60.0% | 0 | 0.0% |
October 30, 2024 — 00:14 EDT | 10 | 7 | 70.0% | 3 | 30.0% | 0 | 0.0% |
October 30, 2024 — 00:07 EDT | 50 | 29 | 58.0% | 21 | 42.0% | 0 | 0.0% |
October 29, 2024 — 23:55 EDT | 50 | 27 | 54.0% | 23 | 46.0% | 0 | 0.0% |
October 29, 2024 — 23:33 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 23:31 EDT | 5 | 1 | 20.0% | 3 | 60.0% | 1 | 20.0% |
October 29, 2024 — 23:28 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 23:26 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 23:22 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 23:20 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 23:13 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 23:08 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 23:03 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 23:00 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 22:44 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 22:39 EDT | 5 | 2 | 40.0% | 3 | 60.0% | 0 | 0.0% |
October 29, 2024 — 22:36 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 22:31 EDT | 5 | 4 | 80.0% | 1 | 20.0% | 0 | 0.0% |
October 29, 2024 — 22:28 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 22:26 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 22:22 EDT | 5 | 2 | 40.0% | 3 | 60.0% | 0 | 0.0% |
October 29, 2024 — 22:13 EDT | 5 | 2 | 40.0% | 3 | 60.0% | 0 | 0.0% |
October 29, 2024 — 22:09 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 22:05 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 21:57 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 21:54 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 21:48 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 21:35 EDT | 5 | 2 | 40.0% | 3 | 60.0% | 0 | 0.0% |
October 29, 2024 — 21:27 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 20:52 EDT | 5 | 3 | 60.0% | 2 | 40.0% | 0 | 0.0% |
October 29, 2024 — 20:05 EDT | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 29, 2024 — 20:00 EDT | 10 | 0 | 0.0% | 1 | 100.0% | 0 | 0.0% |
October 29, 2024 — 19:56 EDT | 10 | 0 | 0.0% | 1 | 100.0% | 0 | 0.0% |
October 29, 2024 — 19:55 EDT | 10 | 2 | 100.0% | 0 | 0.0% | 0 | 0.0% |
October 29, 2024 — 19:47 EDT | 10 | 2 | 100.0% | 0 | 0.0% | 0 | 0.0% |
October 29, 2024 — 19:38 EDT | 1 | 0 | 0.0% | 1 | 100.0% | 0 | 0.0% |
October 29, 2024 — 18:51 EDT | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 29, 2024 — 18:47 EDT | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 29, 2024 — 18:45 EDT | 1 | 0 | 0.0% | 1 | 100.0% | 0 | 0.0% |
October 29, 2024 — 18:42 EDT | 10 | 3 | 30.0% | 7 | 70.0% | 0 | 0.0% |
October 29, 2024 — 17:42 EDT | 100 | 47 | 47.0% | 53 | 53.0% | 0 | 0.0% |
October 29, 2024 — 17:27 EDT | 50 | 20 | 40.0% | 30 | 60.0% | 0 | 0.0% |
October 29, 2024 — 17:15 EDT | 5 | 1 | 20.0% | 4 | 80.0% | 0 | 0.0% |
October 29, 2024 — 17:01 EDT | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 29, 2024 — 16:58 EDT | 20 | 9 | 45.0% | 11 | 55.0% | 0 | 0.0% |
October 29, 2024 — 16:53 EDT | 20 | 8 | 40.0% | 12 | 60.0% | 0 | 0.0% |
October 29, 2024 — 16:47 EDT | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 29, 2024 — 16:41 EDT | 10 | 6 | 60.0% | 4 | 40.0% | 0 | 0.0% |
October 29, 2024 | 10 | 4 | 40.0% | 6 | 60.0% | 0 | 0.0% |
October 29, 2024 | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 29, 2024 | 10 | 5 | 50.0% | 5 | 50.0% | 0 | 0.0% |
October 29, 2024 | 10 | 3 | 30.0% | 7 | 70.0% | 0 | 0.0% |
October 24, 2024 | 100 | 51 | 51.0% | 49 | 49.0% | 0 | 0.0% |
October 24, 2024 | 100 | 48 | 48.0% | 52 | 52.0% | 0 | 0.0% |
October 24, 2024 | 100 | 46 | 46.0% | 54 | 54.0% | 0 | 0.0% |
October 23, 2024 | 10 | 4 | 40.0% | 6 | 60.0% | 0 | 0.0% |
The following script is the automation.py
script that is used for the automation of the 270toWin simulation.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time
# Configuration
url = 'https://www.270towin.com/2024-simulation/'
sim_speed_id = 'sim_speed_4'
run_simulation = 'run-simulation'
results_democrat = 'dem_ev'
results_republican = 'rep_ev'
wins_democrat = 0
wins_republican = 0
wins_tied = 0
wait_time = 6
simulation_count = 100
# Initialize the WebDriver (Chrome)
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
try:
# Open the website
driver.get(url)
# Set Simluation Speed
sim_speed_id_btn = driver.find_element(By.ID, sim_speed_id)
sim_speed_id_btn.click()
# Find the "Run Simluation" button
run_simulation_btn = driver.find_element(By.ID, run_simulation)
# Run the Simluation a specified number of times
for i in range(simulation_count):
# Click the "Run Simluation" Button
run_simulation_btn.click()
# Wait for the Simulation to Complete (for Speed 4, this is about 6 seconds)
time.sleep(wait_time)
# Recording the final Values
results_democrat_value = driver.find_element(By.ID, results_democrat).text
results_republican_value = driver.find_element(By.ID, results_republican).text
# Convert Results to Numbers
try:
results_democrat_value = int(results_democrat_value.replace('',''))
results_republican_value = int(results_republican_value.replace('',''))
except ValueError:
print(f"Count not convert values to numbers: '{results_democrat_value}', '{results_republican_value}'")
continue
# Update the Win Record
if results_democrat_value > results_republican_value:
wins_democrat += 1
elif results_democrat_value < results_republican_value:
wins_republican += 1
else:
wins_tied += 1
# Calculate the Win Percentage
total_runs = wins_democrat + wins_republican + wins_tied
wins_democrat_percentage = (wins_democrat / total_runs) * 100 if total_runs > 0 else 0
wins_republican_percentage = (wins_republican / total_runs) * 100 if total_runs > 0 else 0
wins_tied_percentage = (wins_tied / total_runs) * 100 if total_runs > 0 else 0
# Print the Results, Update Win Record
if results_democrat_value > results_republican_value:
print("-" * 80)
print(f"Simluation {i + 1}: democrat Wins.")
print("-" * 10)
print(f"democrat: {results_democrat_value}, republican: {results_republican_value}")
print(f"democrat has won {wins_democrat_percentage:.2f}% of simulations. ({wins_democrat} out of {total_runs})")
elif results_democrat_value < results_republican_value:
print("-" * 80)
print(f"Simluation {i + 1}: republican Wins.")
print("-" * 10)
print(f"democrat: {results_democrat_value}, republican: {results_republican_value}")
print(f"republican has won {wins_republican_percentage:.2f}% of simulations. ({wins_republican} out of {total_runs})")
else:
print("-" * 80)
print(f"Simluation {i + 1}: democrat and republican have Tied.")
print("-" * 10)
print(f"democrat: {results_democrat_value}, republican: {results_republican_value}")
print(f"{wins_republican_percentage:.2f}% of Simulations ({wins_tied} of {total_runs}) have resulted in a Tie.")
# Keep the browser open after the script finishes
print(f"{i + 1} Simluations have been completed.")
except Exception as e:
print(f"An error occurred: {e}")
# Commented out to keep the browser open
# finally:
# driver.quit()