Avoid single-use variables
After all these years programming, it's fun to catch myself changing my style preferences in real-time. Here's a change I find myself getting very aggressive about: eliminating single-use variables (or functions, or what have you).
# Before
def render_subject(
newsletter: Newsletter, locale: str
) -> str:
welcome_message = localize(
"web.subscriber_facing.welcome_message",
locale=locale,
)
return f"[{newsletter.title}] {welcome_message}"
# After
def render_subject(
newsletter: Newsletter, locale: str
) -> str:
return (
f"[{newsletter.title}] "
f"{localize(
'web.subscriber_facing.welcome_message',
locale=locale
)}"
)
A trivial example, of course. A slightly less trivial one:
# Before
def render_email_view(id: str) -> str:
email = Email.objects.filter(id=id).first()
if not email:
return 'Email not found'
newsletter = email.newsletter
latest_email = (
email.newsletter.emails.latest('creation_date')
)
is_latest_email = email == latest_email
return render('email.html', {
'email': email,
'newsletter': newsletter,
'is_latest_email': is_latest_email,
})
# After
def render_email_view(id: str) -> str:
if email := Email.objects.filter(
id=id
).first():
return render('email.html', {
'email': email,
# Note the absence of `newsletter`; the
# template will access via `email.newsletter`
'is_latest_email': (
email
== email.newsletter.emails.latest(
'creation_date'
)
),
})
return 'Email not found'
(Usual caveats apply: there are cases where you shouldn't do this, ie for performance or testing ergonomics, I am, for the record, completely okay with shaping how you organize your code in service of testing as long as it's not gross — and everyone, deep down, knows when it's gross., and also I don't think lines should be this short it's just hard to show a diff in a blog post.)
But this slight tweak helps me in a few ways:
- Reveals complexity. A lot of seemingly-hairy methods can be unwound into a very straightforward sequence of nested transformations.
- Improves readability. When reviewing code, I often find myself first understanding the surface-level logic of how things plug together and then diving into the details of how things work. This significantly ameliorates the effort involved in the first step.