avatarMartin Thoma

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

4813

Abstract

"8a7f">Those two patterns apply to other languages as well. Let’s phrase it like this:</p><p id="ee2c" type="7">Make good use of the type system.</p><p id="391a">If you want to know more about type annotations in Python, please read:</p><div id="e8a6" class="link-block"> <a href="https://readmedium.com/type-annotations-in-python-3-8-3b401384403d"> <div> <div> <h2>Type Annotations in Python 3.8</h2> <div><h3>Learn how to make Python code easier to read and less error-prone by gradual typing</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*fw3b_alHFz06dX0VUjJUCA.png)"></div> </div> </div> </a> </div><p id="634d">If you want to know about the most recent improvements, read my <a href="https://betterprogramming.pub/python-3-10-is-released-know-whats-new-and-if-it-s-worth-the-switch-19c7a5738f7c">Python 3.10 article</a>.</p><h1 id="3fa5">№4 Consistent Terminology</h1><figure id="1102"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*W2P9YP2EO_JOVB5c"><figcaption>Photo by <a href="https://unsplash.com/@waldemarbrandt67w?utm_source=medium&amp;utm_medium=referral">Waldemar Brandt</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p id="6200">I work at the FinTech company <a href="https://cashlink.de/">Cashlink</a> as a Python backend developer. We handle digital securities, e.g. tokens that represent a real value like a part of a solar farm. Those tokens can be transferred. And here it starts to become interesting. Depending on the type of transfer, we must do different things. Either because of regulations or because of technical reasons. So we started to name different types of transfers differently to not be confused all the time:</p><ul><li><b>Transfer</b>: Any action that changes a balance. All terms below are some kind of transfer (although I would hesitate to call minting and burn a transfer).</li><li><b>Minting</b>: The tokens are generated. This happens first.</li><li><b>Issuance</b>: The transfer from the issuer to the investor. This happens second.</li><li><b>Move</b>: A transfer from wallet A to wallet B, where A and B belong to the same investor.</li><li><b>Handover</b>: A transfer from wallet A to wallet B, where A and B belong to different investors.</li><li><b>Burn</b>: Removing tokens from an investor's account.</li></ul><p id="95d3">Those things are important, but there are other examples where the terminology can be different. For example, internal product names and external ones. Marketing might have different needs than development. Try to get a vocabulary that fits most of the company.</p><h1 id="dff5">№5 Meaningful Names</h1><p id="9699">Think of your codebase like a book. The book has many, many different storylines. The variables are the characters. You can rely a bit on the context, but readers will be confused if you call everybody just “the friend”. They will be annoyed if they need to read half a page just for the name.</p><ul><li><b>Avoid too short names </b>like <code>i</code> or<code>x</code> . They are hard to search for. If you write a mathematical function, they might make sense, though.</li><li><b>Avoid too long names</b> like <code>InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState</code>. Java developers regularly fall into this trap. Yes, the name might be super exact. However, it makes all the logic around it super hard to understand. There is a nice middle ground between <code>x</code> and <code>InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState</code> .</li><li><b>Be consistent</b> with the vocabulary from №4. Also in spelling. Decide if you want to use American English or British English. Decide if you want to write display/show/present/print in your codebase.</li><li><b>Avoid data structures in names</b> like <code>user_dict</code> . If you need that, it might be that you’re violating №6. Try to use only one representation of one object. But keep in mind that this is a general rule. It does make sense sometimes to use <code>user_dict</code> .</li><li><b>Make use of context</b>. For example, the <code>java.sql.SQLIntegrityContraintViolation</code> could simply be a <code>java.sql.IntegrityError</code> . Within the <code>sql</code> package, everything should be about SQL. And a <code>ConstraintViolation</code> simply is an Error.</li></ul><p id="d5d3">A pattern I like when iterating is to use the plural form for the iterator (ending in “s”) and the singular (without the final

Options

“s”)</p><div id="09da"><pre><span class="hljs-comment"># Bad</span> <span class="hljs-keyword">for</span> tmp <span class="hljs-keyword">in</span> <span class="hljs-built_in">users</span>: ...</pre></div><div id="a04b"><pre><span class="hljs-comment"># Good</span> for <span class="hljs-keyword">user</span> <span class="hljs-title">in</span> registered_users: ...</pre></div><p id="aab1">By the way: Please share if you’ve seen <a href="https://www.reddit.com/r/ProgrammerHumor/comments/k1wdrt/whats_the_most_inappropriate_variable_name/">funny variable naming</a> in the wild 😄</p><h1 id="9b96">№6 The step-down rule</h1><figure id="137d"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*beIO8I4KcJNur1tc"><figcaption>Photo by <a href="https://unsplash.com/@larm?utm_source=medium&amp;utm_medium=referral">Larm Rmah</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p id="6cc9">Keeping a function at one abstraction level helps you to focus on one topic.</p><p id="8530" type="7">Separate logic ↔ data collection/transfer ↔ presentation.</p><p id="a044">The presentation does not necessarily have to be visual. It can be print statements or it could be an API response.</p><p id="1168">Marek Hudyma gives <a href="https://marekhudyma.com/code-style/2021/03/02/step-down-rule.html">a good example</a> of the step-down rule.</p><p id="b52b">In Python, you can sometimes see this when there is a lot of indentation.</p><h1 id="ec92">№7 Remove Dead Code</h1><figure id="f12b"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*y9x2yyfDJEhmhkPH"><figcaption>Photo by <a href="https://unsplash.com/@genefoto?utm_source=medium&amp;utm_medium=referral">Gene Gallin</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p id="c593">Code that isn’t there is code that cannot break. It’s code that will not cause security issues. It’s code that doesn’t need to be maintained. Instead of commenting code out, remove it.</p><p id="af6b">You can use <a href="https://pypi.org/project/vulture/">vulture</a> and <a href="https://pypi.org/project/flake8-eradicate/">flake8-eradicate</a> to find such pieces in a Python codebase.</p><p id="74d2">I know the feeling when you have stuff that might be necessary later. I typically try to write a really thorough commit message, removing only those comments/files to be able to find it later if I need it. But there is YAGNI: <a href="https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it">You aren’t gonna need it!</a></p><h1 id="d5b8">№8 Use containers</h1><p id="8b22">If you pass the same few values around in several places of your codebase you might want to consider writing a container. That could be a class, in Python you can use a <a href="https://docs.python.org/3/library/dataclasses.html">dataclass</a>, a <a href="https://docs.python.org/3/library/typing.html#typing.NamedTuple">NamedTuple</a>, or a <a href="https://www.python.org/dev/peps/pep-0589/">TypedDict</a>. If you need to serialize it, a Pydantic class is pretty nice as well.</p><p id="a573">A prime example where you should likely use a container format is configuration.</p><h1 id="997d">№9 Avoid Surprises</h1><p id="b279">This is a no-brainer, but it is sometimes easy to forget. One core part is to <b>avoid side effects</b>. It should be clear whether a function changes state. Another part is to <b>document hacks</b>. Sometimes it is necessary to have hacks, but at least leave a comment on why the hack is there.</p><p id="bf5d">Don’t try to do something smart. Follow the KISS principle — Keep it simple and stupid!</p><h1 id="bc06">Summary</h1><p id="2f9d">Writing good code is like writing good articles: It needs <b>practice</b> and you will always improve. Read a lot, <a href="https://codereview.stackexchange.com/">ask for feedback</a> and encourage people to also give small little notes in feedback. The ones that don’t matter too much, but are just personal preferences.</p><p id="86bc">Finally, understand what you hate when you read code. Avoid <a href="https://cs.fit.edu/~kgallagher/Schtick/How%20To%20Write%20Unmaintainable%20Code.html">those patterns</a> 😄 — but <a href="https://github.com/zedr/clean-code-python/blob/master/README.md">apply this</a> 😍 Practice, be open to feedback, look critical at your code. Then you will be an awesome software engineer 🥂</p><p id="1cca">I love writing about software development and technology 🤩 Don’t miss updates: <a href="https://martinthoma.medium.com/subscribe"><b>Get my free email newsletter</b></a> 📧 or <a href="https://martinthoma.medium.com/membership">sign up for Medium</a> ✍️ if you haven’t done it yet — both encourages me to write more 🤗</p></article></body>

9 Clean Code Patterns I wish I knew earlier

Photo by Tim Chow on Unsplash

Do you know the feeling when you look back at code which you wrote early in your career? I always feel a bit horrified. But there is a positive side to it: I learned something new 😄

A core part of good software is readability. Keeping the mental complexity low so that everybody (including the author) has an easy time understanding it. Clean code patterns help to do so.

In this article, you will get to know 9 clean code patterns that make code easier to read. Please see such patterns as tools. They don’t apply all the time. Don’t get religious about them. The language I use is Python, but the patterns apply outside of Python as well. Let’s start!

№1: Explanatory Variables

This is probably the simplest trick which you can easily apply. If something is hard to understand and you need a comment for it, try giving it a name.

# Bad
if not (
    string.startswith('"""')
    and string.endswith('"""')
    and '"' not in string[3:-3]
):
    return string
# Good
is_tripple_quoted_string = (
    string.startswith('"""')
    and string.endswith('"""')
)
if not (is_tripple_quoted_string and '"' not in string[3:-3]):
    return string

This applies mostly to boolean expressions, but also to regular expressions, and sometimes to return values.

№2: Follow Conventions and Style Guides

Photo by Ruthson Zimmerman on Unsplash

Every programming language has a syntax that you need to follow, otherwise, it will not work. And then there are conventions. You don’t have to follow them; it will still work. However, it makes the life of others way easier if you do follow them.

One of the simplest conventions is style guides. In Python it’s PEP 8, Google published guides for C++ / Java, the Oracle Java Code Conventions, in PHP there is PSR-1, …

Other guides are implicit. For example, how a Django project is structured. Where you typically store views, models, and templates.

Find the style guide(s) that are relevant for you and follow them.

Typically, there are also linters or static code analysis tools that help you to get used to the guides. For example, in Python, there is flake8 with a lot of plugins. For the simplest part, the formatting, you can use tools that do it for you. A code autoformatter for Python which I love is black.

№3: Type Checking

I love type annotations in Python. They are optional, but I highly recommend using them. There are also differences in how to use them.

For example, if you have Dict[str, Any] you might want to consider using NamedTuple / TypedDict / pydantic / dataclasses instead.

In some case, when you use str as the type you might want to consider using NewType to denote which kind of string you are using. Is it an AuthorId ? Is it an UserId ?

Those two patterns apply to other languages as well. Let’s phrase it like this:

Make good use of the type system.

If you want to know more about type annotations in Python, please read:

If you want to know about the most recent improvements, read my Python 3.10 article.

№4 Consistent Terminology

Photo by Waldemar Brandt on Unsplash

I work at the FinTech company Cashlink as a Python backend developer. We handle digital securities, e.g. tokens that represent a real value like a part of a solar farm. Those tokens can be transferred. And here it starts to become interesting. Depending on the type of transfer, we must do different things. Either because of regulations or because of technical reasons. So we started to name different types of transfers differently to not be confused all the time:

  • Transfer: Any action that changes a balance. All terms below are some kind of transfer (although I would hesitate to call minting and burn a transfer).
  • Minting: The tokens are generated. This happens first.
  • Issuance: The transfer from the issuer to the investor. This happens second.
  • Move: A transfer from wallet A to wallet B, where A and B belong to the same investor.
  • Handover: A transfer from wallet A to wallet B, where A and B belong to different investors.
  • Burn: Removing tokens from an investor's account.

Those things are important, but there are other examples where the terminology can be different. For example, internal product names and external ones. Marketing might have different needs than development. Try to get a vocabulary that fits most of the company.

№5 Meaningful Names

Think of your codebase like a book. The book has many, many different storylines. The variables are the characters. You can rely a bit on the context, but readers will be confused if you call everybody just “the friend”. They will be annoyed if they need to read half a page just for the name.

  • Avoid too short names like i orx . They are hard to search for. If you write a mathematical function, they might make sense, though.
  • Avoid too long names like InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState. Java developers regularly fall into this trap. Yes, the name might be super exact. However, it makes all the logic around it super hard to understand. There is a nice middle ground between x and InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState .
  • Be consistent with the vocabulary from №4. Also in spelling. Decide if you want to use American English or British English. Decide if you want to write display/show/present/print in your codebase.
  • Avoid data structures in names like user_dict . If you need that, it might be that you’re violating №6. Try to use only one representation of one object. But keep in mind that this is a general rule. It does make sense sometimes to use user_dict .
  • Make use of context. For example, the java.sql.SQLIntegrityContraintViolation could simply be a java.sql.IntegrityError . Within the sql package, everything should be about SQL. And a ConstraintViolation simply is an Error.

A pattern I like when iterating is to use the plural form for the iterator (ending in “s”) and the singular (without the final “s”)

# Bad
for tmp in users: ...
# Good
for user in registered_users: ...

By the way: Please share if you’ve seen funny variable naming in the wild 😄

№6 The step-down rule

Photo by Larm Rmah on Unsplash

Keeping a function at one abstraction level helps you to focus on one topic.

Separate logic ↔ data collection/transfer ↔ presentation.

The presentation does not necessarily have to be visual. It can be print statements or it could be an API response.

Marek Hudyma gives a good example of the step-down rule.

In Python, you can sometimes see this when there is a lot of indentation.

№7 Remove Dead Code

Photo by Gene Gallin on Unsplash

Code that isn’t there is code that cannot break. It’s code that will not cause security issues. It’s code that doesn’t need to be maintained. Instead of commenting code out, remove it.

You can use vulture and flake8-eradicate to find such pieces in a Python codebase.

I know the feeling when you have stuff that might be necessary later. I typically try to write a really thorough commit message, removing only those comments/files to be able to find it later if I need it. But there is YAGNI: You aren’t gonna need it!

№8 Use containers

If you pass the same few values around in several places of your codebase you might want to consider writing a container. That could be a class, in Python you can use a dataclass, a NamedTuple, or a TypedDict. If you need to serialize it, a Pydantic class is pretty nice as well.

A prime example where you should likely use a container format is configuration.

№9 Avoid Surprises

This is a no-brainer, but it is sometimes easy to forget. One core part is to avoid side effects. It should be clear whether a function changes state. Another part is to document hacks. Sometimes it is necessary to have hacks, but at least leave a comment on why the hack is there.

Don’t try to do something smart. Follow the KISS principle — Keep it simple and stupid!

Summary

Writing good code is like writing good articles: It needs practice and you will always improve. Read a lot, ask for feedback and encourage people to also give small little notes in feedback. The ones that don’t matter too much, but are just personal preferences.

Finally, understand what you hate when you read code. Avoid those patterns 😄 — but apply this 😍 Practice, be open to feedback, look critical at your code. Then you will be an awesome software engineer 🥂

I love writing about software development and technology 🤩 Don’t miss updates: Get my free email newsletter 📧 or sign up for Medium ✍️ if you haven’t done it yet — both encourages me to write more 🤗

Software Development
Programming
Clean Code
Self Improvement
Software Engineering
Recommended from ReadMedium