Common Coding Blunders: How to Avoid and Get Over Them

Pawan natekar
6 min readOct 22, 2024

--

Generated by Pawan Natekar

No programmer is exempt from falling into coding pitfalls sometime. It may as low as buggy codes and reach as high as some system which nobody wants to touch again and subsequently wasted time. In this blog, we’re going to dive into some of the most common coding pitfalls: why they happen and how to overcome them. Whether you’re a beginner or experienced developer, knowing these pitfalls will help you in writing cleaner, more reliable code.

1. Not Handling Errors Properly

Dealing with errors and exceptions is one of the foremost mistakes developers make, at least in my experience. Not handling errors and exceptions properly could result in your application crashing suddenly or, worst still, giving the wrong answers.

Why this happens:

You don’t anticipate certain edge cases or failures.
You haven’t thoroughly tested for exceptional scenarios.
You want to get something out quickly; you have forgotten to prioritize its robustness.

How to avoid it:
- Proper error handling mechanisms: Depending on the language, use `try.catch` blocks in languages like Java and Python or promises/async-await with error handling in JavaScript to gracefully catch and manage errors.
Example (Python):
```
try:
result = divide(x, y)
except ZeroDivisionError:
print(“Cannot divide by zero”)
```

- Provide useful error messages: When something goes wrong, the user or developer should be clear about what has happened in as clear and informative a manner as possible.

- Test edge cases: Try to test every exceptional condition, which may include network failures, invalid input, and file access errors.

2. Not Writing Tests

Another trap is not writing enough tests. Developers tend to skip tests, reasoning that they slow down development or the code is too simple to “not need testing.”

Why it happens

- Lack of education on the value of automated testing.
- Perception that writing tests is a slow-down on development.
- Too much reliance on manual testing and “it works on my machine” assumptions.

— — -

How to avoid it
-Specify unit tests. Through unit testing, you will know if your various components of the code work based on expectation. You may use such frameworks as **JUnit** for Java, **PyTest** for Python, and **Mocha** for JavaScript to automate the process.

Example (Python, with PyTest):

```python
def test_add():
assert add(1, 2) == 3

- Testing Development Driven with Test (TDD): In TDD, you first write your tests before you write the actual code, making sure that every new feature has tests at its inception.

- Utilize Continuous Integration (CI) tools: Establish automated testing pipelines using tools such as Jenkins, CircleCI, or GitHub Actions, so you know for sure your tests run each time you commit code.

3. Hardcoding values

The most common problem associated with inflexible and hard-to-maintain applications is hardcoding file paths, API keys, or URLs directly within your code.

Why it occurs:
- There could be a scenario wherein a developer, in a rush, will hardcode certain values for the sake of quick testing or developing functionality.
Overconfidence that those values will not change.

How to avoid this:
- Config file or environment variables: In this, you separate configurations from the code. Store values in the configuration file (config.json, `.env` etc.) or environment variables.
Example in Python, with the use of environment variables:

- Dependency Injection (DI): Don’t hard code dependencies in your classes. Use the dependency injection frameworks like Spring in Java or Dagger in Android development to inject dependencies at runtime.

4. Code Duplication

Copy and paste coding appears to be a good idea that saves time, but it’ll soon turn into duplication of code, inconsistencies, and technical debt. When bugs creep in, you would have fixed that bug in multiple places, making your code harder to maintain.

Why it happens
Time crunch to deliver features quickly
Abilities lacking for the reusability of the refactoring code

How to avoid it:
- Dry (Don't Repeat Yourself):
Never have duplicate code. Abstract repeated logic in a function or class so that it can be reused.

Bad:
```
def calculate_area_of_rectangle(width, height):
return width * height
def calculate_area_of_square(side):
return side * side
```
Good:
```python
def calculate_area(shape, *dimensions):
```
if shape == "rectangle":
return dimensions[0] * dimensions[1]
elif shape == "square":
return dimensions[0] * dimensions[0]

- Make libraries or helper functions usable: If what you are copying is a reusable part, like a sorting algorithm or HTTP request handler, write a utility function or leverage existing libraries.

5. Over-engineering

Sometimes the obvious trap that developers fall into is over-engineering: building systems much more complex than needed to solve the immediate problem. Over-engineering tends to lead to bloated, nasty code that slows down development.

What's over-engineering?
- Design beforehand to shield the code from features that might never be needed.
- Using latest tools or patterns without being aware of the usage of it.

How to prevent it
- Obey **YAGNI (You Ain't Gonna Need It). Do not add feature or an abstraction unless it is needed currently. Your code should be simple; add complexity only when necessary.

- Refactor when needed: Don't be afraid to come back later and refactor the code when a real need for more complexity materializes itself.

- Avoid premature optimization: First, go for clear and functional code; then optimize for performance if it becomes evident with actual data that such optimization is needed.

6. Overlooked Code Documentation

Failure: To write code with scarce or no comments; doing so leads to a serious failure, especially for multi-developer projects or long-term maintenance. Without comments or documentation, it is difficult for others-or even you someday-to understand the intent behind the code.

Why it happens
- The author assumes the code is self-explanatory.
- They are in such a rush to deliver that feature.

How to avoid it:
- Good comments: Good comments explain why. If your code is complicated, your code should tell something about the logic.

- Document your functions: Use docstrings or documentation comments to explain the use and inputs/output of your functions.

Example (Python, using docstrings):
```
def calculate_area(width, height):
"""
Calculates the area of a rectangle.
""".
:param width: The width of the rectangle.
:param height: The height of the rectangle.
:return: The area of the rectangle.
"""
return width * height
```

- External Documentation: Generate readable documentation automatically from comments in your code using tools like **JSDoc** for JavaScript, **Sphinx** for Python or **Javadoc** for Java.

7. Ignoring the Performance of the Code

Most developers are more concerned about feature development without paying too much attention to the performance factors. That is not an excuse to over-optimize and waste precious development time but complete ignoring of performance can lead to applications that take ages to execute and raise users' frustration.

Why this happens:
- No measurement at one point during the development cycle.
- Never heard about the efficiency algorithms or data structures.

Don't
- **Measure before optimizing**: Learn how to use profiling tools like **cProfile** (Python), **Perf** (Linux), or the **Chrome DevTools** (for JavaScript), and then identify the performance bottlenecks.
- **Use the appropriate data structures**: You need to understand the performance characteristics of data structures like arrays, linked lists, hash maps, etc, and then pick the right one for a given task.

- **Optimize only what matters**: Knowing where the performance bottlenecks lie, you can now optimize the slowest parts of your code, say, to improve the efficiency of the algorithms or to save memory.

Conclusion

There's no level of experience that can make you completely safe from some of the most insidious pitfalls involved with coding; however, awareness of these pesky snafus and adherence to the following guidelines can help you escape most of the pitfalls that plague them. Error-resistant, maintainable, and efficient code is the hallmark of a skill that takes practice to master, but the result of learning the practice is well worth the exercise.

These are the habits—error handling, writing tests, avoidance of hard-coding, and avoidance of over-engineering—that make you a more efficient and reliable developer. The next time you sit down to code, remember these potential pitfalls—and you'll be well on your way to cleaner, better code.

--

--