270 to Win Simulation Results

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:
Terminal
pip install selenium webdriver-manager

Setup Instructions

Step 1: Clone the Repository

To download this script, clone the repository using:

Terminal
git clone https://github.com/thejessicafelts/270towin-simulation-automation.git

Then navigate into the new project folder:

Terminal
cd 270towin-simulation-automation

Step 2: Install Required Packages

Make sure you have selenium and webdriver-manager installed:

Terminal
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:

Terminal
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:

  1. Go to Settings > System > Power & Sleep.
  2. 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:

Terminal
caffeinate -i python3 script_name.py

Windows:

Terminal
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

  1. 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.
  2. 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.
  3. 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.

national_pie_chart.png
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%
az_pie_chart.png
ga_pie_chart.png
mi_pie_chart.png
nc_pie_chart.png
nv_pie_chart.png
pa_pie_chart.png
wi_pie_chart.png

The following script is the automation.py script that is used for the automation of the 270toWin simulation.

Python
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()