Normalizer¶
Purpose¶
When sharing code, a large amount of code is usually dedicated to processing the arguments of the functions or methods to check their value and normalize it to a standard format.
The python language offers the ability to accept a large
range of input type on a unique function through duck typing.
This leads to a better integration of the different objects
at stake, for instance to use a xarray.Dataset
as a list
of dates. TODO: elaborate on this.
CliMetLab offer predefined shortcuts to
implement this. The short API aims to address 80% of
the use cases using the @normalize_args
decorator.
The longer forms aims to tackle specific needs.
Compare the following four codes snippets:
Boilerplate code¶
# Boilerplate code (extract)
def __init__(self, date, option):
if date is None:
date = DEFAULT_DATE_LIST
if isinstance(date, tuple):
date = list(date)
if not isinstance(date, list):
date = [date]
for d in date:
check_date_is_sunday(d)
if not option in VALID_OPTIONS:
raise ValueError(f"option={option} invalid")
(...)
(more check and transformations)
(...)
do_stuff(date, option)
Using CliMetLab short form API¶
from climetlab.normalize import normalize_args
@normalize_args(date="date(%Y%m%d)", option=["foo", "bar"])
def __init__(self, date, option):
do_suff(date, option)
Using CliMetLab medium-range API¶
from climetlab.normalize import normalize_args, Date, Enum
@normalize_args(date=Date("%Y%m%d", single=False, valid=DEFAULT_DATE_LIST),
option=Enum(["foo", "bar"])
def __init__(self, date, option):
do_suff(date, option)
Using CliMetLab fine-control API¶
Todo
The fine-control API is not implemented.
from climetlab.normalize import ArgNormalizer, Date, Enum
norm = ArgNormalizer()
norm.add_argument("date", Date("%Y%m%d", single=False, valid=DEFAULT_DATE_LIST))
norm.add_argument("option", Enum(["foo", "bar"])
norm.available(date=DEFAULT_DATE_LIST, option=["foo", "bar"])
norm.not_available(date="20211231", option="bar"])
@norm
def __init__(self, date, option):
do_suff(date, option)
The following table lists the available normalizer:
Normalizer | Trigger | Example |
---|---|---|
Enum | tuple | option=("a", "b")
option=Enum("a", "b") |
EnumList | list | option=["a", "b"]
option=EnumList("a", "b") |
Date | “date(” | option="date("%Y%m%d")
option="Date("%Y%m%d") |
DateList | “date-list(” | option="date-list("%Y%m%d")
option="DateList("%Y%m%d") |
bounding-box-normalizer | “bounding-box(” | TODO |
Enum¶
The Enum
normalizer pre-process the argument provided when
calling the function, modifies it if needed, and provides a normalised
value to the function. It ensures that the value in the function is an
element of the list provided.
@normalize_args(option=Enum("a", "b"))
def f(self, option):
assert option in ["a", "b"]
print(option)
>>> f("a")
"a"
>>> f(None)
MissingArgument
Shortcut: An Enum
normalizer is created when a tuple is assigned
to a parameter in @normalize_args.
@normalize_args(option=("a", "b"))
EnumList¶
The EnumList
normalizer pre-process the argument provided when
calling the function, modifies it if needed, and provides a normalised
value to the function. It ensures the following:
- The value (provided to the function) is a list.
- Each element of this list belong to the list provided.
- If None was provided by the user, the full list is used.
@normalize_args(option=EnumList("a", "b"))
def f(self, option):
for o in option:
assert o in ["a", "b"]
print(option)
>>> f("a")
["a"]
>>> f(None)
["a", "b"]
Shortcut: An Enum
normalizer is created when a list is assigned
to a parameter in @normalize_args.
@normalize_args(option=["a", "b"])
def f(self, option):
Date¶
Date and time argument used a lot in Climate and Meteorology code.
The Date
normalizer .
@normalize_args(date=Date("%Y%m%d"))
def f(self, date):
Shortcut: An Date
normalizer is created when a string
starting with “date(” is assigned to a parameter in @normalize_args.
@normalize_args(date="date(%Y%m%d)")
DateList¶
The DateList
normalizer is to the Date
normalizer what the EnumList
is to Enum
.
@normalize_args(date=DateList("%Y%m%d"))
def f(self, date):
Shortcut: An DateList
normalizer is created when a string
starting with “date-list(” is assigned to a parameter in @normalize_args.
@normalize_args(date="date-list(%Y%m%d)")
Todo
Add more normalizers.
For instance, for the “parameter” argument such as `t2m`
or `tp`
.