From 9c6fcf0183a910375db5eb44e623cc7f0d63828f Mon Sep 17 00:00:00 2001 From: Peter Norvig Date: Wed, 23 Jan 2019 19:30:58 -0800 Subject: [PATCH] Add files via upload --- ipynb/Electoral Votes.ipynb | 130 ++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 ipynb/Electoral Votes.ipynb diff --git a/ipynb/Electoral Votes.ipynb b/ipynb/Electoral Votes.ipynb new file mode 100644 index 0000000..0b523c8 --- /dev/null +++ b/ipynb/Electoral Votes.ipynb @@ -0,0 +1,130 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tracking Trump: Electoral Votes\n", + "\n", + "[Morning Consult](https://morningconsult.com) has a page called [Tracking Trump](https://morningconsult.com/tracking-trump/) that summarizes the presidential approval polls on a state-by-state basis, and tells you how many states Trump has a net positive or net negative approval rating. But I don't care about the number of *states*; I care about the number of *electoral votes*. This notebook computes that for me:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import urllib.request\n", + "import re\n", + "import collections \n", + "\n", + "Row = collections.namedtuple('Row', 'state delta jan17app jan17dis jan17err app dis err')\n", + "\n", + "def read_data(url='https://morningconsult.com/tracking-trump/'):\n", + " \"Fetch data from the website and return a list of `Row` objects.\"\n", + " with urllib.request.urlopen(url) as response:\n", + " html = response.read().decode('utf-8')\n", + " rows = re.findall(r'', html, re.S)\n", + " return [parse_row(row) for row in rows[1:]]\n", + " \n", + "def parse_row(row):\n", + " \"Parse an html string into a `Row` object.\"\n", + " state, *nums = re.findall('>([^>]*?) 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "164" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "EV()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What that says is that if an election were held today, January 23, 2019, and if Trump won those states in which he has a net positive approval (i.e. more approval than disapproval), **he would get 164 electoral votes** (that's 9 worse than McCain in 2008). You need **270** to win.\n", + "\n", + "But things can change. The election is a long ways away, and we don't know who's running. In the table below, I list the number of electoral votes Trump would get assuming he gets an increase of net approval of 0 to 9 percentage points across the board in every state. We see he would need a **7** percent upswing in order to win." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{0: 164,\n", + " 1: 164,\n", + " 2: 164,\n", + " 3: 164,\n", + " 4: 255,\n", + " 5: 255,\n", + " 6: 255,\n", + " 7: 279,\n", + " 8: 279,\n", + " 9: 294}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{m: EV(m) for m in range(10)}" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}