Why Your First Functions Should Do Only One Thing
A beginner's first few functions almost always try to do genuinely too much at once, calculate a value, print a result, and save it somewhere, all crammed into one single function because splitting it up feels like genuinely unnecessary...

A beginner's first few functions almost always try to do genuinely too much at once, calculate a value, print a result, and save it somewhere, all crammed into one single function because splitting it up feels like genuinely unnecessary extra work. This specific habit causes considerably more real confusion later than it saves time now, and understanding why single-purpose functions actually matter changes how quickly debugging gets easier as programs grow.
A function that does one thing is genuinely easier to actually test
A function that only calculates a value and returns it can be tested directly by checking whether the actual output matches what you genuinely expected for a given input, with no real need to also check whether it printed the right thing or saved to the correct real file at the same time. Splitting printing and saving into separate real functions means each one can be verified independently, which considerably narrows down where an actual bug genuinely lives when something eventually goes wrong.
Combined functions genuinely hide where a real bug actually lives
When a function calculates, prints, and saves all together, and the saved real file ends up wrong, you genuinely cannot tell from the outside whether the actual calculation was wrong, or whether the saving step itself introduced the real error, without stepping through the entire combined function line by line. This connects to how to get unstuck on a problem without peeking at the answer, breaking a function into single-purpose pieces is itself a genuinely powerful debugging technique, because it turns one confusing combined problem into several smaller, considerably more specific questions you can actually answer one at a time.
Single-purpose functions are genuinely easier to reuse later
A function that only calculates something, with no printing or saving built in, can genuinely be reused in a completely different real context later, a web page, a test script, a different output format, without dragging along behavior you specifically do not want in that new real situation. A combined function that always prints cannot be reused anywhere printing is not genuinely wanted, which forces you to either duplicate code or rewrite the function entirely just to change one small real piece of its actual behavior.
Single-purpose functions genuinely make a good, clear name considerably easier to choose
A function that genuinely only calculates something can be named directly and clearly after that one specific job, calculate_total, while a combined function doing three genuinely different things forces you to either pick a genuinely vague name or cram multiple distinct actions into one awkward real name. This connects to what to actually learn first when starting from zero, naming things clearly is itself a genuine early coding skill worth building deliberately, and single-purpose functions make that specific skill considerably easier to actually practice well from the very start.
Where I disagree with how some beginner tutorials introduce functions
Some beginner tutorials introduce functions purely as a way to avoid typing the same code twice, which is technically true but genuinely misses the actual more important real reason functions matter. I think this framing undersells the real skill, the genuine goal is not just avoiding repetition, it is organizing a program into small, independently understandable, independently testable pieces, and a tutorial that only emphasizes repetition avoidance leaves out the actual real habit that makes larger programs genuinely manageable later.
A practical way to actually practice this habit early
When writing a new function, ask directly whether it is doing more than one genuinely distinct job, calculating, then separately printing, then separately saving. Split any function doing multiple distinct real jobs into separate functions, each named specifically for its one actual purpose. Test each small function independently before combining them, confirming each piece genuinely works correctly on its own first. And when debugging later, use this same real split to narrow down exactly which specific piece of a larger combined process is actually causing the problem. This habit genuinely compounds as programs grow larger, a codebase built from small, clearly named single-purpose functions stays genuinely readable long after a codebase built from combined functions has become a real tangle nobody wants to touch. Building this habit early, on genuinely small practice programs, means it is already second nature by the time your actual real projects grow large enough for the difference to genuinely matter. Practicing it now, even on a tiny program that only you will ever see, is genuinely worth the small extra effort it takes to split things apart correctly, and it genuinely pays for itself the very first time you have to actually fix a bug that a combined function would have genuinely hidden from you entirely, buried somewhere inside a single block doing three real jobs at once, with no genuine way to tell which one was actually responsible.
More in Python and Practice
Python and Practice
How to Practice Python With Small Daily Exercises
People learn to code the way they learn an instrument, through regular small practice rather than occasional marathon sessions.
Python and Practice
Common Python Mistakes New Coders Repeat and How to Fix Them
I have watched a lot of beginners work through their first few weeks of Python, and the mistakes rarely surprise me anymore.
Python and Practice
How to Get Unstuck on a Practice Problem Without Peeking
Every programmer gets stuck. Beginners get stuck on loops and syntax errors; experienced developers get stuck on tricky bugs...