x y
x y

Reputation: 1029

Python argparse optional custom date + time with nice usage message

As an optional argument in my Python 3.8 app, I would like to offer a convenient conversion from date+time to GPS week + time-of-week that exits after printing the converted result.

parser.add_argument('-c', '--convert-date-time-to-gps', nargs=7, type=lambda d: datetime.strptime(d, '%y %m %d %H %M %S %f'), \
    help=f'use "YY[YY] M[M] D[D] h[h] m[m] s[s] ms" as date time format to be converted to gps date, e.g. "{datetime.now().strftime("%Y %m %d %H %M %S %f")}"')
# GPSTime conversion follows here..

As you can see in the help argument, the user should be able to enter either "2021 08 13 23 08 00 42" but also "21 8 13 23 8 0 42" as comandline input.

What would be the most convenient way to reach this? Especially, to avoid the ugly usage message like

usage: main [-h] [-m {run,test,debug}] [-g] [-v]
        [-c CONVERT_DATE_TIME_TO_GPS CONVERT_DATE_TIME_TO_GPS CONVERT_DATE_TIME_TO_GPS CONVERT_DATE_TIME_TO_GPS CONVERT_DATE_TIME_TO_GPS CONVERT_DATE_TIME_TO_GPS CONVERT_DATE_TIME_TO_GPS]
        [project_config]

with the CONVERT_DATE_TIME_TO_GPS item repeated 7 times?

Upvotes: 0

Views: 376

Answers (2)

x y
x y

Reputation: 1029

Thanks to @hpaulj for the metavar= hint, and following the answer from @Andrew I came up with the solution:

    parser.add_argument('-c', '--convert_date_time_to_gps', nargs=7, metavar='_',\
    help=f'use "YY[YY] M[M] D[D] H[H] M[M] S[S] MS" as date time format to be converted to gps date, e.g. "{datetime.now().strftime("%Y %m %d %H %M %S %f")}"')
    ...
    if args.convert_date_time_to_gps:
        convert_datetime_to_gps(args.convert_date_time_to_gps)

def convert_datetime_to_gps(dt):
    dt = [int(txt) for txt in dt]
    y = dt[0] if dt[0] > 2000 else dt[0] + 2000
    val = datetime(y, dt[1], dt[2], dt[3], dt[4], dt[5], dt[6])
    gt = GPSTime.from_datetime(val)
    if CONSIDER_LEAP_SECONDS:
        gt = gt + LeapSeconds.get_leap_seconds(gt)

    print(f'Convert {dt} to datetime {val} to {gt}')

Upvotes: 0

Andrew
Andrew

Reputation: 156

If you take 7 args you have to process each one as that type, so really just use one arg as a string and the users put quotes around the date. EG

... -c "2021 08 13 23 08 00 42"

When using one string then the lambda is processing only one date format. So different year formats are not possible. Use a function instead of the lambda and try different decodes in the function or as has been commented parse an ISO date. Its best to parse the date format the users are most likely to use though and you know that best.

If you want to take 7 numbers then you'll need to collect the given list and process it after the initial parse_args(). If there is a problem you can raise a parser.error(message). As has been commented you can set metavar="N" and you will see 7 'N's

Upvotes: 1

Related Questions