Background to that tweet:
What Carl and I both discovered:
# Ugly
page.canvas.drawString(x * em, y * lineheight,
message)
# Better
page.canvas.drawString(
x * em, y * lineheight, message)
# Most general
page.canvas.drawString(
x * em,
y * lineheight,
message,
)
Q: Why the trailing comma?
# Most general
page.canvas.drawString(
x * em,
y * lineheight,
message,
)
page.canvas.drawString(
x * em,
y * lineheight,
- message
+ message,
+ font='Gentium'
)
# vs
page.canvas.drawString(
x * em,
y * lineheight,
message,
+ font='Gentium',
)
My most popular slide:
canvas.drawString(x, y,
'Please press {}'.format(key))
# What if you introduce a name instead?
message = 'Please press {}'.format(key)
canvas.drawString(x, y, message)
widget.reset(True) # forces re-draw
vs.
force_redraw = True
widget.reset(force_redraw)
message = 'Please press {}'.format(key)
canvas.drawString(x, y, message)
def _1(_2, _3):
_4 = _2.get(_3)
return _4.text
def fetch(session, url):
response = session.get(url)
return response.text
def main():
parser.add_argument('page',
help='the page to download')
args = parser.parse_args()
download_page(args.page)
def download_page(page):
? = requests.get(page)
# Whoops
# Instead:
def download_page(url):
page = requests.get(url)
process_page(page)
def process_page(page):
? = page.text
# Whoops
# Instead:
def process_page(response):
page = response.text
...
Q: What have I done?
A: I have failed to refactor!
def main():
... download_page(args.page) ...
def download_page(url):
... process_page(page) ...
def process_page(response):
... page = response.text ...
def main():
... download_page(args.url) ...
def download_page(url):
... process_page(response) ...
def process_page(response):
... page = response.text ...
⋮
process_page(page)
⋮
def process_page(response):
page = response.content
⋮
⋮
process_page(response)
⋮
def process_page(response):
page = response.content
⋮
def database():
'Not at all clear what this does.'
'And, it steals a good variable name!'
def create_database():
'Much clearer; code will read smoothly.'
# Pretty clear despite brevity
document.md5()
# No conflict with local variable `md5`
md5 = document.md5()
# A bit silly and redundant
obj = create_new_obj()
# Because this is just fine
obj = new_obj()
# Would you rather type this?
d = compute_length(compute_center(boston) -
compute_top(mt_adams))
# Or this?
d = length(center(boston) - top(mt_adams))
~
~
~
Lie
The tune was a well-known one
url = 'http://lyrics.com/a-sitting-on-a-gate'
song = 'A sitting on a Gate...'
song = 'http://lyrics.com/a-sitting-on-a-gate'
document = '/home/brandon/2013-03-pycon.rst'
Always name the part
song_url = 'http://lyrics.com/sitting-on-a-gate'
song_text = 'A sitting on a gate'
# or
url = 'http://lyrics.com/sitting-on-a-gate'
text = 'A sitting on a gate'
# In medialib.py:
def fetch_songs(urls):
...
# In songlib.py:
def fetch(urls):
...
# In medialib.py:
def fetch_songs(urls):
...
# In songlib.py:
def fetch(urls):
...
class Logger
class Handler
class Filter
class LogRecord
# The caller has their choice:
from songlib import fetch
fetch(...)
# or:
import songlib
songlib.fetch(...)
You can do this, but you oughtn’t
# foo.py
def go():
print(value)
# program.py
import foo
if __name__ == '__main__':
foo.value = 5
foo.go()
for line in lines: ...
for url in urls: ...
for request in AAAAAARGH—
The problem has three prongs
>>> connections
[<SQLConnection at 0xb72ff4d8>,
<SQLConnection at 0xb72ff4d0>,
<SQLConnection at 0xb72ff4f0>]
>>> connections
{'master': <SQLConnection at 0xb72ff4d8>,
'backup': <SQLConnection at 0xb72ff4f0>}
Plurals are not always unique in English
for box in boxes: ...
for foot in feet: ...
for brother in brethren: ...
for species in AAAAAARGH—
# Ugly:
numconnections = 8
# These must be too much typing:
connection_count = 8
number_of_connections = 8
total_connections = 8
# Because we are all tempted to:
connections = 8
# You built it, know its type:
connection_set
connection_list
connection_dict
connection_deque
# You only care about its interface:
def close_all(connection_seq):
...
def reset_all(connection_map):
...
x = linspace(-10.0, 10.0, 200)
plot(x, sin(x) + 2.0 * cos(x / 2.0))
f(x) = 3 * x ** 2 - 2 * x + 1
plot(x, f(x))
# I have tried these and more:
connection_dict = {}
connection_by_url = {}
url_to_connection = {}
# Current favorite:
connection_map = {}
# But sometimes I *still* say:
connections = {}
# AAAAAARGH MY EYES
url2connection = {}
# Never EVER design an API this way:
yaml.load()
yaml.safe_load()
# Instead:
yaml.load()
yaml.dangerous_load()
Ned Batchelder, “War is Peace”
# Does this mean that each name maps to
# ONE vector, or a LIST of vectors?
vector_map = {} # scientific names -> vectors
# So use the singular, which is clear:
vector_map = {} # scientific name -> vector
@brandon_rhodes