greg troszak

validation

There are a few different forms of validation:

Syntactic validation ensures that you are receiving input that is well-formed. If I have a function that takes a name and prints Hello ${name}, name better be a string (or something that can be coerced into a string).

def say_hello(name):
    if not isinstance(name, str):
        raise TypeError("Name must be a string")
    print(f"Hello {name}")

# This will raise a TypeError
say_hello(123)

Semantic validation ensures that input has meaning. Suppose our program is rude and only says hello to people we know. We’d need to check that we know them before saying hello and throw an error if we don’t. If we don’t know them, they are meaningless to our program (so rude).

known_names = {"Alice", "Bob", "Charlie"}

def say_hello(name):
	# Syntactic
    if not isinstance(name, str):
        raise TypeError("Name must be a string")
	# Semantic
    if name not in known_names:
        raise ValueError(f"We don't know {name}")
    print(f"Hello {name}")

# This will raise a ValueError because "Dave" is not in known_names
say_hello("Dave")

Pragmatic validation ensures that the input is appropriate and makes sense given the current context or state of the application. Imagine our program is supposed to only greet people we know during business hours. If someone tries to greet outside these hours, we should reject the input even if it’s syntactically and semantically valid.

from datetime import datetime

known_names = {"Alice", "Bob", "Charlie"}

def is_business_hours():
    current_hour = datetime.now().hour
    return 9 <= current_hour < 17

def say_hello(name):
    if not isinstance(name, str):
        raise TypeError("Name must be a string")
    if name not in known_names:
        raise ValueError(f"We don't know {name}")
    if not is_business_hours():
        raise ValueError("Cannot greet outside of business hours")
    print(f"Hello {name}")

# This will raise a ValueError if called outside business hours
say_hello("Alice")

where to validate?

Ideally, you should try to keep your core logic focused, which means having all of this validation there would be awful. Instead, you should use the layers around your core logic to protect it from this cruft. In an ideal world: