1

我正在尝试自己制作一个对现场技术人员/销售人员有益的脚本。该产品线由三种产品组成。但这些产品之间的唯一区别是尺寸。每种尺寸都包含安装它们所需的一定数量的支架。对于小的,只需要一个。对于中等,两个。而对于大的,四个。

我希望我的脚本发出一个提示,询问用户每种类型的产品有多少,因为任何安装都可以有任意数量的这些产品尺寸的混合。(对不起,如果这令人困惑,但希望我下面的代码将有助于更好地解释。)理想情况下,我希望这个脚本能够获取所需的每种产品尺寸的数量,将它们相加并吐出安装所需的括号总数。现在,我无法弄清楚我对这段代码的处理有多糟糕,因为我是编程新手。

请查看下面的代码,非常感谢任何帮助和/或建议。

function (t)
    local t = {}
    a,b = i,brackets
    io.write ("Enter Total Number of Small Products")
    answer = io.read()
    if answer then
        brackets = table.insert (t,#t+1,(answer * 1))
    end
    io.write ("Enter Total Number of Medium Products")
    answer = io.read()
    if answer then
        brackets = table.insert (t,#t+1,(answer * 2))
    end
    io.write ("Enter Total Number of Large Products")
    answer = io.read()
    if answer then
        brackets = table.insert (t,#t+1,(answer * 4))
    end
    local sum = 0
    for i,brackets in ipairs (t) do
        sum = sum + brackets
    end
    print (sum)
end
4

2 回答 2

3

我在这里看到了几个我要提出的问题:

  1. 您的代码全部包含在一个匿名函数中。虽然这在语法上是有效的,但您还没有证明这个函数被捕获并最终被调用。一个简单的脚本主要是在文件范围内编写的,尽管有时编写function main() --[[stuff happens]] end是有意义的。特别是如果你写的不仅仅是main()写东西pcall(main),而是捕捉和处理它抛出的任何错误。

  2. 您的匿名函数被声明为采用名为t. 然后,该参数立即被名为 的局部变量遮蔽t,并且在函数内部根本无法访问。

  3. 你清楚地知道局部变量。那么为什么要使用名为a, b,ibrackets的全局变量answer呢?

  4. 变量a, 和b不再使用,并且i被稍后循环brackets创建的局部变量遮蔽。for

  5. 您了解函数,因此您应该注意提示和读取值的重复代码,并将其收集到函数中。

  6. table.insert没有记录返回值。

  7. 您正在使用t数组,这是一种table.insert已经知道的模式,因此第二个参数#t+1是多余的。如果丢失,那就是table.insert放置值的地方。

  8. 您经常拨打table.insertio.read和。io.write当前的最佳实践表明,将这些函数复制到局部变量中将通过消除对全局符号表的访问(查找table)来加速它们的访问,然后再进行第二次访问以查找函数。local insert,read,write = table.insert,io.read,io.write在文件范围内的某处说类似的东西就可以了。这样做函数范围将起作用,但会在每次调用函数时重新创建这些本地变量。

  9. 您正在将t其用作数组,而类似模式t[#t+1] = expression是一种非常常见的习惯用法,用于简单地将项目附加到数组中。它不仅比调用更快table.insert(即使在本地化值之后),而且更清晰。

  10. 您似乎没有将零件尺寸的单个计数用于其他任何事情。所以实际上根本不需要保留数组。当然,一个可能的起皱功能是生成一份报告,总结每种尺寸的数量、括号的数量,然后包括总数。在这种情况下,保留一张桌子是有意义的。

  11. 在命令行中,您将发现流缓冲 I/O 的一些奥秘。特别是,stdout只要输出是终端而不是文件或管道,它就会被行缓冲(默认情况下在 linux 和 Windows 上,几乎可以肯定也在 Mac 上)。行缓冲 I/O 不能保证在流之间同步。因此,当您停下来阅读他们的答案时,用户可能实际上看不到您的提示。解决此问题的一种方法是始终打印换行符,这将导致输出整行。另一种是io.flush()在每次调用后调用io.write()

  12. 对错误处理进行一些考虑。不仅仅是如果io.write失败会发生什么,还有当您的用户回答“无”或“三”而不是预期的“0”或“3”时会发生什么。用户这样做。您的代码使用从字符串到数字的隐式转换,如果转换失败,则会失败并显示非常混乱的错误消息。考虑显式调用tonumber(),然后考虑当它返回时要做什么nil。甚至显式编写(tonumber(answer) or 0) * 3也比仅仅answer * 3因为它将所有非数字都转换为数字 0 更好。更好的是引导用户进行有效输入。

于 2013-11-07T22:16:38.750 回答
2

您发布的代码有很多问题。如果您的唯一要求是您声明的要求,则以下脚本使用一个函数来执行输入和总和的计算,并作为结果返回。

local function GetSum()
    local sum = 0
    local answer
    io.write ("Enter Total Number of Small Products: ")
    answer = io.read()
    if answer then
        sum = sum + tonumber( answer )
    end
    io.write ("Enter Total Number of Medium Products: ")
    answer = io.read()
    if answer then
        sum = sum + 2 * tonumber( answer )
    end
    io.write ("Enter Total Number of Large Products: ")
    answer = io.read()
    if answer then
        sum = sum + 4 * tonumber( answer )
    end
    return sum
end


print( GetSum() )

注意:对tonumber函数的调用不是必需的,因为 Luaanswer在该上下文中将字符串强制转换为数字,但在更大的应用程序中,显式是有用的,这样读者可以清楚地发现正在进行类型转换。

于 2013-11-07T22:15:18.480 回答