检查日期范围的用户输入是否按连续的时间顺序对进行

Check if user input for date ranges has been made in consecutive, chronological pairs

我用 PyWebIO 创建了一个最多包含六个日期的用户表单,每一对组成一个从开始日期 sdt 到结束日期 edt 的日期范围。前两个日期是必需的,其余四个是可选的。可以通过函数验证此表单; check_form 在我的示例中。

我想使用此功能只允许用户输入连续的、按时间顺序排列的对。

示例表格:

from pywebio import *

form = input.input_group("form", [
    input.input("Period 1 - Start",
        name="sdt_1",
        type=input.DATE,
        required=True),
    input.input("Period 1 - End",
        name="edt_1",
        type=input.DATE,
        required=True),
    input.input("Period 2 - Start (optional)",
        name="sdt_2",
        type=input.DATE),
    input.input("Period 2 - End (optional)",
        name="edt_2",
        type=input.DATE),
    input.input("Period 3 - Start (optional)",
        name="sdt_3",
        type=input.DATE),
    input.input("Period 3 - End (optional)",
        name="edt_3",
        type=input.DATE),
    ], validate = check_form)

PyWebIO 将输入排序为字典,使用名称作为键,输入作为值。

print(form) 的输出:

form = {
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-08-08',
    'sdt_3': '2023-01-01',
    'edt_3': '2023-08-08'
}

我想出了一个解决方案,可以检查时间顺序和相同数量的条目。但是,此解决方案仍然允许用户进行无意义的输入,例如只输入 sdt_1, edt_1, sdt_3, sdt_3sdt_1, edt_1, sdt_2, edt_3

的日期
def check_form(data):
    data_lst = []
    for key in data.keys():
        if data[key] != "":
            data_lst.append(data[key])
    if sorted(data_lst) != data_lst:
        return ("sdt_1", "ERROR: Entries not in chronological order.")
    if len(data_lst) % 2:
        return ("sdt_1", "ERROR: Uneven amount of entries.")

非常感谢任何帮助!

我想出了一个解决办法。将字典放入列表中,并从第二个索引开始检查前一个索引是否为空。像这样:

def check_form(data):
    data_lst = []
    data_lst_2 = list(form.values())
    for key in data.keys():
        if data[key] != "":
            data_lst.append(data[key])
    if sorted(data_lst) != data_lst:
        return ("sdt_1", "ERROR: Entries not in chronological order.")
    if len(data_lst) % 2:
        return ("sdt_1", "ERROR: Uneven amount of entries.")
    for item in data_lst_2[1:]:
        if data_lst_2[data_lst_2.index(item) - 1] == "":
            return ("sdt_1", "ERROR: Entries not consecutive.")

由于第一对是必需的,其余两对是可选的,因此您应该强制执行该逻辑。

def check_form(data):
    required_pairs = {1} # Specify all the required pairs in this set
    max_pairs = 3        # Max numbber of pairs
    data_lst = []
    for i in range(1, max_pairs+1):
        s_key = f"sdt_{i}"
        e_key = f"edt_{i}"

        # Get the data from the dict. If the key doesn't exist, treat it as an empty string
        s_val = data.get(s_key, "")
        e_val = data.get(e_key, "")

        if i in required_pairs or s_val or e_val:
            if i in required_pairs: 
                # This is a required pair and input is missing
                if not s_val: return (s_key, "ERROR: Missing required input")
                elif not e_val: return (e_key, "ERROR: Missing required input")
            elif e_val and not s_val:
                # e_key is specified but not s_key
                return (s_key, "ERROR: Uneven pair of inputs")
            elif s_val and not e_val:
                # s_key is specified but not e_key
                return (e_key, "ERROR: Uneven pair of inputs")
            
            # We didn't return an error, so this data must be valid
            data_lst.append(data[s_key])
            data_lst.append(data[e_key])

    if sorted(data_lst) != data_lst:
        return ("sdt_1", "ERROR: Entries not in chronological order")

请注意,您可以通过 if s(空字符串是假的)

来检查字符串 s 是否为空

我们来测试一下:

##### VALID INPUTS:
# Case 1: Specify all inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-08-08',
    'sdt_3': '2023-01-01',
    'edt_3': '2023-08-08'
}) == None

# Case 2: Specify only required inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '',
    'edt_2': '',
    'sdt_3': '',
    'edt_3': ''
}) == None

# Case 3.1: Specify required inputs and one optional input
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-01-08',
    'sdt_3': '',
    'edt_3': ''
}) == None

# Case 3.2: Specify required inputs and one optional input
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '',
    'edt_2': '',
    'sdt_3': '2021-01-01',
    'edt_3': '2021-01-08',
}) == None


#### INVALID INPUTS
# Case 4.1: Skip required inputs
assert check_form({
    'sdt_1': '',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-08-08',
    'sdt_3': '2022-01-01',
    'edt_3': '2022-01-08',
}) == ('sdt_1', "ERROR: Missing required input")

# Case 4.2: Skip required inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-08-08',
    'sdt_3': '2022-01-01',
    'edt_3': '2022-01-08',
}) == ('edt_1', "ERROR: Missing required input")

# Case 4.3: Skip required inputs
assert check_form({
    'sdt_1': '',
    'edt_1': '',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-08-08',
    'sdt_3': '2022-01-01',
    'edt_3': '2022-01-08',
}) == ('sdt_1', "ERROR: Missing required input")

# Case 5.1: Incomplete pair of optional inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '',
    'edt_2': '2021-08-08',
    'sdt_3': '2022-01-01',
    'edt_3': '2022-01-08',
}) == ('sdt_2', "ERROR: Uneven pair of inputs")

# Case 5.2: Incomplete pair of optional inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '',
    'sdt_3': '2022-01-01',
    'edt_3': '2022-01-08',
}) == ('edt_2', "ERROR: Uneven pair of inputs")

# Case 5.3: Incomplete pair of optional inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-08-08',
    'sdt_3': '',
    'edt_3': '2022-01-08',
}) == ('sdt_3', "ERROR: Uneven pair of inputs")

# Case 5.4: Incomplete pair of optional inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-08-08',
    'sdt_3': '2022-01-01',
    'edt_3': '',
}) == ('edt_3', "ERROR: Uneven pair of inputs")

# Case 5.5: Incomplete pair of optional inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '',
    'sdt_3': '2022-01-01',
    'edt_3': '',
}) == ('edt_2', "ERROR: Uneven pair of inputs")

# Case 5.6: Incomplete pair of optional inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '',
    'edt_2': '2021-08-08',
    'sdt_3': '',
    'edt_3': '2022-08-08',
}) == ('sdt_2', "ERROR: Uneven pair of inputs")

# Case 6.1: Non-chronological inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2019-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '2021-08-08',
    'sdt_3': '2022-01-01',
    'edt_3': '2022-08-08',
}) == ('sdt_1', "ERROR: Entries not in chronological order")

# Case 6.2: Non-chronological inputs
assert check_form({
    'sdt_1': '2020-01-01',
    'edt_1': '2020-08-08',
    'sdt_2': '2021-01-01',
    'edt_2': '2022-08-08',
    'sdt_3': '2022-01-01',
    'edt_3': '2022-08-08',
}) == ('sdt_1', "ERROR: Entries not in chronological order")