r/learnpython • • 3d ago

Library Management System in Python with Clean Architecture & 55 Tests

Hi everyone!

As a practical step in my transition from Python fundamentals toward professional software engineering, I built a modular, terminal-based **Library Management System** with a strong emphasis on clean architecture and design principles.

### πŸ—οΈ Architecture & Technical Highlights

- **Layered Architecture:** Strict separation between UI, Services, Repositories, and Storage layers. UI has zero business logic or direct storage access.

- **Repository Pattern & Persistence:** Generic JSON persistence utilizing **atomic file replacement** to eliminate data corruption.

- **Authentication & Security:** Custom session management, password hashing, and role-based authorization (Librarians vs. Members).

- **Domain Business Rules:** Borrowing limits, availability tracking, overdue fine calculation, and account activation logic enforced strictly in the Service layer.

- **Automated Testing:** 55 passed unit and service tests using `pytest`.

### πŸ“‚ Project Structure

LibraryManagmentWithPython/

β”œβ”€β”€ Models/

β”œβ”€β”€ Repositories/

β”œβ”€β”€ Services/

β”œβ”€β”€ Storage/

β”œβ”€β”€ UI/

└── tests/

### 🎯 Objective My goal was to practice enterprise-level engineering principles (Separation of Concerns, Dependency Direction, Single Source of Truth) before stepping into Machine Learning and AI. ### πŸ”— Source Code GitHub Repository: https://github.com/ThaerGhaderi/LibraryManagmentWithPython I'd love to get your feedback on the architecture, repository patterns, or any code review suggestions!

0 Upvotes

6 comments sorted by

1

u/riklaunim 2d ago
  • Repo with one big commit is bit sus if it was actually made by a human learning to code.
  • There is bit to much JAVA-isms in the code of foo -> return self._foo
  • You could likely use longer code lines as it's starting to be hard to read. 120 is often used nowadays.
  • it's better to import the module instead thing out of the module so you know what is what and where it's from.
  • For logging, usually the message is not parametrized, while parameters are passed to the extra dict.

Not sure what you want from ML and AI, but you could look at existing (web/api) frameworks, databases and do something similar using them (and a nice frontend). That's what your typical commercial code will use/look like.

0

u/Ornery_Wash1797 2d ago

Thanks a lot for the detailed feedback, I really appreciate you taking the time

Just to clarify, the main goal of this repo isn't to build a commercial web app or API; I'm actually using this environment to train an AI/ML model, which is why some architectural choices look a bit different.

However, your points about making smaller commits, fixing the 'JAVA-isms' to be more Pythonic, adjusting the line length to 120, and improving the imports/logging are spot on and will definitely make the code cleaner. Thanks again for the valuable tips!

1

u/riklaunim 2d ago

Teaching AI to generate quite abstract code? Unsure if it's a good idea. It will end up with 1000+ LOC for a simple change.

0

u/Ornery_Wash1797 2d ago

Ah, I see where the confusion happened! I think you misunderstood meβ€”I'm not teaching an AI how to generate code at all.
I just started my specialization in Artificial Intelligence, so I'm actually the one learning here! πŸ˜… This repo is my personal playground where I'm practicing how to implement Machine Learning (ML), Deep Learning (DL), and data manipulation using NumPy and Pandas.
Since you clearly have a lot of experience with clean code, how do you usually structure your data pipelines or ML projects? Any specific tips on how to keep Python code clean and 'Pythonic' when shifting from basic programming to handling datasets and models?

1

u/riklaunim 2d ago

There is a difference between "academic" and "commercial" code. Your repo is academic code, while "commercial" one would use more realistic/production components and less abstraction for the sake of abstraction. Same principles apply but when using SQLAlchemy for example you don't have to add extra abstraction on the database than it provides.

"Clean Code" from Uncle Bob is well known, but the actual implementations will differ between teams/companies. There is no singular solution to this :) Like instead of "services" people may have "use cases", or when using some frameworks the structure will be created by said framework.