Postel's law:
Be conservative in what you do, be liberal in what you accept from others.
"Lazy" code (per The Pragmatic Programmer):
Be strict in what you will accept before you begin, and promise as little as possible in return.
I'm developing a finance (asset pricing, etc.) framework for Python. Question: when designing the API for the framework, what factors should I consider when I assess the tradeoff between being strict and being liberal re: inputs?
Example:
I have the following method that downloads stock prices from Yahoo.
def historical_prices(ticker, start=None, end=None, data='d', convert=True):
# Do stuff
For the date arguments (start
& end
), I could:
- Be strict, and only allow a string of ISO format YYYY-mm-dd, or
- Be liberal and accept datetime objects, strings (of specified formats), etc.
3 Answers 3
It is going to be easier to accept the strict input, and reject any other forms, because you will have only one case to consider.
It really depends on your customers' requirements. Do they need flexibility of input, i.e. Internationalization, or can they work comfortably with a single format.
-
I'd argue that date parsing is almost always better in the front end, particularly because it's likely that you may even never have to parse potentially untrustworthy dates, if they're captured through a widget anyway.NeilG– NeilG2023年03月08日 00:41:27 +00:00Commented Mar 8, 2023 at 0:41
Be strict in what you accept. The be liberal in what you accept, and be strict what you return, is based on a world of independent agents, for instance SMTP servers. If a mail server sends you a faulty email, and you can rescue it, that's better than a cryptic error to the sender of the mail.
However, when you're designing an API to be consumed by other programmers, it's different story. They get immediate feedback when they provide wrong input. The other option of guessing what they mean is very dangerous. If you accept 14-12 as december fourtheenth, and 14-10 as october fourteenth, what will your program do with 10-12? Better to be strict, and error with one of them, that way your program will behave in a predictable manner, which is much more important than being able to accept everything.
-
what will your program do with 10-12?
Don't you mean like 10-13, Mr. markijbema?SomeGuyWithFingers– SomeGuyWithFingers2012年07月30日 20:19:58 +00:00Commented Jul 30, 2012 at 20:19 -
1No, actually not, because 10-12 has two possible interpretations, and 10-13 does not. Therefore I cannot deduce what it will do. If your program is strict though it will have one interpretation, and 10-13 wil either be the thirteenth of october, or crash. Predictable and usable, imho.markijbema– markijbema2012年07月31日 09:01:47 +00:00Commented Jul 31, 2012 at 9:01
I would code the main function with a specific format as the input. If there is a request to add more formats etc then create a function to overload the name that converts the date object etc into your format before calling your main function.
datetime.date
objects instead?datetime.date
, then call the function. Question still stands even if I switched todatetime.date
: do I just allowdatetime.date
or also allow strings?