源目录
将模块放在单独的源目录中。这样做的优点是可以使用单独安装此目录pip安装-e
例如,或通过将其添加到.深度
在您的虚拟环境站点包中。您正在使用虚拟环境进行开发?
工具
使用好的IDE和可用的工具来改进代码。我使用黑色
作为代码格式化程序,梅比
通过严格的配置检查键入错误,蟒蛇样式
检查我的文档字符串,pytest测试
对于单元测试,pyflakes公司
其他错误。了解它们,寻找大型python项目的配置灵感,并将它们集成到您的工作流中。大多数IDE使这一点非常简单。
变量名称
在python中,变量名的长度对程序的性能没有影响。然后选择清晰的变量名,如请求的空格
而不是或需求
。由于这些不清楚的名称,解密代码真的很困难。
功能中的拆分
您已经有2个函数,但此代码需要更多的函数。
- 读取输入
- 验证输入
- 生成组合
- 选择一个组合
- 输出到输出文件
每一个都应该有自己的功能。这样做可以更好地记录这一点,测试不同的部分,并在未来进行更改。
我尝试分离我的函数,以便传输的数据清晰。
读取输入
提升IO(对话:1 2)不要传递输入文件。读取您的main()
,函数并将内容传递给验证器和以后的计算。输出也是如此。计算返回所需的木板,然后main()
如果需要,函数会将结果写入磁盘。
验证输入
您的输入验证是围绕主方法进行的。您还可以与字符串通信。另一种方法是将验证失败与值错误
如果您添加类型提示和docstring,您可能会得到如下结果:
导入键入class平板(键入.NamedTuple):“”“请求木板。”“”长度:浮子数量:int类BasePlank(键入.NamedTuple):“”“可用的底板。”“”长度:浮子价格:浮点数还是小数?InputData=键入。键入Dict(输入数据,{“削减损失”:浮动,“所需长度”:键入。列表[平板运动],“可用基材”:键入。列表[BasePlank],},)def validate_planks(planks:键入.Iterable[Plank])->无:“”“验证请求的木板。-长度必须大于0-数量必须大于0"""对于木板中的木板:如果“长度”不在平板中:raise ValueError(f“在{plack}中找不到`Length`”)如果“数量”不在板材中:raise ValueError(f“在{platk}中找不到`Qty'”)如果板材[“长度”]<0:raise ValueError(f“`Length`<0 in{plack}”)如果板材[“数量”]<0:提升值错误(f“{plack}中的`Qty`<0”)def validate_baseplanks(板:typeing.Iterable[BasePlank],)->无:“”“验证可用的底板。-长度必须大于0-价格不得为负"""对于木板中的木板:如果“长度”不在平板中:raise ValueError(f“在{plack}中找不到`Length`”)如果“数量”不在板材中:raise ValueError(f“在{plack}中找不到数量”)如果板材[“长度”]<0:raise ValueError(f“`Length`<0 in{plack}”)如果板材[“价格”]<=0:提高价值错误(f“{plack}中的负`Price`”)def validate_input(input_data:InputData)->无:“”“验证输入。”“”如果“削减损失”不在input_data中:raise ValueError(“找不到`Cut loss`”)如果“可用基材”不在input_data中:raise ValueError(“找不到可用基材”)baseplanks=input_data[“可用基材”]验证底板(底板)如果“所需长度”不在input_data中:raise ValueError(“找不到所需长度”)板=input_data[“所需长度”]validate_planks(木板)if max(木板中木板的木板[“长度”])>max(木板[长度]用于垫板中的木板):提升值错误(“要求的最大块数比最长的底板长”)
jsonschema公司
或者您可以使用jsonschema公司
为您进行验证:
模式=jsonschema。Draft7验证器({“type”:“对象”,“属性”:{“剪切损失”:{“类型”:“数量”,“最小值”:0},“所需长度”:{“type”:“数组”,“项目”:{“type”:“对象”,“属性”:{“长度”:{“类型”:“数字”,“排除最小值”:0},“数量”:{“type”:“数字”,“exclusiveMinimum”:0,“倍数”:1,},},“必需”:[“长度”,“数量”],},},“可用基材”:{“type”:“数组”,“项目”:{“type”:“对象”,“属性”:{“长度”:{“类型”:“数字”,“排除最小值”:0},“价格”:{“类型”:“数量”,“最小值”:0},},“必需”:[“长度”,“价格”],},“最小属性”:1,},“必需”:[“减少损失”,“可用基材”,“所需长度”,],},})
然后使用
errors=列表(schema.iter_errors(data))
验证完输入数据后,您可以选择将其放入类中,但对于此解决方案,这可能有点太多了。
测试
通过这种方式,您可以单独测试验证。
在单独的目录中测试
,文件测试输出列表.py
或在每个要测试的函数的单独文件中
导入pytest定义test_validatebaseplanks():correct_data=[{“长度”:300,“价格”:5.95},{“长度”:180,“价格”:2.95},{“长度”:360,“价格”:6.95}]cutlistcalculator.validate_baseplanks(correct_data)missing_price=[{“长度”:300,},{“长度”:180,“价格”:2.95},{“长度”:360,“价格”:6.95}]将pytest.raises(ValueError)作为exinfo:cutlistcalculator.validate_baseplanks(correct_data)在str中断言“未找到价格”(exinfo.value)
等等。
JSON格式
考虑一下要序列化输入和输出的格式。您使用JSON格式
,但正如您所注意到的,这有一些缺点。它非常冗长,你不能添加评论。JSON的意思是便于计算机读取。备选方案包括BSON公司
,TOML公司
, ...
我并不是说这些更好,但至少看看它。特别是当你处于开发的早期,很容易切换。
另一方面,如果您正确地划分代码,并使输入的解析成为自己的函数,那么您可以稍后轻松地更改输入或输出格式。您甚至可以预见多个解析器,并接受不同的格式。
计算
我不明白你用的算法。我没有太多时间去弄清楚,但你用不清楚的名字,把所有的东西都放在一个大的水滴里,这种方式无济于事。尝试将其划分为逻辑结构,然后重构为单独的函数。仔细命名函数,并预见一个docstring并键入hnts。一旦你有了这些,就把它们作为一个新问题再次发布。
制作一个函数,生成可能的切割平面,仅输入所需的板材和可用的基板。把它变成一个生成器,它会产生一个可能的组合。您可以将此管道连接到计算此安排成本的函数中。这将使用一个组合和基板的价格作为参数,并返回组合的成本。通过这样分解工作,您可以记录它们的行为,并可以分别测试每个组件。
输出
将其与计算最佳解决方案的代码分开
使用具有
语句来构造上下文。
将output_file.open(“w”)作为文件句柄:json.dump(文件句柄,结果,缩进=2)
结论
我知道这是很多,但请尝试结合这些提示,以及来自Reinderien的提示,如果您不确定是否会返回一个新版本。继续努力