Your code smells because there are likely many instances where it could be edited or improved. Most of these smells are just hints of something that might be wrong. Therefore, they are not required to be fixed per se… (You should look into it, though.) Previous Code Smells You can find all the previous code smells (Part I - XLVI) . here Let's continue... Code Smell 231 - Redundant Data Where are your sources of truth? TL;DR: Say it only once Problems Don't Repeat Yourself principle violation Consistency problems Maintainability Testing and Debugging Solutions Keep the responsibilities to relevant objects and delegate to a single source of truth. Context The principle of "Don't Repeat Yourself" (DRY) encourages you to avoid redundancy and duplication of behavior. Redundant data can lead to inconsistencies because updates or changes need to be made in multiple places. If you update one instance of the data and forget to update another, your system can become inconsistent, which can lead to errors and unexpected behavior. Maintaining redundant data can be a nightmare when it comes to making changes or updates since It increases the workload and the likelihood of introducing errors during maintenance. With a single source of truth, you only need to make changes in one place, simplifying the maintenance process. When data is repeated in multiple places, it becomes difficult to identify the authoritative source of that data, leading to confusion for developers. Sample Code Wrong class Transfer: def __init__(self, amount, income, expense): self.amount = amount self.income = income self.expense = expense class Income: def __init__(self, amount): self.amount = amount # amount is the same for party and counterparty class Expense: def __init__(self, amount): self.amount = amount transfer_amount = 1000 # simplification: should be a money object with the currency income = Income(transfer_amount) expense = Expense(transfer_amount) transfer = Transfer(transfer_amount, income, expense) print("Transfer amount:", transfer.amount) print("Income amount:", transfer.income.amount) print("Expense amount:", transfer.expense.amount) Right class Transfer: def __init__(self, amount): self.amount = amount self.income = Income(self) self.expense = Expense(self) class Income: def __init__(self, transfer): self.transfer = transfer def get_amount(self): return self.transfer.amount class Expense: def __init__(self, transfer): self.transfer = transfer def get_amount(self): return self.transfer.amount transfer_amount = 1000 transfer = Transfer(transfer_amount) print("Transfer amount:", transfer.amount) print("Income amount:", transfer.income.get_amount()) print("Expense amount:", transfer.expense.get_amount()) Detection Manual [x] This is a semantic smell Exceptions For performance issues, you can add and redundancy, but you need extra effort to keep the data synchronized caches Tags Data Conclusion In larger and more complex systems, redundancy becomes a significant problem. As your system grows, the challenges associated with maintaining and synchronizing redundant data also increase. Redundant data also increases the surface area for testing and debugging. You need to ensure that all copies of the data behave consistently, which can be a challenging task. Relations Code Smell 49 - Caches Disclaimer Code Smells are my . opinion Credits Photo by on Jørgen Håland Unsplash Everything will ultimately fail. Hardware is fallible, so we add redundancy. This allows us to survive individuals hardware failures, but increases the likelihood of having at least one failure at any given time. Michael Nygard https://hackernoon.com/400-thought-provoking-software-engineering-quotes?embedable=true Code Smell 232 - Reusable Code Don't Repeat Yourself. Don't Repeat Yourself TL;DR: You can find missing abstractions by looking at repeated code Problems DRY principle violation Maintainability Ripple Effect Solutions Create the repeated code Introduce an abstraction Replace the references and point to the new abstraction Remove the duplication Context Repeated code is a symptom of missing abstractions. This is natural in the learning process since we cannot foresee those abstractions. Sample Code Wrong def calculate_area(length, width): return length * width def calculate_volume(length, width, height): return length * width * height Right def calculate_area(length, width): return length * width def calculate_volume(length, width, height): base_area = calculate_area(length, width) return base_area * height Detection Semi-Automatic [x] Some linters can find repeated code patterns. Exceptions The abstraction must have a dependency correspondence on the Bijection Tags Bloaters Conclusion Repeated code is a problem and a hint for a missing abstraction. Remember you copying and pasting. don't need to avoid You must explicitly the repeated code and remove the duplication by introducing an abstraction. write Avoiding the cut and paste is a shortcut and a symptom of premature optimization. Relations Code Smell 46 - Repeated Code Code Smell 182 - Over Generalization Credits Photo by on Mitchell Griest Unsplash Pasting code from the internet into production code is like chewing gum found in the street. Mike Johnson Code Smell 233 - Collections Count You count collections or collections.count? TL;DR: Chose narrow names Problems Bad Naming Solutions Accurately describe your collections Context Names are significant and should not deceive the reader. f You name things and lose the scope of the name. It is important to be accurate of the expected reference on the names. Sample Code Wrong const standardModelParticles = { quarks: [ { name: "Up", charge: "2/3", type: "Quark", }, { name: "Down", charge: "-1/3", type: "Quark", }, // ... ], leptons: [ { name: "Electron", charge: "-1", type: "Lepton", }, { name: "Muon", charge: "-1", type: "Lepton", }, // ... ], gaugeBosons: [ { name: "Photon", charge: "0", type: "Boson", }, { name: "W Boson", charge: "±1", type: "Boson", }, // ... ], higgsBoson: [ { name: "Higgs Boson", charge: "0", type: "Scalar Boson", }, ], }; const quarks = standardModelParticles.quarks.length; // Bad name. It does not represent a count // But a Collection of things Right const standardModelParticles = { }; // Same as the "Wrong" example const quarksCount = standardModelParticles.quarks.length; Detection Semi-Automatic [x] Some linters can check the types and names and infer a mistake Tags Namings Conclusion Take care of your names. Use automatic refactor tools whenever you come across a bad name. Relations Code Smell 163 - Collection in Name Code Smell 134 - Specialized Business Collections Code Smell 33 - Abbreviations Credits Photo by on Sandy Millar Unsplash Some people are good programmers because they can handle many more details than most people. But there are a lot of disadvantages in selecting programmers for that reason - it can result in programs that no one else can maintain. Butler Lampson Code Smell 234 - Long Circuit Be smart (and lazy) with low performant conditions TL;DR: Premature Optimization is Evil. Optimization is Good. Problems Low Performance Solutions Sort the conditions from faster to slower Context Readability is always essential and you should avoid premature optimization. Non-premature optimization happens when you have actual evidence you can improve your code execution time without much readability penalizations. Sample Code Wrong def is_warm(): # This is a fast api call to your thermometer response = requests.get ("https://iot-device-api.example.com/current_temperature") temperature_data = response.json() return temperature_data.get('temperature', 0) > 25 def is_weekend(): # This function checks if today is a weekend # based on a slow calendar API call response = requests.get ("https://calendar-api.example.com/today") calendar_data = response.json() return calendar_data.get('day_of_week', '').lower() in ['saturday', 'sunday'] def is_sunny(): # Very slow function to a low performant weather API call response = requests.get ("https://weather-api.example.com/current") weather_data = response.json() return weather_data.get('weather', '') == 'sunny' is_sunny_value = is_sunny() is_warm_value = is_warm() is_weekend_value = is_weekend() if is_sunny_value and is_warm_value and is_weekend_value: # the 3 conditions are always evaluated print("Let's go outside!") else: print("Stay at home.") Right if is_warm() and is_weekend() and is_sunny(): # the 3 conditions are evaluated in short circuit # and sorted from fastest to slowest # for a fast exit print("Let's go outside!") else: print("Stay at home.") Detection Semi-Automatic [x] You can detect slow calls using actual benchmarks. Do not consider algorithm complexity since sometimes it is unrelated to actual data distribution. (for example, optimizing an array with a few elements). Tags Performance Conclusion Find bottlenecks using Pareto rules. Optimize your code-critical sections. Relations Code Smell 140 - Short Circuit Evaluation Code Smell 145 - Short Circuit Hack Credits Photo by on Nick Abrams Unsplash The key to performance is elegance, not battalions of special cases. Jon Bentley and Douglas McIlroy Code Smell 235 - Console Side Effects You compute and log in the same place TL;DR: Avoid side effects Problems Coupling Testability Reusability Function Composition Solutions Decouple the code and avoid side-effects Inject the output destination Context Outputting to the console within an internal function generates coupling and side effects Sample Code Wrong https://gist.github.com/mcsee/c8fcd38572bce8e59bf28ceaede7a055?embedable=true Right https://gist.github.com/mcsee/1c4881a54286a827b8fc037fdd89722c?embedable=true Detection [X] Automatic Several linters warn for this usage Tags - Globals Conclusion Instead of logging directly within internal functions, a more modular and flexible approach is to have functions return values or throw exceptions when errors occur. The calling code can then decide how to handle and log these results based on the application's logging strategy. Relations [Code Smell 17 - Global Functions]) Credits Image generated by Midjourney Memory is like an orgasm. It's a lot better if you don't have to fake it. Seymour Cray Next week, 5 more smells.