惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
A
About on SuperTechFans
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
Microsoft Security Blog
Microsoft Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
博客园 - Franky
D
Docker
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
Last Week in AI
Last Week in AI
U
Unit 42
F
Fortinet All Blogs
H
Help Net Security
Blog — PlanetScale
Blog — PlanetScale
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
P
Proofpoint News Feed
月光博客
月光博客
G
Google Developers Blog

Secret Weblog

Becoming More Xee: A Modern XPath and XSLT Engine in Rust Looking for new challenges! Repeat Yourself, A Bit The Curious Case of Quentell The Humble For Loop in Rust The Humble For Loop in JavaScript Don Question Best Practices I Was a 1980s Teenage Programmer Part 5: Achieving Assembly I Was a 1980s Teenage Programmer Part 4: The Call of Assembly The Tooling Shift I Was a 1980s Teenage Programmer Part 3: MSX-2 JavaScript: when you need two ways to do it! Empowering Programming Languages Bloat and Retrofuturism Refreshing my Blog Again Random Rust Impressions Apilar: An Alife System I Was a 1980s Teenage Programmer Part 2: Olivetti M24 I Was a 1980s Teenage Programmer: the Alphatronic SolidJS fits my brain Is premature optimization the root of all evil? Framework Patterns: JavaScript edition Roll Your Own Frameworks Framework Patterns Secret Weblog Highlights Refactoring to Multiple Exit Points mstform: a form library for mobx-state-tree Seven Years: A Very Personal History of the Web
The Story of None: Part 3 - Handling It
Martijn Faassen · 2013-01-31 · via Secret Weblog

part 1 part 2 part 3 part 4 part 5 part 6

Last time...

In part 1 of the Story of None we've seen this validation function:

def validate_end_date_later_than_start(start_date, end_date):
    if end_date <= start_date:
        raise ValidationError(
            "The end date should be later than the start date.")

We've determined start_date and end_date may be None. In part 2 we've seen that we can recognize this case by using is None or is not None.

So:

  • we should consider whether None is possibility.
  • we should use value is None or value is not None to check.

Once we know that we're not out of the woods yet though: we still need to decide what to do when either of the arguments is None. This will need to be thought about and depends on the circumstances.

Requirements

So what would make sense in this case? If either start_date or end_date are None, does it make sense to validate this at all? What does an omitted date mean in this case? This depends on the application's requirements.

For the sake of the example I will make up a few simple requirements here:

  • Let's say that in this application the start and end dates define a period when a product is on the market.
  • If a start_date is None, we don't have a start date, and we'll interpret this as as far as we know now, the product has been in the market from the indefinite past, until the end date.
  • If an end date is None, we interpret this as as as we know now, the product will be on the market from the start date until the indefinite future.
  • If both are None, we assume the product has been on the market from the indefinite past to the indefinite future.

Something like that. The specification doesn't have to be perfect and it often won't be. If it isn't clear it'll be your job to find out what it should be, generally by asking someone (and perhaps giving them a few suggestions).

start_date is None

Given these requirements, how would we handle None for start_date? If the start_date is in the indefinite past, we don't have to check whether end_date is earlier than it, because we'll say the indefinite past is always earlier. (If you're not sure about this, ask someone, but in this case we are sure as we make it up ourselves.)

Let's express that in code:

def validate_end_date_later_than_start(start_date, end_date):
    if start_date is None:
        return
    if end_date <= start_date:
        raise ValidationError(
            "The end date should be later than the start date.")

end_date is None

If end_date is None, it's in the indefinite future. start_date can not be later than a date in the indefinite future, so we don't need to check then either. Let's express this in code too:

def validate_end_date_later_than_start(start_date, end_date):
    if start_date is None:
        return
    if end_date is None:
        return
    if end_date <= start_date:
        raise ValidationError(
            "The end date should be later than the start date.")

start_date is None and end_date is None

Now what if both end_date and start_date are None? A date in the indefinite past is always earlier than the indefinite future, so we're safe too and don't need to compare dates either. We can express this in code too:

def validate_end_date_later_than_start(start_date, end_date):
    if start_date is None and end_date is None:
        return
    if start_date is None:
        return
    if end_date is None:
        return
    if end_date <= start_date:
        raise ValidationError(
            "The end date should be later than the start date.")

It turns out the last bit was superfluous as turn out to handle this case correctly already anyway. That's fine and will often be the case, but not always so we do need to briefly think about this case before we stop worrying about it.

Next time we'll talk about what this pattern really is.

part 1 part 2 part 3 part 4 part 5 part 6