Alright. Not to drag up a really old topic, but I am having new trouble with the same program. I have added the equation functions, and added key input as well. The problem I have now, before I can release it, is the 'enter' key on the numpad. The key code is 156 but it does not register as the same action as actually pressing the equals sign on the screen. I don't understand why though.
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 = false
-- 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 == 30 and calc.pos == true and colors.white 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 result = "0"
while true do
local rLen = 0
draw()
display()
term.setBackgroundColor(colors.lightGray)
term.setTextColor(colors.white)
term.setCursorPos(4,2)
write(table.concat(equation))
if string.len(result) >= 15 then
term.setCursorPos(5, 4)
term.setTextColor(colors.black)
write("=")
for num in string.gmatch(result, ".") do
rLen = rLen + 1
local pX,pY = term.getCursorPos()
if pX >= 4 and pX <= 48 then
term.setCursorPos(rLen + 5, 4)
write(num)
else
term.setCursorPos(rLen + 5, 5)
write(num)
end
end
else
for num in string.gmatch(result, ".") do
rLen = rLen + 1
for i = 1, #charList[num] do
term.setTextColor(colors.black)
term.setCursorPos((rLen * 3) + 1, i + 3)
write(charList[num][i])
end
end
end
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
if table.concat(equation) ~= "()" then
table.remove(equation, #equation - 1)
end
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 = false
equation = {"(", ")"}
result = "0"
elseif events[4] >= 16 and events[4] <= 18 then
result = tostring(calculate(equation))
end
-- 3, 6, 9, decimal
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
-- 2, 5, 8, positive/negative
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
if calc.pos == false then
table.insert(equation, #equation, "(0-")
calc.pos = true
elseif calc.pos == true then
table.insert(equation, #equation, ")")
calc.pos = false
end
end
-- 1, 4, 7, 0
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
-- add, subtract, multiply, divide
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
-- filter for keyboard presses
elseif events[1] == "key" then
if events[2] == 79 then
table.insert(equation, #equation, "1")
elseif events[2] == 80 then
table.insert(equation, #equation, "2")
elseif events[2] == 81 then
table.insert(equation, #equation, "3")
elseif events[2] == 75 then
table.insert(equation, #equation, "4")
elseif events[2] == 76 then
table.insert(equation, #equation, "5")
elseif events[2] == 77 then
table.insert(equation, #equation, "6")
elseif events[2] == 71 then
table.insert(equation, #equation, "7")
elseif events[2] == 72 then
table.insert(equation, #equation, "8")
elseif events[2] == 73 then
table.insert(equation, #equation, "9")
elseif events[2] == 82 then
table.insert(equation, #equation, "0")
elseif events[2] == 83 then
table.insert(equation, #equation, ".")
elseif events[2] == 78 then
table.insert(equation, #equation, "+")
elseif events[2] == 74 then
table.insert(equation, #equation, "-")
elseif events[2] == 55 then
table.insert(equation, #equation, "*")
elseif events[2] == 181 then
table.insert(equation, #equation, "/")
elseif events[2] == 14 then
if table.concat(equation) ~= "()" then
table.remove(equation, #equation - 1)
end
elseif events[2] == 156 then
result = tostring(calculate(equation)) --this will not calculate.
end
end
end