This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Cranium's profile picture

Help with string matching

Started by Cranium, 19 December 2012 - 05:25 AM
Cranium #1
Posted 19 December 2012 - 06:25 AM
I am still working on my calculator, but in trying to make some fancy schmancy looking numbers being displayed on the screen, I ran into some trouble.
I am trying to match the result I get from my calculator function(the function that actually does the math), and match the string it returns and write individual characters from a table of items. The charList is just a list of ASCII numbers, just there to make things look good.
The problem I come into is when I am matching. I can use %d to match the numbers, which provides the result I want, but when switching to %. for all characters(including the decimal point( . )), it won't write anything. Here is the block of code giving me trouble:

local result = tostring(calculate(equation))
for num, pos in string.gmatch(result, "%.") do
  rLen = rLen + 1
  for i = 1, #charList[num] do
    term.setCursorPos((rLen * 3) + 1, i + 3)
    write(charList[num][i])
  end
end
And here is the full code if you are interested:
Spoiler

--[[Smart Calculator by Cranium]]--
local tX, tY = term.getSize()
local calc = {}
--equation states
calc.mode = false
calc.inverse = false
calc.hyp = false
calc.sqrt = false
calc.exp = false
calc.asin = false
calc.sin = false
calc.sinh = false
calc.atan = false
calc.tan = false
calc.tanh = false
calc.acos = false
calc.cos = false
calc.cosh = false
calc.log = false
calc.pos = true
-- characters
local charList = {
["0"] = {
  ".-.",
  "| |",
  "'-'"
},
["1"] = {
  ",. ",
  " | ",
  "---"
},
["2"] = {
  ".-.",
  ".-'",
  "'- "
},
["3"] = {
  " -.",
  " -|",
  " -'"
},
["4"] = {
  ". .",
  "'-|",
  "  '"
},
["5"] = {
  ".-.",
  "'-.",
  " -'"
},
["6"] = {
  ".-.",
  "|-.",
  "'-'"
},
["7"] = {
  ".-.",
  "  |",
  "  '"
},
["8"] = {
  ".-.",
  "|-|",
  "'-'"
},
["9"] = {
  ".-.",
  "'-|",
  " -'"
},
["."] = {
  "   ",
  "   ",
  " . "
},
}
-- lay out the button labels
local labels = {
' + ', ' 1 ', ' 2 ', ' 3 ', '<--', 'sin', 'x^y', 'DEG', 'OFF',
' - ', ' 4 ', ' 5 ', ' 6 ', 'CLR', 'cos', 'srt', 'RAD', '   ',
' x ', ' 7 ', ' 8 ', ' 9 ', '   ', 'tan', 'Pi ', 'inv', '   ',
' / ', ' 0 ', '-/+', ' . ', ' = ', 'log', 'exp', 'hyp', '   '
}

-- generate the objects
local function objGen()
local _objects = {}
local width = 9
for i=1, #labels do
  table.insert(_objects, {
   x = (((i - 1)%width + 1)*5) - 1;
   y = (math.ceil(i/width) * 3) + 4;
   label = labels[i];
   -- make operators different colors
   color =
   i == 1 and colors.blue or
   i == 5 and colors.red or
   i == 6 and colors.yellow or
   i == 7 and colors.orange or
   i == 8 and colors.white or
   i == 9 and colors.red or
   i == 10 and colors.blue or
   i == 14 and colors.red or
   i == 15 and colors.yellow or
   i == 16 and colors.orange or
   i == 17 and colors.white or
   i == 18 and colors.white or
   i == 19 and colors.blue or
   i == 24 and colors.yellow or
   i == 25 and colors.orange or
   i == 26 and colors.white or
   i == 27 and colors.white or
   i == 28 and colors.blue or
   i == 30 and colors.red or
   i == 32 and colors.white or
   i == 33 and colors.yellow or
   i == 34 and colors.orange or
   i == 35 and colors.white or
   i == 36 and colors.white or
   colors.lightGray;
 
   back =
   i == 6 and
    calc.sin == true and colors.red or
    calc.asin == true and colors.red or
    calc.sinh == true and colors.red or
   i == 8 and calc.mode == "deg" and colors.blue or
   i == 15 and
    calc.cos == true and colors.red or
    calc.acos == true and colors.red or
    calc.cosh == true and colors.red or
   i == 16 and calc.sqrt == true and colors.lightBlue or
   i == 17 and calc.mode == "rad" and colors.blue or
   i == 24 and
    calc.tan == true and colors.red or
    calc.atan == true and colors.red or
    calc.tanh == true and colors.red or
   i == 26 and calc.inverse == true and colors.blue or
   i == 33 and calc.log == true and colors.red or
   i == 34 and calc.exp == true and colors.lightBlue or
   i == 35 and calc.hyp == true and colors.blue or
   colors.black;
  })
end
return _objects
end
local function draw()
term.setBackgroundColor(colors.black)
term.clear()
local objects = objGen()
for i=1, #objects do
  local obj = objects[i]
  term.setTextColor(colors.gray)
  term.setBackgroundColor(colors.black)
  for num, line in pairs{'+---+','|   |','+---+'} do
   term.setCursorPos(obj.x, obj.y + num - 1)
   write(line)
  end
  term.setCursorPos(obj.x+1, obj.y+1)
  term.setTextColor(obj.color)
  term.setBackgroundColor(obj.back)
  write(obj.label)
end
end
local function display()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.gray)
term.setCursorPos(2,1)
write("+"..string.rep("-", tX - 4).."+")
for i = 2, tY - 1 do
  term.setCursorPos(2,i)
  write("|")
  term.setCursorPos(tX - 1,i)
  write("|")
end
term.setCursorPos(2,tY)
write("+"..string.rep("-", tX - 4).."+")
term.setBackgroundColor(colors.lightGray)
for i = 2, 6 do
  term.setCursorPos(4,i)
  write(string.rep(" ", tX - 6))
end
end
local function calculate(eq)
if table.concat(eq) == "()" then
  eq = {"0"}
elseif table.concat(eq) == "(.)" then
  eq = {"0"}
end
local sExpr = table.concat(eq)
local fnMath, sErr = loadstring("return "..sExpr)
if not fnMath then
  return "ERROR 1: "..sErr
end
--setfenv(fnMath, math)
local bSucc, vRes = pcall(fnMath)
if not bSucc then
  return "ERROR 2: "..vRes
else
  return vRes
end
end
local function rPrint(result)
 

end
-- function loop
local equation = {"(", ")"}
local dispNum = {}
while true do
draw()
display()
  term.setBackgroundColor(colors.lightGray)
  term.setTextColor(colors.white)
  term.setCursorPos(4,1)
  write(table.concat(equation))
local events = {os.pullEvent()}
if events[1] == "mouse_click" and events[2] == 1 then
  if events[3] >= 44 and events[3] <= 48 then
   if events[4] >= 7 and events[4] <= 9 then
    break
   end
  elseif events[3] >= 39 and events[3] <= 43 then
   if events[4] >= 7 and events[4] <= 9 then
    if calc.mode == false then
	 table.remove(equation, 1)
	 calc.mode = "deg"
	 table.insert(equation, 1, "math.deg(")
    elseif calc.mode == "deg" then
	 table.remove(equation, 1)
	 calc.mode = false
    elseif calc.mode == "rad" then
	 table.remove(equation, 1)
	 calc.mode = "deg"
	 table.insert(equation, 1, "math.deg(")
    end
   elseif events[4] >= 10 and events[4] <= 12 then
    if calc.mode == false then
	 table.remove(equation, 1)
	 calc.mode = "rad"
	 table.insert(equation, 1, "math.rad(")
    elseif calc.mode == "rad" then
	 table.remove(equation, 1)
	 calc.mode = false
    elseif calc.mode == "deg" then
	 table.remove(equation, 1)
	 calc.mode = "rad"
	 table.insert(equation, 1, "math.rad(")
    end
   elseif events[4] >= 13 and events[4] <= 15 then
    if calc.inverse == true and calc.hyp == false then
	 calc.inverse = false
    elseif calc.inverse == false and calc.hyp == true then
	 calc.inverse = true
	 calc.hyp = false
    elseif calc.inverse == false and calc.hyp == false then
	 calc.inverse = true
    end
   elseif events[4] >= 16 and events[4] <= 18 then
    if calc.hyp == true and calc.inverse == false then
	 calc.hyp = false
    elseif calc.hyp == false and calc.inverse == true then
	 calc.hyp = true
	 calc.inverse = false
    elseif calc.hyp == false and calc.inverse == false then
	 calc.hyp = true
    end
   end
  elseif events[3] >= 34 and events[3] <= 38 then
   if events[4] >= 7 and events[4] <= 9 then
    table.insert(equation, #equation, "^")
   elseif events[4] >= 10 and events[4] <= 12 then
    if calc.sqrt == false then
	 table.insert(equation, #equation, "math.sqrt(")
	 calc.sqrt = true
    elseif calc.sqrt == true then
	 table.insert(equation, #equation, ")")
	 calc.sqrt = false
    end
   elseif events[4] >= 13 and events[4] <= 15 then
    table.insert(equation, #equation, "math.pi")
   elseif events[4] >= 16 and events[4] <= 18 then
    if calc.exp == false then
	 table.insert(equation, #equation, "math.exp(")
	 calc.exp = true
    elseif calc.exp == true then
	 table.insert(equation, #equation, ")")
	 calc.exp = false
    end
   end
  elseif events[3] >= 29 and events[3] <= 33 then
   if events[4] >= 7 and events[4] <= 9 then
    if calc.inverse == true and calc.asin == false then
	 table.insert(equation, #equation, "math.asin(")
	 calc.asin = true
    elseif calc.inverse == false and calc.hyp == false and calc.sin == false then
	 table.insert(equation, #equation, "math.sin(")
	 calc.sin = true
    elseif calc.hyp == true and calc.sinh == false then
	 table.insert(equation, #equation, "math.sinh(")
	 calc.sinh = true
    elseif calc.asin == true then
	 table.insert(equation, #equation, ")")
	 calc.asin = false
    elseif calc.sin == true then
	 table.insert(equation, #equation, ")")
	 calc.sin = false
    elseif calc.sinh == true then
	 table.insert(equation, #equation, ")")
	 calc.sinh = false
    end
   elseif events[4] >= 10 and events[4] <= 12 then
    if calc.inverse == true and calc.acos == false then
	 table.insert(equation, #equation, "math.acos(")
	 calc.acos = true
    elseif calc.inverse == false and calc.hyp == false and calc.cos == false then
	 table.insert(equation, #equation, "math.cos(")
	 calc.cos = true
    elseif calc.hyp == true and calc.cosh == false then
	 table.insert(equation, #equation, "math.cosh(")
	 calc.cosh = true
    elseif calc.acos == true then
	 table.insert(equation, #equation, ")")
	 calc.acos = false
    elseif calc.cos == true then
	 table.insert(equation, #equation, ")")
	 calc.cos = false
    elseif calc.cosh == true then
	 table.insert(equation, #equation, ")")
	 calc.cosh = false
    end
   elseif events[4] >= 13 and events[4] <= 15 then
    if calc.inverse == true and calc.atan == false then
	 table.insert(equation, #equation, "math.atan(")
	 calc.atan = true
    elseif calc.inverse == false and calc.hyp == false and calc.tan == false then
	 table.insert(equation, #equation, "math.tan(")
	 calc.tan = true
    elseif calc.hyp == true and calc.tanh == false then
	 table.insert(equation, #equation, "math.tanh(")
	 calc.tanh = true
    elseif calc.atan == true then
	 table.insert(equation, #equation, ")")
	 calc.atan = false
    elseif calc.tan == true then
	 table.insert(equation, #equation, ")")
	 calc.tan = false
    elseif calc.tanh == true then
	 table.insert(equation, #equation, ")")
	 calc.tanh = false
    end
   elseif events[4] >= 16 and events[4] <= 18 then
    if calc.log == false then
	 table.insert(equation, #equation, "math.log10(")
	 calc.log = true
    elseif calc.log == true then
	 table.insert(equation, ")")
	 calc.log = false
    end
   end
  elseif events[3] >= 24 and events[3] <= 28 then
   if events[4] >= 7 and events[4] <= 9 then
    table.remove(equation)
   elseif events[4] >= 10 and events[4] <= 12 then
    calc.mode = false
    calc.inverse = false
    calc.hyp = false
    calc.sqrt = false
    calc.exp = false
    calc.asin = false
    calc.sin = false
    calc.sinh = false
    calc.atan = false
    calc.tan = false
    calc.tanh = false
    calc.acos = false
    calc.cos = false
    calc.cosh = false
    calc.log = false
    calc.pos = true
    equation = {"(", ")"}
   elseif events[4] >= 16 and events[4] <= 18 then
    local rLen = 0
    local result = tostring(calculate(equation))
    term.setCursorPos(4,2)
    for num, pos in string.gmatch(result, "%.") do
	 rLen = rLen + 1
	 for i = 1, #charList[num] do
	  term.setCursorPos((rLen * 3) + 1, i + 3)
	  write(charList[num][i])
	 end
    end
    sleep(10)

   end
  elseif events[3] >= 19 and events[3] <= 23 then
   if events[4] >= 7 and events[4] <= 9 then
    table.insert(equation, #equation, "3")
   elseif events[4] >= 10 and events[4] <= 12 then
    table.insert(equation, #equation, "6")
   elseif events[4] >= 13 and events[4] <= 15 then
    table.insert(equation, #equation, "9")
   elseif events[4] >= 16 and events[4] <= 18 then
    table.insert(equation, #equation, ".")
   end
  elseif events[3] >= 14 and events[3] <= 18 then
   if events[4] >= 7 and events[4] <= 9 then
    table.insert(equation, #equation, "2")
   elseif events[4] >= 10 and events[4] <= 12 then
    table.insert(equation, #equation, "5")
   elseif events[4] >= 13 and events[4] <= 15 then
    table.insert(equation, #equation, "8")
   elseif events[4] >= 16 and events[4] <= 18 then
	 --positive/negative
   end
  elseif events[3] >= 9 and events[3] <= 13 then
   if events[4] >= 7 and events[4] <= 9 then
    table.insert(equation, #equation, "1")
   elseif events[4] >= 10 and events[4] <= 12 then
    table.insert(equation, #equation, "4")
   elseif events[4] >= 13 and events[4] <= 15 then
    table.insert(equation, #equation, "7")
   elseif events[4] >= 16 and events[4] <= 18 then
    table.insert(equation, #equation, "0")
   end
  elseif events[3] >= 4 and events[3] <= 8 then
   if events[4] >= 7 and events[4] <= 9 then
    table.insert(equation, #equation, "+")
   elseif events[4] >= 10 and events[4] <= 12 then
    table.insert(equation, #equation, "-")
   elseif events[4] >= 13 and events[4] <= 15 then
    table.insert(equation, #equation, "*")
   elseif events[4] >= 16 and events[4] <= 18 then
    table.insert(equation, #equation, "/")
   end
  end
end
end
Lyqyd #2
Posted 19 December 2012 - 06:43 AM
Since . is a special character for pattern matching, you're actually escaping it (which will match only a literal "." character). Remove the percent sign.
Cranium #3
Posted 19 December 2012 - 06:56 AM
Ah, I see. So %. will only look for " . ", and . will look for EVERYTHING. Thanks for the help!