De Revolutionibus Orbium Coelestium
Almagest
Pythagoras
Why did it take 113 years?
Evidence took 200–300 years to arrive
--1500s-- --1600s-- --1700s-- --1800s-- --1900s--
• • • • • • •
│ │ │ │ │ │ │
│ │ │ └ Newton │ │
│ │ └ Galileo│ │ └ Foucault
│ └ Kepler │ └ Bessel
└ Kopernik └ Bradley
Ideas Evidence
# x-coordinates of the seven planets
# t = time, in Earth years
#
# deferent + epicycle
me = sin(t) + 0.375 * sin(t / 0.24)
ve = sin(t) + 0.719 * sin(t / 0.62)
su = sin(t)
ma = sin(t / 1.88) + 0.658 * sin(t)
ju = sin(t / 11.9) + 0.192 * sin(t)
sa = sin(t / 29.5) + 0.108 * sin(t)
# Step 1: make sin(t) coefficients = 1.0
me = sin(t) + 0.375 * sin(t / 0.24)
ve = sin(t) + 0.719 * sin(t / 0.62)
su = sin(t)
ma = sin(t / 1.88) + 0.658 * sin(t)
ju = sin(t / 11.9) + 0.192 * sin(t)
sa = sin(t / 29.5) + 0.108 * sin(t)
#
me = sin(t) + 0.375 * sin(t / 0.24)
ve = sin(t) + 0.719 * sin(t / 0.62)
su = sin(t)
ma = 1.52 * sin(t / 1.88) + sin(t)
ju = 5.21 * sin(t / 11.9) + sin(t)
sa = 9.26 * sin(t / 29.5) + sin(t)
# Step 2: move sin(t) to the front
me = sin(t) + 0.375 * sin(t / 0.24)
ve = sin(t) + 0.719 * sin(t / 0.62)
su = sin(t)
ma = 1.52 * sin(t / 1.88) + sin(t)
ju = 5.21 * sin(t / 11.9) + sin(t)
sa = 9.26 * sin(t / 29.5) + sin(t)
#
me = sin(t) + 0.375 * sin(t / 0.24)
ve = sin(t) + 0.719 * sin(t / 0.62)
su = sin(t)
ma = sin(t) + 1.52 * sin(t / 1.88)
ju = sin(t) + 5.21 * sin(t / 11.9)
sa = sin(t) + 9.26 * sin(t / 29.5)
# Step 3: “It's not you, it's me”
me = sin(t) + 0.375 * sin(t / 0.24)
ve = sin(t) + 0.719 * sin(t / 0.62)
su = sin(t)
ma = sin(t) + 1.52 * sin(t / 1.88)
ju = sin(t) + 5.21 * sin(t / 11.9)
sa = sin(t) + 9.26 * sin(t / 29.5)
# x-coordinates of the seven planets
# t = time, in Earth years
su = 0
me = 0.375 * sin(t / 0.24)
ve = 0.719 * sin(t / 0.62)
ea = 1.00 * -sin(t) # Earth moves
ma = 1.52 * sin(t / 1.88)
ju = 5.21 * sin(t / 11.9)
sa = 9.26 * sin(t / 29.5)
def planet_position(x):
return x - ea
Not because of physical evidence!
# deferent + epicycle
me = sin(t) + 0.375 * sin(t / 0.24)
ve = sin(t) + 0.719 * sin(t / 0.62)
su = sin(t)
ma = sin(t / 1.88) + 0.658 * sin(t)
ju = sin(t / 11.9) + 0.192 * sin(t)
sa = sin(t / 29.5) + 0.108 * sin(t)
su = 0
me = 0.375 * sin(t / 0.24)
ve = 0.719 * sin(t / 0.62)
ea = 1.00 * -sin(t) # Earth moves
ma = 1.52 * sin(t / 1.88)
ju = 5.21 * sin(t / 11.9)
sa = 9.26 * sin(t / 29.5)
Or, in other words—
Kopernik — The Great Refactorer
examples
Mercedes 300D fan bolts
general principle
dependency injection
# Ugly: injecting I/O routines everywhere
import beautifulsoup, urllib2
def tw(handle, urlopen=urllib2.urlopen):
url = 'http://twitter.com/' + handle
u = urlopen(url)
return beautifulsoup.BeautifulSoup(u.read())
tw('brandon_rhodes')
#
# Tests use: tw('user', urlopen=fake_open)
#
wishbone splitting
"""Instead, I pull I/O up to a higher level."""
import beautifulsoup, urllib2
def make_url(handle):
return 'http://twitter.com/' + handle
def parse_page(u):
return beautifulsoup.BeautifulSoup(u.read())
url = make_url('brandon_rhodes')
u = urllib2.urlopen(url)
soup = parse_page(u)
The old
from argparse import argparse
def main():
parser = argparse.ArgumentParser(
description='Concatenate files.')
parser.add_argument(
'FILE', nargs='*',
help='Path(s) to files')
args = parser.parse_args()
usage: command [-h] [FILE [FILE ...]]
Concatenate files.
positional arguments:
FILE Path(s) to files
optional arguments:
-h, --help show this help message and exit
With docopt
"""Concatenate files.
Usage:
cat [-v] [FILE ...]
Options:
FILE Path(s) to files
-v, --version Display version
"""
from docopt import docopt
def main():
arguments = docopt(__doc__)
m = re.match('/user/([a-z_]+)$', path)
if m:
username = m.group(1)
return render('user.html', username)
m = re.match('/product/([-a-z_]+)$', path)
if m:
productname = m.group(1)
return render('user.html', productname)
m = re.match('/help/([-a-z_]+)$', path)
if m:
helppage = m.group(1)
return render('help.html', helppage)
return render('404.html', code=404)
def userview(request, username):
return render_to_response(
'user.html', username)
def productview(request, productname):
return render_to_response(
'product.html', productname)
def helpview(request, helppage):
return render_to_response(
'help.html', helppage)
Copernican refactorings
are my favorite refactorings!
Stop, and think of Kopernik!
@brandon_rhodes