Categories
Uncategorized

Fifth Post

Welcome back to another blog post! My team is deep into building our prediction model with two core technologies that we have been using: SQLAlchemy and PostgreSQL. Below, I’ll share why SQLAlchemy has become my favorite tool and why PostgreSQL is a close runner-up (despite some frustrations), and how both are shaping my teams development process.

Love-Hate Relationship: SQLAlchemy & PostgreSQL
SQL-Alchemy is definitely my favorite technology that I have used since beiginging work on this project, as it is an ORM-Object-Relational Mapper-that allows me to work with databases in a Pythonic way (I like Python). Instead of writing raw SQL (Yuck), I get to define classes that map directly to tables in PostgreSQL, which keeps my code cleaner and more maintainable, as well as my sanity maintains for another day. In particular, I love how relationships between tables can be managed straightforwardly once everything is set up correctly.

In contrast PostgreSQL is an incredibly robust and capable, but it can be cumbersome to configure initially. Creating roles, setting permissions, and learning its advanced features (like partitioning, custom data types, etc.) can be overwhelming. Yet, for production-level applications where performance and reliability matter, PostgreSQL really shines, once our team of course has done the legwork to get everything running smoothly.

Challenges and Potential Improvements
While I have been enjoying using SQLAlchemy, the learning curve certainly was steep. Getting sessions, relationship configurations, and some of the more advanced querying patterns took me a while to learn. I would love clearer error messages on models or misconfigured relationships, those cryptic stack traces can be hard to unravel.

With PostgreSQL, I would like a smoother setup process. Perhaps a guided setup wizard to ease the early stage of setting up roles, databases, and security policies.

Learning Curves
The ORM approach in SQLAlchemy was the hardest to get used to for me. Once I got over that learning curve, it has been a huge timesaver. The SQL part of PostgreSQL has been relatively easy. If you know the basics of SQL, then simple queries and CRUD operations are pretty straightforward.

If I Could Start Over
I would have probably started with a simpler database like SQLite, just to prototype quickly. Then at some other point I’d migrate to PostgreSQL for the rich features and scalability. Also, I wish I had used Docker from the very beginning to containerize PostgreSQL. It would have saved me from the hassle of local installations and configuration quirks across different machines.

Categories
Uncategorized

Fourth Post

Hello there!

Todays post we will be looking at two topics, clean code, and code-smells!

Looking at the articles, “What Is Clean Code? A Guide to Principles and Best Practices” (clean code) and “When and Why Are Smells Introduced?” (code smells), I will be looking at practices that I want to start as well as stop in order to write better, more maintainable code. Let me share with you some of the things I learned from these articles.

What I’m Starting: Writing Small, Single-Responsibility Classes
While reading the article clean code, the Single Responsibility principle, SRP, stood out to me. It states that “every class should have a single, focused purpose.” (Codacy, 2023) this idea reduces complexity, makes testing easier, and improves maintainability. On the other hand, code smells article identifies that Blob Classes or classes handling too many responsibilities usually are created at the start of the project and remain problematic (Verwijs, 2021). It explains, “Classes that are poorly designed tend to be smelly right from the beginning and continue to be so for a long time” (Verwijs, 2021).

With SRP, we can actually be proactive at avoiding Blob Classes and laying down a good foundation for clean and scalable software. We can look at this with a code example. Suppose we are developing an e-commerce application and need to handle customer orders, storing them in a database. In that case, one Blob Class approach can combine these responsibilities into one class, which over time will create a big mess.

Code Smell Example: Blob Class

class OrderManager:
    def mark_as_paid(self, order_id):
        print(f"Order {order_id} marked as paid.")

    def save_to_database(self, order_data):
        print("Order saved to the database.")

    def generate_invoice(self, order_id):
        print(f"Invoice generated for order {order_id}.")

This may be fine for the moment, but as time goes on and we decide to add more features-such as sending notifications or handling refunds-it will inflate the class. This is a violation of SRP and brings about complexity.

Clean Code Example: SRP in Action
Here’s a refactored design using SRP:

class OrderService:
    def mark_as_paid(self, order_id):
        print(f"Order {order_id} marked as paid.")

class DatabaseService:
    def save_order(self, order_data):
        print("Order saved to the database.")

class InvoiceService:
    def generate_invoice(self, order_id):
        print(f"Invoice generated for order {order_id}.")

Each class has a single, well-defined responsibility: managing orders, handling database interactions, or generating invoices. This modular design makes the code easier to maintain and test as the application grows.

What I’m Avoiding: Rushed Changes Before Deadlines
The Code Smells article highlights that most smells, such as Spaghetti Code, are introduced just before a release (Verwijs, 2021). The study found that “89%-98% of code smells were introduced in the month before a major release” (Verwijs, 2021). This aligns with the Clean Code article, which warns against sacrificing clarity for speed: “Quick fixes prioritize short-term wins over long-term stability” (Codacy, 2023).

Using another code example scenario we can look at this issue. Imagine having to implement order processing logic quickly when a release date is getting closer. In the absence of due planning, rushed changes can lead to Spaghetti Code.

Code Smell Example: Spaghetti Code

def process_order(order_id, order_data):
    if order_id:
        if is_valid(order_data):
            if not is_paid(order_id):
                mark_as_paid(order_id)
                if save_to_database(order_id, order_data):
                    if generate_invoice(order_id):
                        print("Order processed successfully.")
                    else:
                        print("Invoice generation failed!")
                else:
                    print("Database save failed!")

This is too nested and unclear a structure to read, debug, or extend.

Clean Code Example: Modular Approach
We can avoid Spaghetti Code by breaking the logic into smaller functions:

def process_order(order_id, order_data):
    if not is_valid(order_data):
        print("Invalid order data.")
        return

    if is_paid(order_id):
        print("Order already paid.")
        return

    mark_as_paid(order_id)
    save_order(order_id, order_data)
    generate_order_invoice(order_id)

def save_order(order_id, order_data):
    print(f"Saving order {order_id} to database...")

def generate_order_invoice(order_id):
    print(f"Generating invoice for order {order_id}...")

This is a modular approach, following the principles of clean code, improve readability, and ease debugging.

In conclusion the few key takeaways are, write small single-responsibility classes early in a project. As well as avoid rushed last-minute changes that often lead to the creation of code smells (Verwijs, 2021). Clean code is not just about how it looks; it’s about creating maintainable, scalable, and error-resistant systems (Codacy, 2023).

References

Codacy. (2023, December 19). What Is Clean Code? A Guide to Principles and Best Practices. Blog.codacy.com. https://blog.codacy.com/what-is-clean-code

Verwijs, C. (2021, December 20). In-Depth: What Scientific Research Has To Say About Technical Debt And Code Smells. Medium; The Liberators. https://medium.com/the-liberators/on-technical-debt-and-code-smells-ae8de66f0f8b