Python 如何创建一个可以直接从shell执行的程序(调和和)?
我用MatLab做过一些编程,但我对Python完全陌生。对于我们的第一个项目,我们的老师希望我们编写一个调和和(Python 如何创建一个可以直接从shell执行的程序(调和和)?,python,function,shell,executable,main,Python,Function,Shell,Executable,Main,我用MatLab做过一些编程,但我对Python完全陌生。对于我们的第一个项目,我们的老师希望我们编写一个调和和(1/1+1/2+1/3…)和一个“可以直接从shell执行的完整程序,如下所示: $python3 hsum.py 10 0 0 1.1.0 2.1.5 3 1.8333333 4 2.083333 5 2.2833333 6 2.4499999997 7.2.5928571428571425 8.2.7178571428571425 9.2.8289682539682537 我是这
1/1+1/2+1/3…
)和一个“可以直接从shell执行的完整程序,如下所示:
$python3 hsum.py 100 0
1.1.0
2.1.5
3 1.8333333
4 2.083333
5 2.2833333
6 2.4499999997
7.2.5928571428571425
8.2.7178571428571425
9.2.8289682539682537 我是这样管理的: 导入系统 def hSum(n): s=0 对于范围(n+1)内的i: 如果i==0: s=0 其他: s+=1/i 返回s def main(): hSum(int(sys.argv[1])#他指定给我们使用的命令 main() 主要问题是我实际上不理解他所说的“一个可以直接从shell执行的完整程序”是什么意思。显然,第二个问题是,当我运行他提供的“测试”文件时,它会测试程序是否正确,它会告诉我: main函数应生成与赋值中完全相同的输出
得到:
[空白]
而不是:
[上一引用中的列表] 下面是test.py代码:
import sys
import importlib.util
def testEq(res, ref, msg):
global pass_tests, fail_tests
if res == ref:
pass_tests = pass_tests + 1
else:
print(msg)
print("Got:")
print(res)
print("Instead of:")
print(ref)
fail_tests = fail_tests + 1
def test(fun, x, y):
global pass_tests, fail_tests
if type(x) == tuple:
z = fun(*x)
else:
z = fun(x)
if y == z:
pass_tests = pass_tests + 1
else:
if type(x) == tuple:
s = repr(x)
else:
s = "(" + repr(x) + ")"
print("Condition failed:")
print(" " + fun.__name__ + s + " == " + repr(y))
print(fun.__name__ + " returned/printed:")
print(str(z))
fail_tests = fail_tests + 1
def run(src_path=None):
global pass_tests, fail_tests
saved_stdout = sys.stdout
sys.stdout = io.StringIO()
saved_argv = sys.argv
sys.argv = ["hsum.py", "10"]
if src_path == None:
import hsum
else:
spec = importlib.util.spec_from_file_location("hsum", src_path + "/hsum.py")
hsum = importlib.util.module_from_spec(spec)
spec.loader.exec_module(hsum)
sys.argv = saved_argv
out = sys.stdout.getvalue()
sys.stdout = saved_stdout
pass_tests = 0
fail_tests = 0
fun_count = 0
if hasattr(hsum, "hSum"):
fun_count = fun_count + 1
test(hsum.hSum, 5, 2.283333333333333)
test(hsum.hSum, 7, 2.5928571428571425)
else:
print("hSum is not implemented yet!")
if hasattr(hsum, "main"):
fun_count = fun_count + 1
testEq(out,
"0 0\n1 1.0\n2 1.5\n3 1.8333333333333333\n4 2.083333333333333\n5 2.283333333333333\n6 "
"2.4499999999999997\n7 2.5928571428571425\n8 2.7178571428571425\n9 2.8289682539682537\n",
"function main should generate exactly the same output as in the assignment")
else:
print("main is not implemented yet!")
print(str(pass_tests) + " out of " + str(pass_tests + fail_tests) + " passed.")
return fun_count == 2 and fail_tests == 0
if __name__ == "__main__":
run()
现在,您的代码不打印或不返回任何内容。这可能是复制/粘贴中的错误-如果您取消输入最后一行
main()
,那么它将运行,并且hSum()
在代码写入时返回一个s
值。现在,这最后一行作为main()
函数本身的一部分执行(使其无限循环),但函数本身从未真正被调用,因此不会发生任何事情
您是否也可以上传test.py脚本的副本?目前尚不清楚它希望如何返回结果
从第一个引号判断,它只是想让您打印所有的值。您可以通过在for
循环中添加print(str(i)+“+str(s))
来轻松完成这一操作(当然,在计算s
之后)。您不需要返回s
,因为这将导致hSum()
与s
相等(例如,value=hSum()
使用下面的代码,我的测试通过了2/3。我将在后面解释原因
import sys
def hSum(n):
s = 0
for i in range(n + 1):
if i == 0:
s = 0
else:
s += 1 / i
print(str(i) + " " + str(s))
return s
def main():
hSum(int(sys.argv[1])) # a command he has specified for us to use
main()
使用returns
是正确的做法,因为它允许测试脚本调用hSum(n)
函数并获得s
的最终值。这对测试1和2正确工作,返回5和7的正确值
我认为第三个测试有一个错误,或者在测试代码的实现方式上有一个我看不到的核心差异。这个问题导致了冲突-在测试1和2中,它希望函数返回5和7的值,包括5和7。对于最终测试,它希望返回10包括10的值,但打印不包括1的值0.为了通过测试,可以为此编写一个变通方法,但如果是的,即通过了任意测试,则代码的功能将不如您保持原样。这是测试驱动开发的常见问题。您的测试需要完美才能生成好的代码
除非有人解释我失踪,否则我建议给你的导师/讲师发邮件,询问这一冲突
FWIW这里有一个解决方法,它不打印最终结果。我不建议这样编码,但它通过了所有测试
import sys
def hSum(n):
s = 0
for i in range(n+1):
if i == 0:
s = 0
else:
s += 1 / i
if(i != n):
print(str(i) + " " + str(s))
return s
def main():
hSum(int(sys.argv[1])) # a command he has specified for us to use
main()
我同意yuuuu的观点,多看看可能会有帮助
还有一种叫做shebang(#!/usr/bin/env python3)的东西,你可以把它放在文件的顶部,使它也可以执行。它应该是文件中的第一行(在导入或任何操作之前)。它告诉操作系统使用什么来执行文件。它看起来像下面的代码:
#!/usr/bin/env python3
import sys
def hSum(n):
s = 0
...
正如Yuuu指出的,调用main()时,由于缩进的原因,它看起来像是在调用main()函数本身。您可以像调用main()时那样(但缩进正确)进行调用,但还有另一个选项,name='main'if语句。这里有一个更深入的解释,但我的理解是,这是从命令行执行python脚本时调用函数或w/e的标准方式
#!/usr/bin/env python3
import sys
def hSum(n):
s = 0
for i in range(n + 1):
if i == 0:
s = 0
else:
s += 1 / i
return s
def main():
hSum(int(sys.argv[1])) # a command he has specified for us to use
if __name__ == '__main__':
main()
编辑//
如果没有Yuuu询问的信息,很难给出更多的答案。谢谢,我已经更新了帖子,加入了test.py。我没有注册main()
,但现在它给了我一条信息:回溯(最近一次调用):\File“xxx”,第16行,in main()\File“xxx”,第15行,in main\hSum(int(sys.argv[1]))\索引器:列表索引超出范围
@Cacti我在回答中添加了对我有效的代码,将查看测试代码,并查看它的确切期望值。@Cacti-您自己在问题的第一段中编写了完整的程序,可以直接从shell执行,如下所示:…-现在您只需继续并执行即可它是这样的。@Cacti只是再次阅读您的注释,此错误意味着sys.argv参数列表中没有“1”元素。此列表是您在运行脚本时在“python”之后编写的内容列表-其中sys.argv[0]是脚本的路径。[1]超出范围表明您没有在路径后添加要计算的数字。谢谢,我已更新帖子以包含test.py。我希望尽可能保持此代码的基本性,因为这是我们的第一项任务。您是否尝试过您所说的我已这样管理的代码?