Readable Code and Documentation#
Learning Objectives#
Understand the importance of readable code and documentation in software development
Apply techniques to improve the readability of code
Utilize structuring, consistency, and documentation to enhance code clarity
Recognize different types of documentation and their purposes
Plan and create effective documentation for various audiences
Introduction to Readable Cdoe#
Readable code is essential for effective programming and maintenance. It makes the code easier to understand, debug, extend, and share with others. These notes will guide you through understanding what makes code readable and how to apply these principles in practice.
Improving Code Readability#
For this exercise please take a look at the following Python code snippet. Be aware that you do not need to know Python (or even have any programming experience) to engage with this exercise. Start by trying to ascertain what the code does. What do you think this code does? The answer is below.
Click to reveal what the code snippet does!
The code prints the Fibonacci sequence up to the required sentence length.
Knowing what the code actually does, how would you improve the code’s readability?
def my_f(arg1):
"""
This function prints stuff.
"""
e2 = 0
e1 = 1
print(e2)
print(e1)
# Remove 2 from arg1
arg1 -= 2
while arg1 > 0:
print(e2 + e1)
i = e1
e1 = e2 + e1
e2 = i
arg1 -= 1
Steps to Enhance Readability
Renaming the Function: Rename functions to clearly indicate their purpose. For example,
my_f
becomesprint_fibonacci
.Refining Variable Names: Use meaningful variable names that reflect their roles. For instance,
e2
ande1
are renamed tofirst_element
andsecond_element
.Enhancing Documentation: Improve the function documentation to provide a clear explanation of what the function does and its parameters.
Consistent Use of Whitespace: Utilize whitespace to separate code blocks and enhance code clarity.
Adding Type Hints: Use type hints to specify the expected types of function arguments and the return type.
An improved version of the same could be:
def print_fibonacci(sequence_length: int) -> None:
"""
Prints the Fibonacci sequence up to the required sequence length.
Args:
`sequence_length` (int): Required number of Fibonacci numbers.
"""
first_element = 0
second_element = 1
print(first_element)
print(second_element)
sequence_length -= 2
while sequence_length > 0:
print(first_element + second_element)
temp_var = second_element
second_element = first_element + second_element
first_element = temp_var
sequence_length -= 1
Readable Code#
Readable code is defined by its clarity in communicating its intention to the reader, who can easily follow its functionality. The importance of maintaining readable code cannot be overstated, as it brings several significant advantages:
Makes identifying bugs or errors in the methodology simpler, thus enhancing the quality and reliability of the code.
The process of adding new functionality is streamlined, because developers can more quickly understand how new and existing pieces of code interact. This ease of understanding also makes revisiting the code in the future a less daunting task, reducing the time and effort required for future modifications or debugging.
Readable code is critical for collaborative and ongoing research projects. It allows other researchers to continue using, fixing, and developing the code even in the absence of the original authors. This accessibility also enables other researchers to more easily reproduce, replicate, or extend the research, promoting a continuous advancement in the field.
Developing readable code is not only beneficial for the immediate development team but also for the broader research community that may interact with the code later on.
How can we improve the readability of our code?#
Code readability is crucial for effective maintenance, debugging, and enhancement of software. Here are the foundational strategies to achieve a high standard of code clarity and maintainability:
Structuring#
Single Responsibility: Each component should have a single responsibility and minimal dependencies on other components. This separation of concerns aids in understanding what different parts of the code are intended to do.
Avoid Excessive Nesting: Instead of deeply nested functions, opt for larger, well-defined functions. This approach helps keep the code straightforward and easy to follow.
Adhere to DRY Principles: Avoid repetition in your code. Minimizing code duplication not only reduces the overall codebase size but also decreases the number of places where changes might be needed, facilitating easier maintenance.
Consistency#
Coding Style: Implement a consistent coding style to reduce cognitive load. This consistency helps others quickly understand and follow the logic within the code.
Naming Conventions: Use logical and descriptive naming conventions for functions, variables, and classes. Effective names can communicate the purpose of a code element, reducing the need for additional comments.
Whitespace Usage: Employ whitespace strategically to separate and emphasize related code blocks, enhancing the readability.
Line Length: Keep line lengths short to avoid horizontal scrolling, which can be disruptive and hinder code readability.
Style Guides and Formatters: Utilize style guides (e.g. PEP8 for Python) and tools like code formatters (e.g. Black for Python) to maintain consistent formatting automatically.
Documentation#
Concise and Constructive: In-code documentation should be concise yet comprehensive, providing clear explanations of the functionality.
Explain Complex Aspects: Documentation should clarify complex parts of the code and explain the rationale behind specific design decisions, rather than just reiterating what the code does.
Focusing on the structure, consistency, and comprehensive documentation, creating readable and maintainable code is possible. These practices not only make the code easier to work with but also ensure it can be effectively used and enhanced by others in the future.
Documentation#
Documentation plays a crucial role in the usability, extensibility, and sustainability of software. It is also a valuable tool for understanding and revisiting our own code in the future. Here’s a breakdown of the various aspects and types of documentation, along with guidance on how to effectively plan and produce documentation.
Importance of Documentation#
Ease of Use and Extendibility: Good documentation makes software easier to use and extend, which contributes significantly to its long-term viability.
Future Reference: Documentation helps developers understand their past work, which can be particularly useful when returning to a project after a long period.
Types of Documentation#
Documentation can be categorized into three main types, each serving a different purpose and catering to different audiences:
Conceptual Documentation: This type of documentation offers a high-level overview of the software, covering its requirements, design specifications, and architecture. It’s essential for giving users and developers a broad understanding of the software’s purpose and structure.
Hands-On Documentation: Includes practical guides such as tutorials and user manuals that help new users start using the software. This documentation is instrumental in lowering the entry barrier for new users and contributors.
Reference Documentation: Provides detailed descriptions of the software’s functionality and implementation details. This is often integrated directly into the code through comments and is invaluable for those who need to work intimately with the codebase.
Understanding the Audience#
Different documentation types serve different audiences. The audience for a piece of software can range from end-users to developers and may vary, especially in the context of research software where these roles can overlap:
User Documentation: Aimed at those who will use the software, focusing on how to use its features.
Developer Documentation: Aimed at those who will develop or maintain the software, focusing on how the software is built and how to contribute to its development.
Planning Documentation#
Effective documentation requires careful planning, ideally starting before the software development begins. Some key aspects to consider when developing documentation include:
Early Planning: Think about the types of documentation needed from the start of the project. This foresight can influence design decisions and software architecture.
Motivation and Goals: Consider why the documentation is being created. Is it to increase impact, facilitate collaboration, or ensure citation? Understanding these goals can help tailor the documentation to meet these ends.
Audience Analysis: Determining who the documentation is for, what they need from it, and how best to communicate with them are critical steps in the planning process. These considerations ensure that the documentation is useful and accessible to its intended audience.
Strategic Questions: To start the documentation planning, ask:
Who is it for?
What do they want?
How else could we communicate with them?
By understanding the different types of documentation and carefully planning its creation and maintenance, developers can greatly enhance the usability and longevity of their software. Good documentation not only supports current users and developers but also ensures that the software can be used and understood long into the future.
Adapted Content From:
What are best practices for research software documentation? Software Sustainability Institute (CC BY-NC 2.5 SCOTLAND)