I appreciate the sentiment behind this post, but the use of FizzBuzz as an example inexorably leads to comparisons with the infamous https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition
I feel like adding the logging and tests makes this borderline unreadable and crowded looking. I might just be dumb though.
The perfect has always been the mortal enemy of the pretty good.
Looks like a huge pile of YAGNI, except possibly for the tests.
I think I might leave the logging and tests out. They’re unlikely to be exercised on the simple script.
The other stuff is fast to write and doesn’t introduce significant readability burden.
I have a process for taking python scripts from prototype to production that I think strikes a better balance.
I wrote it up: Practical production python scripts
the commit log makes a reasonable summary:
Thanks for sharing. I have added a link to your post at the bottom of mine.
The only part I disagree with is except Exception as e: log(e).
except Exception as e: log(e)
It strips the exception of its context, so when something unexpected happens, you may not even know where to start looking for the cause. Printing a traceback can save a lot of time.
Also, if a program has some global state, it may be better to just let it crash when something it doesn’t know how to handle happens, than allow it to end up in a messed up state without anyone noticing.
logger.exception() will print a traceback. The reason for catching and “logging” the exception is to also get it through syslog if you enable syslog output.
Ah, sorry, I missed which exact logging.* call it makes somehow. Then I agree.
I write a lot of rarely-read scripts for myself, and I usually write them in a literate programming style so I can go back and understand my frame of mind. I rarely write tests for my scripts, though.
You can, but can a coworker do the same?
I often use python as glue code, to tie different legacy systems to gether, using webscraping and such. When writing documentation for these types of scripts I usually struggle to explain the rationale behind the code deeper then “because these are the parameters the system expects”.
For slightly more involved scripts it might help to turn them into tiny packages with a setup.py and requirements.txt file.
Adding things like command line options might make things harder, rather than easier, because now users have a slew of options they may never need. In the worst cases you get cases of “run foo.py with this list of magic flags”, which doesn’t strike me as easier than “run foo.py”.
In many cases there are only 2 or 3 possible set of flags, so I create foo-dothis.py and foo-dothat.py, rather than one script with flags. Fewer moving parts, fewer things that can go wrong, easier to use, easier to modify.
The biggest problem is usually “what does this even do?” and that’s fixed by a simple comment. Most of then time, nothing more is needed. Complexity comes with its own problems.