编程竞赛就像输入验证器

时间:2013-12-30 19:35:56

标签: python regex validation

我正在使用自己的框架来生成输入,验证它们并对它们运行一组解决方案以检查它们是否完全相同。您可以在https://bitbucket.org/danielmaxx/judge-tools上查看该框架。

现在它工作正常,但我正在寻找一种更好的方法来定义验证器而不是使用复杂的正则表达式。我正在考虑使用某种语言来输入规范,更容易编写并且更易读。对于那些不了解ACM-ICPC输入标准的人来说,它就像是:

2
3 8
3
abc def ghi
4
8 44 6 6
2 45 96 20
21 4 64 14
6 66 78 12

其中可以解释为“将有一个整数N表示玩家数量的行。下一行将包含N个整数,表示玩家的年龄。下一行将包含一个整数M,表示可能选择的名称,然后,下一行将包含由空格分隔的M个字母数字字符串。最后,带有整数K的行将表示关系矩阵。以下K行将包含矩阵的a_ij元素的K个整数。“

由于读取输入可以编程,我想知道是否有一些库或实用程序(最好是在Python中)以非编程方式从输入数据的描述创建数据验证器。

欢迎任何建议:)

1 个答案:

答案 0 :(得分:2)

这是我刚刚为您写的一个简单框架:)

class SizedInput(object):
    def __init__(self,label="input",map_fn=str):
        self.map_fn = map_fn
        self.label = label
        self._rval = None
    def _proc(self,sz,tokens):
        if len(tokens) < sz:
            msg = "Insufficient arguments for %s (expected %s got %s)"
            raise Exception(msg%(self.label,sz,len(tokens) )    )

        return (self.map_fn(x) for x in tokens[:sz]), tokens[sz:]
    def parse(self,input_tokens):
        sz = int(input_tokens[0])
        self._rval,rest = self._proc(sz,input_tokens[1:])
        return list(self._rval),rest
    def GetValue():
        return self._rval
    def __call__(self,input_tokens):
        return self.parse(input_tokens)

class MatrixInput(SizedInput):
    def _proc(self,sz,tokens):
        result, rest = SizedInput._proc(self,sz**2,tokens) #call super function with new size
        result = zip(*[iter(result)]*sz)  #this looks fancy but it just resizes 1d to 2d
            return result,rest          

def validateSchema(schema,input_tokens):
    rest = input_tokens
    results = {}
    for schema_item in schema:
        results[schema_item.label] ,rest = schema_item(rest)
    if rest:
        print "Warning : %d unconsumed tokens!"
    return results

要使用它,您必须首先创建一个模式以进行验证

schema = [ #define a schema
    SizedInput("ages",int),
    SizedInput("names",str),
    MatrixInput("matrix",int),
]

然后你需要标记你的输入数据

input_stream = """
2 
8 9
3
asd dsa fff
2
1 2
3 4
"""
tokens = input_stream.split()

然后你只需要将它传递给你的验证器(第一个代码块),如果没有足够的令牌就会引发异常,如果有剩余的令牌就会打印警告(你可以轻松改变它以引发异常) )

print validateSchema(schema, tokens)