Problems with math using a table on my calculator

I’m new into the area of Lua and currently I’ve been trying to make some randon things so I could learn some of the features I can use with Lua, I tried creating a Calculator but in the process I’ve came into an issue with doing a math using a table.

Basically I’m using a table for the calculator which stores the values and the “operation” it will take ( as one string ), example: 25 + 30 - 35 * 5 will apear on the table as:

[1] = "25 +"
[2] = "30 -"
[3] = "35 X"
[4] = "5 =" -- ( I pressed the result button )

and through that I get the number and the signal with string.sub on the table, with a loop I get the result of it.

Everything works fine but for some reason when the value of 2 values are different, example
First value = 5 . Second value = 10 for some reason it will not find the signal and will go through it as if those numbers and signals on the table didn’t exist, I don’t know why that’s happening.

Script:

function Result()
result = 0
local skip = false
local Operatorr = nil
local AfterOperator = nil
local lastresult = nil

for i = 2, #myTable, 1 do

Operatorr = (string.sub(myTable[i-1], string.len(myTable[i]),-1)) -- the signal of the table before the current one.

if result == 0 then -- If It's the first time the loop executed
print("FIRST TIME SIGNAL = "..Operatorr) -- To check if found signal

if Operatorr == "+"; then -- if the signal is + then result will be the signal from the current table + the one before it.
result = (string.sub(myTable[i-1], 0, -2)) + (string.sub(myTable[i], 0, -2))

elseif Operatorr == "-" then
result = (string.sub(myTable[i-1], 0, -2)) - (string.sub(myTable[i], 0, -2))

elseif Operatorr == "X" then
result = (string.sub(myTable[i-1], 0, -2)) * (string.sub(myTable[i], 0, -2))

end

else-- [if result ~= 0]

if Operatorr == "+" then -- Result will be the result + the value of the current table.
result = result + (string.sub(myTable[i], 0, -2))

elseif Operatorr == "-" then
result = result - (string.sub(myTable[i], 0, -2))

elseif Operatorr == "X" then
result = result * (string.sub(myTable[i], 0, -2))

end

end-- [if result == 0]

warn("Result = "..result)

end-- for loop

If there’s a value and it’s value goes above 9 all the other values need to be above 9 else it doesn’t find the signal, if both values are 1 digit then they’ll work but if 1 is 2 digits and the other is 1 then for some reason it doesn’t.

Table = {
[1] = "5 +"  -- < FIRST TIME SIGNAL
[2] = "10 =" -- ( 5 + 10 )
}

Outputs: Result = 0 FIRST TIME SIGNAL = ( There’s no signal )

Table = {
[1] = "2 +" -- < FIRST TIME SIGNAL
[2] = "2 X" -- ( (2 + 2) * 2)
[3] = "2 ="
}

Outputs Result = 8 FIRST TIME SIGNAL = + ( did find the first signal )

Table = {
[1] = "3 X" -- < FIRST TIME SIGNAL
[2] = "10 =" -- ( 3 * 10 )

Outputs Result = 0 FIRST TIME SIGNAL = ( no signal )

I honestly don’t know why this is happening, I’d be glad if someone did find the error and did give suggestions on it.

It’s also the first time I’m posting on the devforums so hello everyone! :smiley:

Looks like you are being inconsistent with how you write multiplication

You should pick one operator and stick with it.

Oh, sorry I did put the wrong char on the thread, Edited this little error, thanks for noticing it.
( It’s on the thread only )

A few tips

  1. Please indent your code
  2. The function should operate on an argument, not on a global variable
  3. Don’t use warn when you are not warning, use print.
  4. Don’t print the result, return it and handle the print outside the procedure.
  5. Tables are automatically indexed, you should not specify the position manually.

The code is not working so I can’t test it. Here’s my rewrite.

function compute_result(input_table)
	assert(type(input_table) == "table", "Invalid argument type")

	local result = 0
	local next_operator = "init"
	local to_return = false
	for index = 1, #input_table do
		if to_return then
			return result
		end

		local current_row = input_table[index]
		local number, operator = current_row:match("(%d+) +([%+%*/%-=])")

		if operator == "=" then
			to_return = true
		end

		if next_operator == "*" then
			result = result * tonumber(number)
		elseif next_operator == "+" then
			result = result + tonumber(number)
		elseif next_operator == "-" then
			result = result - tonumber(number)
		elseif next_operator == "/" then
			result = result / tonumber(number)
		elseif next_operator == "init" then
			result = tonumber(number)
		else
			error("Invalid operator")
		end

		next_operator = operator
	end
	return result
end

print(compute_result({
	"5 +", -- < FIRST TIME SIGNAL
	"10 =", -- ( (2 + 2) * 2)
}))
2 Likes

I think your problem is that you’re incorrectly finding the location of the operator here:
Operatorr = (string.sub(myTable[i-1], string.len(myTable[i]),-1))

The second argument of string.sub is the location it will begin to crop out a substring, and in your code your starting that search at the same position as the length of the next string. This makes no sense to me. If you have something like {"2 +", 30 ="}, you’ll be selecting the 4th position and onwards of table[1], which doesn’t exist.

Instead of doing that, you should change that line to be:

local s = myTable[i-1]
Operatorr = string.sub(s, #s) -- cuts out the last character of your string

As long as your operator is always the last character of the string, you will cut it out correctly.

2 Likes

I am not sure if this is the issue, but from the top of my head it seems like it’s due to how you fetch the operators and signal. You use the character index to find these, if you write a number above 9 it’ll increase the string length thus increase the operator/signal’s index by 1 per digit.

Edit: @ExtremeBuilder15 explained it in more detail, and provided a possible fix.

1 Like

Thanks, didn’t know I could get the last char easy as that, now everything is working alright! :smiley:

1 Like