Reputation: 649
I am trying to write an argument (for argparse) in which, I am trying to define the inputs in terms of hours or days.
For example:
def setup_args():
....
parser.add_argument(
"--time",
type=str,
help="Define the time period (only hours or days). Eg. 3h or 3d"
)
def time_input(user_input):
if user_input.endswith('h'):
...
# using datetime module to forward current time X hours later
elif user_input.endswith('d'):
...
# I may specify it to a max 2 days.
# using datetime module to forward current time X days later
While the function I wrote works, I am wondering if there is a better way to approach this, or is using endswith
the only way to go?
Upvotes: 4
Views: 1915
Reputation: 231395
A function like this, can be used as a type
in argparse
. It could also be used after parsing:
def period(astr):
if astr.lower().endswith('h'):
units = 'timedelta64[h]'
elif astr.lower().endswith('d'):
units = 'timedelta64[D]'
else:
raise argparse.ArgumentTypeError('wrong time units')
return np.array(astr[:-1], dtype=units)
I defined it to return a numpy
timedelta64
array, in part because I'm more familiar with it than with the Python timedelta
, and it is easy to specify the time units:
In [249]: period('4h')
Out[249]: array(4, dtype='timedelta64[h]')
In [250]: period('3d')
Out[250]: array(3, dtype='timedelta64[D]')
tolist
will extract it from the array and return a timedelta
object.
In [251]: period('3d').tolist()
Out[251]: datetime.timedelta(3)
In [253]: period('3h').item()
Out[253]: datetime.timedelta(0, 10800)
The function could be changed to work with timedelta
directly.
A parser could be:
In [239]: parser = argparse.ArgumentParser()
In [240]: parser.add_argument('--time', type=period, help='time delta');
testing:
In [241]: parser.parse_args('--time 3d'.split())
Out[241]: Namespace(time=array(3, dtype='timedelta64[D]'))
In [255]: parser.parse_args('--time 4h'.split())
Out[255]: Namespace(time=array(4, dtype='timedelta64[h]'))
errors:
In [256]: parser.parse_args('--time 4m'.split())
usage: ipython3 [-h] [--time TIME]
ipython3: error: argument --time: wrong time units
In [257]: parser.parse_args('--time 4.34d'.split())
usage: ipython3 [-h] [--time TIME]
ipython3: error: argument --time: invalid period value: '4.34d'
Upvotes: 2
Reputation: 26900
Maya might work for you:
>>> maya.when("in 1H").datetime()
datetime.datetime(2018, 6, 27, 22, 16, 42, 371621, tzinfo=<UTC>)
>>> maya.when("in 1 day").datetime()
datetime.datetime(2018, 6, 28, 21, 16, 42, 371621, tzinfo=<UTC>)
You may even specify arbitrary time values and not limit to only hours or days, which causes your app to be even more flexible:
>>> maya.when("now").datetime()
datetime.datetime(2018, 6, 27, 21, 20, 7, 409348, tzinfo=<UTC>)
>>> maya.when("in 1 hour 2 minutes").datetime()
datetime.datetime(2018, 6, 27, 22, 22, 7, 825372, tzinfo=<UTC>)
P.S. Maya is powered by dateparser. Although you can use dateparser straight out of the bat to handle everything, I think Maya will prove more useful.
Upvotes: 4