Add files via upload

This commit is contained in:
Peter Norvig 2019-01-23 19:30:58 -08:00 committed by GitHub
parent db46e8df33
commit 9c6fcf0183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

130
ipynb/Electoral Votes.ipynb Normal file
View File

@ -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'<tr(.*?)</tr>', 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('>([^>]*?)</td', row.replace('%', ''))\n",
" return Row(state, *map(int, nums))\n",
"\n",
"def net(row): \"Approval minus disapproval.\"; return row.app - row.dis \n",
"\n",
"votes = dict(AL=9, AK=3, AZ=11, AR=6, CA=55, CO=9, CT=7, DE=3, DC=3, FL=29, GA=16, HI=4, ID=4,\n",
" IL=20, IN=11, IA=6, KS=6, KY=8, LA=8, ME=4, MD=10, MA=11, MI=16, MN=10, MS=6, MO=10, \n",
" MT=3, NE=5, NV=6, NH=4, NJ=14, NM=5, NY=29, NC=15, ND=3, OH=18, OK=7, OR=7, PA=20, \n",
" RI=4, SC=9, SD=3, TN=11, TX=38, UT=6, VT=3, VA=13, WA=12, WV=5, WI=10, WY=3)\n",
"\n",
"rows = read_data()\n",
"\n",
"def EV(swing=0, rows=rows):\n",
" \"How many electoral votes would Trump win today, given a swing.\"\n",
" return sum(votes[row.state] for row in rows if net(row) + swing > 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
}