将用户输入放入表中并将Lua中的总和相加

时间:2013-11-07 21:37:58

标签: lua sum user-input lua-table

我正在尝试自己创建一个脚本,这对于该领域的技术人员/销售人员是有益的。该产品系列有三种产品。但这些产品之间的唯一区别是尺寸。每种尺寸都包含安装它们所需的一定数量的支架。对于小型,只需要一个。对于媒体,两个。而对于大,四。

我希望我的脚本发出提示,询问用户每种类型产品的数量,因为任何安装都可以包含这些产品大小的任意数量。 (对不起,如果这令人困惑,但希望我的代码可以帮助解释更好。)我理想地喜欢这个脚本来获取所需的每个产品大小的数量,添加它们并吐出安装所需的总括号。现在,我无法弄清楚我是多么糟糕地抨击这段代码,因为我是编程新手。

请查看以下代码,我们非常感谢您提供任何帮助和/或建议。

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

2 个答案:

答案 0 :(得分:3)

我在这里看到几个问题:

  1. 您的代码全部包含在匿名函数中。虽然这在语法上是有效的,但您没有显示此函数被捕获并最终被调用。一个简单的脚本主要是在文件范围内编写的,尽管有时编写function main() --[[stuff happens]] end是有意义的。特别是如果不是只写main()而是编写类似pcall(main)的内容来捕获并处理它所引发的任何错误。

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

  3. 您清楚地了解局部变量。那么为什么要使用名为abibracketsanswer的全局变量?

  4. 变量ab不会再次使用,而ibrackets会被for创建的本地人所遮蔽稍后循环。

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

  6. table.insert未记录为返回值。

  7. 您正在使用t作为数组,这是table.insert已经知道的模式,因此#t+1的第二个参数是多余的。如果遗漏,那就是table.insert将值放在哪里。

  8. 您经常致电table.insertio.readio.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”时会发生什么。用户那样做。您的代码使用从字符串到数字的隐式转换,如果转换失败,则会出现 very 凌乱的错误消息。考虑显式调用tonumber(),然后考虑在返回nil时要执行的操作。即使明确地写(tonumber(answer) or 0) * 3也比仅仅answer * 3更好,因为它将所有非数字转换为数字0.更好的是引导用户进行有效输入。

答案 1 :(得分: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函数的调用不是必需的,因为Lua将answer中的字符串强制转换为该上下文中的数字,但是在更大的应用程序中,显式是有用的,以便读者可以清楚地发现正在进行类型转换。