I gave myself a hard rule for this project: the entire shop program had to stay under 600 lines. One file, everything included, database, billing, search, reports, receipts, under 600. It sounds arbitrary, and it partly was, but that ceiling turned out to be the best teacher in the whole build, because a line limit is really a duplication detector.
Here is what the limit exposed immediately. Every screen of the app builds labelled input fields, a label plus an entry, laid out in a grid. Written naively, that is four lines per field, and the app has dozens of fields. My first product form alone spent forty lines saying label, entry, label, entry. Under a 600-line budget, that pattern is robbery. The fix is the oldest one in programming, notice the repetition and fold it into a function:
def add_field(self, parent, label, row):
ttk.Label(parent, text=label).grid(row=row, column=0,
sticky='w', padx=8, pady=4)
var = tk.StringVar()
ttk.Entry(parent, textvariable=var, width=28).grid(row=row, column=1,
padx=8, pady=4)
return var
Now every field everywhere is one line, and the returned StringVar is the handle for reading it later:
self.p_name = self.add_field(form, "Product Name", 0)
self.p_article = self.add_field(form, "Article Number", 1)
self.p_cost = self.add_field(form, "Cost Price", 2)
self.p_sell = self.add_field(form, "Selling Price", 3)
self.p_stock = self.add_field(form, "Stock Quantity", 4)
Five readable lines instead of twenty, and, the part that matters more than the count, one place to change. When I decided every field needed more padding, I edited add_field once and the entire application updated. The same folding happened to database work, one helper that executes a query and commits, replacing the connect-execute-commit ritual scattered everywhere, and to money formatting, one function that renders PKR amounts, so every price on every screen formats identically.
What the limit really taught me is what those helpers are: the vocabulary of the application. By the end, screens read like sentences, add_field, run_query, money, preview_receipt, and a new screen assembled itself from words that already existed. That is also, honestly, where the limit’s arbitrariness shows, 600 is not sacred, and a rule like it should bend before it makes code worse. Mine never had to bend, which was the proof of how much of my code had been repetition wearing a disguise.
A few things people ask me about this
How do I stop repeating label-and-entry code in Tkinter? Write a helper that creates the label and entry, grids them, and returns the StringVar. Every form field becomes one line and one point of change.
Is a line limit actually good practice? As a learning constraint, absolutely, it forces you to see repetition. As a permanent law, no, clarity beats count, let the limit push you toward reuse, not toward cryptic compression.
Next
That was the last technical wall. In the final post of this series I step back and look honestly at what building software for a real shop, with real money on the counter, actually taught me. That is the finale.

